diff --git a/config/kernel/linux-rockchip64-current.config b/config/kernel/linux-rockchip64-current.config index 0208a8d5c1..2ce0494d6d 100644 --- a/config/kernel/linux-rockchip64-current.config +++ b/config/kernel/linux-rockchip64-current.config @@ -1,16 +1,14 @@ # # Automatically generated file; DO NOT EDIT. -# Linux/arm64 5.7.12 Kernel Configuration -# - -# -# Compiler: aarch64-none-linux-gnu-gcc (GNU Toolchain for the A-profile Architecture 9.2-2019.12 (arm-9.10)) 9.2.1 20191025 +# Linux/arm64 5.8.5 Kernel Configuration # +CONFIG_CC_VERSION_TEXT="aarch64-none-linux-gnu-gcc (GNU Toolchain for the A-profile Architecture 9.2-2019.12 (arm-9.10)) 9.2.1 20191025" CONFIG_CC_IS_GCC=y CONFIG_GCC_VERSION=90201 CONFIG_LD_VERSION=233010000 CONFIG_CLANG_VERSION=0 CONFIG_CC_CAN_LINK=y +CONFIG_CC_CAN_LINK_STATIC=y CONFIG_CC_HAS_ASM_GOTO=y CONFIG_CC_HAS_ASM_INLINE=y CONFIG_IRQ_WORK=y @@ -25,12 +23,14 @@ CONFIG_INIT_ENV_ARG_LIMIT=32 CONFIG_LOCALVERSION="" # CONFIG_LOCALVERSION_AUTO is not set CONFIG_BUILD_SALT="" +CONFIG_DEFAULT_INIT="" CONFIG_DEFAULT_HOSTNAME="(none)" CONFIG_SWAP=y CONFIG_SYSVIPC=y CONFIG_SYSVIPC_SYSCTL=y CONFIG_POSIX_MQUEUE=y CONFIG_POSIX_MQUEUE_SYSCTL=y +# CONFIG_WATCH_QUEUE is not set CONFIG_CROSS_MEMORY_ATTACH=y CONFIG_USELIB=y CONFIG_AUDIT=y @@ -109,7 +109,10 @@ CONFIG_PREEMPT_RCU=y # CONFIG_RCU_EXPERT is not set CONFIG_SRCU=y CONFIG_TREE_SRCU=y +CONFIG_TASKS_RCU_GENERIC=y CONFIG_TASKS_RCU=y +CONFIG_TASKS_RUDE_RCU=y +CONFIG_TASKS_TRACE_RCU=y CONFIG_RCU_STALL_COMMON=y CONFIG_RCU_NEED_SEGCBLIST=y # end of RCU Subsystem @@ -138,7 +141,6 @@ CONFIG_CGROUPS=y CONFIG_PAGE_COUNTER=y CONFIG_MEMCG=y CONFIG_MEMCG_SWAP=y -CONFIG_MEMCG_SWAP_ENABLED=y CONFIG_MEMCG_KMEM=y CONFIG_BLK_CGROUP=y CONFIG_CGROUP_WRITEBACK=y @@ -334,12 +336,12 @@ CONFIG_ARM64_ERRATUM_845719=y CONFIG_ARM64_ERRATUM_843419=y CONFIG_ARM64_ERRATUM_1024718=y CONFIG_ARM64_ERRATUM_1418040=y -CONFIG_ARM64_WORKAROUND_SPECULATIVE_AT_VHE=y +CONFIG_ARM64_WORKAROUND_SPECULATIVE_AT=y CONFIG_ARM64_ERRATUM_1165522=y -CONFIG_ARM64_ERRATUM_1530923=y -CONFIG_ARM64_ERRATUM_1286807=y -CONFIG_ARM64_WORKAROUND_SPECULATIVE_AT_NVHE=y CONFIG_ARM64_ERRATUM_1319367=y +CONFIG_ARM64_ERRATUM_1530923=y +CONFIG_ARM64_WORKAROUND_REPEAT_TLBI=y +CONFIG_ARM64_ERRATUM_1286807=y CONFIG_ARM64_ERRATUM_1463225=y CONFIG_ARM64_ERRATUM_1542419=y CONFIG_CAVIUM_ERRATUM_22375=y @@ -348,14 +350,13 @@ CONFIG_CAVIUM_ERRATUM_23154=y CONFIG_CAVIUM_ERRATUM_27456=y CONFIG_CAVIUM_ERRATUM_30115=y CONFIG_CAVIUM_TX2_ERRATUM_219=y +CONFIG_FUJITSU_ERRATUM_010001=y +CONFIG_HISILICON_ERRATUM_161600802=y CONFIG_QCOM_FALKOR_ERRATUM_1003=y -CONFIG_ARM64_WORKAROUND_REPEAT_TLBI=y CONFIG_QCOM_FALKOR_ERRATUM_1009=y CONFIG_QCOM_QDF2400_ERRATUM_0065=y -CONFIG_SOCIONEXT_SYNQUACER_PREITS=y -CONFIG_HISILICON_ERRATUM_161600802=y CONFIG_QCOM_FALKOR_ERRATUM_E1041=y -CONFIG_FUJITSU_ERRATUM_010001=y +CONFIG_SOCIONEXT_SYNQUACER_PREITS=y # end of ARM errata workarounds via the alternatives framework CONFIG_ARM64_4K_PAGES=y @@ -455,6 +456,8 @@ CONFIG_ARM64_AMU_EXTN=y # # ARMv8.5 architectural features # +CONFIG_ARM64_BTI=y +CONFIG_CC_HAS_BRANCH_PROT_PAC_RET_BTI=y CONFIG_ARM64_E0PD=y CONFIG_ARCH_RANDOM=y # end of ARMv8.5 architectural features @@ -462,6 +465,7 @@ CONFIG_ARCH_RANDOM=y CONFIG_ARM64_SVE=y CONFIG_ARM64_MODULE_PLTS=y # CONFIG_ARM64_PSEUDO_NMI is not set +CONFIG_RELOCATABLE=y # CONFIG_RANDOMIZE_BASE is not set CONFIG_CC_HAVE_STACKPROTECTOR_SYSREG=y CONFIG_STACKPROTECTOR_PER_TASK=y @@ -487,6 +491,7 @@ CONFIG_SUSPEND_FREEZER=y # CONFIG_SUSPEND_SKIP_SYNC is not set CONFIG_HIBERNATE_CALLBACKS=y CONFIG_HIBERNATION=y +CONFIG_HIBERNATION_SNAPSHOT_DEV=y CONFIG_PM_STD_PARTITION="" CONFIG_PM_SLEEP=y CONFIG_PM_SLEEP_SMP=y @@ -555,7 +560,6 @@ CONFIG_CPUFREQ_DT=m CONFIG_CPUFREQ_DT_PLATDEV=y CONFIG_ARM_ALLWINNER_SUN50I_CPUFREQ_NVMEM=m CONFIG_ARM_SCPI_CPUFREQ=y -# CONFIG_QORIQ_CPUFREQ is not set # end of CPU Frequency scaling # end of CPU Power Management @@ -570,10 +574,7 @@ CONFIG_ARM_SCPI_POWER_DOMAIN=y CONFIG_DMIID=y # CONFIG_DMI_SYSFS is not set # CONFIG_FW_CFG_SYSFS is not set -CONFIG_HAVE_ARM_SMCCC=y CONFIG_ROCKCHIP_SIP=y -CONFIG_ARM_PSCI_FW=y -# CONFIG_ARM_PSCI_CHECKER is not set # CONFIG_GOOGLE_FIRMWARE is not set # @@ -583,8 +584,9 @@ CONFIG_ARM_PSCI_FW=y CONFIG_EFI_ESRT=y CONFIG_EFI_PARAMS_FROM_FDT=y CONFIG_EFI_RUNTIME_WRAPPERS=y -CONFIG_EFI_ARMSTUB=y +CONFIG_EFI_GENERIC_STUB=y CONFIG_EFI_ARMSTUB_DTB_LOADER=y +CONFIG_EFI_GENERIC_STUB_INITRD_CMDLINE_LOADER=y CONFIG_EFI_CAPSULE_LOADER=y # CONFIG_EFI_TEST is not set # CONFIG_RESET_ATTACK_MITIGATION is not set @@ -593,6 +595,10 @@ CONFIG_EFI_CAPSULE_LOADER=y CONFIG_EFI_EARLYCON=y CONFIG_MESON_SM=y +CONFIG_ARM_PSCI_FW=y +# CONFIG_ARM_PSCI_CHECKER is not set +CONFIG_HAVE_ARM_SMCCC=y +CONFIG_HAVE_ARM_SMCCC_DISCOVERY=y # # Tegra firmware driver @@ -602,6 +608,9 @@ CONFIG_MESON_SM=y CONFIG_ARCH_SUPPORTS_ACPI=y # CONFIG_ACPI is not set +CONFIG_IRQ_BYPASS_MANAGER=y +CONFIG_VIRTUALIZATION=y +CONFIG_KVM=y CONFIG_HAVE_KVM_IRQCHIP=y CONFIG_HAVE_KVM_IRQFD=y CONFIG_HAVE_KVM_IRQ_ROUTING=y @@ -614,10 +623,6 @@ CONFIG_HAVE_KVM_ARCH_TLB_FLUSH_ALL=y CONFIG_KVM_GENERIC_DIRTYLOG_READ_PROTECT=y CONFIG_HAVE_KVM_IRQ_BYPASS=y CONFIG_HAVE_KVM_VCPU_RUN_PID_CHANGE=y -CONFIG_IRQ_BYPASS_MANAGER=y -CONFIG_VIRTUALIZATION=y -CONFIG_KVM=y -CONFIG_KVM_ARM_HOST=y CONFIG_KVM_ARM_PMU=y CONFIG_KVM_INDIRECT_VECTORS=y CONFIG_ARM64_CRYPTO=y @@ -668,7 +673,6 @@ CONFIG_HAVE_ASM_MODVERSIONS=y CONFIG_HAVE_REGS_AND_STACK_ACCESS_API=y CONFIG_HAVE_RSEQ=y CONFIG_HAVE_FUNCTION_ARG_ACCESS_API=y -CONFIG_HAVE_CLK=y CONFIG_HAVE_HW_BREAKPOINT=y CONFIG_HAVE_PERF_REGS=y CONFIG_HAVE_PERF_USER_STACK_DUMP=y @@ -716,6 +720,7 @@ CONFIG_HAVE_ARCH_COMPILER_H=y CONFIG_HAVE_ARCH_PREL32_RELOCATIONS=y CONFIG_ARCH_USE_MEMREMAP_PROT=y # CONFIG_LOCK_EVENT_COUNTS is not set +CONFIG_ARCH_HAS_RELR=y # # GCOV-based kernel profiling @@ -768,6 +773,7 @@ CONFIG_BLK_WBT_MQ=y CONFIG_BLK_DEBUG_FS=y CONFIG_BLK_DEBUG_FS_ZONED=y # CONFIG_BLK_SED_OPAL is not set +# CONFIG_BLK_INLINE_ENCRYPTION is not set # # Partition Types @@ -813,6 +819,9 @@ CONFIG_FREEZER=y # CONFIG_BINFMT_ELF=y CONFIG_COMPAT_BINFMT_ELF=y +CONFIG_ARCH_BINFMT_ELF_STATE=y +CONFIG_ARCH_HAVE_ELF_PROT=y +CONFIG_ARCH_USE_GNU_PROPERTY=y CONFIG_ELFCORE=y # CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS is not set CONFIG_BINFMT_SCRIPT=y @@ -831,7 +840,6 @@ CONFIG_HAVE_MEMORY_PRESENT=y CONFIG_SPARSEMEM_EXTREME=y CONFIG_SPARSEMEM_VMEMMAP_ENABLE=y CONFIG_SPARSEMEM_VMEMMAP=y -CONFIG_HAVE_MEMBLOCK_NODE_MAP=y CONFIG_HAVE_FAST_GUP=y CONFIG_ARCH_KEEP_MEMBLOCK=y CONFIG_MEMORY_ISOLATION=y @@ -876,7 +884,7 @@ CONFIG_ZPOOL=y CONFIG_ZBUD=y CONFIG_Z3FOLD=y CONFIG_ZSMALLOC=y -CONFIG_PGTABLE_MAPPING=y +# CONFIG_ZSMALLOC_PGTABLE_MAPPING is not set # CONFIG_ZSMALLOC_STAT is not set CONFIG_GENERIC_EARLY_IOREMAP=y # CONFIG_DEFERRED_STRUCT_PAGE_INIT is not set @@ -915,6 +923,8 @@ CONFIG_XFRM_INTERFACE=m CONFIG_XFRM_SUB_POLICY=y CONFIG_XFRM_MIGRATE=y CONFIG_XFRM_STATISTICS=y +CONFIG_XFRM_AH=m +CONFIG_XFRM_ESP=m CONFIG_XFRM_IPCOMP=m CONFIG_NET_KEY=m CONFIG_NET_KEY_MIGRATE=y @@ -987,6 +997,7 @@ CONFIG_IPV6_OPTIMISTIC_DAD=y CONFIG_INET6_AH=m CONFIG_INET6_ESP=m CONFIG_INET6_ESP_OFFLOAD=m +# CONFIG_INET6_ESPINTCP is not set CONFIG_INET6_IPCOMP=m CONFIG_IPV6_MIP6=m CONFIG_IPV6_ILA=m @@ -1409,6 +1420,7 @@ CONFIG_MRP=y CONFIG_BRIDGE=m CONFIG_BRIDGE_IGMP_SNOOPING=y CONFIG_BRIDGE_VLAN_FILTERING=y +# CONFIG_BRIDGE_MRP is not set CONFIG_HAVE_NET_DSA=y CONFIG_NET_DSA=m CONFIG_NET_DSA_TAG_8021Q=m @@ -1555,6 +1567,7 @@ CONFIG_NET_ACT_SKBMOD=m CONFIG_NET_ACT_IFE=m CONFIG_NET_ACT_TUNNEL_KEY=m CONFIG_NET_ACT_CT=m +# CONFIG_NET_ACT_GATE is not set CONFIG_NET_IFE_SKBMARK=m CONFIG_NET_IFE_SKBPRIO=m CONFIG_NET_IFE_SKBTCINDEX=m @@ -1590,6 +1603,7 @@ CONFIG_NET_NSH=m CONFIG_HSR=m CONFIG_NET_SWITCHDEV=y CONFIG_NET_L3_MASTER_DEV=y +# CONFIG_QRTR is not set # CONFIG_NET_NCSI is not set CONFIG_RPS=y CONFIG_RFS_ACCEL=y @@ -1706,8 +1720,9 @@ CONFIG_BT_HS=y CONFIG_BT_LE=y CONFIG_BT_6LOWPAN=m CONFIG_BT_LEDS=y -# CONFIG_BT_SELFTEST is not set +# CONFIG_BT_MSFTEXT is not set # CONFIG_BT_DEBUGFS is not set +# CONFIG_BT_SELFTEST is not set # # Bluetooth device drivers @@ -2189,7 +2204,6 @@ CONFIG_TIFM_7XX1=m # CONFIG_DS1682 is not set # CONFIG_LATTICE_ECP3_CONFIG is not set CONFIG_SRAM=y -CONFIG_VEXPRESS_SYSCFG=y # CONFIG_PCI_ENDPOINT_TEST is not set CONFIG_XILINX_SDFEC=m CONFIG_MISC_RTSX=m @@ -2441,6 +2455,7 @@ CONFIG_MD_CLUSTER=m CONFIG_BCACHE=y # CONFIG_BCACHE_DEBUG is not set # CONFIG_BCACHE_CLOSURES_DEBUG is not set +# CONFIG_BCACHE_ASYNC_REGISTRAION is not set CONFIG_BLK_DEV_DM_BUILTIN=y CONFIG_BLK_DEV_DM=m # CONFIG_DM_DEBUG is not set @@ -2455,6 +2470,7 @@ CONFIG_DM_THIN_PROVISIONING=m CONFIG_DM_CACHE=m CONFIG_DM_CACHE_SMQ=m CONFIG_DM_WRITECACHE=m +# CONFIG_DM_EBS is not set CONFIG_DM_ERA=m CONFIG_DM_CLONE=m CONFIG_DM_MIRROR=m @@ -2464,6 +2480,7 @@ CONFIG_DM_ZERO=m CONFIG_DM_MULTIPATH=m CONFIG_DM_MULTIPATH_QL=m CONFIG_DM_MULTIPATH_ST=m +# CONFIG_DM_MULTIPATH_HST is not set CONFIG_DM_DELAY=m CONFIG_DM_DUST=m CONFIG_DM_UEVENT=y @@ -2834,6 +2851,7 @@ CONFIG_MDIO_CAVIUM=y # CONFIG_MDIO_GPIO is not set # CONFIG_MDIO_HISI_FEMAC is not set CONFIG_MDIO_I2C=m +# CONFIG_MDIO_IPQ4019 is not set CONFIG_MDIO_IPQ8064=m CONFIG_MDIO_MSCC_MIIM=m CONFIG_MDIO_MVUSB=m @@ -2858,6 +2876,7 @@ CONFIG_BCM7XXX_PHY=m CONFIG_BCM87XX_PHY=m CONFIG_BCM_NET_PHYLIB=m CONFIG_BROADCOM_PHY=m +# CONFIG_BCM54140_PHY is not set CONFIG_BCM84881_PHY=m CONFIG_CICADA_PHY=m # CONFIG_CORTINA_PHY is not set @@ -3083,7 +3102,10 @@ CONFIG_MT76x2_COMMON=m CONFIG_MT76x2E=m CONFIG_MT76x2U=m CONFIG_MT7603E=m +CONFIG_MT7615_COMMON=m CONFIG_MT7615E=m +# CONFIG_MT7663U is not set +# CONFIG_MT7915E is not set CONFIG_WLAN_VENDOR_RALINK=y CONFIG_RT2X00=m CONFIG_RT2400PCI=m @@ -3139,6 +3161,7 @@ CONFIG_RTL8XXXU=m CONFIG_RTW88=m # CONFIG_RTW88_8822BE is not set # CONFIG_RTW88_8822CE is not set +# CONFIG_RTW88_8723DE is not set CONFIG_WLAN_VENDOR_RSI=y CONFIG_RSI_91X=m # CONFIG_RSI_DEBUGFS is not set @@ -3165,6 +3188,7 @@ CONFIG_RTL8822BU=m CONFIG_RTL8188EU=m CONFIG_RTL8821CU=m CONFIG_88XXAU=m +# CONFIG_RTL8192EU is not set CONFIG_RTL8189FS=m CONFIG_RTL8189ES=m CONFIG_WLAN_VENDOR_ZYDAS=y @@ -3305,6 +3329,7 @@ CONFIG_TOUCHSCREEN_AUO_PIXCIR=m CONFIG_TOUCHSCREEN_BU21013=m CONFIG_TOUCHSCREEN_BU21029=m CONFIG_TOUCHSCREEN_CHIPONE_ICN8318=m +# CONFIG_TOUCHSCREEN_CY8CTMA140 is not set CONFIG_TOUCHSCREEN_CY8CTMG110=m CONFIG_TOUCHSCREEN_CYTTSP_CORE=m CONFIG_TOUCHSCREEN_CYTTSP_I2C=m @@ -3393,10 +3418,8 @@ CONFIG_INPUT_MISC=y # CONFIG_INPUT_ATMEL_CAPTOUCH is not set # CONFIG_INPUT_BMA150 is not set # CONFIG_INPUT_E3X0_BUTTON is not set -CONFIG_INPUT_MSM_VIBRATOR=m CONFIG_INPUT_MAX77650_ONKEY=m # CONFIG_INPUT_MMA8450 is not set -# CONFIG_INPUT_GP2A is not set CONFIG_INPUT_GPIO_BEEPER=m CONFIG_INPUT_GPIO_DECODER=m CONFIG_INPUT_GPIO_VIBRA=m @@ -3416,6 +3439,7 @@ CONFIG_INPUT_RK805_PWRKEY=y # CONFIG_INPUT_GPIO_ROTARY_ENCODER is not set # CONFIG_INPUT_ADXL34X is not set # CONFIG_INPUT_IMS_PCU is not set +# CONFIG_INPUT_IQS269A is not set # CONFIG_INPUT_CMA3000 is not set CONFIG_INPUT_XEN_KBDDEV_FRONTEND=y # CONFIG_INPUT_DRV260X_HAPTICS is not set @@ -3566,6 +3590,7 @@ CONFIG_HW_RANDOM=m # CONFIG_HW_RANDOM_VIRTIO is not set CONFIG_HW_RANDOM_MESON=m CONFIG_HW_RANDOM_CAVIUM=m +# CONFIG_HW_RANDOM_CCTRNG is not set # CONFIG_APPLICOM is not set CONFIG_DEVMEM=y # CONFIG_RAW_DRIVER is not set @@ -3634,8 +3659,8 @@ CONFIG_I2C_ALGOBIT=y CONFIG_I2C_CADENCE=m CONFIG_I2C_CBUS_GPIO=m CONFIG_I2C_DESIGNWARE_CORE=y -CONFIG_I2C_DESIGNWARE_PLATFORM=y # CONFIG_I2C_DESIGNWARE_SLAVE is not set +CONFIG_I2C_DESIGNWARE_PLATFORM=y # CONFIG_I2C_DESIGNWARE_PCI is not set # CONFIG_I2C_EMEV2 is not set # CONFIG_I2C_GPIO is not set @@ -3687,6 +3712,7 @@ CONFIG_SPI_AXI_SPI_ENGINE=m CONFIG_SPI_BITBANG=m CONFIG_SPI_CADENCE=m CONFIG_SPI_DESIGNWARE=m +# CONFIG_SPI_DW_DMA is not set CONFIG_SPI_DW_PCI=m CONFIG_SPI_DW_MMIO=m CONFIG_SPI_NXP_FLEXSPI=m @@ -3708,6 +3734,7 @@ CONFIG_SPI_MXIC=m # CONFIG_SPI_XCOMM is not set # CONFIG_SPI_XILINX is not set # CONFIG_SPI_ZYNQMP_GQSPI is not set +# CONFIG_SPI_AMD is not set # # SPI Multiplexer support @@ -3723,6 +3750,7 @@ CONFIG_SPI_TLE62X0=m CONFIG_SPI_SLAVE=y CONFIG_SPI_SLAVE_TIME=m CONFIG_SPI_SLAVE_SYSTEM_CONTROL=m +CONFIG_SPI_DYNAMIC=y CONFIG_SPMI=y # CONFIG_HSI is not set CONFIG_PPS=y @@ -3758,7 +3786,6 @@ CONFIG_GENERIC_PINCONF=y # CONFIG_DEBUG_PINCTRL is not set CONFIG_PINCTRL_AS3722=m CONFIG_PINCTRL_AXP209=m -# CONFIG_PINCTRL_AMD is not set # CONFIG_PINCTRL_MCP23S08 is not set CONFIG_PINCTRL_ROCKCHIP=y CONFIG_PINCTRL_SINGLE=y @@ -3795,7 +3822,6 @@ CONFIG_PINCTRL_MESON_AXG=y CONFIG_PINCTRL_MESON_AXG_PMX=y CONFIG_PINCTRL_MESON_G12A=y CONFIG_PINCTRL_MESON_A1=y -CONFIG_PINCTRL_EQUILIBRIUM=m CONFIG_GPIOLIB=y CONFIG_GPIOLIB_FASTPATH_LIMIT=512 CONFIG_OF_GPIO=y @@ -3880,6 +3906,7 @@ CONFIG_GPIO_XRA1403=m # # end of USB GPIO expanders +# CONFIG_GPIO_AGGREGATOR is not set CONFIG_GPIO_MOCKUP=m CONFIG_W1=m CONFIG_W1_CON=y @@ -3982,6 +4009,7 @@ CONFIG_BATTERY_RT5033=m # CONFIG_CHARGER_CROS_USBPD is not set CONFIG_CHARGER_UCS1002=m CONFIG_CHARGER_BD70528=m +# CONFIG_CHARGER_BD99954 is not set CONFIG_HWMON=y CONFIG_HWMON_VID=m # CONFIG_HWMON_DEBUG_CHIP is not set @@ -4100,6 +4128,7 @@ CONFIG_SENSORS_LTC2978=m CONFIG_SENSORS_LTC2978_REGULATOR=y CONFIG_SENSORS_LTC3815=m CONFIG_SENSORS_MAX16064=m +# CONFIG_SENSORS_MAX16601 is not set CONFIG_SENSORS_MAX20730=m CONFIG_SENSORS_MAX20751=m CONFIG_SENSORS_MAX31785=m @@ -4180,7 +4209,6 @@ CONFIG_DEVFREQ_THERMAL=y CONFIG_THERMAL_EMULATION=y CONFIG_THERMAL_MMIO=m # CONFIG_MAX77620_THERMAL is not set -# CONFIG_QORIQ_THERMAL is not set CONFIG_SUN8I_THERMAL=m CONFIG_ROCKCHIP_THERMAL=y CONFIG_AMLOGIC_THERMAL=y @@ -4216,6 +4244,7 @@ CONFIG_SUNXI_WATCHDOG=m # CONFIG_MAX77620_WATCHDOG is not set CONFIG_MESON_GXBB_WATCHDOG=m CONFIG_MESON_WATCHDOG=m +# CONFIG_ARM_SMC_WATCHDOG is not set # CONFIG_ALIM7101_WDT is not set # CONFIG_I6300ESB_WDT is not set # CONFIG_MEN_A21_WDT is not set @@ -4282,8 +4311,10 @@ CONFIG_MFD_CROS_EC_DEV=y # CONFIG_MFD_DA9063 is not set # CONFIG_MFD_DA9150 is not set # CONFIG_MFD_DLN2 is not set +# CONFIG_MFD_GATEWORKS_GSC is not set # CONFIG_MFD_MC13XXX_SPI is not set # CONFIG_MFD_MC13XXX_I2C is not set +# CONFIG_MFD_MP2629 is not set # CONFIG_MFD_HI6421_PMIC is not set # CONFIG_HTC_PASIC3 is not set # CONFIG_HTC_I2CPLD is not set @@ -4305,6 +4336,7 @@ CONFIG_MFD_MAX77650=m # CONFIG_MFD_MAX8925 is not set # CONFIG_MFD_MAX8997 is not set # CONFIG_MFD_MAX8998 is not set +# CONFIG_MFD_MT6360 is not set # CONFIG_MFD_MT6397 is not set # CONFIG_MFD_MENF21BMC is not set # CONFIG_EZX_PCAP is not set @@ -4403,6 +4435,7 @@ CONFIG_REGULATOR_MAX77650=m # CONFIG_REGULATOR_MAX8660 is not set # CONFIG_REGULATOR_MAX8952 is not set # CONFIG_REGULATOR_MAX8973 is not set +# CONFIG_REGULATOR_MAX77826 is not set CONFIG_REGULATOR_MCP16502=m CONFIG_REGULATOR_MP5416=m CONFIG_REGULATOR_MP8859=m @@ -4434,9 +4467,6 @@ CONFIG_REGULATOR_SY8824X=m # CONFIG_REGULATOR_TPS6524X is not set # CONFIG_REGULATOR_VCTRL is not set # CONFIG_REGULATOR_VEXPRESS is not set -CONFIG_CEC_CORE=m -CONFIG_CEC_NOTIFIER=y -CONFIG_CEC_PIN=y CONFIG_RC_CORE=m CONFIG_RC_MAP=m CONFIG_LIRC=y @@ -4474,26 +4504,48 @@ CONFIG_IR_SERIAL=m CONFIG_IR_SERIAL_TRANSMITTER=y CONFIG_IR_SIR=m CONFIG_RC_XBOX_DVD=m +CONFIG_CEC_CORE=m +CONFIG_CEC_NOTIFIER=y +CONFIG_CEC_PIN=y +CONFIG_MEDIA_CEC_RC=y +CONFIG_CEC_PIN_ERROR_INJ=y +CONFIG_MEDIA_CEC_SUPPORT=y +# CONFIG_CEC_CROS_EC is not set +# CONFIG_CEC_MESON_AO is not set +# CONFIG_CEC_MESON_G12A_AO is not set +# CONFIG_CEC_GPIO is not set +CONFIG_USB_PULSE8_CEC=m +CONFIG_USB_RAINSHADOW_CEC=m CONFIG_MEDIA_SUPPORT=m +# CONFIG_MEDIA_SUPPORT_FILTER is not set +CONFIG_MEDIA_SUBDRV_AUTOSELECT=y # -# Multimedia core support +# Media device types # CONFIG_MEDIA_CAMERA_SUPPORT=y CONFIG_MEDIA_ANALOG_TV_SUPPORT=y CONFIG_MEDIA_DIGITAL_TV_SUPPORT=y CONFIG_MEDIA_RADIO_SUPPORT=y CONFIG_MEDIA_SDR_SUPPORT=y -CONFIG_MEDIA_CEC_SUPPORT=y -CONFIG_MEDIA_CEC_RC=y -CONFIG_CEC_PIN_ERROR_INJ=y -CONFIG_MEDIA_CONTROLLER=y -CONFIG_MEDIA_CONTROLLER_DVB=y -CONFIG_MEDIA_CONTROLLER_REQUEST_API=y +CONFIG_MEDIA_PLATFORM_SUPPORT=y +CONFIG_MEDIA_TEST_SUPPORT=y +# end of Media device types + +# +# Media core support +# CONFIG_VIDEO_DEV=m -CONFIG_VIDEO_V4L2_SUBDEV_API=y +CONFIG_MEDIA_CONTROLLER=y +CONFIG_DVB_CORE=m +# end of Media core support + +# +# Video4Linux options +# CONFIG_VIDEO_V4L2=m CONFIG_VIDEO_V4L2_I2C=y +CONFIG_VIDEO_V4L2_SUBDEV_API=y # CONFIG_VIDEO_ADV_DEBUG is not set CONFIG_VIDEO_FIXED_MINOR_RANGES=y CONFIG_VIDEO_TUNER=m @@ -4502,18 +4554,34 @@ CONFIG_V4L2_MEM2MEM_DEV=m CONFIG_V4L2_FWNODE=m CONFIG_VIDEOBUF_GEN=m CONFIG_VIDEOBUF_VMALLOC=m -CONFIG_DVB_CORE=m +# end of Video4Linux options + +# +# Media controller options +# +CONFIG_MEDIA_CONTROLLER_DVB=y +CONFIG_MEDIA_CONTROLLER_REQUEST_API=y + +# +# Please notice that the enabled Media controller Request API is EXPERIMENTAL +# +# end of Media controller options + +# +# Digital TV options +# CONFIG_DVB_MMAP=y CONFIG_DVB_NET=y -CONFIG_TTPCI_EEPROM=m CONFIG_DVB_MAX_ADAPTERS=8 CONFIG_DVB_DYNAMIC_MINORS=y # CONFIG_DVB_DEMUX_SECTION_LOSS_LOG is not set # CONFIG_DVB_ULE_DEBUG is not set +# end of Digital TV options # # Media drivers # +CONFIG_TTPCI_EEPROM=m CONFIG_MEDIA_USB_SUPPORT=y # @@ -4676,29 +4744,7 @@ CONFIG_VIDEO_EM28XX_RC=m CONFIG_USB_AIRSPY=m CONFIG_USB_HACKRF=m CONFIG_USB_MSI2500=m - -# -# USB HDMI CEC adapters -# -CONFIG_USB_PULSE8_CEC=m -CONFIG_USB_RAINSHADOW_CEC=m # CONFIG_MEDIA_PCI_SUPPORT is not set -# CONFIG_V4L_PLATFORM_DRIVERS is not set -CONFIG_V4L_MEM2MEM_DRIVERS=y -# CONFIG_VIDEO_MEM2MEM_DEINTERLACE is not set -# CONFIG_VIDEO_SH_VEU is not set -CONFIG_VIDEO_ROCKCHIP_RGA=m -CONFIG_VIDEO_SUN8I_DEINTERLACE=m -CONFIG_VIDEO_SUN8I_ROTATE=m -# CONFIG_V4L_TEST_DRIVERS is not set -CONFIG_DVB_PLATFORM_DRIVERS=y -# CONFIG_CEC_PLATFORM_DRIVERS is not set -CONFIG_SDR_PLATFORM_DRIVERS=y - -# -# Supported MMC/SDIO adapters -# -CONFIG_SMS_SDIO_DRV=m CONFIG_RADIO_ADAPTERS=y CONFIG_RADIO_TEA575X=m CONFIG_RADIO_SI470X=m @@ -4720,12 +4766,6 @@ CONFIG_RADIO_TEA5764=m CONFIG_RADIO_SAA7706H=m CONFIG_RADIO_TEF6862=m CONFIG_RADIO_WL1273=m - -# -# Texas Instruments WL128x FM driver (ST based) -# -# end of Texas Instruments WL128x FM driver (ST based) - CONFIG_MEDIA_COMMON_OPTIONS=y # @@ -4744,17 +4784,31 @@ CONFIG_DVB_B2C2_FLEXCOP=m CONFIG_SMS_SIANO_MDTV=m CONFIG_SMS_SIANO_RC=y # CONFIG_SMS_SIANO_DEBUGFS is not set +# CONFIG_V4L_PLATFORM_DRIVERS is not set +CONFIG_V4L_MEM2MEM_DRIVERS=y +# CONFIG_VIDEO_MEM2MEM_DEINTERLACE is not set +CONFIG_VIDEO_ROCKCHIP_RGA=m +CONFIG_VIDEO_SUN8I_DEINTERLACE=m +CONFIG_VIDEO_SUN8I_ROTATE=m +CONFIG_DVB_PLATFORM_DRIVERS=y +CONFIG_SDR_PLATFORM_DRIVERS=y # -# Media ancillary drivers (tuners, sensors, i2c, spi, frontends) +# MMC/SDIO DVB adapters +# +CONFIG_SMS_SDIO_DRV=m +# CONFIG_V4L_TEST_DRIVERS is not set +# end of Media drivers + +# +# Media ancillary drivers # -CONFIG_MEDIA_SUBDRV_AUTOSELECT=y CONFIG_MEDIA_ATTACH=y -CONFIG_VIDEO_IR_I2C=m # -# I2C Encoders, decoders, sensors and other helper chips +# IR I2C driver auto-selected by 'Autoselect ancillary drivers' # +CONFIG_VIDEO_IR_I2C=m # # Audio decoders, processors and mixers @@ -4775,11 +4829,13 @@ CONFIG_VIDEO_WM8775=m CONFIG_VIDEO_WM8739=m CONFIG_VIDEO_VP27SMPX=m CONFIG_VIDEO_SONY_BTF_MPX=m +# end of Audio decoders, processors and mixers # # RDS decoders # CONFIG_VIDEO_SAA6588=m +# end of RDS decoders # # Video decoders @@ -4814,6 +4870,7 @@ CONFIG_VIDEO_VPX3220=m # CONFIG_VIDEO_SAA717X=m CONFIG_VIDEO_CX25840=m +# end of Video decoders # # Video encoders @@ -4827,6 +4884,35 @@ CONFIG_VIDEO_ADV7393=m CONFIG_VIDEO_AD9389B=m CONFIG_VIDEO_AK881X=m CONFIG_VIDEO_THS8200=m +# end of Video encoders + +# +# Video improvement chips +# +CONFIG_VIDEO_UPD64031A=m +CONFIG_VIDEO_UPD64083=m +# end of Video improvement chips + +# +# Audio/Video compression chips +# +CONFIG_VIDEO_SAA6752HS=m +# end of Audio/Video compression chips + +# +# SDR tuner chips +# +CONFIG_SDR_MAX2175=m +# end of SDR tuner chips + +# +# Miscellaneous helper chips +# +CONFIG_VIDEO_THS7303=m +CONFIG_VIDEO_M52790=m +CONFIG_VIDEO_I2C=m +CONFIG_VIDEO_ST_MIPID02=m +# end of Miscellaneous helper chips # # Camera sensor devices @@ -4845,6 +4931,7 @@ CONFIG_VIDEO_OV2640=m CONFIG_VIDEO_OV2659=m CONFIG_VIDEO_OV2680=m CONFIG_VIDEO_OV2685=m +# CONFIG_VIDEO_OV2740 is not set CONFIG_VIDEO_OV5640=m CONFIG_VIDEO_OV5645=m CONFIG_VIDEO_OV5647=m @@ -4882,6 +4969,7 @@ CONFIG_VIDEO_S5K5BAF=m CONFIG_VIDEO_SMIAPP=m CONFIG_VIDEO_ET8EK8=m CONFIG_VIDEO_S5C73M3=m +# end of Camera sensor devices # # Lens drivers @@ -4890,6 +4978,7 @@ CONFIG_VIDEO_AD5820=m CONFIG_VIDEO_AK7375=m CONFIG_VIDEO_DW9714=m CONFIG_VIDEO_DW9807_VCM=m +# end of Lens drivers # # Flash devices @@ -4897,31 +4986,7 @@ CONFIG_VIDEO_DW9807_VCM=m CONFIG_VIDEO_ADP1653=m CONFIG_VIDEO_LM3560=m CONFIG_VIDEO_LM3646=m - -# -# Video improvement chips -# -CONFIG_VIDEO_UPD64031A=m -CONFIG_VIDEO_UPD64083=m - -# -# Audio/Video compression chips -# -CONFIG_VIDEO_SAA6752HS=m - -# -# SDR tuner chips -# -CONFIG_SDR_MAX2175=m - -# -# Miscellaneous helper chips -# -CONFIG_VIDEO_THS7303=m -CONFIG_VIDEO_M52790=m -CONFIG_VIDEO_I2C=m -CONFIG_VIDEO_ST_MIPID02=m -# end of I2C Encoders, decoders, sensors and other helper chips +# end of Flash devices # # SPI helper chips @@ -5142,12 +5207,13 @@ CONFIG_DVB_HELENE=m # CONFIG_DVB_CXD2099=m CONFIG_DVB_SP2=m +# end of Customise DVB Frontends # # Tools to develop new frontends # CONFIG_DVB_DUMMY_FE=m -# end of Customise DVB Frontends +# end of Media ancillary drivers # # Graphics support @@ -5211,7 +5277,6 @@ CONFIG_ROCKCHIP_LVDS=y # CONFIG_DRM_UDL is not set # CONFIG_DRM_AST is not set # CONFIG_DRM_MGAG200 is not set -# CONFIG_DRM_CIRRUS_QEMU is not set # CONFIG_DRM_RCAR_DW_HDMI is not set CONFIG_DRM_RCAR_LVDS=m CONFIG_DRM_RCAR_WRITEBACK=y @@ -5232,6 +5297,7 @@ CONFIG_DRM_PANEL=y # Display Panels # CONFIG_DRM_PANEL_ARM_VERSATILE=m +# CONFIG_DRM_PANEL_ASUS_Z00T_TM5P5_NT35596 is not set CONFIG_DRM_PANEL_BOE_HIMAX8279D=m CONFIG_DRM_PANEL_BOE_TV101WUM_NL6=m CONFIG_DRM_PANEL_LVDS=m @@ -5244,6 +5310,7 @@ CONFIG_DRM_PANEL_ILITEK_ILI9881C=m CONFIG_DRM_PANEL_INNOLUX_P079ZCA=m CONFIG_DRM_PANEL_JDI_LT070ME05000=m CONFIG_DRM_PANEL_KINGDISPLAY_KD097D04=m +# CONFIG_DRM_PANEL_LEADTEK_LTK050H3146W is not set CONFIG_DRM_PANEL_LEADTEK_LTK500HD1829=m # CONFIG_DRM_PANEL_SAMSUNG_LD9040 is not set CONFIG_DRM_PANEL_LG_LB035Q02=m @@ -5278,6 +5345,7 @@ CONFIG_DRM_PANEL_TPO_TD028TTEC1=m CONFIG_DRM_PANEL_TPO_TD043MTEA1=m CONFIG_DRM_PANEL_TPO_TPG110=m CONFIG_DRM_PANEL_TRULY_NT35597_WQXGA=m +# CONFIG_DRM_PANEL_VISIONOX_RM69299 is not set CONFIG_DRM_PANEL_XINPENG_XPP055C272=m # end of Display Panels @@ -5288,9 +5356,11 @@ CONFIG_DRM_PANEL_BRIDGE=y # Display Interface Bridges # CONFIG_DRM_CDNS_DSI=m +# CONFIG_DRM_CHRONTEL_CH7033 is not set CONFIG_DRM_DISPLAY_CONNECTOR=m CONFIG_DRM_LVDS_CODEC=m # CONFIG_DRM_MEGACHIPS_STDPXXXX_GE_B850V3_FW is not set +# CONFIG_DRM_NWL_MIPI_DSI is not set # CONFIG_DRM_NXP_PTN3460 is not set # CONFIG_DRM_PARADE_PS8622 is not set CONFIG_DRM_PARADE_PS8640=m @@ -5326,6 +5396,7 @@ CONFIG_DRM_HISI_KIRIN=m # CONFIG_DRM_MXSFB is not set CONFIG_DRM_MESON=m CONFIG_DRM_MESON_DW_HDMI=m +# CONFIG_DRM_CIRRUS_QEMU is not set CONFIG_DRM_GM12U320=m CONFIG_TINYDRM_HX8357D=m CONFIG_TINYDRM_ILI9225=m @@ -5752,6 +5823,7 @@ CONFIG_SND_SOC_MAX98357A=m CONFIG_SND_SOC_MAX9867=m # CONFIG_SND_SOC_MAX98927 is not set CONFIG_SND_SOC_MAX98373=m +# CONFIG_SND_SOC_MAX98390 is not set # CONFIG_SND_SOC_MAX9860 is not set # CONFIG_SND_SOC_MSM8916_WCD_ANALOG is not set # CONFIG_SND_SOC_MSM8916_WCD_DIGITAL is not set @@ -5840,6 +5912,7 @@ CONFIG_SND_SOC_WM8962=m CONFIG_SND_SOC_WM8974=m CONFIG_SND_SOC_WM8978=m CONFIG_SND_SOC_WM8985=m +# CONFIG_SND_SOC_ZL38060 is not set CONFIG_SND_SOC_ZX_AUD96P22=m CONFIG_SND_SOC_MAX9759=m CONFIG_SND_SOC_MT6351=m @@ -6029,6 +6102,7 @@ CONFIG_USB_MON=m CONFIG_USB_XHCI_HCD=y # CONFIG_USB_XHCI_DBGCAP is not set CONFIG_USB_XHCI_PCI=y +# CONFIG_USB_XHCI_PCI_RENESAS is not set CONFIG_USB_XHCI_PLATFORM=y CONFIG_USB_EHCI_HCD=y CONFIG_USB_EHCI_ROOT_HUB_TT=y @@ -6122,10 +6196,13 @@ CONFIG_USB_DWC2_PCI=m # CONFIG_USB_DWC2_DEBUG is not set # CONFIG_USB_DWC2_TRACK_MISSED_SOFS is not set CONFIG_USB_CHIPIDEA=y -CONFIG_USB_CHIPIDEA_OF=y -CONFIG_USB_CHIPIDEA_PCI=y CONFIG_USB_CHIPIDEA_UDC=y CONFIG_USB_CHIPIDEA_HOST=y +CONFIG_USB_CHIPIDEA_PCI=y +CONFIG_USB_CHIPIDEA_MSM=y +CONFIG_USB_CHIPIDEA_IMX=y +CONFIG_USB_CHIPIDEA_GENERIC=y +CONFIG_USB_CHIPIDEA_TEGRA=y CONFIG_USB_ISP1760=y CONFIG_USB_ISP1760_HCD=y CONFIG_USB_ISP1761_UDC=y @@ -6433,6 +6510,7 @@ CONFIG_LEDS_CLASS=y # LED drivers # CONFIG_LEDS_AN30259A=m +# CONFIG_LEDS_AW2013 is not set # CONFIG_LEDS_BCM6328 is not set # CONFIG_LEDS_BCM6358 is not set CONFIG_LEDS_CR0014114=m @@ -6720,7 +6798,6 @@ CONFIG_VDPA_SIM=m CONFIG_IFCVF=m CONFIG_VHOST_IOTLB=m CONFIG_VHOST_RING=m -CONFIG_VHOST_DPN=y CONFIG_VHOST=m CONFIG_VHOST_MENU=y CONFIG_VHOST_NET=m @@ -6933,16 +7010,10 @@ CONFIG_CROS_EC_SYSFS=y CONFIG_CROS_EC_TYPEC=m CONFIG_CROS_USBPD_NOTIFY=y # CONFIG_MELLANOX_PLATFORM is not set +CONFIG_HAVE_CLK=y CONFIG_CLKDEV_LOOKUP=y CONFIG_HAVE_CLK_PREPARE=y CONFIG_COMMON_CLK=y - -# -# Common Clock Framework -# -CONFIG_COMMON_CLK_VERSATILE=y -CONFIG_CLK_SP810=y -CONFIG_CLK_VEXPRESS_OSC=y # CONFIG_CLK_HSDK is not set # CONFIG_COMMON_CLK_MAX77686 is not set # CONFIG_COMMON_CLK_MAX9485 is not set @@ -6990,8 +7061,6 @@ CONFIG_SUN8I_A83T_CCU=y CONFIG_SUN8I_H3_CCU=y CONFIG_SUN8I_DE2_CCU=y CONFIG_SUN8I_R_CCU=y -# end of Common Clock Framework - # CONFIG_HWSPINLOCK is not set # @@ -7008,7 +7077,6 @@ CONFIG_FSL_ERRATUM_A008585=y CONFIG_HISILICON_ERRATUM_161010101=y CONFIG_ARM64_ERRATUM_858921=y CONFIG_SUN50I_ERRATUM_UNKNOWN1=y -CONFIG_CLKSRC_VERSATILE=y # CONFIG_MICROCHIP_PIT64B is not set # end of Clock Source drivers @@ -7038,6 +7106,7 @@ CONFIG_IOMMU_IO_PGTABLE_LPAE=y CONFIG_OF_IOMMU=y CONFIG_IOMMU_DMA=y CONFIG_ROCKCHIP_IOMMU=y +# CONFIG_SUN50I_IOMMU is not set CONFIG_ARM_SMMU=y # CONFIG_ARM_SMMU_LEGACY_DT_BINDINGS is not set CONFIG_ARM_SMMU_DISABLE_BYPASS_BY_DEFAULT=y @@ -7234,6 +7303,8 @@ CONFIG_AD7887=m CONFIG_AD7923=m CONFIG_AD7949=m CONFIG_AD799X=m +# CONFIG_AD9467 is not set +# CONFIG_ADI_AXI_ADC is not set CONFIG_AXP20X_ADC=m CONFIG_AXP288_ADC=m # CONFIG_CC10001_ADC is not set @@ -7248,6 +7319,7 @@ CONFIG_LTC2496=m # CONFIG_MAX1027 is not set # CONFIG_MAX11100 is not set # CONFIG_MAX1118 is not set +# CONFIG_MAX1241 is not set # CONFIG_MAX1363 is not set # CONFIG_MAX9611 is not set # CONFIG_MCP320X is not set @@ -7296,6 +7368,7 @@ CONFIG_HMC425=m # Chemical Sensors # # CONFIG_ATLAS_PH_SENSOR is not set +# CONFIG_ATLAS_EZO_SENSOR is not set CONFIG_BME680=m CONFIG_BME680_I2C=m CONFIG_BME680_SPI=m @@ -7451,6 +7524,7 @@ CONFIG_SI7020=m # # CONFIG_ADIS16400 is not set CONFIG_ADIS16460=m +# CONFIG_ADIS16475 is not set # CONFIG_ADIS16480 is not set # CONFIG_BMI160_I2C is not set # CONFIG_BMI160_SPI is not set @@ -7631,8 +7705,10 @@ CONFIG_MB1232=m CONFIG_PING=m # CONFIG_RFD77402 is not set # CONFIG_SRF04 is not set +# CONFIG_SX9310 is not set # CONFIG_SX9500 is not set # CONFIG_SRF08 is not set +# CONFIG_VCNL3020 is not set CONFIG_VL53L0X_I2C=m # end of Proximity and distance sensors @@ -7666,6 +7742,7 @@ CONFIG_PWM_SYSFS=y # CONFIG_PWM_DEBUG is not set CONFIG_PWM_CROS_EC=m # CONFIG_PWM_FSL_FTM is not set +# CONFIG_PWM_IQS620A is not set CONFIG_PWM_MESON=m # CONFIG_PWM_PCA9685 is not set CONFIG_PWM_ROCKCHIP=y @@ -7709,7 +7786,6 @@ CONFIG_PHY_SUN9I_USB=m CONFIG_PHY_SUN50I_USB3=m CONFIG_PHY_MESON8B_USB2=m CONFIG_PHY_MESON_GXL_USB2=m -CONFIG_PHY_MESON_GXL_USB3=m CONFIG_PHY_MESON_G12A_USB2=m CONFIG_PHY_MESON_G12A_USB3_PCIE=m CONFIG_PHY_MESON_AXG_PCIE=y @@ -7718,6 +7794,7 @@ CONFIG_PHY_MESON_AXG_MIPI_PCIE_ANALOG=y CONFIG_PHY_CADENCE_TORRENT=m CONFIG_PHY_CADENCE_DPHY=m CONFIG_PHY_CADENCE_SIERRA=m +# CONFIG_PHY_CADENCE_SALVO is not set CONFIG_PHY_FSL_IMX8MQ_USB=m CONFIG_PHY_MIXEL_MIPI_DPHY=m # CONFIG_PHY_PXA_28NM_HSIC is not set @@ -7738,7 +7815,6 @@ CONFIG_PHY_ROCKCHIP_TYPEC=y CONFIG_PHY_ROCKCHIP_USB=y CONFIG_PHY_SAMSUNG_USB2=y # CONFIG_PHY_TUSB1210 is not set -CONFIG_PHY_INTEL_EMMC=m # end of PHY Subsystem # CONFIG_POWERCAP is not set @@ -7757,6 +7833,7 @@ CONFIG_ARM_PMU=y # end of Performance monitor support CONFIG_RAS=y +# CONFIG_USB4 is not set # # Android @@ -7801,7 +7878,7 @@ CONFIG_MUX_MMIO=m CONFIG_PM_OPP=y # CONFIG_SIOX is not set # CONFIG_SLIMBUS is not set -CONFIG_INTERCONNECT=m +# CONFIG_INTERCONNECT is not set CONFIG_COUNTER=m CONFIG_FTM_QUADDEC=m CONFIG_MOST=m @@ -8042,6 +8119,7 @@ CONFIG_PSTORE_COMPRESS_DEFAULT="deflate" # CONFIG_PSTORE_CONSOLE is not set # CONFIG_PSTORE_PMSG is not set CONFIG_PSTORE_RAM=m +# CONFIG_PSTORE_BLK is not set CONFIG_SYSV_FS=m CONFIG_UFS_FS=m CONFIG_UFS_FS_WRITE=y @@ -8202,7 +8280,6 @@ CONFIG_IO_WQ=y CONFIG_KEYS=y CONFIG_KEYS_REQUEST_CACHE=y CONFIG_PERSISTENT_KEYRINGS=y -CONFIG_BIG_KEYS=y CONFIG_ENCRYPTED_KEYS=y CONFIG_KEY_DH_OPERATIONS=y # CONFIG_SECURITY_DMESG_RESTRICT is not set @@ -8488,10 +8565,6 @@ CONFIG_CRYPTO_DEV_VIRTIO=m CONFIG_CRYPTO_DEV_SAFEXCEL=m CONFIG_CRYPTO_DEV_CCREE=m CONFIG_CRYPTO_DEV_HISI_SEC=m -CONFIG_CRYPTO_DEV_HISI_SEC2=m -CONFIG_CRYPTO_DEV_HISI_QM=m -CONFIG_CRYPTO_DEV_HISI_ZIP=m -CONFIG_CRYPTO_DEV_HISI_HPRE=m CONFIG_CRYPTO_DEV_AMLOGIC_GXL=y CONFIG_CRYPTO_DEV_AMLOGIC_GXL_DEBUG=y CONFIG_ASYMMETRIC_KEY_TYPE=y @@ -8522,6 +8595,7 @@ CONFIG_BINARY_PRINTF=y # CONFIG_RAID6_PQ=y CONFIG_RAID6_PQ_BENCHMARK=y +CONFIG_LINEAR_RANGES=y CONFIG_PACKING=y CONFIG_BITREVERSE=y CONFIG_HAVE_ARCH_BITREVERSE=y @@ -8529,10 +8603,12 @@ CONFIG_GENERIC_STRNCPY_FROM_USER=y CONFIG_GENERIC_STRNLEN_USER=y CONFIG_GENERIC_NET_UTILS=y CONFIG_CORDIC=m +# CONFIG_PRIME_NUMBERS is not set CONFIG_RATIONAL=y CONFIG_GENERIC_PCI_IOMAP=y CONFIG_ARCH_USE_CMPXCHG_LOCKREF=y CONFIG_ARCH_HAS_FAST_MULTIPLIER=y +CONFIG_ARCH_USE_SYM_ANNOTATIONS=y # CONFIG_INDIRECT_PIO is not set CONFIG_CRC_CCITT=y CONFIG_CRC16=y @@ -8607,6 +8683,7 @@ CONFIG_ARCH_HAS_SYNC_DMA_FOR_CPU=y CONFIG_ARCH_HAS_DMA_PREP_COHERENT=y CONFIG_SWIOTLB=y CONFIG_DMA_NONCOHERENT_MMAP=y +CONFIG_DMA_COHERENT_POOL=y CONFIG_DMA_REMAP=y CONFIG_DMA_DIRECT_REMAP=y CONFIG_DMA_CMA=y @@ -8672,6 +8749,7 @@ CONFIG_CONSOLE_LOGLEVEL_QUIET=4 CONFIG_MESSAGE_LOGLEVEL_DEFAULT=4 # CONFIG_BOOT_PRINTK_DELAY is not set CONFIG_DYNAMIC_DEBUG=y +CONFIG_DYNAMIC_DEBUG_CORE=y CONFIG_SYMBOLIC_ERRNAME=y CONFIG_DEBUG_BUGVERBOSE=y # end of printk and dmesg options @@ -8718,6 +8796,8 @@ CONFIG_DEBUG_MISC=y # CONFIG_PAGE_POISONING is not set # CONFIG_DEBUG_PAGE_REF is not set # CONFIG_DEBUG_RODATA_TEST is not set +CONFIG_ARCH_HAS_DEBUG_WX=y +# CONFIG_DEBUG_WX is not set CONFIG_GENERIC_PTDUMP=y # CONFIG_PTDUMP_DEBUGFS is not set # CONFIG_DEBUG_OBJECTS is not set @@ -8727,7 +8807,9 @@ CONFIG_HAVE_DEBUG_KMEMLEAK=y # CONFIG_DEBUG_KMEMLEAK is not set # CONFIG_DEBUG_STACK_USAGE is not set # CONFIG_SCHED_STACK_END_CHECK is not set +CONFIG_ARCH_HAS_DEBUG_VM_PGTABLE=y # CONFIG_DEBUG_VM is not set +# CONFIG_DEBUG_VM_PGTABLE is not set CONFIG_ARCH_HAS_DEBUG_VIRTUAL=y # CONFIG_DEBUG_VIRTUAL is not set CONFIG_DEBUG_MEMORY_INIT=y @@ -8735,6 +8817,7 @@ CONFIG_DEBUG_MEMORY_INIT=y CONFIG_HAVE_ARCH_KASAN=y CONFIG_HAVE_ARCH_KASAN_SW_TAGS=y CONFIG_CC_HAS_KASAN_GENERIC=y +CONFIG_CC_HAS_WORKING_NOSANITIZE_ADDRESS=y # CONFIG_KASAN is not set CONFIG_KASAN_STACK=1 # end of Memory Debugging @@ -8832,7 +8915,6 @@ CONFIG_FTRACE=y # CONFIG_BOOTTIME_TRACING is not set # CONFIG_FUNCTION_TRACER is not set # CONFIG_STACK_TRACER is not set -# CONFIG_PREEMPTIRQ_EVENTS is not set # CONFIG_IRQSOFF_TRACER is not set # CONFIG_PREEMPT_TRACER is not set # CONFIG_SCHED_TRACER is not set @@ -8847,6 +8929,7 @@ CONFIG_UPROBE_EVENTS=y CONFIG_BPF_EVENTS=y CONFIG_DYNAMIC_EVENTS=y CONFIG_PROBE_EVENTS=y +# CONFIG_SYNTH_EVENTS is not set # CONFIG_HIST_TRIGGERS is not set # CONFIG_TRACE_EVENT_INJECT is not set # CONFIG_TRACEPOINT_BENCHMARK is not set @@ -8863,8 +8946,6 @@ CONFIG_STRICT_DEVMEM=y # arm64 Debugging # # CONFIG_PID_IN_CONTEXTIDR is not set -# CONFIG_ARM64_RANDOMIZE_TEXT_OFFSET is not set -# CONFIG_DEBUG_WX is not set # CONFIG_ARM64_RELOC_TEST is not set # CONFIG_CORESIGHT is not set # end of arm64 Debugging @@ -8876,6 +8957,7 @@ CONFIG_KUNIT=m # CONFIG_KUNIT_DEBUGFS is not set # CONFIG_KUNIT_TEST is not set # CONFIG_KUNIT_EXAMPLE_TEST is not set +# CONFIG_KUNIT_ALL_TESTS is not set # CONFIG_NOTIFIER_ERROR_INJECTION is not set # CONFIG_FAULT_INJECTION is not set CONFIG_ARCH_HAS_KCOV=y @@ -8907,6 +8989,7 @@ CONFIG_TEST_XARRAY=m # CONFIG_TEST_HASH is not set # CONFIG_TEST_IDA is not set # CONFIG_TEST_LKM is not set +# CONFIG_TEST_BITOPS is not set CONFIG_TEST_VMALLOC=m # CONFIG_TEST_USER_COPY is not set CONFIG_TEST_BPF=m @@ -8916,6 +8999,7 @@ CONFIG_TEST_BLACKHOLE_DEV=m # CONFIG_TEST_SYSCTL is not set # CONFIG_SYSCTL_KUNIT_TEST is not set # CONFIG_LIST_KUNIT_TEST is not set +# CONFIG_LINEAR_RANGES_TEST is not set # CONFIG_TEST_UDELAY is not set # CONFIG_TEST_STATIC_KEYS is not set # CONFIG_TEST_KMOD is not set diff --git a/config/sources/families/include/rockchip64_common.inc b/config/sources/families/include/rockchip64_common.inc index 7c0c1e930c..a5a1080d8e 100644 --- a/config/sources/families/include/rockchip64_common.inc +++ b/config/sources/families/include/rockchip64_common.inc @@ -68,7 +68,7 @@ case $BRANCH in current) KERNELPATCHDIR='rockchip64-'$BRANCH - KERNELBRANCH="branch:linux-5.7.y" + KERNELBRANCH="branch:linux-5.8.y" LINUXFAMILY=rockchip64 LINUXCONFIG='linux-rockchip64-'$BRANCH diff --git a/patch/kernel/rockchip64-current/0009-drivers-power-supply-Add-support-for-cw2015.patch b/patch/kernel/rockchip64-current/0009-drivers-power-supply-Add-support-for-cw2015.patch deleted file mode 100644 index 0222e8c023..0000000000 --- a/patch/kernel/rockchip64-current/0009-drivers-power-supply-Add-support-for-cw2015.patch +++ /dev/null @@ -1,909 +0,0 @@ -From bafb1b58516e5794cfb4533309492dca2b56c522 Mon Sep 17 00:00:00 2001 -From: Dan Johansen -Date: Sat, 30 May 2020 10:53:56 +0200 -Subject: [PATCH] drivers/power/supply Add support for cw2015 - ---- - .../bindings/power/supply/cw2015_battery.yaml | 83 ++ - .../devicetree/bindings/vendor-prefixes.yaml | 2 + - drivers/power/supply/Kconfig | 11 + - drivers/power/supply/Makefile | 1 + - drivers/power/supply/cw2015-battery.c | 749 ++++++++++++++++++ - 5 files changed, 846 insertions(+) - create mode 100644 Documentation/devicetree/bindings/power/supply/cw2015_battery.yaml - create mode 100644 drivers/power/supply/cw2015-battery.c - -diff --git a/Documentation/devicetree/bindings/power/supply/cw2015_battery.yaml b/Documentation/devicetree/bindings/power/supply/cw2015_battery.yaml -new file mode 100644 -index 000000000000..0c0181ae27c9 ---- /dev/null -+++ b/Documentation/devicetree/bindings/power/supply/cw2015_battery.yaml -@@ -0,0 +1,83 @@ -+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) -+%YAML 1.2 -+--- -+$id: http://devicetree.org/schemas/power/supply/cw2015_battery.yaml# -+$schema: http://devicetree.org/meta-schemas/core.yaml# -+ -+title: Battery driver for CW2015 shuntless fuel gauge by CellWise. -+ -+maintainers: -+ - Tobias Schramm -+ -+description: | -+ The driver can utilize information from a simple-battery linked via a -+ phandle in monitored-battery. If specified the driver uses the -+ charge-full-design-microamp-hours property of the battery. -+ -+properties: -+ compatible: -+ const: cellwise,cw2015 -+ -+ reg: -+ maxItems: 1 -+ -+ cellwise,battery-profile: -+ description: | -+ This property specifies characteristics of the battery used. The format -+ of this binary blob is kept secret by CellWise. The only way to obtain -+ it is to mail two batteries to a test facility of CellWise and receive -+ back a test report with the binary blob. -+ allOf: -+ - $ref: /schemas/types.yaml#definitions/uint8-array -+ items: -+ - minItems: 64 -+ maxItems: 64 -+ -+ cellwise,monitor-interval-ms: -+ description: -+ Specifies the interval in milliseconds gauge values are polled at -+ minimum: 250 -+ -+ power-supplies: -+ description: -+ Specifies supplies used for charging the battery connected to this gauge -+ allOf: -+ - $ref: /schemas/types.yaml#/definitions/phandle-array -+ - minItems: 1 -+ maxItems: 8 # Should be enough -+ -+ monitored-battery: -+ description: -+ Specifies the phandle of a simple-battery connected to this gauge -+ $ref: /schemas/types.yaml#/definitions/phandle -+ -+required: -+ - compatible -+ - reg -+ -+examples: -+ - | -+ i2c { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ -+ cw2015@62 { -+ compatible = "cellwise,cw201x"; -+ reg = <0x62>; -+ cellwise,battery-profile = /bits/ 8 < -+ 0x17 0x67 0x80 0x73 0x6E 0x6C 0x6B 0x63 -+ 0x77 0x51 0x5C 0x58 0x50 0x4C 0x48 0x36 -+ 0x15 0x0C 0x0C 0x19 0x5B 0x7D 0x6F 0x69 -+ 0x69 0x5B 0x0C 0x29 0x20 0x40 0x52 0x59 -+ 0x57 0x56 0x54 0x4F 0x3B 0x1F 0x7F 0x17 -+ 0x06 0x1A 0x30 0x5A 0x85 0x93 0x96 0x2D -+ 0x48 0x77 0x9C 0xB3 0x80 0x52 0x94 0xCB -+ 0x2F 0x00 0x64 0xA5 0xB5 0x11 0xF0 0x11 -+ >; -+ cellwise,monitor-interval-ms = <5000>; -+ monitored-battery = <&bat>; -+ power-supplies = <&mains_charger>, <&usb_charger>; -+ }; -+ }; -+ -+ -diff --git a/Documentation/devicetree/bindings/vendor-prefixes.yaml b/Documentation/devicetree/bindings/vendor-prefixes.yaml -index d3891386d671..58cf4e8b8d56 100644 ---- a/Documentation/devicetree/bindings/vendor-prefixes.yaml -+++ b/Documentation/devicetree/bindings/vendor-prefixes.yaml -@@ -179,6 +179,8 @@ patternProperties: - description: Cadence Design Systems Inc. - "^cdtech,.*": - description: CDTech(H.K.) Electronics Limited -+ "^cellwise,.*": -+ description: CellWise Microelectronics Co., Ltd - "^ceva,.*": - description: Ceva, Inc. - "^chipidea,.*": -diff --git a/drivers/power/supply/Kconfig b/drivers/power/supply/Kconfig -index f3424fdce341..7953e6c92521 100644 ---- a/drivers/power/supply/Kconfig -+++ b/drivers/power/supply/Kconfig -@@ -116,6 +116,17 @@ config BATTERY_CPCAP - Say Y here to enable support for battery on Motorola - phones and tablets such as droid 4. - -+config BATTERY_CW2015 -+ tristate "CW2015 Battery driver" -+ depends on I2C -+ select REGMAP_I2C -+ help -+ Say Y here to enable support for the cellwise cw2015 -+ battery fuel gauge (used in the Pinebook Pro & others) -+ -+ This driver can also be built as a module. If so, the module will be -+ called cw2015_battery. -+ - config BATTERY_DS2760 - tristate "DS2760 battery driver (HP iPAQ & others)" - depends on W1 -diff --git a/drivers/power/supply/Makefile b/drivers/power/supply/Makefile -index 6c7da920ea83..69727a10e835 100644 ---- a/drivers/power/supply/Makefile -+++ b/drivers/power/supply/Makefile -@@ -24,6 +24,7 @@ obj-$(CONFIG_BATTERY_ACT8945A) += act8945a_charger.o - obj-$(CONFIG_BATTERY_AXP20X) += axp20x_battery.o - obj-$(CONFIG_CHARGER_AXP20X) += axp20x_ac_power.o - obj-$(CONFIG_BATTERY_CPCAP) += cpcap-battery.o -+obj-$(CONFIG_BATTERY_CW2015) += cw2015_battery.o - obj-$(CONFIG_BATTERY_DS2760) += ds2760_battery.o - obj-$(CONFIG_BATTERY_DS2780) += ds2780_battery.o - obj-$(CONFIG_BATTERY_DS2781) += ds2781_battery.o -diff --git a/drivers/power/supply/cw2015_battery.c b/drivers/power/supply/cw2015_battery.c -new file mode 100644 -index 000000000000..19f62ea957ee ---- /dev/null -+++ b/drivers/power/supply/cw2015_battery.c -@@ -0,0 +1,749 @@ -+// SPDX-License-Identifier: GPL-2.0 -+/* -+ * Fuel gauge driver for CellWise 2013 / 2015 -+ * -+ * Copyright (C) 2012, RockChip -+ * Copyright (C) 2020, Tobias Schramm -+ * -+ * Authors: xuhuicong -+ * Authors: Tobias Schramm -+ */ -+ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+ -+#define CW2015_SIZE_BATINFO 64 -+ -+#define CW2015_RESET_TRIES 5 -+ -+#define CW2015_REG_VERSION 0x00 -+#define CW2015_REG_VCELL 0x02 -+#define CW2015_REG_SOC 0x04 -+#define CW2015_REG_RRT_ALERT 0x06 -+#define CW2015_REG_CONFIG 0x08 -+#define CW2015_REG_MODE 0x0A -+#define CW2015_REG_BATINFO 0x10 -+ -+#define CW2015_MODE_SLEEP_MASK GENMASK(7, 6) -+#define CW2015_MODE_SLEEP (0x03 << 6) -+#define CW2015_MODE_NORMAL (0x00 << 6) -+#define CW2015_MODE_QUICK_START (0x03 << 4) -+#define CW2015_MODE_RESTART (0x0f << 0) -+ -+#define CW2015_CONFIG_UPDATE_FLG (0x01 << 1) -+#define CW2015_ATHD(x) ((x) << 3) -+#define CW2015_MASK_ATHD GENMASK(7, 3) -+#define CW2015_MASK_SOC GENMASK(12, 0) -+ -+/* reset gauge of no valid state of charge could be polled for 40s */ -+#define CW2015_BAT_SOC_ERROR_MS (40 * MSEC_PER_SEC) -+/* reset gauge if state of charge stuck for half an hour during charging */ -+#define CW2015_BAT_CHARGING_STUCK_MS (1800 * MSEC_PER_SEC) -+ -+/* poll interval from CellWise GPL Android driver example */ -+#define CW2015_DEFAULT_POLL_INTERVAL_MS 8000 -+ -+#define CW2015_AVERAGING_SAMPLES 3 -+ -+struct cw_battery { -+ struct device *dev; -+ struct workqueue_struct *battery_workqueue; -+ struct delayed_work battery_delay_work; -+ struct regmap *regmap; -+ struct power_supply *rk_bat; -+ struct power_supply_battery_info battery; -+ u8 *bat_profile; -+ -+ bool charger_attached; -+ bool battery_changed; -+ -+ int soc; -+ int voltage_mv; -+ int status; -+ int time_to_empty; -+ int charge_count; -+ -+ u32 poll_interval_ms; -+ u8 alert_level; -+ -+ unsigned int read_errors; -+ unsigned int charge_stuck_cnt; -+}; -+ -+static int cw_read_word(struct cw_battery *cw_bat, u8 reg, u16 *val) -+{ -+ __be16 value; -+ int ret; -+ -+ ret = regmap_bulk_read(cw_bat->regmap, reg, &value, sizeof(value)); -+ if (ret) -+ return ret; -+ -+ *val = be16_to_cpu(value); -+ return 0; -+} -+ -+static int cw_update_profile(struct cw_battery *cw_bat) -+{ -+ int ret; -+ unsigned int reg_val; -+ u8 reset_val; -+ -+ /* make sure gauge is not in sleep mode */ -+ ret = regmap_read(cw_bat->regmap, CW2015_REG_MODE, ®_val); -+ if (ret) -+ return ret; -+ -+ reset_val = reg_val; -+ if ((reg_val & CW2015_MODE_SLEEP_MASK) == CW2015_MODE_SLEEP) { -+ dev_err(cw_bat->dev, -+ "Gauge is in sleep mode, can't update battery info\n"); -+ return -EINVAL; -+ } -+ -+ /* write new battery info */ -+ ret = regmap_raw_write(cw_bat->regmap, CW2015_REG_BATINFO, -+ cw_bat->bat_profile, -+ CW2015_SIZE_BATINFO); -+ if (ret) -+ return ret; -+ -+ /* set config update flag */ -+ reg_val |= CW2015_CONFIG_UPDATE_FLG; -+ reg_val &= ~CW2015_MASK_ATHD; -+ reg_val |= CW2015_ATHD(cw_bat->alert_level); -+ ret = regmap_write(cw_bat->regmap, CW2015_REG_CONFIG, reg_val); -+ if (ret) -+ return ret; -+ -+ /* reset gauge to apply new battery profile */ -+ reset_val &= ~CW2015_MODE_RESTART; -+ reg_val = reset_val | CW2015_MODE_RESTART; -+ ret = regmap_write(cw_bat->regmap, CW2015_REG_MODE, reg_val); -+ if (ret) -+ return ret; -+ -+ /* wait for gauge to reset */ -+ msleep(20); -+ -+ /* clear reset flag */ -+ ret = regmap_write(cw_bat->regmap, CW2015_REG_MODE, reset_val); -+ if (ret) -+ return ret; -+ -+ /* wait for gauge to become ready */ -+ ret = regmap_read_poll_timeout(cw_bat->regmap, CW2015_REG_SOC, -+ reg_val, reg_val <= 100, -+ 10 * USEC_PER_MSEC, 10 * USEC_PER_SEC); -+ if (ret) -+ dev_err(cw_bat->dev, -+ "Gauge did not become ready after profile upload\n"); -+ else -+ dev_dbg(cw_bat->dev, "Battery profile updated\n"); -+ -+ return ret; -+} -+ -+static int cw_init(struct cw_battery *cw_bat) -+{ -+ int ret; -+ unsigned int reg_val = CW2015_MODE_SLEEP; -+ -+ if ((reg_val & CW2015_MODE_SLEEP_MASK) == CW2015_MODE_SLEEP) { -+ reg_val = CW2015_MODE_NORMAL; -+ ret = regmap_write(cw_bat->regmap, CW2015_REG_MODE, reg_val); -+ if (ret) -+ return ret; -+ } -+ -+ ret = regmap_read(cw_bat->regmap, CW2015_REG_CONFIG, ®_val); -+ if (ret) -+ return ret; -+ -+ if ((reg_val & CW2015_MASK_ATHD) != CW2015_ATHD(cw_bat->alert_level)) { -+ dev_dbg(cw_bat->dev, "Setting new alert level\n"); -+ reg_val &= ~CW2015_MASK_ATHD; -+ reg_val |= ~CW2015_ATHD(cw_bat->alert_level); -+ ret = regmap_write(cw_bat->regmap, CW2015_REG_CONFIG, reg_val); -+ if (ret) -+ return ret; -+ } -+ -+ ret = regmap_read(cw_bat->regmap, CW2015_REG_CONFIG, ®_val); -+ if (ret) -+ return ret; -+ -+ if (!(reg_val & CW2015_CONFIG_UPDATE_FLG)) { -+ dev_dbg(cw_bat->dev, -+ "Battery profile not present, uploading battery profile\n"); -+ if (cw_bat->bat_profile) { -+ ret = cw_update_profile(cw_bat); -+ if (ret) { -+ dev_err(cw_bat->dev, -+ "Failed to upload battery profile\n"); -+ return ret; -+ } -+ } else { -+ dev_warn(cw_bat->dev, -+ "No profile specified, continuing without profile\n"); -+ } -+ } else if (cw_bat->bat_profile) { -+ u8 bat_info[CW2015_SIZE_BATINFO]; -+ -+ ret = regmap_raw_read(cw_bat->regmap, CW2015_REG_BATINFO, -+ bat_info, CW2015_SIZE_BATINFO); -+ if (ret) { -+ dev_err(cw_bat->dev, -+ "Failed to read stored battery profile\n"); -+ return ret; -+ } -+ -+ if (memcmp(bat_info, cw_bat->bat_profile, CW2015_SIZE_BATINFO)) { -+ dev_warn(cw_bat->dev, "Replacing stored battery profile\n"); -+ ret = cw_update_profile(cw_bat); -+ if (ret) -+ return ret; -+ } -+ } else { -+ dev_warn(cw_bat->dev, -+ "Can't check current battery profile, no profile provided\n"); -+ } -+ -+ dev_dbg(cw_bat->dev, "Battery profile configured\n"); -+ return 0; -+} -+ -+static int cw_power_on_reset(struct cw_battery *cw_bat) -+{ -+ int ret; -+ unsigned char reset_val; -+ -+ reset_val = CW2015_MODE_SLEEP; -+ ret = regmap_write(cw_bat->regmap, CW2015_REG_MODE, reset_val); -+ if (ret) -+ return ret; -+ -+ /* wait for gauge to enter sleep */ -+ msleep(20); -+ -+ reset_val = CW2015_MODE_NORMAL; -+ ret = regmap_write(cw_bat->regmap, CW2015_REG_MODE, reset_val); -+ if (ret) -+ return ret; -+ -+ ret = cw_init(cw_bat); -+ if (ret) -+ return ret; -+ return 0; -+} -+ -+#define HYSTERESIS(current, previous, up, down) \ -+ (((current) < (previous) + (up)) && ((current) > (previous) - (down))) -+ -+static int cw_get_soc(struct cw_battery *cw_bat) -+{ -+ unsigned int soc; -+ int ret; -+ -+ ret = regmap_read(cw_bat->regmap, CW2015_REG_SOC, &soc); -+ if (ret) -+ return ret; -+ -+ if (soc > 100) { -+ int max_error_cycles = -+ CW2015_BAT_SOC_ERROR_MS / cw_bat->poll_interval_ms; -+ -+ dev_err(cw_bat->dev, "Invalid SoC %d%%\n", soc); -+ cw_bat->read_errors++; -+ if (cw_bat->read_errors > max_error_cycles) { -+ dev_warn(cw_bat->dev, -+ "Too many invalid SoC reports, resetting gauge\n"); -+ cw_power_on_reset(cw_bat); -+ cw_bat->read_errors = 0; -+ } -+ return cw_bat->soc; -+ } -+ cw_bat->read_errors = 0; -+ -+ /* Reset gauge if stuck while charging */ -+ if (cw_bat->status == POWER_SUPPLY_STATUS_CHARGING && soc == cw_bat->soc) { -+ int max_stuck_cycles = -+ CW2015_BAT_CHARGING_STUCK_MS / cw_bat->poll_interval_ms; -+ -+ cw_bat->charge_stuck_cnt++; -+ if (cw_bat->charge_stuck_cnt > max_stuck_cycles) { -+ dev_warn(cw_bat->dev, -+ "SoC stuck @%u%%, resetting gauge\n", soc); -+ cw_power_on_reset(cw_bat); -+ cw_bat->charge_stuck_cnt = 0; -+ } -+ } else { -+ cw_bat->charge_stuck_cnt = 0; -+ } -+ -+ /* Ignore voltage dips during charge */ -+ if (cw_bat->charger_attached && HYSTERESIS(soc, cw_bat->soc, 0, 3)) -+ soc = cw_bat->soc; -+ -+ /* Ignore voltage spikes during discharge */ -+ if (!cw_bat->charger_attached && HYSTERESIS(soc, cw_bat->soc, 3, 0)) -+ soc = cw_bat->soc; -+ -+ return soc; -+} -+ -+static int cw_get_voltage(struct cw_battery *cw_bat) -+{ -+ int ret, i, voltage_mv; -+ u16 reg_val; -+ u32 avg = 0; -+ -+ for (i = 0; i < CW2015_AVERAGING_SAMPLES; i++) { -+ ret = cw_read_word(cw_bat, CW2015_REG_VCELL, ®_val); -+ if (ret) -+ return ret; -+ -+ avg += reg_val; -+ } -+ avg /= CW2015_AVERAGING_SAMPLES; -+ -+ /* -+ * 305 uV per ADC step -+ * Use 312 / 1024 as efficient approximation of 305 / 1000 -+ * Negligible error of 0.1% -+ */ -+ voltage_mv = avg * 312 / 1024; -+ -+ dev_dbg(cw_bat->dev, "Read voltage: %d mV, raw=0x%04x\n", -+ voltage_mv, reg_val); -+ return voltage_mv; -+} -+ -+static int cw_get_time_to_empty(struct cw_battery *cw_bat) -+{ -+ int ret; -+ u16 value16; -+ -+ ret = cw_read_word(cw_bat, CW2015_REG_RRT_ALERT, &value16); -+ if (ret) -+ return ret; -+ -+ return value16 & CW2015_MASK_SOC; -+} -+ -+static void cw_update_charge_status(struct cw_battery *cw_bat) -+{ -+ int ret; -+ -+ ret = power_supply_am_i_supplied(cw_bat->rk_bat); -+ if (ret < 0) { -+ dev_warn(cw_bat->dev, "Failed to get supply state: %d\n", ret); -+ } else { -+ bool charger_attached; -+ -+ charger_attached = !!ret; -+ if (cw_bat->charger_attached != charger_attached) { -+ cw_bat->battery_changed = true; -+ if (charger_attached) -+ cw_bat->charge_count++; -+ } -+ cw_bat->charger_attached = charger_attached; -+ } -+} -+ -+static void cw_update_soc(struct cw_battery *cw_bat) -+{ -+ int soc; -+ -+ soc = cw_get_soc(cw_bat); -+ if (soc < 0) -+ dev_err(cw_bat->dev, "Failed to get SoC from gauge: %d\n", soc); -+ else if (cw_bat->soc != soc) { -+ cw_bat->soc = soc; -+ cw_bat->battery_changed = true; -+ } -+} -+ -+static void cw_update_voltage(struct cw_battery *cw_bat) -+{ -+ int voltage_mv; -+ -+ voltage_mv = cw_get_voltage(cw_bat); -+ if (voltage_mv < 0) -+ dev_err(cw_bat->dev, "Failed to get voltage from gauge: %d\n", -+ voltage_mv); -+ else -+ cw_bat->voltage_mv = voltage_mv; -+} -+ -+static void cw_update_status(struct cw_battery *cw_bat) -+{ -+ int status = POWER_SUPPLY_STATUS_DISCHARGING; -+ -+ if (cw_bat->charger_attached) { -+ if (cw_bat->soc >= 100) -+ status = POWER_SUPPLY_STATUS_FULL; -+ else -+ status = POWER_SUPPLY_STATUS_CHARGING; -+ } -+ -+ if (cw_bat->status != status) -+ cw_bat->battery_changed = true; -+ cw_bat->status = status; -+} -+ -+static void cw_update_time_to_empty(struct cw_battery *cw_bat) -+{ -+ int time_to_empty; -+ -+ time_to_empty = cw_get_time_to_empty(cw_bat); -+ if (time_to_empty < 0) -+ dev_err(cw_bat->dev, "Failed to get time to empty from gauge: %d\n", -+ time_to_empty); -+ else if (cw_bat->time_to_empty != time_to_empty) { -+ cw_bat->time_to_empty = time_to_empty; -+ cw_bat->battery_changed = true; -+ } -+} -+ -+static void cw_bat_work(struct work_struct *work) -+{ -+ struct delayed_work *delay_work; -+ struct cw_battery *cw_bat; -+ int ret; -+ unsigned int reg_val; -+ -+ delay_work = to_delayed_work(work); -+ cw_bat = container_of(delay_work, struct cw_battery, battery_delay_work); -+ ret = regmap_read(cw_bat->regmap, CW2015_REG_MODE, ®_val); -+ if (ret) { -+ dev_err(cw_bat->dev, "Failed to read mode from gauge: %d\n", ret); -+ } else { -+ if ((reg_val & CW2015_MODE_SLEEP_MASK) == CW2015_MODE_SLEEP) { -+ int i; -+ -+ for (i = 0; i < CW2015_RESET_TRIES; i++) { -+ if (!cw_power_on_reset(cw_bat)) -+ break; -+ } -+ } -+ cw_update_soc(cw_bat); -+ cw_update_voltage(cw_bat); -+ cw_update_charge_status(cw_bat); -+ cw_update_status(cw_bat); -+ cw_update_time_to_empty(cw_bat); -+ } -+ dev_dbg(cw_bat->dev, "charger_attached = %d\n", cw_bat->charger_attached); -+ dev_dbg(cw_bat->dev, "status = %d\n", cw_bat->status); -+ dev_dbg(cw_bat->dev, "soc = %d%%\n", cw_bat->soc); -+ dev_dbg(cw_bat->dev, "voltage = %dmV\n", cw_bat->voltage_mv); -+ -+ if (cw_bat->battery_changed) -+ power_supply_changed(cw_bat->rk_bat); -+ cw_bat->battery_changed = false; -+ -+ queue_delayed_work(cw_bat->battery_workqueue, -+ &cw_bat->battery_delay_work, -+ msecs_to_jiffies(cw_bat->poll_interval_ms)); -+} -+ -+static bool cw_battery_valid_time_to_empty(struct cw_battery *cw_bat) -+{ -+ return cw_bat->time_to_empty > 0 && -+ cw_bat->time_to_empty < CW2015_MASK_SOC && -+ cw_bat->status == POWER_SUPPLY_STATUS_DISCHARGING; -+} -+ -+static int cw_battery_get_property(struct power_supply *psy, -+ enum power_supply_property psp, -+ union power_supply_propval *val) -+{ -+ struct cw_battery *cw_bat; -+ -+ cw_bat = power_supply_get_drvdata(psy); -+ switch (psp) { -+ case POWER_SUPPLY_PROP_CAPACITY: -+ val->intval = cw_bat->soc; -+ break; -+ -+ case POWER_SUPPLY_PROP_STATUS: -+ val->intval = cw_bat->status; -+ break; -+ -+ case POWER_SUPPLY_PROP_PRESENT: -+ val->intval = !!cw_bat->voltage_mv; -+ break; -+ -+ case POWER_SUPPLY_PROP_VOLTAGE_NOW: -+ val->intval = cw_bat->voltage_mv * 1000; -+ break; -+ -+ case POWER_SUPPLY_PROP_TIME_TO_EMPTY_NOW: -+ if (cw_battery_valid_time_to_empty(cw_bat)) -+ val->intval = cw_bat->time_to_empty; -+ else -+ val->intval = 0; -+ break; -+ -+ case POWER_SUPPLY_PROP_TECHNOLOGY: -+ val->intval = POWER_SUPPLY_TECHNOLOGY_LION; -+ break; -+ -+ case POWER_SUPPLY_PROP_CHARGE_COUNTER: -+ val->intval = cw_bat->charge_count; -+ break; -+ -+ case POWER_SUPPLY_PROP_CHARGE_FULL: -+ case POWER_SUPPLY_PROP_CHARGE_FULL_DESIGN: -+ if (cw_bat->battery.charge_full_design_uah > 0) -+ val->intval = cw_bat->battery.charge_full_design_uah; -+ else -+ val->intval = 0; -+ break; -+ -+ case POWER_SUPPLY_PROP_CURRENT_NOW: -+ if (cw_battery_valid_time_to_empty(cw_bat) && -+ cw_bat->battery.charge_full_design_uah > 0) { -+ /* calculate remaining capacity */ -+ val->intval = cw_bat->battery.charge_full_design_uah; -+ val->intval = val->intval * cw_bat->soc / 100; -+ -+ /* estimate current based on time to empty */ -+ val->intval = 60 * val->intval / cw_bat->time_to_empty; -+ } else { -+ val->intval = 0; -+ } -+ -+ break; -+ -+ default: -+ break; -+ } -+ return 0; -+} -+ -+static enum power_supply_property cw_battery_properties[] = { -+ POWER_SUPPLY_PROP_CAPACITY, -+ POWER_SUPPLY_PROP_STATUS, -+ POWER_SUPPLY_PROP_PRESENT, -+ POWER_SUPPLY_PROP_VOLTAGE_NOW, -+ POWER_SUPPLY_PROP_TIME_TO_EMPTY_NOW, -+ POWER_SUPPLY_PROP_TECHNOLOGY, -+ POWER_SUPPLY_PROP_CHARGE_COUNTER, -+ POWER_SUPPLY_PROP_CHARGE_FULL, -+ POWER_SUPPLY_PROP_CHARGE_FULL_DESIGN, -+ POWER_SUPPLY_PROP_CURRENT_NOW, -+}; -+ -+static const struct power_supply_desc cw2015_bat_desc = { -+ .name = "cw2015-battery", -+ .type = POWER_SUPPLY_TYPE_BATTERY, -+ .properties = cw_battery_properties, -+ .num_properties = ARRAY_SIZE(cw_battery_properties), -+ .get_property = cw_battery_get_property, -+}; -+ -+static int cw2015_parse_properties(struct cw_battery *cw_bat) -+{ -+ struct device *dev = cw_bat->dev; -+ int length; -+ int ret; -+ -+ length = device_property_count_u8(dev, "cellwise,battery-profile"); -+ if (length < 0) { -+ dev_warn(cw_bat->dev, -+ "No battery-profile found, using current flash contents\n"); -+ } else if (length != CW2015_SIZE_BATINFO) { -+ dev_err(cw_bat->dev, "battery-profile must be %d bytes\n", -+ CW2015_SIZE_BATINFO); -+ return -EINVAL; -+ } else { -+ cw_bat->bat_profile = devm_kzalloc(dev, length, GFP_KERNEL); -+ if (!cw_bat->bat_profile) -+ return -ENOMEM; -+ -+ ret = device_property_read_u8_array(dev, -+ "cellwise,battery-profile", -+ cw_bat->bat_profile, -+ length); -+ if (ret) -+ return ret; -+ } -+ -+ ret = device_property_read_u32(dev, "cellwise,monitor-interval-ms", -+ &cw_bat->poll_interval_ms); -+ if (ret) { -+ dev_dbg(cw_bat->dev, "Using default poll interval\n"); -+ cw_bat->poll_interval_ms = CW2015_DEFAULT_POLL_INTERVAL_MS; -+ } -+ -+ return 0; -+} -+ -+static const struct regmap_range regmap_ranges_rd_yes[] = { -+ regmap_reg_range(CW2015_REG_VERSION, CW2015_REG_VERSION), -+ regmap_reg_range(CW2015_REG_VCELL, CW2015_REG_CONFIG), -+ regmap_reg_range(CW2015_REG_MODE, CW2015_REG_MODE), -+ regmap_reg_range(CW2015_REG_BATINFO, -+ CW2015_REG_BATINFO + CW2015_SIZE_BATINFO - 1), -+}; -+ -+static const struct regmap_access_table regmap_rd_table = { -+ .yes_ranges = regmap_ranges_rd_yes, -+ .n_yes_ranges = 4, -+}; -+ -+static const struct regmap_range regmap_ranges_wr_yes[] = { -+ regmap_reg_range(CW2015_REG_RRT_ALERT, CW2015_REG_CONFIG), -+ regmap_reg_range(CW2015_REG_MODE, CW2015_REG_MODE), -+ regmap_reg_range(CW2015_REG_BATINFO, -+ CW2015_REG_BATINFO + CW2015_SIZE_BATINFO - 1), -+}; -+ -+static const struct regmap_access_table regmap_wr_table = { -+ .yes_ranges = regmap_ranges_wr_yes, -+ .n_yes_ranges = 3, -+}; -+ -+static const struct regmap_range regmap_ranges_vol_yes[] = { -+ regmap_reg_range(CW2015_REG_VCELL, CW2015_REG_SOC + 1), -+}; -+ -+static const struct regmap_access_table regmap_vol_table = { -+ .yes_ranges = regmap_ranges_vol_yes, -+ .n_yes_ranges = 1, -+}; -+ -+static const struct regmap_config cw2015_regmap_config = { -+ .reg_bits = 8, -+ .val_bits = 8, -+ .rd_table = ®map_rd_table, -+ .wr_table = ®map_wr_table, -+ .volatile_table = ®map_vol_table, -+ .max_register = CW2015_REG_BATINFO + CW2015_SIZE_BATINFO - 1, -+}; -+ -+static int cw_bat_probe(struct i2c_client *client) -+{ -+ int ret; -+ struct cw_battery *cw_bat; -+ struct power_supply_config psy_cfg = { 0 }; -+ -+ cw_bat = devm_kzalloc(&client->dev, sizeof(*cw_bat), GFP_KERNEL); -+ if (!cw_bat) -+ return -ENOMEM; -+ -+ i2c_set_clientdata(client, cw_bat); -+ cw_bat->dev = &client->dev; -+ cw_bat->soc = 1; -+ -+ ret = cw2015_parse_properties(cw_bat); -+ if (ret) { -+ dev_err(cw_bat->dev, "Failed to parse cw2015 properties\n"); -+ return ret; -+ } -+ -+ cw_bat->regmap = devm_regmap_init_i2c(client, &cw2015_regmap_config); -+ if (IS_ERR(cw_bat->regmap)) { -+ dev_err(cw_bat->dev, "Failed to allocate regmap: %ld\n", -+ PTR_ERR(cw_bat->regmap)); -+ return PTR_ERR(cw_bat->regmap); -+ } -+ -+ ret = cw_init(cw_bat); -+ if (ret) { -+ dev_err(cw_bat->dev, "Init failed: %d\n", ret); -+ return ret; -+ } -+ -+ psy_cfg.drv_data = cw_bat; -+ psy_cfg.fwnode = dev_fwnode(cw_bat->dev); -+ -+ cw_bat->rk_bat = devm_power_supply_register(&client->dev, -+ &cw2015_bat_desc, -+ &psy_cfg); -+ if (IS_ERR(cw_bat->rk_bat)) { -+ dev_err(cw_bat->dev, "Failed to register power supply\n"); -+ return PTR_ERR(cw_bat->rk_bat); -+ } -+ -+ ret = power_supply_get_battery_info(cw_bat->rk_bat, &cw_bat->battery); -+ if (ret) { -+ dev_warn(cw_bat->dev, -+ "No monitored battery, some properties will be missing\n"); -+ } -+ -+ cw_bat->battery_workqueue = create_singlethread_workqueue("rk_battery"); -+ INIT_DELAYED_WORK(&cw_bat->battery_delay_work, cw_bat_work); -+ queue_delayed_work(cw_bat->battery_workqueue, -+ &cw_bat->battery_delay_work, msecs_to_jiffies(10)); -+ return 0; -+} -+ -+static int __maybe_unused cw_bat_suspend(struct device *dev) -+{ -+ struct i2c_client *client = to_i2c_client(dev); -+ struct cw_battery *cw_bat = i2c_get_clientdata(client); -+ -+ cancel_delayed_work_sync(&cw_bat->battery_delay_work); -+ return 0; -+} -+ -+static int __maybe_unused cw_bat_resume(struct device *dev) -+{ -+ struct i2c_client *client = to_i2c_client(dev); -+ struct cw_battery *cw_bat = i2c_get_clientdata(client); -+ -+ queue_delayed_work(cw_bat->battery_workqueue, -+ &cw_bat->battery_delay_work, 0); -+ return 0; -+} -+ -+static SIMPLE_DEV_PM_OPS(cw_bat_pm_ops, cw_bat_suspend, cw_bat_resume); -+ -+static int cw_bat_remove(struct i2c_client *client) -+{ -+ struct cw_battery *cw_bat = i2c_get_clientdata(client); -+ -+ cancel_delayed_work_sync(&cw_bat->battery_delay_work); -+ power_supply_put_battery_info(cw_bat->rk_bat, &cw_bat->battery); -+ return 0; -+} -+ -+static const struct i2c_device_id cw_bat_id_table[] = { -+ { "cw2015", 0 }, -+ { } -+}; -+ -+static const struct of_device_id cw2015_of_match[] = { -+ { .compatible = "cellwise,cw2015" }, -+ { } -+}; -+MODULE_DEVICE_TABLE(of, cw2015_of_match); -+ -+static struct i2c_driver cw_bat_driver = { -+ .driver = { -+ .name = "cw2015", -+ .pm = &cw_bat_pm_ops, -+ }, -+ .probe_new = cw_bat_probe, -+ .remove = cw_bat_remove, -+ .id_table = cw_bat_id_table, -+}; -+ -+module_i2c_driver(cw_bat_driver); -+ -+MODULE_AUTHOR("xhc"); -+MODULE_AUTHOR("Tobias Schramm "); -+MODULE_DESCRIPTION("cw2015/cw2013 battery driver"); -+MODULE_LICENSE("GPL"); --- -2.26.2 - diff --git a/patch/kernel/rockchip64-current/0012-add-suspend-to-rk3399-PBP.patch b/patch/kernel/rockchip64-current/0012-add-suspend-to-rk3399-PBP.patch index 00b33a72f5..5f6c1f4dd5 100644 --- a/patch/kernel/rockchip64-current/0012-add-suspend-to-rk3399-PBP.patch +++ b/patch/kernel/rockchip64-current/0012-add-suspend-to-rk3399-PBP.patch @@ -177,9 +177,9 @@ diff --git a/drivers/firmware/Kconfig b/drivers/firmware/Kconfig index 8007d4aa76dc..37f8039a5e27 100644 --- a/drivers/firmware/Kconfig +++ b/drivers/firmware/Kconfig -@@ -298,6 +298,13 @@ config TURRIS_MOX_RWTM - config HAVE_ARM_SMCCC - bool +@@ -295,6 +295,13 @@ config TURRIS_MOX_RWTM + other manufacturing data and also utilize the Entropy Bit Generator + for hardware random number generation. +config ROCKCHIP_SIP + bool "Rockchip SIP interface" @@ -188,9 +188,9 @@ index 8007d4aa76dc..37f8039a5e27 100644 + Say Y here if you want to enable SIP callbacks for Rockchip platforms + This option enables support for communicating with the ATF. + - source "drivers/firmware/psci/Kconfig" source "drivers/firmware/broadcom/Kconfig" source "drivers/firmware/google/Kconfig" + source "drivers/firmware/efi/Kconfig" diff --git a/drivers/firmware/Makefile b/drivers/firmware/Makefile index e9fb838af4df..575f45d55939 100644 --- a/drivers/firmware/Makefile diff --git a/patch/kernel/rockchip64-current/add-board-helios64.patch b/patch/kernel/rockchip64-current/add-board-helios64.patch index d5a3ad6f4b..4f3b9b768f 100644 --- a/patch/kernel/rockchip64-current/add-board-helios64.patch +++ b/patch/kernel/rockchip64-current/add-board-helios64.patch @@ -908,7 +908,7 @@ index 000000000..342589131 + + sdmmc0_pwr_h: sdmmc0-pwr-h { + rockchip,pins = -+ ; ++ <0 RK_PA1 RK_FUNC_GPIO &pcfg_output_high>; + }; + + usb_lan_en: usb-lan-en { diff --git a/patch/kernel/rockchip64-current/add-board-orangepi-4.patch b/patch/kernel/rockchip64-current/add-board-orangepi-4.patch index 5d9e38e705..74091adc89 100644 --- a/patch/kernel/rockchip64-current/add-board-orangepi-4.patch +++ b/patch/kernel/rockchip64-current/add-board-orangepi-4.patch @@ -1001,7 +1001,7 @@ index 000000000..1e1747ceb + + i2s1 { + i2s_8ch_mclk: i2s-8ch-mclk { -+ rockchip,pins = <4 RK_PA0 RK_FUNC_1 &pcfg_pull_none>; ++ rockchip,pins = <4 RK_PA0 1 &pcfg_pull_none>; + }; + }; + @@ -1073,7 +1073,7 @@ index 000000000..1e1747ceb + + cam_pins { + cif_clkout_a: cif-clkout-a { -+ rockchip,pins = <2 11 RK_FUNC_3 &pcfg_pull_none>; ++ rockchip,pins = <2 11 3 &pcfg_pull_none>; + }; + + cif_clkout_a_sleep: cif-clkout-a-sleep { diff --git a/patch/kernel/rockchip64-current/add-mp8859-regulator.patch b/patch/kernel/rockchip64-current/add-mp8859-regulator.patch deleted file mode 100644 index a9d98041fb..0000000000 --- a/patch/kernel/rockchip64-current/add-mp8859-regulator.patch +++ /dev/null @@ -1,178 +0,0 @@ -From 4444a1c10069e2f371fa497ba22feafafed5aada Mon Sep 17 00:00:00 2001 -From: Markus Reichl -Date: Mon, 6 Jan 2020 22:16:24 +0100 -Subject: [PATCH] regulator: mp8859: add driver - -The MP8859 from Monolithic Power Systems is a single output DC/DC -converter. The voltage can be controlled via I2C. - -Signed-off-by: Markus Reichl -Link: https://lore.kernel.org/r/20200106211633.2882-2-m.reichl@fivetechno.de -Signed-off-by: Mark Brown ---- - drivers/regulator/mp8859.c | 156 +++++++++++++++++++++++++++++++++++++ - 1 file changed, 156 insertions(+) - create mode 100644 drivers/regulator/mp8859.c - -diff --git a/drivers/regulator/mp8859.c b/drivers/regulator/mp8859.c -new file mode 100644 -index 0000000000000..e804a52673017 ---- /dev/null -+++ b/drivers/regulator/mp8859.c -@@ -0,0 +1,156 @@ -+// SPDX-License-Identifier: GPL-2.0 -+// -+// Copyright (c) 2019 five technologies GmbH -+// Author: Markus Reichl -+ -+#include -+#include -+#include -+#include -+#include -+ -+ -+#define VOL_MIN_IDX 0x00 -+#define VOL_MAX_IDX 0x7ff -+ -+/* Register definitions */ -+#define MP8859_VOUT_L_REG 0 //3 lo Bits -+#define MP8859_VOUT_H_REG 1 //8 hi Bits -+#define MP8859_VOUT_GO_REG 2 -+#define MP8859_IOUT_LIM_REG 3 -+#define MP8859_CTL1_REG 4 -+#define MP8859_CTL2_REG 5 -+#define MP8859_RESERVED1_REG 6 -+#define MP8859_RESERVED2_REG 7 -+#define MP8859_RESERVED3_REG 8 -+#define MP8859_STATUS_REG 9 -+#define MP8859_INTERRUPT_REG 0x0A -+#define MP8859_MASK_REG 0x0B -+#define MP8859_ID1_REG 0x0C -+#define MP8859_MFR_ID_REG 0x27 -+#define MP8859_DEV_ID_REG 0x28 -+#define MP8859_IC_REV_REG 0x29 -+ -+#define MP8859_MAX_REG 0x29 -+ -+#define MP8859_GO_BIT 0x01 -+ -+ -+static int mp8859_set_voltage_sel(struct regulator_dev *rdev, unsigned int sel) -+{ -+ int ret; -+ -+ ret = regmap_write(rdev->regmap, MP8859_VOUT_L_REG, sel & 0x7); -+ -+ if (ret) -+ return ret; -+ ret = regmap_write(rdev->regmap, MP8859_VOUT_H_REG, sel >> 3); -+ -+ if (ret) -+ return ret; -+ ret = regmap_update_bits(rdev->regmap, MP8859_VOUT_GO_REG, -+ MP8859_GO_BIT, 1); -+ return ret; -+} -+ -+static int mp8859_get_voltage_sel(struct regulator_dev *rdev) -+{ -+ unsigned int val_tmp; -+ unsigned int val; -+ int ret; -+ -+ ret = regmap_read(rdev->regmap, MP8859_VOUT_H_REG, &val_tmp); -+ -+ if (ret) -+ return ret; -+ val = val_tmp << 3; -+ -+ ret = regmap_read(rdev->regmap, MP8859_VOUT_L_REG, &val_tmp); -+ -+ if (ret) -+ return ret; -+ val |= val_tmp & 0x07; -+ return val; -+} -+ -+static const struct regulator_linear_range mp8859_dcdc_ranges[] = { -+ REGULATOR_LINEAR_RANGE(0, VOL_MIN_IDX, VOL_MAX_IDX, 10000), -+}; -+ -+static const struct regmap_config mp8859_regmap = { -+ .reg_bits = 8, -+ .val_bits = 8, -+ .max_register = MP8859_MAX_REG, -+ .cache_type = REGCACHE_RBTREE, -+}; -+ -+static const struct regulator_ops mp8859_ops = { -+ .set_voltage_sel = mp8859_set_voltage_sel, -+ .get_voltage_sel = mp8859_get_voltage_sel, -+ .list_voltage = regulator_list_voltage_linear_range, -+}; -+ -+static const struct regulator_desc mp8859_regulators[] = { -+ { -+ .id = 0, -+ .type = REGULATOR_VOLTAGE, -+ .name = "mp8859_dcdc", -+ .of_match = of_match_ptr("mp8859_dcdc"), -+ .n_voltages = VOL_MAX_IDX + 1, -+ .linear_ranges = mp8859_dcdc_ranges, -+ .n_linear_ranges = 1, -+ .ops = &mp8859_ops, -+ .owner = THIS_MODULE, -+ }, -+}; -+ -+static int mp8859_i2c_probe(struct i2c_client *i2c) -+{ -+ int ret; -+ struct regulator_config config = {.dev = &i2c->dev}; -+ struct regmap *regmap = devm_regmap_init_i2c(i2c, &mp8859_regmap); -+ struct regulator_dev *rdev; -+ -+ if (IS_ERR(regmap)) { -+ ret = PTR_ERR(regmap); -+ dev_err(&i2c->dev, "regmap init failed: %d\n", ret); -+ return ret; -+ } -+ rdev = devm_regulator_register(&i2c->dev, &mp8859_regulators[0], -+ &config); -+ -+ if (IS_ERR(rdev)) { -+ ret = PTR_ERR(rdev); -+ dev_err(&i2c->dev, "failed to register %s: %d\n", -+ mp8859_regulators[0].name, ret); -+ return ret; -+ } -+ return 0; -+} -+ -+static const struct of_device_id mp8859_dt_id[] = { -+ {.compatible = "mps,mp8859"}, -+ {}, -+}; -+MODULE_DEVICE_TABLE(of, mp8859_dt_id); -+ -+static const struct i2c_device_id mp8859_i2c_id[] = { -+ { "mp8859", }, -+ { }, -+}; -+MODULE_DEVICE_TABLE(i2c, mp8859_i2c_id); -+ -+static struct i2c_driver mp8859_regulator_driver = { -+ .driver = { -+ .name = "mp8859", -+ .of_match_table = of_match_ptr(mp8859_dt_id), -+ }, -+ .probe_new = mp8859_i2c_probe, -+ .id_table = mp8859_i2c_id, -+}; -+ -+module_i2c_driver(mp8859_regulator_driver); -+ -+MODULE_DESCRIPTION("Monolithic Power Systems MP8859 voltage regulator driver"); -+MODULE_AUTHOR("Markus Reichl "); -+MODULE_LICENSE("GPL v2"); diff --git a/patch/kernel/rockchip64-current/board-rockpro64-work-led-heartbeat.patch b/patch/kernel/rockchip64-current/board-rockpro64-work-led-heartbeat.patch index d357c56c33..0458328ca3 100644 --- a/patch/kernel/rockchip64-current/board-rockpro64-work-led-heartbeat.patch +++ b/patch/kernel/rockchip64-current/board-rockpro64-work-led-heartbeat.patch @@ -1,5 +1,5 @@ diff --git a/arch/arm64/boot/dts/rockchip/rk3399-rockpro64.dtsi b/arch/arm64/boot/dts/rockchip/rk3399-rockpro64.dtsi -index 4750e366c..1c0ad2df7 100644 +index 274e72b37..311e5886f 100644 --- a/arch/arm64/boot/dts/rockchip/rk3399-rockpro64.dtsi +++ b/arch/arm64/boot/dts/rockchip/rk3399-rockpro64.dtsi @@ -44,7 +44,7 @@ diff --git a/patch/kernel/rockchip64-current/general-increasing_DMA_block_memory_allocation_to_2048.patch b/patch/kernel/rockchip64-current/general-increasing_DMA_block_memory_allocation_to_2048.patch index dd533639da..fc6c2485b8 100644 --- a/patch/kernel/rockchip64-current/general-increasing_DMA_block_memory_allocation_to_2048.patch +++ b/patch/kernel/rockchip64-current/general-increasing_DMA_block_memory_allocation_to_2048.patch @@ -1,13 +1,21 @@ -diff --git a/kernel/dma/remap.c b/kernel/dma/remap.c -index 7a723194e..1a05e9e5b 100644 ---- a/kernel/dma/remap.c -+++ b/kernel/dma/remap.c -@@ -95,7 +95,7 @@ void dma_common_free_remap(void *cpu_addr, size_t size, unsigned long vm_flags) - #ifdef CONFIG_DMA_DIRECT_REMAP - static struct gen_pool *atomic_pool __ro_after_init; +diff --git a/kernel/dma/pool.c b/kernel/dma/pool.c +index 6bc74a2d5..e3827da51 100644 +--- a/kernel/dma/pool.c ++++ b/kernel/dma/pool.c +@@ -164,13 +164,11 @@ static int __init dma_atomic_pool_init(void) + int ret = 0; --#define DEFAULT_DMA_COHERENT_POOL_SIZE SZ_256K -+#define DEFAULT_DMA_COHERENT_POOL_SIZE SZ_2M - static size_t atomic_pool_size __initdata = DEFAULT_DMA_COHERENT_POOL_SIZE; + /* +- * If coherent_pool was not used on the command line, default the pool +- * sizes to 128KB per 1GB of memory, min 128KB, max MAX_ORDER-1. ++ * Always use 2MiB as default pool size. ++ * See: https://forum.armbian.com/topic/4811-uas-mainline-kernel-coherent-pool-memory-size/ + */ + if (!atomic_pool_size) { +- unsigned long pages = totalram_pages() / (SZ_1G / SZ_128K); +- pages = min_t(unsigned long, pages, MAX_ORDER_NR_PAGES); +- atomic_pool_size = max_t(size_t, pages << PAGE_SHIFT, SZ_128K); ++ atomic_pool_size = SZ_2M; + } + INIT_WORK(&atomic_pool_work, atomic_pool_work_fn); - static int __init early_coherent_pool(char *p) diff --git a/patch/kernel/rockchip64-current/rk3399-sd-drive-level-8ma.patch b/patch/kernel/rockchip64-current/rk3399-sd-drive-level-8ma.patch index 0a87da80cd..cac129aa04 100644 --- a/patch/kernel/rockchip64-current/rk3399-sd-drive-level-8ma.patch +++ b/patch/kernel/rockchip64-current/rk3399-sd-drive-level-8ma.patch @@ -7,7 +7,7 @@ index 6eb9dda..d6fc676 100644 sdmmc_bus1: sdmmc-bus1 { rockchip,pins = - <4 RK_PB0 1 &pcfg_pull_up>; -+ <4 RK_PB0 RK_FUNC_1 &pcfg_pull_up_8ma>; ++ <4 RK_PB0 1 &pcfg_pull_up_8ma>; }; sdmmc_bus4: sdmmc-bus4 { @@ -16,34 +16,34 @@ index 6eb9dda..d6fc676 100644 - <4 RK_PB1 1 &pcfg_pull_up>, - <4 RK_PB2 1 &pcfg_pull_up>, - <4 RK_PB3 1 &pcfg_pull_up>; -+ <4 RK_PB0 RK_FUNC_1 &pcfg_pull_up_8ma>, -+ <4 RK_PB1 RK_FUNC_1 &pcfg_pull_up_8ma>, -+ <4 RK_PB2 RK_FUNC_1 &pcfg_pull_up_8ma>, -+ <4 RK_PB3 RK_FUNC_1 &pcfg_pull_up_8ma>; ++ <4 RK_PB0 1 &pcfg_pull_up_8ma>, ++ <4 RK_PB1 1 &pcfg_pull_up_8ma>, ++ <4 RK_PB2 1 &pcfg_pull_up_8ma>, ++ <4 RK_PB3 1 &pcfg_pull_up_8ma>; }; sdmmc_clk: sdmmc-clk { rockchip,pins = - <4 RK_PB4 1 &pcfg_pull_none>; -+ <4 RK_PB4 RK_FUNC_1 &pcfg_pull_none_12ma>; ++ <4 RK_PB4 1 &pcfg_pull_none_12ma>; }; sdmmc_cmd: sdmmc-cmd { rockchip,pins = - <4 RK_PB5 1 &pcfg_pull_up>; -+ <4 RK_PB5 RK_FUNC_1 &pcfg_pull_up_8ma>; ++ <4 RK_PB5 1 &pcfg_pull_up_8ma>; }; sdmmc_cd: sdmmc-cd { rockchip,pins = - <0 RK_PA7 1 &pcfg_pull_up>; -+ <0 RK_PA7 RK_FUNC_1 &pcfg_pull_up>; ++ <0 RK_PA7 1 &pcfg_pull_up>; }; sdmmc_wp: sdmmc-wp { rockchip,pins = - <0 RK_PB0 1 &pcfg_pull_up>; -+ <0 RK_PB0 RK_FUNC_1 &pcfg_pull_up_8ma>; ++ <0 RK_PB0 1 &pcfg_pull_up_8ma>; }; }; diff --git a/patch/kernel/rockchip64-current/rkvdec.patch b/patch/kernel/rockchip64-current/rkvdec.patch deleted file mode 100644 index e287c5544d..0000000000 --- a/patch/kernel/rockchip64-current/rkvdec.patch +++ /dev/null @@ -1,3778 +0,0 @@ -From ezequiel at collabora.com Fri Apr 3 15:13:40 2020 -From: ezequiel at collabora.com (Ezequiel Garcia) -Date: Fri, 3 Apr 2020 19:13:40 -0300 -Subject: [PATCH v8 0/5] media: rockchip: Add the rkvdec driver -Message-ID: <20200403221345.16702-1-ezequiel@collabora.com> - -Hello, - -This is v8 of Boris' rkvdec driver, to support H264 -decoding on Rockchip RK3399 SoCs. - -Support for VP9 is planned, but not covered by this -patchset. - -I've addressed the feedback from Andriy Gelman and -fixed two warnings reported by the 0-day bot. - -While here, this is now rebased on top of Hans' -latest pull requests. - -Thanks, -Ezequiel - -Boris Brezillon (5): - media: v4l2-core: Add helpers to build the H264 P/B0/B1 reflists - media: hantro: h264: Use the generic H264 reflist builder - media: dt-bindings: rockchip: Document RK3399 Video Decoder bindings - media: rkvdec: Add the rkvdec driver - arm64: dts: rockchip: rk3399: Define the rockchip Video Decoder node - - .../bindings/media/rockchip,vdec.yaml | 73 ++ - MAINTAINERS | 7 + - arch/arm64/boot/dts/rockchip/rk3399.dtsi | 14 +- - drivers/media/v4l2-core/Kconfig | 4 + - drivers/media/v4l2-core/Makefile | 1 + - drivers/media/v4l2-core/v4l2-h264.c | 270 ++++ - drivers/staging/media/Kconfig | 2 + - drivers/staging/media/Makefile | 1 + - drivers/staging/media/hantro/Kconfig | 1 + - drivers/staging/media/hantro/hantro_h264.c | 237 +--- - drivers/staging/media/rkvdec/Kconfig | 15 + - drivers/staging/media/rkvdec/Makefile | 3 + - drivers/staging/media/rkvdec/TODO | 11 + - drivers/staging/media/rkvdec/rkvdec-h264.c | 1156 +++++++++++++++++ - drivers/staging/media/rkvdec/rkvdec-regs.h | 223 ++++ - drivers/staging/media/rkvdec/rkvdec.c | 1103 ++++++++++++++++ - drivers/staging/media/rkvdec/rkvdec.h | 121 ++ - include/media/h264-ctrls.h | 8 +- - include/media/v4l2-h264.h | 85 ++ - 19 files changed, 3104 insertions(+), 231 deletions(-) - create mode 100644 Documentation/devicetree/bindings/media/rockchip,vdec.yaml - create mode 100644 drivers/media/v4l2-core/v4l2-h264.c - create mode 100644 drivers/staging/media/rkvdec/Kconfig - create mode 100644 drivers/staging/media/rkvdec/Makefile - create mode 100644 drivers/staging/media/rkvdec/TODO - create mode 100644 drivers/staging/media/rkvdec/rkvdec-h264.c - create mode 100644 drivers/staging/media/rkvdec/rkvdec-regs.h - create mode 100644 drivers/staging/media/rkvdec/rkvdec.c - create mode 100644 drivers/staging/media/rkvdec/rkvdec.h - create mode 100644 include/media/v4l2-h264.h - --- -2.26.0.rc2 - - - -From ezequiel at collabora.com Fri Apr 3 15:13:41 2020 -From: ezequiel at collabora.com (Ezequiel Garcia) -Date: Fri, 3 Apr 2020 19:13:41 -0300 -Subject: [PATCH v8 1/5] media: v4l2-core: Add helpers to build the H264 - P/B0/B1 reflists -In-Reply-To: <20200403221345.16702-1-ezequiel@collabora.com> -References: <20200403221345.16702-1-ezequiel@collabora.com> -Message-ID: <20200403221345.16702-2-ezequiel@collabora.com> - -From: Boris Brezillon - -Building those list is a standard procedure described in section -'8.2.4 Decoding process for reference picture lists construction' of -the H264 specification. - -We already have 2 drivers needing the same logic (hantro and rkvdec) and -I suspect we will soon have more. - -Let's provide generic helpers to create those lists. - -Signed-off-by: Boris Brezillon -Signed-off-by: Ezequiel Garcia --- -v8: -* None. -v7: -* Replace magic numbers with macros, - as pointed out by Mauro. -* Prevent and WARN_ON() out of bounds access. ---- - drivers/media/v4l2-core/Kconfig | 4 + - drivers/media/v4l2-core/Makefile | 1 + - drivers/media/v4l2-core/v4l2-h264.c | 270 ++++++++++++++++++++++++++++ - include/media/h264-ctrls.h | 8 +- - include/media/v4l2-h264.h | 85 +++++++++ - 5 files changed, 367 insertions(+), 1 deletion(-) - create mode 100644 drivers/media/v4l2-core/v4l2-h264.c - create mode 100644 include/media/v4l2-h264.h - -diff --git a/drivers/media/v4l2-core/Kconfig b/drivers/media/v4l2-core/Kconfig -index 89809ec24779..db09e8b643fd 100644 ---- a/drivers/media/v4l2-core/Kconfig -+++ b/drivers/media/v4l2-core/Kconfig -@@ -49,6 +49,10 @@ config VIDEO_TUNER - config V4L2_JPEG_HELPER - tristate - -+# Used by drivers that need v4l2-h264.ko -+config V4L2_H264 -+ tristate -+ - # Used by drivers that need v4l2-mem2mem.ko - config V4L2_MEM2MEM_DEV - tristate -diff --git a/drivers/media/v4l2-core/Makefile b/drivers/media/v4l2-core/Makefile -index 144564656d22..2ef0c7c958a2 100644 ---- a/drivers/media/v4l2-core/Makefile -+++ b/drivers/media/v4l2-core/Makefile -@@ -21,6 +21,7 @@ obj-$(CONFIG_VIDEO_V4L2) += v4l2-dv-timings.o - obj-$(CONFIG_VIDEO_TUNER) += tuner.o - - obj-$(CONFIG_V4L2_MEM2MEM_DEV) += v4l2-mem2mem.o -+obj-$(CONFIG_V4L2_H264) += v4l2-h264.o - - obj-$(CONFIG_V4L2_FLASH_LED_CLASS) += v4l2-flash-led-class.o - -diff --git a/drivers/media/v4l2-core/v4l2-h264.c b/drivers/media/v4l2-core/v4l2-h264.c -new file mode 100644 -index 000000000000..edf6225f0522 ---- /dev/null -+++ b/drivers/media/v4l2-core/v4l2-h264.c -@@ -0,0 +1,270 @@ -+// SPDX-License-Identifier: GPL-2.0 -+/* -+ * V4L2 H264 helpers. -+ * -+ * Copyright (C) 2019 Collabora, Ltd. -+ * -+ * Author: Boris Brezillon -+ */ -+ -+#include -+#include -+ -+#include -+ -+/** -+ * v4l2_h264_init_reflist_builder() - Initialize a P/B0/B1 reference list -+ * builder -+ * -+ * @b: the builder context to initialize -+ * @dec_params: decode parameters control -+ * @slice_params: first slice parameters control -+ * @sps: SPS control -+ * @dpb: DPB to use when creating the reference list -+ */ -+void -+v4l2_h264_init_reflist_builder(struct v4l2_h264_reflist_builder *b, -+ const struct v4l2_ctrl_h264_decode_params *dec_params, -+ const struct v4l2_ctrl_h264_slice_params *slice_params, -+ const struct v4l2_ctrl_h264_sps *sps, -+ const struct v4l2_h264_dpb_entry dpb[V4L2_H264_NUM_DPB_ENTRIES]) -+{ -+ int cur_frame_num, max_frame_num; -+ unsigned int i; -+ -+ max_frame_num = 1 << (sps->log2_max_frame_num_minus4 + 4); -+ cur_frame_num = slice_params->frame_num; -+ -+ memset(b, 0, sizeof(*b)); -+ if (!(slice_params->flags & V4L2_H264_SLICE_FLAG_FIELD_PIC)) -+ b->cur_pic_order_count = min(dec_params->bottom_field_order_cnt, -+ dec_params->top_field_order_cnt); -+ else if (slice_params->flags & V4L2_H264_SLICE_FLAG_BOTTOM_FIELD) -+ b->cur_pic_order_count = dec_params->bottom_field_order_cnt; -+ else -+ b->cur_pic_order_count = dec_params->top_field_order_cnt; -+ -+ for (i = 0; i < V4L2_H264_NUM_DPB_ENTRIES; i++) { -+ u32 pic_order_count; -+ -+ if (!(dpb[i].flags & V4L2_H264_DPB_ENTRY_FLAG_ACTIVE)) -+ continue; -+ -+ b->refs[i].pic_num = dpb[i].pic_num; -+ if (dpb[i].flags & V4L2_H264_DPB_ENTRY_FLAG_LONG_TERM) -+ b->refs[i].longterm = true; -+ -+ /* -+ * Handle frame_num wraparound as described in section -+ * '8.2.4.1 Decoding process for picture numbers' of the spec. -+ * TODO: This logic will have to be adjusted when we start -+ * supporting interlaced content. -+ */ -+ if (dpb[i].frame_num > cur_frame_num) -+ b->refs[i].frame_num = (int)dpb[i].frame_num - -+ max_frame_num; -+ else -+ b->refs[i].frame_num = dpb[i].frame_num; -+ -+ if (!(dpb[i].flags & V4L2_H264_DPB_ENTRY_FLAG_FIELD)) -+ pic_order_count = min(dpb[i].top_field_order_cnt, -+ dpb[i].bottom_field_order_cnt); -+ else if (dpb[i].flags & V4L2_H264_DPB_ENTRY_FLAG_BOTTOM_FIELD) -+ pic_order_count = dpb[i].bottom_field_order_cnt; -+ else -+ pic_order_count = dpb[i].top_field_order_cnt; -+ -+ b->refs[i].pic_order_count = pic_order_count; -+ b->unordered_reflist[b->num_valid] = i; -+ b->num_valid++; -+ } -+ -+ for (i = b->num_valid; i < ARRAY_SIZE(b->unordered_reflist); i++) -+ b->unordered_reflist[i] = i; -+} -+EXPORT_SYMBOL_GPL(v4l2_h264_init_reflist_builder); -+ -+static int v4l2_h264_p_ref_list_cmp(const void *ptra, const void *ptrb, -+ const void *data) -+{ -+ const struct v4l2_h264_reflist_builder *builder = data; -+ u8 idxa, idxb; -+ -+ idxa = *((u8 *)ptra); -+ idxb = *((u8 *)ptrb); -+ -+ if (WARN_ON(idxa >= V4L2_H264_NUM_DPB_ENTRIES || -+ idxb >= V4L2_H264_NUM_DPB_ENTRIES)) -+ return 1; -+ -+ if (builder->refs[idxa].longterm != builder->refs[idxb].longterm) { -+ /* Short term pics first. */ -+ if (!builder->refs[idxa].longterm) -+ return -1; -+ else -+ return 1; -+ } -+ -+ /* -+ * Short term pics in descending pic num order, long term ones in -+ * ascending order. -+ */ -+ if (!builder->refs[idxa].longterm) -+ return builder->refs[idxb].frame_num < -+ builder->refs[idxa].frame_num ? -+ -1 : 1; -+ -+ return builder->refs[idxa].pic_num < builder->refs[idxb].pic_num ? -+ -1 : 1; -+} -+ -+static int v4l2_h264_b0_ref_list_cmp(const void *ptra, const void *ptrb, -+ const void *data) -+{ -+ const struct v4l2_h264_reflist_builder *builder = data; -+ s32 poca, pocb; -+ u8 idxa, idxb; -+ -+ idxa = *((u8 *)ptra); -+ idxb = *((u8 *)ptrb); -+ -+ if (WARN_ON(idxa >= V4L2_H264_NUM_DPB_ENTRIES || -+ idxb >= V4L2_H264_NUM_DPB_ENTRIES)) -+ return 1; -+ -+ if (builder->refs[idxa].longterm != builder->refs[idxb].longterm) { -+ /* Short term pics first. */ -+ if (!builder->refs[idxa].longterm) -+ return -1; -+ else -+ return 1; -+ } -+ -+ /* Long term pics in ascending pic num order. */ -+ if (builder->refs[idxa].longterm) -+ return builder->refs[idxa].pic_num < -+ builder->refs[idxb].pic_num ? -+ -1 : 1; -+ -+ poca = builder->refs[idxa].pic_order_count; -+ pocb = builder->refs[idxb].pic_order_count; -+ -+ /* -+ * Short term pics with POC < cur POC first in POC descending order -+ * followed by short term pics with POC > cur POC in POC ascending -+ * order. -+ */ -+ if ((poca < builder->cur_pic_order_count) != -+ (pocb < builder->cur_pic_order_count)) -+ return poca < pocb ? -1 : 1; -+ else if (poca < builder->cur_pic_order_count) -+ return pocb < poca ? -1 : 1; -+ -+ return poca < pocb ? -1 : 1; -+} -+ -+static int v4l2_h264_b1_ref_list_cmp(const void *ptra, const void *ptrb, -+ const void *data) -+{ -+ const struct v4l2_h264_reflist_builder *builder = data; -+ s32 poca, pocb; -+ u8 idxa, idxb; -+ -+ idxa = *((u8 *)ptra); -+ idxb = *((u8 *)ptrb); -+ -+ if (WARN_ON(idxa >= V4L2_H264_NUM_DPB_ENTRIES || -+ idxb >= V4L2_H264_NUM_DPB_ENTRIES)) -+ return 1; -+ -+ if (builder->refs[idxa].longterm != builder->refs[idxb].longterm) { -+ /* Short term pics first. */ -+ if (!builder->refs[idxa].longterm) -+ return -1; -+ else -+ return 1; -+ } -+ -+ /* Long term pics in ascending pic num order. */ -+ if (builder->refs[idxa].longterm) -+ return builder->refs[idxa].pic_num < -+ builder->refs[idxb].pic_num ? -+ -1 : 1; -+ -+ poca = builder->refs[idxa].pic_order_count; -+ pocb = builder->refs[idxb].pic_order_count; -+ -+ /* -+ * Short term pics with POC > cur POC first in POC ascending order -+ * followed by short term pics with POC < cur POC in POC descending -+ * order. -+ */ -+ if ((poca < builder->cur_pic_order_count) != -+ (pocb < builder->cur_pic_order_count)) -+ return pocb < poca ? -1 : 1; -+ else if (poca < builder->cur_pic_order_count) -+ return pocb < poca ? -1 : 1; -+ -+ return poca < pocb ? -1 : 1; -+} -+ -+/** -+ * v4l2_h264_build_p_ref_list() - Build the P reference list -+ * -+ * @builder: reference list builder context -+ * @reflist: 16-bytes array used to store the P reference list. Each entry -+ * is an index in the DPB -+ * -+ * This functions builds the P reference lists. This procedure is describe in -+ * section '8.2.4 Decoding process for reference picture lists construction' -+ * of the H264 spec. This function can be used by H264 decoder drivers that -+ * need to pass a P reference list to the hardware. -+ */ -+void -+v4l2_h264_build_p_ref_list(const struct v4l2_h264_reflist_builder *builder, -+ u8 *reflist) -+{ -+ memcpy(reflist, builder->unordered_reflist, -+ sizeof(builder->unordered_reflist[0]) * builder->num_valid); -+ sort_r(reflist, builder->num_valid, sizeof(*reflist), -+ v4l2_h264_p_ref_list_cmp, NULL, builder); -+} -+EXPORT_SYMBOL_GPL(v4l2_h264_build_p_ref_list); -+ -+/** -+ * v4l2_h264_build_b_ref_lists() - Build the B0/B1 reference lists -+ * -+ * @builder: reference list builder context -+ * @b0_reflist: 16-bytes array used to store the B0 reference list. Each entry -+ * is an index in the DPB -+ * @b1_reflist: 16-bytes array used to store the B1 reference list. Each entry -+ * is an index in the DPB -+ * -+ * This functions builds the B0/B1 reference lists. This procedure is described -+ * in section '8.2.4 Decoding process for reference picture lists construction' -+ * of the H264 spec. This function can be used by H264 decoder drivers that -+ * need to pass B0/B1 reference lists to the hardware. -+ */ -+void -+v4l2_h264_build_b_ref_lists(const struct v4l2_h264_reflist_builder *builder, -+ u8 *b0_reflist, u8 *b1_reflist) -+{ -+ memcpy(b0_reflist, builder->unordered_reflist, -+ sizeof(builder->unordered_reflist[0]) * builder->num_valid); -+ sort_r(b0_reflist, builder->num_valid, sizeof(*b0_reflist), -+ v4l2_h264_b0_ref_list_cmp, NULL, builder); -+ -+ memcpy(b1_reflist, builder->unordered_reflist, -+ sizeof(builder->unordered_reflist[0]) * builder->num_valid); -+ sort_r(b1_reflist, builder->num_valid, sizeof(*b1_reflist), -+ v4l2_h264_b1_ref_list_cmp, NULL, builder); -+ -+ if (builder->num_valid > 1 && -+ !memcmp(b1_reflist, b0_reflist, builder->num_valid)) -+ swap(b1_reflist[0], b1_reflist[1]); -+} -+EXPORT_SYMBOL_GPL(v4l2_h264_build_b_ref_lists); -+ -+MODULE_LICENSE("GPL"); -+MODULE_DESCRIPTION("V4L2 H264 Helpers"); -+MODULE_AUTHOR("Boris Brezillon "); -diff --git a/include/media/h264-ctrls.h b/include/media/h264-ctrls.h -index 1c6ff7d63bca..080fd1293c42 100644 ---- a/include/media/h264-ctrls.h -+++ b/include/media/h264-ctrls.h -@@ -13,6 +13,12 @@ - - #include - -+/* -+ * Maximum DPB size, as specified by section 'A.3.1 Level limits -+ * common to the Baseline, Main, and Extended profiles'. -+ */ -+#define V4L2_H264_NUM_DPB_ENTRIES 16 -+ - /* Our pixel format isn't stable at the moment */ - #define V4L2_PIX_FMT_H264_SLICE v4l2_fourcc('S', '2', '6', '4') /* H264 parsed slices */ - -@@ -201,7 +207,7 @@ struct v4l2_h264_dpb_entry { - #define V4L2_H264_DECODE_PARAM_FLAG_IDR_PIC 0x01 - - struct v4l2_ctrl_h264_decode_params { -- struct v4l2_h264_dpb_entry dpb[16]; -+ struct v4l2_h264_dpb_entry dpb[V4L2_H264_NUM_DPB_ENTRIES]; - __u16 num_slices; - __u16 nal_ref_idc; - __s32 top_field_order_cnt; -diff --git a/include/media/v4l2-h264.h b/include/media/v4l2-h264.h -new file mode 100644 -index 000000000000..bc9ebb560ccf ---- /dev/null -+++ b/include/media/v4l2-h264.h -@@ -0,0 +1,85 @@ -+/* SPDX-License-Identifier: GPL-2.0-or-later */ -+/* -+ * Helper functions for H264 codecs. -+ * -+ * Copyright (c) 2019 Collabora, Ltd. -+ * -+ * Author: Boris Brezillon -+ */ -+ -+#ifndef _MEDIA_V4L2_H264_H -+#define _MEDIA_V4L2_H264_H -+ -+#include -+ -+/** -+ * struct v4l2_h264_reflist_builder - Reference list builder object -+ * -+ * @refs.pic_order_count: reference picture order count -+ * @refs.frame_num: reference frame number -+ * @refs.pic_num: reference picture number -+ * @refs.longterm: set to true for a long term reference -+ * @refs: array of references -+ * @cur_pic_order_count: picture order count of the frame being decoded -+ * @unordered_reflist: unordered list of references. Will be used to generate -+ * ordered P/B0/B1 lists -+ * @num_valid: number of valid references in the refs array -+ * -+ * This object stores the context of the P/B0/B1 reference list builder. -+ * This procedure is described in section '8.2.4 Decoding process for reference -+ * picture lists construction' of the H264 spec. -+ */ -+struct v4l2_h264_reflist_builder { -+ struct { -+ s32 pic_order_count; -+ int frame_num; -+ u16 pic_num; -+ u16 longterm : 1; -+ } refs[V4L2_H264_NUM_DPB_ENTRIES]; -+ s32 cur_pic_order_count; -+ u8 unordered_reflist[V4L2_H264_NUM_DPB_ENTRIES]; -+ u8 num_valid; -+}; -+ -+void -+v4l2_h264_init_reflist_builder(struct v4l2_h264_reflist_builder *b, -+ const struct v4l2_ctrl_h264_decode_params *dec_params, -+ const struct v4l2_ctrl_h264_slice_params *slice_params, -+ const struct v4l2_ctrl_h264_sps *sps, -+ const struct v4l2_h264_dpb_entry dpb[V4L2_H264_NUM_DPB_ENTRIES]); -+ -+/** -+ * v4l2_h264_build_b_ref_lists() - Build the B0/B1 reference lists -+ * -+ * @builder: reference list builder context -+ * @b0_reflist: 16-bytes array used to store the B0 reference list. Each entry -+ * is an index in the DPB -+ * @b1_reflist: 16-bytes array used to store the B1 reference list. Each entry -+ * is an index in the DPB -+ * -+ * This functions builds the B0/B1 reference lists. This procedure is described -+ * in section '8.2.4 Decoding process for reference picture lists construction' -+ * of the H264 spec. This function can be used by H264 decoder drivers that -+ * need to pass B0/B1 reference lists to the hardware. -+ */ -+void -+v4l2_h264_build_b_ref_lists(const struct v4l2_h264_reflist_builder *builder, -+ u8 *b0_reflist, u8 *b1_reflist); -+ -+/** -+ * v4l2_h264_build_b_ref_lists() - Build the P reference list -+ * -+ * @builder: reference list builder context -+ * @p_reflist: 16-bytes array used to store the P reference list. Each entry -+ * is an index in the DPB -+ * -+ * This functions builds the P reference lists. This procedure is describe in -+ * section '8.2.4 Decoding process for reference picture lists construction' -+ * of the H264 spec. This function can be used by H264 decoder drivers that -+ * need to pass a P reference list to the hardware. -+ */ -+void -+v4l2_h264_build_p_ref_list(const struct v4l2_h264_reflist_builder *builder, -+ u8 *reflist); -+ -+#endif /* _MEDIA_V4L2_H264_H */ --- -2.26.0.rc2 - - - -From ezequiel at collabora.com Fri Apr 3 15:13:42 2020 -From: ezequiel at collabora.com (Ezequiel Garcia) -Date: Fri, 3 Apr 2020 19:13:42 -0300 -Subject: [PATCH v8 2/5] media: hantro: h264: Use the generic H264 reflist - builder -In-Reply-To: <20200403221345.16702-1-ezequiel@collabora.com> -References: <20200403221345.16702-1-ezequiel@collabora.com> -Message-ID: <20200403221345.16702-3-ezequiel@collabora.com> - -From: Boris Brezillon - -Now that the core provides generic reflist builders, we can use them -instead of implementing our own. - -Signed-off-by: Boris Brezillon -Signed-off-by: Ezequiel Garcia ---- -v8: -* None. ---- - drivers/staging/media/hantro/Kconfig | 1 + - drivers/staging/media/hantro/hantro_h264.c | 237 +-------------------- - 2 files changed, 9 insertions(+), 229 deletions(-) - -diff --git a/drivers/staging/media/hantro/Kconfig b/drivers/staging/media/hantro/Kconfig -index 99aed9a5b0b9..868fe2ad439e 100644 ---- a/drivers/staging/media/hantro/Kconfig -+++ b/drivers/staging/media/hantro/Kconfig -@@ -7,6 +7,7 @@ config VIDEO_HANTRO - select VIDEOBUF2_DMA_CONTIG - select VIDEOBUF2_VMALLOC - select V4L2_MEM2MEM_DEV -+ select V4L2_H264 - help - Support for the Hantro IP based Video Processing Units present on - Rockchip and NXP i.MX8M SoCs, which accelerate video and image -diff --git a/drivers/staging/media/hantro/hantro_h264.c b/drivers/staging/media/hantro/hantro_h264.c -index f2d3e81fb6ce..d561f125085a 100644 ---- a/drivers/staging/media/hantro/hantro_h264.c -+++ b/drivers/staging/media/hantro/hantro_h264.c -@@ -11,7 +11,7 @@ - */ - - #include --#include -+#include - #include - - #include "hantro.h" -@@ -240,229 +240,6 @@ static void prepare_table(struct hantro_ctx *ctx) - reorder_scaling_list(ctx); - } - --struct hantro_h264_reflist_builder { -- const struct v4l2_h264_dpb_entry *dpb; -- s32 pocs[HANTRO_H264_DPB_SIZE]; -- u8 unordered_reflist[HANTRO_H264_DPB_SIZE]; -- int frame_nums[HANTRO_H264_DPB_SIZE]; -- s32 curpoc; -- u8 num_valid; --}; -- --static s32 get_poc(enum v4l2_field field, s32 top_field_order_cnt, -- s32 bottom_field_order_cnt) --{ -- switch (field) { -- case V4L2_FIELD_TOP: -- return top_field_order_cnt; -- case V4L2_FIELD_BOTTOM: -- return bottom_field_order_cnt; -- default: -- break; -- } -- -- return min(top_field_order_cnt, bottom_field_order_cnt); --} -- --static void --init_reflist_builder(struct hantro_ctx *ctx, -- struct hantro_h264_reflist_builder *b) --{ -- const struct v4l2_ctrl_h264_slice_params *slice_params; -- const struct v4l2_ctrl_h264_decode_params *dec_param; -- const struct v4l2_ctrl_h264_sps *sps; -- struct vb2_v4l2_buffer *buf = hantro_get_dst_buf(ctx); -- const struct v4l2_h264_dpb_entry *dpb = ctx->h264_dec.dpb; -- struct vb2_queue *cap_q = &ctx->fh.m2m_ctx->cap_q_ctx.q; -- int cur_frame_num, max_frame_num; -- unsigned int i; -- -- dec_param = ctx->h264_dec.ctrls.decode; -- slice_params = &ctx->h264_dec.ctrls.slices[0]; -- sps = ctx->h264_dec.ctrls.sps; -- max_frame_num = 1 << (sps->log2_max_frame_num_minus4 + 4); -- cur_frame_num = slice_params->frame_num; -- -- memset(b, 0, sizeof(*b)); -- b->dpb = dpb; -- b->curpoc = get_poc(buf->field, dec_param->top_field_order_cnt, -- dec_param->bottom_field_order_cnt); -- -- for (i = 0; i < ARRAY_SIZE(ctx->h264_dec.dpb); i++) { -- int buf_idx; -- -- if (!(dpb[i].flags & V4L2_H264_DPB_ENTRY_FLAG_ACTIVE)) -- continue; -- -- buf_idx = vb2_find_timestamp(cap_q, dpb[i].reference_ts, 0); -- if (buf_idx < 0) -- continue; -- -- buf = to_vb2_v4l2_buffer(vb2_get_buffer(cap_q, buf_idx)); -- -- /* -- * Handle frame_num wraparound as described in section -- * '8.2.4.1 Decoding process for picture numbers' of the spec. -- * TODO: This logic will have to be adjusted when we start -- * supporting interlaced content. -- */ -- if (dpb[i].frame_num > cur_frame_num) -- b->frame_nums[i] = (int)dpb[i].frame_num - max_frame_num; -- else -- b->frame_nums[i] = dpb[i].frame_num; -- -- b->pocs[i] = get_poc(buf->field, dpb[i].top_field_order_cnt, -- dpb[i].bottom_field_order_cnt); -- b->unordered_reflist[b->num_valid] = i; -- b->num_valid++; -- } -- -- for (i = b->num_valid; i < ARRAY_SIZE(ctx->h264_dec.dpb); i++) -- b->unordered_reflist[i] = i; --} -- --static int p_ref_list_cmp(const void *ptra, const void *ptrb, const void *data) --{ -- const struct hantro_h264_reflist_builder *builder = data; -- const struct v4l2_h264_dpb_entry *a, *b; -- u8 idxa, idxb; -- -- idxa = *((u8 *)ptra); -- idxb = *((u8 *)ptrb); -- a = &builder->dpb[idxa]; -- b = &builder->dpb[idxb]; -- -- if ((a->flags & V4L2_H264_DPB_ENTRY_FLAG_LONG_TERM) != -- (b->flags & V4L2_H264_DPB_ENTRY_FLAG_LONG_TERM)) { -- /* Short term pics firt. */ -- if (!(a->flags & V4L2_H264_DPB_ENTRY_FLAG_LONG_TERM)) -- return -1; -- else -- return 1; -- } -- -- /* -- * Short term pics in descending pic num order, long term ones in -- * ascending order. -- */ -- if (!(a->flags & V4L2_H264_DPB_ENTRY_FLAG_LONG_TERM)) -- return HANTRO_CMP(builder->frame_nums[idxb], -- builder->frame_nums[idxa]); -- -- return HANTRO_CMP(a->pic_num, b->pic_num); --} -- --static int b0_ref_list_cmp(const void *ptra, const void *ptrb, const void *data) --{ -- const struct hantro_h264_reflist_builder *builder = data; -- const struct v4l2_h264_dpb_entry *a, *b; -- s32 poca, pocb; -- u8 idxa, idxb; -- -- idxa = *((u8 *)ptra); -- idxb = *((u8 *)ptrb); -- a = &builder->dpb[idxa]; -- b = &builder->dpb[idxb]; -- -- if ((a->flags & V4L2_H264_DPB_ENTRY_FLAG_LONG_TERM) != -- (b->flags & V4L2_H264_DPB_ENTRY_FLAG_LONG_TERM)) { -- /* Short term pics firt. */ -- if (!(a->flags & V4L2_H264_DPB_ENTRY_FLAG_LONG_TERM)) -- return -1; -- else -- return 1; -- } -- -- /* Long term pics in ascending pic num order. */ -- if (a->flags & V4L2_H264_DPB_ENTRY_FLAG_LONG_TERM) -- return HANTRO_CMP(a->pic_num, b->pic_num); -- -- poca = builder->pocs[idxa]; -- pocb = builder->pocs[idxb]; -- -- /* -- * Short term pics with POC < cur POC first in POC descending order -- * followed by short term pics with POC > cur POC in POC ascending -- * order. -- */ -- if ((poca < builder->curpoc) != (pocb < builder->curpoc)) -- return HANTRO_CMP(poca, pocb); -- else if (poca < builder->curpoc) -- return HANTRO_CMP(pocb, poca); -- -- return HANTRO_CMP(poca, pocb); --} -- --static int b1_ref_list_cmp(const void *ptra, const void *ptrb, const void *data) --{ -- const struct hantro_h264_reflist_builder *builder = data; -- const struct v4l2_h264_dpb_entry *a, *b; -- s32 poca, pocb; -- u8 idxa, idxb; -- -- idxa = *((u8 *)ptra); -- idxb = *((u8 *)ptrb); -- a = &builder->dpb[idxa]; -- b = &builder->dpb[idxb]; -- -- if ((a->flags & V4L2_H264_DPB_ENTRY_FLAG_LONG_TERM) != -- (b->flags & V4L2_H264_DPB_ENTRY_FLAG_LONG_TERM)) { -- /* Short term pics firt. */ -- if (!(a->flags & V4L2_H264_DPB_ENTRY_FLAG_LONG_TERM)) -- return -1; -- else -- return 1; -- } -- -- /* Long term pics in ascending pic num order. */ -- if (a->flags & V4L2_H264_DPB_ENTRY_FLAG_LONG_TERM) -- return HANTRO_CMP(a->pic_num, b->pic_num); -- -- poca = builder->pocs[idxa]; -- pocb = builder->pocs[idxb]; -- -- /* -- * Short term pics with POC > cur POC first in POC ascending order -- * followed by short term pics with POC < cur POC in POC descending -- * order. -- */ -- if ((poca < builder->curpoc) != (pocb < builder->curpoc)) -- return HANTRO_CMP(pocb, poca); -- else if (poca < builder->curpoc) -- return HANTRO_CMP(pocb, poca); -- -- return HANTRO_CMP(poca, pocb); --} -- --static void --build_p_ref_list(const struct hantro_h264_reflist_builder *builder, -- u8 *reflist) --{ -- memcpy(reflist, builder->unordered_reflist, -- sizeof(builder->unordered_reflist)); -- sort_r(reflist, builder->num_valid, sizeof(*reflist), -- p_ref_list_cmp, NULL, builder); --} -- --static void --build_b_ref_lists(const struct hantro_h264_reflist_builder *builder, -- u8 *b0_reflist, u8 *b1_reflist) --{ -- memcpy(b0_reflist, builder->unordered_reflist, -- sizeof(builder->unordered_reflist)); -- sort_r(b0_reflist, builder->num_valid, sizeof(*b0_reflist), -- b0_ref_list_cmp, NULL, builder); -- -- memcpy(b1_reflist, builder->unordered_reflist, -- sizeof(builder->unordered_reflist)); -- sort_r(b1_reflist, builder->num_valid, sizeof(*b1_reflist), -- b1_ref_list_cmp, NULL, builder); -- -- if (builder->num_valid > 1 && -- !memcmp(b1_reflist, b0_reflist, builder->num_valid)) -- swap(b1_reflist[0], b1_reflist[1]); --} -- - static bool dpb_entry_match(const struct v4l2_h264_dpb_entry *a, - const struct v4l2_h264_dpb_entry *b) - { -@@ -560,7 +337,7 @@ int hantro_h264_dec_prepare_run(struct hantro_ctx *ctx) - { - struct hantro_h264_dec_hw_ctx *h264_ctx = &ctx->h264_dec; - struct hantro_h264_dec_ctrls *ctrls = &h264_ctx->ctrls; -- struct hantro_h264_reflist_builder reflist_builder; -+ struct v4l2_h264_reflist_builder reflist_builder; - - hantro_start_prepare_run(ctx); - -@@ -596,10 +373,12 @@ int hantro_h264_dec_prepare_run(struct hantro_ctx *ctx) - prepare_table(ctx); - - /* Build the P/B{0,1} ref lists. */ -- init_reflist_builder(ctx, &reflist_builder); -- build_p_ref_list(&reflist_builder, h264_ctx->reflists.p); -- build_b_ref_lists(&reflist_builder, h264_ctx->reflists.b0, -- h264_ctx->reflists.b1); -+ v4l2_h264_init_reflist_builder(&reflist_builder, ctrls->decode, -+ &ctrls->slices[0], ctrls->sps, -+ ctx->h264_dec.dpb); -+ v4l2_h264_build_p_ref_list(&reflist_builder, h264_ctx->reflists.p); -+ v4l2_h264_build_b_ref_lists(&reflist_builder, h264_ctx->reflists.b0, -+ h264_ctx->reflists.b1); - return 0; - } - --- -2.26.0.rc2 - - - -From ezequiel at collabora.com Fri Apr 3 15:13:43 2020 -From: ezequiel at collabora.com (Ezequiel Garcia) -Date: Fri, 3 Apr 2020 19:13:43 -0300 -Subject: [PATCH v8 3/5] media: dt-bindings: rockchip: Document RK3399 Video - Decoder bindings -In-Reply-To: <20200403221345.16702-1-ezequiel@collabora.com> -References: <20200403221345.16702-1-ezequiel@collabora.com> -Message-ID: <20200403221345.16702-4-ezequiel@collabora.com> - -From: Boris Brezillon - -Document the Rockchip RK3399 Video Decoder bindings. - -Signed-off-by: Boris Brezillon -Reviewed-by: Rob Herring -Signed-off-by: Ezequiel Garcia ---- -v8: -* None. ---- - .../bindings/media/rockchip,vdec.yaml | 73 +++++++++++++++++++ - 1 file changed, 73 insertions(+) - create mode 100644 Documentation/devicetree/bindings/media/rockchip,vdec.yaml - -diff --git a/Documentation/devicetree/bindings/media/rockchip,vdec.yaml b/Documentation/devicetree/bindings/media/rockchip,vdec.yaml -new file mode 100644 -index 000000000000..0c68cdad9a31 ---- /dev/null -+++ b/Documentation/devicetree/bindings/media/rockchip,vdec.yaml -@@ -0,0 +1,73 @@ -+# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause) -+%YAML 1.2 -+--- -+$id: http://devicetree.org/schemas/media/rockchip,vdec.yaml# -+$schema: http://devicetree.org/meta-schemas/core.yaml# -+ -+title: Rockchip Video Decoder (VDec) Device Tree Bindings -+ -+maintainers: -+ - Heiko Stuebner -+ -+description: |- -+ The Rockchip rk3399 has a stateless Video Decoder that can decodes H.264, -+ HEVC an VP9 streams. -+ -+properties: -+ compatible: -+ const: rockchip,rk3399-vdec -+ -+ reg: -+ maxItems: 1 -+ -+ interrupts: -+ maxItems: 1 -+ -+ clocks: -+ items: -+ - description: The Video Decoder AXI interface clock -+ - description: The Video Decoder AHB interface clock -+ - description: The Video Decoded CABAC clock -+ - description: The Video Decoder core clock -+ -+ clock-names: -+ items: -+ - const: axi -+ - const: ahb -+ - const: cabac -+ - const: core -+ -+ power-domains: -+ maxItems: 1 -+ -+ iommus: -+ maxItems: 1 -+ -+required: -+ - compatible -+ - reg -+ - interrupts -+ - clocks -+ - clock-names -+ - power-domains -+ -+additionalProperties: false -+ -+examples: -+ - | -+ #include -+ #include -+ #include -+ -+ vdec: video-codec at ff660000 { -+ compatible = "rockchip,rk3399-vdec"; -+ reg = <0x0 0xff660000 0x0 0x400>; -+ interrupts = ; -+ clocks = <&cru ACLK_VDU>, <&cru HCLK_VDU>, -+ <&cru SCLK_VDU_CA>, <&cru SCLK_VDU_CORE>; -+ clock-names = "axi", "ahb", "cabac", "core"; -+ power-domains = <&power RK3399_PD_VDU>; -+ iommus = <&vdec_mmu>; -+ }; -+ -+... --- -2.26.0.rc2 - - - -From ezequiel at collabora.com Fri Apr 3 15:13:44 2020 -From: ezequiel at collabora.com (Ezequiel Garcia) -Date: Fri, 3 Apr 2020 19:13:44 -0300 -Subject: [PATCH v8 4/5] media: rkvdec: Add the rkvdec driver -In-Reply-To: <20200403221345.16702-1-ezequiel@collabora.com> -References: <20200403221345.16702-1-ezequiel@collabora.com> -Message-ID: <20200403221345.16702-5-ezequiel@collabora.com> - -From: Boris Brezillon - -The rockchip vdec block is a stateless decoder that's able to decode -H264, HEVC and VP9 content. This commit adds the core infrastructure -and the H264 backend. Support for VP9 and HEVS will be added later on. - -Signed-off-by: Boris Brezillon -Signed-off-by: Ezequiel Garcia --- -v8: -* Fix kfree and style changes, as suggested by Andriy. -v7: -* hverkuil-cisco at xs4all.nl: replaced VFL_TYPE_GRABBER by _VIDEO -* Use macros and ARRAY_SIZE instead of magic numbers, - as suggested by Mauro. -* Renamed M_N macro, suggested by Mauro. -* Use v4l2_m2m_buf_done_and_job_finish. -* Set buffers' zeroth plane payload in .buf_prepare -* Refactor try/s_fmt for spec compliance. ---- - MAINTAINERS | 7 + - drivers/staging/media/Kconfig | 2 + - drivers/staging/media/Makefile | 1 + - drivers/staging/media/rkvdec/Kconfig | 15 + - drivers/staging/media/rkvdec/Makefile | 3 + - drivers/staging/media/rkvdec/TODO | 11 + - drivers/staging/media/rkvdec/rkvdec-h264.c | 1156 ++++++++++++++++++++ - drivers/staging/media/rkvdec/rkvdec-regs.h | 223 ++++ - drivers/staging/media/rkvdec/rkvdec.c | 1103 +++++++++++++++++++ - drivers/staging/media/rkvdec/rkvdec.h | 121 ++ - 10 files changed, 2642 insertions(+) - create mode 100644 drivers/staging/media/rkvdec/Kconfig - create mode 100644 drivers/staging/media/rkvdec/Makefile - create mode 100644 drivers/staging/media/rkvdec/TODO - create mode 100644 drivers/staging/media/rkvdec/rkvdec-h264.c - create mode 100644 drivers/staging/media/rkvdec/rkvdec-regs.h - create mode 100644 drivers/staging/media/rkvdec/rkvdec.c - create mode 100644 drivers/staging/media/rkvdec/rkvdec.h - -diff --git a/MAINTAINERS b/MAINTAINERS -index 2b8b3e7f3df3..3cd32c54dcec 100644 ---- a/MAINTAINERS -+++ b/MAINTAINERS -@@ -14298,6 +14298,13 @@ F: drivers/hid/hid-roccat* - F: include/linux/hid-roccat* - F: Documentation/ABI/*/sysfs-driver-hid-roccat* - -+ROCKCHIP VIDEO DECODER DRIVER -+M: Ezequiel Garcia -+L: linux-media at vger.kernel.org -+S: Maintained -+F: drivers/staging/media/rkvdec/ -+F: Documentation/devicetree/bindings/media/rockchip,vdec.yaml -+ - ROCKCHIP ISP V1 DRIVER - M: Helen Koike - L: linux-media at vger.kernel.org -diff --git a/drivers/staging/media/Kconfig b/drivers/staging/media/Kconfig -index e59a846bc909..c6b4fb5d48b4 100644 ---- a/drivers/staging/media/Kconfig -+++ b/drivers/staging/media/Kconfig -@@ -30,6 +30,8 @@ source "drivers/staging/media/meson/vdec/Kconfig" - - source "drivers/staging/media/omap4iss/Kconfig" - -+source "drivers/staging/media/rkvdec/Kconfig" -+ - source "drivers/staging/media/sunxi/Kconfig" - - source "drivers/staging/media/tegra-vde/Kconfig" -diff --git a/drivers/staging/media/Makefile b/drivers/staging/media/Makefile -index 23c682461b62..8b24be1a7076 100644 ---- a/drivers/staging/media/Makefile -+++ b/drivers/staging/media/Makefile -@@ -3,6 +3,7 @@ obj-$(CONFIG_VIDEO_ALLEGRO_DVT) += allegro-dvt/ - obj-$(CONFIG_VIDEO_IMX_MEDIA) += imx/ - obj-$(CONFIG_VIDEO_MESON_VDEC) += meson/vdec/ - obj-$(CONFIG_VIDEO_OMAP4) += omap4iss/ -+obj-$(CONFIG_VIDEO_ROCKCHIP_VDEC) += rkvdec/ - obj-$(CONFIG_VIDEO_SUNXI) += sunxi/ - obj-$(CONFIG_TEGRA_VDE) += tegra-vde/ - obj-$(CONFIG_VIDEO_HANTRO) += hantro/ -diff --git a/drivers/staging/media/rkvdec/Kconfig b/drivers/staging/media/rkvdec/Kconfig -new file mode 100644 -index 000000000000..a22756deded7 ---- /dev/null -+++ b/drivers/staging/media/rkvdec/Kconfig -@@ -0,0 +1,15 @@ -+# SPDX-License-Identifier: GPL-2.0 -+config VIDEO_ROCKCHIP_VDEC -+ tristate "Rockchip Video Decoder driver" -+ depends on ARCH_ROCKCHIP || COMPILE_TEST -+ depends on VIDEO_DEV && VIDEO_V4L2 && MEDIA_CONTROLLER -+ depends on MEDIA_CONTROLLER_REQUEST_API -+ select VIDEOBUF2_DMA_CONTIG -+ select VIDEOBUF2_VMALLOC -+ select V4L2_MEM2MEM_DEV -+ select V4L2_H264 -+ help -+ Support for the Rockchip Video Decoder IP present on Rockchip SoCs, -+ which accelerates video decoding. -+ To compile this driver as a module, choose M here: the module -+ will be called rockchip-vdec. -diff --git a/drivers/staging/media/rkvdec/Makefile b/drivers/staging/media/rkvdec/Makefile -new file mode 100644 -index 000000000000..c08fed0a39f9 ---- /dev/null -+++ b/drivers/staging/media/rkvdec/Makefile -@@ -0,0 +1,3 @@ -+obj-$(CONFIG_VIDEO_ROCKCHIP_VDEC) += rockchip-vdec.o -+ -+rockchip-vdec-y += rkvdec.o rkvdec-h264.o -diff --git a/drivers/staging/media/rkvdec/TODO b/drivers/staging/media/rkvdec/TODO -new file mode 100644 -index 000000000000..e0f0f12f0ac5 ---- /dev/null -+++ b/drivers/staging/media/rkvdec/TODO -@@ -0,0 +1,11 @@ -+* Support for VP9 is planned for this driver. -+ -+ Given the V4L controls for those CODECs will be part of -+ the uABI, it will be required to have the driver in staging. -+ -+ For this reason, we are keeping this driver in staging for now. -+ -+* Evaluate introducing a helper to consolidate duplicated -+ code in rkvdec_request_validate and cedrus_request_validate. -+ The helper needs to the driver private data associated with -+ the videobuf2 queue, from a media request. -diff --git a/drivers/staging/media/rkvdec/rkvdec-h264.c b/drivers/staging/media/rkvdec/rkvdec-h264.c -new file mode 100644 -index 000000000000..cd4980d06be7 ---- /dev/null -+++ b/drivers/staging/media/rkvdec/rkvdec-h264.c -@@ -0,0 +1,1156 @@ -+// SPDX-License-Identifier: GPL-2.0 -+/* -+ * Rockchip Video Decoder H264 backend -+ * -+ * Copyright (C) 2019 Collabora, Ltd. -+ * Boris Brezillon -+ * -+ * Copyright (C) 2016 Rockchip Electronics Co., Ltd. -+ * Jeffy Chen -+ */ -+ -+#include -+#include -+ -+#include "rkvdec.h" -+#include "rkvdec-regs.h" -+ -+/* Size with u32 units. */ -+#define RKV_CABAC_INIT_BUFFER_SIZE (3680 + 128) -+#define RKV_RPS_SIZE ((128 + 128) / 4) -+#define RKV_SCALING_LIST_SIZE (6 * 16 + 6 * 64 + 128) -+#define RKV_ERROR_INFO_SIZE (256 * 144 * 4) -+ -+#define RKVDEC_NUM_REFLIST 3 -+ -+struct rkvdec_sps_pps_packet { -+ u32 info[8]; -+}; -+ -+struct rkvdec_ps_field { -+ u16 offset; -+ u8 len; -+}; -+ -+#define PS_FIELD(_offset, _len) \ -+ ((struct rkvdec_ps_field){ _offset, _len }) -+ -+#define SEQ_PARAMETER_SET_ID PS_FIELD(0, 4) -+#define PROFILE_IDC PS_FIELD(4, 8) -+#define CONSTRAINT_SET3_FLAG PS_FIELD(12, 1) -+#define CHROMA_FORMAT_IDC PS_FIELD(13, 2) -+#define BIT_DEPTH_LUMA PS_FIELD(15, 3) -+#define BIT_DEPTH_CHROMA PS_FIELD(18, 3) -+#define QPPRIME_Y_ZERO_TRANSFORM_BYPASS_FLAG PS_FIELD(21, 1) -+#define LOG2_MAX_FRAME_NUM_MINUS4 PS_FIELD(22, 4) -+#define MAX_NUM_REF_FRAMES PS_FIELD(26, 5) -+#define PIC_ORDER_CNT_TYPE PS_FIELD(31, 2) -+#define LOG2_MAX_PIC_ORDER_CNT_LSB_MINUS4 PS_FIELD(33, 4) -+#define DELTA_PIC_ORDER_ALWAYS_ZERO_FLAG PS_FIELD(37, 1) -+#define PIC_WIDTH_IN_MBS PS_FIELD(38, 9) -+#define PIC_HEIGHT_IN_MBS PS_FIELD(47, 9) -+#define FRAME_MBS_ONLY_FLAG PS_FIELD(56, 1) -+#define MB_ADAPTIVE_FRAME_FIELD_FLAG PS_FIELD(57, 1) -+#define DIRECT_8X8_INFERENCE_FLAG PS_FIELD(58, 1) -+#define MVC_EXTENSION_ENABLE PS_FIELD(59, 1) -+#define NUM_VIEWS PS_FIELD(60, 2) -+#define VIEW_ID(i) PS_FIELD(62 + ((i) * 10), 10) -+#define NUM_ANCHOR_REFS_L(i) PS_FIELD(82 + ((i) * 11), 1) -+#define ANCHOR_REF_L(i) PS_FIELD(83 + ((i) * 11), 10) -+#define NUM_NON_ANCHOR_REFS_L(i) PS_FIELD(104 + ((i) * 11), 1) -+#define NON_ANCHOR_REFS_L(i) PS_FIELD(105 + ((i) * 11), 10) -+#define PIC_PARAMETER_SET_ID PS_FIELD(128, 8) -+#define PPS_SEQ_PARAMETER_SET_ID PS_FIELD(136, 5) -+#define ENTROPY_CODING_MODE_FLAG PS_FIELD(141, 1) -+#define BOTTOM_FIELD_PIC_ORDER_IN_FRAME_PRESENT_FLAG PS_FIELD(142, 1) -+#define NUM_REF_IDX_L_DEFAULT_ACTIVE_MINUS1(i) PS_FIELD(143 + ((i) * 5), 5) -+#define WEIGHTED_PRED_FLAG PS_FIELD(153, 1) -+#define WEIGHTED_BIPRED_IDC PS_FIELD(154, 2) -+#define PIC_INIT_QP_MINUS26 PS_FIELD(156, 7) -+#define PIC_INIT_QS_MINUS26 PS_FIELD(163, 6) -+#define CHROMA_QP_INDEX_OFFSET PS_FIELD(169, 5) -+#define DEBLOCKING_FILTER_CONTROL_PRESENT_FLAG PS_FIELD(174, 1) -+#define CONSTRAINED_INTRA_PRED_FLAG PS_FIELD(175, 1) -+#define REDUNDANT_PIC_CNT_PRESENT PS_FIELD(176, 1) -+#define TRANSFORM_8X8_MODE_FLAG PS_FIELD(177, 1) -+#define SECOND_CHROMA_QP_INDEX_OFFSET PS_FIELD(178, 5) -+#define SCALING_LIST_ENABLE_FLAG PS_FIELD(183, 1) -+#define SCALING_LIST_ADDRESS PS_FIELD(184, 32) -+#define IS_LONG_TERM(i) PS_FIELD(216 + (i), 1) -+ -+#define DPB_OFFS(i, j) (288 + ((j) * 32 * 7) + ((i) * 7)) -+#define DPB_INFO(i, j) PS_FIELD(DPB_OFFS(i, j), 5) -+#define BOTTOM_FLAG(i, j) PS_FIELD(DPB_OFFS(i, j) + 5, 1) -+#define VIEW_INDEX_OFF(i, j) PS_FIELD(DPB_OFFS(i, j) + 6, 1) -+ -+/* Data structure describing auxiliary buffer format. */ -+struct rkvdec_h264_priv_tbl { -+ s8 cabac_table[4][464][2]; -+ u8 scaling_list[RKV_SCALING_LIST_SIZE]; -+ u32 rps[RKV_RPS_SIZE]; -+ struct rkvdec_sps_pps_packet param_set[256]; -+ u8 err_info[RKV_ERROR_INFO_SIZE]; -+}; -+ -+#define RKVDEC_H264_DPB_SIZE 16 -+ -+struct rkvdec_h264_reflists { -+ u8 p[RKVDEC_H264_DPB_SIZE]; -+ u8 b0[RKVDEC_H264_DPB_SIZE]; -+ u8 b1[RKVDEC_H264_DPB_SIZE]; -+ u8 num_valid; -+}; -+ -+struct rkvdec_h264_run { -+ struct rkvdec_run base; -+ const struct v4l2_ctrl_h264_decode_params *decode_params; -+ const struct v4l2_ctrl_h264_slice_params *slices_params; -+ const struct v4l2_ctrl_h264_sps *sps; -+ const struct v4l2_ctrl_h264_pps *pps; -+ const struct v4l2_ctrl_h264_scaling_matrix *scaling_matrix; -+}; -+ -+struct rkvdec_h264_ctx { -+ struct rkvdec_aux_buf priv_tbl; -+ struct rkvdec_h264_reflists reflists; -+}; -+ -+#define CABAC_ENTRY(ctxidx, idc0_m, idc0_n, idc1_m, idc1_n, \ -+ idc2_m, idc2_n, intra_m, intra_n) \ -+ [0][(ctxidx)] = {idc0_m, idc0_n}, \ -+ [1][(ctxidx)] = {idc1_m, idc1_n}, \ -+ [2][(ctxidx)] = {idc2_m, idc2_n}, \ -+ [3][(ctxidx)] = {intra_m, intra_n} -+ -+/* -+ * Constant CABAC table. -+ * Built from the tables described in section '9.3.1.1 Initialisation process -+ * for context variables' of the H264 spec. -+ */ -+static const s8 rkvdec_h264_cabac_table[4][464][2] = { -+ /* Table 9-12 ? Values of variables m and n for ctxIdx from 0 to 10 */ -+ CABAC_ENTRY(0, 20, -15, 20, -15, 20, -15, 20, -15), -+ CABAC_ENTRY(1, 2, 54, 2, 54, 2, 54, 2, 54), -+ CABAC_ENTRY(2, 3, 74, 3, 74, 3, 74, 3, 74), -+ CABAC_ENTRY(3, 20, -15, 20, -15, 20, -15, 20, -15), -+ CABAC_ENTRY(4, 2, 54, 2, 54, 2, 54, 2, 54), -+ CABAC_ENTRY(5, 3, 74, 3, 74, 3, 74, 3, 74), -+ CABAC_ENTRY(6, -28, 127, -28, 127, -28, 127, -28, 127), -+ CABAC_ENTRY(7, -23, 104, -23, 104, -23, 104, -23, 104), -+ CABAC_ENTRY(8, -6, 53, -6, 53, -6, 53, -6, 53), -+ CABAC_ENTRY(9, -1, 54, -1, 54, -1, 54, -1, 54), -+ CABAC_ENTRY(10, 7, 51, 7, 51, 7, 51, 7, 51), -+ -+ /* Table 9-13 ? Values of variables m and n for ctxIdx from 11 to 23 */ -+ CABAC_ENTRY(11, 23, 33, 22, 25, 29, 16, 0, 0), -+ CABAC_ENTRY(12, 23, 2, 34, 0, 25, 0, 0, 0), -+ CABAC_ENTRY(13, 21, 0, 16, 0, 14, 0, 0, 0), -+ CABAC_ENTRY(14, 1, 9, -2, 9, -10, 51, 0, 0), -+ CABAC_ENTRY(15, 0, 49, 4, 41, -3, 62, 0, 0), -+ CABAC_ENTRY(16, -37, 118, -29, 118, -27, 99, 0, 0), -+ CABAC_ENTRY(17, 5, 57, 2, 65, 26, 16, 0, 0), -+ CABAC_ENTRY(18, -13, 78, -6, 71, -4, 85, 0, 0), -+ CABAC_ENTRY(19, -11, 65, -13, 79, -24, 102, 0, 0), -+ CABAC_ENTRY(20, 1, 62, 5, 52, 5, 57, 0, 0), -+ CABAC_ENTRY(21, 12, 49, 9, 50, 6, 57, 0, 0), -+ CABAC_ENTRY(22, -4, 73, -3, 70, -17, 73, 0, 0), -+ CABAC_ENTRY(23, 17, 50, 10, 54, 14, 57, 0, 0), -+ -+ /* Table 9-14 ? Values of variables m and n for ctxIdx from 24 to 39 */ -+ CABAC_ENTRY(24, 18, 64, 26, 34, 20, 40, 0, 0), -+ CABAC_ENTRY(25, 9, 43, 19, 22, 20, 10, 0, 0), -+ CABAC_ENTRY(26, 29, 0, 40, 0, 29, 0, 0, 0), -+ CABAC_ENTRY(27, 26, 67, 57, 2, 54, 0, 0, 0), -+ CABAC_ENTRY(28, 16, 90, 41, 36, 37, 42, 0, 0), -+ CABAC_ENTRY(29, 9, 104, 26, 69, 12, 97, 0, 0), -+ CABAC_ENTRY(30, -46, 127, -45, 127, -32, 127, 0, 0), -+ CABAC_ENTRY(31, -20, 104, -15, 101, -22, 117, 0, 0), -+ CABAC_ENTRY(32, 1, 67, -4, 76, -2, 74, 0, 0), -+ CABAC_ENTRY(33, -13, 78, -6, 71, -4, 85, 0, 0), -+ CABAC_ENTRY(34, -11, 65, -13, 79, -24, 102, 0, 0), -+ CABAC_ENTRY(35, 1, 62, 5, 52, 5, 57, 0, 0), -+ CABAC_ENTRY(36, -6, 86, 6, 69, -6, 93, 0, 0), -+ CABAC_ENTRY(37, -17, 95, -13, 90, -14, 88, 0, 0), -+ CABAC_ENTRY(38, -6, 61, 0, 52, -6, 44, 0, 0), -+ CABAC_ENTRY(39, 9, 45, 8, 43, 4, 55, 0, 0), -+ -+ /* Table 9-15 ? Values of variables m and n for ctxIdx from 40 to 53 */ -+ CABAC_ENTRY(40, -3, 69, -2, 69, -11, 89, 0, 0), -+ CABAC_ENTRY(41, -6, 81, -5, 82, -15, 103, 0, 0), -+ CABAC_ENTRY(42, -11, 96, -10, 96, -21, 116, 0, 0), -+ CABAC_ENTRY(43, 6, 55, 2, 59, 19, 57, 0, 0), -+ CABAC_ENTRY(44, 7, 67, 2, 75, 20, 58, 0, 0), -+ CABAC_ENTRY(45, -5, 86, -3, 87, 4, 84, 0, 0), -+ CABAC_ENTRY(46, 2, 88, -3, 100, 6, 96, 0, 0), -+ CABAC_ENTRY(47, 0, 58, 1, 56, 1, 63, 0, 0), -+ CABAC_ENTRY(48, -3, 76, -3, 74, -5, 85, 0, 0), -+ CABAC_ENTRY(49, -10, 94, -6, 85, -13, 106, 0, 0), -+ CABAC_ENTRY(50, 5, 54, 0, 59, 5, 63, 0, 0), -+ CABAC_ENTRY(51, 4, 69, -3, 81, 6, 75, 0, 0), -+ CABAC_ENTRY(52, -3, 81, -7, 86, -3, 90, 0, 0), -+ CABAC_ENTRY(53, 0, 88, -5, 95, -1, 101, 0, 0), -+ -+ /* Table 9-16 ? Values of variables m and n for ctxIdx from 54 to 59 */ -+ CABAC_ENTRY(54, -7, 67, -1, 66, 3, 55, 0, 0), -+ CABAC_ENTRY(55, -5, 74, -1, 77, -4, 79, 0, 0), -+ CABAC_ENTRY(56, -4, 74, 1, 70, -2, 75, 0, 0), -+ CABAC_ENTRY(57, -5, 80, -2, 86, -12, 97, 0, 0), -+ CABAC_ENTRY(58, -7, 72, -5, 72, -7, 50, 0, 0), -+ CABAC_ENTRY(59, 1, 58, 0, 61, 1, 60, 0, 0), -+ -+ /* Table 9-17 ? Values of variables m and n for ctxIdx from 60 to 69 */ -+ CABAC_ENTRY(60, 0, 41, 0, 41, 0, 41, 0, 41), -+ CABAC_ENTRY(61, 0, 63, 0, 63, 0, 63, 0, 63), -+ CABAC_ENTRY(62, 0, 63, 0, 63, 0, 63, 0, 63), -+ CABAC_ENTRY(63, 0, 63, 0, 63, 0, 63, 0, 63), -+ CABAC_ENTRY(64, -9, 83, -9, 83, -9, 83, -9, 83), -+ CABAC_ENTRY(65, 4, 86, 4, 86, 4, 86, 4, 86), -+ CABAC_ENTRY(66, 0, 97, 0, 97, 0, 97, 0, 97), -+ CABAC_ENTRY(67, -7, 72, -7, 72, -7, 72, -7, 72), -+ CABAC_ENTRY(68, 13, 41, 13, 41, 13, 41, 13, 41), -+ CABAC_ENTRY(69, 3, 62, 3, 62, 3, 62, 3, 62), -+ -+ /* Table 9-18 ? Values of variables m and n for ctxIdx from 70 to 104 */ -+ CABAC_ENTRY(70, 0, 45, 13, 15, 7, 34, 0, 11), -+ CABAC_ENTRY(71, -4, 78, 7, 51, -9, 88, 1, 55), -+ CABAC_ENTRY(72, -3, 96, 2, 80, -20, 127, 0, 69), -+ CABAC_ENTRY(73, -27, 126, -39, 127, -36, 127, -17, 127), -+ CABAC_ENTRY(74, -28, 98, -18, 91, -17, 91, -13, 102), -+ CABAC_ENTRY(75, -25, 101, -17, 96, -14, 95, 0, 82), -+ CABAC_ENTRY(76, -23, 67, -26, 81, -25, 84, -7, 74), -+ CABAC_ENTRY(77, -28, 82, -35, 98, -25, 86, -21, 107), -+ CABAC_ENTRY(78, -20, 94, -24, 102, -12, 89, -27, 127), -+ CABAC_ENTRY(79, -16, 83, -23, 97, -17, 91, -31, 127), -+ CABAC_ENTRY(80, -22, 110, -27, 119, -31, 127, -24, 127), -+ CABAC_ENTRY(81, -21, 91, -24, 99, -14, 76, -18, 95), -+ CABAC_ENTRY(82, -18, 102, -21, 110, -18, 103, -27, 127), -+ CABAC_ENTRY(83, -13, 93, -18, 102, -13, 90, -21, 114), -+ CABAC_ENTRY(84, -29, 127, -36, 127, -37, 127, -30, 127), -+ CABAC_ENTRY(85, -7, 92, 0, 80, 11, 80, -17, 123), -+ CABAC_ENTRY(86, -5, 89, -5, 89, 5, 76, -12, 115), -+ CABAC_ENTRY(87, -7, 96, -7, 94, 2, 84, -16, 122), -+ CABAC_ENTRY(88, -13, 108, -4, 92, 5, 78, -11, 115), -+ CABAC_ENTRY(89, -3, 46, 0, 39, -6, 55, -12, 63), -+ CABAC_ENTRY(90, -1, 65, 0, 65, 4, 61, -2, 68), -+ CABAC_ENTRY(91, -1, 57, -15, 84, -14, 83, -15, 84), -+ CABAC_ENTRY(92, -9, 93, -35, 127, -37, 127, -13, 104), -+ CABAC_ENTRY(93, -3, 74, -2, 73, -5, 79, -3, 70), -+ CABAC_ENTRY(94, -9, 92, -12, 104, -11, 104, -8, 93), -+ CABAC_ENTRY(95, -8, 87, -9, 91, -11, 91, -10, 90), -+ CABAC_ENTRY(96, -23, 126, -31, 127, -30, 127, -30, 127), -+ CABAC_ENTRY(97, 5, 54, 3, 55, 0, 65, -1, 74), -+ CABAC_ENTRY(98, 6, 60, 7, 56, -2, 79, -6, 97), -+ CABAC_ENTRY(99, 6, 59, 7, 55, 0, 72, -7, 91), -+ CABAC_ENTRY(100, 6, 69, 8, 61, -4, 92, -20, 127), -+ CABAC_ENTRY(101, -1, 48, -3, 53, -6, 56, -4, 56), -+ CABAC_ENTRY(102, 0, 68, 0, 68, 3, 68, -5, 82), -+ CABAC_ENTRY(103, -4, 69, -7, 74, -8, 71, -7, 76), -+ CABAC_ENTRY(104, -8, 88, -9, 88, -13, 98, -22, 125), -+ -+ /* Table 9-19 ? Values of variables m and n for ctxIdx from 105 to 165 */ -+ CABAC_ENTRY(105, -2, 85, -13, 103, -4, 86, -7, 93), -+ CABAC_ENTRY(106, -6, 78, -13, 91, -12, 88, -11, 87), -+ CABAC_ENTRY(107, -1, 75, -9, 89, -5, 82, -3, 77), -+ CABAC_ENTRY(108, -7, 77, -14, 92, -3, 72, -5, 71), -+ CABAC_ENTRY(109, 2, 54, -8, 76, -4, 67, -4, 63), -+ CABAC_ENTRY(110, 5, 50, -12, 87, -8, 72, -4, 68), -+ CABAC_ENTRY(111, -3, 68, -23, 110, -16, 89, -12, 84), -+ CABAC_ENTRY(112, 1, 50, -24, 105, -9, 69, -7, 62), -+ CABAC_ENTRY(113, 6, 42, -10, 78, -1, 59, -7, 65), -+ CABAC_ENTRY(114, -4, 81, -20, 112, 5, 66, 8, 61), -+ CABAC_ENTRY(115, 1, 63, -17, 99, 4, 57, 5, 56), -+ CABAC_ENTRY(116, -4, 70, -78, 127, -4, 71, -2, 66), -+ CABAC_ENTRY(117, 0, 67, -70, 127, -2, 71, 1, 64), -+ CABAC_ENTRY(118, 2, 57, -50, 127, 2, 58, 0, 61), -+ CABAC_ENTRY(119, -2, 76, -46, 127, -1, 74, -2, 78), -+ CABAC_ENTRY(120, 11, 35, -4, 66, -4, 44, 1, 50), -+ CABAC_ENTRY(121, 4, 64, -5, 78, -1, 69, 7, 52), -+ CABAC_ENTRY(122, 1, 61, -4, 71, 0, 62, 10, 35), -+ CABAC_ENTRY(123, 11, 35, -8, 72, -7, 51, 0, 44), -+ CABAC_ENTRY(124, 18, 25, 2, 59, -4, 47, 11, 38), -+ CABAC_ENTRY(125, 12, 24, -1, 55, -6, 42, 1, 45), -+ CABAC_ENTRY(126, 13, 29, -7, 70, -3, 41, 0, 46), -+ CABAC_ENTRY(127, 13, 36, -6, 75, -6, 53, 5, 44), -+ CABAC_ENTRY(128, -10, 93, -8, 89, 8, 76, 31, 17), -+ CABAC_ENTRY(129, -7, 73, -34, 119, -9, 78, 1, 51), -+ CABAC_ENTRY(130, -2, 73, -3, 75, -11, 83, 7, 50), -+ CABAC_ENTRY(131, 13, 46, 32, 20, 9, 52, 28, 19), -+ CABAC_ENTRY(132, 9, 49, 30, 22, 0, 67, 16, 33), -+ CABAC_ENTRY(133, -7, 100, -44, 127, -5, 90, 14, 62), -+ CABAC_ENTRY(134, 9, 53, 0, 54, 1, 67, -13, 108), -+ CABAC_ENTRY(135, 2, 53, -5, 61, -15, 72, -15, 100), -+ CABAC_ENTRY(136, 5, 53, 0, 58, -5, 75, -13, 101), -+ CABAC_ENTRY(137, -2, 61, -1, 60, -8, 80, -13, 91), -+ CABAC_ENTRY(138, 0, 56, -3, 61, -21, 83, -12, 94), -+ CABAC_ENTRY(139, 0, 56, -8, 67, -21, 64, -10, 88), -+ CABAC_ENTRY(140, -13, 63, -25, 84, -13, 31, -16, 84), -+ CABAC_ENTRY(141, -5, 60, -14, 74, -25, 64, -10, 86), -+ CABAC_ENTRY(142, -1, 62, -5, 65, -29, 94, -7, 83), -+ CABAC_ENTRY(143, 4, 57, 5, 52, 9, 75, -13, 87), -+ CABAC_ENTRY(144, -6, 69, 2, 57, 17, 63, -19, 94), -+ CABAC_ENTRY(145, 4, 57, 0, 61, -8, 74, 1, 70), -+ CABAC_ENTRY(146, 14, 39, -9, 69, -5, 35, 0, 72), -+ CABAC_ENTRY(147, 4, 51, -11, 70, -2, 27, -5, 74), -+ CABAC_ENTRY(148, 13, 68, 18, 55, 13, 91, 18, 59), -+ CABAC_ENTRY(149, 3, 64, -4, 71, 3, 65, -8, 102), -+ CABAC_ENTRY(150, 1, 61, 0, 58, -7, 69, -15, 100), -+ CABAC_ENTRY(151, 9, 63, 7, 61, 8, 77, 0, 95), -+ CABAC_ENTRY(152, 7, 50, 9, 41, -10, 66, -4, 75), -+ CABAC_ENTRY(153, 16, 39, 18, 25, 3, 62, 2, 72), -+ CABAC_ENTRY(154, 5, 44, 9, 32, -3, 68, -11, 75), -+ CABAC_ENTRY(155, 4, 52, 5, 43, -20, 81, -3, 71), -+ CABAC_ENTRY(156, 11, 48, 9, 47, 0, 30, 15, 46), -+ CABAC_ENTRY(157, -5, 60, 0, 44, 1, 7, -13, 69), -+ CABAC_ENTRY(158, -1, 59, 0, 51, -3, 23, 0, 62), -+ CABAC_ENTRY(159, 0, 59, 2, 46, -21, 74, 0, 65), -+ CABAC_ENTRY(160, 22, 33, 19, 38, 16, 66, 21, 37), -+ CABAC_ENTRY(161, 5, 44, -4, 66, -23, 124, -15, 72), -+ CABAC_ENTRY(162, 14, 43, 15, 38, 17, 37, 9, 57), -+ CABAC_ENTRY(163, -1, 78, 12, 42, 44, -18, 16, 54), -+ CABAC_ENTRY(164, 0, 60, 9, 34, 50, -34, 0, 62), -+ CABAC_ENTRY(165, 9, 69, 0, 89, -22, 127, 12, 72), -+ -+ /* Table 9-20 ? Values of variables m and n for ctxIdx from 166 to 226 */ -+ CABAC_ENTRY(166, 11, 28, 4, 45, 4, 39, 24, 0), -+ CABAC_ENTRY(167, 2, 40, 10, 28, 0, 42, 15, 9), -+ CABAC_ENTRY(168, 3, 44, 10, 31, 7, 34, 8, 25), -+ CABAC_ENTRY(169, 0, 49, 33, -11, 11, 29, 13, 18), -+ CABAC_ENTRY(170, 0, 46, 52, -43, 8, 31, 15, 9), -+ CABAC_ENTRY(171, 2, 44, 18, 15, 6, 37, 13, 19), -+ CABAC_ENTRY(172, 2, 51, 28, 0, 7, 42, 10, 37), -+ CABAC_ENTRY(173, 0, 47, 35, -22, 3, 40, 12, 18), -+ CABAC_ENTRY(174, 4, 39, 38, -25, 8, 33, 6, 29), -+ CABAC_ENTRY(175, 2, 62, 34, 0, 13, 43, 20, 33), -+ CABAC_ENTRY(176, 6, 46, 39, -18, 13, 36, 15, 30), -+ CABAC_ENTRY(177, 0, 54, 32, -12, 4, 47, 4, 45), -+ CABAC_ENTRY(178, 3, 54, 102, -94, 3, 55, 1, 58), -+ CABAC_ENTRY(179, 2, 58, 0, 0, 2, 58, 0, 62), -+ CABAC_ENTRY(180, 4, 63, 56, -15, 6, 60, 7, 61), -+ CABAC_ENTRY(181, 6, 51, 33, -4, 8, 44, 12, 38), -+ CABAC_ENTRY(182, 6, 57, 29, 10, 11, 44, 11, 45), -+ CABAC_ENTRY(183, 7, 53, 37, -5, 14, 42, 15, 39), -+ CABAC_ENTRY(184, 6, 52, 51, -29, 7, 48, 11, 42), -+ CABAC_ENTRY(185, 6, 55, 39, -9, 4, 56, 13, 44), -+ CABAC_ENTRY(186, 11, 45, 52, -34, 4, 52, 16, 45), -+ CABAC_ENTRY(187, 14, 36, 69, -58, 13, 37, 12, 41), -+ CABAC_ENTRY(188, 8, 53, 67, -63, 9, 49, 10, 49), -+ CABAC_ENTRY(189, -1, 82, 44, -5, 19, 58, 30, 34), -+ CABAC_ENTRY(190, 7, 55, 32, 7, 10, 48, 18, 42), -+ CABAC_ENTRY(191, -3, 78, 55, -29, 12, 45, 10, 55), -+ CABAC_ENTRY(192, 15, 46, 32, 1, 0, 69, 17, 51), -+ CABAC_ENTRY(193, 22, 31, 0, 0, 20, 33, 17, 46), -+ CABAC_ENTRY(194, -1, 84, 27, 36, 8, 63, 0, 89), -+ CABAC_ENTRY(195, 25, 7, 33, -25, 35, -18, 26, -19), -+ CABAC_ENTRY(196, 30, -7, 34, -30, 33, -25, 22, -17), -+ CABAC_ENTRY(197, 28, 3, 36, -28, 28, -3, 26, -17), -+ CABAC_ENTRY(198, 28, 4, 38, -28, 24, 10, 30, -25), -+ CABAC_ENTRY(199, 32, 0, 38, -27, 27, 0, 28, -20), -+ CABAC_ENTRY(200, 34, -1, 34, -18, 34, -14, 33, -23), -+ CABAC_ENTRY(201, 30, 6, 35, -16, 52, -44, 37, -27), -+ CABAC_ENTRY(202, 30, 6, 34, -14, 39, -24, 33, -23), -+ CABAC_ENTRY(203, 32, 9, 32, -8, 19, 17, 40, -28), -+ CABAC_ENTRY(204, 31, 19, 37, -6, 31, 25, 38, -17), -+ CABAC_ENTRY(205, 26, 27, 35, 0, 36, 29, 33, -11), -+ CABAC_ENTRY(206, 26, 30, 30, 10, 24, 33, 40, -15), -+ CABAC_ENTRY(207, 37, 20, 28, 18, 34, 15, 41, -6), -+ CABAC_ENTRY(208, 28, 34, 26, 25, 30, 20, 38, 1), -+ CABAC_ENTRY(209, 17, 70, 29, 41, 22, 73, 41, 17), -+ CABAC_ENTRY(210, 1, 67, 0, 75, 20, 34, 30, -6), -+ CABAC_ENTRY(211, 5, 59, 2, 72, 19, 31, 27, 3), -+ CABAC_ENTRY(212, 9, 67, 8, 77, 27, 44, 26, 22), -+ CABAC_ENTRY(213, 16, 30, 14, 35, 19, 16, 37, -16), -+ CABAC_ENTRY(214, 18, 32, 18, 31, 15, 36, 35, -4), -+ CABAC_ENTRY(215, 18, 35, 17, 35, 15, 36, 38, -8), -+ CABAC_ENTRY(216, 22, 29, 21, 30, 21, 28, 38, -3), -+ CABAC_ENTRY(217, 24, 31, 17, 45, 25, 21, 37, 3), -+ CABAC_ENTRY(218, 23, 38, 20, 42, 30, 20, 38, 5), -+ CABAC_ENTRY(219, 18, 43, 18, 45, 31, 12, 42, 0), -+ CABAC_ENTRY(220, 20, 41, 27, 26, 27, 16, 35, 16), -+ CABAC_ENTRY(221, 11, 63, 16, 54, 24, 42, 39, 22), -+ CABAC_ENTRY(222, 9, 59, 7, 66, 0, 93, 14, 48), -+ CABAC_ENTRY(223, 9, 64, 16, 56, 14, 56, 27, 37), -+ CABAC_ENTRY(224, -1, 94, 11, 73, 15, 57, 21, 60), -+ CABAC_ENTRY(225, -2, 89, 10, 67, 26, 38, 12, 68), -+ CABAC_ENTRY(226, -9, 108, -10, 116, -24, 127, 2, 97), -+ -+ /* Table 9-21 ? Values of variables m and n for ctxIdx from 227 to 275 */ -+ CABAC_ENTRY(227, -6, 76, -23, 112, -24, 115, -3, 71), -+ CABAC_ENTRY(228, -2, 44, -15, 71, -22, 82, -6, 42), -+ CABAC_ENTRY(229, 0, 45, -7, 61, -9, 62, -5, 50), -+ CABAC_ENTRY(230, 0, 52, 0, 53, 0, 53, -3, 54), -+ CABAC_ENTRY(231, -3, 64, -5, 66, 0, 59, -2, 62), -+ CABAC_ENTRY(232, -2, 59, -11, 77, -14, 85, 0, 58), -+ CABAC_ENTRY(233, -4, 70, -9, 80, -13, 89, 1, 63), -+ CABAC_ENTRY(234, -4, 75, -9, 84, -13, 94, -2, 72), -+ CABAC_ENTRY(235, -8, 82, -10, 87, -11, 92, -1, 74), -+ CABAC_ENTRY(236, -17, 102, -34, 127, -29, 127, -9, 91), -+ CABAC_ENTRY(237, -9, 77, -21, 101, -21, 100, -5, 67), -+ CABAC_ENTRY(238, 3, 24, -3, 39, -14, 57, -5, 27), -+ CABAC_ENTRY(239, 0, 42, -5, 53, -12, 67, -3, 39), -+ CABAC_ENTRY(240, 0, 48, -7, 61, -11, 71, -2, 44), -+ CABAC_ENTRY(241, 0, 55, -11, 75, -10, 77, 0, 46), -+ CABAC_ENTRY(242, -6, 59, -15, 77, -21, 85, -16, 64), -+ CABAC_ENTRY(243, -7, 71, -17, 91, -16, 88, -8, 68), -+ CABAC_ENTRY(244, -12, 83, -25, 107, -23, 104, -10, 78), -+ CABAC_ENTRY(245, -11, 87, -25, 111, -15, 98, -6, 77), -+ CABAC_ENTRY(246, -30, 119, -28, 122, -37, 127, -10, 86), -+ CABAC_ENTRY(247, 1, 58, -11, 76, -10, 82, -12, 92), -+ CABAC_ENTRY(248, -3, 29, -10, 44, -8, 48, -15, 55), -+ CABAC_ENTRY(249, -1, 36, -10, 52, -8, 61, -10, 60), -+ CABAC_ENTRY(250, 1, 38, -10, 57, -8, 66, -6, 62), -+ CABAC_ENTRY(251, 2, 43, -9, 58, -7, 70, -4, 65), -+ CABAC_ENTRY(252, -6, 55, -16, 72, -14, 75, -12, 73), -+ CABAC_ENTRY(253, 0, 58, -7, 69, -10, 79, -8, 76), -+ CABAC_ENTRY(254, 0, 64, -4, 69, -9, 83, -7, 80), -+ CABAC_ENTRY(255, -3, 74, -5, 74, -12, 92, -9, 88), -+ CABAC_ENTRY(256, -10, 90, -9, 86, -18, 108, -17, 110), -+ CABAC_ENTRY(257, 0, 70, 2, 66, -4, 79, -11, 97), -+ CABAC_ENTRY(258, -4, 29, -9, 34, -22, 69, -20, 84), -+ CABAC_ENTRY(259, 5, 31, 1, 32, -16, 75, -11, 79), -+ CABAC_ENTRY(260, 7, 42, 11, 31, -2, 58, -6, 73), -+ CABAC_ENTRY(261, 1, 59, 5, 52, 1, 58, -4, 74), -+ CABAC_ENTRY(262, -2, 58, -2, 55, -13, 78, -13, 86), -+ CABAC_ENTRY(263, -3, 72, -2, 67, -9, 83, -13, 96), -+ CABAC_ENTRY(264, -3, 81, 0, 73, -4, 81, -11, 97), -+ CABAC_ENTRY(265, -11, 97, -8, 89, -13, 99, -19, 117), -+ CABAC_ENTRY(266, 0, 58, 3, 52, -13, 81, -8, 78), -+ CABAC_ENTRY(267, 8, 5, 7, 4, -6, 38, -5, 33), -+ CABAC_ENTRY(268, 10, 14, 10, 8, -13, 62, -4, 48), -+ CABAC_ENTRY(269, 14, 18, 17, 8, -6, 58, -2, 53), -+ CABAC_ENTRY(270, 13, 27, 16, 19, -2, 59, -3, 62), -+ CABAC_ENTRY(271, 2, 40, 3, 37, -16, 73, -13, 71), -+ CABAC_ENTRY(272, 0, 58, -1, 61, -10, 76, -10, 79), -+ CABAC_ENTRY(273, -3, 70, -5, 73, -13, 86, -12, 86), -+ CABAC_ENTRY(274, -6, 79, -1, 70, -9, 83, -13, 90), -+ CABAC_ENTRY(275, -8, 85, -4, 78, -10, 87, -14, 97), -+ -+ /* Table 9-22 ? Values of variables m and n for ctxIdx from 277 to 337 */ -+ CABAC_ENTRY(277, -13, 106, -21, 126, -22, 127, -6, 93), -+ CABAC_ENTRY(278, -16, 106, -23, 124, -25, 127, -6, 84), -+ CABAC_ENTRY(279, -10, 87, -20, 110, -25, 120, -8, 79), -+ CABAC_ENTRY(280, -21, 114, -26, 126, -27, 127, 0, 66), -+ CABAC_ENTRY(281, -18, 110, -25, 124, -19, 114, -1, 71), -+ CABAC_ENTRY(282, -14, 98, -17, 105, -23, 117, 0, 62), -+ CABAC_ENTRY(283, -22, 110, -27, 121, -25, 118, -2, 60), -+ CABAC_ENTRY(284, -21, 106, -27, 117, -26, 117, -2, 59), -+ CABAC_ENTRY(285, -18, 103, -17, 102, -24, 113, -5, 75), -+ CABAC_ENTRY(286, -21, 107, -26, 117, -28, 118, -3, 62), -+ CABAC_ENTRY(287, -23, 108, -27, 116, -31, 120, -4, 58), -+ CABAC_ENTRY(288, -26, 112, -33, 122, -37, 124, -9, 66), -+ CABAC_ENTRY(289, -10, 96, -10, 95, -10, 94, -1, 79), -+ CABAC_ENTRY(290, -12, 95, -14, 100, -15, 102, 0, 71), -+ CABAC_ENTRY(291, -5, 91, -8, 95, -10, 99, 3, 68), -+ CABAC_ENTRY(292, -9, 93, -17, 111, -13, 106, 10, 44), -+ CABAC_ENTRY(293, -22, 94, -28, 114, -50, 127, -7, 62), -+ CABAC_ENTRY(294, -5, 86, -6, 89, -5, 92, 15, 36), -+ CABAC_ENTRY(295, 9, 67, -2, 80, 17, 57, 14, 40), -+ CABAC_ENTRY(296, -4, 80, -4, 82, -5, 86, 16, 27), -+ CABAC_ENTRY(297, -10, 85, -9, 85, -13, 94, 12, 29), -+ CABAC_ENTRY(298, -1, 70, -8, 81, -12, 91, 1, 44), -+ CABAC_ENTRY(299, 7, 60, -1, 72, -2, 77, 20, 36), -+ CABAC_ENTRY(300, 9, 58, 5, 64, 0, 71, 18, 32), -+ CABAC_ENTRY(301, 5, 61, 1, 67, -1, 73, 5, 42), -+ CABAC_ENTRY(302, 12, 50, 9, 56, 4, 64, 1, 48), -+ CABAC_ENTRY(303, 15, 50, 0, 69, -7, 81, 10, 62), -+ CABAC_ENTRY(304, 18, 49, 1, 69, 5, 64, 17, 46), -+ CABAC_ENTRY(305, 17, 54, 7, 69, 15, 57, 9, 64), -+ CABAC_ENTRY(306, 10, 41, -7, 69, 1, 67, -12, 104), -+ CABAC_ENTRY(307, 7, 46, -6, 67, 0, 68, -11, 97), -+ CABAC_ENTRY(308, -1, 51, -16, 77, -10, 67, -16, 96), -+ CABAC_ENTRY(309, 7, 49, -2, 64, 1, 68, -7, 88), -+ CABAC_ENTRY(310, 8, 52, 2, 61, 0, 77, -8, 85), -+ CABAC_ENTRY(311, 9, 41, -6, 67, 2, 64, -7, 85), -+ CABAC_ENTRY(312, 6, 47, -3, 64, 0, 68, -9, 85), -+ CABAC_ENTRY(313, 2, 55, 2, 57, -5, 78, -13, 88), -+ CABAC_ENTRY(314, 13, 41, -3, 65, 7, 55, 4, 66), -+ CABAC_ENTRY(315, 10, 44, -3, 66, 5, 59, -3, 77), -+ CABAC_ENTRY(316, 6, 50, 0, 62, 2, 65, -3, 76), -+ CABAC_ENTRY(317, 5, 53, 9, 51, 14, 54, -6, 76), -+ CABAC_ENTRY(318, 13, 49, -1, 66, 15, 44, 10, 58), -+ CABAC_ENTRY(319, 4, 63, -2, 71, 5, 60, -1, 76), -+ CABAC_ENTRY(320, 6, 64, -2, 75, 2, 70, -1, 83), -+ CABAC_ENTRY(321, -2, 69, -1, 70, -2, 76, -7, 99), -+ CABAC_ENTRY(322, -2, 59, -9, 72, -18, 86, -14, 95), -+ CABAC_ENTRY(323, 6, 70, 14, 60, 12, 70, 2, 95), -+ CABAC_ENTRY(324, 10, 44, 16, 37, 5, 64, 0, 76), -+ CABAC_ENTRY(325, 9, 31, 0, 47, -12, 70, -5, 74), -+ CABAC_ENTRY(326, 12, 43, 18, 35, 11, 55, 0, 70), -+ CABAC_ENTRY(327, 3, 53, 11, 37, 5, 56, -11, 75), -+ CABAC_ENTRY(328, 14, 34, 12, 41, 0, 69, 1, 68), -+ CABAC_ENTRY(329, 10, 38, 10, 41, 2, 65, 0, 65), -+ CABAC_ENTRY(330, -3, 52, 2, 48, -6, 74, -14, 73), -+ CABAC_ENTRY(331, 13, 40, 12, 41, 5, 54, 3, 62), -+ CABAC_ENTRY(332, 17, 32, 13, 41, 7, 54, 4, 62), -+ CABAC_ENTRY(333, 7, 44, 0, 59, -6, 76, -1, 68), -+ CABAC_ENTRY(334, 7, 38, 3, 50, -11, 82, -13, 75), -+ CABAC_ENTRY(335, 13, 50, 19, 40, -2, 77, 11, 55), -+ CABAC_ENTRY(336, 10, 57, 3, 66, -2, 77, 5, 64), -+ CABAC_ENTRY(337, 26, 43, 18, 50, 25, 42, 12, 70), -+ -+ /* Table 9-23 ? Values of variables m and n for ctxIdx from 338 to 398 */ -+ CABAC_ENTRY(338, 14, 11, 19, -6, 17, -13, 15, 6), -+ CABAC_ENTRY(339, 11, 14, 18, -6, 16, -9, 6, 19), -+ CABAC_ENTRY(340, 9, 11, 14, 0, 17, -12, 7, 16), -+ CABAC_ENTRY(341, 18, 11, 26, -12, 27, -21, 12, 14), -+ CABAC_ENTRY(342, 21, 9, 31, -16, 37, -30, 18, 13), -+ CABAC_ENTRY(343, 23, -2, 33, -25, 41, -40, 13, 11), -+ CABAC_ENTRY(344, 32, -15, 33, -22, 42, -41, 13, 15), -+ CABAC_ENTRY(345, 32, -15, 37, -28, 48, -47, 15, 16), -+ CABAC_ENTRY(346, 34, -21, 39, -30, 39, -32, 12, 23), -+ CABAC_ENTRY(347, 39, -23, 42, -30, 46, -40, 13, 23), -+ CABAC_ENTRY(348, 42, -33, 47, -42, 52, -51, 15, 20), -+ CABAC_ENTRY(349, 41, -31, 45, -36, 46, -41, 14, 26), -+ CABAC_ENTRY(350, 46, -28, 49, -34, 52, -39, 14, 44), -+ CABAC_ENTRY(351, 38, -12, 41, -17, 43, -19, 17, 40), -+ CABAC_ENTRY(352, 21, 29, 32, 9, 32, 11, 17, 47), -+ CABAC_ENTRY(353, 45, -24, 69, -71, 61, -55, 24, 17), -+ CABAC_ENTRY(354, 53, -45, 63, -63, 56, -46, 21, 21), -+ CABAC_ENTRY(355, 48, -26, 66, -64, 62, -50, 25, 22), -+ CABAC_ENTRY(356, 65, -43, 77, -74, 81, -67, 31, 27), -+ CABAC_ENTRY(357, 43, -19, 54, -39, 45, -20, 22, 29), -+ CABAC_ENTRY(358, 39, -10, 52, -35, 35, -2, 19, 35), -+ CABAC_ENTRY(359, 30, 9, 41, -10, 28, 15, 14, 50), -+ CABAC_ENTRY(360, 18, 26, 36, 0, 34, 1, 10, 57), -+ CABAC_ENTRY(361, 20, 27, 40, -1, 39, 1, 7, 63), -+ CABAC_ENTRY(362, 0, 57, 30, 14, 30, 17, -2, 77), -+ CABAC_ENTRY(363, -14, 82, 28, 26, 20, 38, -4, 82), -+ CABAC_ENTRY(364, -5, 75, 23, 37, 18, 45, -3, 94), -+ CABAC_ENTRY(365, -19, 97, 12, 55, 15, 54, 9, 69), -+ CABAC_ENTRY(366, -35, 125, 11, 65, 0, 79, -12, 109), -+ CABAC_ENTRY(367, 27, 0, 37, -33, 36, -16, 36, -35), -+ CABAC_ENTRY(368, 28, 0, 39, -36, 37, -14, 36, -34), -+ CABAC_ENTRY(369, 31, -4, 40, -37, 37, -17, 32, -26), -+ CABAC_ENTRY(370, 27, 6, 38, -30, 32, 1, 37, -30), -+ CABAC_ENTRY(371, 34, 8, 46, -33, 34, 15, 44, -32), -+ CABAC_ENTRY(372, 30, 10, 42, -30, 29, 15, 34, -18), -+ CABAC_ENTRY(373, 24, 22, 40, -24, 24, 25, 34, -15), -+ CABAC_ENTRY(374, 33, 19, 49, -29, 34, 22, 40, -15), -+ CABAC_ENTRY(375, 22, 32, 38, -12, 31, 16, 33, -7), -+ CABAC_ENTRY(376, 26, 31, 40, -10, 35, 18, 35, -5), -+ CABAC_ENTRY(377, 21, 41, 38, -3, 31, 28, 33, 0), -+ CABAC_ENTRY(378, 26, 44, 46, -5, 33, 41, 38, 2), -+ CABAC_ENTRY(379, 23, 47, 31, 20, 36, 28, 33, 13), -+ CABAC_ENTRY(380, 16, 65, 29, 30, 27, 47, 23, 35), -+ CABAC_ENTRY(381, 14, 71, 25, 44, 21, 62, 13, 58), -+ CABAC_ENTRY(382, 8, 60, 12, 48, 18, 31, 29, -3), -+ CABAC_ENTRY(383, 6, 63, 11, 49, 19, 26, 26, 0), -+ CABAC_ENTRY(384, 17, 65, 26, 45, 36, 24, 22, 30), -+ CABAC_ENTRY(385, 21, 24, 22, 22, 24, 23, 31, -7), -+ CABAC_ENTRY(386, 23, 20, 23, 22, 27, 16, 35, -15), -+ CABAC_ENTRY(387, 26, 23, 27, 21, 24, 30, 34, -3), -+ CABAC_ENTRY(388, 27, 32, 33, 20, 31, 29, 34, 3), -+ CABAC_ENTRY(389, 28, 23, 26, 28, 22, 41, 36, -1), -+ CABAC_ENTRY(390, 28, 24, 30, 24, 22, 42, 34, 5), -+ CABAC_ENTRY(391, 23, 40, 27, 34, 16, 60, 32, 11), -+ CABAC_ENTRY(392, 24, 32, 18, 42, 15, 52, 35, 5), -+ CABAC_ENTRY(393, 28, 29, 25, 39, 14, 60, 34, 12), -+ CABAC_ENTRY(394, 23, 42, 18, 50, 3, 78, 39, 11), -+ CABAC_ENTRY(395, 19, 57, 12, 70, -16, 123, 30, 29), -+ CABAC_ENTRY(396, 22, 53, 21, 54, 21, 53, 34, 26), -+ CABAC_ENTRY(397, 22, 61, 14, 71, 22, 56, 29, 39), -+ CABAC_ENTRY(398, 11, 86, 11, 83, 25, 61, 19, 66), -+ -+ /* Values of variables m and n for ctxIdx from 399 to 463 (not documented) */ -+ CABAC_ENTRY(399, 12, 40, 25, 32, 21, 33, 31, 21), -+ CABAC_ENTRY(400, 11, 51, 21, 49, 19, 50, 31, 31), -+ CABAC_ENTRY(401, 14, 59, 21, 54, 17, 61, 25, 50), -+ CABAC_ENTRY(402, -4, 79, -5, 85, -3, 78, -17, 120), -+ CABAC_ENTRY(403, -7, 71, -6, 81, -8, 74, -20, 112), -+ CABAC_ENTRY(404, -5, 69, -10, 77, -9, 72, -18, 114), -+ CABAC_ENTRY(405, -9, 70, -7, 81, -10, 72, -11, 85), -+ CABAC_ENTRY(406, -8, 66, -17, 80, -18, 75, -15, 92), -+ CABAC_ENTRY(407, -10, 68, -18, 73, -12, 71, -14, 89), -+ CABAC_ENTRY(408, -19, 73, -4, 74, -11, 63, -26, 71), -+ CABAC_ENTRY(409, -12, 69, -10, 83, -5, 70, -15, 81), -+ CABAC_ENTRY(410, -16, 70, -9, 71, -17, 75, -14, 80), -+ CABAC_ENTRY(411, -15, 67, -9, 67, -14, 72, 0, 68), -+ CABAC_ENTRY(412, -20, 62, -1, 61, -16, 67, -14, 70), -+ CABAC_ENTRY(413, -19, 70, -8, 66, -8, 53, -24, 56), -+ CABAC_ENTRY(414, -16, 66, -14, 66, -14, 59, -23, 68), -+ CABAC_ENTRY(415, -22, 65, 0, 59, -9, 52, -24, 50), -+ CABAC_ENTRY(416, -20, 63, 2, 59, -11, 68, -11, 74), -+ CABAC_ENTRY(417, 9, -2, 17, -10, 9, -2, 23, -13), -+ CABAC_ENTRY(418, 26, -9, 32, -13, 30, -10, 26, -13), -+ CABAC_ENTRY(419, 33, -9, 42, -9, 31, -4, 40, -15), -+ CABAC_ENTRY(420, 39, -7, 49, -5, 33, -1, 49, -14), -+ CABAC_ENTRY(421, 41, -2, 53, 0, 33, 7, 44, 3), -+ CABAC_ENTRY(422, 45, 3, 64, 3, 31, 12, 45, 6), -+ CABAC_ENTRY(423, 49, 9, 68, 10, 37, 23, 44, 34), -+ CABAC_ENTRY(424, 45, 27, 66, 27, 31, 38, 33, 54), -+ CABAC_ENTRY(425, 36, 59, 47, 57, 20, 64, 19, 82), -+ CABAC_ENTRY(426, -6, 66, -5, 71, -9, 71, -3, 75), -+ CABAC_ENTRY(427, -7, 35, 0, 24, -7, 37, -1, 23), -+ CABAC_ENTRY(428, -7, 42, -1, 36, -8, 44, 1, 34), -+ CABAC_ENTRY(429, -8, 45, -2, 42, -11, 49, 1, 43), -+ CABAC_ENTRY(430, -5, 48, -2, 52, -10, 56, 0, 54), -+ CABAC_ENTRY(431, -12, 56, -9, 57, -12, 59, -2, 55), -+ CABAC_ENTRY(432, -6, 60, -6, 63, -8, 63, 0, 61), -+ CABAC_ENTRY(433, -5, 62, -4, 65, -9, 67, 1, 64), -+ CABAC_ENTRY(434, -8, 66, -4, 67, -6, 68, 0, 68), -+ CABAC_ENTRY(435, -8, 76, -7, 82, -10, 79, -9, 92), -+ CABAC_ENTRY(436, -5, 85, -3, 81, -3, 78, -14, 106), -+ CABAC_ENTRY(437, -6, 81, -3, 76, -8, 74, -13, 97), -+ CABAC_ENTRY(438, -10, 77, -7, 72, -9, 72, -15, 90), -+ CABAC_ENTRY(439, -7, 81, -6, 78, -10, 72, -12, 90), -+ CABAC_ENTRY(440, -17, 80, -12, 72, -18, 75, -18, 88), -+ CABAC_ENTRY(441, -18, 73, -14, 68, -12, 71, -10, 73), -+ CABAC_ENTRY(442, -4, 74, -3, 70, -11, 63, -9, 79), -+ CABAC_ENTRY(443, -10, 83, -6, 76, -5, 70, -14, 86), -+ CABAC_ENTRY(444, -9, 71, -5, 66, -17, 75, -10, 73), -+ CABAC_ENTRY(445, -9, 67, -5, 62, -14, 72, -10, 70), -+ CABAC_ENTRY(446, -1, 61, 0, 57, -16, 67, -10, 69), -+ CABAC_ENTRY(447, -8, 66, -4, 61, -8, 53, -5, 66), -+ CABAC_ENTRY(448, -14, 66, -9, 60, -14, 59, -9, 64), -+ CABAC_ENTRY(449, 0, 59, 1, 54, -9, 52, -5, 58), -+ CABAC_ENTRY(450, 2, 59, 2, 58, -11, 68, 2, 59), -+ CABAC_ENTRY(451, 21, -13, 17, -10, 9, -2, 21, -10), -+ CABAC_ENTRY(452, 33, -14, 32, -13, 30, -10, 24, -11), -+ CABAC_ENTRY(453, 39, -7, 42, -9, 31, -4, 28, -8), -+ CABAC_ENTRY(454, 46, -2, 49, -5, 33, -1, 28, -1), -+ CABAC_ENTRY(455, 51, 2, 53, 0, 33, 7, 29, 3), -+ CABAC_ENTRY(456, 60, 6, 64, 3, 31, 12, 29, 9), -+ CABAC_ENTRY(457, 61, 17, 68, 10, 37, 23, 35, 20), -+ CABAC_ENTRY(458, 55, 34, 66, 27, 31, 38, 29, 36), -+ CABAC_ENTRY(459, 42, 62, 47, 57, 20, 64, 14, 67), -+}; -+ -+static void set_ps_field(u32 *buf, struct rkvdec_ps_field field, u32 value) -+{ -+ u8 bit = field.offset % 32, word = field.offset / 32; -+ u64 mask = GENMASK_ULL(bit + field.len - 1, bit); -+ u64 val = ((u64)value << bit) & mask; -+ -+ buf[word] &= ~mask; -+ buf[word] |= val; -+ if (bit + field.len > 32) { -+ buf[word + 1] &= ~(mask >> 32); -+ buf[word + 1] |= val >> 32; -+ } -+} -+ -+static void assemble_hw_pps(struct rkvdec_ctx *ctx, -+ struct rkvdec_h264_run *run) -+{ -+ struct rkvdec_h264_ctx *h264_ctx = ctx->priv; -+ const struct v4l2_ctrl_h264_sps *sps = run->sps; -+ const struct v4l2_ctrl_h264_pps *pps = run->pps; -+ const struct v4l2_ctrl_h264_decode_params *dec_params = run->decode_params; -+ const struct v4l2_h264_dpb_entry *dpb = dec_params->dpb; -+ struct rkvdec_h264_priv_tbl *priv_tbl = h264_ctx->priv_tbl.cpu; -+ struct rkvdec_sps_pps_packet *hw_ps; -+ dma_addr_t scaling_list_address; -+ u32 scaling_distance; -+ u32 i; -+ -+ /* -+ * HW read the SPS/PPS information from PPS packet index by PPS id. -+ * offset from the base can be calculated by PPS_id * 32 (size per PPS -+ * packet unit). so the driver copy SPS/PPS information to the exact PPS -+ * packet unit for HW accessing. -+ */ -+ hw_ps = &priv_tbl->param_set[pps->pic_parameter_set_id]; -+ memset(hw_ps, 0, sizeof(*hw_ps)); -+ -+#define WRITE_PPS(value, field) set_ps_field(hw_ps->info, field, value) -+ /* write sps */ -+ WRITE_PPS(0xf, SEQ_PARAMETER_SET_ID); -+ WRITE_PPS(0xff, PROFILE_IDC); -+ WRITE_PPS(1, CONSTRAINT_SET3_FLAG); -+ WRITE_PPS(sps->chroma_format_idc, CHROMA_FORMAT_IDC); -+ WRITE_PPS(sps->bit_depth_luma_minus8 + 8, BIT_DEPTH_LUMA); -+ WRITE_PPS(sps->bit_depth_chroma_minus8 + 8, BIT_DEPTH_CHROMA); -+ WRITE_PPS(0, QPPRIME_Y_ZERO_TRANSFORM_BYPASS_FLAG); -+ WRITE_PPS(sps->log2_max_frame_num_minus4, LOG2_MAX_FRAME_NUM_MINUS4); -+ WRITE_PPS(sps->max_num_ref_frames, MAX_NUM_REF_FRAMES); -+ WRITE_PPS(sps->pic_order_cnt_type, PIC_ORDER_CNT_TYPE); -+ WRITE_PPS(sps->log2_max_pic_order_cnt_lsb_minus4, -+ LOG2_MAX_PIC_ORDER_CNT_LSB_MINUS4); -+ WRITE_PPS(!!(sps->flags & V4L2_H264_SPS_FLAG_DELTA_PIC_ORDER_ALWAYS_ZERO), -+ DELTA_PIC_ORDER_ALWAYS_ZERO_FLAG); -+ WRITE_PPS(DIV_ROUND_UP(ctx->coded_fmt.fmt.pix_mp.width, 16), PIC_WIDTH_IN_MBS); -+ WRITE_PPS(DIV_ROUND_UP(ctx->coded_fmt.fmt.pix_mp.height, 16), PIC_HEIGHT_IN_MBS); -+ WRITE_PPS(!!(sps->flags & V4L2_H264_SPS_FLAG_FRAME_MBS_ONLY), -+ FRAME_MBS_ONLY_FLAG); -+ WRITE_PPS(!!(sps->flags & V4L2_H264_SPS_FLAG_MB_ADAPTIVE_FRAME_FIELD), -+ MB_ADAPTIVE_FRAME_FIELD_FLAG); -+ WRITE_PPS(!!(sps->flags & V4L2_H264_SPS_FLAG_DIRECT_8X8_INFERENCE), -+ DIRECT_8X8_INFERENCE_FLAG); -+ -+ /* write pps */ -+ WRITE_PPS(0xff, PIC_PARAMETER_SET_ID); -+ WRITE_PPS(0x1f, PPS_SEQ_PARAMETER_SET_ID); -+ WRITE_PPS(!!(pps->flags & V4L2_H264_PPS_FLAG_ENTROPY_CODING_MODE), -+ ENTROPY_CODING_MODE_FLAG); -+ WRITE_PPS(!!(pps->flags & V4L2_H264_PPS_FLAG_BOTTOM_FIELD_PIC_ORDER_IN_FRAME_PRESENT), -+ BOTTOM_FIELD_PIC_ORDER_IN_FRAME_PRESENT_FLAG); -+ WRITE_PPS(pps->num_ref_idx_l0_default_active_minus1, -+ NUM_REF_IDX_L_DEFAULT_ACTIVE_MINUS1(0)); -+ WRITE_PPS(pps->num_ref_idx_l1_default_active_minus1, -+ NUM_REF_IDX_L_DEFAULT_ACTIVE_MINUS1(1)); -+ WRITE_PPS(!!(pps->flags & V4L2_H264_PPS_FLAG_WEIGHTED_PRED), -+ WEIGHTED_PRED_FLAG); -+ WRITE_PPS(pps->weighted_bipred_idc, WEIGHTED_BIPRED_IDC); -+ WRITE_PPS(pps->pic_init_qp_minus26, PIC_INIT_QP_MINUS26); -+ WRITE_PPS(pps->pic_init_qs_minus26, PIC_INIT_QS_MINUS26); -+ WRITE_PPS(pps->chroma_qp_index_offset, CHROMA_QP_INDEX_OFFSET); -+ WRITE_PPS(!!(pps->flags & V4L2_H264_PPS_FLAG_DEBLOCKING_FILTER_CONTROL_PRESENT), -+ DEBLOCKING_FILTER_CONTROL_PRESENT_FLAG); -+ WRITE_PPS(!!(pps->flags & V4L2_H264_PPS_FLAG_CONSTRAINED_INTRA_PRED), -+ CONSTRAINED_INTRA_PRED_FLAG); -+ WRITE_PPS(!!(pps->flags & V4L2_H264_PPS_FLAG_REDUNDANT_PIC_CNT_PRESENT), -+ REDUNDANT_PIC_CNT_PRESENT); -+ WRITE_PPS(!!(pps->flags & V4L2_H264_PPS_FLAG_TRANSFORM_8X8_MODE), -+ TRANSFORM_8X8_MODE_FLAG); -+ WRITE_PPS(pps->second_chroma_qp_index_offset, -+ SECOND_CHROMA_QP_INDEX_OFFSET); -+ -+ /* always use the matrix sent from userspace */ -+ WRITE_PPS(1, SCALING_LIST_ENABLE_FLAG); -+ -+ scaling_distance = offsetof(struct rkvdec_h264_priv_tbl, scaling_list); -+ scaling_list_address = h264_ctx->priv_tbl.dma + scaling_distance; -+ WRITE_PPS(scaling_list_address, SCALING_LIST_ADDRESS); -+ -+ for (i = 0; i < ARRAY_SIZE(dec_params->dpb); i++) { -+ u32 is_longterm = 0; -+ -+ if (dpb[i].flags & V4L2_H264_DPB_ENTRY_FLAG_LONG_TERM) -+ is_longterm = 1; -+ -+ WRITE_PPS(is_longterm, IS_LONG_TERM(i)); -+ } -+} -+ -+static void assemble_hw_rps(struct rkvdec_ctx *ctx, -+ struct rkvdec_h264_run *run) -+{ -+ const struct v4l2_ctrl_h264_decode_params *dec_params = run->decode_params; -+ const struct v4l2_ctrl_h264_slice_params *sl_params = &run->slices_params[0]; -+ const struct v4l2_h264_dpb_entry *dpb = dec_params->dpb; -+ struct rkvdec_h264_ctx *h264_ctx = ctx->priv; -+ const struct v4l2_ctrl_h264_sps *sps = run->sps; -+ struct rkvdec_h264_priv_tbl *priv_tbl = h264_ctx->priv_tbl.cpu; -+ u32 max_frame_num = 1 << (sps->log2_max_frame_num_minus4 + 4); -+ -+ u32 *hw_rps = priv_tbl->rps; -+ u32 i, j; -+ u16 *p = (u16 *)hw_rps; -+ -+ memset(hw_rps, 0, sizeof(priv_tbl->rps)); -+ -+ /* -+ * Assign an invalid pic_num if DPB entry at that position is inactive. -+ * If we assign 0 in that position hardware will treat that as a real -+ * reference picture with pic_num 0, triggering output picture -+ * corruption. -+ */ -+ for (i = 0; i < ARRAY_SIZE(dec_params->dpb); i++) { -+ if (!(dpb[i].flags & V4L2_H264_DPB_ENTRY_FLAG_ACTIVE)) -+ continue; -+ -+ if (dpb[i].flags & V4L2_H264_DPB_ENTRY_FLAG_LONG_TERM || -+ dpb[i].frame_num < sl_params->frame_num) { -+ p[i] = dpb[i].frame_num; -+ continue; -+ } -+ -+ p[i] = dpb[i].frame_num - max_frame_num; -+ } -+ -+ for (j = 0; j < RKVDEC_NUM_REFLIST; j++) { -+ for (i = 0; i < h264_ctx->reflists.num_valid; i++) { -+ u8 dpb_valid = 0; -+ u8 idx = 0; -+ -+ switch (j) { -+ case 0: -+ idx = h264_ctx->reflists.p[i]; -+ break; -+ case 1: -+ idx = h264_ctx->reflists.b0[i]; -+ break; -+ case 2: -+ idx = h264_ctx->reflists.b1[i]; -+ break; -+ } -+ -+ if (idx >= ARRAY_SIZE(dec_params->dpb)) -+ continue; -+ dpb_valid = !!(dpb[idx].flags & -+ V4L2_H264_DPB_ENTRY_FLAG_ACTIVE); -+ -+ set_ps_field(hw_rps, DPB_INFO(i, j), -+ idx | dpb_valid << 4); -+ } -+ } -+} -+ -+/* -+ * NOTE: The values in a scaling list are in zig-zag order, apply inverse -+ * scanning process to get the values in matrix order. -+ */ -+static const u32 zig_zag_4x4[16] = { -+ 0, 1, 4, 8, 5, 2, 3, 6, 9, 12, 13, 10, 7, 11, 14, 15 -+}; -+ -+static const u32 zig_zag_8x8[64] = { -+ 0, 1, 8, 16, 9, 2, 3, 10, 17, 24, 32, 25, 18, 11, 4, 5, -+ 12, 19, 26, 33, 40, 48, 41, 34, 27, 20, 13, 6, 7, 14, 21, 28, -+ 35, 42, 49, 56, 57, 50, 43, 36, 29, 22, 15, 23, 30, 37, 44, 51, -+ 58, 59, 52, 45, 38, 31, 39, 46, 53, 60, 61, 54, 47, 55, 62, 63 -+}; -+ -+static void reorder_scaling_list(struct rkvdec_ctx *ctx, -+ struct rkvdec_h264_run *run) -+{ -+ const struct v4l2_ctrl_h264_scaling_matrix *scaling = run->scaling_matrix; -+ const size_t num_list_4x4 = ARRAY_SIZE(scaling->scaling_list_4x4); -+ const size_t list_len_4x4 = ARRAY_SIZE(scaling->scaling_list_4x4[0]); -+ const size_t num_list_8x8 = ARRAY_SIZE(scaling->scaling_list_8x8); -+ const size_t list_len_8x8 = ARRAY_SIZE(scaling->scaling_list_8x8[0]); -+ struct rkvdec_h264_ctx *h264_ctx = ctx->priv; -+ struct rkvdec_h264_priv_tbl *tbl = h264_ctx->priv_tbl.cpu; -+ u8 *dst = tbl->scaling_list; -+ const u8 *src; -+ int i, j; -+ -+ BUILD_BUG_ON(ARRAY_SIZE(zig_zag_4x4) != list_len_4x4); -+ BUILD_BUG_ON(ARRAY_SIZE(zig_zag_8x8) != list_len_8x8); -+ BUILD_BUG_ON(ARRAY_SIZE(tbl->scaling_list) < -+ num_list_4x4 * list_len_4x4 + -+ num_list_8x8 * list_len_8x8); -+ -+ src = &scaling->scaling_list_4x4[0][0]; -+ for (i = 0; i < num_list_4x4; ++i) { -+ for (j = 0; j < list_len_4x4; ++j) -+ dst[zig_zag_4x4[j]] = src[j]; -+ src += list_len_4x4; -+ dst += list_len_4x4; -+ } -+ -+ src = &scaling->scaling_list_8x8[0][0]; -+ for (i = 0; i < num_list_8x8; ++i) { -+ for (j = 0; j < list_len_8x8; ++j) -+ dst[zig_zag_8x8[j]] = src[j]; -+ src += list_len_8x8; -+ dst += list_len_8x8; -+ } -+} -+ -+/* -+ * dpb poc related registers table -+ */ -+static const u32 poc_reg_tbl_top_field[16] = { -+ RKVDEC_REG_H264_POC_REFER0(0), -+ RKVDEC_REG_H264_POC_REFER0(2), -+ RKVDEC_REG_H264_POC_REFER0(4), -+ RKVDEC_REG_H264_POC_REFER0(6), -+ RKVDEC_REG_H264_POC_REFER0(8), -+ RKVDEC_REG_H264_POC_REFER0(10), -+ RKVDEC_REG_H264_POC_REFER0(12), -+ RKVDEC_REG_H264_POC_REFER0(14), -+ RKVDEC_REG_H264_POC_REFER1(1), -+ RKVDEC_REG_H264_POC_REFER1(3), -+ RKVDEC_REG_H264_POC_REFER1(5), -+ RKVDEC_REG_H264_POC_REFER1(7), -+ RKVDEC_REG_H264_POC_REFER1(9), -+ RKVDEC_REG_H264_POC_REFER1(11), -+ RKVDEC_REG_H264_POC_REFER1(13), -+ RKVDEC_REG_H264_POC_REFER2(0) -+}; -+ -+static const u32 poc_reg_tbl_bottom_field[16] = { -+ RKVDEC_REG_H264_POC_REFER0(1), -+ RKVDEC_REG_H264_POC_REFER0(3), -+ RKVDEC_REG_H264_POC_REFER0(5), -+ RKVDEC_REG_H264_POC_REFER0(7), -+ RKVDEC_REG_H264_POC_REFER0(9), -+ RKVDEC_REG_H264_POC_REFER0(11), -+ RKVDEC_REG_H264_POC_REFER0(13), -+ RKVDEC_REG_H264_POC_REFER1(0), -+ RKVDEC_REG_H264_POC_REFER1(2), -+ RKVDEC_REG_H264_POC_REFER1(4), -+ RKVDEC_REG_H264_POC_REFER1(6), -+ RKVDEC_REG_H264_POC_REFER1(8), -+ RKVDEC_REG_H264_POC_REFER1(10), -+ RKVDEC_REG_H264_POC_REFER1(12), -+ RKVDEC_REG_H264_POC_REFER1(14), -+ RKVDEC_REG_H264_POC_REFER2(1) -+}; -+ -+static struct vb2_buffer * -+get_ref_buf(struct rkvdec_ctx *ctx, struct rkvdec_h264_run *run, -+ unsigned int dpb_idx) -+{ -+ struct v4l2_m2m_ctx *m2m_ctx = ctx->fh.m2m_ctx; -+ const struct v4l2_h264_dpb_entry *dpb = run->decode_params->dpb; -+ struct vb2_queue *cap_q = &m2m_ctx->cap_q_ctx.q; -+ int buf_idx = -1; -+ -+ if (dpb[dpb_idx].flags & V4L2_H264_DPB_ENTRY_FLAG_ACTIVE) -+ buf_idx = vb2_find_timestamp(cap_q, -+ dpb[dpb_idx].reference_ts, 0); -+ -+ /* -+ * If a DPB entry is unused or invalid, address of current destination -+ * buffer is returned. -+ */ -+ if (buf_idx < 0) -+ return &run->base.bufs.dst->vb2_buf; -+ -+ return vb2_get_buffer(cap_q, buf_idx); -+} -+ -+static void config_registers(struct rkvdec_ctx *ctx, -+ struct rkvdec_h264_run *run) -+{ -+ struct rkvdec_dev *rkvdec = ctx->dev; -+ const struct v4l2_ctrl_h264_decode_params *dec_params = run->decode_params; -+ const struct v4l2_ctrl_h264_sps *sps = run->sps; -+ const struct v4l2_h264_dpb_entry *dpb = dec_params->dpb; -+ struct rkvdec_h264_ctx *h264_ctx = ctx->priv; -+ dma_addr_t priv_start_addr = h264_ctx->priv_tbl.dma; -+ const struct v4l2_pix_format_mplane *dst_fmt; -+ struct vb2_v4l2_buffer *src_buf = run->base.bufs.src; -+ struct vb2_v4l2_buffer *dst_buf = run->base.bufs.dst; -+ const struct v4l2_format *f; -+ dma_addr_t rlc_addr; -+ dma_addr_t refer_addr; -+ u32 rlc_len; -+ u32 hor_virstride = 0; -+ u32 ver_virstride = 0; -+ u32 y_virstride = 0; -+ u32 yuv_virstride = 0; -+ u32 offset; -+ dma_addr_t dst_addr; -+ u32 reg, i; -+ -+ reg = RKVDEC_MODE(RKVDEC_MODE_H264); -+ writel_relaxed(reg, rkvdec->regs + RKVDEC_REG_SYSCTRL); -+ -+ f = &ctx->decoded_fmt; -+ dst_fmt = &f->fmt.pix_mp; -+ hor_virstride = (sps->bit_depth_luma_minus8 + 8) * dst_fmt->width / 8; -+ ver_virstride = round_up(dst_fmt->height, 16); -+ y_virstride = hor_virstride * ver_virstride; -+ -+ if (sps->chroma_format_idc == 0) -+ yuv_virstride = y_virstride; -+ else if (sps->chroma_format_idc == 1) -+ yuv_virstride += y_virstride + y_virstride / 2; -+ else if (sps->chroma_format_idc == 2) -+ yuv_virstride += 2 * y_virstride; -+ -+ reg = RKVDEC_Y_HOR_VIRSTRIDE(hor_virstride / 16) | -+ RKVDEC_UV_HOR_VIRSTRIDE(hor_virstride / 16) | -+ RKVDEC_SLICE_NUM_HIGHBIT | -+ RKVDEC_SLICE_NUM_LOWBITS(0x7ff); -+ writel_relaxed(reg, rkvdec->regs + RKVDEC_REG_PICPAR); -+ -+ /* config rlc base address */ -+ rlc_addr = vb2_dma_contig_plane_dma_addr(&src_buf->vb2_buf, 0); -+ writel_relaxed(rlc_addr, rkvdec->regs + RKVDEC_REG_STRM_RLC_BASE); -+ writel_relaxed(rlc_addr, rkvdec->regs + RKVDEC_REG_RLCWRITE_BASE); -+ -+ rlc_len = vb2_get_plane_payload(&src_buf->vb2_buf, 0); -+ reg = RKVDEC_STRM_LEN(rlc_len); -+ writel_relaxed(reg, rkvdec->regs + RKVDEC_REG_STRM_LEN); -+ -+ /* config cabac table */ -+ offset = offsetof(struct rkvdec_h264_priv_tbl, cabac_table); -+ writel_relaxed(priv_start_addr + offset, -+ rkvdec->regs + RKVDEC_REG_CABACTBL_PROB_BASE); -+ -+ /* config output base address */ -+ dst_addr = vb2_dma_contig_plane_dma_addr(&dst_buf->vb2_buf, 0); -+ writel_relaxed(dst_addr, rkvdec->regs + RKVDEC_REG_DECOUT_BASE); -+ -+ reg = RKVDEC_Y_VIRSTRIDE(y_virstride / 16); -+ writel_relaxed(reg, rkvdec->regs + RKVDEC_REG_Y_VIRSTRIDE); -+ -+ reg = RKVDEC_YUV_VIRSTRIDE(yuv_virstride / 16); -+ writel_relaxed(reg, rkvdec->regs + RKVDEC_REG_YUV_VIRSTRIDE); -+ -+ /* config ref pic address & poc */ -+ for (i = 0; i < ARRAY_SIZE(dec_params->dpb); i++) { -+ struct vb2_buffer *vb_buf = get_ref_buf(ctx, run, i); -+ -+ refer_addr = vb2_dma_contig_plane_dma_addr(vb_buf, 0) | -+ RKVDEC_COLMV_USED_FLAG_REF; -+ -+ if (!(dpb[i].flags & V4L2_H264_DPB_ENTRY_FLAG_FIELD)) -+ refer_addr |= RKVDEC_TOPFIELD_USED_REF | -+ RKVDEC_BOTFIELD_USED_REF; -+ else if (dpb[i].flags & V4L2_H264_DPB_ENTRY_FLAG_BOTTOM_FIELD) -+ refer_addr |= RKVDEC_BOTFIELD_USED_REF; -+ else -+ refer_addr |= RKVDEC_TOPFIELD_USED_REF; -+ -+ writel_relaxed(dpb[i].top_field_order_cnt, -+ rkvdec->regs + poc_reg_tbl_top_field[i]); -+ writel_relaxed(dpb[i].bottom_field_order_cnt, -+ rkvdec->regs + poc_reg_tbl_bottom_field[i]); -+ -+ if (i < V4L2_H264_NUM_DPB_ENTRIES - 1) -+ writel_relaxed(refer_addr, -+ rkvdec->regs + RKVDEC_REG_H264_BASE_REFER(i)); -+ else -+ writel_relaxed(refer_addr, -+ rkvdec->regs + RKVDEC_REG_H264_BASE_REFER15); -+ } -+ -+ /* -+ * Since support frame mode only -+ * top_field_order_cnt is the same as bottom_field_order_cnt -+ */ -+ reg = RKVDEC_CUR_POC(dec_params->top_field_order_cnt); -+ writel_relaxed(reg, rkvdec->regs + RKVDEC_REG_CUR_POC0); -+ -+ reg = RKVDEC_CUR_POC(dec_params->bottom_field_order_cnt); -+ writel_relaxed(reg, rkvdec->regs + RKVDEC_REG_CUR_POC1); -+ -+ /* config hw pps address */ -+ offset = offsetof(struct rkvdec_h264_priv_tbl, param_set); -+ writel_relaxed(priv_start_addr + offset, -+ rkvdec->regs + RKVDEC_REG_PPS_BASE); -+ -+ /* config hw rps address */ -+ offset = offsetof(struct rkvdec_h264_priv_tbl, rps); -+ writel_relaxed(priv_start_addr + offset, -+ rkvdec->regs + RKVDEC_REG_RPS_BASE); -+ -+ reg = RKVDEC_AXI_DDR_RDATA(0); -+ writel_relaxed(reg, rkvdec->regs + RKVDEC_REG_AXI_DDR_RDATA); -+ -+ reg = RKVDEC_AXI_DDR_WDATA(0); -+ writel_relaxed(reg, rkvdec->regs + RKVDEC_REG_AXI_DDR_WDATA); -+ -+ offset = offsetof(struct rkvdec_h264_priv_tbl, err_info); -+ writel_relaxed(priv_start_addr + offset, -+ rkvdec->regs + RKVDEC_REG_H264_ERRINFO_BASE); -+} -+ -+#define RKVDEC_H264_MAX_DEPTH_IN_BYTES 2 -+ -+static int rkvdec_h264_adjust_fmt(struct rkvdec_ctx *ctx, -+ struct v4l2_format *f) -+{ -+ struct v4l2_pix_format_mplane *fmt = &f->fmt.pix_mp; -+ -+ fmt->num_planes = 1; -+ fmt->plane_fmt[0].sizeimage = fmt->width * fmt->height * -+ RKVDEC_H264_MAX_DEPTH_IN_BYTES; -+ return 0; -+} -+ -+static int rkvdec_h264_start(struct rkvdec_ctx *ctx) -+{ -+ struct rkvdec_dev *rkvdec = ctx->dev; -+ struct rkvdec_h264_priv_tbl *priv_tbl; -+ struct rkvdec_h264_ctx *h264_ctx; -+ int ret; -+ -+ h264_ctx = kzalloc(sizeof(*h264_ctx), GFP_KERNEL); -+ if (!h264_ctx) -+ return -ENOMEM; -+ -+ priv_tbl = dma_alloc_coherent(rkvdec->dev, sizeof(*priv_tbl), -+ &h264_ctx->priv_tbl.dma, GFP_KERNEL); -+ if (!priv_tbl) { -+ ret = -ENOMEM; -+ goto err_free_ctx; -+ } -+ -+ h264_ctx->priv_tbl.size = sizeof(*priv_tbl); -+ h264_ctx->priv_tbl.cpu = priv_tbl; -+ memcpy(priv_tbl->cabac_table, rkvdec_h264_cabac_table, -+ sizeof(rkvdec_h264_cabac_table)); -+ -+ ctx->priv = h264_ctx; -+ return 0; -+ -+err_free_ctx: -+ kfree(h264_ctx); -+ return ret; -+} -+ -+static void rkvdec_h264_stop(struct rkvdec_ctx *ctx) -+{ -+ struct rkvdec_h264_ctx *h264_ctx = ctx->priv; -+ struct rkvdec_dev *rkvdec = ctx->dev; -+ -+ dma_free_coherent(rkvdec->dev, h264_ctx->priv_tbl.size, -+ h264_ctx->priv_tbl.cpu, h264_ctx->priv_tbl.dma); -+ kfree(h264_ctx); -+} -+ -+static void rkvdec_h264_run_preamble(struct rkvdec_ctx *ctx, -+ struct rkvdec_h264_run *run) -+{ -+ struct v4l2_ctrl *ctrl; -+ -+ ctrl = v4l2_ctrl_find(&ctx->ctrl_hdl, -+ V4L2_CID_MPEG_VIDEO_H264_DECODE_PARAMS); -+ run->decode_params = ctrl ? ctrl->p_cur.p : NULL; -+ ctrl = v4l2_ctrl_find(&ctx->ctrl_hdl, -+ V4L2_CID_MPEG_VIDEO_H264_SLICE_PARAMS); -+ run->slices_params = ctrl ? ctrl->p_cur.p : NULL; -+ ctrl = v4l2_ctrl_find(&ctx->ctrl_hdl, -+ V4L2_CID_MPEG_VIDEO_H264_SPS); -+ run->sps = ctrl ? ctrl->p_cur.p : NULL; -+ ctrl = v4l2_ctrl_find(&ctx->ctrl_hdl, -+ V4L2_CID_MPEG_VIDEO_H264_PPS); -+ run->pps = ctrl ? ctrl->p_cur.p : NULL; -+ ctrl = v4l2_ctrl_find(&ctx->ctrl_hdl, -+ V4L2_CID_MPEG_VIDEO_H264_SCALING_MATRIX); -+ run->scaling_matrix = ctrl ? ctrl->p_cur.p : NULL; -+ -+ rkvdec_run_preamble(ctx, &run->base); -+} -+ -+static int rkvdec_h264_run(struct rkvdec_ctx *ctx) -+{ -+ struct v4l2_h264_reflist_builder reflist_builder; -+ struct rkvdec_dev *rkvdec = ctx->dev; -+ struct rkvdec_h264_ctx *h264_ctx = ctx->priv; -+ struct rkvdec_h264_run run; -+ -+ rkvdec_h264_run_preamble(ctx, &run); -+ -+ /* Build the P/B{0,1} ref lists. */ -+ v4l2_h264_init_reflist_builder(&reflist_builder, run.decode_params, -+ &run.slices_params[0], run.sps, -+ run.decode_params->dpb); -+ h264_ctx->reflists.num_valid = reflist_builder.num_valid; -+ v4l2_h264_build_p_ref_list(&reflist_builder, h264_ctx->reflists.p); -+ v4l2_h264_build_b_ref_lists(&reflist_builder, h264_ctx->reflists.b0, -+ h264_ctx->reflists.b1); -+ -+ reorder_scaling_list(ctx, &run); -+ assemble_hw_pps(ctx, &run); -+ assemble_hw_rps(ctx, &run); -+ config_registers(ctx, &run); -+ -+ rkvdec_run_postamble(ctx, &run.base); -+ -+ schedule_delayed_work(&rkvdec->watchdog_work, msecs_to_jiffies(2000)); -+ -+ writel(0xffffffff, rkvdec->regs + RKVDEC_REG_STRMD_ERR_EN); -+ writel(0xffffffff, rkvdec->regs + RKVDEC_REG_H264_ERR_E); -+ writel(1, rkvdec->regs + RKVDEC_REG_PREF_LUMA_CACHE_COMMAND); -+ writel(1, rkvdec->regs + RKVDEC_REG_PREF_CHR_CACHE_COMMAND); -+ -+ /* Start decoding! */ -+ writel(RKVDEC_INTERRUPT_DEC_E | RKVDEC_CONFIG_DEC_CLK_GATE_E | -+ RKVDEC_TIMEOUT_E | RKVDEC_BUF_EMPTY_E, -+ rkvdec->regs + RKVDEC_REG_INTERRUPT); -+ -+ return 0; -+} -+ -+const struct rkvdec_coded_fmt_ops rkvdec_h264_fmt_ops = { -+ .adjust_fmt = rkvdec_h264_adjust_fmt, -+ .start = rkvdec_h264_start, -+ .stop = rkvdec_h264_stop, -+ .run = rkvdec_h264_run, -+}; -diff --git a/drivers/staging/media/rkvdec/rkvdec-regs.h b/drivers/staging/media/rkvdec/rkvdec-regs.h -new file mode 100644 -index 000000000000..15b9bee92016 ---- /dev/null -+++ b/drivers/staging/media/rkvdec/rkvdec-regs.h -@@ -0,0 +1,223 @@ -+/* SPDX-License-Identifier: GPL-2.0 */ -+ -+#ifndef RKVDEC_REGS_H_ -+#define RKVDEC_REGS_H_ -+ -+/* rkvcodec registers */ -+#define RKVDEC_REG_INTERRUPT 0x004 -+#define RKVDEC_INTERRUPT_DEC_E BIT(0) -+#define RKVDEC_CONFIG_DEC_CLK_GATE_E BIT(1) -+#define RKVDEC_E_STRMD_CLKGATE_DIS BIT(2) -+#define RKVDEC_TIMEOUT_MODE BIT(3) -+#define RKVDEC_IRQ_DIS BIT(4) -+#define RKVDEC_TIMEOUT_E BIT(5) -+#define RKVDEC_BUF_EMPTY_E BIT(6) -+#define RKVDEC_STRM_E_WAITDECFIFO_EMPTY BIT(7) -+#define RKVDEC_IRQ BIT(8) -+#define RKVDEC_IRQ_RAW BIT(9) -+#define RKVDEC_E_REWRITE_VALID BIT(10) -+#define RKVDEC_COMMONIRQ_MODE BIT(11) -+#define RKVDEC_RDY_STA BIT(12) -+#define RKVDEC_BUS_STA BIT(13) -+#define RKVDEC_ERR_STA BIT(14) -+#define RKVDEC_TIMEOUT_STA BIT(15) -+#define RKVDEC_BUF_EMPTY_STA BIT(16) -+#define RKVDEC_COLMV_REF_ERR_STA BIT(17) -+#define RKVDEC_CABU_END_STA BIT(18) -+#define RKVDEC_H264ORVP9_ERR_MODE BIT(19) -+#define RKVDEC_SOFTRST_EN_P BIT(20) -+#define RKVDEC_FORCE_SOFTRESET_VALID BIT(21) -+#define RKVDEC_SOFTRESET_RDY BIT(22) -+ -+#define RKVDEC_REG_SYSCTRL 0x008 -+#define RKVDEC_IN_ENDIAN BIT(0) -+#define RKVDEC_IN_SWAP32_E BIT(1) -+#define RKVDEC_IN_SWAP64_E BIT(2) -+#define RKVDEC_STR_ENDIAN BIT(3) -+#define RKVDEC_STR_SWAP32_E BIT(4) -+#define RKVDEC_STR_SWAP64_E BIT(5) -+#define RKVDEC_OUT_ENDIAN BIT(6) -+#define RKVDEC_OUT_SWAP32_E BIT(7) -+#define RKVDEC_OUT_CBCR_SWAP BIT(8) -+#define RKVDEC_RLC_MODE_DIRECT_WRITE BIT(10) -+#define RKVDEC_RLC_MODE BIT(11) -+#define RKVDEC_STRM_START_BIT(x) (((x) & 0x7f) << 12) -+#define RKVDEC_MODE(x) (((x) & 0x03) << 20) -+#define RKVDEC_MODE_H264 1 -+#define RKVDEC_MODE_VP9 2 -+#define RKVDEC_RPS_MODE BIT(24) -+#define RKVDEC_STRM_MODE BIT(25) -+#define RKVDEC_H264_STRM_LASTPKT BIT(26) -+#define RKVDEC_H264_FIRSTSLICE_FLAG BIT(27) -+#define RKVDEC_H264_FRAME_ORSLICE BIT(28) -+#define RKVDEC_BUSPR_SLOT_DIS BIT(29) -+ -+#define RKVDEC_REG_PICPAR 0x00C -+#define RKVDEC_Y_HOR_VIRSTRIDE(x) ((x) & 0x1ff) -+#define RKVDEC_SLICE_NUM_HIGHBIT BIT(11) -+#define RKVDEC_UV_HOR_VIRSTRIDE(x) (((x) & 0x1ff) << 12) -+#define RKVDEC_SLICE_NUM_LOWBITS(x) (((x) & 0x7ff) << 21) -+ -+#define RKVDEC_REG_STRM_RLC_BASE 0x010 -+ -+#define RKVDEC_REG_STRM_LEN 0x014 -+#define RKVDEC_STRM_LEN(x) ((x) & 0x7ffffff) -+ -+#define RKVDEC_REG_CABACTBL_PROB_BASE 0x018 -+#define RKVDEC_REG_DECOUT_BASE 0x01C -+ -+#define RKVDEC_REG_Y_VIRSTRIDE 0x020 -+#define RKVDEC_Y_VIRSTRIDE(x) ((x) & 0xfffff) -+ -+#define RKVDEC_REG_YUV_VIRSTRIDE 0x024 -+#define RKVDEC_YUV_VIRSTRIDE(x) ((x) & 0x1fffff) -+#define RKVDEC_REG_H264_BASE_REFER(i) (((i) * 0x04) + 0x028) -+ -+#define RKVDEC_REG_H264_BASE_REFER15 0x0C0 -+#define RKVDEC_FIELD_REF BIT(0) -+#define RKVDEC_TOPFIELD_USED_REF BIT(1) -+#define RKVDEC_BOTFIELD_USED_REF BIT(2) -+#define RKVDEC_COLMV_USED_FLAG_REF BIT(3) -+ -+#define RKVDEC_REG_VP9_LAST_FRAME_BASE 0x02c -+#define RKVDEC_REG_VP9_GOLDEN_FRAME_BASE 0x030 -+#define RKVDEC_REG_VP9_ALTREF_FRAME_BASE 0x034 -+ -+#define RKVDEC_REG_VP9_CPRHEADER_OFFSET 0x028 -+#define RKVDEC_VP9_CPRHEADER_OFFSET(x) ((x) & 0xffff) -+ -+#define RKVDEC_REG_VP9_REFERLAST_BASE 0x02C -+#define RKVDEC_REG_VP9_REFERGOLDEN_BASE 0x030 -+#define RKVDEC_REG_VP9_REFERALFTER_BASE 0x034 -+ -+#define RKVDEC_REG_VP9COUNT_BASE 0x038 -+#define RKVDEC_VP9COUNT_UPDATE_EN BIT(0) -+ -+#define RKVDEC_REG_VP9_SEGIDLAST_BASE 0x03C -+#define RKVDEC_REG_VP9_SEGIDCUR_BASE 0x040 -+#define RKVDEC_REG_VP9_FRAME_SIZE(i) ((i) * 0x04 + 0x044) -+#define RKVDEC_VP9_FRAMEWIDTH(x) (((x) & 0xffff) << 0) -+#define RKVDEC_VP9_FRAMEHEIGHT(x) (((x) & 0xffff) << 16) -+ -+#define RKVDEC_VP9_SEGID_GRP(i) ((i) * 0x04 + 0x050) -+#define RKVDEC_SEGID_ABS_DELTA(x) ((x) & 0x1) -+#define RKVDEC_SEGID_FRAME_QP_DELTA_EN(x) (((x) & 0x1) << 1) -+#define RKVDEC_SEGID_FRAME_QP_DELTA(x) (((x) & 0x1ff) << 2) -+#define RKVDEC_SEGID_FRAME_LOOPFILTER_VALUE_EN(x) (((x) & 0x1) << 11) -+#define RKVDEC_SEGID_FRAME_LOOPFILTER_VALUE(x) (((x) & 0x7f) << 12) -+#define RKVDEC_SEGID_REFERINFO_EN(x) (((x) & 0x1) << 19) -+#define RKVDEC_SEGID_REFERINFO(x) (((x) & 0x03) << 20) -+#define RKVDEC_SEGID_FRAME_SKIP_EN(x) (((x) & 0x1) << 22) -+ -+#define RKVDEC_VP9_CPRHEADER_CONFIG 0x070 -+#define RKVDEC_VP9_TX_MODE(x) ((x) & 0x07) -+#define RKVDEC_VP9_FRAME_REF_MODE(x) (((x) & 0x03) << 3) -+ -+#define RKVDEC_VP9_REF_SCALE(i) ((i) * 0x04 + 0x074) -+#define RKVDEC_VP9_REF_HOR_SCALE(x) ((x) & 0xffff) -+#define RKVDEC_VP9_REF_VER_SCALE(x) (((x) & 0xffff) << 16) -+ -+#define RKVDEC_VP9_REF_DELTAS_LASTFRAME 0x080 -+#define RKVDEC_REF_DELTAS_LASTFRAME(pos, val) (((val) & 0x7f) << ((pos) * 7)) -+ -+#define RKVDEC_VP9_INFO_LASTFRAME 0x084 -+#define RKVDEC_MODE_DELTAS_LASTFRAME(pos, val) (((val) & 0x7f) << ((pos) * 7)) -+#define RKVDEC_SEG_EN_LASTFRAME BIT(16) -+#define RKVDEC_LAST_SHOW_FRAME BIT(17) -+#define RKVDEC_LAST_INTRA_ONLY BIT(18) -+#define RKVDEC_LAST_WIDHHEIGHT_EQCUR BIT(19) -+#define RKVDEC_COLOR_SPACE_LASTKEYFRAME(x) (((x) & 0x07) << 20) -+ -+#define RKVDEC_VP9_INTERCMD_BASE 0x088 -+ -+#define RKVDEC_VP9_INTERCMD_NUM 0x08C -+#define RKVDEC_INTERCMD_NUM(x) ((x) & 0xffffff) -+ -+#define RKVDEC_VP9_LASTTILE_SIZE 0x090 -+#define RKVDEC_LASTTILE_SIZE(x) ((x) & 0xffffff) -+ -+#define RKVDEC_VP9_HOR_VIRSTRIDE(i) ((i) * 0x04 + 0x094) -+#define RKVDEC_HOR_Y_VIRSTRIDE(x) ((x) & 0x1ff) -+#define RKVDEC_HOR_UV_VIRSTRIDE(x) (((x) & 0x1ff) << 16) -+ -+#define RKVDEC_REG_H264_POC_REFER0(i) (((i) * 0x04) + 0x064) -+#define RKVDEC_REG_H264_POC_REFER1(i) (((i) * 0x04) + 0x0C4) -+#define RKVDEC_REG_H264_POC_REFER2(i) (((i) * 0x04) + 0x120) -+#define RKVDEC_POC_REFER(x) ((x) & 0xffffffff) -+ -+#define RKVDEC_REG_CUR_POC0 0x0A0 -+#define RKVDEC_REG_CUR_POC1 0x128 -+#define RKVDEC_CUR_POC(x) ((x) & 0xffffffff) -+ -+#define RKVDEC_REG_RLCWRITE_BASE 0x0A4 -+#define RKVDEC_REG_PPS_BASE 0x0A8 -+#define RKVDEC_REG_RPS_BASE 0x0AC -+ -+#define RKVDEC_REG_STRMD_ERR_EN 0x0B0 -+#define RKVDEC_STRMD_ERR_EN(x) ((x) & 0xffffffff) -+ -+#define RKVDEC_REG_STRMD_ERR_STA 0x0B4 -+#define RKVDEC_STRMD_ERR_STA(x) ((x) & 0xfffffff) -+#define RKVDEC_COLMV_ERR_REF_PICIDX(x) (((x) & 0x0f) << 28) -+ -+#define RKVDEC_REG_STRMD_ERR_CTU 0x0B8 -+#define RKVDEC_STRMD_ERR_CTU(x) ((x) & 0xff) -+#define RKVDEC_STRMD_ERR_CTU_YOFFSET(x) (((x) & 0xff) << 8) -+#define RKVDEC_STRMFIFO_SPACE2FULL(x) (((x) & 0x7f) << 16) -+#define RKVDEC_VP9_ERR_EN_CTU0 BIT(24) -+ -+#define RKVDEC_REG_SAO_CTU_POS 0x0BC -+#define RKVDEC_SAOWR_XOFFSET(x) ((x) & 0x1ff) -+#define RKVDEC_SAOWR_YOFFSET(x) (((x) & 0x3ff) << 16) -+ -+#define RKVDEC_VP9_LAST_FRAME_YSTRIDE 0x0C0 -+#define RKVDEC_VP9_GOLDEN_FRAME_YSTRIDE 0x0C4 -+#define RKVDEC_VP9_ALTREF_FRAME_YSTRIDE 0x0C8 -+#define RKVDEC_VP9_REF_YSTRIDE(x) (((x) & 0xfffff) << 0) -+ -+#define RKVDEC_VP9_LAST_FRAME_YUVSTRIDE 0x0CC -+#define RKVDEC_VP9_REF_YUVSTRIDE(x) (((x) & 0x1fffff) << 0) -+ -+#define RKVDEC_VP9_REF_COLMV_BASE 0x0D0 -+ -+#define RKVDEC_REG_PERFORMANCE_CYCLE 0x100 -+#define RKVDEC_PERFORMANCE_CYCLE(x) ((x) & 0xffffffff) -+ -+#define RKVDEC_REG_AXI_DDR_RDATA 0x104 -+#define RKVDEC_AXI_DDR_RDATA(x) ((x) & 0xffffffff) -+ -+#define RKVDEC_REG_AXI_DDR_WDATA 0x108 -+#define RKVDEC_AXI_DDR_WDATA(x) ((x) & 0xffffffff) -+ -+#define RKVDEC_REG_FPGADEBUG_RESET 0x10C -+#define RKVDEC_BUSIFD_RESETN BIT(0) -+#define RKVDEC_CABAC_RESETN BIT(1) -+#define RKVDEC_DEC_CTRL_RESETN BIT(2) -+#define RKVDEC_TRANSD_RESETN BIT(3) -+#define RKVDEC_INTRA_RESETN BIT(4) -+#define RKVDEC_INTER_RESETN BIT(5) -+#define RKVDEC_RECON_RESETN BIT(6) -+#define RKVDEC_FILER_RESETN BIT(7) -+ -+#define RKVDEC_REG_PERFORMANCE_SEL 0x110 -+#define RKVDEC_PERF_SEL_CNT0(x) ((x) & 0x3f) -+#define RKVDEC_PERF_SEL_CNT1(x) (((x) & 0x3f) << 8) -+#define RKVDEC_PERF_SEL_CNT2(x) (((x) & 0x3f) << 16) -+ -+#define RKVDEC_REG_PERFORMANCE_CNT(i) ((i) * 0x04 + 0x114) -+#define RKVDEC_PERF_CNT(x) ((x) & 0xffffffff) -+ -+#define RKVDEC_REG_H264_ERRINFO_BASE 0x12C -+ -+#define RKVDEC_REG_H264_ERRINFO_NUM 0x130 -+#define RKVDEC_SLICEDEC_NUM(x) ((x) & 0x3fff) -+#define RKVDEC_STRMD_DECT_ERR_FLAG BIT(15) -+#define RKVDEC_ERR_PKT_NUM(x) (((x) & 0x3fff) << 16) -+ -+#define RKVDEC_REG_H264_ERR_E 0x134 -+#define RKVDEC_H264_ERR_EN_HIGHBITS(x) ((x) & 0x3fffffff) -+ -+#define RKVDEC_REG_PREF_LUMA_CACHE_COMMAND 0x410 -+#define RKVDEC_REG_PREF_CHR_CACHE_COMMAND 0x450 -+ -+#endif /* RKVDEC_REGS_H_ */ -diff --git a/drivers/staging/media/rkvdec/rkvdec.c b/drivers/staging/media/rkvdec/rkvdec.c -new file mode 100644 -index 000000000000..225eeca73356 ---- /dev/null -+++ b/drivers/staging/media/rkvdec/rkvdec.c -@@ -0,0 +1,1103 @@ -+// SPDX-License-Identifier: GPL-2.0 -+/* -+ * Rockchip Video Decoder driver -+ * -+ * Copyright (C) 2019 Collabora, Ltd. -+ * -+ * Based on rkvdec driver by Google LLC. (Tomasz Figa ) -+ * Based on s5p-mfc driver by Samsung Electronics Co., Ltd. -+ * Copyright (C) 2011 Samsung Electronics Co., Ltd. -+ */ -+ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+ -+#include "rkvdec.h" -+#include "rkvdec-regs.h" -+ -+static const struct rkvdec_ctrl_desc rkvdec_h264_ctrl_descs[] = { -+ { -+ .per_request = true, -+ .mandatory = true, -+ .cfg.id = V4L2_CID_MPEG_VIDEO_H264_DECODE_PARAMS, -+ }, -+ { -+ .per_request = true, -+ .mandatory = true, -+ .cfg.id = V4L2_CID_MPEG_VIDEO_H264_SLICE_PARAMS, -+ }, -+ { -+ .per_request = true, -+ .mandatory = true, -+ .cfg.id = V4L2_CID_MPEG_VIDEO_H264_SPS, -+ }, -+ { -+ .per_request = true, -+ .mandatory = true, -+ .cfg.id = V4L2_CID_MPEG_VIDEO_H264_PPS, -+ }, -+ { -+ .per_request = true, -+ .mandatory = true, -+ .cfg.id = V4L2_CID_MPEG_VIDEO_H264_SCALING_MATRIX, -+ }, -+ { -+ .mandatory = true, -+ .cfg.id = V4L2_CID_MPEG_VIDEO_H264_DECODE_MODE, -+ .cfg.min = V4L2_MPEG_VIDEO_H264_DECODE_MODE_FRAME_BASED, -+ .cfg.max = V4L2_MPEG_VIDEO_H264_DECODE_MODE_FRAME_BASED, -+ .cfg.def = V4L2_MPEG_VIDEO_H264_DECODE_MODE_FRAME_BASED, -+ }, -+ { -+ .mandatory = true, -+ .cfg.id = V4L2_CID_MPEG_VIDEO_H264_START_CODE, -+ .cfg.min = V4L2_MPEG_VIDEO_H264_START_CODE_ANNEX_B, -+ .cfg.def = V4L2_MPEG_VIDEO_H264_START_CODE_ANNEX_B, -+ .cfg.max = V4L2_MPEG_VIDEO_H264_START_CODE_ANNEX_B, -+ }, -+}; -+ -+static const struct rkvdec_ctrls rkvdec_h264_ctrls = { -+ .ctrls = rkvdec_h264_ctrl_descs, -+ .num_ctrls = ARRAY_SIZE(rkvdec_h264_ctrl_descs), -+}; -+ -+static const u32 rkvdec_h264_decoded_fmts[] = { -+ V4L2_PIX_FMT_NV12, -+}; -+ -+static const struct rkvdec_coded_fmt_desc rkvdec_coded_fmts[] = { -+ { -+ .fourcc = V4L2_PIX_FMT_H264_SLICE, -+ .frmsize = { -+ .min_width = 48, -+ .max_width = 4096, -+ .step_width = 16, -+ .min_height = 48, -+ .max_height = 2304, -+ .step_height = 16, -+ }, -+ .ctrls = &rkvdec_h264_ctrls, -+ .ops = &rkvdec_h264_fmt_ops, -+ .num_decoded_fmts = ARRAY_SIZE(rkvdec_h264_decoded_fmts), -+ .decoded_fmts = rkvdec_h264_decoded_fmts, -+ } -+}; -+ -+static const struct rkvdec_coded_fmt_desc * -+rkvdec_find_coded_fmt_desc(u32 fourcc) -+{ -+ unsigned int i; -+ -+ for (i = 0; i < ARRAY_SIZE(rkvdec_coded_fmts); i++) { -+ if (rkvdec_coded_fmts[i].fourcc == fourcc) -+ return &rkvdec_coded_fmts[i]; -+ } -+ -+ return NULL; -+} -+ -+static void rkvdec_reset_fmt(struct rkvdec_ctx *ctx, struct v4l2_format *f, -+ u32 fourcc) -+{ -+ memset(f, 0, sizeof(*f)); -+ f->fmt.pix_mp.pixelformat = fourcc; -+ f->fmt.pix_mp.field = V4L2_FIELD_NONE; -+ f->fmt.pix_mp.colorspace = V4L2_COLORSPACE_REC709, -+ f->fmt.pix_mp.ycbcr_enc = V4L2_YCBCR_ENC_DEFAULT; -+ f->fmt.pix_mp.quantization = V4L2_QUANTIZATION_DEFAULT; -+ f->fmt.pix_mp.xfer_func = V4L2_XFER_FUNC_DEFAULT; -+} -+ -+static void rkvdec_reset_coded_fmt(struct rkvdec_ctx *ctx) -+{ -+ struct v4l2_format *f = &ctx->coded_fmt; -+ -+ ctx->coded_fmt_desc = &rkvdec_coded_fmts[0]; -+ rkvdec_reset_fmt(ctx, f, ctx->coded_fmt_desc->fourcc); -+ -+ f->type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE; -+ f->fmt.pix_mp.width = ctx->coded_fmt_desc->frmsize.min_width; -+ f->fmt.pix_mp.height = ctx->coded_fmt_desc->frmsize.min_height; -+ -+ if (ctx->coded_fmt_desc->ops->adjust_fmt) -+ ctx->coded_fmt_desc->ops->adjust_fmt(ctx, f); -+} -+ -+static void rkvdec_reset_decoded_fmt(struct rkvdec_ctx *ctx) -+{ -+ struct v4l2_format *f = &ctx->decoded_fmt; -+ -+ rkvdec_reset_fmt(ctx, f, ctx->coded_fmt_desc->decoded_fmts[0]); -+ f->type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE; -+ v4l2_fill_pixfmt_mp(&f->fmt.pix_mp, -+ ctx->coded_fmt_desc->decoded_fmts[0], -+ ctx->coded_fmt.fmt.pix_mp.width, -+ ctx->coded_fmt.fmt.pix_mp.height); -+ f->fmt.pix_mp.plane_fmt[0].sizeimage += 128 * -+ DIV_ROUND_UP(f->fmt.pix_mp.width, 16) * -+ DIV_ROUND_UP(f->fmt.pix_mp.height, 16); -+} -+ -+static int rkvdec_enum_framesizes(struct file *file, void *priv, -+ struct v4l2_frmsizeenum *fsize) -+{ -+ const struct rkvdec_coded_fmt_desc *fmt; -+ -+ if (fsize->index != 0) -+ return -EINVAL; -+ -+ fmt = rkvdec_find_coded_fmt_desc(fsize->pixel_format); -+ if (!fmt) -+ return -EINVAL; -+ -+ fsize->type = V4L2_FRMSIZE_TYPE_STEPWISE; -+ fsize->stepwise = fmt->frmsize; -+ return 0; -+} -+ -+static int rkvdec_querycap(struct file *file, void *priv, -+ struct v4l2_capability *cap) -+{ -+ struct rkvdec_dev *rkvdec = video_drvdata(file); -+ struct video_device *vdev = video_devdata(file); -+ -+ strscpy(cap->driver, rkvdec->dev->driver->name, -+ sizeof(cap->driver)); -+ strscpy(cap->card, vdev->name, sizeof(cap->card)); -+ snprintf(cap->bus_info, sizeof(cap->bus_info), "platform:%s", -+ rkvdec->dev->driver->name); -+ return 0; -+} -+ -+static int rkvdec_try_capture_fmt(struct file *file, void *priv, -+ struct v4l2_format *f) -+{ -+ struct v4l2_pix_format_mplane *pix_mp = &f->fmt.pix_mp; -+ struct rkvdec_ctx *ctx = fh_to_rkvdec_ctx(priv); -+ const struct rkvdec_coded_fmt_desc *coded_desc; -+ unsigned int i; -+ -+ /* -+ * The codec context should point to a coded format desc, if the format -+ * on the coded end has not been set yet, it should point to the -+ * default value. -+ */ -+ coded_desc = ctx->coded_fmt_desc; -+ if (WARN_ON(!coded_desc)) -+ return -EINVAL; -+ -+ for (i = 0; i < coded_desc->num_decoded_fmts; i++) { -+ if (coded_desc->decoded_fmts[i] == pix_mp->pixelformat) -+ break; -+ } -+ -+ if (i == coded_desc->num_decoded_fmts) -+ pix_mp->pixelformat = coded_desc->decoded_fmts[0]; -+ -+ /* Always apply the frmsize constraint of the coded end. */ -+ v4l2_apply_frmsize_constraints(&pix_mp->width, -+ &pix_mp->height, -+ &coded_desc->frmsize); -+ -+ v4l2_fill_pixfmt_mp(pix_mp, pix_mp->pixelformat, -+ pix_mp->width, pix_mp->height); -+ pix_mp->plane_fmt[0].sizeimage += -+ 128 * -+ DIV_ROUND_UP(pix_mp->width, 16) * -+ DIV_ROUND_UP(pix_mp->height, 16); -+ pix_mp->field = V4L2_FIELD_NONE; -+ -+ return 0; -+} -+ -+static int rkvdec_try_output_fmt(struct file *file, void *priv, -+ struct v4l2_format *f) -+{ -+ struct v4l2_pix_format_mplane *pix_mp = &f->fmt.pix_mp; -+ struct rkvdec_ctx *ctx = fh_to_rkvdec_ctx(priv); -+ const struct rkvdec_coded_fmt_desc *desc; -+ -+ desc = rkvdec_find_coded_fmt_desc(pix_mp->pixelformat); -+ if (!desc) { -+ pix_mp->pixelformat = rkvdec_coded_fmts[0].fourcc; -+ desc = &rkvdec_coded_fmts[0]; -+ } -+ -+ v4l2_apply_frmsize_constraints(&pix_mp->width, -+ &pix_mp->height, -+ &desc->frmsize); -+ -+ pix_mp->field = V4L2_FIELD_NONE; -+ /* All coded formats are considered single planar for now. */ -+ pix_mp->num_planes = 1; -+ -+ if (desc->ops->adjust_fmt) { -+ int ret; -+ -+ ret = desc->ops->adjust_fmt(ctx, f); -+ if (ret) -+ return ret; -+ } -+ -+ return 0; -+} -+ -+static int rkvdec_s_fmt(struct file *file, void *priv, -+ struct v4l2_format *f, -+ int (*try_fmt)(struct file *, void *, -+ struct v4l2_format *)) -+{ -+ struct rkvdec_ctx *ctx = fh_to_rkvdec_ctx(priv); -+ struct vb2_queue *vq; -+ -+ if (!try_fmt) -+ return -EINVAL; -+ -+ vq = v4l2_m2m_get_vq(ctx->fh.m2m_ctx, f->type); -+ if (vb2_is_busy(vq)) -+ return -EBUSY; -+ -+ return try_fmt(file, priv, f); -+} -+ -+static int rkvdec_s_capture_fmt(struct file *file, void *priv, -+ struct v4l2_format *f) -+{ -+ struct rkvdec_ctx *ctx = fh_to_rkvdec_ctx(priv); -+ int ret; -+ -+ ret = rkvdec_s_fmt(file, priv, f, rkvdec_try_capture_fmt); -+ if (ret) -+ return ret; -+ -+ ctx->decoded_fmt = *f; -+ return 0; -+} -+ -+static int rkvdec_s_output_fmt(struct file *file, void *priv, -+ struct v4l2_format *f) -+{ -+ struct rkvdec_ctx *ctx = fh_to_rkvdec_ctx(priv); -+ struct v4l2_m2m_ctx *m2m_ctx = ctx->fh.m2m_ctx; -+ const struct rkvdec_coded_fmt_desc *desc; -+ struct v4l2_format *cap_fmt; -+ struct vb2_queue *peer_vq; -+ int ret; -+ -+ /* -+ * Since format change on the OUTPUT queue will reset the CAPTURE -+ * queue, we can't allow doing so when the CAPTURE queue has buffers -+ * allocated. -+ */ -+ peer_vq = v4l2_m2m_get_vq(m2m_ctx, V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE); -+ if (vb2_is_busy(peer_vq)) -+ return -EBUSY; -+ -+ ret = rkvdec_s_fmt(file, priv, f, rkvdec_try_output_fmt); -+ if (ret) -+ return ret; -+ -+ desc = rkvdec_find_coded_fmt_desc(f->fmt.pix_mp.pixelformat); -+ if (!desc) -+ return -EINVAL; -+ ctx->coded_fmt_desc = desc; -+ ctx->coded_fmt = *f; -+ -+ /* -+ * Current decoded format might have become invalid with newly -+ * selected codec, so reset it to default just to be safe and -+ * keep internal driver state sane. User is mandated to set -+ * the decoded format again after we return, so we don't need -+ * anything smarter. -+ * -+ * Note that this will propagates any size changes to the decoded format. -+ */ -+ rkvdec_reset_decoded_fmt(ctx); -+ -+ /* Propagate colorspace information to capture. */ -+ cap_fmt = &ctx->decoded_fmt; -+ cap_fmt->fmt.pix_mp.colorspace = f->fmt.pix_mp.colorspace; -+ cap_fmt->fmt.pix_mp.xfer_func = f->fmt.pix_mp.xfer_func; -+ cap_fmt->fmt.pix_mp.ycbcr_enc = f->fmt.pix_mp.ycbcr_enc; -+ cap_fmt->fmt.pix_mp.quantization = f->fmt.pix_mp.quantization; -+ -+ return 0; -+} -+ -+static int rkvdec_g_output_fmt(struct file *file, void *priv, -+ struct v4l2_format *f) -+{ -+ struct rkvdec_ctx *ctx = fh_to_rkvdec_ctx(priv); -+ -+ *f = ctx->coded_fmt; -+ return 0; -+} -+ -+static int rkvdec_g_capture_fmt(struct file *file, void *priv, -+ struct v4l2_format *f) -+{ -+ struct rkvdec_ctx *ctx = fh_to_rkvdec_ctx(priv); -+ -+ *f = ctx->decoded_fmt; -+ return 0; -+} -+ -+static int rkvdec_enum_output_fmt(struct file *file, void *priv, -+ struct v4l2_fmtdesc *f) -+{ -+ if (f->index >= ARRAY_SIZE(rkvdec_coded_fmts)) -+ return -EINVAL; -+ -+ f->pixelformat = rkvdec_coded_fmts[f->index].fourcc; -+ return 0; -+} -+ -+static int rkvdec_enum_capture_fmt(struct file *file, void *priv, -+ struct v4l2_fmtdesc *f) -+{ -+ struct rkvdec_ctx *ctx = fh_to_rkvdec_ctx(priv); -+ -+ if (WARN_ON(!ctx->coded_fmt_desc)) -+ return -EINVAL; -+ -+ if (f->index >= ctx->coded_fmt_desc->num_decoded_fmts) -+ return -EINVAL; -+ -+ f->pixelformat = ctx->coded_fmt_desc->decoded_fmts[f->index]; -+ return 0; -+} -+ -+static const struct v4l2_ioctl_ops rkvdec_ioctl_ops = { -+ .vidioc_querycap = rkvdec_querycap, -+ .vidioc_enum_framesizes = rkvdec_enum_framesizes, -+ -+ .vidioc_try_fmt_vid_cap_mplane = rkvdec_try_capture_fmt, -+ .vidioc_try_fmt_vid_out_mplane = rkvdec_try_output_fmt, -+ .vidioc_s_fmt_vid_out_mplane = rkvdec_s_output_fmt, -+ .vidioc_s_fmt_vid_cap_mplane = rkvdec_s_capture_fmt, -+ .vidioc_g_fmt_vid_out_mplane = rkvdec_g_output_fmt, -+ .vidioc_g_fmt_vid_cap_mplane = rkvdec_g_capture_fmt, -+ .vidioc_enum_fmt_vid_out = rkvdec_enum_output_fmt, -+ .vidioc_enum_fmt_vid_cap = rkvdec_enum_capture_fmt, -+ -+ .vidioc_reqbufs = v4l2_m2m_ioctl_reqbufs, -+ .vidioc_querybuf = v4l2_m2m_ioctl_querybuf, -+ .vidioc_qbuf = v4l2_m2m_ioctl_qbuf, -+ .vidioc_dqbuf = v4l2_m2m_ioctl_dqbuf, -+ .vidioc_prepare_buf = v4l2_m2m_ioctl_prepare_buf, -+ .vidioc_create_bufs = v4l2_m2m_ioctl_create_bufs, -+ .vidioc_expbuf = v4l2_m2m_ioctl_expbuf, -+ -+ .vidioc_subscribe_event = v4l2_ctrl_subscribe_event, -+ .vidioc_unsubscribe_event = v4l2_event_unsubscribe, -+ -+ .vidioc_streamon = v4l2_m2m_ioctl_streamon, -+ .vidioc_streamoff = v4l2_m2m_ioctl_streamoff, -+}; -+ -+static int rkvdec_queue_setup(struct vb2_queue *vq, unsigned int *num_buffers, -+ unsigned int *num_planes, unsigned int sizes[], -+ struct device *alloc_devs[]) -+{ -+ struct rkvdec_ctx *ctx = vb2_get_drv_priv(vq); -+ struct v4l2_format *f; -+ unsigned int i; -+ -+ if (V4L2_TYPE_IS_OUTPUT(vq->type)) -+ f = &ctx->coded_fmt; -+ else -+ f = &ctx->decoded_fmt; -+ -+ if (*num_planes) { -+ if (*num_planes != f->fmt.pix_mp.num_planes) -+ return -EINVAL; -+ -+ for (i = 0; i < f->fmt.pix_mp.num_planes; i++) { -+ if (sizes[i] < f->fmt.pix_mp.plane_fmt[i].sizeimage) -+ return -EINVAL; -+ } -+ } else { -+ *num_planes = f->fmt.pix_mp.num_planes; -+ for (i = 0; i < f->fmt.pix_mp.num_planes; i++) -+ sizes[i] = f->fmt.pix_mp.plane_fmt[i].sizeimage; -+ } -+ -+ return 0; -+} -+ -+static int rkvdec_buf_prepare(struct vb2_buffer *vb) -+{ -+ struct vb2_queue *vq = vb->vb2_queue; -+ struct rkvdec_ctx *ctx = vb2_get_drv_priv(vq); -+ struct v4l2_format *f; -+ unsigned int i; -+ -+ if (V4L2_TYPE_IS_OUTPUT(vq->type)) -+ f = &ctx->coded_fmt; -+ else -+ f = &ctx->decoded_fmt; -+ -+ for (i = 0; i < f->fmt.pix_mp.num_planes; ++i) { -+ u32 sizeimage = f->fmt.pix_mp.plane_fmt[i].sizeimage; -+ -+ if (vb2_plane_size(vb, i) < sizeimage) -+ return -EINVAL; -+ } -+ vb2_set_plane_payload(vb, 0, f->fmt.pix_mp.plane_fmt[0].sizeimage); -+ return 0; -+} -+ -+static void rkvdec_buf_queue(struct vb2_buffer *vb) -+{ -+ struct rkvdec_ctx *ctx = vb2_get_drv_priv(vb->vb2_queue); -+ struct vb2_v4l2_buffer *vbuf = to_vb2_v4l2_buffer(vb); -+ -+ v4l2_m2m_buf_queue(ctx->fh.m2m_ctx, vbuf); -+} -+ -+static int rkvdec_buf_out_validate(struct vb2_buffer *vb) -+{ -+ struct vb2_v4l2_buffer *vbuf = to_vb2_v4l2_buffer(vb); -+ -+ vbuf->field = V4L2_FIELD_NONE; -+ return 0; -+} -+ -+static void rkvdec_buf_request_complete(struct vb2_buffer *vb) -+{ -+ struct rkvdec_ctx *ctx = vb2_get_drv_priv(vb->vb2_queue); -+ -+ v4l2_ctrl_request_complete(vb->req_obj.req, &ctx->ctrl_hdl); -+} -+ -+static int rkvdec_start_streaming(struct vb2_queue *q, unsigned int count) -+{ -+ struct rkvdec_ctx *ctx = vb2_get_drv_priv(q); -+ const struct rkvdec_coded_fmt_desc *desc; -+ int ret; -+ -+ if (!V4L2_TYPE_IS_OUTPUT(q->type)) -+ return 0; -+ -+ desc = ctx->coded_fmt_desc; -+ if (WARN_ON(!desc)) -+ return -EINVAL; -+ -+ if (desc->ops->start) { -+ ret = desc->ops->start(ctx); -+ if (ret) -+ return ret; -+ } -+ -+ return 0; -+} -+ -+static void rkvdec_queue_cleanup(struct vb2_queue *vq, u32 state) -+{ -+ struct rkvdec_ctx *ctx = vb2_get_drv_priv(vq); -+ -+ while (true) { -+ struct vb2_v4l2_buffer *vbuf; -+ -+ if (V4L2_TYPE_IS_OUTPUT(vq->type)) -+ vbuf = v4l2_m2m_src_buf_remove(ctx->fh.m2m_ctx); -+ else -+ vbuf = v4l2_m2m_dst_buf_remove(ctx->fh.m2m_ctx); -+ -+ if (!vbuf) -+ break; -+ -+ v4l2_ctrl_request_complete(vbuf->vb2_buf.req_obj.req, -+ &ctx->ctrl_hdl); -+ v4l2_m2m_buf_done(vbuf, state); -+ } -+} -+ -+static void rkvdec_stop_streaming(struct vb2_queue *q) -+{ -+ struct rkvdec_ctx *ctx = vb2_get_drv_priv(q); -+ -+ if (V4L2_TYPE_IS_OUTPUT(q->type)) { -+ const struct rkvdec_coded_fmt_desc *desc = ctx->coded_fmt_desc; -+ -+ if (WARN_ON(!desc)) -+ return; -+ -+ if (desc->ops->stop) -+ desc->ops->stop(ctx); -+ } -+ -+ rkvdec_queue_cleanup(q, VB2_BUF_STATE_ERROR); -+} -+ -+static const struct vb2_ops rkvdec_queue_ops = { -+ .queue_setup = rkvdec_queue_setup, -+ .buf_prepare = rkvdec_buf_prepare, -+ .buf_queue = rkvdec_buf_queue, -+ .buf_out_validate = rkvdec_buf_out_validate, -+ .buf_request_complete = rkvdec_buf_request_complete, -+ .start_streaming = rkvdec_start_streaming, -+ .stop_streaming = rkvdec_stop_streaming, -+ .wait_prepare = vb2_ops_wait_prepare, -+ .wait_finish = vb2_ops_wait_finish, -+}; -+ -+static int rkvdec_request_validate(struct media_request *req) -+{ -+ struct media_request_object *obj; -+ const struct rkvdec_ctrls *ctrls; -+ struct v4l2_ctrl_handler *hdl; -+ struct rkvdec_ctx *ctx = NULL; -+ unsigned int count, i; -+ int ret; -+ -+ list_for_each_entry(obj, &req->objects, list) { -+ if (vb2_request_object_is_buffer(obj)) { -+ struct vb2_buffer *vb; -+ -+ vb = container_of(obj, struct vb2_buffer, req_obj); -+ ctx = vb2_get_drv_priv(vb->vb2_queue); -+ break; -+ } -+ } -+ -+ if (!ctx) -+ return -EINVAL; -+ -+ count = vb2_request_buffer_cnt(req); -+ if (!count) -+ return -ENOENT; -+ else if (count > 1) -+ return -EINVAL; -+ -+ hdl = v4l2_ctrl_request_hdl_find(req, &ctx->ctrl_hdl); -+ if (!hdl) -+ return -ENOENT; -+ -+ ret = 0; -+ ctrls = ctx->coded_fmt_desc->ctrls; -+ for (i = 0; ctrls && i < ctrls->num_ctrls; i++) { -+ u32 id = ctrls->ctrls[i].cfg.id; -+ struct v4l2_ctrl *ctrl; -+ -+ if (!ctrls->ctrls[i].per_request || !ctrls->ctrls[i].mandatory) -+ continue; -+ -+ ctrl = v4l2_ctrl_request_hdl_ctrl_find(hdl, id); -+ if (!ctrl) { -+ ret = -ENOENT; -+ break; -+ } -+ } -+ -+ v4l2_ctrl_request_hdl_put(hdl); -+ -+ if (ret) -+ return ret; -+ -+ return vb2_request_validate(req); -+} -+ -+static const struct media_device_ops rkvdec_media_ops = { -+ .req_validate = rkvdec_request_validate, -+ .req_queue = v4l2_m2m_request_queue, -+}; -+ -+static void rkvdec_job_finish_no_pm(struct rkvdec_ctx *ctx, -+ enum vb2_buffer_state result) -+{ -+ if (ctx->coded_fmt_desc->ops->done) { -+ struct vb2_v4l2_buffer *src_buf, *dst_buf; -+ -+ src_buf = v4l2_m2m_next_src_buf(ctx->fh.m2m_ctx); -+ dst_buf = v4l2_m2m_next_dst_buf(ctx->fh.m2m_ctx); -+ ctx->coded_fmt_desc->ops->done(ctx, src_buf, dst_buf, result); -+ } -+ -+ v4l2_m2m_buf_done_and_job_finish(ctx->dev->m2m_dev, ctx->fh.m2m_ctx, -+ result); -+} -+ -+static void rkvdec_job_finish(struct rkvdec_ctx *ctx, -+ enum vb2_buffer_state result) -+{ -+ struct rkvdec_dev *rkvdec = ctx->dev; -+ -+ pm_runtime_mark_last_busy(rkvdec->dev); -+ pm_runtime_put_autosuspend(rkvdec->dev); -+ rkvdec_job_finish_no_pm(ctx, result); -+} -+ -+void rkvdec_run_preamble(struct rkvdec_ctx *ctx, struct rkvdec_run *run) -+{ -+ struct media_request *src_req; -+ -+ memset(run, 0, sizeof(*run)); -+ -+ run->bufs.src = v4l2_m2m_next_src_buf(ctx->fh.m2m_ctx); -+ run->bufs.dst = v4l2_m2m_next_dst_buf(ctx->fh.m2m_ctx); -+ -+ /* Apply request(s) controls if needed. */ -+ src_req = run->bufs.src->vb2_buf.req_obj.req; -+ if (src_req) -+ v4l2_ctrl_request_setup(src_req, &ctx->ctrl_hdl); -+ -+ v4l2_m2m_buf_copy_metadata(run->bufs.src, run->bufs.dst, true); -+} -+ -+void rkvdec_run_postamble(struct rkvdec_ctx *ctx, struct rkvdec_run *run) -+{ -+ struct media_request *src_req = run->bufs.src->vb2_buf.req_obj.req; -+ -+ if (src_req) -+ v4l2_ctrl_request_complete(src_req, &ctx->ctrl_hdl); -+} -+ -+static void rkvdec_device_run(void *priv) -+{ -+ struct rkvdec_ctx *ctx = priv; -+ struct rkvdec_dev *rkvdec = ctx->dev; -+ const struct rkvdec_coded_fmt_desc *desc = ctx->coded_fmt_desc; -+ int ret; -+ -+ if (WARN_ON(!desc)) -+ return; -+ -+ ret = pm_runtime_get_sync(rkvdec->dev); -+ if (ret < 0) { -+ rkvdec_job_finish_no_pm(ctx, VB2_BUF_STATE_ERROR); -+ return; -+ } -+ -+ ret = desc->ops->run(ctx); -+ if (ret) -+ rkvdec_job_finish(ctx, VB2_BUF_STATE_ERROR); -+} -+ -+static struct v4l2_m2m_ops rkvdec_m2m_ops = { -+ .device_run = rkvdec_device_run, -+}; -+ -+static int rkvdec_queue_init(void *priv, -+ struct vb2_queue *src_vq, -+ struct vb2_queue *dst_vq) -+{ -+ struct rkvdec_ctx *ctx = priv; -+ struct rkvdec_dev *rkvdec = ctx->dev; -+ int ret; -+ -+ src_vq->type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE; -+ src_vq->io_modes = VB2_MMAP | VB2_DMABUF; -+ src_vq->drv_priv = ctx; -+ src_vq->ops = &rkvdec_queue_ops; -+ src_vq->mem_ops = &vb2_dma_contig_memops; -+ -+ /* -+ * Driver does mostly sequential access, so sacrifice TLB efficiency -+ * for faster allocation. Also, no CPU access on the source queue, -+ * so no kernel mapping needed. -+ */ -+ src_vq->dma_attrs = DMA_ATTR_ALLOC_SINGLE_PAGES | -+ DMA_ATTR_NO_KERNEL_MAPPING; -+ src_vq->buf_struct_size = sizeof(struct v4l2_m2m_buffer); -+ src_vq->timestamp_flags = V4L2_BUF_FLAG_TIMESTAMP_COPY; -+ src_vq->lock = &rkvdec->vdev_lock; -+ src_vq->dev = rkvdec->v4l2_dev.dev; -+ src_vq->supports_requests = true; -+ src_vq->requires_requests = true; -+ -+ ret = vb2_queue_init(src_vq); -+ if (ret) -+ return ret; -+ -+ dst_vq->bidirectional = true; -+ dst_vq->mem_ops = &vb2_dma_contig_memops; -+ dst_vq->dma_attrs = DMA_ATTR_ALLOC_SINGLE_PAGES | -+ DMA_ATTR_NO_KERNEL_MAPPING; -+ dst_vq->type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE; -+ dst_vq->io_modes = VB2_MMAP | VB2_DMABUF; -+ dst_vq->drv_priv = ctx; -+ dst_vq->ops = &rkvdec_queue_ops; -+ dst_vq->buf_struct_size = sizeof(struct rkvdec_decoded_buffer); -+ dst_vq->timestamp_flags = V4L2_BUF_FLAG_TIMESTAMP_COPY; -+ dst_vq->lock = &rkvdec->vdev_lock; -+ dst_vq->dev = rkvdec->v4l2_dev.dev; -+ -+ return vb2_queue_init(dst_vq); -+} -+ -+static int rkvdec_add_ctrls(struct rkvdec_ctx *ctx, -+ const struct rkvdec_ctrls *ctrls) -+{ -+ unsigned int i; -+ -+ for (i = 0; i < ctrls->num_ctrls; i++) { -+ const struct v4l2_ctrl_config *cfg = &ctrls->ctrls[i].cfg; -+ -+ v4l2_ctrl_new_custom(&ctx->ctrl_hdl, cfg, ctx); -+ if (ctx->ctrl_hdl.error) -+ return ctx->ctrl_hdl.error; -+ } -+ -+ return 0; -+} -+ -+static int rkvdec_init_ctrls(struct rkvdec_ctx *ctx) -+{ -+ unsigned int i, nctrls = 0; -+ int ret; -+ -+ for (i = 0; i < ARRAY_SIZE(rkvdec_coded_fmts); i++) -+ nctrls += rkvdec_coded_fmts[i].ctrls->num_ctrls; -+ -+ v4l2_ctrl_handler_init(&ctx->ctrl_hdl, nctrls); -+ -+ for (i = 0; i < ARRAY_SIZE(rkvdec_coded_fmts); i++) { -+ ret = rkvdec_add_ctrls(ctx, rkvdec_coded_fmts[i].ctrls); -+ if (ret) -+ goto err_free_handler; -+ } -+ -+ ret = v4l2_ctrl_handler_setup(&ctx->ctrl_hdl); -+ if (ret) -+ goto err_free_handler; -+ -+ ctx->fh.ctrl_handler = &ctx->ctrl_hdl; -+ return 0; -+ -+err_free_handler: -+ v4l2_ctrl_handler_free(&ctx->ctrl_hdl); -+ return ret; -+} -+ -+static int rkvdec_open(struct file *filp) -+{ -+ struct rkvdec_dev *rkvdec = video_drvdata(filp); -+ struct rkvdec_ctx *ctx; -+ int ret; -+ -+ ctx = kzalloc(sizeof(*ctx), GFP_KERNEL); -+ if (!ctx) -+ return -ENOMEM; -+ -+ ctx->dev = rkvdec; -+ rkvdec_reset_coded_fmt(ctx); -+ rkvdec_reset_decoded_fmt(ctx); -+ v4l2_fh_init(&ctx->fh, video_devdata(filp)); -+ -+ ret = rkvdec_init_ctrls(ctx); -+ if (ret) -+ goto err_free_ctx; -+ -+ ctx->fh.m2m_ctx = v4l2_m2m_ctx_init(rkvdec->m2m_dev, ctx, -+ rkvdec_queue_init); -+ if (IS_ERR(ctx->fh.m2m_ctx)) { -+ ret = PTR_ERR(ctx->fh.m2m_ctx); -+ goto err_cleanup_ctrls; -+ } -+ -+ filp->private_data = &ctx->fh; -+ v4l2_fh_add(&ctx->fh); -+ -+ return 0; -+ -+err_cleanup_ctrls: -+ v4l2_ctrl_handler_free(&ctx->ctrl_hdl); -+ -+err_free_ctx: -+ kfree(ctx); -+ return ret; -+} -+ -+static int rkvdec_release(struct file *filp) -+{ -+ struct rkvdec_ctx *ctx = fh_to_rkvdec_ctx(filp->private_data); -+ -+ v4l2_fh_del(&ctx->fh); -+ v4l2_m2m_ctx_release(ctx->fh.m2m_ctx); -+ v4l2_ctrl_handler_free(&ctx->ctrl_hdl); -+ v4l2_fh_exit(&ctx->fh); -+ kfree(ctx); -+ -+ return 0; -+} -+ -+static const struct v4l2_file_operations rkvdec_fops = { -+ .owner = THIS_MODULE, -+ .open = rkvdec_open, -+ .release = rkvdec_release, -+ .poll = v4l2_m2m_fop_poll, -+ .unlocked_ioctl = video_ioctl2, -+ .mmap = v4l2_m2m_fop_mmap, -+}; -+ -+static int rkvdec_v4l2_init(struct rkvdec_dev *rkvdec) -+{ -+ int ret; -+ -+ ret = v4l2_device_register(rkvdec->dev, &rkvdec->v4l2_dev); -+ if (ret) { -+ dev_err(rkvdec->dev, "Failed to register V4L2 device\n"); -+ return ret; -+ } -+ -+ rkvdec->m2m_dev = v4l2_m2m_init(&rkvdec_m2m_ops); -+ if (IS_ERR(rkvdec->m2m_dev)) { -+ v4l2_err(&rkvdec->v4l2_dev, "Failed to init mem2mem device\n"); -+ ret = PTR_ERR(rkvdec->m2m_dev); -+ goto err_unregister_v4l2; -+ } -+ -+ rkvdec->mdev.dev = rkvdec->dev; -+ strscpy(rkvdec->mdev.model, "rkvdec", sizeof(rkvdec->mdev.model)); -+ strscpy(rkvdec->mdev.bus_info, "platform:rkvdec", -+ sizeof(rkvdec->mdev.bus_info)); -+ media_device_init(&rkvdec->mdev); -+ rkvdec->mdev.ops = &rkvdec_media_ops; -+ rkvdec->v4l2_dev.mdev = &rkvdec->mdev; -+ -+ rkvdec->vdev.lock = &rkvdec->vdev_lock; -+ rkvdec->vdev.v4l2_dev = &rkvdec->v4l2_dev; -+ rkvdec->vdev.fops = &rkvdec_fops; -+ rkvdec->vdev.release = video_device_release_empty; -+ rkvdec->vdev.vfl_dir = VFL_DIR_M2M; -+ rkvdec->vdev.device_caps = V4L2_CAP_STREAMING | -+ V4L2_CAP_VIDEO_M2M_MPLANE; -+ rkvdec->vdev.ioctl_ops = &rkvdec_ioctl_ops; -+ video_set_drvdata(&rkvdec->vdev, rkvdec); -+ strscpy(rkvdec->vdev.name, "rkvdec", sizeof(rkvdec->vdev.name)); -+ -+ ret = video_register_device(&rkvdec->vdev, 0, -1); -+ if (ret) { -+ v4l2_err(&rkvdec->v4l2_dev, "Failed to register video device\n"); -+ goto err_cleanup_mc; -+ } -+ -+ ret = v4l2_m2m_register_media_controller(rkvdec->m2m_dev, &rkvdec->vdev, -+ MEDIA_ENT_F_PROC_VIDEO_DECODER); -+ if (ret) { -+ v4l2_err(&rkvdec->v4l2_dev, -+ "Failed to initialize V4L2 M2M media controller\n"); -+ goto err_unregister_vdev; -+ } -+ -+ ret = media_device_register(&rkvdec->mdev); -+ if (ret) { -+ v4l2_err(&rkvdec->v4l2_dev, "Failed to register media device\n"); -+ goto err_unregister_mc; -+ } -+ -+ return 0; -+ -+err_unregister_mc: -+ v4l2_m2m_unregister_media_controller(rkvdec->m2m_dev); -+ -+err_unregister_vdev: -+ video_unregister_device(&rkvdec->vdev); -+ -+err_cleanup_mc: -+ media_device_cleanup(&rkvdec->mdev); -+ v4l2_m2m_release(rkvdec->m2m_dev); -+ -+err_unregister_v4l2: -+ v4l2_device_unregister(&rkvdec->v4l2_dev); -+ return ret; -+} -+ -+static void rkvdec_v4l2_cleanup(struct rkvdec_dev *rkvdec) -+{ -+ media_device_unregister(&rkvdec->mdev); -+ v4l2_m2m_unregister_media_controller(rkvdec->m2m_dev); -+ video_unregister_device(&rkvdec->vdev); -+ media_device_cleanup(&rkvdec->mdev); -+ v4l2_m2m_release(rkvdec->m2m_dev); -+ v4l2_device_unregister(&rkvdec->v4l2_dev); -+} -+ -+static irqreturn_t rkvdec_irq_handler(int irq, void *priv) -+{ -+ struct rkvdec_dev *rkvdec = priv; -+ enum vb2_buffer_state state; -+ u32 status; -+ -+ status = readl(rkvdec->regs + RKVDEC_REG_INTERRUPT); -+ state = (status & RKVDEC_RDY_STA) ? -+ VB2_BUF_STATE_DONE : VB2_BUF_STATE_ERROR; -+ -+ writel(0, rkvdec->regs + RKVDEC_REG_INTERRUPT); -+ if (cancel_delayed_work(&rkvdec->watchdog_work)) { -+ struct rkvdec_ctx *ctx; -+ -+ ctx = v4l2_m2m_get_curr_priv(rkvdec->m2m_dev); -+ rkvdec_job_finish(ctx, state); -+ } -+ -+ return IRQ_HANDLED; -+} -+ -+static void rkvdec_watchdog_func(struct work_struct *work) -+{ -+ struct rkvdec_dev *rkvdec; -+ struct rkvdec_ctx *ctx; -+ -+ rkvdec = container_of(to_delayed_work(work), struct rkvdec_dev, -+ watchdog_work); -+ ctx = v4l2_m2m_get_curr_priv(rkvdec->m2m_dev); -+ if (ctx) { -+ dev_err(rkvdec->dev, "Frame processing timed out!\n"); -+ writel(RKVDEC_IRQ_DIS, rkvdec->regs + RKVDEC_REG_INTERRUPT); -+ writel(0, rkvdec->regs + RKVDEC_REG_SYSCTRL); -+ rkvdec_job_finish(ctx, VB2_BUF_STATE_ERROR); -+ } -+} -+ -+static const struct of_device_id of_rkvdec_match[] = { -+ { .compatible = "rockchip,rk3399-vdec" }, -+ { /* sentinel */ } -+}; -+MODULE_DEVICE_TABLE(of, of_rkvdec_match); -+ -+static const char * const rkvdec_clk_names[] = { -+ "axi", "ahb", "cabac", "core" -+}; -+ -+static int rkvdec_probe(struct platform_device *pdev) -+{ -+ struct rkvdec_dev *rkvdec; -+ struct resource *res; -+ unsigned int i; -+ int ret, irq; -+ -+ rkvdec = devm_kzalloc(&pdev->dev, sizeof(*rkvdec), GFP_KERNEL); -+ if (!rkvdec) -+ return -ENOMEM; -+ -+ platform_set_drvdata(pdev, rkvdec); -+ rkvdec->dev = &pdev->dev; -+ mutex_init(&rkvdec->vdev_lock); -+ INIT_DELAYED_WORK(&rkvdec->watchdog_work, rkvdec_watchdog_func); -+ -+ rkvdec->clocks = devm_kcalloc(&pdev->dev, ARRAY_SIZE(rkvdec_clk_names), -+ sizeof(*rkvdec->clocks), GFP_KERNEL); -+ if (!rkvdec->clocks) -+ return -ENOMEM; -+ -+ for (i = 0; i < ARRAY_SIZE(rkvdec_clk_names); i++) -+ rkvdec->clocks[i].id = rkvdec_clk_names[i]; -+ -+ ret = devm_clk_bulk_get(&pdev->dev, ARRAY_SIZE(rkvdec_clk_names), -+ rkvdec->clocks); -+ if (ret) -+ return ret; -+ -+ /* -+ * Bump ACLK to max. possible freq. (500 MHz) to improve performance -+ * When 4k video playback. -+ */ -+ clk_set_rate(rkvdec->clocks[0].clk, 500 * 1000 * 1000); -+ -+ res = platform_get_resource(pdev, IORESOURCE_MEM, 0); -+ rkvdec->regs = devm_ioremap_resource(&pdev->dev, res); -+ if (IS_ERR(rkvdec->regs)) -+ return PTR_ERR(rkvdec->regs); -+ -+ ret = dma_set_coherent_mask(&pdev->dev, DMA_BIT_MASK(32)); -+ if (ret) { -+ dev_err(&pdev->dev, "Could not set DMA coherent mask.\n"); -+ return ret; -+ } -+ -+ vb2_dma_contig_set_max_seg_size(&pdev->dev, DMA_BIT_MASK(32)); -+ -+ irq = platform_get_irq(pdev, 0); -+ if (irq <= 0) { -+ dev_err(&pdev->dev, "Could not get vdec IRQ\n"); -+ return -ENXIO; -+ } -+ -+ ret = devm_request_threaded_irq(&pdev->dev, irq, NULL, -+ rkvdec_irq_handler, IRQF_ONESHOT, -+ dev_name(&pdev->dev), rkvdec); -+ if (ret) { -+ dev_err(&pdev->dev, "Could not request vdec IRQ\n"); -+ return ret; -+ } -+ -+ pm_runtime_set_autosuspend_delay(&pdev->dev, 100); -+ pm_runtime_use_autosuspend(&pdev->dev); -+ pm_runtime_enable(&pdev->dev); -+ -+ ret = rkvdec_v4l2_init(rkvdec); -+ if (ret) -+ goto err_disable_runtime_pm; -+ -+ return 0; -+ -+err_disable_runtime_pm: -+ pm_runtime_dont_use_autosuspend(&pdev->dev); -+ pm_runtime_disable(&pdev->dev); -+ return ret; -+} -+ -+static int rkvdec_remove(struct platform_device *pdev) -+{ -+ struct rkvdec_dev *rkvdec = platform_get_drvdata(pdev); -+ -+ rkvdec_v4l2_cleanup(rkvdec); -+ pm_runtime_disable(&pdev->dev); -+ pm_runtime_dont_use_autosuspend(&pdev->dev); -+ return 0; -+} -+ -+#ifdef CONFIG_PM -+static int rkvdec_runtime_resume(struct device *dev) -+{ -+ struct rkvdec_dev *rkvdec = dev_get_drvdata(dev); -+ -+ return clk_bulk_prepare_enable(ARRAY_SIZE(rkvdec_clk_names), -+ rkvdec->clocks); -+} -+ -+static int rkvdec_runtime_suspend(struct device *dev) -+{ -+ struct rkvdec_dev *rkvdec = dev_get_drvdata(dev); -+ -+ clk_bulk_disable_unprepare(ARRAY_SIZE(rkvdec_clk_names), -+ rkvdec->clocks); -+ return 0; -+} -+#endif -+ -+static const struct dev_pm_ops rkvdec_pm_ops = { -+ SET_SYSTEM_SLEEP_PM_OPS(pm_runtime_force_suspend, -+ pm_runtime_force_resume) -+ SET_RUNTIME_PM_OPS(rkvdec_runtime_suspend, rkvdec_runtime_resume, NULL) -+}; -+ -+static struct platform_driver rkvdec_driver = { -+ .probe = rkvdec_probe, -+ .remove = rkvdec_remove, -+ .driver = { -+ .name = "rkvdec", -+ .of_match_table = of_match_ptr(of_rkvdec_match), -+ .pm = &rkvdec_pm_ops, -+ }, -+}; -+module_platform_driver(rkvdec_driver); -+ -+MODULE_AUTHOR("Boris Brezillon "); -+MODULE_DESCRIPTION("Rockchip Video Decoder driver"); -+MODULE_LICENSE("GPL v2"); -diff --git a/drivers/staging/media/rkvdec/rkvdec.h b/drivers/staging/media/rkvdec/rkvdec.h -new file mode 100644 -index 000000000000..2fc9f46b6910 ---- /dev/null -+++ b/drivers/staging/media/rkvdec/rkvdec.h -@@ -0,0 +1,121 @@ -+/* SPDX-License-Identifier: GPL-2.0 */ -+/* -+ * Rockchip Video Decoder driver -+ * -+ * Copyright (C) 2019 Collabora, Ltd. -+ * -+ * Based on rkvdec driver by Google LLC. (Tomasz Figa ) -+ * Based on s5p-mfc driver by Samsung Electronics Co., Ltd. -+ * Copyright (C) 2011 Samsung Electronics Co., Ltd. -+ */ -+#ifndef RKVDEC_H_ -+#define RKVDEC_H_ -+ -+#include -+#include -+#include -+#include -+ -+#include -+#include -+#include -+#include -+#include -+ -+struct rkvdec_ctx; -+ -+struct rkvdec_ctrl_desc { -+ u32 per_request : 1; -+ u32 mandatory : 1; -+ struct v4l2_ctrl_config cfg; -+}; -+ -+struct rkvdec_ctrls { -+ const struct rkvdec_ctrl_desc *ctrls; -+ unsigned int num_ctrls; -+}; -+ -+struct rkvdec_run { -+ struct { -+ struct vb2_v4l2_buffer *src; -+ struct vb2_v4l2_buffer *dst; -+ } bufs; -+}; -+ -+struct rkvdec_vp9_decoded_buffer_info { -+ /* Info needed when the decoded frame serves as a reference frame. */ -+ u16 width; -+ u16 height; -+ u32 bit_depth : 4; -+}; -+ -+struct rkvdec_decoded_buffer { -+ /* Must be the first field in this struct. */ -+ struct v4l2_m2m_buffer base; -+}; -+ -+static inline struct rkvdec_decoded_buffer * -+vb2_to_rkvdec_decoded_buf(struct vb2_buffer *buf) -+{ -+ return container_of(buf, struct rkvdec_decoded_buffer, -+ base.vb.vb2_buf); -+} -+ -+struct rkvdec_coded_fmt_ops { -+ int (*adjust_fmt)(struct rkvdec_ctx *ctx, -+ struct v4l2_format *f); -+ int (*start)(struct rkvdec_ctx *ctx); -+ void (*stop)(struct rkvdec_ctx *ctx); -+ int (*run)(struct rkvdec_ctx *ctx); -+ void (*done)(struct rkvdec_ctx *ctx, struct vb2_v4l2_buffer *src_buf, -+ struct vb2_v4l2_buffer *dst_buf, -+ enum vb2_buffer_state result); -+}; -+ -+struct rkvdec_coded_fmt_desc { -+ u32 fourcc; -+ struct v4l2_frmsize_stepwise frmsize; -+ const struct rkvdec_ctrls *ctrls; -+ const struct rkvdec_coded_fmt_ops *ops; -+ unsigned int num_decoded_fmts; -+ const u32 *decoded_fmts; -+}; -+ -+struct rkvdec_dev { -+ struct v4l2_device v4l2_dev; -+ struct media_device mdev; -+ struct video_device vdev; -+ struct v4l2_m2m_dev *m2m_dev; -+ struct device *dev; -+ struct clk_bulk_data *clocks; -+ void __iomem *regs; -+ struct mutex vdev_lock; /* serializes ioctls */ -+ struct delayed_work watchdog_work; -+}; -+ -+struct rkvdec_ctx { -+ struct v4l2_fh fh; -+ struct v4l2_format coded_fmt; -+ struct v4l2_format decoded_fmt; -+ const struct rkvdec_coded_fmt_desc *coded_fmt_desc; -+ struct v4l2_ctrl_handler ctrl_hdl; -+ struct rkvdec_dev *dev; -+ void *priv; -+}; -+ -+static inline struct rkvdec_ctx *fh_to_rkvdec_ctx(struct v4l2_fh *fh) -+{ -+ return container_of(fh, struct rkvdec_ctx, fh); -+} -+ -+struct rkvdec_aux_buf { -+ void *cpu; -+ dma_addr_t dma; -+ size_t size; -+}; -+ -+void rkvdec_run_preamble(struct rkvdec_ctx *ctx, struct rkvdec_run *run); -+void rkvdec_run_postamble(struct rkvdec_ctx *ctx, struct rkvdec_run *run); -+ -+extern const struct rkvdec_coded_fmt_ops rkvdec_h264_fmt_ops; -+#endif /* RKVDEC_H_ */ --- -2.26.0.rc2 - - - -From ezequiel at collabora.com Fri Apr 3 15:13:45 2020 -From: ezequiel at collabora.com (Ezequiel Garcia) -Date: Fri, 3 Apr 2020 19:13:45 -0300 -Subject: [PATCH v8 5/5] arm64: dts: rockchip: rk3399: Define the rockchip - Video Decoder node -In-Reply-To: <20200403221345.16702-1-ezequiel@collabora.com> -References: <20200403221345.16702-1-ezequiel@collabora.com> -Message-ID: <20200403221345.16702-6-ezequiel@collabora.com> - -From: Boris Brezillon - -RK3399 has a Video decoder, define the node in the dtsi. We also add -the missing power-domain in mmu node and enable the block. - -Signed-off-by: Boris Brezillon -Signed-off-by: Ezequiel Garcia --- -v8: -* None. -v7: -* As noted by Johan Jonker, fix node order. ---- - arch/arm64/boot/dts/rockchip/rk3399.dtsi | 14 +++++++++++++- - 1 file changed, 13 insertions(+), 1 deletion(-) - -diff --git a/arch/arm64/boot/dts/rockchip/rk3399.dtsi b/arch/arm64/boot/dts/rockchip/rk3399.dtsi -index 33cc21fcf4c1..dfb737e8ff31 100644 ---- a/arch/arm64/boot/dts/rockchip/rk3399.dtsi -+++ b/arch/arm64/boot/dts/rockchip/rk3399.dtsi -@@ -1278,6 +1278,18 @@ vpu_mmu: iommu at ff650800 { - power-domains = <&power RK3399_PD_VCODEC>; - }; - -+ vdec: video-codec@ff660000 { -+ compatible = "rockchip,rk3399-vdec"; -+ reg = <0x0 0xff660000 0x0 0x400>; -+ interrupts = ; -+ interrupt-names = "vdpu"; -+ clocks = <&cru ACLK_VDU>, <&cru HCLK_VDU>, -+ <&cru SCLK_VDU_CA>, <&cru SCLK_VDU_CORE>; -+ clock-names = "axi", "ahb", "cabac", "core"; -+ power-domains = <&power RK3399_PD_VDU>; -+ iommus = <&vdec_mmu>; -+ }; -+ - vdec_mmu: iommu@ff660480 { - compatible = "rockchip,iommu"; - reg = <0x0 0xff660480 0x0 0x40>, <0x0 0xff6604c0 0x0 0x40>; -@@ -1285,8 +1297,8 @@ vdec_mmu: iommu at ff660480 { - interrupt-names = "vdec_mmu"; - clocks = <&cru ACLK_VDU>, <&cru HCLK_VDU>; - clock-names = "aclk", "iface"; -+ power-domains = <&power RK3399_PD_VDU>; - #iommu-cells = <0>; -- status = "disabled"; - }; - - iep_mmu: iommu at ff670800 { --- -2.26.0.rc2 - diff --git a/patch/kernel/rockchip64-current/rkvdec_nv15.patch b/patch/kernel/rockchip64-current/rkvdec_nv15.patch new file mode 100644 index 0000000000..ac531c4fd7 --- /dev/null +++ b/patch/kernel/rockchip64-current/rkvdec_nv15.patch @@ -0,0 +1,1602 @@ +From bbfdef43b6f4a65b960ebe6e540233a4c26e9374 Mon Sep 17 00:00:00 2001 +From: Ezequiel Garcia +Date: Fri, 26 Jun 2020 14:11:29 -0300 +Subject: [PATCH 01/18] rkvdec: h264: Refuse to decode unsupported bitstream + +The hardware only supports 4:2:2, 4:2:0 or 4:0:0 (monochrome), +8-bit or 10-bit depth content. + +Verify that the PPS refers to a supported bitstream, and refuse +unsupported bitstreams by failing at TRY_EXT_CTRLS time. + +The driver is currently broken on 10-bit and 4:2:2 +so disallow those as well. + +Signed-off-by: Ezequiel Garcia +--- + drivers/staging/media/rkvdec/rkvdec.c | 27 +++++++++++++++++++++++++++ + 1 file changed, 27 insertions(+) + +diff --git a/drivers/staging/media/rkvdec/rkvdec.c b/drivers/staging/media/rkvdec/rkvdec.c +index 225eeca73356..0f81b47792f6 100644 +--- a/drivers/staging/media/rkvdec/rkvdec.c ++++ b/drivers/staging/media/rkvdec/rkvdec.c +@@ -27,6 +27,32 @@ + #include "rkvdec.h" + #include "rkvdec-regs.h" + ++static int rkvdec_try_ctrl(struct v4l2_ctrl *ctrl) ++{ ++ if (ctrl->id == V4L2_CID_MPEG_VIDEO_H264_SPS) { ++ const struct v4l2_ctrl_h264_sps *sps = ctrl->p_cur.p; ++ /* ++ * TODO: The hardware supports 10-bit and 4:2:2 profiles, ++ * but it's currently broken in the driver. ++ * Reject them for now, until it's fixed. ++ */ ++ if (sps->chroma_format_idc > 1) ++ /* Only 4:0:0 and 4:2:0 are supported */ ++ return -EINVAL; ++ if (sps->bit_depth_luma_minus8 != sps->bit_depth_chroma_minus8) ++ /* Luma and chroma bit depth mismatch */ ++ return -EINVAL; ++ if (sps->bit_depth_luma_minus8 != 0) ++ /* Only 8-bit is supported */ ++ return -EINVAL; ++ } ++ return 0; ++} ++ ++static const struct v4l2_ctrl_ops rkvdec_ctrl_ops = { ++ .try_ctrl = rkvdec_try_ctrl, ++}; ++ + static const struct rkvdec_ctrl_desc rkvdec_h264_ctrl_descs[] = { + { + .per_request = true, +@@ -42,6 +68,7 @@ static const struct rkvdec_ctrl_desc rkvdec_h264_ctrl_descs[] = { + .per_request = true, + .mandatory = true, + .cfg.id = V4L2_CID_MPEG_VIDEO_H264_SPS, ++ .cfg.ops = &rkvdec_ctrl_ops, + }, + { + .per_request = true, +-- +2.25.1 + + +From 843e3576055776df5cafb3f8e28ea08f9fa71e9a Mon Sep 17 00:00:00 2001 +From: Ezequiel Garcia +Date: Fri, 26 Jun 2020 14:11:30 -0300 +Subject: [PATCH 02/18] hantro: h264: Refuse to decode unsupported bitstream + +The hardware only supports 4:2:0 or 4:0:0 (monochrome), +8-bit depth content. + +Verify that the PPS refers to a supported bitstream, and refuse +unsupported bitstreams by failing at TRY_EXT_CTRLS time. + +Given the JPEG compression level control is the only one +that needs setting, a specific ops is provided. + +Signed-off-by: Ezequiel Garcia +--- + drivers/staging/media/hantro/hantro_drv.c | 29 ++++++++++++++++++++--- + 1 file changed, 26 insertions(+), 3 deletions(-) + +diff --git a/drivers/staging/media/hantro/hantro_drv.c b/drivers/staging/media/hantro/hantro_drv.c +index 0db8ad455160..361ffaa821ef 100644 +--- a/drivers/staging/media/hantro/hantro_drv.c ++++ b/drivers/staging/media/hantro/hantro_drv.c +@@ -261,7 +261,25 @@ queue_init(void *priv, struct vb2_queue *src_vq, struct vb2_queue *dst_vq) + return vb2_queue_init(dst_vq); + } + +-static int hantro_s_ctrl(struct v4l2_ctrl *ctrl) ++static int hantro_try_ctrl(struct v4l2_ctrl *ctrl) ++{ ++ if (ctrl->id == V4L2_CID_MPEG_VIDEO_H264_SPS) { ++ const struct v4l2_ctrl_h264_sps *sps = ctrl->p_cur.p; ++ ++ if (sps->chroma_format_idc > 1) ++ /* Only 4:0:0 and 4:2:0 are supported */ ++ return -EINVAL; ++ if (sps->bit_depth_luma_minus8 != sps->bit_depth_chroma_minus8) ++ /* Luma and chroma bit depth mismatch */ ++ return -EINVAL; ++ if (sps->bit_depth_luma_minus8 != 0) ++ /* Only 8-bit is supported */ ++ return -EINVAL; ++ } ++ return 0; ++} ++ ++static int hantro_jpeg_s_ctrl(struct v4l2_ctrl *ctrl) + { + struct hantro_ctx *ctx; + +@@ -282,7 +300,11 @@ static int hantro_s_ctrl(struct v4l2_ctrl *ctrl) + } + + static const struct v4l2_ctrl_ops hantro_ctrl_ops = { +- .s_ctrl = hantro_s_ctrl, ++ .try_ctrl = hantro_try_ctrl, ++}; ++ ++static const struct v4l2_ctrl_ops hantro_jpeg_ctrl_ops = { ++ .s_ctrl = hantro_jpeg_s_ctrl, + }; + + static const struct hantro_ctrl controls[] = { +@@ -294,7 +316,7 @@ static const struct hantro_ctrl controls[] = { + .max = 100, + .step = 1, + .def = 50, +- .ops = &hantro_ctrl_ops, ++ .ops = &hantro_jpeg_ctrl_ops, + }, + }, { + .codec = HANTRO_MPEG2_DECODER, +@@ -325,6 +347,7 @@ static const struct hantro_ctrl controls[] = { + .codec = HANTRO_H264_DECODER, + .cfg = { + .id = V4L2_CID_MPEG_VIDEO_H264_SPS, ++ .ops = &hantro_ctrl_ops, + }, + }, { + .codec = HANTRO_H264_DECODER, +-- +2.25.1 + + +From 22400b16c3d7af8cf3b044277264cc5fc3a07c54 Mon Sep 17 00:00:00 2001 +From: Jonas Karlman +Date: Sun, 5 Jul 2020 21:48:56 +0000 +Subject: [PATCH 03/18] fixup! rkvdec: h264: Refuse to decode unsupported + bitstream + +--- + drivers/staging/media/rkvdec/rkvdec.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/drivers/staging/media/rkvdec/rkvdec.c b/drivers/staging/media/rkvdec/rkvdec.c +index 0f81b47792f6..55dc27171ce4 100644 +--- a/drivers/staging/media/rkvdec/rkvdec.c ++++ b/drivers/staging/media/rkvdec/rkvdec.c +@@ -30,7 +30,7 @@ + static int rkvdec_try_ctrl(struct v4l2_ctrl *ctrl) + { + if (ctrl->id == V4L2_CID_MPEG_VIDEO_H264_SPS) { +- const struct v4l2_ctrl_h264_sps *sps = ctrl->p_cur.p; ++ const struct v4l2_ctrl_h264_sps *sps = ctrl->p_new.p; + /* + * TODO: The hardware supports 10-bit and 4:2:2 profiles, + * but it's currently broken in the driver. +-- +2.25.1 + + +From 974229575250290e49d004933cb0aade87fa4566 Mon Sep 17 00:00:00 2001 +From: Jonas Karlman +Date: Mon, 6 Jul 2020 21:54:33 +0000 +Subject: [PATCH 04/18] media: rkvdec: h264: Fix reference frame_num wrap for + second field + +When decoding the second field in a complementary field pair the second +field is sharing the same frame_num with the first field. + +Currently the frame_num for the first field is wrapped when it matches the +field being decoded, this cause issues to decode the second field in a +complementary field pair. + +Fix this by using inclusive comparison, less than or equal. + +Signed-off-by: Jonas Karlman +Reviewed-by: Ezequiel Garcia +--- + drivers/staging/media/rkvdec/rkvdec-h264.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/drivers/staging/media/rkvdec/rkvdec-h264.c b/drivers/staging/media/rkvdec/rkvdec-h264.c +index 7b66e2743a4f..f0cfed84d60d 100644 +--- a/drivers/staging/media/rkvdec/rkvdec-h264.c ++++ b/drivers/staging/media/rkvdec/rkvdec-h264.c +@@ -754,7 +754,7 @@ static void assemble_hw_rps(struct rkvdec_ctx *ctx, + continue; + + if (dpb[i].flags & V4L2_H264_DPB_ENTRY_FLAG_LONG_TERM || +- dpb[i].frame_num < sl_params->frame_num) { ++ dpb[i].frame_num <= sl_params->frame_num) { + p[i] = dpb[i].frame_num; + continue; + } +-- +2.25.1 + + +From 031ff8b97b208e20b49554c657e8ca9c79a079db Mon Sep 17 00:00:00 2001 +From: Jonas Karlman +Date: Mon, 6 Jul 2020 21:54:34 +0000 +Subject: [PATCH 05/18] media: rkvdec: Ensure decoded resolution fit coded + resolution + +Ensure decoded CAPTURE buffer resolution is larger or equal to the coded +OPTUPT buffer resolution. + +Signed-off-by: Jonas Karlman +--- + drivers/staging/media/rkvdec/rkvdec.c | 2 ++ + 1 file changed, 2 insertions(+) + +diff --git a/drivers/staging/media/rkvdec/rkvdec.c b/drivers/staging/media/rkvdec/rkvdec.c +index 55dc27171ce4..4ab8f7e0566b 100644 +--- a/drivers/staging/media/rkvdec/rkvdec.c ++++ b/drivers/staging/media/rkvdec/rkvdec.c +@@ -235,6 +235,8 @@ static int rkvdec_try_capture_fmt(struct file *file, void *priv, + pix_mp->pixelformat = coded_desc->decoded_fmts[0]; + + /* Always apply the frmsize constraint of the coded end. */ ++ pix_mp->width = max(pix_mp->width, ctx->coded_fmt.fmt.pix_mp.width); ++ pix_mp->height = max(pix_mp->height, ctx->coded_fmt.fmt.pix_mp.height); + v4l2_apply_frmsize_constraints(&pix_mp->width, + &pix_mp->height, + &coded_desc->frmsize); +-- +2.25.1 + + +From 4c7271baa21e2e508593c8e87d77febff68afb6a Mon Sep 17 00:00:00 2001 +From: Jonas Karlman +Date: Mon, 6 Jul 2020 21:54:34 +0000 +Subject: [PATCH 06/18] media: rkvdec: h264: Validate and use pic width and + height in mbs + +The width and height in mbs is currently configured based on OUTPUT buffer +resolution, this works for frame pictures but can cause issues for field +pictures. + +When frame_mbs_only_flag is 0 the height in mbs should be height of +the field instead of height of frame. + +Validate pic_width_in_mbs_minus1 and pic_height_in_map_units_minus1 +against OUTPUT buffer resolution and use these values to configure HW. + +Signed-off-by: Jonas Karlman +--- + drivers/staging/media/rkvdec/rkvdec-h264.c | 4 ++-- + drivers/staging/media/rkvdec/rkvdec.c | 10 ++++++++++ + 2 files changed, 12 insertions(+), 2 deletions(-) + +diff --git a/drivers/staging/media/rkvdec/rkvdec-h264.c b/drivers/staging/media/rkvdec/rkvdec-h264.c +index f0cfed84d60d..3498e9eec3d8 100644 +--- a/drivers/staging/media/rkvdec/rkvdec-h264.c ++++ b/drivers/staging/media/rkvdec/rkvdec-h264.c +@@ -672,8 +672,8 @@ static void assemble_hw_pps(struct rkvdec_ctx *ctx, + LOG2_MAX_PIC_ORDER_CNT_LSB_MINUS4); + WRITE_PPS(!!(sps->flags & V4L2_H264_SPS_FLAG_DELTA_PIC_ORDER_ALWAYS_ZERO), + DELTA_PIC_ORDER_ALWAYS_ZERO_FLAG); +- WRITE_PPS(DIV_ROUND_UP(ctx->coded_fmt.fmt.pix_mp.width, 16), PIC_WIDTH_IN_MBS); +- WRITE_PPS(DIV_ROUND_UP(ctx->coded_fmt.fmt.pix_mp.height, 16), PIC_HEIGHT_IN_MBS); ++ WRITE_PPS(sps->pic_width_in_mbs_minus1 + 1, PIC_WIDTH_IN_MBS); ++ WRITE_PPS(sps->pic_height_in_map_units_minus1 + 1, PIC_HEIGHT_IN_MBS); + WRITE_PPS(!!(sps->flags & V4L2_H264_SPS_FLAG_FRAME_MBS_ONLY), + FRAME_MBS_ONLY_FLAG); + WRITE_PPS(!!(sps->flags & V4L2_H264_SPS_FLAG_MB_ADAPTIVE_FRAME_FIELD), +diff --git a/drivers/staging/media/rkvdec/rkvdec.c b/drivers/staging/media/rkvdec/rkvdec.c +index 4ab8f7e0566b..7a9f78bc0a55 100644 +--- a/drivers/staging/media/rkvdec/rkvdec.c ++++ b/drivers/staging/media/rkvdec/rkvdec.c +@@ -29,8 +29,11 @@ + + static int rkvdec_try_ctrl(struct v4l2_ctrl *ctrl) + { ++ struct rkvdec_ctx *ctx = container_of(ctrl->handler, struct rkvdec_ctx, ctrl_hdl); ++ + if (ctrl->id == V4L2_CID_MPEG_VIDEO_H264_SPS) { + const struct v4l2_ctrl_h264_sps *sps = ctrl->p_new.p; ++ unsigned int width, height; + /* + * TODO: The hardware supports 10-bit and 4:2:2 profiles, + * but it's currently broken in the driver. +@@ -45,6 +48,13 @@ static int rkvdec_try_ctrl(struct v4l2_ctrl *ctrl) + if (sps->bit_depth_luma_minus8 != 0) + /* Only 8-bit is supported */ + return -EINVAL; ++ ++ width = (sps->pic_width_in_mbs_minus1 + 1) * 16; ++ height = (sps->pic_height_in_map_units_minus1 + 1) * 16; ++ ++ if (width > ctx->coded_fmt.fmt.pix_mp.width || ++ height > ctx->coded_fmt.fmt.pix_mp.height) ++ return -EINVAL; + } + return 0; + } +-- +2.25.1 + + +From d0673c50f58c79198b3c2958beaa8b88e2bdfaef Mon Sep 17 00:00:00 2001 +From: Jonas Karlman +Date: Mon, 6 Jul 2020 21:54:35 +0000 +Subject: [PATCH 07/18] media: rkvdec: h264: Fix bit depth wrap in pps packet + +The luma and chroma bit depth fields in the pps packet is 3 bits wide. +8 is wrongly added to the bit depth value written to these 3-bit fields. +Because only the 3 LSB is written the hardware is configured correctly. + +Correct this by not adding 8 to the luma and chroma bit depth value. + +Signed-off-by: Jonas Karlman +Reviewed-by: Ezequiel Garcia +--- + drivers/staging/media/rkvdec/rkvdec-h264.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +diff --git a/drivers/staging/media/rkvdec/rkvdec-h264.c b/drivers/staging/media/rkvdec/rkvdec-h264.c +index 3498e9eec3d8..6576b4a101ae 100644 +--- a/drivers/staging/media/rkvdec/rkvdec-h264.c ++++ b/drivers/staging/media/rkvdec/rkvdec-h264.c +@@ -662,8 +662,8 @@ static void assemble_hw_pps(struct rkvdec_ctx *ctx, + WRITE_PPS(0xff, PROFILE_IDC); + WRITE_PPS(1, CONSTRAINT_SET3_FLAG); + WRITE_PPS(sps->chroma_format_idc, CHROMA_FORMAT_IDC); +- WRITE_PPS(sps->bit_depth_luma_minus8 + 8, BIT_DEPTH_LUMA); +- WRITE_PPS(sps->bit_depth_chroma_minus8 + 8, BIT_DEPTH_CHROMA); ++ WRITE_PPS(sps->bit_depth_luma_minus8, BIT_DEPTH_LUMA); ++ WRITE_PPS(sps->bit_depth_chroma_minus8, BIT_DEPTH_CHROMA); + WRITE_PPS(0, QPPRIME_Y_ZERO_TRANSFORM_BYPASS_FLAG); + WRITE_PPS(sps->log2_max_frame_num_minus4, LOG2_MAX_FRAME_NUM_MINUS4); + WRITE_PPS(sps->max_num_ref_frames, MAX_NUM_REF_FRAMES); +-- +2.25.1 + + +From c1cb24d82d654583f9b716f8385254d61223aa03 Mon Sep 17 00:00:00 2001 +From: Jonas Karlman +Date: Mon, 6 Jul 2020 21:54:35 +0000 +Subject: [PATCH 08/18] media: rkvdec: h264: Do not override output buffer + sizeimage + +The output buffer sizeimage is currently forced to 2 bytes per pixel, this +can lead to high memory usage for 4K content when multiple output buffers +is created by userspace. + +Do not override output buffer sizeimage and let userspace have control of +output buffer sizeimage by only setting sizeimage if none is provided. + +Signed-off-by: Jonas Karlman +--- + drivers/staging/media/rkvdec/rkvdec-h264.c | 5 +++-- + 1 file changed, 3 insertions(+), 2 deletions(-) + +diff --git a/drivers/staging/media/rkvdec/rkvdec-h264.c b/drivers/staging/media/rkvdec/rkvdec-h264.c +index 6576b4a101ae..3a85545bcb38 100644 +--- a/drivers/staging/media/rkvdec/rkvdec-h264.c ++++ b/drivers/staging/media/rkvdec/rkvdec-h264.c +@@ -1012,8 +1012,9 @@ static int rkvdec_h264_adjust_fmt(struct rkvdec_ctx *ctx, + struct v4l2_pix_format_mplane *fmt = &f->fmt.pix_mp; + + fmt->num_planes = 1; +- fmt->plane_fmt[0].sizeimage = fmt->width * fmt->height * +- RKVDEC_H264_MAX_DEPTH_IN_BYTES; ++ if (!fmt->plane_fmt[0].sizeimage) ++ fmt->plane_fmt[0].sizeimage = fmt->width * fmt->height * ++ RKVDEC_H264_MAX_DEPTH_IN_BYTES; + return 0; + } + +-- +2.25.1 + + +From 1f381d3ddd88174c12846ba93ddd7deb47089a8e Mon Sep 17 00:00:00 2001 +From: Jonas Karlman +Date: Mon, 6 Jul 2020 21:54:35 +0000 +Subject: [PATCH 09/18] media: v4l2-common: Add helpers to calculate + bytesperline and sizeimage + +Add helper functions to calculate plane bytesperline and sizeimage, these +new helpers consider block width and height when calculating plane +bytesperline and sizeimage. + +This prepare support for new pixel formats added in next patch that make +use of block width and height. + +Signed-off-by: Jonas Karlman +--- + drivers/media/v4l2-core/v4l2-common.c | 77 +++++++++++++-------------- + 1 file changed, 38 insertions(+), 39 deletions(-) + +diff --git a/drivers/media/v4l2-core/v4l2-common.c b/drivers/media/v4l2-core/v4l2-common.c +index 3dc17ebe14fa..4102c373b48a 100644 +--- a/drivers/media/v4l2-core/v4l2-common.c ++++ b/drivers/media/v4l2-core/v4l2-common.c +@@ -333,6 +333,33 @@ static inline unsigned int v4l2_format_block_height(const struct v4l2_format_inf + return info->block_h[plane]; + } + ++static inline unsigned int v4l2_format_plane_width(const struct v4l2_format_info *info, int plane, ++ unsigned int width) ++{ ++ unsigned int hdiv = plane ? info->hdiv : 1; ++ unsigned int bytes = DIV_ROUND_UP(width * info->bpp[plane], ++ v4l2_format_block_width(info, plane) * ++ v4l2_format_block_height(info, plane)); ++ ++ return DIV_ROUND_UP(bytes, hdiv); ++} ++ ++static inline unsigned int v4l2_format_plane_height(const struct v4l2_format_info *info, int plane, ++ unsigned int height) ++{ ++ unsigned int vdiv = plane ? info->vdiv : 1; ++ unsigned int lines = ALIGN(height, v4l2_format_block_height(info, plane)); ++ ++ return DIV_ROUND_UP(lines, vdiv); ++} ++ ++static inline unsigned int v4l2_format_plane_size(const struct v4l2_format_info *info, int plane, ++ unsigned int width, unsigned int height) ++{ ++ return v4l2_format_plane_width(info, plane, width) * ++ v4l2_format_plane_height(info, plane, height); ++} ++ + void v4l2_apply_frmsize_constraints(u32 *width, u32 *height, + const struct v4l2_frmsize_stepwise *frmsize) + { +@@ -368,37 +395,19 @@ int v4l2_fill_pixfmt_mp(struct v4l2_pix_format_mplane *pixfmt, + + if (info->mem_planes == 1) { + plane = &pixfmt->plane_fmt[0]; +- plane->bytesperline = ALIGN(width, v4l2_format_block_width(info, 0)) * info->bpp[0]; ++ plane->bytesperline = v4l2_format_plane_width(info, 0, width); + plane->sizeimage = 0; + +- for (i = 0; i < info->comp_planes; i++) { +- unsigned int hdiv = (i == 0) ? 1 : info->hdiv; +- unsigned int vdiv = (i == 0) ? 1 : info->vdiv; +- unsigned int aligned_width; +- unsigned int aligned_height; +- +- aligned_width = ALIGN(width, v4l2_format_block_width(info, i)); +- aligned_height = ALIGN(height, v4l2_format_block_height(info, i)); +- +- plane->sizeimage += info->bpp[i] * +- DIV_ROUND_UP(aligned_width, hdiv) * +- DIV_ROUND_UP(aligned_height, vdiv); +- } ++ for (i = 0; i < info->comp_planes; i++) ++ plane->sizeimage += ++ v4l2_format_plane_size(info, i, width, height); + } else { + for (i = 0; i < info->comp_planes; i++) { +- unsigned int hdiv = (i == 0) ? 1 : info->hdiv; +- unsigned int vdiv = (i == 0) ? 1 : info->vdiv; +- unsigned int aligned_width; +- unsigned int aligned_height; +- +- aligned_width = ALIGN(width, v4l2_format_block_width(info, i)); +- aligned_height = ALIGN(height, v4l2_format_block_height(info, i)); +- + plane = &pixfmt->plane_fmt[i]; + plane->bytesperline = +- info->bpp[i] * DIV_ROUND_UP(aligned_width, hdiv); +- plane->sizeimage = +- plane->bytesperline * DIV_ROUND_UP(aligned_height, vdiv); ++ v4l2_format_plane_width(info, i, width); ++ plane->sizeimage = plane->bytesperline * ++ v4l2_format_plane_height(info, i, height); + } + } + return 0; +@@ -422,22 +431,12 @@ int v4l2_fill_pixfmt(struct v4l2_pix_format *pixfmt, u32 pixelformat, + pixfmt->width = width; + pixfmt->height = height; + pixfmt->pixelformat = pixelformat; +- pixfmt->bytesperline = ALIGN(width, v4l2_format_block_width(info, 0)) * info->bpp[0]; ++ pixfmt->bytesperline = v4l2_format_plane_width(info, 0, width); + pixfmt->sizeimage = 0; + +- for (i = 0; i < info->comp_planes; i++) { +- unsigned int hdiv = (i == 0) ? 1 : info->hdiv; +- unsigned int vdiv = (i == 0) ? 1 : info->vdiv; +- unsigned int aligned_width; +- unsigned int aligned_height; +- +- aligned_width = ALIGN(width, v4l2_format_block_width(info, i)); +- aligned_height = ALIGN(height, v4l2_format_block_height(info, i)); +- +- pixfmt->sizeimage += info->bpp[i] * +- DIV_ROUND_UP(aligned_width, hdiv) * +- DIV_ROUND_UP(aligned_height, vdiv); +- } ++ for (i = 0; i < info->comp_planes; i++) ++ pixfmt->sizeimage += ++ v4l2_format_plane_size(info, i, width, height); + return 0; + } + EXPORT_SYMBOL_GPL(v4l2_fill_pixfmt); +-- +2.25.1 + + +From 778ba4f6cb10b7e4ae2dd71c35dcdd2363d43b21 Mon Sep 17 00:00:00 2001 +From: Jonas Karlman +Date: Mon, 6 Jul 2020 21:54:36 +0000 +Subject: [PATCH 10/18] media: v4l2: Add NV15 and NV20 pixel formats + +Add NV15 and NV20 pixel formats used by the Rockchip Video Decoder for +10-bit buffers. + +NV15 and NV20 is a packed 10-bit 4:2:0/4:2:2 semi-planar Y/CbCr format +similar to P010 and P210 but has no padding between components. Instead, +luminance and chrominance samples are grouped into 4s so that each group is +packed into an integer number of bytes: + +YYYY = UVUV = 4 * 10 bits = 40 bits = 5 bytes + +The '15' and '20' suffix refers to the optimum effective bits per pixel +which is achieved when the total number of luminance samples is a multiple +of 8 for NV15 and 4 for NV20. + +Signed-off-by: Jonas Karlman +--- + .../userspace-api/media/v4l/pixfmt-nv15.rst | 101 ++++++++++++++++++ + .../userspace-api/media/v4l/pixfmt-nv20.rst | 99 +++++++++++++++++ + .../userspace-api/media/v4l/yuv-formats.rst | 2 + + drivers/media/v4l2-core/v4l2-common.c | 3 + + drivers/media/v4l2-core/v4l2-ioctl.c | 2 + + include/uapi/linux/videodev2.h | 3 + + 6 files changed, 210 insertions(+) + create mode 100644 Documentation/userspace-api/media/v4l/pixfmt-nv15.rst + create mode 100644 Documentation/userspace-api/media/v4l/pixfmt-nv20.rst + +diff --git a/Documentation/userspace-api/media/v4l/pixfmt-nv15.rst b/Documentation/userspace-api/media/v4l/pixfmt-nv15.rst +new file mode 100644 +index 000000000000..d059db58c6e0 +--- /dev/null ++++ b/Documentation/userspace-api/media/v4l/pixfmt-nv15.rst +@@ -0,0 +1,101 @@ ++.. Permission is granted to copy, distribute and/or modify this ++.. document under the terms of the GNU Free Documentation License, ++.. Version 1.1 or any later version published by the Free Software ++.. Foundation, with no Invariant Sections, no Front-Cover Texts ++.. and no Back-Cover Texts. A copy of the license is included at ++.. Documentation/userspace-api/media/fdl-appendix.rst. ++.. ++.. TODO: replace it to GFDL-1.1-or-later WITH no-invariant-sections ++ ++.. _V4L2-PIX-FMT-NV15: ++ ++************************** ++V4L2_PIX_FMT_NV15 ('NV15') ++************************** ++ ++Format with ½ horizontal and vertical chroma resolution, also known as ++YUV 4:2:0. One luminance and one chrominance plane with alternating ++chroma samples similar to ``V4L2_PIX_FMT_NV12`` but with 10-bit samples ++that are grouped into four and packed into five bytes. ++ ++The '15' suffix refers to the optimum effective bits per pixel which is ++achieved when the total number of luminance samples is a multiple of 8. ++ ++ ++Description ++=========== ++ ++This is a packed 10-bit two-plane version of the YUV 4:2:0 format. The ++three components are separated into two sub-images or planes. The Y plane ++is first. The Y plane has five bytes per each group of four pixels. A ++combined CbCr plane immediately follows the Y plane in memory. The CbCr ++plane is the same width, in bytes, as the Y plane (and of the image), but ++is half as tall in pixels. Each CbCr pair belongs to four pixels. For ++example, Cb\ :sub:`00`/Cr\ :sub:`00` belongs to Y'\ :sub:`00`, ++Y'\ :sub:`01`, Y'\ :sub:`10`, Y'\ :sub:`11`. ++ ++If the Y plane has pad bytes after each row, then the CbCr plane has as ++many pad bytes after its rows. ++ ++**Byte Order.** ++Little endian. Each cell is one byte. Pixels cross the byte boundary. ++ ++ ++.. flat-table:: ++ :header-rows: 0 ++ :stub-columns: 0 ++ ++ * - start + 0: ++ - Y'\ :sub:`00[7:0]` ++ - Y'\ :sub:`01[5:0]`\ Y'\ :sub:`00[9:8]` ++ - Y'\ :sub:`02[3:0]`\ Y'\ :sub:`01[9:6]` ++ - Y'\ :sub:`03[1:0]`\ Y'\ :sub:`02[9:4]` ++ - Y'\ :sub:`03[9:2]` ++ * - start + 5: ++ - Y'\ :sub:`10[7:0]` ++ - Y'\ :sub:`11[5:0]`\ Y'\ :sub:`10[9:8]` ++ - Y'\ :sub:`12[3:0]`\ Y'\ :sub:`11[9:6]` ++ - Y'\ :sub:`13[1:0]`\ Y'\ :sub:`12[9:4]` ++ - Y'\ :sub:`13[9:2]` ++ * - start + 10: ++ - Cb'\ :sub:`00[7:0]` ++ - Cr'\ :sub:`00[5:0]`\ Cb'\ :sub:`00[9:8]` ++ - Cb'\ :sub:`01[3:0]`\ Cr'\ :sub:`00[9:6]` ++ - Cr'\ :sub:`01[1:0]`\ Cb'\ :sub:`01[9:4]` ++ - Cr'\ :sub:`01[9:2]` ++ ++ ++**Color Sample Location:** ++ ++.. flat-table:: ++ :header-rows: 0 ++ :stub-columns: 0 ++ ++ * - ++ - 0 ++ - ++ - 1 ++ - 2 ++ - ++ - 3 ++ * - 0 ++ - Y ++ - ++ - Y ++ - Y ++ - ++ - Y ++ * - ++ - ++ - C ++ - ++ - ++ - C ++ - ++ * - 1 ++ - Y ++ - ++ - Y ++ - Y ++ - ++ - Y +diff --git a/Documentation/userspace-api/media/v4l/pixfmt-nv20.rst b/Documentation/userspace-api/media/v4l/pixfmt-nv20.rst +new file mode 100644 +index 000000000000..a8123be0baa3 +--- /dev/null ++++ b/Documentation/userspace-api/media/v4l/pixfmt-nv20.rst +@@ -0,0 +1,99 @@ ++.. Permission is granted to copy, distribute and/or modify this ++.. document under the terms of the GNU Free Documentation License, ++.. Version 1.1 or any later version published by the Free Software ++.. Foundation, with no Invariant Sections, no Front-Cover Texts ++.. and no Back-Cover Texts. A copy of the license is included at ++.. Documentation/userspace-api/media/fdl-appendix.rst. ++.. ++.. TODO: replace it to GFDL-1.1-or-later WITH no-invariant-sections ++ ++.. _V4L2-PIX-FMT-NV20: ++ ++************************** ++V4L2_PIX_FMT_NV20 ('NV20') ++************************** ++ ++Format with ½ horizontal chroma resolution, also known as YUV 4:2:2. ++One luminance and one chrominance plane with alternating chroma samples ++similar to ``V4L2_PIX_FMT_NV16`` but with 10-bit samples ++that are grouped into four and packed into five bytes. ++ ++The '20' suffix refers to the optimum effective bits per pixel which is ++achieved when the total number of luminance samples is a multiple of 4. ++ ++ ++Description ++=========== ++ ++This is a packed 10-bit two-plane version of the YUV 4:2:2 format. The ++three components are separated into two sub-images or planes. The Y plane ++is first. The Y plane has five bytes per each group of four pixels. A ++combined CbCr plane immediately follows the Y plane in memory. The CbCr ++plane is the same width and height, in bytes, as the Y plane (and of the ++image). Each CbCr pair belongs to two pixels. For example, ++Cb\ :sub:`00`/Cr\ :sub:`00` belongs to Y'\ :sub:`00`, Y'\ :sub:`01`. ++ ++If the Y plane has pad bytes after each row, then the CbCr plane has as ++many pad bytes after its rows. ++ ++**Byte Order.** ++Little endian. Each cell is one byte. Pixels cross the byte boundary. ++ ++ ++.. flat-table:: ++ :header-rows: 0 ++ :stub-columns: 0 ++ ++ * - start + 0: ++ - Y'\ :sub:`00[7:0]` ++ - Y'\ :sub:`01[5:0]`\ Y'\ :sub:`00[9:8]` ++ - Y'\ :sub:`02[3:0]`\ Y'\ :sub:`01[9:6]` ++ - Y'\ :sub:`03[1:0]`\ Y'\ :sub:`02[9:4]` ++ - Y'\ :sub:`03[9:2]` ++ * - start + 5: ++ - Y'\ :sub:`10[7:0]` ++ - Y'\ :sub:`11[5:0]`\ Y'\ :sub:`10[9:8]` ++ - Y'\ :sub:`12[3:0]`\ Y'\ :sub:`11[9:6]` ++ - Y'\ :sub:`13[1:0]`\ Y'\ :sub:`12[9:4]` ++ - Y'\ :sub:`13[9:2]` ++ * - start + 10: ++ - Cb'\ :sub:`00[7:0]` ++ - Cr'\ :sub:`00[5:0]`\ Cb'\ :sub:`00[9:8]` ++ - Cb'\ :sub:`01[3:0]`\ Cr'\ :sub:`00[9:6]` ++ - Cr'\ :sub:`01[1:0]`\ Cb'\ :sub:`01[9:4]` ++ - Cr'\ :sub:`01[9:2]` ++ * - start + 15: ++ - Cb'\ :sub:`10[7:0]` ++ - Cr'\ :sub:`10[5:0]`\ Cb'\ :sub:`10[9:8]` ++ - Cb'\ :sub:`11[3:0]`\ Cr'\ :sub:`10[9:6]` ++ - Cr'\ :sub:`11[1:0]`\ Cb'\ :sub:`11[9:4]` ++ - Cr'\ :sub:`11[9:2]` ++ ++ ++**Color Sample Location:** ++ ++.. flat-table:: ++ :header-rows: 0 ++ :stub-columns: 0 ++ ++ * - ++ - 0 ++ - ++ - 1 ++ - 2 ++ - ++ - 3 ++ * - 0 ++ - Y ++ - C ++ - Y ++ - Y ++ - C ++ - Y ++ * - 1 ++ - Y ++ - C ++ - Y ++ - Y ++ - C ++ - Y +diff --git a/Documentation/userspace-api/media/v4l/yuv-formats.rst b/Documentation/userspace-api/media/v4l/yuv-formats.rst +index 8ee92d0cd769..7cca883f178a 100644 +--- a/Documentation/userspace-api/media/v4l/yuv-formats.rst ++++ b/Documentation/userspace-api/media/v4l/yuv-formats.rst +@@ -61,4 +61,6 @@ to brightness information. + pixfmt-nv16 + pixfmt-nv16m + pixfmt-nv24 ++ pixfmt-nv15 ++ pixfmt-nv20 + pixfmt-m420 +diff --git a/drivers/media/v4l2-core/v4l2-common.c b/drivers/media/v4l2-core/v4l2-common.c +index 4102c373b48a..0caac755d303 100644 +--- a/drivers/media/v4l2-core/v4l2-common.c ++++ b/drivers/media/v4l2-core/v4l2-common.c +@@ -267,6 +267,9 @@ const struct v4l2_format_info *v4l2_format_info(u32 format) + { .format = V4L2_PIX_FMT_NV24, .pixel_enc = V4L2_PIXEL_ENC_YUV, .mem_planes = 1, .comp_planes = 2, .bpp = { 1, 2, 0, 0 }, .hdiv = 1, .vdiv = 1 }, + { .format = V4L2_PIX_FMT_NV42, .pixel_enc = V4L2_PIXEL_ENC_YUV, .mem_planes = 1, .comp_planes = 2, .bpp = { 1, 2, 0, 0 }, .hdiv = 1, .vdiv = 1 }, + ++ { .format = V4L2_PIX_FMT_NV15, .pixel_enc = V4L2_PIXEL_ENC_YUV, .mem_planes = 1, .comp_planes = 2, .bpp = { 5, 5, 0, 0 }, .hdiv = 2, .vdiv = 2, .block_w = { 4, 2, 0, 0 }, .block_h = { 1, 1, 0, 0 } }, ++ { .format = V4L2_PIX_FMT_NV20, .pixel_enc = V4L2_PIXEL_ENC_YUV, .mem_planes = 1, .comp_planes = 2, .bpp = { 5, 5, 0, 0 }, .hdiv = 2, .vdiv = 1, .block_w = { 4, 2, 0, 0 }, .block_h = { 1, 1, 0, 0 } }, ++ + { .format = V4L2_PIX_FMT_YUV410, .pixel_enc = V4L2_PIXEL_ENC_YUV, .mem_planes = 1, .comp_planes = 3, .bpp = { 1, 1, 1, 0 }, .hdiv = 4, .vdiv = 4 }, + { .format = V4L2_PIX_FMT_YVU410, .pixel_enc = V4L2_PIXEL_ENC_YUV, .mem_planes = 1, .comp_planes = 3, .bpp = { 1, 1, 1, 0 }, .hdiv = 4, .vdiv = 4 }, + { .format = V4L2_PIX_FMT_YUV411P, .pixel_enc = V4L2_PIXEL_ENC_YUV, .mem_planes = 1, .comp_planes = 3, .bpp = { 1, 1, 1, 0 }, .hdiv = 4, .vdiv = 1 }, +diff --git a/drivers/media/v4l2-core/v4l2-ioctl.c b/drivers/media/v4l2-core/v4l2-ioctl.c +index 02bfef0da76d..4657274bb37a 100644 +--- a/drivers/media/v4l2-core/v4l2-ioctl.c ++++ b/drivers/media/v4l2-core/v4l2-ioctl.c +@@ -1315,6 +1315,8 @@ static void v4l_fill_fmtdesc(struct v4l2_fmtdesc *fmt) + case V4L2_PIX_FMT_NV61: descr = "Y/CrCb 4:2:2"; break; + case V4L2_PIX_FMT_NV24: descr = "Y/CbCr 4:4:4"; break; + case V4L2_PIX_FMT_NV42: descr = "Y/CrCb 4:4:4"; break; ++ case V4L2_PIX_FMT_NV15: descr = "10-bit Y/CbCr 4:2:0 (Packed)"; break; ++ case V4L2_PIX_FMT_NV20: descr = "10-bit Y/CbCr 4:2:2 (Packed)"; break; + case V4L2_PIX_FMT_NV12M: descr = "Y/CbCr 4:2:0 (N-C)"; break; + case V4L2_PIX_FMT_NV21M: descr = "Y/CrCb 4:2:0 (N-C)"; break; + case V4L2_PIX_FMT_NV16M: descr = "Y/CbCr 4:2:2 (N-C)"; break; +diff --git a/include/uapi/linux/videodev2.h b/include/uapi/linux/videodev2.h +index 303805438814..bd23aeaf0706 100644 +--- a/include/uapi/linux/videodev2.h ++++ b/include/uapi/linux/videodev2.h +@@ -610,6 +610,9 @@ struct v4l2_pix_format { + #define V4L2_PIX_FMT_NV24 v4l2_fourcc('N', 'V', '2', '4') /* 24 Y/CbCr 4:4:4 */ + #define V4L2_PIX_FMT_NV42 v4l2_fourcc('N', 'V', '4', '2') /* 24 Y/CrCb 4:4:4 */ + ++#define V4L2_PIX_FMT_NV15 v4l2_fourcc('N', 'V', '1', '5') /* 15 Y/CbCr 4:2:0 10-bit packed */ ++#define V4L2_PIX_FMT_NV20 v4l2_fourcc('N', 'V', '2', '0') /* 20 Y/CbCr 4:2:2 10-bit packed */ ++ + /* two non contiguous planes - one Y, one Cr + Cb interleaved */ + #define V4L2_PIX_FMT_NV12M v4l2_fourcc('N', 'M', '1', '2') /* 12 Y/CbCr 4:2:0 */ + #define V4L2_PIX_FMT_NV21M v4l2_fourcc('N', 'M', '2', '1') /* 21 Y/CrCb 4:2:0 */ +-- +2.25.1 + + +From ac18ccac6e1a05ecdffd1eb5e8017d92a5eb6c0f Mon Sep 17 00:00:00 2001 +From: Jonas Karlman +Date: Mon, 6 Jul 2020 21:54:36 +0000 +Subject: [PATCH 11/18] media: rkvdec: h264: Use bytesperline and buffer height + to calculate stride + +Use bytesperline and buffer height to calculate the strides configured. + +This does not really change anything other than ensuring the bytesperline +that is signaled to userspace matches what is configured in HW. + +Signed-off-by: Jonas Karlman +--- + drivers/staging/media/rkvdec/rkvdec-h264.c | 10 +++++----- + 1 file changed, 5 insertions(+), 5 deletions(-) + +diff --git a/drivers/staging/media/rkvdec/rkvdec-h264.c b/drivers/staging/media/rkvdec/rkvdec-h264.c +index 3a85545bcb38..10756b9d6118 100644 +--- a/drivers/staging/media/rkvdec/rkvdec-h264.c ++++ b/drivers/staging/media/rkvdec/rkvdec-h264.c +@@ -891,9 +891,9 @@ static void config_registers(struct rkvdec_ctx *ctx, + dma_addr_t rlc_addr; + dma_addr_t refer_addr; + u32 rlc_len; +- u32 hor_virstride = 0; +- u32 ver_virstride = 0; +- u32 y_virstride = 0; ++ u32 hor_virstride; ++ u32 ver_virstride; ++ u32 y_virstride; + u32 yuv_virstride = 0; + u32 offset; + dma_addr_t dst_addr; +@@ -904,8 +904,8 @@ static void config_registers(struct rkvdec_ctx *ctx, + + f = &ctx->decoded_fmt; + dst_fmt = &f->fmt.pix_mp; +- hor_virstride = (sps->bit_depth_luma_minus8 + 8) * dst_fmt->width / 8; +- ver_virstride = round_up(dst_fmt->height, 16); ++ hor_virstride = dst_fmt->plane_fmt[0].bytesperline; ++ ver_virstride = dst_fmt->height; + y_virstride = hor_virstride * ver_virstride; + + if (sps->chroma_format_idc == 0) +-- +2.25.1 + + +From 62e313c4f82da894647a166a923c32746c2715ad Mon Sep 17 00:00:00 2001 +From: Jonas Karlman +Date: Mon, 6 Jul 2020 21:54:37 +0000 +Subject: [PATCH 12/18] media: rkvdec: Extract rkvdec_fill_decoded_pixfmt + helper method + +This extract setting decoded pixfmt into a helper method, current code is +replaced with a call to the new helper method. + +The helper method is also called from a new function in next patch. + +Signed-off-by: Jonas Karlman +--- + drivers/staging/media/rkvdec/rkvdec.c | 29 ++++++++++++++------------- + 1 file changed, 15 insertions(+), 14 deletions(-) + +diff --git a/drivers/staging/media/rkvdec/rkvdec.c b/drivers/staging/media/rkvdec/rkvdec.c +index 7a9f78bc0a55..911132be6d50 100644 +--- a/drivers/staging/media/rkvdec/rkvdec.c ++++ b/drivers/staging/media/rkvdec/rkvdec.c +@@ -27,6 +27,17 @@ + #include "rkvdec.h" + #include "rkvdec-regs.h" + ++static void rkvdec_fill_decoded_pixfmt(struct rkvdec_ctx *ctx, ++ struct v4l2_pix_format_mplane *pix_mp) ++{ ++ v4l2_fill_pixfmt_mp(pix_mp, pix_mp->pixelformat, ++ pix_mp->width, pix_mp->height); ++ pix_mp->plane_fmt[0].sizeimage += 128 * ++ DIV_ROUND_UP(pix_mp->width, 16) * ++ DIV_ROUND_UP(pix_mp->height, 16); ++ pix_mp->field = V4L2_FIELD_NONE; ++} ++ + static int rkvdec_try_ctrl(struct v4l2_ctrl *ctrl) + { + struct rkvdec_ctx *ctx = container_of(ctrl->handler, struct rkvdec_ctx, ctrl_hdl); +@@ -179,13 +190,9 @@ static void rkvdec_reset_decoded_fmt(struct rkvdec_ctx *ctx) + + rkvdec_reset_fmt(ctx, f, ctx->coded_fmt_desc->decoded_fmts[0]); + f->type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE; +- v4l2_fill_pixfmt_mp(&f->fmt.pix_mp, +- ctx->coded_fmt_desc->decoded_fmts[0], +- ctx->coded_fmt.fmt.pix_mp.width, +- ctx->coded_fmt.fmt.pix_mp.height); +- f->fmt.pix_mp.plane_fmt[0].sizeimage += 128 * +- DIV_ROUND_UP(f->fmt.pix_mp.width, 16) * +- DIV_ROUND_UP(f->fmt.pix_mp.height, 16); ++ f->fmt.pix_mp.width = ctx->coded_fmt.fmt.pix_mp.width; ++ f->fmt.pix_mp.height = ctx->coded_fmt.fmt.pix_mp.height; ++ rkvdec_fill_decoded_pixfmt(ctx, &f->fmt.pix_mp); + } + + static int rkvdec_enum_framesizes(struct file *file, void *priv, +@@ -251,13 +258,7 @@ static int rkvdec_try_capture_fmt(struct file *file, void *priv, + &pix_mp->height, + &coded_desc->frmsize); + +- v4l2_fill_pixfmt_mp(pix_mp, pix_mp->pixelformat, +- pix_mp->width, pix_mp->height); +- pix_mp->plane_fmt[0].sizeimage += +- 128 * +- DIV_ROUND_UP(pix_mp->width, 16) * +- DIV_ROUND_UP(pix_mp->height, 16); +- pix_mp->field = V4L2_FIELD_NONE; ++ rkvdec_fill_decoded_pixfmt(ctx, pix_mp); + + return 0; + } +-- +2.25.1 + + +From ce2a49e0b4908dbc148df81a053bb3eaf8c28048 Mon Sep 17 00:00:00 2001 +From: Jonas Karlman +Date: Mon, 6 Jul 2020 21:54:37 +0000 +Subject: [PATCH 13/18] media: rkvdec: Lock capture pixel format in s_ctrl and + s_fmt + +Add an optional valid_fmt operation that should return the valid +pixelformat of CAPTURE buffers. + +This is used in next patch to ensure correct pixelformat is used for 10-bit +and 4:2:2 content. + +Signed-off-by: Jonas Karlman +--- + drivers/staging/media/rkvdec/rkvdec.c | 59 ++++++++++++++++++++++++--- + drivers/staging/media/rkvdec/rkvdec.h | 2 + + 2 files changed, 55 insertions(+), 6 deletions(-) + +diff --git a/drivers/staging/media/rkvdec/rkvdec.c b/drivers/staging/media/rkvdec/rkvdec.c +index 911132be6d50..11a88cb6407d 100644 +--- a/drivers/staging/media/rkvdec/rkvdec.c ++++ b/drivers/staging/media/rkvdec/rkvdec.c +@@ -38,6 +38,16 @@ static void rkvdec_fill_decoded_pixfmt(struct rkvdec_ctx *ctx, + pix_mp->field = V4L2_FIELD_NONE; + } + ++static u32 rkvdec_valid_fmt(struct rkvdec_ctx *ctx, struct v4l2_ctrl *ctrl) ++{ ++ const struct rkvdec_coded_fmt_desc *coded_desc = ctx->coded_fmt_desc; ++ ++ if (coded_desc->ops->valid_fmt) ++ return coded_desc->ops->valid_fmt(ctx, ctrl); ++ ++ return ctx->valid_fmt; ++} ++ + static int rkvdec_try_ctrl(struct v4l2_ctrl *ctrl) + { + struct rkvdec_ctx *ctx = container_of(ctrl->handler, struct rkvdec_ctx, ctrl_hdl); +@@ -60,6 +70,10 @@ static int rkvdec_try_ctrl(struct v4l2_ctrl *ctrl) + /* Only 8-bit is supported */ + return -EINVAL; + ++ if (ctx->valid_fmt && ctx->valid_fmt != rkvdec_valid_fmt(ctx, ctrl)) ++ /* Only current valid format */ ++ return -EINVAL; ++ + width = (sps->pic_width_in_mbs_minus1 + 1) * 16; + height = (sps->pic_height_in_map_units_minus1 + 1) * 16; + +@@ -70,8 +84,27 @@ static int rkvdec_try_ctrl(struct v4l2_ctrl *ctrl) + return 0; + } + ++static int rkvdec_s_ctrl(struct v4l2_ctrl *ctrl) ++{ ++ struct rkvdec_ctx *ctx = container_of(ctrl->handler, struct rkvdec_ctx, ctrl_hdl); ++ ++ if (ctrl->id == V4L2_CID_MPEG_VIDEO_H264_SPS && !ctx->valid_fmt) { ++ ctx->valid_fmt = rkvdec_valid_fmt(ctx, ctrl); ++ if (ctx->valid_fmt) { ++ struct v4l2_pix_format_mplane *pix_mp; ++ ++ pix_mp = &ctx->decoded_fmt.fmt.pix_mp; ++ pix_mp->pixelformat = ctx->valid_fmt; ++ rkvdec_fill_decoded_pixfmt(ctx, pix_mp); ++ } ++ } ++ ++ return 0; ++} ++ + static const struct v4l2_ctrl_ops rkvdec_ctrl_ops = { + .try_ctrl = rkvdec_try_ctrl, ++ .s_ctrl = rkvdec_s_ctrl, + }; + + static const struct rkvdec_ctrl_desc rkvdec_h264_ctrl_descs[] = { +@@ -188,6 +221,7 @@ static void rkvdec_reset_decoded_fmt(struct rkvdec_ctx *ctx) + { + struct v4l2_format *f = &ctx->decoded_fmt; + ++ ctx->valid_fmt = 0; + rkvdec_reset_fmt(ctx, f, ctx->coded_fmt_desc->decoded_fmts[0]); + f->type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE; + f->fmt.pix_mp.width = ctx->coded_fmt.fmt.pix_mp.width; +@@ -243,13 +277,17 @@ static int rkvdec_try_capture_fmt(struct file *file, void *priv, + if (WARN_ON(!coded_desc)) + return -EINVAL; + +- for (i = 0; i < coded_desc->num_decoded_fmts; i++) { +- if (coded_desc->decoded_fmts[i] == pix_mp->pixelformat) +- break; +- } ++ if (ctx->valid_fmt) { ++ pix_mp->pixelformat = ctx->valid_fmt; ++ } else { ++ for (i = 0; i < coded_desc->num_decoded_fmts; i++) { ++ if (coded_desc->decoded_fmts[i] == pix_mp->pixelformat) ++ break; ++ } + +- if (i == coded_desc->num_decoded_fmts) +- pix_mp->pixelformat = coded_desc->decoded_fmts[0]; ++ if (i == coded_desc->num_decoded_fmts) ++ pix_mp->pixelformat = coded_desc->decoded_fmts[0]; ++ } + + /* Always apply the frmsize constraint of the coded end. */ + pix_mp->width = max(pix_mp->width, ctx->coded_fmt.fmt.pix_mp.width); +@@ -324,6 +362,7 @@ static int rkvdec_s_capture_fmt(struct file *file, void *priv, + return ret; + + ctx->decoded_fmt = *f; ++ ctx->valid_fmt = f->fmt.pix_mp.pixelformat; + return 0; + } + +@@ -413,6 +452,14 @@ static int rkvdec_enum_capture_fmt(struct file *file, void *priv, + if (WARN_ON(!ctx->coded_fmt_desc)) + return -EINVAL; + ++ if (ctx->valid_fmt) { ++ if (f->index) ++ return -EINVAL; ++ ++ f->pixelformat = ctx->valid_fmt; ++ return 0; ++ } ++ + if (f->index >= ctx->coded_fmt_desc->num_decoded_fmts) + return -EINVAL; + +diff --git a/drivers/staging/media/rkvdec/rkvdec.h b/drivers/staging/media/rkvdec/rkvdec.h +index 2fc9f46b6910..50e67401fdbe 100644 +--- a/drivers/staging/media/rkvdec/rkvdec.h ++++ b/drivers/staging/media/rkvdec/rkvdec.h +@@ -64,6 +64,7 @@ vb2_to_rkvdec_decoded_buf(struct vb2_buffer *buf) + struct rkvdec_coded_fmt_ops { + int (*adjust_fmt)(struct rkvdec_ctx *ctx, + struct v4l2_format *f); ++ u32 (*valid_fmt)(struct rkvdec_ctx *ctx, struct v4l2_ctrl *ctrl); + int (*start)(struct rkvdec_ctx *ctx); + void (*stop)(struct rkvdec_ctx *ctx); + int (*run)(struct rkvdec_ctx *ctx); +@@ -97,6 +98,7 @@ struct rkvdec_ctx { + struct v4l2_fh fh; + struct v4l2_format coded_fmt; + struct v4l2_format decoded_fmt; ++ u32 valid_fmt; + const struct rkvdec_coded_fmt_desc *coded_fmt_desc; + struct v4l2_ctrl_handler ctrl_hdl; + struct rkvdec_dev *dev; +-- +2.25.1 + + +From 4a5ebc230d6f6ad93699631f2f55abb6d7bff43f Mon Sep 17 00:00:00 2001 +From: Jonas Karlman +Date: Mon, 6 Jul 2020 21:54:37 +0000 +Subject: [PATCH 14/18] media: rkvdec: h264: Support High 10 and 4:2:2 profiles + +Add support and enable decoding of H264 High 10 and 4:2:2 profiles. + +Decoded CAPTURE buffer width is aligned to 64 pixels to accommodate HW +requirement on 10-bit format buffers. + +The new valid_fmt operation is implemented and return a valid pixelformat +for the provided SPS control. + +Signed-off-by: Jonas Karlman +--- + drivers/staging/media/rkvdec/rkvdec-h264.c | 20 ++++++++++++++++++++ + drivers/staging/media/rkvdec/rkvdec.c | 19 +++++++++---------- + 2 files changed, 29 insertions(+), 10 deletions(-) + +diff --git a/drivers/staging/media/rkvdec/rkvdec-h264.c b/drivers/staging/media/rkvdec/rkvdec-h264.c +index 10756b9d6118..0757fc97d1ff 100644 +--- a/drivers/staging/media/rkvdec/rkvdec-h264.c ++++ b/drivers/staging/media/rkvdec/rkvdec-h264.c +@@ -1018,6 +1018,25 @@ static int rkvdec_h264_adjust_fmt(struct rkvdec_ctx *ctx, + return 0; + } + ++static u32 rkvdec_h264_valid_fmt(struct rkvdec_ctx *ctx, struct v4l2_ctrl *ctrl) ++{ ++ const struct v4l2_ctrl_h264_sps *sps = ctrl->p_new.p; ++ ++ if (sps->bit_depth_luma_minus8 == 0) { ++ if (sps->chroma_format_idc == 2) ++ return V4L2_PIX_FMT_NV16; ++ else ++ return V4L2_PIX_FMT_NV12; ++ } else if (sps->bit_depth_luma_minus8 == 2) { ++ if (sps->chroma_format_idc == 2) ++ return V4L2_PIX_FMT_NV20; ++ else ++ return V4L2_PIX_FMT_NV15; ++ } ++ ++ return 0; ++} ++ + static int rkvdec_h264_start(struct rkvdec_ctx *ctx) + { + struct rkvdec_dev *rkvdec = ctx->dev; +@@ -1125,6 +1144,7 @@ static int rkvdec_h264_run(struct rkvdec_ctx *ctx) + + const struct rkvdec_coded_fmt_ops rkvdec_h264_fmt_ops = { + .adjust_fmt = rkvdec_h264_adjust_fmt, ++ .valid_fmt = rkvdec_h264_valid_fmt, + .start = rkvdec_h264_start, + .stop = rkvdec_h264_stop, + .run = rkvdec_h264_run, +diff --git a/drivers/staging/media/rkvdec/rkvdec.c b/drivers/staging/media/rkvdec/rkvdec.c +index 11a88cb6407d..4faee9262392 100644 +--- a/drivers/staging/media/rkvdec/rkvdec.c ++++ b/drivers/staging/media/rkvdec/rkvdec.c +@@ -31,7 +31,7 @@ static void rkvdec_fill_decoded_pixfmt(struct rkvdec_ctx *ctx, + struct v4l2_pix_format_mplane *pix_mp) + { + v4l2_fill_pixfmt_mp(pix_mp, pix_mp->pixelformat, +- pix_mp->width, pix_mp->height); ++ ALIGN(pix_mp->width, 64), pix_mp->height); + pix_mp->plane_fmt[0].sizeimage += 128 * + DIV_ROUND_UP(pix_mp->width, 16) * + DIV_ROUND_UP(pix_mp->height, 16); +@@ -55,19 +55,15 @@ static int rkvdec_try_ctrl(struct v4l2_ctrl *ctrl) + if (ctrl->id == V4L2_CID_MPEG_VIDEO_H264_SPS) { + const struct v4l2_ctrl_h264_sps *sps = ctrl->p_new.p; + unsigned int width, height; +- /* +- * TODO: The hardware supports 10-bit and 4:2:2 profiles, +- * but it's currently broken in the driver. +- * Reject them for now, until it's fixed. +- */ +- if (sps->chroma_format_idc > 1) +- /* Only 4:0:0 and 4:2:0 are supported */ ++ ++ if (sps->chroma_format_idc > 2) ++ /* Only 4:0:0, 4:2:0 and 4:2:2 are supported */ + return -EINVAL; + if (sps->bit_depth_luma_minus8 != sps->bit_depth_chroma_minus8) + /* Luma and chroma bit depth mismatch */ + return -EINVAL; +- if (sps->bit_depth_luma_minus8 != 0) +- /* Only 8-bit is supported */ ++ if (sps->bit_depth_luma_minus8 != 0 && sps->bit_depth_luma_minus8 != 2) ++ /* Only 8-bit and 10-bit is supported */ + return -EINVAL; + + if (ctx->valid_fmt && ctx->valid_fmt != rkvdec_valid_fmt(ctx, ctrl)) +@@ -157,6 +153,9 @@ static const struct rkvdec_ctrls rkvdec_h264_ctrls = { + + static const u32 rkvdec_h264_decoded_fmts[] = { + V4L2_PIX_FMT_NV12, ++ V4L2_PIX_FMT_NV15, ++ V4L2_PIX_FMT_NV16, ++ V4L2_PIX_FMT_NV20, + }; + + static const struct rkvdec_coded_fmt_desc rkvdec_coded_fmts[] = { +-- +2.25.1 + + +From 4dc94c5df4663d2120faaddfe1c581b4c3f347b9 Mon Sep 17 00:00:00 2001 +From: Jonas Karlman +Date: Mon, 6 Jul 2020 21:54:38 +0000 +Subject: [PATCH 15/18] media: rkvdec: h264: Support profile and level controls + +The Rockchip Video Decoder used in RK3399 supports H.264 profiles from +Baseline to High 4:2:2 up to Level 5.1, except for the Extended profile. + +Expose the V4L2_CID_MPEG_VIDEO_H264_PROFILE and the +V4L2_CID_MPEG_VIDEO_H264_LEVEL control, so that userspace can query the +driver for the list of supported profiles and level. + +Signed-off-by: Jonas Karlman +Reviewed-by: Ezequiel Garcia +--- + drivers/staging/media/rkvdec/rkvdec.c | 13 +++++++++++++ + 1 file changed, 13 insertions(+) + +diff --git a/drivers/staging/media/rkvdec/rkvdec.c b/drivers/staging/media/rkvdec/rkvdec.c +index 4faee9262392..b21031535330 100644 +--- a/drivers/staging/media/rkvdec/rkvdec.c ++++ b/drivers/staging/media/rkvdec/rkvdec.c +@@ -144,6 +144,19 @@ static const struct rkvdec_ctrl_desc rkvdec_h264_ctrl_descs[] = { + .cfg.def = V4L2_MPEG_VIDEO_H264_START_CODE_ANNEX_B, + .cfg.max = V4L2_MPEG_VIDEO_H264_START_CODE_ANNEX_B, + }, ++ { ++ .cfg.id = V4L2_CID_MPEG_VIDEO_H264_PROFILE, ++ .cfg.min = V4L2_MPEG_VIDEO_H264_PROFILE_BASELINE, ++ .cfg.max = V4L2_MPEG_VIDEO_H264_PROFILE_HIGH_422, ++ .cfg.menu_skip_mask = ++ BIT(V4L2_MPEG_VIDEO_H264_PROFILE_EXTENDED), ++ .cfg.def = V4L2_MPEG_VIDEO_H264_PROFILE_MAIN, ++ }, ++ { ++ .cfg.id = V4L2_CID_MPEG_VIDEO_H264_LEVEL, ++ .cfg.min = V4L2_MPEG_VIDEO_H264_LEVEL_1_0, ++ .cfg.max = V4L2_MPEG_VIDEO_H264_LEVEL_5_1, ++ }, + }; + + static const struct rkvdec_ctrls rkvdec_h264_ctrls = { +-- +2.25.1 + + +From 4bf8f995e8b6f06db483cee2952de5662bb5cf37 Mon Sep 17 00:00:00 2001 +From: Ben Davis +Date: Mon, 1 Jun 2020 17:28:17 +0100 +Subject: [PATCH 16/18] drm: drm_fourcc: add NV15, Q410, Q401 YUV formats + +DRM_FORMAT_NV15 is a 2 plane format suitable for linear and 16x16 +block-linear memory layouts (DRM_FORMAT_MOD_SAMSUNG_16_16_TILE). The +format is similar to P010 with 4:2:0 sub-sampling but has no padding +between components. Instead, luminance and chrominance samples are +grouped into 4s so that each group is packed into an integer number +of bytes: + +YYYY = UVUV = 4 * 10 bits = 40 bits = 5 bytes + +The '15' suffix refers to the optimum effective bits per pixel which is +achieved when the total number of luminance samples is a multiple of 8. + +Q410 and Q401 are both 3 plane non-subsampled formats with 16 bits per +component, but only 10 bits are used and 6 are padded. 'Q' is chosen +as the first letter to denote 3 plane YUV444, (and is the next letter +along from P which is usually 2 plane). + +V2: Updated block_w of NV15 to {4, 2, 0} +V3: Updated commit message to include specific modifier name + +NV15: +Tested-by: Jonas Karlman + +Reviewed-by: Brian Starkey +Signed-off-by: Ben Davis +Signed-off-by: Liviu Dudau +Link: https://patchwork.freedesktop.org/patch/msgid/20200601162817.18230-1-ben.davis@arm.com +--- + drivers/gpu/drm/drm_fourcc.c | 12 ++++++++++++ + include/uapi/drm/drm_fourcc.h | 22 ++++++++++++++++++++++ + 2 files changed, 34 insertions(+) + +diff --git a/drivers/gpu/drm/drm_fourcc.c b/drivers/gpu/drm/drm_fourcc.c +index b234bfaeda06..722c7ebe4e88 100644 +--- a/drivers/gpu/drm/drm_fourcc.c ++++ b/drivers/gpu/drm/drm_fourcc.c +@@ -274,6 +274,18 @@ const struct drm_format_info *__drm_format_info(u32 format) + { .format = DRM_FORMAT_YUV420_10BIT, .depth = 0, + .num_planes = 1, .cpp = { 0, 0, 0 }, .hsub = 2, .vsub = 2, + .is_yuv = true }, ++ { .format = DRM_FORMAT_NV15, .depth = 0, ++ .num_planes = 2, .char_per_block = { 5, 5, 0 }, ++ .block_w = { 4, 2, 0 }, .block_h = { 1, 1, 0 }, .hsub = 2, ++ .vsub = 2, .is_yuv = true }, ++ { .format = DRM_FORMAT_Q410, .depth = 0, ++ .num_planes = 3, .char_per_block = { 2, 2, 2 }, ++ .block_w = { 1, 1, 1 }, .block_h = { 1, 1, 1 }, .hsub = 0, ++ .vsub = 0, .is_yuv = true }, ++ { .format = DRM_FORMAT_Q401, .depth = 0, ++ .num_planes = 3, .char_per_block = { 2, 2, 2 }, ++ .block_w = { 1, 1, 1 }, .block_h = { 1, 1, 1 }, .hsub = 0, ++ .vsub = 0, .is_yuv = true }, + }; + + unsigned int i; +diff --git a/include/uapi/drm/drm_fourcc.h b/include/uapi/drm/drm_fourcc.h +index 490143500a50..8ba2d9153a94 100644 +--- a/include/uapi/drm/drm_fourcc.h ++++ b/include/uapi/drm/drm_fourcc.h +@@ -236,6 +236,12 @@ extern "C" { + #define DRM_FORMAT_NV61 fourcc_code('N', 'V', '6', '1') /* 2x1 subsampled Cb:Cr plane */ + #define DRM_FORMAT_NV24 fourcc_code('N', 'V', '2', '4') /* non-subsampled Cr:Cb plane */ + #define DRM_FORMAT_NV42 fourcc_code('N', 'V', '4', '2') /* non-subsampled Cb:Cr plane */ ++/* ++ * 2 plane YCbCr ++ * index 0 = Y plane, [39:0] Y3:Y2:Y1:Y0 little endian ++ * index 1 = Cr:Cb plane, [39:0] Cr1:Cb1:Cr0:Cb0 little endian ++ */ ++#define DRM_FORMAT_NV15 fourcc_code('N', 'V', '1', '5') /* 2x2 subsampled Cr:Cb plane */ + + /* + * 2 plane YCbCr MSB aligned +@@ -265,6 +271,22 @@ extern "C" { + */ + #define DRM_FORMAT_P016 fourcc_code('P', '0', '1', '6') /* 2x2 subsampled Cr:Cb plane 16 bits per channel */ + ++/* 3 plane non-subsampled (444) YCbCr ++ * 16 bits per component, but only 10 bits are used and 6 bits are padded ++ * index 0: Y plane, [15:0] Y:x [10:6] little endian ++ * index 1: Cb plane, [15:0] Cb:x [10:6] little endian ++ * index 2: Cr plane, [15:0] Cr:x [10:6] little endian ++ */ ++#define DRM_FORMAT_Q410 fourcc_code('Q', '4', '1', '0') ++ ++/* 3 plane non-subsampled (444) YCrCb ++ * 16 bits per component, but only 10 bits are used and 6 bits are padded ++ * index 0: Y plane, [15:0] Y:x [10:6] little endian ++ * index 1: Cr plane, [15:0] Cr:x [10:6] little endian ++ * index 2: Cb plane, [15:0] Cb:x [10:6] little endian ++ */ ++#define DRM_FORMAT_Q401 fourcc_code('Q', '4', '0', '1') ++ + /* + * 3 plane YCbCr + * index 0: Y plane, [7:0] Y +-- +2.25.1 + + +From 588b8545dda3cd0ef8f066dcafff3fa7a93e4056 Mon Sep 17 00:00:00 2001 +From: Jonas Karlman +Date: Mon, 6 Jul 2020 22:30:13 +0000 +Subject: [PATCH 17/18] drm: drm_fourcc: add NV20 and NV30 YUV formats + +DRM_FORMAT_NV20 and DRM_FORMAT_NV30 formats is the 2x1 and non-subsampled +variant of NV15, a 10-bit 2-plane YUV format that has no padding between +components. Instead, luminance and chrominance samples are grouped into 4s +so that each group is packed into an integer number of bytes: + +YYYY = UVUV = 4 * 10 bits = 40 bits = 5 bytes + +The '20' and '30' suffix refers to the optimum effective bits per pixel +which is achieved when the total number of luminance samples is a multiple +of 4. + +V2: Added NV30 format + +Signed-off-by: Jonas Karlman +Reviewed-by: Sandy Huang +--- + drivers/gpu/drm/drm_fourcc.c | 8 ++++++++ + include/uapi/drm/drm_fourcc.h | 2 ++ + 2 files changed, 10 insertions(+) + +diff --git a/drivers/gpu/drm/drm_fourcc.c b/drivers/gpu/drm/drm_fourcc.c +index 722c7ebe4e88..2daf8a304b53 100644 +--- a/drivers/gpu/drm/drm_fourcc.c ++++ b/drivers/gpu/drm/drm_fourcc.c +@@ -278,6 +278,14 @@ const struct drm_format_info *__drm_format_info(u32 format) + .num_planes = 2, .char_per_block = { 5, 5, 0 }, + .block_w = { 4, 2, 0 }, .block_h = { 1, 1, 0 }, .hsub = 2, + .vsub = 2, .is_yuv = true }, ++ { .format = DRM_FORMAT_NV20, .depth = 0, ++ .num_planes = 2, .char_per_block = { 5, 5, 0 }, ++ .block_w = { 4, 2, 0 }, .block_h = { 1, 1, 0 }, .hsub = 2, ++ .vsub = 1, .is_yuv = true }, ++ { .format = DRM_FORMAT_NV30, .depth = 0, ++ .num_planes = 2, .char_per_block = { 5, 5, 0 }, ++ .block_w = { 4, 2, 0 }, .block_h = { 1, 1, 0 }, .hsub = 1, ++ .vsub = 1, .is_yuv = true }, + { .format = DRM_FORMAT_Q410, .depth = 0, + .num_planes = 3, .char_per_block = { 2, 2, 2 }, + .block_w = { 1, 1, 1 }, .block_h = { 1, 1, 1 }, .hsub = 0, +diff --git a/include/uapi/drm/drm_fourcc.h b/include/uapi/drm/drm_fourcc.h +index 8ba2d9153a94..c3024c82a3e3 100644 +--- a/include/uapi/drm/drm_fourcc.h ++++ b/include/uapi/drm/drm_fourcc.h +@@ -242,6 +242,8 @@ extern "C" { + * index 1 = Cr:Cb plane, [39:0] Cr1:Cb1:Cr0:Cb0 little endian + */ + #define DRM_FORMAT_NV15 fourcc_code('N', 'V', '1', '5') /* 2x2 subsampled Cr:Cb plane */ ++#define DRM_FORMAT_NV20 fourcc_code('N', 'V', '2', '0') /* 2x1 subsampled Cr:Cb plane */ ++#define DRM_FORMAT_NV30 fourcc_code('N', 'V', '3', '0') /* non-subsampled Cr:Cb plane */ + + /* + * 2 plane YCbCr MSB aligned +-- +2.25.1 + + +From 5e09593745d332f82471e1a763e9b9b2632543eb Mon Sep 17 00:00:00 2001 +From: Jonas Karlman +Date: Mon, 6 Jul 2020 22:30:13 +0000 +Subject: [PATCH 18/18] drm: rockchip: add NV15, NV20 and NV30 support + +Add support for displaying 10-bit 4:2:0 and 4:2:2 formats produced by the +Rockchip Video Decoder on RK322X, RK3288, RK3328, RK3368 and RK3399. +Also add support for 10-bit 4:4:4 format while at it. + +V2: Added NV30 support + +Signed-off-by: Jonas Karlman +Reviewed-by: Sandy Huang +--- + drivers/gpu/drm/rockchip/rockchip_drm_vop.c | 29 +++++++++++++++++-- + drivers/gpu/drm/rockchip/rockchip_drm_vop.h | 1 + + drivers/gpu/drm/rockchip/rockchip_vop_reg.c | 32 +++++++++++++++++---- + 3 files changed, 54 insertions(+), 8 deletions(-) + +diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_vop.c b/drivers/gpu/drm/rockchip/rockchip_drm_vop.c +index 33463b79a37b..dc2667cfb575 100644 +--- a/drivers/gpu/drm/rockchip/rockchip_drm_vop.c ++++ b/drivers/gpu/drm/rockchip/rockchip_drm_vop.c +@@ -261,6 +261,18 @@ static bool has_rb_swapped(uint32_t format) + } + } + ++static bool is_fmt_10(uint32_t format) ++{ ++ switch (format) { ++ case DRM_FORMAT_NV15: ++ case DRM_FORMAT_NV20: ++ case DRM_FORMAT_NV30: ++ return true; ++ default: ++ return false; ++ } ++} ++ + static enum vop_data_format vop_convert_format(uint32_t format) + { + switch (format) { +@@ -276,10 +288,13 @@ static enum vop_data_format vop_convert_format(uint32_t format) + case DRM_FORMAT_BGR565: + return VOP_FMT_RGB565; + case DRM_FORMAT_NV12: ++ case DRM_FORMAT_NV15: + return VOP_FMT_YUV420SP; + case DRM_FORMAT_NV16: ++ case DRM_FORMAT_NV20: + return VOP_FMT_YUV422SP; + case DRM_FORMAT_NV24: ++ case DRM_FORMAT_NV30: + return VOP_FMT_YUV444SP; + default: + DRM_ERROR("unsupported format[%08x]\n", format); +@@ -922,7 +937,12 @@ static void vop_plane_atomic_update(struct drm_plane *plane, + dsp_sty = dest->y1 + crtc->mode.vtotal - crtc->mode.vsync_start; + dsp_st = dsp_sty << 16 | (dsp_stx & 0xffff); + +- offset = (src->x1 >> 16) * fb->format->cpp[0]; ++ if (fb->format->block_w[0]) ++ offset = (src->x1 >> 16) * fb->format->char_per_block[0] / ++ fb->format->block_w[0]; ++ else ++ offset = (src->x1 >> 16) * fb->format->cpp[0]; ++ + offset += (src->y1 >> 16) * fb->pitches[0]; + dma_addr = rk_obj->dma_addr + offset + fb->offsets[0]; + +@@ -948,6 +968,7 @@ static void vop_plane_atomic_update(struct drm_plane *plane, + } + + VOP_WIN_SET(vop, win, format, format); ++ VOP_WIN_SET(vop, win, fmt_10, is_fmt_10(fb->format->format)); + VOP_WIN_SET(vop, win, yrgb_vir, DIV_ROUND_UP(fb->pitches[0], 4)); + VOP_WIN_SET(vop, win, yrgb_mst, dma_addr); + VOP_WIN_YUV2YUV_SET(vop, win_yuv2yuv, y2r_en, is_yuv); +@@ -964,7 +985,11 @@ static void vop_plane_atomic_update(struct drm_plane *plane, + uv_obj = fb->obj[1]; + rk_uv_obj = to_rockchip_obj(uv_obj); + +- offset = (src->x1 >> 16) * bpp / hsub; ++ if (fb->format->block_w[1]) ++ offset = (src->x1 >> 16) * bpp / ++ fb->format->block_w[1] / hsub; ++ else ++ offset = (src->x1 >> 16) * bpp / hsub; + offset += (src->y1 >> 16) * fb->pitches[1] / vsub; + + dma_addr = rk_uv_obj->dma_addr + offset + fb->offsets[1]; +diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_vop.h b/drivers/gpu/drm/rockchip/rockchip_drm_vop.h +index d03bdb531ef2..db1138da2bd4 100644 +--- a/drivers/gpu/drm/rockchip/rockchip_drm_vop.h ++++ b/drivers/gpu/drm/rockchip/rockchip_drm_vop.h +@@ -154,6 +154,7 @@ struct vop_win_phy { + struct vop_reg enable; + struct vop_reg gate; + struct vop_reg format; ++ struct vop_reg fmt_10; + struct vop_reg rb_swap; + struct vop_reg act_info; + struct vop_reg dsp_info; +diff --git a/drivers/gpu/drm/rockchip/rockchip_vop_reg.c b/drivers/gpu/drm/rockchip/rockchip_vop_reg.c +index 2413deded22c..475c435d659b 100644 +--- a/drivers/gpu/drm/rockchip/rockchip_vop_reg.c ++++ b/drivers/gpu/drm/rockchip/rockchip_vop_reg.c +@@ -50,6 +50,23 @@ static const uint32_t formats_win_full[] = { + DRM_FORMAT_NV24, + }; + ++static const uint32_t formats_win_full_10[] = { ++ DRM_FORMAT_XRGB8888, ++ DRM_FORMAT_ARGB8888, ++ DRM_FORMAT_XBGR8888, ++ DRM_FORMAT_ABGR8888, ++ DRM_FORMAT_RGB888, ++ DRM_FORMAT_BGR888, ++ DRM_FORMAT_RGB565, ++ DRM_FORMAT_BGR565, ++ DRM_FORMAT_NV12, ++ DRM_FORMAT_NV16, ++ DRM_FORMAT_NV24, ++ DRM_FORMAT_NV15, ++ DRM_FORMAT_NV20, ++ DRM_FORMAT_NV30, ++}; ++ + static const uint64_t format_modifiers_win_full[] = { + DRM_FORMAT_MOD_LINEAR, + DRM_FORMAT_MOD_INVALID, +@@ -570,11 +587,12 @@ static const struct vop_scl_regs rk3288_win_full_scl = { + + static const struct vop_win_phy rk3288_win01_data = { + .scl = &rk3288_win_full_scl, +- .data_formats = formats_win_full, +- .nformats = ARRAY_SIZE(formats_win_full), ++ .data_formats = formats_win_full_10, ++ .nformats = ARRAY_SIZE(formats_win_full_10), + .format_modifiers = format_modifiers_win_full, + .enable = VOP_REG(RK3288_WIN0_CTRL0, 0x1, 0), + .format = VOP_REG(RK3288_WIN0_CTRL0, 0x7, 1), ++ .fmt_10 = VOP_REG(RK3288_WIN0_CTRL0, 0x1, 4), + .rb_swap = VOP_REG(RK3288_WIN0_CTRL0, 0x1, 12), + .act_info = VOP_REG(RK3288_WIN0_ACT_INFO, 0x1fff1fff, 0), + .dsp_info = VOP_REG(RK3288_WIN0_DSP_INFO, 0x0fff0fff, 0), +@@ -704,11 +722,12 @@ static const struct vop_intr rk3368_vop_intr = { + + static const struct vop_win_phy rk3368_win01_data = { + .scl = &rk3288_win_full_scl, +- .data_formats = formats_win_full, +- .nformats = ARRAY_SIZE(formats_win_full), ++ .data_formats = formats_win_full_10, ++ .nformats = ARRAY_SIZE(formats_win_full_10), + .format_modifiers = format_modifiers_win_full, + .enable = VOP_REG(RK3368_WIN0_CTRL0, 0x1, 0), + .format = VOP_REG(RK3368_WIN0_CTRL0, 0x7, 1), ++ .fmt_10 = VOP_REG(RK3368_WIN0_CTRL0, 0x1, 4), + .rb_swap = VOP_REG(RK3368_WIN0_CTRL0, 0x1, 12), + .x_mir_en = VOP_REG(RK3368_WIN0_CTRL0, 0x1, 21), + .y_mir_en = VOP_REG(RK3368_WIN0_CTRL0, 0x1, 22), +@@ -853,11 +872,12 @@ static const struct vop_win_yuv2yuv_data rk3399_vop_big_win_yuv2yuv_data[] = { + + static const struct vop_win_phy rk3399_win01_data = { + .scl = &rk3288_win_full_scl, +- .data_formats = formats_win_full, +- .nformats = ARRAY_SIZE(formats_win_full), ++ .data_formats = formats_win_full_10, ++ .nformats = ARRAY_SIZE(formats_win_full_10), + .format_modifiers = format_modifiers_win_full_afbc, + .enable = VOP_REG(RK3288_WIN0_CTRL0, 0x1, 0), + .format = VOP_REG(RK3288_WIN0_CTRL0, 0x7, 1), ++ .fmt_10 = VOP_REG(RK3288_WIN0_CTRL0, 0x1, 4), + .rb_swap = VOP_REG(RK3288_WIN0_CTRL0, 0x1, 12), + .y_mir_en = VOP_REG(RK3288_WIN0_CTRL0, 0x1, 22), + .act_info = VOP_REG(RK3288_WIN0_ACT_INFO, 0x1fff1fff, 0), +-- +2.25.1 + diff --git a/patch/kernel/rockchip64-current/rockpi4-0005-arm64-dts-enable-es8316-audio.patch b/patch/kernel/rockchip64-current/rockpi4-0005-arm64-dts-enable-es8316-audio.patch index 5c54c64ada..8ab49b428e 100644 --- a/patch/kernel/rockchip64-current/rockpi4-0005-arm64-dts-enable-es8316-audio.patch +++ b/patch/kernel/rockchip64-current/rockpi4-0005-arm64-dts-enable-es8316-audio.patch @@ -69,16 +69,16 @@ + i2s0 { + i2s0_8ch_bus: i2s0-8ch-bus { + rockchip,pins = -+ <3 24 RK_FUNC_1 &pcfg_pull_none>, -+ <3 25 RK_FUNC_1 &pcfg_pull_none>, -+ <3 26 RK_FUNC_1 &pcfg_pull_none>, -+ <3 27 RK_FUNC_1 &pcfg_pull_none>, -+ <3 30 RK_FUNC_1 &pcfg_pull_none>, -+ <3 31 RK_FUNC_1 &pcfg_pull_none>; ++ <3 24 1 &pcfg_pull_none>, ++ <3 25 1 &pcfg_pull_none>, ++ <3 26 1 &pcfg_pull_none>, ++ <3 27 1 &pcfg_pull_none>, ++ <3 30 1 &pcfg_pull_none>, ++ <3 31 1 &pcfg_pull_none>; + }; + + i2s_8ch_mclk: i2s-8ch-mclk { -+ rockchip,pins = <4 0 RK_FUNC_1 &pcfg_pull_none>; ++ rockchip,pins = <4 0 1 &pcfg_pull_none>; + }; + }; }; diff --git a/patch/kernel/rockchip64-current/rockpis-0001-arm64-dts-rockchip-add-ROCK-Pi-S-DTS-support.patch b/patch/kernel/rockchip64-current/rockpis-0001-arm64-dts-rockchip-add-ROCK-Pi-S-DTS-support.patch index 1cb659deb3..acb02ed7ae 100644 --- a/patch/kernel/rockchip64-current/rockpis-0001-arm64-dts-rockchip-add-ROCK-Pi-S-DTS-support.patch +++ b/patch/kernel/rockchip64-current/rockpis-0001-arm64-dts-rockchip-add-ROCK-Pi-S-DTS-support.patch @@ -49,9 +49,9 @@ index 48fb631d5451..e56a5527bab4 100644 dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3308-evb.dtb dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3308-roc-cc.dtb +dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3308-rock-pi-s.dtb + dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3326-odroid-go2.dtb dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3328-a1.dtb dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3328-evb.dtb - dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3328-rock64.dtb diff --git a/arch/arm64/boot/dts/rockchip/rk3308-rock-pi-s.dts b/arch/arm64/boot/dts/rockchip/rk3308-rock-pi-s.dts new file mode 100644 index 000000000000..4fccae43f008 diff --git a/patch/kernel/rockchip64-current/rockpis-0023-ASoC-rockchip-i2s-add-compatible-for-rk3308.patch b/patch/kernel/rockchip64-current/rockpis-0023-ASoC-rockchip-i2s-add-compatible-for-rk3308.patch deleted file mode 100644 index 441c3cc673..0000000000 --- a/patch/kernel/rockchip64-current/rockpis-0023-ASoC-rockchip-i2s-add-compatible-for-rk3308.patch +++ /dev/null @@ -1,37 +0,0 @@ -From 3f90a9ef2e8d7e647572b2f2f2f54dce20c654c5 Mon Sep 17 00:00:00 2001 -From: ashthespy -Date: Mon, 3 Feb 2020 21:29:44 +0100 -Subject: [PATCH 23/23] ASoC: rockchip: i2s: add compatible for rk3308 - ---- - Documentation/devicetree/bindings/sound/rockchip-i2s.yaml | 1 + - sound/soc/rockchip/rockchip_i2s.c | 1 + - 2 files changed, 2 insertions(+) - -diff --git a/Documentation/devicetree/bindings/sound/rockchip-i2s.yaml b/Documentation/devicetree/bindings/sound/rockchip-i2s.yaml -index a3ba2186d..122c2e958 100644 ---- a/Documentation/devicetree/bindings/sound/rockchip-i2s.yaml -+++ b/Documentation/devicetree/bindings/sound/rockchip-i2s.yaml -@@ -24,6 +24,7 @@ properties: - - rockchip,rk3188-i2s - - rockchip,rk3228-i2s - - rockchip,rk3288-i2s -+ - rockchip,rk3308-i2s - - rockchip,rk3328-i2s - - rockchip,rk3366-i2s - - rockchip,rk3368-i2s -diff --git a/sound/soc/rockchip/rockchip_i2s.c b/sound/soc/rockchip/rockchip_i2s.c -index e6125ebfe5a9..dcee123b0939 100644 ---- a/sound/soc/rockchip/rockchip_i2s.c -+++ b/sound/soc/rockchip/rockchip_i2s.c -@@ -598,6 +598,7 @@ static const struct of_device_id rockchip_i2s_match[] = { - { .compatible = "rockchip,rk3066-i2s", }, - { .compatible = "rockchip,rk3128-i2s", }, - { .compatible = "rockchip,rk3188-i2s", }, -+ { .compatible = "rockchip,rk3308-i2s", }, - { .compatible = "rockchip,rk3288-i2s", }, - { .compatible = "rockchip,rk3308-i2s", }, - { .compatible = "rockchip,rk3328-i2s", }, --- -2.25.1 - diff --git a/patch/kernel/rockchip64-current/wifi-4003-fix-sha256_state-clashes.patch b/patch/kernel/rockchip64-current/wifi-4003-fix-sha256_state-clashes.patch new file mode 100644 index 0000000000..f528e5c592 --- /dev/null +++ b/patch/kernel/rockchip64-current/wifi-4003-fix-sha256_state-clashes.patch @@ -0,0 +1,310 @@ +diff --git a/drivers/net/wireless/rtl8189es/include/rtw_security.h b/drivers/net/wireless/rtl8189es/include/rtw_security.h +index 5820a55..3e8e428 100644 +--- a/drivers/net/wireless/rtl8189es/include/rtw_security.h ++++ b/drivers/net/wireless/rtl8189es/include/rtw_security.h +@@ -238,7 +238,7 @@ struct security_priv + #endif /* DBG_SW_SEC_CNT */ + }; + +-struct sha256_state { ++struct rtl_sha256_state { + u64 length; + u32 state[8], curlen; + u8 buf[64]; +diff --git a/drivers/net/wireless/rtl8189es/core/rtw_security.c b/drivers/net/wireless/rtl8189es/core/rtw_security.c +index 8dac771..9b3a1f9 100644 +--- a/drivers/net/wireless/rtl8189es/core/rtw_security.c ++++ b/drivers/net/wireless/rtl8189es/core/rtw_security.c +@@ -2281,7 +2281,7 @@ BIP_exit: + + #ifndef PLATFORM_FREEBSD + /* compress 512-bits */ +-static int sha256_compress(struct sha256_state *md, unsigned char *buf) ++static int sha256_compress(struct rtl_sha256_state *md, unsigned char *buf) + { + u32 S[8], W[64], t0, t1; + u32 t; +@@ -2323,7 +2323,7 @@ static int sha256_compress(struct sha256_state *md, unsigned char *buf) + } + + /* Initialize the hash state */ +-static void sha256_init(struct sha256_state *md) ++static void sha256_init(struct rtl_sha256_state *md) + { + md->curlen = 0; + md->length = 0; +@@ -2344,7 +2344,7 @@ static void sha256_init(struct sha256_state *md) + @param inlen The length of the data (octets) + @return CRYPT_OK if successful + */ +-static int sha256_process(struct sha256_state *md, unsigned char *in, ++static int sha256_process(struct rtl_sha256_state *md, unsigned char *in, + unsigned long inlen) + { + unsigned long n; +@@ -2385,7 +2385,7 @@ static int sha256_process(struct sha256_state *md, unsigned char *in, + @param out [out] The destination of the hash (32 bytes) + @return CRYPT_OK if successful + */ +-static int sha256_done(struct sha256_state *md, unsigned char *out) ++static int sha256_done(struct rtl_sha256_state *md, unsigned char *out) + { + int i; + +@@ -2437,7 +2437,7 @@ static int sha256_done(struct sha256_state *md, unsigned char *out) + static int sha256_vector(size_t num_elem, u8 *addr[], size_t *len, + u8 *mac) + { +- struct sha256_state ctx; ++ struct rtl_sha256_state ctx; + size_t i; + + sha256_init(&ctx); +diff --git a/drivers/net/wireless/rtl8811cu/include/rtw_security.h b/drivers/net/wireless/rtl8811cu/include/rtw_security.h +index ac8432e..5f74fb7 100755 +--- a/drivers/net/wireless/rtl8811cu/include/rtw_security.h ++++ b/drivers/net/wireless/rtl8811cu/include/rtw_security.h +@@ -249,7 +249,7 @@ struct security_priv { + #define SEC_IS_BIP_KEY_INSTALLED(sec) _FALSE + #endif + +-struct sha256_state { ++struct rtl_sha256_state { + u64 length; + u32 state[8], curlen; + u8 buf[64]; +diff --git a/drivers/net/wireless/rtl8811cu/core/rtw_security.c b/drivers/net/wireless/rtl8811cu/core/rtw_security.c +index b537a26..f8c42f4 100755 +--- a/drivers/net/wireless/rtl8811cu/core/rtw_security.c ++++ b/drivers/net/wireless/rtl8811cu/core/rtw_security.c +@@ -2133,7 +2133,7 @@ BIP_exit: + #ifndef PLATFORM_FREEBSD + #if defined(CONFIG_TDLS) + /* compress 512-bits */ +-static int sha256_compress(struct sha256_state *md, unsigned char *buf) ++static int sha256_compress(struct rtl_sha256_state *md, unsigned char *buf) + { + u32 S[8], W[64], t0, t1; + u32 t; +@@ -2181,7 +2181,7 @@ static int sha256_compress(struct sha256_state *md, unsigned char *buf) + } + + /* Initialize the hash state */ +-static void sha256_init(struct sha256_state *md) ++static void sha256_init(struct rtl_sha256_state *md) + { + md->curlen = 0; + md->length = 0; +@@ -2202,7 +2202,7 @@ static void sha256_init(struct sha256_state *md) + @param inlen The length of the data (octets) + @return CRYPT_OK if successful + */ +-static int sha256_process(struct sha256_state *md, unsigned char *in, ++static int sha256_process(struct rtl_sha256_state *md, unsigned char *in, + unsigned long inlen) + { + unsigned long n; +@@ -2243,7 +2243,7 @@ static int sha256_process(struct sha256_state *md, unsigned char *in, + @param out [out] The destination of the hash (32 bytes) + @return CRYPT_OK if successful + */ +-static int sha256_done(struct sha256_state *md, unsigned char *out) ++static int sha256_done(struct rtl_sha256_state *md, unsigned char *out) + { + int i; + +@@ -2293,7 +2293,7 @@ static int sha256_done(struct sha256_state *md, unsigned char *out) + static int sha256_vector(size_t num_elem, u8 *addr[], size_t *len, + u8 *mac) + { +- struct sha256_state ctx; ++ struct rtl_sha256_state ctx; + size_t i; + + sha256_init(&ctx); +diff --git a/drivers/net/wireless/rtl8188eu/include/rtw_security.h b/drivers/net/wireless/rtl8188eu/include/rtw_security.h +index 0adc700..2a9cf9d 100644 +--- a/drivers/net/wireless/rtl8188eu/include/rtw_security.h ++++ b/drivers/net/wireless/rtl8188eu/include/rtw_security.h +@@ -249,7 +249,7 @@ struct security_priv { + #define SEC_IS_BIP_KEY_INSTALLED(sec) _FALSE + #endif + +-struct sha256_state { ++struct rtl_sha256_state { + u64 length; + u32 state[8], curlen; + u8 buf[64]; +diff --git a/drivers/net/wireless/rtl8188eu/core/rtw_security.c b/drivers/net/wireless/rtl8188eu/core/rtw_security.c +index 5807521..0b3eed2 100644 +--- a/drivers/net/wireless/rtl8188eu/core/rtw_security.c ++++ b/drivers/net/wireless/rtl8188eu/core/rtw_security.c +@@ -2133,7 +2133,7 @@ BIP_exit: + #ifndef PLATFORM_FREEBSD + #if defined(CONFIG_TDLS) + /* compress 512-bits */ +-static int sha256_compress(struct sha256_state *md, unsigned char *buf) ++static int sha256_compress(struct rtl_sha256_state *md, unsigned char *buf) + { + u32 S[8], W[64], t0, t1; + u32 t; +@@ -2181,7 +2181,7 @@ static int sha256_compress(struct sha256_state *md, unsigned char *buf) + } + + /* Initialize the hash state */ +-static void sha256_init(struct sha256_state *md) ++static void sha256_init(struct rtl_sha256_state *md) + { + md->curlen = 0; + md->length = 0; +@@ -2202,7 +2202,7 @@ static void sha256_init(struct sha256_state *md) + @param inlen The length of the data (octets) + @return CRYPT_OK if successful + */ +-static int sha256_process(struct sha256_state *md, unsigned char *in, ++static int sha256_process(struct rtl_sha256_state *md, unsigned char *in, + unsigned long inlen) + { + unsigned long n; +@@ -2243,7 +2243,7 @@ static int sha256_process(struct sha256_state *md, unsigned char *in, + @param out [out] The destination of the hash (32 bytes) + @return CRYPT_OK if successful + */ +-static int sha256_done(struct sha256_state *md, unsigned char *out) ++static int sha256_done(struct rtl_sha256_state *md, unsigned char *out) + { + int i; + +@@ -2293,7 +2293,7 @@ static int sha256_done(struct sha256_state *md, unsigned char *out) + static int sha256_vector(size_t num_elem, u8 *addr[], size_t *len, + u8 *mac) + { +- struct sha256_state ctx; ++ struct rtl_sha256_state ctx; + size_t i; + + sha256_init(&ctx); +diff --git a/drivers/net/wireless/rtl88x2bu/include/rtw_security.h b/drivers/net/wireless/rtl88x2bu/include/rtw_security.h +index ac8432e..5f74fb7 100644 +--- a/drivers/net/wireless/rtl88x2bu/include/rtw_security.h ++++ b/drivers/net/wireless/rtl88x2bu/include/rtw_security.h +@@ -249,7 +249,7 @@ struct security_priv { + #define SEC_IS_BIP_KEY_INSTALLED(sec) _FALSE + #endif + +-struct sha256_state { ++struct rtl_sha256_state { + u64 length; + u32 state[8], curlen; + u8 buf[64]; +diff --git a/drivers/net/wireless/rtl88x2bu/core/rtw_security.c b/drivers/net/wireless/rtl88x2bu/core/rtw_security.c +index b537a26..f8c42f4 100644 +--- a/drivers/net/wireless/rtl88x2bu/core/rtw_security.c ++++ b/drivers/net/wireless/rtl88x2bu/core/rtw_security.c +@@ -2133,7 +2133,7 @@ BIP_exit: + #ifndef PLATFORM_FREEBSD + #if defined(CONFIG_TDLS) + /* compress 512-bits */ +-static int sha256_compress(struct sha256_state *md, unsigned char *buf) ++static int sha256_compress(struct rtl_sha256_state *md, unsigned char *buf) + { + u32 S[8], W[64], t0, t1; + u32 t; +@@ -2181,7 +2181,7 @@ static int sha256_compress(struct sha256_state *md, unsigned char *buf) + } + + /* Initialize the hash state */ +-static void sha256_init(struct sha256_state *md) ++static void sha256_init(struct rtl_sha256_state *md) + { + md->curlen = 0; + md->length = 0; +@@ -2202,7 +2202,7 @@ static void sha256_init(struct sha256_state *md) + @param inlen The length of the data (octets) + @return CRYPT_OK if successful + */ +-static int sha256_process(struct sha256_state *md, unsigned char *in, ++static int sha256_process(struct rtl_sha256_state *md, unsigned char *in, + unsigned long inlen) + { + unsigned long n; +@@ -2243,7 +2243,7 @@ static int sha256_process(struct sha256_state *md, unsigned char *in, + @param out [out] The destination of the hash (32 bytes) + @return CRYPT_OK if successful + */ +-static int sha256_done(struct sha256_state *md, unsigned char *out) ++static int sha256_done(struct rtl_sha256_state *md, unsigned char *out) + { + int i; + +@@ -2293,7 +2293,7 @@ static int sha256_done(struct sha256_state *md, unsigned char *out) + static int sha256_vector(size_t num_elem, u8 *addr[], size_t *len, + u8 *mac) + { +- struct sha256_state ctx; ++ struct rtl_sha256_state ctx; + size_t i; + + sha256_init(&ctx); +diff --git a/drivers/net/wireless/rtl8723ds/include/rtw_security.h b/drivers/net/wireless/rtl8723ds/include/rtw_security.h +index 83c06a5..bcea21a 100644 +--- a/drivers/net/wireless/rtl8723ds/include/rtw_security.h ++++ b/drivers/net/wireless/rtl8723ds/include/rtw_security.h +@@ -242,7 +242,7 @@ struct security_priv { + #endif /* DBG_SW_SEC_CNT */ + }; + +-struct sha256_state { ++struct rtl_sha256_state { + u64 length; + u32 state[8], curlen; + u8 buf[64]; +diff --git a/drivers/net/wireless/rtl8723ds/core/rtw_security.c b/drivers/net/wireless/rtl8723ds/core/rtw_security.c +index 88033df..11aa9a4 100644 +--- a/drivers/net/wireless/rtl8723ds/core/rtw_security.c ++++ b/drivers/net/wireless/rtl8723ds/core/rtw_security.c +@@ -2132,7 +2132,7 @@ BIP_exit: + #endif /* CONFIG_IEEE80211W */ + + /* compress 512-bits */ +-static int sha256_compress(struct sha256_state *md, unsigned char *buf) ++static int sha256_compress(struct rtl_sha256_state *md, unsigned char *buf) + { + u32 S[8], W[64], t0, t1; + u32 t; +@@ -2180,7 +2180,7 @@ static int sha256_compress(struct sha256_state *md, unsigned char *buf) + } + + /* Initialize the hash state */ +-static void sha256_init(struct sha256_state *md) ++static void sha256_init(struct rtl_sha256_state *md) + { + md->curlen = 0; + md->length = 0; +@@ -2201,7 +2201,7 @@ static void sha256_init(struct sha256_state *md) + @param inlen The length of the data (octets) + @return CRYPT_OK if successful + */ +-static int sha256_process(struct sha256_state *md, unsigned char *in, ++static int sha256_process(struct rtl_sha256_state *md, unsigned char *in, + unsigned long inlen) + { + unsigned long n; +@@ -2242,7 +2242,7 @@ static int sha256_process(struct sha256_state *md, unsigned char *in, + @param out [out] The destination of the hash (32 bytes) + @return CRYPT_OK if successful + */ +-static int sha256_done(struct sha256_state *md, unsigned char *out) ++static int sha256_done(struct rtl_sha256_state *md, unsigned char *out) + { + int i; + +@@ -2292,7 +2292,7 @@ static int sha256_done(struct sha256_state *md, unsigned char *out) + static int sha256_vector(size_t num_elem, u8 *addr[], size_t *len, + u8 *mac) + { +- struct sha256_state ctx; ++ struct rtl_sha256_state ctx; + size_t i; + + sha256_init(&ctx); diff --git a/patch/kernel/rockchip64-current/wifi-4004-fix-cfg80211-for-5.8.patch b/patch/kernel/rockchip64-current/wifi-4004-fix-cfg80211-for-5.8.patch new file mode 100644 index 0000000000..b9d8f8c7fe --- /dev/null +++ b/patch/kernel/rockchip64-current/wifi-4004-fix-cfg80211-for-5.8.patch @@ -0,0 +1,295 @@ +diff --git a/drivers/net/wireless/rtl8189es/os_dep/linux/ioctl_cfg80211.c b/drivers/net/wireless/rtl8189es/os_dep/linux/ioctl_cfg80211.c +index d77cc17..32cc240 100644 +--- a/drivers/net/wireless/rtl8189es/os_dep/linux/ioctl_cfg80211.c ++++ b/drivers/net/wireless/rtl8189es/os_dep/linux/ioctl_cfg80211.c +@@ -5567,6 +5567,33 @@ exit: + return ret; + } + ++#if (LINUX_VERSION_CODE >= KERNEL_VERSION(5, 8, 0)) ++ ++static void ++cfg80211_rtw_update_mgmt_frame_registrations(struct wiphy *wiphy, ++ struct wireless_dev *wdev, ++ struct mgmt_frame_regs *upd) ++{ ++ struct net_device *ndev = wdev_to_ndev(wdev); ++ struct rtw_wdev_priv *pwdev_priv; ++ _adapter *adapter; ++ ++ if (ndev == NULL) ++ return; ++ ++ adapter = (_adapter *)rtw_netdev_priv(ndev); ++ pwdev_priv = adapter_wdev_data(adapter); ++ ++#ifdef CONFIG_DEBUG_CFG80211 ++ RTW_INFO(FUNC_ADPT_FMT" stypes:%x\n", FUNC_ADPT_ARG(adapter), ++ upd->interface_stypes); ++#endif ++ ++ /* not implemented, see bellow */ ++} ++ ++#else ++ + static void cfg80211_rtw_mgmt_frame_register(struct wiphy *wiphy, + #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 6, 0)) + struct wireless_dev *wdev, +@@ -5611,6 +5638,8 @@ exit: + return; + } + ++#endif ++ + #if defined(CONFIG_TDLS) && (LINUX_VERSION_CODE >= KERNEL_VERSION(3,2,0)) + static int cfg80211_rtw_tdls_mgmt(struct wiphy *wiphy, + struct net_device *ndev, +@@ -6505,7 +6534,11 @@ static struct cfg80211_ops rtw_cfg80211_ops = { + + #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,37)) || defined(COMPAT_KERNEL_RELEASE) + .mgmt_tx = cfg80211_rtw_mgmt_tx, ++#if (LINUX_VERSION_CODE >= KERNEL_VERSION(5, 8, 0)) ++ .update_mgmt_frame_registrations = cfg80211_rtw_update_mgmt_frame_registrations, ++#else + .mgmt_frame_register = cfg80211_rtw_mgmt_frame_register, ++#endif + #elif (LINUX_VERSION_CODE>=KERNEL_VERSION(2,6,34) && LINUX_VERSION_CODE<=KERNEL_VERSION(2,6,35)) + .action = cfg80211_rtw_mgmt_tx, + #endif +diff --git a/drivers/net/wireless/rtl8811cu/os_dep/linux/ioctl_cfg80211.c b/drivers/net/wireless/rtl8811cu/os_dep/linux/ioctl_cfg80211.c +index c0df148..9bff924 100755 +--- a/drivers/net/wireless/rtl8811cu/os_dep/linux/ioctl_cfg80211.c ++++ b/drivers/net/wireless/rtl8811cu/os_dep/linux/ioctl_cfg80211.c +@@ -7143,6 +7143,33 @@ exit: + return ret; + } + ++#if (LINUX_VERSION_CODE >= KERNEL_VERSION(5, 8, 0)) ++ ++static void ++cfg80211_rtw_update_mgmt_frame_registrations(struct wiphy *wiphy, ++ struct wireless_dev *wdev, ++ struct mgmt_frame_regs *upd) ++{ ++ struct net_device *ndev = wdev_to_ndev(wdev); ++ struct rtw_wdev_priv *pwdev_priv; ++ _adapter *adapter; ++ ++ if (ndev == NULL) ++ return; ++ ++ adapter = (_adapter *)rtw_netdev_priv(ndev); ++ pwdev_priv = adapter_wdev_data(adapter); ++ ++#ifdef CONFIG_DEBUG_CFG80211 ++ RTW_INFO(FUNC_ADPT_FMT" stypes:%x\n", FUNC_ADPT_ARG(adapter), ++ upd->interface_stypes); ++#endif ++ ++ /* not implemented, see bellow */ ++} ++ ++#else ++ + static void cfg80211_rtw_mgmt_frame_register(struct wiphy *wiphy, + #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 6, 0)) + struct wireless_dev *wdev, +@@ -7187,6 +7214,8 @@ exit: + return; + } + ++#endif ++ + #if defined(CONFIG_TDLS) && (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 2, 0)) + static int cfg80211_rtw_tdls_mgmt(struct wiphy *wiphy, + struct net_device *ndev, +@@ -9457,7 +9486,11 @@ static struct cfg80211_ops rtw_cfg80211_ops = { + + #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 37)) || defined(COMPAT_KERNEL_RELEASE) + .mgmt_tx = cfg80211_rtw_mgmt_tx, ++#if (LINUX_VERSION_CODE >= KERNEL_VERSION(5, 8, 0)) ++ .update_mgmt_frame_registrations = cfg80211_rtw_update_mgmt_frame_registrations, ++#else + .mgmt_frame_register = cfg80211_rtw_mgmt_frame_register, ++#endif + #elif (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 34) && LINUX_VERSION_CODE <= KERNEL_VERSION(2, 6, 35)) + .action = cfg80211_rtw_mgmt_tx, + #endif +diff --git a/drivers/net/wireless/rtl8188eu/os_dep/linux/ioctl_cfg80211.c b/drivers/net/wireless/rtl8188eu/os_dep/linux/ioctl_cfg80211.c +index 721723e..62fd530 100644 +--- a/drivers/net/wireless/rtl8188eu/os_dep/linux/ioctl_cfg80211.c ++++ b/drivers/net/wireless/rtl8188eu/os_dep/linux/ioctl_cfg80211.c +@@ -7470,6 +7470,33 @@ exit: + return ret; + } + ++#if (LINUX_VERSION_CODE >= KERNEL_VERSION(5, 8, 0)) ++ ++static void ++cfg80211_rtw_update_mgmt_frame_registrations(struct wiphy *wiphy, ++ struct wireless_dev *wdev, ++ struct mgmt_frame_regs *upd) ++{ ++ struct net_device *ndev = wdev_to_ndev(wdev); ++ struct rtw_wdev_priv *pwdev_priv; ++ _adapter *adapter; ++ ++ if (ndev == NULL) ++ return; ++ ++ adapter = (_adapter *)rtw_netdev_priv(ndev); ++ pwdev_priv = adapter_wdev_data(adapter); ++ ++#ifdef CONFIG_DEBUG_CFG80211 ++ RTW_INFO(FUNC_ADPT_FMT" stypes:%x\n", FUNC_ADPT_ARG(adapter), ++ upd->interface_stypes); ++#endif ++ ++ /* not implemented, see bellow */ ++} ++ ++#else ++ + static void cfg80211_rtw_mgmt_frame_register(struct wiphy *wiphy, + #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 6, 0)) + struct wireless_dev *wdev, +@@ -7525,6 +7552,8 @@ exit: + return; + } + ++#endif ++ + #if defined(CONFIG_TDLS) && (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 2, 0)) + static int cfg80211_rtw_tdls_mgmt(struct wiphy *wiphy, + struct net_device *ndev, +@@ -9903,7 +9932,11 @@ static struct cfg80211_ops rtw_cfg80211_ops = { + + #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 37)) || defined(COMPAT_KERNEL_RELEASE) + .mgmt_tx = cfg80211_rtw_mgmt_tx, ++#if (LINUX_VERSION_CODE >= KERNEL_VERSION(5, 8, 0)) ++ .update_mgmt_frame_registrations = cfg80211_rtw_update_mgmt_frame_registrations, ++#else + .mgmt_frame_register = cfg80211_rtw_mgmt_frame_register, ++#endif + #elif (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 34) && LINUX_VERSION_CODE <= KERNEL_VERSION(2, 6, 35)) + .action = cfg80211_rtw_mgmt_tx, + #endif +diff --git a/drivers/net/wireless/rtl88x2bu/os_dep/linux/ioctl_cfg80211.c b/drivers/net/wireless/rtl88x2bu/os_dep/linux/ioctl_cfg80211.c +index 2fd4e28..b463e55 100755 +--- a/drivers/net/wireless/rtl88x2bu/os_dep/linux/ioctl_cfg80211.c ++++ b/drivers/net/wireless/rtl88x2bu/os_dep/linux/ioctl_cfg80211.c +@@ -7325,6 +7325,33 @@ exit: + return ret; + } + ++#if (LINUX_VERSION_CODE >= KERNEL_VERSION(5, 8, 0)) ++ ++static void ++cfg80211_rtw_update_mgmt_frame_registrations(struct wiphy *wiphy, ++ struct wireless_dev *wdev, ++ struct mgmt_frame_regs *upd) ++{ ++ struct net_device *ndev = wdev_to_ndev(wdev); ++ struct rtw_wdev_priv *pwdev_priv; ++ _adapter *adapter; ++ ++ if (ndev == NULL) ++ return; ++ ++ adapter = (_adapter *)rtw_netdev_priv(ndev); ++ pwdev_priv = adapter_wdev_data(adapter); ++ ++#ifdef CONFIG_DEBUG_CFG80211 ++ RTW_INFO(FUNC_ADPT_FMT" stypes:%x\n", FUNC_ADPT_ARG(adapter), ++ upd->interface_stypes); ++#endif ++ ++ /* not implemented, see bellow */ ++} ++ ++#else ++ + static void cfg80211_rtw_mgmt_frame_register(struct wiphy *wiphy, + #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 6, 0)) + struct wireless_dev *wdev, +@@ -7369,6 +7396,8 @@ exit: + return; + } + ++#endif ++ + #if defined(CONFIG_TDLS) && (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 2, 0)) + static int cfg80211_rtw_tdls_mgmt(struct wiphy *wiphy, + struct net_device *ndev, +@@ -9652,7 +9681,11 @@ static struct cfg80211_ops rtw_cfg80211_ops = { + + #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 37)) || defined(COMPAT_KERNEL_RELEASE) + .mgmt_tx = cfg80211_rtw_mgmt_tx, ++#if (LINUX_VERSION_CODE >= KERNEL_VERSION(5, 8, 0)) ++ .update_mgmt_frame_registrations = cfg80211_rtw_update_mgmt_frame_registrations, ++#else + .mgmt_frame_register = cfg80211_rtw_mgmt_frame_register, ++#endif + #elif (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 34) && LINUX_VERSION_CODE <= KERNEL_VERSION(2, 6, 35)) + .action = cfg80211_rtw_mgmt_tx, + #endif +diff --git a/drivers/net/wireless/rtl8723ds/os_dep/linux/ioctl_cfg80211.c b/drivers/net/wireless/rtl8723ds/os_dep/linux/ioctl_cfg80211.c +index 564c2c5..921a452 100644 +--- a/drivers/net/wireless/rtl8723ds/os_dep/linux/ioctl_cfg80211.c ++++ b/drivers/net/wireless/rtl8723ds/os_dep/linux/ioctl_cfg80211.c +@@ -5872,6 +5872,33 @@ exit: + return ret; + } + ++#if (LINUX_VERSION_CODE >= KERNEL_VERSION(5, 8, 0)) ++ ++static void ++cfg80211_rtw_update_mgmt_frame_registrations(struct wiphy *wiphy, ++ struct wireless_dev *wdev, ++ struct mgmt_frame_regs *upd) ++{ ++ struct net_device *ndev = wdev_to_ndev(wdev); ++ struct rtw_wdev_priv *pwdev_priv; ++ _adapter *adapter; ++ ++ if (ndev == NULL) ++ return; ++ ++ adapter = (_adapter *)rtw_netdev_priv(ndev); ++ pwdev_priv = adapter_wdev_data(adapter); ++ ++#ifdef CONFIG_DEBUG_CFG80211 ++ RTW_INFO(FUNC_ADPT_FMT" stypes:%x\n", FUNC_ADPT_ARG(adapter), ++ upd->interface_stypes); ++#endif ++ ++ /* not implemented, see bellow */ ++} ++ ++#else ++ + static void cfg80211_rtw_mgmt_frame_register(struct wiphy *wiphy, + #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 6, 0)) + struct wireless_dev *wdev, +@@ -5916,6 +5943,8 @@ exit: + return; + } + ++#endif ++ + #if defined(CONFIG_TDLS) && (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 2, 0)) + static int cfg80211_rtw_tdls_mgmt(struct wiphy *wiphy, + struct net_device *ndev, +@@ -6866,7 +6895,11 @@ static struct cfg80211_ops rtw_cfg80211_ops = { + + #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 37)) || defined(COMPAT_KERNEL_RELEASE) + .mgmt_tx = cfg80211_rtw_mgmt_tx, ++#if (LINUX_VERSION_CODE >= KERNEL_VERSION(5, 8, 0)) ++ .update_mgmt_frame_registrations = cfg80211_rtw_update_mgmt_frame_registrations, ++#else + .mgmt_frame_register = cfg80211_rtw_mgmt_frame_register, ++#endif + #elif (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 34) && LINUX_VERSION_CODE <= KERNEL_VERSION(2, 6, 35)) + .action = cfg80211_rtw_mgmt_tx, + #endif