From 2f14f2ee0c6815b37e2a17b3e726f9b9b82dcc1d Mon Sep 17 00:00:00 2001 From: Alex Bee Date: Sun, 17 Jan 2021 17:00:03 +0100 Subject: [PATCH 1/6] rockchip: linux: update patches and configs for 5.10 --- .../RK3288/linux/default/linux.arm.conf | 225 +- .../RK3328/linux/default/linux.aarch64.conf | 247 +- .../RK3399/linux/default/linux.aarch64.conf | 242 +- .../linux-0001-rockchip-from-5.10.patch | 2967 ---------------- .../linux-0001-rockchip-from-5.11.patch | 3068 +++++++++++++++++ ...iQi-Add-missing-GPU-CPU-nodes-in-dts.patch | 42 - .../linux-0002-rockchip-from-next.patch | 949 +++++ .../linux-0003-rockchip-from-list.patch | 1369 ++++++++ .../default/linux-0010-v4l2-from-list.patch | 1039 ++++++ .../default/linux-0011-v4l2-from-5.10.patch | 2632 -------------- .../default/linux-0020-drm-from-5.11.patch | 647 ++++ .../default/linux-0021-drm-from-5.10.patch | 2194 ------------ .../default/linux-0021-drm-from-list.patch | 234 ++ .../default/linux-0022-drm-from-next.patch | 403 --- .../default/linux-1001-drm-rockchip.patch | 3030 ++++++++++++++++ .../default/linux-1002-v4l2-rockchip.patch | 670 ++++ ...328-enable-USB3-for-supported-boards.patch | 76 + 17 files changed, 11531 insertions(+), 8503 deletions(-) delete mode 100644 projects/Rockchip/patches/linux/default/linux-0001-rockchip-from-5.10.patch create mode 100644 projects/Rockchip/patches/linux/default/linux-0001-rockchip-from-5.11.patch delete mode 100644 projects/Rockchip/patches/linux/default/linux-0002-MiQi-Add-missing-GPU-CPU-nodes-in-dts.patch create mode 100644 projects/Rockchip/patches/linux/default/linux-0002-rockchip-from-next.patch create mode 100644 projects/Rockchip/patches/linux/default/linux-0003-rockchip-from-list.patch create mode 100644 projects/Rockchip/patches/linux/default/linux-0010-v4l2-from-list.patch delete mode 100644 projects/Rockchip/patches/linux/default/linux-0011-v4l2-from-5.10.patch create mode 100644 projects/Rockchip/patches/linux/default/linux-0020-drm-from-5.11.patch delete mode 100644 projects/Rockchip/patches/linux/default/linux-0021-drm-from-5.10.patch create mode 100644 projects/Rockchip/patches/linux/default/linux-0021-drm-from-list.patch delete mode 100644 projects/Rockchip/patches/linux/default/linux-0022-drm-from-next.patch create mode 100644 projects/Rockchip/patches/linux/default/linux-1001-drm-rockchip.patch create mode 100644 projects/Rockchip/patches/linux/default/linux-1002-v4l2-rockchip.patch create mode 100644 projects/Rockchip/patches/linux/default/linux-1003-RK3328-enable-USB3-for-supported-boards.patch diff --git a/projects/Rockchip/devices/RK3288/linux/default/linux.arm.conf b/projects/Rockchip/devices/RK3288/linux/default/linux.arm.conf index 8cdaa9daa5..ead26a4926 100644 --- a/projects/Rockchip/devices/RK3288/linux/default/linux.arm.conf +++ b/projects/Rockchip/devices/RK3288/linux/default/linux.arm.conf @@ -1,18 +1,7 @@ # # Automatically generated file; DO NOT EDIT. -# Linux/arm 5.9.0 Kernel Configuration +# Linux/arm 5.10.4 Kernel Configuration # -CONFIG_CC_VERSION_TEXT="arm-none-linux-gnueabihf-gcc-9.2.1 (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 -CONFIG_BUILDTIME_TABLE_SORT=y # # General setup @@ -57,6 +46,7 @@ CONFIG_HARDIRQS_SW_RESEND=y CONFIG_GENERIC_IRQ_CHIP=y CONFIG_IRQ_DOMAIN=y CONFIG_IRQ_DOMAIN_HIERARCHY=y +CONFIG_GENERIC_IRQ_IPI=y CONFIG_HANDLE_DOMAIN_IRQ=y CONFIG_IRQ_FORCED_THREADING=y CONFIG_SPARSE_IRQ=y @@ -111,6 +101,8 @@ CONFIG_TREE_RCU=y # CONFIG_RCU_EXPERT is not set CONFIG_SRCU=y CONFIG_TREE_SRCU=y +CONFIG_TASKS_RCU_GENERIC=y +CONFIG_TASKS_TRACE_RCU=y CONFIG_RCU_STALL_COMMON=y CONFIG_RCU_NEED_SEGCBLIST=y # end of RCU Subsystem @@ -177,6 +169,7 @@ CONFIG_INITRAMFS_COMPRESSION_NONE=y # CONFIG_BOOT_CONFIG is not set CONFIG_CC_OPTIMIZE_FOR_PERFORMANCE=y # CONFIG_CC_OPTIMIZE_FOR_SIZE is not set +CONFIG_LD_ORPHAN_WARN=y CONFIG_SYSCTL=y CONFIG_HAVE_UID16=y CONFIG_BPF=y @@ -206,6 +199,7 @@ CONFIG_KALLSYMS=y CONFIG_KALLSYMS_ALL=y CONFIG_KALLSYMS_BASE_RELATIVE=y CONFIG_BPF_SYSCALL=y +# CONFIG_BPF_PRELOAD is not set # CONFIG_USERFAULTFD is not set CONFIG_ARCH_HAS_MEMBARRIER_SYNC_CORE=y CONFIG_RSEQ=y @@ -457,7 +451,6 @@ CONFIG_ARCH_WANT_GENERAL_HUGETLB=y CONFIG_FORCE_MAX_ZONEORDER=11 CONFIG_ALIGNMENT_TRAP=y # CONFIG_UACCESS_WITH_MEMCPY is not set -CONFIG_SECCOMP=y # CONFIG_PARAVIRT is not set # CONFIG_PARAVIRT_TIME_ACCOUNTING is not set # CONFIG_XEN is not set @@ -601,6 +594,7 @@ CONFIG_AS_VFP_VMRS_FPINST=y # # General architecture-dependent options # +CONFIG_SET_FS=y CONFIG_HAVE_OPROFILE=y # CONFIG_KPROBES is not set # CONFIG_JUMP_LABEL is not set @@ -627,7 +621,9 @@ CONFIG_HAVE_PERF_REGS=y CONFIG_HAVE_PERF_USER_STACK_DUMP=y CONFIG_HAVE_ARCH_JUMP_LABEL=y CONFIG_ARCH_WANT_IPC_PARSE_VERSION=y +CONFIG_HAVE_ARCH_SECCOMP=y CONFIG_HAVE_ARCH_SECCOMP_FILTER=y +CONFIG_SECCOMP=y CONFIG_SECCOMP_FILTER=y CONFIG_HAVE_STACKPROTECTOR=y CONFIG_STACKPROTECTOR=y @@ -654,6 +650,7 @@ CONFIG_ARCH_HAS_STRICT_MODULE_RWX=y CONFIG_STRICT_MODULE_RWX=y CONFIG_ARCH_HAS_PHYS_TO_DMA=y # CONFIG_LOCK_EVENT_COUNTS is not set +CONFIG_ARCH_WANT_LD_ORPHAN_WARN=y # # GCOV-based kernel profiling @@ -663,7 +660,6 @@ CONFIG_ARCH_HAS_GCOV_PROFILE_ALL=y # end of GCOV-based kernel profiling CONFIG_HAVE_GCC_PLUGINS=y -# CONFIG_GCC_PLUGINS is not set # end of General architecture-dependent options CONFIG_RT_MUTEXES=y @@ -1151,6 +1147,11 @@ CONFIG_MTD_CFI_I2=y # CONFIG_MTD_ONENAND is not set # CONFIG_MTD_RAW_NAND is not set # CONFIG_MTD_SPI_NAND is not set + +# +# ECC engine support +# +# end of ECC engine support # end of NAND # @@ -1179,7 +1180,6 @@ CONFIG_OF_DYNAMIC=y CONFIG_OF_ADDRESS=y CONFIG_OF_IRQ=y CONFIG_OF_NET=y -CONFIG_OF_MDIO=y CONFIG_OF_RESERVED_MEM=y CONFIG_OF_RESOLVE=y CONFIG_OF_OVERLAY=y @@ -1229,6 +1229,7 @@ CONFIG_ISL29003=y # CONFIG_SRAM is not set # CONFIG_XILINX_SDFEC is not set # CONFIG_PVPANIC is not set +# CONFIG_HISI_HIKEY_USB is not set # CONFIG_C2PORT is not set # @@ -1253,14 +1254,6 @@ CONFIG_EEPROM_93CX6=y # CONFIG_SENSORS_LIS3_SPI is not set # CONFIG_SENSORS_LIS3_I2C is not set # CONFIG_ALTERA_STAPL is not set - -# -# Intel MIC & related support -# -CONFIG_VOP_BUS=y -CONFIG_VOP=y -# end of Intel MIC & related support - # CONFIG_ECHO is not set # CONFIG_MISC_RTSX_USB is not set # CONFIG_UACCE is not set @@ -1407,56 +1400,38 @@ CONFIG_STMMAC_PLATFORM=y CONFIG_DWMAC_DWC_QOS_ETH=y CONFIG_DWMAC_GENERIC=y CONFIG_DWMAC_ROCKCHIP=y +# CONFIG_DWMAC_INTEL_PLAT is not set # CONFIG_NET_VENDOR_SYNOPSYS is not set # CONFIG_NET_VENDOR_VIA is not set # CONFIG_NET_VENDOR_WIZNET is not set # CONFIG_NET_VENDOR_XILINX is not set -CONFIG_MDIO_DEVICE=y -CONFIG_MDIO_BUS=y -CONFIG_MDIO_DEVRES=y -CONFIG_MDIO_BCM_UNIMAC=m -# CONFIG_MDIO_BITBANG is not set -# CONFIG_MDIO_BUS_MUX_GPIO is not set -# CONFIG_MDIO_BUS_MUX_MMIOREG is not set -# CONFIG_MDIO_BUS_MUX_MULTIPLEXER is not set -# CONFIG_MDIO_HISI_FEMAC is not set -# CONFIG_MDIO_IPQ4019 is not set -# CONFIG_MDIO_IPQ8064 is not set -# CONFIG_MDIO_MSCC_MIIM is not set -# CONFIG_MDIO_MVUSB is not set -CONFIG_MDIO_XPCS=y CONFIG_PHYLINK=y CONFIG_PHYLIB=y CONFIG_SWPHY=y # CONFIG_LED_TRIGGER_PHY is not set +CONFIG_FIXED_PHY=y +# CONFIG_SFP is not set # # MII PHY device drivers # -# CONFIG_SFP is not set -# CONFIG_ADIN_PHY is not set # CONFIG_AMD_PHY is not set +# CONFIG_ADIN_PHY is not set # CONFIG_AQUANTIA_PHY is not set # CONFIG_AX88796B_PHY is not set -CONFIG_BCM7XXX_PHY=m -# CONFIG_BCM87XX_PHY is not set -CONFIG_BCM_NET_PHYLIB=m # CONFIG_BROADCOM_PHY is not set # CONFIG_BCM54140_PHY is not set +CONFIG_BCM7XXX_PHY=m # CONFIG_BCM84881_PHY is not set +# CONFIG_BCM87XX_PHY is not set +CONFIG_BCM_NET_PHYLIB=m # CONFIG_CICADA_PHY is not set # CONFIG_CORTINA_PHY is not set # CONFIG_DAVICOM_PHY is not set -# CONFIG_DP83822_PHY is not set -# CONFIG_DP83TC811_PHY is not set -# CONFIG_DP83848_PHY is not set -# CONFIG_DP83867_PHY is not set -# CONFIG_DP83869_PHY is not set -CONFIG_FIXED_PHY=y # CONFIG_ICPLUS_PHY is not set +# CONFIG_LXT_PHY is not set # CONFIG_INTEL_XWAY_PHY is not set # CONFIG_LSI_ET1011C_PHY is not set -# CONFIG_LXT_PHY is not set # CONFIG_MARVELL_PHY is not set # CONFIG_MARVELL_10G_PHY is not set # CONFIG_MICREL_PHY is not set @@ -1470,12 +1445,42 @@ CONFIG_MICROCHIP_PHY=m CONFIG_REALTEK_PHY=y # CONFIG_RENESAS_PHY is not set CONFIG_ROCKCHIP_PHY=y -# CONFIG_SMSC_PHY is not set +CONFIG_SMSC_PHY=m # CONFIG_STE10XP is not set # CONFIG_TERANETICS_PHY is not set +# CONFIG_DP83822_PHY is not set +# CONFIG_DP83TC811_PHY is not set +# CONFIG_DP83848_PHY is not set +# CONFIG_DP83867_PHY is not set +# CONFIG_DP83869_PHY is not set # CONFIG_VITESSE_PHY is not set # CONFIG_XILINX_GMII2RGMII is not set # CONFIG_MICREL_KS8995MA is not set +CONFIG_MDIO_DEVICE=y +CONFIG_MDIO_BUS=y +CONFIG_OF_MDIO=y +CONFIG_MDIO_DEVRES=y +# CONFIG_MDIO_BITBANG is not set +CONFIG_MDIO_BCM_UNIMAC=m +# CONFIG_MDIO_HISI_FEMAC is not set +# CONFIG_MDIO_MVUSB is not set +# CONFIG_MDIO_MSCC_MIIM is not set +# CONFIG_MDIO_IPQ4019 is not set +# CONFIG_MDIO_IPQ8064 is not set + +# +# MDIO Multiplexers +# +# CONFIG_MDIO_BUS_MUX_GPIO is not set +# CONFIG_MDIO_BUS_MUX_MULTIPLEXER is not set +# CONFIG_MDIO_BUS_MUX_MMIOREG is not set + +# +# PCS device drivers +# +CONFIG_PCS_XPCS=y +# end of PCS device drivers + # CONFIG_PPP is not set # CONFIG_SLIP is not set CONFIG_USB_NET_DRIVERS=y @@ -1900,6 +1905,7 @@ CONFIG_HW_RANDOM=y # CONFIG_HW_RANDOM_VIRTIO is not set CONFIG_HW_RANDOM_OPTEE=m # CONFIG_HW_RANDOM_CCTRNG is not set +# CONFIG_HW_RANDOM_XIPHERA is not set CONFIG_DEVMEM=y # CONFIG_DEVKMEM is not set # CONFIG_RAW_DRIVER is not set @@ -1974,6 +1980,7 @@ CONFIG_I2C_CROS_EC_TUNNEL=m # CONFIG_I2C_STUB is not set CONFIG_I2C_SLAVE=y CONFIG_I2C_SLAVE_EEPROM=y +# CONFIG_I2C_SLAVE_TESTUNIT is not set # CONFIG_I2C_DEBUG_CORE is not set # CONFIG_I2C_DEBUG_ALGO is not set # CONFIG_I2C_DEBUG_BUS is not set @@ -2064,6 +2071,12 @@ CONFIG_PINCTRL_ROCKCHIP=y CONFIG_PINCTRL_PALMAS=y # CONFIG_PINCTRL_RK805 is not set # CONFIG_PINCTRL_OCELOT is not set + +# +# Renesas pinctrl drivers +# +# end of Renesas pinctrl drivers + CONFIG_ARCH_HAVE_CUSTOM_GPIO_H=y CONFIG_GPIOLIB=y CONFIG_GPIOLIB_FASTPATH_LIMIT=512 @@ -2071,6 +2084,8 @@ CONFIG_OF_GPIO=y CONFIG_GPIOLIB_IRQCHIP=y # CONFIG_DEBUG_GPIO is not set # CONFIG_GPIO_SYSFS is not set +CONFIG_GPIO_CDEV=y +CONFIG_GPIO_CDEV_V1=y CONFIG_GPIO_GENERIC=y # @@ -2141,9 +2156,6 @@ CONFIG_GPIO_TPS65910=y # CONFIG_GPIO_AGGREGATOR is not set # CONFIG_GPIO_MOCKUP is not set # CONFIG_W1 is not set -CONFIG_POWER_AVS=y -# CONFIG_QCOM_CPR is not set -CONFIG_ROCKCHIP_IODOMAIN=y # CONFIG_POWER_RESET is not set CONFIG_POWER_SUPPLY=y # CONFIG_POWER_SUPPLY_DEBUG is not set @@ -2158,7 +2170,6 @@ CONFIG_BATTERY_CPCAP=y # CONFIG_BATTERY_DS2780 is not set # CONFIG_BATTERY_DS2781 is not set # CONFIG_BATTERY_DS2782 is not set -# CONFIG_BATTERY_LEGO_EV3 is not set # CONFIG_BATTERY_SBS is not set # CONFIG_CHARGER_SBS is not set # CONFIG_MANAGER_SBS is not set @@ -2184,6 +2195,7 @@ CONFIG_BATTERY_CPCAP=y # CONFIG_CHARGER_BQ24735 is not set # CONFIG_CHARGER_BQ2515X is not set # CONFIG_CHARGER_BQ25890 is not set +# CONFIG_CHARGER_BQ25980 is not set # CONFIG_CHARGER_SMB347 is not set # CONFIG_CHARGER_TPS65090 is not set # CONFIG_CHARGER_TPS65217 is not set @@ -2192,6 +2204,7 @@ CONFIG_BATTERY_CPCAP=y # CONFIG_CHARGER_CROS_USBPD is not set # CONFIG_CHARGER_UCS1002 is not set # CONFIG_CHARGER_BD99954 is not set +# CONFIG_RN5T618_POWER is not set CONFIG_HWMON=y # CONFIG_HWMON_DEBUG_CHIP is not set @@ -2264,6 +2277,7 @@ CONFIG_SENSORS_IIO_HWMON=y # CONFIG_SENSORS_MAX31790 is not set # CONFIG_SENSORS_MCP3021 is not set # CONFIG_SENSORS_TC654 is not set +# CONFIG_SENSORS_MR75203 is not set # CONFIG_SENSORS_ADCXX is not set # CONFIG_SENSORS_LM63 is not set # CONFIG_SENSORS_LM70 is not set @@ -2522,6 +2536,7 @@ CONFIG_MFD_TPS65910=y # CONFIG_MFD_STMFX is not set # CONFIG_MFD_KHADAS_MCU is not set # CONFIG_RAVE_SP_CORE is not set +# CONFIG_MFD_INTEL_M10_BMC is not set # end of Multifunction device drivers CONFIG_REGULATOR=y @@ -2581,8 +2596,11 @@ CONFIG_REGULATOR_PALMAS=y CONFIG_REGULATOR_PWM=y # CONFIG_REGULATOR_QCOM_SPMI is not set # CONFIG_REGULATOR_QCOM_USB_VBUS is not set +# CONFIG_REGULATOR_RASPBERRYPI_TOUCHSCREEN_ATTINY is not set CONFIG_REGULATOR_RK808=y CONFIG_REGULATOR_RN5T618=y +# CONFIG_REGULATOR_RT4801 is not set +# CONFIG_REGULATOR_RTMV20 is not set # CONFIG_REGULATOR_S2MPA01 is not set CONFIG_REGULATOR_S2MPS11=y CONFIG_REGULATOR_S5M8767=y @@ -2660,7 +2678,7 @@ CONFIG_MEDIA_CAMERA_SUPPORT=y # CONFIG_MEDIA_DIGITAL_TV_SUPPORT is not set # CONFIG_MEDIA_RADIO_SUPPORT is not set # CONFIG_MEDIA_SDR_SUPPORT is not set -# CONFIG_MEDIA_PLATFORM_SUPPORT is not set +CONFIG_MEDIA_PLATFORM_SUPPORT=y # CONFIG_MEDIA_TEST_SUPPORT is not set # end of Media device types @@ -2770,6 +2788,11 @@ CONFIG_VIDEOBUF2_V4L2=m CONFIG_VIDEOBUF2_MEMOPS=m CONFIG_VIDEOBUF2_DMA_CONTIG=m CONFIG_VIDEOBUF2_VMALLOC=m +CONFIG_VIDEOBUF2_DMA_SG=m +# CONFIG_V4L_PLATFORM_DRIVERS is not set +CONFIG_V4L_MEM2MEM_DRIVERS=y +# CONFIG_VIDEO_MEM2MEM_DEINTERLACE is not set +CONFIG_VIDEO_ROCKCHIP_RGA=m # end of Media drivers # @@ -3050,6 +3073,7 @@ CONFIG_DRM_PANEL_SIMPLE=y # CONFIG_DRM_PANEL_NEC_NL8048HL11 is not set # CONFIG_DRM_PANEL_NOVATEK_NT35510 is not set # CONFIG_DRM_PANEL_NOVATEK_NT39016 is not set +# CONFIG_DRM_PANEL_MANTIX_MLAF057WE51 is not set # CONFIG_DRM_PANEL_OLIMEX_LCD_OLINUXINO is not set CONFIG_DRM_PANEL_ORISETECH_OTM8009A=m # CONFIG_DRM_PANEL_OSD_OSD101T2587_53TS is not set @@ -3090,6 +3114,7 @@ CONFIG_DRM_PANEL_BRIDGE=y # CONFIG_DRM_CDNS_DSI is not set # CONFIG_DRM_CHRONTEL_CH7033 is not set # CONFIG_DRM_DISPLAY_CONNECTOR is not set +# CONFIG_DRM_LONTIUM_LT9611 is not set # CONFIG_DRM_LVDS_CODEC is not set # CONFIG_DRM_MEGACHIPS_STDPXXXX_GE_B850V3_FW is not set # CONFIG_DRM_NWL_MIPI_DSI is not set @@ -3101,9 +3126,11 @@ CONFIG_DRM_PARADE_PS8622=m CONFIG_DRM_SII9234=m # CONFIG_DRM_SIMPLE_BRIDGE is not set # CONFIG_DRM_THINE_THC63LVD1024 is not set +# CONFIG_DRM_TOSHIBA_TC358762 is not set # CONFIG_DRM_TOSHIBA_TC358764 is not set # CONFIG_DRM_TOSHIBA_TC358767 is not set # CONFIG_DRM_TOSHIBA_TC358768 is not set +# CONFIG_DRM_TOSHIBA_TC358775 is not set # CONFIG_DRM_TI_TFP410 is not set # CONFIG_DRM_TI_SN65DSI86 is not set # CONFIG_DRM_TI_TPD12S015 is not set @@ -3112,6 +3139,7 @@ CONFIG_DRM_SII9234=m CONFIG_DRM_I2C_ADV7511=m CONFIG_DRM_I2C_ADV7511_AUDIO=y CONFIG_DRM_I2C_ADV7511_CEC=y +# CONFIG_DRM_CDNS_MHDP8546 is not set CONFIG_DRM_DW_HDMI=y # CONFIG_DRM_DW_HDMI_AHB_AUDIO is not set CONFIG_DRM_DW_HDMI_I2S_AUDIO=y @@ -3182,6 +3210,7 @@ CONFIG_FB_MODE_HELPERS=y # # CONFIG_LCD_CLASS_DEVICE is not set CONFIG_BACKLIGHT_CLASS_DEVICE=y +# CONFIG_BACKLIGHT_KTD253 is not set CONFIG_BACKLIGHT_PWM=y # CONFIG_BACKLIGHT_QCOM_WLED is not set # CONFIG_BACKLIGHT_ADP8860 is not set @@ -3345,6 +3374,7 @@ CONFIG_SND_SOC_CPCAP=m # CONFIG_SND_SOC_CS42L52 is not set # CONFIG_SND_SOC_CS42L56 is not set # CONFIG_SND_SOC_CS42L73 is not set +# CONFIG_SND_SOC_CS4234 is not set # CONFIG_SND_SOC_CS4265 is not set # CONFIG_SND_SOC_CS4270 is not set # CONFIG_SND_SOC_CS4271_I2C is not set @@ -3407,6 +3437,7 @@ CONFIG_SND_SOC_SPDIF=m CONFIG_SND_SOC_STI_SAS=m # CONFIG_SND_SOC_TAS2552 is not set # CONFIG_SND_SOC_TAS2562 is not set +# CONFIG_SND_SOC_TAS2764 is not set # CONFIG_SND_SOC_TAS2770 is not set # CONFIG_SND_SOC_TAS5086 is not set # CONFIG_SND_SOC_TAS571X is not set @@ -3507,6 +3538,7 @@ CONFIG_HID_GENERIC=y # CONFIG_HID_GLORIOUS is not set # CONFIG_HID_HOLTEK is not set # CONFIG_HID_GOOGLE_HAMMER is not set +# CONFIG_HID_VIVALDI is not set # CONFIG_HID_GT683R is not set # CONFIG_HID_KEYTOUCH is not set # CONFIG_HID_KYE is not set @@ -3533,7 +3565,6 @@ CONFIG_HID_GENERIC=y # CONFIG_HID_NTI is not set # CONFIG_HID_NTRIG is not set # CONFIG_HID_ORTEK is not set -# CONFIG_HID_OUYA is not set # CONFIG_HID_PANTHERLORD is not set # CONFIG_HID_PENMOUNT is not set # CONFIG_HID_PETALYNX is not set @@ -3597,6 +3628,7 @@ CONFIG_USB_ANNOUNCE_NEW_DEVICES=y # Miscellaneous USB options # CONFIG_USB_DEFAULT_PERSIST=y +# CONFIG_USB_FEW_INIT_RETRIES is not set # CONFIG_USB_DYNAMIC_MINORS is not set CONFIG_USB_OTG=y # CONFIG_USB_OTG_PRODUCTLIST is not set @@ -3693,6 +3725,7 @@ CONFIG_USB_DWC3_DUAL_ROLE=y # Platform Glue Driver Support # CONFIG_USB_DWC3_OF_SIMPLE=y +CONFIG_USB_DWC3_ROCKCHIP_INNO=y CONFIG_USB_DWC2=y # CONFIG_USB_DWC2_HOST is not set @@ -3929,6 +3962,7 @@ CONFIG_LEDS_CPCAP=m CONFIG_LEDS_GPIO=y # CONFIG_LEDS_LP3944 is not set # CONFIG_LEDS_LP3952 is not set +# CONFIG_LEDS_LP50XX is not set # CONFIG_LEDS_LP55XX_COMMON is not set # CONFIG_LEDS_LP8860 is not set # CONFIG_LEDS_PCA955X is not set @@ -4045,6 +4079,7 @@ CONFIG_RTC_DRV_RX8581=m # CONFIG_RTC_DRV_RX8025 is not set CONFIG_RTC_DRV_EM3027=y # CONFIG_RTC_DRV_RV3028 is not set +# CONFIG_RTC_DRV_RV3032 is not set # CONFIG_RTC_DRV_RV8803 is not set CONFIG_RTC_DRV_S5M=m # CONFIG_RTC_DRV_SD3078 is not set @@ -4166,8 +4201,6 @@ CONFIG_VIRTIO_MENU=y CONFIG_VIRTIO_MMIO=y # CONFIG_VIRTIO_MMIO_CMDLINE_DEVICES is not set # CONFIG_VDPA is not set -CONFIG_VHOST_IOTLB=y -CONFIG_VHOST_RING=y CONFIG_VHOST_MENU=y # CONFIG_VHOST_NET is not set # CONFIG_VHOST_CROSS_ENDIAN_LEGACY is not set @@ -4248,7 +4281,6 @@ CONFIG_STAGING_MEDIA=y CONFIG_VIDEO_HANTRO=m CONFIG_VIDEO_HANTRO_ROCKCHIP=y CONFIG_VIDEO_ROCKCHIP_VDEC=m -# CONFIG_PHY_ROCKCHIP_DPHY_RX0 is not set # CONFIG_VIDEO_ROCKCHIP_ISP1 is not set # @@ -4272,8 +4304,9 @@ CONFIG_VIDEO_ROCKCHIP_VDEC=m # CONFIG_XIL_AXIS_FIFO is not set # CONFIG_FIELDBUS_DEV is not set # CONFIG_WFX is not set +# CONFIG_SPMI_HISI3670 is not set +# CONFIG_MFD_HI6421_SPMI is not set # CONFIG_GOLDFISH is not set -CONFIG_MFD_CROS_EC=m CONFIG_CHROME_PLATFORMS=y CONFIG_CROS_EC=m # CONFIG_CROS_EC_I2C is not set @@ -4292,7 +4325,6 @@ CONFIG_HAVE_CLK=y CONFIG_CLKDEV_LOOKUP=y CONFIG_HAVE_CLK_PREPARE=y CONFIG_COMMON_CLK=y -# CONFIG_CLK_HSDK is not set CONFIG_COMMON_CLK_MAX77686=y # CONFIG_COMMON_CLK_MAX9485 is not set CONFIG_COMMON_CLK_RK808=y @@ -4313,17 +4345,12 @@ CONFIG_CLK_QORIQ=y # CONFIG_COMMON_CLK_VC5 is not set # CONFIG_COMMON_CLK_FIXED_MMIO is not set CONFIG_COMMON_CLK_ROCKCHIP=y -CONFIG_CLK_PX30=y CONFIG_CLK_RV110X=y CONFIG_CLK_RK3036=y CONFIG_CLK_RK312X=y CONFIG_CLK_RK3188=y CONFIG_CLK_RK322X=y CONFIG_CLK_RK3288=y -CONFIG_CLK_RK3308=y -CONFIG_CLK_RK3328=y -CONFIG_CLK_RK3368=y -CONFIG_CLK_RK3399=y # CONFIG_HWSPINLOCK is not set # @@ -4422,6 +4449,7 @@ CONFIG_RPMSG_VIRTIO=m # end of Qualcomm SoC drivers CONFIG_ROCKCHIP_GRF=y +CONFIG_ROCKCHIP_IODOMAIN=y CONFIG_ROCKCHIP_PM_DOMAINS=y # CONFIG_SOC_TI is not set @@ -4471,6 +4499,8 @@ CONFIG_EXTCON=y CONFIG_IIO=y CONFIG_IIO_BUFFER=y CONFIG_IIO_BUFFER_CB=m +# CONFIG_IIO_BUFFER_DMA is not set +# CONFIG_IIO_BUFFER_DMAENGINE is not set # CONFIG_IIO_BUFFER_HW_CONSUMER is not set CONFIG_IIO_KFIFO_BUF=y CONFIG_IIO_TRIGGERED_BUFFER=y @@ -4479,6 +4509,7 @@ CONFIG_IIO_TRIGGER=y CONFIG_IIO_CONSUMERS_PER_TRIGGER=2 # CONFIG_IIO_SW_DEVICE is not set CONFIG_IIO_SW_TRIGGER=y +# CONFIG_IIO_TRIGGERED_EVENT is not set # # Accelerometers @@ -4695,6 +4726,7 @@ CONFIG_VF610_ADC=m # CONFIG_ADIS16130 is not set # CONFIG_ADIS16136 is not set # CONFIG_ADIS16260 is not set +# CONFIG_ADXRS290 is not set # CONFIG_ADXRS450 is not set # CONFIG_BMG160 is not set # CONFIG_FXAS21002C is not set @@ -4724,6 +4756,7 @@ CONFIG_MPU3050_I2C=y # CONFIG_AM2315 is not set # CONFIG_DHT11 is not set # CONFIG_HDC100X is not set +# CONFIG_HDC2010 is not set # CONFIG_HTS221 is not set # CONFIG_HTU21 is not set # CONFIG_SI7005 is not set @@ -4758,6 +4791,7 @@ CONFIG_MPU3050_I2C=y # CONFIG_AL3320A is not set # CONFIG_APDS9300 is not set # CONFIG_APDS9960 is not set +# CONFIG_AS73211 is not set # CONFIG_BH1750 is not set # CONFIG_BH1780 is not set # CONFIG_CM32181 is not set @@ -4955,6 +4989,7 @@ CONFIG_RESET_SCMI=y # PHY Subsystem # CONFIG_GENERIC_PHY=y +# CONFIG_USB_LGM_PHY is not set # CONFIG_BCM_KONA_USB2_PHY is not set # CONFIG_PHY_CADENCE_TORRENT is not set # CONFIG_PHY_CADENCE_DPHY is not set @@ -4970,9 +5005,11 @@ CONFIG_GENERIC_PHY=y # CONFIG_PHY_QCOM_USB_HS is not set # CONFIG_PHY_QCOM_USB_HSIC is not set CONFIG_PHY_ROCKCHIP_DP=m +# CONFIG_PHY_ROCKCHIP_DPHY_RX0 is not set CONFIG_PHY_ROCKCHIP_EMMC=m CONFIG_PHY_ROCKCHIP_INNO_HDMI=m CONFIG_PHY_ROCKCHIP_INNO_USB2=m +# CONFIG_PHY_ROCKCHIP_INNO_USB3 is not set # CONFIG_PHY_ROCKCHIP_INNO_DSIDPHY is not set # CONFIG_PHY_ROCKCHIP_PCIE is not set # CONFIG_PHY_ROCKCHIP_TYPEC is not set @@ -5214,6 +5251,7 @@ CONFIG_ROOT_NFS=y # CONFIG_NFS_USE_LEGACY_DNS is not set CONFIG_NFS_USE_KERNEL_DNS=y CONFIG_NFS_DISABLE_UDP_SUPPORT=y +# CONFIG_NFS_V4_2_READ_PLUS is not set # CONFIG_NFSD is not set CONFIG_GRACE_PERIOD=y CONFIG_LOCKD=y @@ -5224,7 +5262,15 @@ CONFIG_SUNRPC_GSS=y CONFIG_SUNRPC_BACKCHANNEL=y # CONFIG_SUNRPC_DEBUG is not set # CONFIG_CEPH_FS is not set -# CONFIG_CIFS is not set +CONFIG_CIFS=y +CONFIG_CIFS_STATS2=y +CONFIG_CIFS_ALLOW_INSECURE_LEGACY=y +# CONFIG_CIFS_WEAK_PW_HASH is not set +# CONFIG_CIFS_UPCALL is not set +# CONFIG_CIFS_XATTR is not set +# CONFIG_CIFS_DEBUG is not set +# CONFIG_CIFS_DFS_UPCALL is not set +# CONFIG_CIFS_ROOT is not set # CONFIG_CODA_FS is not set # CONFIG_AFS_FS is not set CONFIG_NLS=y @@ -5323,9 +5369,9 @@ CONFIG_CRYPTO=y # CONFIG_CRYPTO_ALGAPI=y CONFIG_CRYPTO_ALGAPI2=y -CONFIG_CRYPTO_AEAD=m +CONFIG_CRYPTO_AEAD=y CONFIG_CRYPTO_AEAD2=y -CONFIG_CRYPTO_SKCIPHER=m +CONFIG_CRYPTO_SKCIPHER=y CONFIG_CRYPTO_SKCIPHER2=y CONFIG_CRYPTO_HASH=y CONFIG_CRYPTO_HASH2=y @@ -5341,8 +5387,8 @@ CONFIG_CRYPTO_MANAGER=y CONFIG_CRYPTO_MANAGER2=y CONFIG_CRYPTO_USER=m CONFIG_CRYPTO_MANAGER_DISABLE_TESTS=y -CONFIG_CRYPTO_GF128MUL=m -CONFIG_CRYPTO_NULL=m +CONFIG_CRYPTO_GF128MUL=y +CONFIG_CRYPTO_NULL=y CONFIG_CRYPTO_NULL2=y # CONFIG_CRYPTO_PCRYPT is not set # CONFIG_CRYPTO_CRYPTD is not set @@ -5358,13 +5404,14 @@ CONFIG_CRYPTO_RSA=y CONFIG_CRYPTO_ECC=m CONFIG_CRYPTO_ECDH=m # CONFIG_CRYPTO_ECRDSA is not set +# CONFIG_CRYPTO_SM2 is not set CONFIG_CRYPTO_CURVE25519=m # # Authenticated Encryption with Associated Data # -CONFIG_CRYPTO_CCM=m -CONFIG_CRYPTO_GCM=m +CONFIG_CRYPTO_CCM=y +CONFIG_CRYPTO_GCM=y # CONFIG_CRYPTO_CHACHA20POLY1305 is not set # CONFIG_CRYPTO_AEGIS128 is not set CONFIG_CRYPTO_SEQIV=m @@ -5375,9 +5422,9 @@ CONFIG_CRYPTO_ECHAINIV=m # CONFIG_CRYPTO_CBC=m # CONFIG_CRYPTO_CFB is not set -CONFIG_CRYPTO_CTR=m +CONFIG_CRYPTO_CTR=y # CONFIG_CRYPTO_CTS is not set -CONFIG_CRYPTO_ECB=m +CONFIG_CRYPTO_ECB=y # CONFIG_CRYPTO_LRW is not set # CONFIG_CRYPTO_OFB is not set # CONFIG_CRYPTO_PCBC is not set @@ -5389,8 +5436,8 @@ CONFIG_CRYPTO_ECB=m # # Hash modes # -CONFIG_CRYPTO_CMAC=m -CONFIG_CRYPTO_HMAC=m +CONFIG_CRYPTO_CMAC=y +CONFIG_CRYPTO_HMAC=y # CONFIG_CRYPTO_XCBC is not set # CONFIG_CRYPTO_VMAC is not set @@ -5403,18 +5450,18 @@ CONFIG_CRYPTO_XXHASH=m CONFIG_CRYPTO_BLAKE2B=m CONFIG_CRYPTO_BLAKE2S=m # CONFIG_CRYPTO_CRCT10DIF is not set -CONFIG_CRYPTO_GHASH=m +CONFIG_CRYPTO_GHASH=y # CONFIG_CRYPTO_POLY1305 is not set -# CONFIG_CRYPTO_MD4 is not set -CONFIG_CRYPTO_MD5=m +CONFIG_CRYPTO_MD4=y +CONFIG_CRYPTO_MD5=y # CONFIG_CRYPTO_MICHAEL_MIC is not set # CONFIG_CRYPTO_RMD128 is not set # CONFIG_CRYPTO_RMD160 is not set # CONFIG_CRYPTO_RMD256 is not set # CONFIG_CRYPTO_RMD320 is not set CONFIG_CRYPTO_SHA1=y -CONFIG_CRYPTO_SHA256=m -# CONFIG_CRYPTO_SHA512 is not set +CONFIG_CRYPTO_SHA256=y +CONFIG_CRYPTO_SHA512=y # CONFIG_CRYPTO_SHA3 is not set # CONFIG_CRYPTO_SM3 is not set # CONFIG_CRYPTO_STREEBOG is not set @@ -5467,7 +5514,9 @@ CONFIG_CRYPTO_USER_API=m CONFIG_CRYPTO_USER_API_HASH=m CONFIG_CRYPTO_USER_API_SKCIPHER=m CONFIG_CRYPTO_USER_API_RNG=m +# CONFIG_CRYPTO_USER_API_RNG_CAVP is not set CONFIG_CRYPTO_USER_API_AEAD=m +CONFIG_CRYPTO_USER_API_ENABLE_OBSOLETE=y # CONFIG_CRYPTO_STATS is not set CONFIG_CRYPTO_HASH_INFO=y @@ -5475,19 +5524,19 @@ CONFIG_CRYPTO_HASH_INFO=y # Crypto library routines # CONFIG_CRYPTO_LIB_AES=y -CONFIG_CRYPTO_LIB_ARC4=m +CONFIG_CRYPTO_LIB_ARC4=y CONFIG_CRYPTO_LIB_BLAKE2S_GENERIC=m CONFIG_CRYPTO_LIB_BLAKE2S=m CONFIG_CRYPTO_ARCH_HAVE_LIB_CHACHA=m CONFIG_CRYPTO_LIB_CHACHA=m CONFIG_CRYPTO_LIB_CURVE25519_GENERIC=m CONFIG_CRYPTO_LIB_CURVE25519=m -CONFIG_CRYPTO_LIB_DES=m +CONFIG_CRYPTO_LIB_DES=y CONFIG_CRYPTO_LIB_POLY1305_RSIZE=9 CONFIG_CRYPTO_ARCH_HAVE_LIB_POLY1305=m CONFIG_CRYPTO_LIB_POLY1305=m CONFIG_CRYPTO_LIB_CHACHA20POLY1305=m -CONFIG_CRYPTO_LIB_SHA256=m +CONFIG_CRYPTO_LIB_SHA256=y CONFIG_CRYPTO_HW=y # CONFIG_CRYPTO_DEV_ATMEL_ECC is not set # CONFIG_CRYPTO_DEV_ATMEL_SHA204A is not set @@ -5584,6 +5633,7 @@ CONFIG_ARCH_HAS_TEARDOWN_DMA_OPS=y CONFIG_DMA_NONCOHERENT_MMAP=y CONFIG_DMA_REMAP=y CONFIG_DMA_CMA=y +# CONFIG_DMA_PERNUMA_CMA is not set # # Default contiguous memory area size: @@ -5740,6 +5790,7 @@ CONFIG_LOCK_DEBUGGING_SUPPORT=y # CONFIG_DEBUG_LOCKING_API_SELFTESTS is not set # CONFIG_LOCK_TORTURE_TEST is not set # CONFIG_WW_MUTEX_SELFTEST is not set +# CONFIG_SCF_TORTURE_TEST is not set # end of Lock Debugging (spinlocks, mutexes, etc...) CONFIG_STACKTRACE=y @@ -5761,7 +5812,7 @@ CONFIG_STACKTRACE=y # # RCU Debugging # -# CONFIG_RCU_PERF_TEST is not set +# CONFIG_RCU_SCALE_TEST is not set # CONFIG_RCU_TORTURE_TEST is not set # CONFIG_RCU_REF_SCALE_TEST is not set CONFIG_RCU_CPU_STALL_TIMEOUT=21 @@ -5857,7 +5908,6 @@ CONFIG_RUNTIME_TESTING_MENU=y # CONFIG_TEST_KSTRTOX is not set # CONFIG_TEST_PRINTF is not set # CONFIG_TEST_BITMAP is not set -# CONFIG_TEST_BITFIELD is not set # CONFIG_TEST_UUID is not set # CONFIG_TEST_XARRAY is not set # CONFIG_TEST_OVERFLOW is not set @@ -5879,6 +5929,7 @@ CONFIG_RUNTIME_TESTING_MENU=y # CONFIG_TEST_MEMCAT_P is not set # CONFIG_TEST_STACKINIT is not set # CONFIG_TEST_MEMINIT is not set +# CONFIG_TEST_FREE_PAGES is not set # CONFIG_MEMTEST is not set # end of Kernel Testing and Coverage # end of Kernel hacking diff --git a/projects/Rockchip/devices/RK3328/linux/default/linux.aarch64.conf b/projects/Rockchip/devices/RK3328/linux/default/linux.aarch64.conf index 7dc6d65508..5e6fa3289b 100644 --- a/projects/Rockchip/devices/RK3328/linux/default/linux.aarch64.conf +++ b/projects/Rockchip/devices/RK3328/linux/default/linux.aarch64.conf @@ -1,19 +1,7 @@ # # Automatically generated file; DO NOT EDIT. -# Linux/arm64 5.9.0 Kernel Configuration +# Linux/arm64 5.10.4 Kernel Configuration # -CONFIG_CC_VERSION_TEXT="aarch64-none-linux-gnu-gcc-9.2.1 (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 -CONFIG_BUILDTIME_TABLE_SORT=y -CONFIG_THREAD_INFO_IN_TASK=y # # General setup @@ -48,6 +36,7 @@ CONFIG_HARDIRQS_SW_RESEND=y CONFIG_GENERIC_IRQ_CHIP=y CONFIG_IRQ_DOMAIN=y CONFIG_IRQ_DOMAIN_HIERARCHY=y +CONFIG_GENERIC_IRQ_IPI=y CONFIG_GENERIC_MSI_IRQ=y CONFIG_GENERIC_MSI_IRQ_DOMAIN=y CONFIG_IRQ_MSI_IOMMU=y @@ -105,6 +94,8 @@ CONFIG_TREE_RCU=y # CONFIG_RCU_EXPERT is not set CONFIG_SRCU=y CONFIG_TREE_SRCU=y +CONFIG_TASKS_RCU_GENERIC=y +CONFIG_TASKS_TRACE_RCU=y CONFIG_RCU_STALL_COMMON=y CONFIG_RCU_NEED_SEGCBLIST=y # end of RCU Subsystem @@ -177,6 +168,7 @@ CONFIG_INITRAMFS_COMPRESSION_LZ4=y # CONFIG_BOOT_CONFIG is not set CONFIG_CC_OPTIMIZE_FOR_PERFORMANCE=y # CONFIG_CC_OPTIMIZE_FOR_SIZE is not set +CONFIG_LD_ORPHAN_WARN=y CONFIG_SYSCTL=y CONFIG_HAVE_UID16=y CONFIG_SYSCTL_EXCEPTION_TRACE=y @@ -211,6 +203,7 @@ CONFIG_BPF_SYSCALL=y CONFIG_ARCH_WANT_DEFAULT_BPF_JIT=y # CONFIG_BPF_JIT_ALWAYS_ON is not set CONFIG_BPF_JIT_DEFAULT_ON=y +# CONFIG_BPF_PRELOAD is not set # CONFIG_USERFAULTFD is not set CONFIG_ARCH_HAS_MEMBARRIER_SYNC_CORE=y CONFIG_RSEQ=y @@ -242,7 +235,8 @@ CONFIG_ARM64=y CONFIG_64BIT=y CONFIG_MMU=y CONFIG_ARM64_PAGE_SHIFT=12 -CONFIG_ARM64_CONT_SHIFT=4 +CONFIG_ARM64_CONT_PTE_SHIFT=4 +CONFIG_ARM64_CONT_PMD_SHIFT=4 CONFIG_ARCH_MMAP_RND_BITS_MIN=18 CONFIG_ARCH_MMAP_RND_BITS_MAX=33 CONFIG_ARCH_MMAP_RND_COMPAT_BITS_MIN=11 @@ -305,6 +299,7 @@ CONFIG_ARCH_ROCKCHIP=y # CONFIG_ARCH_THUNDER2 is not set # CONFIG_ARCH_UNIPHIER is not set # CONFIG_ARCH_VEXPRESS is not set +# CONFIG_ARCH_VISCONTI is not set # CONFIG_ARCH_XGENE is not set # CONFIG_ARCH_ZX is not set # CONFIG_ARCH_ZYNQMP is not set @@ -335,6 +330,7 @@ CONFIG_ARM64_WORKAROUND_REPEAT_TLBI=y CONFIG_ARM64_ERRATUM_1286807=y CONFIG_ARM64_ERRATUM_1463225=y CONFIG_ARM64_ERRATUM_1542419=y +CONFIG_ARM64_ERRATUM_1508412=y CONFIG_CAVIUM_ERRATUM_22375=y CONFIG_CAVIUM_ERRATUM_23154=y CONFIG_CAVIUM_ERRATUM_27456=y @@ -382,7 +378,6 @@ CONFIG_SYS_SUPPORTS_HUGETLBFS=y CONFIG_ARCH_WANT_HUGE_PMD_SHARE=y CONFIG_ARCH_HAS_CACHE_LINE_SIZE=y CONFIG_ARCH_ENABLE_SPLIT_PMD_PTLOCK=y -CONFIG_SECCOMP=y # CONFIG_PARAVIRT is not set # CONFIG_PARAVIRT_TIME_ACCOUNTING is not set # CONFIG_KEXEC is not set @@ -391,8 +386,6 @@ CONFIG_SECCOMP=y # CONFIG_XEN is not set CONFIG_FORCE_MAX_ZONEORDER=11 CONFIG_UNMAP_KERNEL_AT_EL0=y -CONFIG_HARDEN_BRANCH_PREDICTOR=y -CONFIG_ARM64_SSBD=y CONFIG_RODATA_FULL_DEFAULT_ENABLED=y # CONFIG_ARM64_SW_TTBR0_PAN is not set CONFIG_ARM64_TAGGED_ADDR_ABI=y @@ -444,6 +437,8 @@ CONFIG_ARM64_BTI=y CONFIG_CC_HAS_BRANCH_PROT_PAC_RET_BTI=y CONFIG_ARM64_E0PD=y CONFIG_ARCH_RANDOM=y +CONFIG_ARM64_AS_HAS_MTE=y +CONFIG_ARM64_MTE=y # end of ARMv8.5 architectural features CONFIG_ARM64_SVE=y @@ -464,6 +459,7 @@ CONFIG_CMDLINE="" CONFIG_SYSVIPC_COMPAT=y CONFIG_ARCH_ENABLE_HUGEPAGE_MIGRATION=y +CONFIG_ARCH_ENABLE_THP_MIGRATION=y # # Power management options @@ -548,7 +544,6 @@ CONFIG_ARM_SCPI_PROTOCOL=y CONFIG_ARM_SCPI_POWER_DOMAIN=y # CONFIG_ARM_SDE_INTERFACE is not set # CONFIG_GOOGLE_FIRMWARE is not set -CONFIG_EFI_EARLYCON=y CONFIG_ARM_PSCI_FW=y # CONFIG_ARM_PSCI_CHECKER is not set CONFIG_HAVE_ARM_SMCCC=y @@ -585,6 +580,7 @@ CONFIG_CRYPTO_AES_ARM64_BS=m # # General architecture-dependent options # +CONFIG_SET_FS=y # CONFIG_KPROBES is not set CONFIG_JUMP_LABEL=y # CONFIG_STATIC_KEYS_SELFTEST is not set @@ -618,7 +614,9 @@ CONFIG_HAVE_ALIGNED_STRUCT_PAGE=y CONFIG_HAVE_CMPXCHG_LOCAL=y CONFIG_HAVE_CMPXCHG_DOUBLE=y CONFIG_ARCH_WANT_COMPAT_IPC_PARSE_VERSION=y +CONFIG_HAVE_ARCH_SECCOMP=y CONFIG_HAVE_ARCH_SECCOMP_FILTER=y +CONFIG_SECCOMP=y CONFIG_SECCOMP_FILTER=y CONFIG_HAVE_ARCH_STACKLEAK=y CONFIG_HAVE_STACKPROTECTOR=y @@ -627,6 +625,7 @@ CONFIG_STACKPROTECTOR_STRONG=y CONFIG_HAVE_CONTEXT_TRACKING=y CONFIG_HAVE_VIRT_CPU_ACCOUNTING_GEN=y CONFIG_HAVE_IRQ_TIME_ACCOUNTING=y +CONFIG_HAVE_MOVE_PMD=y CONFIG_HAVE_ARCH_TRANSPARENT_HUGEPAGE=y CONFIG_HAVE_ARCH_HUGE_VMAP=y CONFIG_HAVE_MOD_ARCH_SPECIFIC=y @@ -649,9 +648,9 @@ CONFIG_ARCH_HAS_STRICT_MODULE_RWX=y CONFIG_STRICT_MODULE_RWX=y 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 +CONFIG_ARCH_WANT_LD_ORPHAN_WARN=y # # GCOV-based kernel profiling @@ -661,7 +660,10 @@ CONFIG_ARCH_HAS_GCOV_PROFILE_ALL=y # end of GCOV-based kernel profiling CONFIG_HAVE_GCC_PLUGINS=y -# CONFIG_GCC_PLUGINS is not set +CONFIG_GCC_PLUGINS=y +# CONFIG_GCC_PLUGIN_LATENT_ENTROPY is not set +CONFIG_GCC_PLUGIN_RANDSTRUCT=y +# CONFIG_GCC_PLUGIN_RANDSTRUCT_PERFORMANCE is not set # end of General architecture-dependent options CONFIG_RT_MUTEXES=y @@ -670,7 +672,8 @@ CONFIG_MODULES=y # CONFIG_MODULE_FORCE_LOAD is not set CONFIG_MODULE_UNLOAD=y # CONFIG_MODULE_FORCE_UNLOAD is not set -# CONFIG_MODVERSIONS is not set +CONFIG_MODVERSIONS=y +CONFIG_ASM_MODVERSIONS=y # CONFIG_MODULE_SRCVERSION_ALL is not set # CONFIG_MODULE_SIG is not set # CONFIG_MODULE_COMPRESS is not set @@ -837,6 +840,7 @@ CONFIG_GENERIC_EARLY_IOREMAP=y # CONFIG_IDLE_PAGE_TRACKING is not set CONFIG_ARCH_HAS_PTE_DEVMAP=y CONFIG_FRAME_VECTOR=y +CONFIG_ARCH_USES_HIGH_VMA_FLAGS=y # CONFIG_PERCPU_STATS is not set # CONFIG_GUP_BENCHMARK is not set # CONFIG_READ_ONLY_THP_FOR_FS is not set @@ -1392,6 +1396,11 @@ CONFIG_MTD_CFI_I2=y # CONFIG_MTD_ONENAND is not set # CONFIG_MTD_RAW_NAND is not set # CONFIG_MTD_SPI_NAND is not set + +# +# ECC engine support +# +# end of ECC engine support # end of NAND # @@ -1414,7 +1423,6 @@ CONFIG_OF_DYNAMIC=y CONFIG_OF_ADDRESS=y CONFIG_OF_IRQ=y CONFIG_OF_NET=y -CONFIG_OF_MDIO=y CONFIG_OF_RESERVED_MEM=y CONFIG_OF_RESOLVE=y CONFIG_OF_OVERLAY=y @@ -1458,6 +1466,7 @@ CONFIG_VIRTIO_BLK=y CONFIG_SRAM=y # CONFIG_XILINX_SDFEC is not set # CONFIG_PVPANIC is not set +# CONFIG_HISI_HIKEY_USB is not set # CONFIG_C2PORT is not set # @@ -1482,14 +1491,6 @@ CONFIG_EEPROM_93CX6=m # CONFIG_SENSORS_LIS3_SPI is not set # CONFIG_SENSORS_LIS3_I2C is not set # CONFIG_ALTERA_STAPL is not set - -# -# Intel MIC & related support -# -CONFIG_VOP_BUS=y -CONFIG_VOP=y -# end of Intel MIC & related support - # CONFIG_ECHO is not set # CONFIG_MISC_RTSX_USB is not set # CONFIG_UACCE is not set @@ -1613,58 +1614,37 @@ CONFIG_STMMAC_PLATFORM=y CONFIG_DWMAC_DWC_QOS_ETH=y CONFIG_DWMAC_GENERIC=y CONFIG_DWMAC_ROCKCHIP=y +# CONFIG_DWMAC_INTEL_PLAT is not set # CONFIG_NET_VENDOR_SYNOPSYS is not set # CONFIG_NET_VENDOR_VIA is not set # CONFIG_NET_VENDOR_WIZNET is not set # CONFIG_NET_VENDOR_XILINX is not set -CONFIG_MDIO_DEVICE=y -CONFIG_MDIO_BUS=y -CONFIG_MDIO_DEVRES=y -# CONFIG_MDIO_BCM_UNIMAC is not set -CONFIG_MDIO_BITBANG=y -CONFIG_MDIO_BUS_MUX=y -CONFIG_MDIO_BUS_MUX_GPIO=y -CONFIG_MDIO_BUS_MUX_MMIOREG=y -CONFIG_MDIO_BUS_MUX_MULTIPLEXER=y -CONFIG_MDIO_GPIO=y -# CONFIG_MDIO_HISI_FEMAC is not set -# CONFIG_MDIO_IPQ4019 is not set -# CONFIG_MDIO_IPQ8064 is not set -# CONFIG_MDIO_MSCC_MIIM is not set -# CONFIG_MDIO_MVUSB is not set -# CONFIG_MDIO_OCTEON is not set -CONFIG_MDIO_XPCS=y CONFIG_PHYLINK=y CONFIG_PHYLIB=y CONFIG_SWPHY=y # CONFIG_LED_TRIGGER_PHY is not set +CONFIG_FIXED_PHY=y +# CONFIG_SFP is not set # # MII PHY device drivers # -# CONFIG_SFP is not set -# CONFIG_ADIN_PHY is not set # CONFIG_AMD_PHY is not set +# CONFIG_ADIN_PHY is not set # CONFIG_AQUANTIA_PHY is not set # CONFIG_AX88796B_PHY is not set -# CONFIG_BCM7XXX_PHY is not set -# CONFIG_BCM87XX_PHY is not set # CONFIG_BROADCOM_PHY is not set # CONFIG_BCM54140_PHY is not set +# CONFIG_BCM7XXX_PHY is not set # CONFIG_BCM84881_PHY is not set +# CONFIG_BCM87XX_PHY is not set # CONFIG_CICADA_PHY is not set # CONFIG_CORTINA_PHY is not set # CONFIG_DAVICOM_PHY is not set -# CONFIG_DP83822_PHY is not set -# CONFIG_DP83TC811_PHY is not set -# CONFIG_DP83848_PHY is not set -# CONFIG_DP83867_PHY is not set -# CONFIG_DP83869_PHY is not set -CONFIG_FIXED_PHY=y # CONFIG_ICPLUS_PHY is not set +# CONFIG_LXT_PHY is not set # CONFIG_INTEL_XWAY_PHY is not set # CONFIG_LSI_ET1011C_PHY is not set -# CONFIG_LXT_PHY is not set # CONFIG_MARVELL_PHY is not set # CONFIG_MARVELL_10G_PHY is not set # CONFIG_MICREL_PHY is not set @@ -1678,12 +1658,45 @@ CONFIG_MICROCHIP_PHY=m CONFIG_REALTEK_PHY=y # CONFIG_RENESAS_PHY is not set CONFIG_ROCKCHIP_PHY=y -# CONFIG_SMSC_PHY is not set +CONFIG_SMSC_PHY=m # CONFIG_STE10XP is not set # CONFIG_TERANETICS_PHY is not set +# CONFIG_DP83822_PHY is not set +# CONFIG_DP83TC811_PHY is not set +# CONFIG_DP83848_PHY is not set +# CONFIG_DP83867_PHY is not set +# CONFIG_DP83869_PHY is not set # CONFIG_VITESSE_PHY is not set # CONFIG_XILINX_GMII2RGMII is not set # CONFIG_MICREL_KS8995MA is not set +CONFIG_MDIO_DEVICE=y +CONFIG_MDIO_BUS=y +CONFIG_OF_MDIO=y +CONFIG_MDIO_DEVRES=y +CONFIG_MDIO_BITBANG=y +# CONFIG_MDIO_BCM_UNIMAC is not set +CONFIG_MDIO_GPIO=y +# CONFIG_MDIO_HISI_FEMAC is not set +# CONFIG_MDIO_MVUSB is not set +# CONFIG_MDIO_MSCC_MIIM is not set +# CONFIG_MDIO_OCTEON is not set +# CONFIG_MDIO_IPQ4019 is not set +# CONFIG_MDIO_IPQ8064 is not set + +# +# MDIO Multiplexers +# +CONFIG_MDIO_BUS_MUX=y +CONFIG_MDIO_BUS_MUX_GPIO=y +CONFIG_MDIO_BUS_MUX_MULTIPLEXER=y +CONFIG_MDIO_BUS_MUX_MMIOREG=y + +# +# PCS device drivers +# +CONFIG_PCS_XPCS=y +# end of PCS device drivers + # CONFIG_PPP is not set # CONFIG_SLIP is not set CONFIG_USB_NET_DRIVERS=y @@ -2087,6 +2100,7 @@ CONFIG_HW_RANDOM=m # CONFIG_HW_RANDOM_VIRTIO is not set CONFIG_HW_RANDOM_OPTEE=m # CONFIG_HW_RANDOM_CCTRNG is not set +# CONFIG_HW_RANDOM_XIPHERA is not set CONFIG_DEVMEM=y # CONFIG_RAW_DRIVER is not set # CONFIG_TCG_TPM is not set @@ -2248,12 +2262,20 @@ CONFIG_PINCTRL_ROCKCHIP=y CONFIG_PINCTRL_MAX77620=y CONFIG_PINCTRL_RK805=y # CONFIG_PINCTRL_OCELOT is not set + +# +# Renesas pinctrl drivers +# +# end of Renesas pinctrl drivers + CONFIG_GPIOLIB=y CONFIG_GPIOLIB_FASTPATH_LIMIT=512 CONFIG_OF_GPIO=y CONFIG_GPIOLIB_IRQCHIP=y # CONFIG_DEBUG_GPIO is not set CONFIG_GPIO_SYSFS=y +CONFIG_GPIO_CDEV=y +CONFIG_GPIO_CDEV_V1=y CONFIG_GPIO_GENERIC=y # @@ -2318,9 +2340,6 @@ CONFIG_GPIO_MAX77620=y # CONFIG_GPIO_AGGREGATOR is not set # CONFIG_GPIO_MOCKUP is not set # CONFIG_W1 is not set -CONFIG_POWER_AVS=y -# CONFIG_QCOM_CPR is not set -CONFIG_ROCKCHIP_IODOMAIN=y CONFIG_POWER_RESET=y # CONFIG_POWER_RESET_BRCMSTB is not set # CONFIG_POWER_RESET_GPIO is not set @@ -2344,7 +2363,6 @@ CONFIG_POWER_SUPPLY_HWMON=y # CONFIG_BATTERY_DS2780 is not set # CONFIG_BATTERY_DS2781 is not set # CONFIG_BATTERY_DS2782 is not set -# CONFIG_BATTERY_LEGO_EV3 is not set # CONFIG_BATTERY_SBS is not set # CONFIG_CHARGER_SBS is not set # CONFIG_MANAGER_SBS is not set @@ -2364,6 +2382,7 @@ CONFIG_POWER_SUPPLY_HWMON=y # CONFIG_CHARGER_BQ24735 is not set # CONFIG_CHARGER_BQ2515X is not set # CONFIG_CHARGER_BQ25890 is not set +# CONFIG_CHARGER_BQ25980 is not set # CONFIG_CHARGER_SMB347 is not set # CONFIG_BATTERY_GAUGE_LTC2941 is not set # CONFIG_CHARGER_RT9455 is not set @@ -2440,6 +2459,7 @@ CONFIG_SENSORS_ARM_SCPI=y # CONFIG_SENSORS_MAX31790 is not set # CONFIG_SENSORS_MCP3021 is not set # CONFIG_SENSORS_TC654 is not set +# CONFIG_SENSORS_MR75203 is not set # CONFIG_SENSORS_ADCXX is not set # CONFIG_SENSORS_LM63 is not set # CONFIG_SENSORS_LM70 is not set @@ -2682,6 +2702,7 @@ CONFIG_MFD_SYSCON=y # CONFIG_MFD_STMFX is not set # CONFIG_MFD_KHADAS_MCU is not set # CONFIG_RAVE_SP_CORE is not set +# CONFIG_MFD_INTEL_M10_BMC is not set # end of Multifunction device drivers CONFIG_REGULATOR=y @@ -2726,7 +2747,10 @@ CONFIG_REGULATOR_GPIO=y CONFIG_REGULATOR_PWM=y # CONFIG_REGULATOR_QCOM_SPMI is not set # CONFIG_REGULATOR_QCOM_USB_VBUS is not set +# CONFIG_REGULATOR_RASPBERRYPI_TOUCHSCREEN_ATTINY is not set CONFIG_REGULATOR_RK808=y +# CONFIG_REGULATOR_RT4801 is not set +# CONFIG_REGULATOR_RTMV20 is not set # CONFIG_REGULATOR_S2MPA01 is not set # CONFIG_REGULATOR_S2MPS11 is not set # CONFIG_REGULATOR_S5M8767 is not set @@ -2798,7 +2822,7 @@ CONFIG_MEDIA_ANALOG_TV_SUPPORT=y CONFIG_MEDIA_DIGITAL_TV_SUPPORT=y # CONFIG_MEDIA_RADIO_SUPPORT is not set # CONFIG_MEDIA_SDR_SUPPORT is not set -# CONFIG_MEDIA_PLATFORM_SUPPORT is not set +CONFIG_MEDIA_PLATFORM_SUPPORT=y # CONFIG_MEDIA_TEST_SUPPORT is not set # end of Media device types @@ -2895,6 +2919,17 @@ CONFIG_VIDEOBUF2_V4L2=m CONFIG_VIDEOBUF2_MEMOPS=m CONFIG_VIDEOBUF2_DMA_CONTIG=m CONFIG_VIDEOBUF2_VMALLOC=m +CONFIG_VIDEOBUF2_DMA_SG=m +# 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_DVB_PLATFORM_DRIVERS is not set + +# +# MMC/SDIO DVB adapters +# +# CONFIG_SMS_SDIO_DRV is not set # end of Media drivers CONFIG_MEDIA_HIDE_ANCILLARY_SUBDRV=y @@ -3113,7 +3148,6 @@ CONFIG_ROCKCHIP_DW_HDMI=y # CONFIG_DRM_UDL is not set # CONFIG_DRM_RCAR_DW_HDMI is not set # CONFIG_DRM_RCAR_LVDS is not set -CONFIG_DRM_RCAR_WRITEBACK=y # CONFIG_DRM_VIRTIO_GPU is not set CONFIG_DRM_PANEL=y @@ -3151,6 +3185,7 @@ CONFIG_DRM_PANEL_BRIDGE=y # CONFIG_DRM_CDNS_DSI is not set # CONFIG_DRM_CHRONTEL_CH7033 is not set # CONFIG_DRM_DISPLAY_CONNECTOR is not set +# CONFIG_DRM_LONTIUM_LT9611 is not set # CONFIG_DRM_LVDS_CODEC is not set # CONFIG_DRM_MEGACHIPS_STDPXXXX_GE_B850V3_FW is not set # CONFIG_DRM_NWL_MIPI_DSI is not set @@ -3162,15 +3197,18 @@ CONFIG_DRM_PANEL_BRIDGE=y # CONFIG_DRM_SII9234 is not set # CONFIG_DRM_SIMPLE_BRIDGE is not set # CONFIG_DRM_THINE_THC63LVD1024 is not set +# CONFIG_DRM_TOSHIBA_TC358762 is not set # CONFIG_DRM_TOSHIBA_TC358764 is not set # CONFIG_DRM_TOSHIBA_TC358767 is not set # CONFIG_DRM_TOSHIBA_TC358768 is not set +# CONFIG_DRM_TOSHIBA_TC358775 is not set # CONFIG_DRM_TI_TFP410 is not set # CONFIG_DRM_TI_SN65DSI86 is not set # CONFIG_DRM_TI_TPD12S015 is not set # CONFIG_DRM_ANALOGIX_ANX6345 is not set # CONFIG_DRM_ANALOGIX_ANX78XX is not set # CONFIG_DRM_I2C_ADV7511 is not set +# CONFIG_DRM_CDNS_MHDP8546 is not set CONFIG_DRM_DW_HDMI=y # CONFIG_DRM_DW_HDMI_AHB_AUDIO is not set CONFIG_DRM_DW_HDMI_I2S_AUDIO=y @@ -3236,6 +3274,7 @@ CONFIG_FB_MODE_HELPERS=y # # CONFIG_LCD_CLASS_DEVICE is not set CONFIG_BACKLIGHT_CLASS_DEVICE=y +# CONFIG_BACKLIGHT_KTD253 is not set # CONFIG_BACKLIGHT_PWM is not set # CONFIG_BACKLIGHT_QCOM_WLED is not set # CONFIG_BACKLIGHT_ADP8860 is not set @@ -3341,7 +3380,6 @@ CONFIG_SND_SOC_GENERIC_DMAENGINE_PCM=y # CONFIG_SND_I2S_HI6210_I2S is not set # CONFIG_SND_SOC_IMG is not set -# CONFIG_SND_SOC_INTEL_KEEMBAY is not set # CONFIG_SND_SOC_MTK_BTCVSD is not set CONFIG_SND_SOC_ROCKCHIP=y CONFIG_SND_SOC_ROCKCHIP_I2S=y @@ -3396,6 +3434,7 @@ CONFIG_SND_SOC_AK4613=m # CONFIG_SND_SOC_CS42L52 is not set # CONFIG_SND_SOC_CS42L56 is not set # CONFIG_SND_SOC_CS42L73 is not set +# CONFIG_SND_SOC_CS4234 is not set # CONFIG_SND_SOC_CS4265 is not set # CONFIG_SND_SOC_CS4270 is not set # CONFIG_SND_SOC_CS4271_I2C is not set @@ -3461,6 +3500,7 @@ CONFIG_SND_SOC_SPDIF=y # CONFIG_SND_SOC_STI_SAS is not set # CONFIG_SND_SOC_TAS2552 is not set # CONFIG_SND_SOC_TAS2562 is not set +# CONFIG_SND_SOC_TAS2764 is not set # CONFIG_SND_SOC_TAS2770 is not set # CONFIG_SND_SOC_TAS5086 is not set # CONFIG_SND_SOC_TAS571X is not set @@ -3560,6 +3600,7 @@ CONFIG_HID_GENERIC=y # CONFIG_HID_GFRM is not set # CONFIG_HID_GLORIOUS is not set # CONFIG_HID_HOLTEK is not set +# CONFIG_HID_VIVALDI is not set # CONFIG_HID_GT683R is not set # CONFIG_HID_KEYTOUCH is not set # CONFIG_HID_KYE is not set @@ -3650,6 +3691,7 @@ CONFIG_USB_ANNOUNCE_NEW_DEVICES=y # Miscellaneous USB options # CONFIG_USB_DEFAULT_PERSIST=y +# CONFIG_USB_FEW_INIT_RETRIES is not set # CONFIG_USB_DYNAMIC_MINORS is not set CONFIG_USB_OTG=y # CONFIG_USB_OTG_PRODUCTLIST is not set @@ -3746,6 +3788,7 @@ CONFIG_USB_DWC3_DUAL_ROLE=y # Platform Glue Driver Support # CONFIG_USB_DWC3_OF_SIMPLE=y +CONFIG_USB_DWC3_ROCKCHIP_INNO=y CONFIG_USB_DWC2=y # CONFIG_USB_DWC2_HOST is not set @@ -3935,6 +3978,7 @@ CONFIG_LEDS_CLASS_FLASH=m CONFIG_LEDS_GPIO=y # CONFIG_LEDS_LP3944 is not set # CONFIG_LEDS_LP3952 is not set +# CONFIG_LEDS_LP50XX is not set # CONFIG_LEDS_LP55XX_COMMON is not set # CONFIG_LEDS_LP8860 is not set # CONFIG_LEDS_PCA955X is not set @@ -4043,6 +4087,7 @@ CONFIG_RTC_DRV_RK808=y # CONFIG_RTC_DRV_RX8025 is not set # CONFIG_RTC_DRV_EM3027 is not set # CONFIG_RTC_DRV_RV3028 is not set +# CONFIG_RTC_DRV_RV3032 is not set # CONFIG_RTC_DRV_RV8803 is not set CONFIG_RTC_DRV_S5M=y # CONFIG_RTC_DRV_SD3078 is not set @@ -4165,8 +4210,6 @@ CONFIG_VIRTIO_BALLOON=y CONFIG_VIRTIO_MMIO=y # CONFIG_VIRTIO_MMIO_CMDLINE_DEVICES is not set # CONFIG_VDPA is not set -CONFIG_VHOST_IOTLB=y -CONFIG_VHOST_RING=y CONFIG_VHOST_MENU=y # CONFIG_VHOST_NET is not set # CONFIG_VHOST_CROSS_ENDIAN_LEGACY is not set @@ -4247,9 +4290,7 @@ CONFIG_STAGING_MEDIA=y CONFIG_VIDEO_HANTRO=m CONFIG_VIDEO_HANTRO_ROCKCHIP=y CONFIG_VIDEO_ROCKCHIP_VDEC=m -# CONFIG_PHY_ROCKCHIP_DPHY_RX0 is not set # CONFIG_VIDEO_ROCKCHIP_ISP1 is not set -# CONFIG_VIDEO_USBVISION is not set # # Android @@ -4272,8 +4313,9 @@ CONFIG_VIDEO_ROCKCHIP_VDEC=m # CONFIG_XIL_AXIS_FIFO is not set # CONFIG_FIELDBUS_DEV is not set # CONFIG_WFX is not set +# CONFIG_SPMI_HISI3670 is not set +# CONFIG_MFD_HI6421_SPMI is not set # CONFIG_GOLDFISH is not set -# CONFIG_MFD_CROS_EC is not set CONFIG_CHROME_PLATFORMS=y # CONFIG_CROS_EC is not set # CONFIG_MELLANOX_PLATFORM is not set @@ -4281,7 +4323,6 @@ CONFIG_HAVE_CLK=y CONFIG_CLKDEV_LOOKUP=y CONFIG_HAVE_CLK_PREPARE=y CONFIG_COMMON_CLK=y -# CONFIG_CLK_HSDK is not set # CONFIG_COMMON_CLK_MAX77686 is not set # CONFIG_COMMON_CLK_MAX9485 is not set CONFIG_COMMON_CLK_RK808=y @@ -4302,11 +4343,6 @@ CONFIG_COMMON_CLK_PWM=y # CONFIG_COMMON_CLK_FIXED_MMIO is not set CONFIG_COMMON_CLK_ROCKCHIP=y CONFIG_CLK_PX30=y -CONFIG_CLK_RV110X=y -CONFIG_CLK_RK3036=y -CONFIG_CLK_RK312X=y -CONFIG_CLK_RK3188=y -CONFIG_CLK_RK322X=y CONFIG_CLK_RK3308=y CONFIG_CLK_RK3328=y CONFIG_CLK_RK3368=y @@ -4358,6 +4394,7 @@ CONFIG_ARM_SMMU=y # CONFIG_ARM_SMMU_LEGACY_DT_BINDINGS is not set CONFIG_ARM_SMMU_DISABLE_BYPASS_BY_DEFAULT=y CONFIG_ARM_SMMU_V3=y +# CONFIG_ARM_SMMU_V3_SVA is not set # CONFIG_VIRTIO_IOMMU is not set # @@ -4413,6 +4450,7 @@ CONFIG_ARM_SMMU_V3=y # end of Qualcomm SoC drivers CONFIG_ROCKCHIP_GRF=y +CONFIG_ROCKCHIP_IODOMAIN=y CONFIG_ROCKCHIP_PM_DOMAINS=y # CONFIG_SOC_TI is not set @@ -4457,6 +4495,8 @@ CONFIG_EXTCON_USB_GPIO=y CONFIG_IIO=y CONFIG_IIO_BUFFER=y # CONFIG_IIO_BUFFER_CB is not set +# CONFIG_IIO_BUFFER_DMA is not set +# CONFIG_IIO_BUFFER_DMAENGINE is not set # CONFIG_IIO_BUFFER_HW_CONSUMER is not set CONFIG_IIO_KFIFO_BUF=y CONFIG_IIO_TRIGGERED_BUFFER=y @@ -4465,6 +4505,7 @@ CONFIG_IIO_TRIGGER=y CONFIG_IIO_CONSUMERS_PER_TRIGGER=2 # CONFIG_IIO_SW_DEVICE is not set # CONFIG_IIO_SW_TRIGGER is not set +# CONFIG_IIO_TRIGGERED_EVENT is not set # # Accelerometers @@ -4674,6 +4715,7 @@ CONFIG_ROCKCHIP_SARADC=y # CONFIG_ADIS16130 is not set # CONFIG_ADIS16136 is not set # CONFIG_ADIS16260 is not set +# CONFIG_ADXRS290 is not set # CONFIG_ADXRS450 is not set # CONFIG_BMG160 is not set # CONFIG_FXAS21002C is not set @@ -4702,6 +4744,7 @@ CONFIG_ROCKCHIP_SARADC=y # CONFIG_AM2315 is not set # CONFIG_DHT11 is not set # CONFIG_HDC100X is not set +# CONFIG_HDC2010 is not set # CONFIG_HTS221 is not set # CONFIG_HTU21 is not set # CONFIG_SI7005 is not set @@ -4736,6 +4779,7 @@ CONFIG_ROCKCHIP_SARADC=y # CONFIG_AL3320A is not set # CONFIG_APDS9300 is not set # CONFIG_APDS9960 is not set +# CONFIG_AS73211 is not set # CONFIG_BH1750 is not set # CONFIG_BH1780 is not set # CONFIG_CM32181 is not set @@ -4931,6 +4975,7 @@ CONFIG_RESET_CONTROLLER=y # CONFIG_GENERIC_PHY=y # CONFIG_PHY_XGENE is not set +# CONFIG_USB_LGM_PHY is not set # CONFIG_BCM_KONA_USB2_PHY is not set # CONFIG_PHY_CADENCE_TORRENT is not set # CONFIG_PHY_CADENCE_DPHY is not set @@ -4946,9 +4991,11 @@ CONFIG_GENERIC_PHY=y # CONFIG_PHY_QCOM_USB_HS is not set # CONFIG_PHY_QCOM_USB_HSIC is not set CONFIG_PHY_ROCKCHIP_DP=y +# CONFIG_PHY_ROCKCHIP_DPHY_RX0 is not set CONFIG_PHY_ROCKCHIP_EMMC=y CONFIG_PHY_ROCKCHIP_INNO_HDMI=y CONFIG_PHY_ROCKCHIP_INNO_USB2=y +CONFIG_PHY_ROCKCHIP_INNO_USB3=y # CONFIG_PHY_ROCKCHIP_INNO_DSIDPHY is not set CONFIG_PHY_ROCKCHIP_PCIE=m CONFIG_PHY_ROCKCHIP_TYPEC=y @@ -4965,6 +5012,7 @@ CONFIG_PHY_ROCKCHIP_USB=y # # CONFIG_ARM_CCI_PMU is not set # CONFIG_ARM_CCN is not set +# CONFIG_ARM_CMN is not set CONFIG_ARM_PMU=y # CONFIG_ARM_DSU_PMU is not set # CONFIG_ARM_SPE_PMU is not set @@ -5204,6 +5252,7 @@ CONFIG_ROOT_NFS=y # CONFIG_NFS_USE_LEGACY_DNS is not set CONFIG_NFS_USE_KERNEL_DNS=y CONFIG_NFS_DISABLE_UDP_SUPPORT=y +# CONFIG_NFS_V4_2_READ_PLUS is not set # CONFIG_NFSD is not set CONFIG_GRACE_PERIOD=y CONFIG_LOCKD=y @@ -5214,7 +5263,15 @@ CONFIG_SUNRPC_GSS=y CONFIG_SUNRPC_BACKCHANNEL=y # CONFIG_SUNRPC_DEBUG is not set # CONFIG_CEPH_FS is not set -# CONFIG_CIFS is not set +CONFIG_CIFS=y +CONFIG_CIFS_STATS2=y +CONFIG_CIFS_ALLOW_INSECURE_LEGACY=y +# CONFIG_CIFS_WEAK_PW_HASH is not set +# CONFIG_CIFS_UPCALL is not set +# CONFIG_CIFS_XATTR is not set +# CONFIG_CIFS_DEBUG is not set +# CONFIG_CIFS_DFS_UPCALL is not set +# CONFIG_CIFS_ROOT is not set # CONFIG_CODA_FS is not set # CONFIG_AFS_FS is not set CONFIG_9P_FS=y @@ -5315,6 +5372,10 @@ CONFIG_LSM="yama,loadpin,safesetid,integrity" # Memory initialization # CONFIG_INIT_STACK_NONE=y +# CONFIG_GCC_PLUGIN_STRUCTLEAK_USER is not set +# CONFIG_GCC_PLUGIN_STRUCTLEAK_BYREF is not set +# CONFIG_GCC_PLUGIN_STRUCTLEAK_BYREF_ALL is not set +# CONFIG_GCC_PLUGIN_STACKLEAK is not set # CONFIG_INIT_ON_ALLOC_DEFAULT_ON is not set # CONFIG_INIT_ON_FREE_DEFAULT_ON is not set # end of Memory initialization @@ -5365,13 +5426,14 @@ CONFIG_CRYPTO_RSA=y CONFIG_CRYPTO_ECC=m CONFIG_CRYPTO_ECDH=m # CONFIG_CRYPTO_ECRDSA is not set +# CONFIG_CRYPTO_SM2 is not set CONFIG_CRYPTO_CURVE25519=m # # Authenticated Encryption with Associated Data # -CONFIG_CRYPTO_CCM=m -CONFIG_CRYPTO_GCM=m +CONFIG_CRYPTO_CCM=y +CONFIG_CRYPTO_GCM=y # CONFIG_CRYPTO_CHACHA20POLY1305 is not set # CONFIG_CRYPTO_AEGIS128 is not set CONFIG_CRYPTO_SEQIV=m @@ -5382,9 +5444,9 @@ CONFIG_CRYPTO_ECHAINIV=y # # CONFIG_CRYPTO_CBC is not set # CONFIG_CRYPTO_CFB is not set -CONFIG_CRYPTO_CTR=m +CONFIG_CRYPTO_CTR=y # CONFIG_CRYPTO_CTS is not set -CONFIG_CRYPTO_ECB=m +CONFIG_CRYPTO_ECB=y # CONFIG_CRYPTO_LRW is not set # CONFIG_CRYPTO_OFB is not set # CONFIG_CRYPTO_PCBC is not set @@ -5397,7 +5459,7 @@ CONFIG_CRYPTO_NHPOLY1305=m # # Hash modes # -CONFIG_CRYPTO_CMAC=m +CONFIG_CRYPTO_CMAC=y CONFIG_CRYPTO_HMAC=y # CONFIG_CRYPTO_XCBC is not set # CONFIG_CRYPTO_VMAC is not set @@ -5411,10 +5473,10 @@ CONFIG_CRYPTO_XXHASH=m CONFIG_CRYPTO_BLAKE2B=m CONFIG_CRYPTO_BLAKE2S=m # CONFIG_CRYPTO_CRCT10DIF is not set -CONFIG_CRYPTO_GHASH=m +CONFIG_CRYPTO_GHASH=y CONFIG_CRYPTO_POLY1305=m -# CONFIG_CRYPTO_MD4 is not set -# CONFIG_CRYPTO_MD5 is not set +CONFIG_CRYPTO_MD4=y +CONFIG_CRYPTO_MD5=y # CONFIG_CRYPTO_MICHAEL_MIC is not set # CONFIG_CRYPTO_RMD128 is not set # CONFIG_CRYPTO_RMD160 is not set @@ -5422,7 +5484,7 @@ CONFIG_CRYPTO_POLY1305=m # CONFIG_CRYPTO_RMD320 is not set CONFIG_CRYPTO_SHA1=y CONFIG_CRYPTO_SHA256=y -# CONFIG_CRYPTO_SHA512 is not set +CONFIG_CRYPTO_SHA512=y # CONFIG_CRYPTO_SHA3 is not set # CONFIG_CRYPTO_SM3 is not set # CONFIG_CRYPTO_STREEBOG is not set @@ -5476,13 +5538,14 @@ CONFIG_CRYPTO_USER_API_HASH=y CONFIG_CRYPTO_USER_API_SKCIPHER=y # CONFIG_CRYPTO_USER_API_RNG is not set # CONFIG_CRYPTO_USER_API_AEAD is not set +CONFIG_CRYPTO_USER_API_ENABLE_OBSOLETE=y CONFIG_CRYPTO_HASH_INFO=y # # Crypto library routines # CONFIG_CRYPTO_LIB_AES=y -CONFIG_CRYPTO_LIB_ARC4=m +CONFIG_CRYPTO_LIB_ARC4=y CONFIG_CRYPTO_LIB_BLAKE2S_GENERIC=m CONFIG_CRYPTO_LIB_BLAKE2S=m CONFIG_CRYPTO_ARCH_HAVE_LIB_CHACHA=m @@ -5490,6 +5553,7 @@ CONFIG_CRYPTO_LIB_CHACHA_GENERIC=m CONFIG_CRYPTO_LIB_CHACHA=m CONFIG_CRYPTO_LIB_CURVE25519_GENERIC=m CONFIG_CRYPTO_LIB_CURVE25519=m +CONFIG_CRYPTO_LIB_DES=y CONFIG_CRYPTO_LIB_POLY1305_RSIZE=9 CONFIG_CRYPTO_ARCH_HAVE_LIB_POLY1305=m CONFIG_CRYPTO_LIB_POLY1305_GENERIC=m @@ -5604,6 +5668,7 @@ CONFIG_DMA_COHERENT_POOL=y CONFIG_DMA_REMAP=y CONFIG_DMA_DIRECT_REMAP=y CONFIG_DMA_CMA=y +# CONFIG_DMA_PERNUMA_CMA is not set # # Default contiguous memory area size: @@ -5634,6 +5699,7 @@ CONFIG_FONT_SUPPORT=y CONFIG_FONT_8x8=y CONFIG_FONT_8x16=y CONFIG_SG_POOL=y +CONFIG_ARCH_STACKWALK=y CONFIG_SBITMAP=y # CONFIG_STRING_SELFTEST is not set # end of Library routines @@ -5665,7 +5731,6 @@ CONFIG_DEBUG_INFO=y # CONFIG_DEBUG_INFO_COMPRESSED is not set # CONFIG_DEBUG_INFO_SPLIT is not set # CONFIG_DEBUG_INFO_DWARF4 is not set -# CONFIG_DEBUG_INFO_BTF is not set # CONFIG_GDB_SCRIPTS is not set CONFIG_ENABLE_MUST_CHECK=y CONFIG_FRAME_WARN=2048 @@ -5772,6 +5837,8 @@ CONFIG_LOCK_DEBUGGING_SUPPORT=y # CONFIG_DEBUG_LOCKING_API_SELFTESTS is not set # CONFIG_LOCK_TORTURE_TEST is not set # CONFIG_WW_MUTEX_SELFTEST is not set +# CONFIG_SCF_TORTURE_TEST is not set +# CONFIG_CSD_LOCK_WAIT_DEBUG is not set # end of Lock Debugging (spinlocks, mutexes, etc...) # CONFIG_STACKTRACE is not set @@ -5794,7 +5861,7 @@ CONFIG_HAVE_DEBUG_BUGVERBOSE=y # # RCU Debugging # -# CONFIG_RCU_PERF_TEST is not set +# CONFIG_RCU_SCALE_TEST is not set # CONFIG_RCU_TORTURE_TEST is not set # CONFIG_RCU_REF_SCALE_TEST is not set CONFIG_RCU_CPU_STALL_TIMEOUT=21 diff --git a/projects/Rockchip/devices/RK3399/linux/default/linux.aarch64.conf b/projects/Rockchip/devices/RK3399/linux/default/linux.aarch64.conf index a06132a50c..b4e3d85e80 100644 --- a/projects/Rockchip/devices/RK3399/linux/default/linux.aarch64.conf +++ b/projects/Rockchip/devices/RK3399/linux/default/linux.aarch64.conf @@ -1,19 +1,7 @@ # # Automatically generated file; DO NOT EDIT. -# Linux/arm64 5.9.0 Kernel Configuration +# Linux/arm64 5.10.4 Kernel Configuration # -CONFIG_CC_VERSION_TEXT="aarch64-none-linux-gnu-gcc-9.2.1 (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 -CONFIG_BUILDTIME_TABLE_SORT=y -CONFIG_THREAD_INFO_IN_TASK=y # # General setup @@ -48,6 +36,7 @@ CONFIG_HARDIRQS_SW_RESEND=y CONFIG_GENERIC_IRQ_CHIP=y CONFIG_IRQ_DOMAIN=y CONFIG_IRQ_DOMAIN_HIERARCHY=y +CONFIG_GENERIC_IRQ_IPI=y CONFIG_GENERIC_MSI_IRQ=y CONFIG_GENERIC_MSI_IRQ_DOMAIN=y CONFIG_IRQ_MSI_IOMMU=y @@ -105,6 +94,8 @@ CONFIG_TREE_RCU=y # CONFIG_RCU_EXPERT is not set CONFIG_SRCU=y CONFIG_TREE_SRCU=y +CONFIG_TASKS_RCU_GENERIC=y +CONFIG_TASKS_TRACE_RCU=y CONFIG_RCU_STALL_COMMON=y CONFIG_RCU_NEED_SEGCBLIST=y # end of RCU Subsystem @@ -177,6 +168,7 @@ CONFIG_INITRAMFS_COMPRESSION_LZ4=y # CONFIG_BOOT_CONFIG is not set CONFIG_CC_OPTIMIZE_FOR_PERFORMANCE=y # CONFIG_CC_OPTIMIZE_FOR_SIZE is not set +CONFIG_LD_ORPHAN_WARN=y CONFIG_SYSCTL=y CONFIG_HAVE_UID16=y CONFIG_SYSCTL_EXCEPTION_TRACE=y @@ -211,6 +203,7 @@ CONFIG_BPF_SYSCALL=y CONFIG_ARCH_WANT_DEFAULT_BPF_JIT=y # CONFIG_BPF_JIT_ALWAYS_ON is not set CONFIG_BPF_JIT_DEFAULT_ON=y +# CONFIG_BPF_PRELOAD is not set # CONFIG_USERFAULTFD is not set CONFIG_ARCH_HAS_MEMBARRIER_SYNC_CORE=y CONFIG_RSEQ=y @@ -242,7 +235,8 @@ CONFIG_ARM64=y CONFIG_64BIT=y CONFIG_MMU=y CONFIG_ARM64_PAGE_SHIFT=12 -CONFIG_ARM64_CONT_SHIFT=4 +CONFIG_ARM64_CONT_PTE_SHIFT=4 +CONFIG_ARM64_CONT_PMD_SHIFT=4 CONFIG_ARCH_MMAP_RND_BITS_MIN=18 CONFIG_ARCH_MMAP_RND_BITS_MAX=33 CONFIG_ARCH_MMAP_RND_COMPAT_BITS_MIN=11 @@ -305,6 +299,7 @@ CONFIG_ARCH_ROCKCHIP=y # CONFIG_ARCH_THUNDER2 is not set # CONFIG_ARCH_UNIPHIER is not set # CONFIG_ARCH_VEXPRESS is not set +# CONFIG_ARCH_VISCONTI is not set # CONFIG_ARCH_XGENE is not set # CONFIG_ARCH_ZX is not set # CONFIG_ARCH_ZYNQMP is not set @@ -335,6 +330,7 @@ CONFIG_ARM64_WORKAROUND_REPEAT_TLBI=y CONFIG_ARM64_ERRATUM_1286807=y CONFIG_ARM64_ERRATUM_1463225=y CONFIG_ARM64_ERRATUM_1542419=y +CONFIG_ARM64_ERRATUM_1508412=y CONFIG_CAVIUM_ERRATUM_22375=y CONFIG_CAVIUM_ERRATUM_23154=y CONFIG_CAVIUM_ERRATUM_27456=y @@ -382,7 +378,6 @@ CONFIG_SYS_SUPPORTS_HUGETLBFS=y CONFIG_ARCH_WANT_HUGE_PMD_SHARE=y CONFIG_ARCH_HAS_CACHE_LINE_SIZE=y CONFIG_ARCH_ENABLE_SPLIT_PMD_PTLOCK=y -CONFIG_SECCOMP=y # CONFIG_PARAVIRT is not set # CONFIG_PARAVIRT_TIME_ACCOUNTING is not set # CONFIG_KEXEC is not set @@ -391,8 +386,6 @@ CONFIG_SECCOMP=y # CONFIG_XEN is not set CONFIG_FORCE_MAX_ZONEORDER=11 CONFIG_UNMAP_KERNEL_AT_EL0=y -CONFIG_HARDEN_BRANCH_PREDICTOR=y -CONFIG_ARM64_SSBD=y CONFIG_RODATA_FULL_DEFAULT_ENABLED=y # CONFIG_ARM64_SW_TTBR0_PAN is not set CONFIG_ARM64_TAGGED_ADDR_ABI=y @@ -444,6 +437,8 @@ CONFIG_ARM64_BTI=y CONFIG_CC_HAS_BRANCH_PROT_PAC_RET_BTI=y CONFIG_ARM64_E0PD=y CONFIG_ARCH_RANDOM=y +CONFIG_ARM64_AS_HAS_MTE=y +CONFIG_ARM64_MTE=y # end of ARMv8.5 architectural features CONFIG_ARM64_SVE=y @@ -464,6 +459,7 @@ CONFIG_CMDLINE="" CONFIG_SYSVIPC_COMPAT=y CONFIG_ARCH_ENABLE_HUGEPAGE_MIGRATION=y +CONFIG_ARCH_ENABLE_THP_MIGRATION=y # # Power management options @@ -548,7 +544,6 @@ CONFIG_ARM_SCPI_PROTOCOL=y CONFIG_ARM_SCPI_POWER_DOMAIN=y # CONFIG_ARM_SDE_INTERFACE is not set # CONFIG_GOOGLE_FIRMWARE is not set -CONFIG_EFI_EARLYCON=y CONFIG_ARM_PSCI_FW=y # CONFIG_ARM_PSCI_CHECKER is not set CONFIG_HAVE_ARM_SMCCC=y @@ -585,6 +580,7 @@ CONFIG_CRYPTO_AES_ARM64_BS=m # # General architecture-dependent options # +CONFIG_SET_FS=y # CONFIG_KPROBES is not set CONFIG_JUMP_LABEL=y # CONFIG_STATIC_KEYS_SELFTEST is not set @@ -618,7 +614,9 @@ CONFIG_HAVE_ALIGNED_STRUCT_PAGE=y CONFIG_HAVE_CMPXCHG_LOCAL=y CONFIG_HAVE_CMPXCHG_DOUBLE=y CONFIG_ARCH_WANT_COMPAT_IPC_PARSE_VERSION=y +CONFIG_HAVE_ARCH_SECCOMP=y CONFIG_HAVE_ARCH_SECCOMP_FILTER=y +CONFIG_SECCOMP=y CONFIG_SECCOMP_FILTER=y CONFIG_HAVE_ARCH_STACKLEAK=y CONFIG_HAVE_STACKPROTECTOR=y @@ -627,6 +625,7 @@ CONFIG_STACKPROTECTOR_STRONG=y CONFIG_HAVE_CONTEXT_TRACKING=y CONFIG_HAVE_VIRT_CPU_ACCOUNTING_GEN=y CONFIG_HAVE_IRQ_TIME_ACCOUNTING=y +CONFIG_HAVE_MOVE_PMD=y CONFIG_HAVE_ARCH_TRANSPARENT_HUGEPAGE=y CONFIG_HAVE_ARCH_HUGE_VMAP=y CONFIG_HAVE_MOD_ARCH_SPECIFIC=y @@ -649,9 +648,9 @@ CONFIG_ARCH_HAS_STRICT_MODULE_RWX=y CONFIG_STRICT_MODULE_RWX=y 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 +CONFIG_ARCH_WANT_LD_ORPHAN_WARN=y # # GCOV-based kernel profiling @@ -661,7 +660,9 @@ CONFIG_ARCH_HAS_GCOV_PROFILE_ALL=y # end of GCOV-based kernel profiling CONFIG_HAVE_GCC_PLUGINS=y -# CONFIG_GCC_PLUGINS is not set +CONFIG_GCC_PLUGINS=y +# CONFIG_GCC_PLUGIN_LATENT_ENTROPY is not set +# CONFIG_GCC_PLUGIN_RANDSTRUCT is not set # end of General architecture-dependent options CONFIG_RT_MUTEXES=y @@ -837,6 +838,7 @@ CONFIG_GENERIC_EARLY_IOREMAP=y # CONFIG_IDLE_PAGE_TRACKING is not set CONFIG_ARCH_HAS_PTE_DEVMAP=y CONFIG_FRAME_VECTOR=y +CONFIG_ARCH_USES_HIGH_VMA_FLAGS=y # CONFIG_PERCPU_STATS is not set # CONFIG_GUP_BENCHMARK is not set # CONFIG_READ_ONLY_THP_FOR_FS is not set @@ -1392,6 +1394,11 @@ CONFIG_MTD_CFI_I2=y # CONFIG_MTD_ONENAND is not set # CONFIG_MTD_RAW_NAND is not set # CONFIG_MTD_SPI_NAND is not set + +# +# ECC engine support +# +# end of ECC engine support # end of NAND # @@ -1414,7 +1421,6 @@ CONFIG_OF_DYNAMIC=y CONFIG_OF_ADDRESS=y CONFIG_OF_IRQ=y CONFIG_OF_NET=y -CONFIG_OF_MDIO=y CONFIG_OF_RESERVED_MEM=y CONFIG_OF_RESOLVE=y CONFIG_OF_OVERLAY=y @@ -1458,6 +1464,7 @@ CONFIG_VIRTIO_BLK=y CONFIG_SRAM=y # CONFIG_XILINX_SDFEC is not set # CONFIG_PVPANIC is not set +# CONFIG_HISI_HIKEY_USB is not set # CONFIG_C2PORT is not set # @@ -1482,14 +1489,6 @@ CONFIG_EEPROM_93CX6=m # CONFIG_SENSORS_LIS3_SPI is not set # CONFIG_SENSORS_LIS3_I2C is not set # CONFIG_ALTERA_STAPL is not set - -# -# Intel MIC & related support -# -CONFIG_VOP_BUS=y -CONFIG_VOP=y -# end of Intel MIC & related support - # CONFIG_ECHO is not set # CONFIG_MISC_RTSX_USB is not set # CONFIG_UACCE is not set @@ -1613,58 +1612,37 @@ CONFIG_STMMAC_PLATFORM=y CONFIG_DWMAC_DWC_QOS_ETH=y CONFIG_DWMAC_GENERIC=y CONFIG_DWMAC_ROCKCHIP=y +# CONFIG_DWMAC_INTEL_PLAT is not set # CONFIG_NET_VENDOR_SYNOPSYS is not set # CONFIG_NET_VENDOR_VIA is not set # CONFIG_NET_VENDOR_WIZNET is not set # CONFIG_NET_VENDOR_XILINX is not set -CONFIG_MDIO_DEVICE=y -CONFIG_MDIO_BUS=y -CONFIG_MDIO_DEVRES=y -# CONFIG_MDIO_BCM_UNIMAC is not set -CONFIG_MDIO_BITBANG=y -CONFIG_MDIO_BUS_MUX=y -CONFIG_MDIO_BUS_MUX_GPIO=y -CONFIG_MDIO_BUS_MUX_MMIOREG=y -CONFIG_MDIO_BUS_MUX_MULTIPLEXER=y -CONFIG_MDIO_GPIO=y -# CONFIG_MDIO_HISI_FEMAC is not set -# CONFIG_MDIO_IPQ4019 is not set -# CONFIG_MDIO_IPQ8064 is not set -# CONFIG_MDIO_MSCC_MIIM is not set -# CONFIG_MDIO_MVUSB is not set -# CONFIG_MDIO_OCTEON is not set -CONFIG_MDIO_XPCS=y CONFIG_PHYLINK=y CONFIG_PHYLIB=y CONFIG_SWPHY=y # CONFIG_LED_TRIGGER_PHY is not set +CONFIG_FIXED_PHY=y +# CONFIG_SFP is not set # # MII PHY device drivers # -# CONFIG_SFP is not set -# CONFIG_ADIN_PHY is not set # CONFIG_AMD_PHY is not set +# CONFIG_ADIN_PHY is not set # CONFIG_AQUANTIA_PHY is not set # CONFIG_AX88796B_PHY is not set -# CONFIG_BCM7XXX_PHY is not set -# CONFIG_BCM87XX_PHY is not set # CONFIG_BROADCOM_PHY is not set # CONFIG_BCM54140_PHY is not set +# CONFIG_BCM7XXX_PHY is not set # CONFIG_BCM84881_PHY is not set +# CONFIG_BCM87XX_PHY is not set # CONFIG_CICADA_PHY is not set # CONFIG_CORTINA_PHY is not set # CONFIG_DAVICOM_PHY is not set -# CONFIG_DP83822_PHY is not set -# CONFIG_DP83TC811_PHY is not set -# CONFIG_DP83848_PHY is not set -# CONFIG_DP83867_PHY is not set -# CONFIG_DP83869_PHY is not set -CONFIG_FIXED_PHY=y # CONFIG_ICPLUS_PHY is not set +# CONFIG_LXT_PHY is not set # CONFIG_INTEL_XWAY_PHY is not set # CONFIG_LSI_ET1011C_PHY is not set -# CONFIG_LXT_PHY is not set # CONFIG_MARVELL_PHY is not set # CONFIG_MARVELL_10G_PHY is not set # CONFIG_MICREL_PHY is not set @@ -1678,12 +1656,45 @@ CONFIG_MICROCHIP_PHY=m CONFIG_REALTEK_PHY=y # CONFIG_RENESAS_PHY is not set CONFIG_ROCKCHIP_PHY=y -# CONFIG_SMSC_PHY is not set +CONFIG_SMSC_PHY=m # CONFIG_STE10XP is not set # CONFIG_TERANETICS_PHY is not set +# CONFIG_DP83822_PHY is not set +# CONFIG_DP83TC811_PHY is not set +# CONFIG_DP83848_PHY is not set +# CONFIG_DP83867_PHY is not set +# CONFIG_DP83869_PHY is not set # CONFIG_VITESSE_PHY is not set # CONFIG_XILINX_GMII2RGMII is not set # CONFIG_MICREL_KS8995MA is not set +CONFIG_MDIO_DEVICE=y +CONFIG_MDIO_BUS=y +CONFIG_OF_MDIO=y +CONFIG_MDIO_DEVRES=y +CONFIG_MDIO_BITBANG=y +# CONFIG_MDIO_BCM_UNIMAC is not set +CONFIG_MDIO_GPIO=y +# CONFIG_MDIO_HISI_FEMAC is not set +# CONFIG_MDIO_MVUSB is not set +# CONFIG_MDIO_MSCC_MIIM is not set +# CONFIG_MDIO_OCTEON is not set +# CONFIG_MDIO_IPQ4019 is not set +# CONFIG_MDIO_IPQ8064 is not set + +# +# MDIO Multiplexers +# +CONFIG_MDIO_BUS_MUX=y +CONFIG_MDIO_BUS_MUX_GPIO=y +CONFIG_MDIO_BUS_MUX_MULTIPLEXER=y +CONFIG_MDIO_BUS_MUX_MMIOREG=y + +# +# PCS device drivers +# +CONFIG_PCS_XPCS=y +# end of PCS device drivers + # CONFIG_PPP is not set # CONFIG_SLIP is not set CONFIG_USB_NET_DRIVERS=y @@ -2087,6 +2098,7 @@ CONFIG_HW_RANDOM=m # CONFIG_HW_RANDOM_VIRTIO is not set CONFIG_HW_RANDOM_OPTEE=m # CONFIG_HW_RANDOM_CCTRNG is not set +# CONFIG_HW_RANDOM_XIPHERA is not set CONFIG_DEVMEM=y # CONFIG_RAW_DRIVER is not set # CONFIG_TCG_TPM is not set @@ -2248,12 +2260,20 @@ CONFIG_PINCTRL_ROCKCHIP=y CONFIG_PINCTRL_MAX77620=y CONFIG_PINCTRL_RK805=y # CONFIG_PINCTRL_OCELOT is not set + +# +# Renesas pinctrl drivers +# +# end of Renesas pinctrl drivers + CONFIG_GPIOLIB=y CONFIG_GPIOLIB_FASTPATH_LIMIT=512 CONFIG_OF_GPIO=y CONFIG_GPIOLIB_IRQCHIP=y # CONFIG_DEBUG_GPIO is not set CONFIG_GPIO_SYSFS=y +CONFIG_GPIO_CDEV=y +CONFIG_GPIO_CDEV_V1=y CONFIG_GPIO_GENERIC=y # @@ -2318,9 +2338,6 @@ CONFIG_GPIO_MAX77620=y # CONFIG_GPIO_AGGREGATOR is not set # CONFIG_GPIO_MOCKUP is not set # CONFIG_W1 is not set -CONFIG_POWER_AVS=y -# CONFIG_QCOM_CPR is not set -CONFIG_ROCKCHIP_IODOMAIN=y CONFIG_POWER_RESET=y # CONFIG_POWER_RESET_BRCMSTB is not set # CONFIG_POWER_RESET_GPIO is not set @@ -2344,7 +2361,6 @@ CONFIG_POWER_SUPPLY_HWMON=y # CONFIG_BATTERY_DS2780 is not set # CONFIG_BATTERY_DS2781 is not set # CONFIG_BATTERY_DS2782 is not set -# CONFIG_BATTERY_LEGO_EV3 is not set # CONFIG_BATTERY_SBS is not set # CONFIG_CHARGER_SBS is not set # CONFIG_MANAGER_SBS is not set @@ -2364,6 +2380,7 @@ CONFIG_POWER_SUPPLY_HWMON=y # CONFIG_CHARGER_BQ24735 is not set # CONFIG_CHARGER_BQ2515X is not set # CONFIG_CHARGER_BQ25890 is not set +# CONFIG_CHARGER_BQ25980 is not set # CONFIG_CHARGER_SMB347 is not set # CONFIG_BATTERY_GAUGE_LTC2941 is not set # CONFIG_CHARGER_RT9455 is not set @@ -2440,6 +2457,7 @@ CONFIG_SENSORS_ARM_SCPI=y # CONFIG_SENSORS_MAX31790 is not set # CONFIG_SENSORS_MCP3021 is not set # CONFIG_SENSORS_TC654 is not set +# CONFIG_SENSORS_MR75203 is not set # CONFIG_SENSORS_ADCXX is not set # CONFIG_SENSORS_LM63 is not set # CONFIG_SENSORS_LM70 is not set @@ -2682,6 +2700,7 @@ CONFIG_MFD_SYSCON=y # CONFIG_MFD_STMFX is not set # CONFIG_MFD_KHADAS_MCU is not set # CONFIG_RAVE_SP_CORE is not set +# CONFIG_MFD_INTEL_M10_BMC is not set # end of Multifunction device drivers CONFIG_REGULATOR=y @@ -2726,7 +2745,10 @@ CONFIG_REGULATOR_GPIO=y CONFIG_REGULATOR_PWM=y # CONFIG_REGULATOR_QCOM_SPMI is not set # CONFIG_REGULATOR_QCOM_USB_VBUS is not set +# CONFIG_REGULATOR_RASPBERRYPI_TOUCHSCREEN_ATTINY is not set CONFIG_REGULATOR_RK808=y +# CONFIG_REGULATOR_RT4801 is not set +# CONFIG_REGULATOR_RTMV20 is not set # CONFIG_REGULATOR_S2MPA01 is not set # CONFIG_REGULATOR_S2MPS11 is not set # CONFIG_REGULATOR_S5M8767 is not set @@ -2798,7 +2820,7 @@ CONFIG_MEDIA_ANALOG_TV_SUPPORT=y CONFIG_MEDIA_DIGITAL_TV_SUPPORT=y # CONFIG_MEDIA_RADIO_SUPPORT is not set # CONFIG_MEDIA_SDR_SUPPORT is not set -# CONFIG_MEDIA_PLATFORM_SUPPORT is not set +CONFIG_MEDIA_PLATFORM_SUPPORT=y # CONFIG_MEDIA_TEST_SUPPORT is not set # end of Media device types @@ -2895,6 +2917,17 @@ CONFIG_VIDEOBUF2_V4L2=m CONFIG_VIDEOBUF2_MEMOPS=m CONFIG_VIDEOBUF2_DMA_CONTIG=m CONFIG_VIDEOBUF2_VMALLOC=m +CONFIG_VIDEOBUF2_DMA_SG=m +# 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_DVB_PLATFORM_DRIVERS is not set + +# +# MMC/SDIO DVB adapters +# +# CONFIG_SMS_SDIO_DRV is not set # end of Media drivers CONFIG_MEDIA_HIDE_ANCILLARY_SUBDRV=y @@ -3113,7 +3146,6 @@ CONFIG_ROCKCHIP_DW_HDMI=y # CONFIG_DRM_UDL is not set # CONFIG_DRM_RCAR_DW_HDMI is not set # CONFIG_DRM_RCAR_LVDS is not set -CONFIG_DRM_RCAR_WRITEBACK=y # CONFIG_DRM_VIRTIO_GPU is not set CONFIG_DRM_PANEL=y @@ -3151,6 +3183,7 @@ CONFIG_DRM_PANEL_BRIDGE=y # CONFIG_DRM_CDNS_DSI is not set # CONFIG_DRM_CHRONTEL_CH7033 is not set # CONFIG_DRM_DISPLAY_CONNECTOR is not set +# CONFIG_DRM_LONTIUM_LT9611 is not set # CONFIG_DRM_LVDS_CODEC is not set # CONFIG_DRM_MEGACHIPS_STDPXXXX_GE_B850V3_FW is not set # CONFIG_DRM_NWL_MIPI_DSI is not set @@ -3162,15 +3195,18 @@ CONFIG_DRM_PANEL_BRIDGE=y # CONFIG_DRM_SII9234 is not set # CONFIG_DRM_SIMPLE_BRIDGE is not set # CONFIG_DRM_THINE_THC63LVD1024 is not set +# CONFIG_DRM_TOSHIBA_TC358762 is not set # CONFIG_DRM_TOSHIBA_TC358764 is not set # CONFIG_DRM_TOSHIBA_TC358767 is not set # CONFIG_DRM_TOSHIBA_TC358768 is not set +# CONFIG_DRM_TOSHIBA_TC358775 is not set # CONFIG_DRM_TI_TFP410 is not set # CONFIG_DRM_TI_SN65DSI86 is not set # CONFIG_DRM_TI_TPD12S015 is not set # CONFIG_DRM_ANALOGIX_ANX6345 is not set # CONFIG_DRM_ANALOGIX_ANX78XX is not set # CONFIG_DRM_I2C_ADV7511 is not set +# CONFIG_DRM_CDNS_MHDP8546 is not set CONFIG_DRM_DW_HDMI=y # CONFIG_DRM_DW_HDMI_AHB_AUDIO is not set CONFIG_DRM_DW_HDMI_I2S_AUDIO=y @@ -3236,6 +3272,7 @@ CONFIG_FB_MODE_HELPERS=y # # CONFIG_LCD_CLASS_DEVICE is not set CONFIG_BACKLIGHT_CLASS_DEVICE=y +# CONFIG_BACKLIGHT_KTD253 is not set # CONFIG_BACKLIGHT_PWM is not set # CONFIG_BACKLIGHT_QCOM_WLED is not set # CONFIG_BACKLIGHT_ADP8860 is not set @@ -3341,7 +3378,6 @@ CONFIG_SND_SOC_GENERIC_DMAENGINE_PCM=y # CONFIG_SND_I2S_HI6210_I2S is not set # CONFIG_SND_SOC_IMG is not set -# CONFIG_SND_SOC_INTEL_KEEMBAY is not set # CONFIG_SND_SOC_MTK_BTCVSD is not set CONFIG_SND_SOC_ROCKCHIP=y CONFIG_SND_SOC_ROCKCHIP_I2S=y @@ -3396,6 +3432,7 @@ CONFIG_SND_SOC_AK4613=m # CONFIG_SND_SOC_CS42L52 is not set # CONFIG_SND_SOC_CS42L56 is not set # CONFIG_SND_SOC_CS42L73 is not set +# CONFIG_SND_SOC_CS4234 is not set # CONFIG_SND_SOC_CS4265 is not set # CONFIG_SND_SOC_CS4270 is not set # CONFIG_SND_SOC_CS4271_I2C is not set @@ -3461,6 +3498,7 @@ CONFIG_SND_SOC_SPDIF=y # CONFIG_SND_SOC_STI_SAS is not set # CONFIG_SND_SOC_TAS2552 is not set # CONFIG_SND_SOC_TAS2562 is not set +# CONFIG_SND_SOC_TAS2764 is not set # CONFIG_SND_SOC_TAS2770 is not set # CONFIG_SND_SOC_TAS5086 is not set # CONFIG_SND_SOC_TAS571X is not set @@ -3560,6 +3598,7 @@ CONFIG_HID_GENERIC=y # CONFIG_HID_GFRM is not set # CONFIG_HID_GLORIOUS is not set # CONFIG_HID_HOLTEK is not set +# CONFIG_HID_VIVALDI is not set # CONFIG_HID_GT683R is not set # CONFIG_HID_KEYTOUCH is not set # CONFIG_HID_KYE is not set @@ -3650,6 +3689,7 @@ CONFIG_USB_ANNOUNCE_NEW_DEVICES=y # Miscellaneous USB options # CONFIG_USB_DEFAULT_PERSIST=y +# CONFIG_USB_FEW_INIT_RETRIES is not set # CONFIG_USB_DYNAMIC_MINORS is not set CONFIG_USB_OTG=y # CONFIG_USB_OTG_PRODUCTLIST is not set @@ -3746,6 +3786,7 @@ CONFIG_USB_DWC3_DUAL_ROLE=y # Platform Glue Driver Support # CONFIG_USB_DWC3_OF_SIMPLE=y +# CONFIG_USB_DWC3_ROCKCHIP_INNO is not set CONFIG_USB_DWC2=y # CONFIG_USB_DWC2_HOST is not set @@ -3935,6 +3976,7 @@ CONFIG_LEDS_CLASS_FLASH=m CONFIG_LEDS_GPIO=y # CONFIG_LEDS_LP3944 is not set # CONFIG_LEDS_LP3952 is not set +# CONFIG_LEDS_LP50XX is not set # CONFIG_LEDS_LP55XX_COMMON is not set # CONFIG_LEDS_LP8860 is not set # CONFIG_LEDS_PCA955X is not set @@ -4043,6 +4085,7 @@ CONFIG_RTC_DRV_RK808=y # CONFIG_RTC_DRV_RX8025 is not set # CONFIG_RTC_DRV_EM3027 is not set # CONFIG_RTC_DRV_RV3028 is not set +# CONFIG_RTC_DRV_RV3032 is not set # CONFIG_RTC_DRV_RV8803 is not set CONFIG_RTC_DRV_S5M=y # CONFIG_RTC_DRV_SD3078 is not set @@ -4165,8 +4208,6 @@ CONFIG_VIRTIO_BALLOON=y CONFIG_VIRTIO_MMIO=y # CONFIG_VIRTIO_MMIO_CMDLINE_DEVICES is not set # CONFIG_VDPA is not set -CONFIG_VHOST_IOTLB=y -CONFIG_VHOST_RING=y CONFIG_VHOST_MENU=y # CONFIG_VHOST_NET is not set # CONFIG_VHOST_CROSS_ENDIAN_LEGACY is not set @@ -4247,9 +4288,7 @@ CONFIG_STAGING_MEDIA=y CONFIG_VIDEO_HANTRO=m CONFIG_VIDEO_HANTRO_ROCKCHIP=y CONFIG_VIDEO_ROCKCHIP_VDEC=m -# CONFIG_PHY_ROCKCHIP_DPHY_RX0 is not set # CONFIG_VIDEO_ROCKCHIP_ISP1 is not set -# CONFIG_VIDEO_USBVISION is not set # # Android @@ -4272,8 +4311,9 @@ CONFIG_VIDEO_ROCKCHIP_VDEC=m # CONFIG_XIL_AXIS_FIFO is not set # CONFIG_FIELDBUS_DEV is not set # CONFIG_WFX is not set +# CONFIG_SPMI_HISI3670 is not set +# CONFIG_MFD_HI6421_SPMI is not set # CONFIG_GOLDFISH is not set -# CONFIG_MFD_CROS_EC is not set CONFIG_CHROME_PLATFORMS=y # CONFIG_CROS_EC is not set # CONFIG_MELLANOX_PLATFORM is not set @@ -4281,7 +4321,6 @@ CONFIG_HAVE_CLK=y CONFIG_CLKDEV_LOOKUP=y CONFIG_HAVE_CLK_PREPARE=y CONFIG_COMMON_CLK=y -# CONFIG_CLK_HSDK is not set # CONFIG_COMMON_CLK_MAX77686 is not set # CONFIG_COMMON_CLK_MAX9485 is not set CONFIG_COMMON_CLK_RK808=y @@ -4302,11 +4341,6 @@ CONFIG_COMMON_CLK_PWM=y # CONFIG_COMMON_CLK_FIXED_MMIO is not set CONFIG_COMMON_CLK_ROCKCHIP=y CONFIG_CLK_PX30=y -CONFIG_CLK_RV110X=y -CONFIG_CLK_RK3036=y -CONFIG_CLK_RK312X=y -CONFIG_CLK_RK3188=y -CONFIG_CLK_RK322X=y CONFIG_CLK_RK3308=y CONFIG_CLK_RK3328=y CONFIG_CLK_RK3368=y @@ -4358,6 +4392,7 @@ CONFIG_ARM_SMMU=y # CONFIG_ARM_SMMU_LEGACY_DT_BINDINGS is not set CONFIG_ARM_SMMU_DISABLE_BYPASS_BY_DEFAULT=y CONFIG_ARM_SMMU_V3=y +# CONFIG_ARM_SMMU_V3_SVA is not set # CONFIG_VIRTIO_IOMMU is not set # @@ -4413,6 +4448,7 @@ CONFIG_ARM_SMMU_V3=y # end of Qualcomm SoC drivers CONFIG_ROCKCHIP_GRF=y +CONFIG_ROCKCHIP_IODOMAIN=y CONFIG_ROCKCHIP_PM_DOMAINS=y # CONFIG_SOC_TI is not set @@ -4457,6 +4493,8 @@ CONFIG_EXTCON_USB_GPIO=y CONFIG_IIO=y CONFIG_IIO_BUFFER=y # CONFIG_IIO_BUFFER_CB is not set +# CONFIG_IIO_BUFFER_DMA is not set +# CONFIG_IIO_BUFFER_DMAENGINE is not set # CONFIG_IIO_BUFFER_HW_CONSUMER is not set CONFIG_IIO_KFIFO_BUF=y CONFIG_IIO_TRIGGERED_BUFFER=y @@ -4465,6 +4503,7 @@ CONFIG_IIO_TRIGGER=y CONFIG_IIO_CONSUMERS_PER_TRIGGER=2 # CONFIG_IIO_SW_DEVICE is not set # CONFIG_IIO_SW_TRIGGER is not set +# CONFIG_IIO_TRIGGERED_EVENT is not set # # Accelerometers @@ -4674,6 +4713,7 @@ CONFIG_ROCKCHIP_SARADC=y # CONFIG_ADIS16130 is not set # CONFIG_ADIS16136 is not set # CONFIG_ADIS16260 is not set +# CONFIG_ADXRS290 is not set # CONFIG_ADXRS450 is not set # CONFIG_BMG160 is not set # CONFIG_FXAS21002C is not set @@ -4702,6 +4742,7 @@ CONFIG_ROCKCHIP_SARADC=y # CONFIG_AM2315 is not set # CONFIG_DHT11 is not set # CONFIG_HDC100X is not set +# CONFIG_HDC2010 is not set # CONFIG_HTS221 is not set # CONFIG_HTU21 is not set # CONFIG_SI7005 is not set @@ -4736,6 +4777,7 @@ CONFIG_ROCKCHIP_SARADC=y # CONFIG_AL3320A is not set # CONFIG_APDS9300 is not set # CONFIG_APDS9960 is not set +# CONFIG_AS73211 is not set # CONFIG_BH1750 is not set # CONFIG_BH1780 is not set # CONFIG_CM32181 is not set @@ -4931,6 +4973,7 @@ CONFIG_RESET_CONTROLLER=y # CONFIG_GENERIC_PHY=y # CONFIG_PHY_XGENE is not set +# CONFIG_USB_LGM_PHY is not set # CONFIG_BCM_KONA_USB2_PHY is not set # CONFIG_PHY_CADENCE_TORRENT is not set # CONFIG_PHY_CADENCE_DPHY is not set @@ -4946,9 +4989,11 @@ CONFIG_GENERIC_PHY=y # CONFIG_PHY_QCOM_USB_HS is not set # CONFIG_PHY_QCOM_USB_HSIC is not set CONFIG_PHY_ROCKCHIP_DP=y +# CONFIG_PHY_ROCKCHIP_DPHY_RX0 is not set CONFIG_PHY_ROCKCHIP_EMMC=y CONFIG_PHY_ROCKCHIP_INNO_HDMI=y CONFIG_PHY_ROCKCHIP_INNO_USB2=y +# CONFIG_PHY_ROCKCHIP_INNO_USB3 is not set # CONFIG_PHY_ROCKCHIP_INNO_DSIDPHY is not set CONFIG_PHY_ROCKCHIP_PCIE=m CONFIG_PHY_ROCKCHIP_TYPEC=y @@ -4965,6 +5010,7 @@ CONFIG_PHY_ROCKCHIP_USB=y # # CONFIG_ARM_CCI_PMU is not set # CONFIG_ARM_CCN is not set +# CONFIG_ARM_CMN is not set CONFIG_ARM_PMU=y # CONFIG_ARM_DSU_PMU is not set # CONFIG_ARM_SPE_PMU is not set @@ -5204,6 +5250,7 @@ CONFIG_ROOT_NFS=y # CONFIG_NFS_USE_LEGACY_DNS is not set CONFIG_NFS_USE_KERNEL_DNS=y CONFIG_NFS_DISABLE_UDP_SUPPORT=y +CONFIG_NFS_V4_2_READ_PLUS=y # CONFIG_NFSD is not set CONFIG_GRACE_PERIOD=y CONFIG_LOCKD=y @@ -5214,7 +5261,15 @@ CONFIG_SUNRPC_GSS=y CONFIG_SUNRPC_BACKCHANNEL=y # CONFIG_SUNRPC_DEBUG is not set # CONFIG_CEPH_FS is not set -# CONFIG_CIFS is not set +CONFIG_CIFS=y +CONFIG_CIFS_STATS2=y +CONFIG_CIFS_ALLOW_INSECURE_LEGACY=y +# CONFIG_CIFS_WEAK_PW_HASH is not set +# CONFIG_CIFS_UPCALL is not set +# CONFIG_CIFS_XATTR is not set +# CONFIG_CIFS_DEBUG is not set +# CONFIG_CIFS_DFS_UPCALL is not set +# CONFIG_CIFS_ROOT is not set # CONFIG_CODA_FS is not set # CONFIG_AFS_FS is not set CONFIG_9P_FS=y @@ -5315,6 +5370,10 @@ CONFIG_LSM="yama,loadpin,safesetid,integrity" # Memory initialization # CONFIG_INIT_STACK_NONE=y +# CONFIG_GCC_PLUGIN_STRUCTLEAK_USER is not set +# CONFIG_GCC_PLUGIN_STRUCTLEAK_BYREF is not set +# CONFIG_GCC_PLUGIN_STRUCTLEAK_BYREF_ALL is not set +# CONFIG_GCC_PLUGIN_STACKLEAK is not set # CONFIG_INIT_ON_ALLOC_DEFAULT_ON is not set # CONFIG_INIT_ON_FREE_DEFAULT_ON is not set # end of Memory initialization @@ -5365,13 +5424,14 @@ CONFIG_CRYPTO_RSA=y CONFIG_CRYPTO_ECC=m CONFIG_CRYPTO_ECDH=m # CONFIG_CRYPTO_ECRDSA is not set +# CONFIG_CRYPTO_SM2 is not set CONFIG_CRYPTO_CURVE25519=m # # Authenticated Encryption with Associated Data # -CONFIG_CRYPTO_CCM=m -CONFIG_CRYPTO_GCM=m +CONFIG_CRYPTO_CCM=y +CONFIG_CRYPTO_GCM=y # CONFIG_CRYPTO_CHACHA20POLY1305 is not set # CONFIG_CRYPTO_AEGIS128 is not set CONFIG_CRYPTO_SEQIV=m @@ -5382,9 +5442,9 @@ CONFIG_CRYPTO_ECHAINIV=y # # CONFIG_CRYPTO_CBC is not set # CONFIG_CRYPTO_CFB is not set -CONFIG_CRYPTO_CTR=m +CONFIG_CRYPTO_CTR=y # CONFIG_CRYPTO_CTS is not set -CONFIG_CRYPTO_ECB=m +CONFIG_CRYPTO_ECB=y # CONFIG_CRYPTO_LRW is not set # CONFIG_CRYPTO_OFB is not set # CONFIG_CRYPTO_PCBC is not set @@ -5397,7 +5457,7 @@ CONFIG_CRYPTO_NHPOLY1305=m # # Hash modes # -CONFIG_CRYPTO_CMAC=m +CONFIG_CRYPTO_CMAC=y CONFIG_CRYPTO_HMAC=y # CONFIG_CRYPTO_XCBC is not set # CONFIG_CRYPTO_VMAC is not set @@ -5411,10 +5471,10 @@ CONFIG_CRYPTO_XXHASH=m CONFIG_CRYPTO_BLAKE2B=m CONFIG_CRYPTO_BLAKE2S=m # CONFIG_CRYPTO_CRCT10DIF is not set -CONFIG_CRYPTO_GHASH=m +CONFIG_CRYPTO_GHASH=y CONFIG_CRYPTO_POLY1305=m -# CONFIG_CRYPTO_MD4 is not set -# CONFIG_CRYPTO_MD5 is not set +CONFIG_CRYPTO_MD4=y +CONFIG_CRYPTO_MD5=y # CONFIG_CRYPTO_MICHAEL_MIC is not set # CONFIG_CRYPTO_RMD128 is not set # CONFIG_CRYPTO_RMD160 is not set @@ -5422,7 +5482,7 @@ CONFIG_CRYPTO_POLY1305=m # CONFIG_CRYPTO_RMD320 is not set CONFIG_CRYPTO_SHA1=y CONFIG_CRYPTO_SHA256=y -# CONFIG_CRYPTO_SHA512 is not set +CONFIG_CRYPTO_SHA512=y # CONFIG_CRYPTO_SHA3 is not set # CONFIG_CRYPTO_SM3 is not set # CONFIG_CRYPTO_STREEBOG is not set @@ -5476,13 +5536,14 @@ CONFIG_CRYPTO_USER_API_HASH=y CONFIG_CRYPTO_USER_API_SKCIPHER=y # CONFIG_CRYPTO_USER_API_RNG is not set # CONFIG_CRYPTO_USER_API_AEAD is not set +CONFIG_CRYPTO_USER_API_ENABLE_OBSOLETE=y CONFIG_CRYPTO_HASH_INFO=y # # Crypto library routines # CONFIG_CRYPTO_LIB_AES=y -CONFIG_CRYPTO_LIB_ARC4=m +CONFIG_CRYPTO_LIB_ARC4=y CONFIG_CRYPTO_LIB_BLAKE2S_GENERIC=m CONFIG_CRYPTO_LIB_BLAKE2S=m CONFIG_CRYPTO_ARCH_HAVE_LIB_CHACHA=m @@ -5490,6 +5551,7 @@ CONFIG_CRYPTO_LIB_CHACHA_GENERIC=m CONFIG_CRYPTO_LIB_CHACHA=m CONFIG_CRYPTO_LIB_CURVE25519_GENERIC=m CONFIG_CRYPTO_LIB_CURVE25519=m +CONFIG_CRYPTO_LIB_DES=y CONFIG_CRYPTO_LIB_POLY1305_RSIZE=9 CONFIG_CRYPTO_ARCH_HAVE_LIB_POLY1305=m CONFIG_CRYPTO_LIB_POLY1305_GENERIC=m @@ -5604,6 +5666,7 @@ CONFIG_DMA_COHERENT_POOL=y CONFIG_DMA_REMAP=y CONFIG_DMA_DIRECT_REMAP=y CONFIG_DMA_CMA=y +# CONFIG_DMA_PERNUMA_CMA is not set # # Default contiguous memory area size: @@ -5634,6 +5697,7 @@ CONFIG_FONT_SUPPORT=y CONFIG_FONT_8x8=y CONFIG_FONT_8x16=y CONFIG_SG_POOL=y +CONFIG_ARCH_STACKWALK=y CONFIG_SBITMAP=y # CONFIG_STRING_SELFTEST is not set # end of Library routines @@ -5772,6 +5836,8 @@ CONFIG_LOCK_DEBUGGING_SUPPORT=y # CONFIG_DEBUG_LOCKING_API_SELFTESTS is not set # CONFIG_LOCK_TORTURE_TEST is not set # CONFIG_WW_MUTEX_SELFTEST is not set +# CONFIG_SCF_TORTURE_TEST is not set +# CONFIG_CSD_LOCK_WAIT_DEBUG is not set # end of Lock Debugging (spinlocks, mutexes, etc...) # CONFIG_STACKTRACE is not set @@ -5794,7 +5860,7 @@ CONFIG_HAVE_DEBUG_BUGVERBOSE=y # # RCU Debugging # -# CONFIG_RCU_PERF_TEST is not set +# CONFIG_RCU_SCALE_TEST is not set # CONFIG_RCU_TORTURE_TEST is not set # CONFIG_RCU_REF_SCALE_TEST is not set CONFIG_RCU_CPU_STALL_TIMEOUT=21 diff --git a/projects/Rockchip/patches/linux/default/linux-0001-rockchip-from-5.10.patch b/projects/Rockchip/patches/linux/default/linux-0001-rockchip-from-5.10.patch deleted file mode 100644 index e1b9d3fd21..0000000000 --- a/projects/Rockchip/patches/linux/default/linux-0001-rockchip-from-5.10.patch +++ /dev/null @@ -1,2967 +0,0 @@ -From 2e3fedafa307db03549840de3f5e342f09fb5c45 Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?=C5=81ukasz=20Stelmach?= -Date: Thu, 13 Aug 2020 22:41:23 +0200 -Subject: [PATCH] dmaengine: pl330: fix instruction dump formatting -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -Instruction dump uses two printk() in a row to print one instruction. Use -KERN_CONT to prevent breaking the output in the middle. - -Signed-off-by: Łukasz Stelmach -Link: https://lore.kernel.org/r/20200813204123.19044-1-l.stelmach@samsung.com -Signed-off-by: Vinod Koul -(cherry picked from commit 112ec61b212200d378963cbafdd736a62e9ddaec) ---- - drivers/dma/pl330.c | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/drivers/dma/pl330.c b/drivers/dma/pl330.c -index 5274a0704d96..106f47298f9e 100644 ---- a/drivers/dma/pl330.c -+++ b/drivers/dma/pl330.c -@@ -255,7 +255,7 @@ enum pl330_byteswap { - static unsigned cmd_line; - #define PL330_DBGCMD_DUMP(off, x...) do { \ - printk("%x:", cmd_line); \ -- printk(x); \ -+ printk(KERN_CONT x); \ - cmd_line += off; \ - } while (0) - #define PL330_DBGMC_START(addr) (cmd_line = addr) - -From 3bb4e2c068270e9c910e3a3b7bec8b0225e2d442 Mon Sep 17 00:00:00 2001 -From: Jagan Teki -Date: Wed, 19 Aug 2020 00:15:05 +0530 -Subject: [PATCH] arm64: dts: rockchip: Fix power routing to support POE on - rk3399-roc-pc - -When POE used, the current power routing is failing to power-up -the PMIC regulators which cause Linux boot hangs. - -This patch is trying to update the power routing in order to -support Type C0 and POE powering methods. - -As per the schematics, sys_12v is a common output power regulator -when type c and POE power being used. sys_12v is supplied by dc_12v -which is supplied from MP8859 in type c0 power routing and sys_12v -is supplied by MP8009 PoE PD in POE power supply routing. - -Signed-off-by: Jagan Teki -Tested-by: Suniel Mahesh -Link: https://lore.kernel.org/r/20200818184505.30064-1-jagan@amarulasolutions.com -Signed-off-by: Heiko Stuebner -(cherry picked from commit bd77d0ad7a698f5e04edf02328d11e808a71d87c) ---- - .../boot/dts/rockchip/rk3399-roc-pc-mezzanine.dts | 18 ++++++++++++++++-- - arch/arm64/boot/dts/rockchip/rk3399-roc-pc.dtsi | 12 ++++++++++-- - 2 files changed, 26 insertions(+), 4 deletions(-) - -diff --git a/arch/arm64/boot/dts/rockchip/rk3399-roc-pc-mezzanine.dts b/arch/arm64/boot/dts/rockchip/rk3399-roc-pc-mezzanine.dts -index 2acb3d500fb9..754627d97144 100644 ---- a/arch/arm64/boot/dts/rockchip/rk3399-roc-pc-mezzanine.dts -+++ b/arch/arm64/boot/dts/rockchip/rk3399-roc-pc-mezzanine.dts -@@ -11,6 +11,16 @@ - model = "Firefly ROC-RK3399-PC Mezzanine Board"; - compatible = "firefly,roc-rk3399-pc-mezzanine", "rockchip,rk3399"; - -+ /* MP8009 PoE PD */ -+ poe_12v: poe-12v { -+ compatible = "regulator-fixed"; -+ regulator-name = "poe_12v"; -+ regulator-always-on; -+ regulator-boot-on; -+ regulator-min-microvolt = <12000000>; -+ regulator-max-microvolt = <12000000>; -+ }; -+ - vcc3v3_ngff: vcc3v3-ngff { - compatible = "regulator-fixed"; - regulator-name = "vcc3v3_ngff"; -@@ -22,7 +32,7 @@ - regulator-boot-on; - regulator-min-microvolt = <3300000>; - regulator-max-microvolt = <3300000>; -- vin-supply = <&dc_12v>; -+ vin-supply = <&sys_12v>; - }; - - vcc3v3_pcie: vcc3v3-pcie { -@@ -34,10 +44,14 @@ - pinctrl-0 = <&vcc3v3_pcie_en>; - regulator-min-microvolt = <3300000>; - regulator-max-microvolt = <3300000>; -- vin-supply = <&dc_12v>; -+ vin-supply = <&sys_12v>; - }; - }; - -+&sys_12v { -+ vin-supply = <&poe_12v>; -+}; -+ - &pcie_phy { - status = "okay"; - }; -diff --git a/arch/arm64/boot/dts/rockchip/rk3399-roc-pc.dtsi b/arch/arm64/boot/dts/rockchip/rk3399-roc-pc.dtsi -index b85ec31cd283..e7a459fa4322 100644 ---- a/arch/arm64/boot/dts/rockchip/rk3399-roc-pc.dtsi -+++ b/arch/arm64/boot/dts/rockchip/rk3399-roc-pc.dtsi -@@ -110,6 +110,14 @@ - regulator-max-microvolt = <5000000>; - }; - -+ sys_12v: sys-12v { -+ compatible = "regulator-fixed"; -+ regulator-name = "sys_12v"; -+ regulator-always-on; -+ regulator-boot-on; -+ vin-supply = <&dc_12v>; -+ }; -+ - /* switched by pmic_sleep */ - vcc1v8_s3: vcca1v8_s3: vcc1v8-s3 { - compatible = "regulator-fixed"; -@@ -141,7 +149,7 @@ - regulator-boot-on; - regulator-min-microvolt = <3300000>; - regulator-max-microvolt = <3300000>; -- vin-supply = <&dc_12v>; -+ vin-supply = <&sys_12v>; - }; - - vcca_0v9: vcca-0v9 { -@@ -186,7 +194,7 @@ - regulator-boot-on; - regulator-min-microvolt = <5000000>; - regulator-max-microvolt = <5000000>; -- vin-supply = <&dc_12v>; -+ vin-supply = <&sys_12v>; - }; - - vdd_log: vdd-log { - -From 9d3c764ef494a805ed623e81e7485d5fc3f57a97 Mon Sep 17 00:00:00 2001 -From: Johan Jonker -Date: Tue, 18 Aug 2020 16:37:27 +0200 -Subject: [PATCH] arm64: dts: rockchip: change spdif fallback compatible on - rk3308 - -A test with the command below shows that the compatible string - -"rockchip,rk3308-spdif", "rockchip,rk3328-spdif" - -is already in use, but is not added to a document. -The current fallback string "rockchip,rk3328-spdif" points to a data -set enum RK_SPDIF_RK3366 in rockchip_spdif.c that is not used both -in the mainline as in the manufacturer kernel. -(Of the enum only RK_SPDIF_RK3288 is used.) -So if the properties don't change we might as well use the first SoC -in line as fallback string and add the description for rk3308 as: - -"rockchip,rk3308-spdif", "rockchip,rk3066-spdif" - -make ARCH=arm64 dtbs_check -DT_SCHEMA_FILES=Documentation/devicetree/bindings/sound/rockchip-spdif.yaml - -Signed-off-by: Johan Jonker -Link: https://lore.kernel.org/r/20200818143727.5882-2-jbx6244@gmail.com -Signed-off-by: Heiko Stuebner -(cherry picked from commit bc1f9bff0629a15e3de1ef106ac03cba930227dd) ---- - arch/arm64/boot/dts/rockchip/rk3308.dtsi | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/arch/arm64/boot/dts/rockchip/rk3308.dtsi b/arch/arm64/boot/dts/rockchip/rk3308.dtsi -index e8b754d415d8..2560b98771ca 100644 ---- a/arch/arm64/boot/dts/rockchip/rk3308.dtsi -+++ b/arch/arm64/boot/dts/rockchip/rk3308.dtsi -@@ -574,7 +574,7 @@ - }; - - spdif_tx: spdif-tx@ff3a0000 { -- compatible = "rockchip,rk3308-spdif", "rockchip,rk3328-spdif"; -+ compatible = "rockchip,rk3308-spdif", "rockchip,rk3066-spdif"; - reg = <0x0 0xff3a0000 0x0 0x1000>; - interrupts = ; - clocks = <&cru SCLK_SPDIF_TX>, <&cru HCLK_SPDIFTX>; - -From a87e7be5beb9646557e70f0b42c558d418ba16ce Mon Sep 17 00:00:00 2001 -From: Jagan Teki -Date: Fri, 7 Aug 2020 15:18:23 +0530 -Subject: [PATCH] dt-bindings: arm: rockchip: Update ROCKPi 4 binding - -ROCKPi 4 has 3 variants of hardware platforms called -ROCKPi 4A, 4B, and 4C. - -- ROCKPi 4A has no Wif/BT. -- ROCKPi 4B has AP6256 Wifi/BT, PoE. -- ROCKPi 4C has AP6256 Wifi/BT, PoE, miniDP, USB Host enabled - GPIO pin change compared to 4B, 4C - -So, update the existing ROCKPi 4 binding to support -ROCKPi 4A/B/C hardware platforms. - -Signed-off-by: Jagan Teki -Acked-by: Rob Herring -Link: https://lore.kernel.org/r/20200807094826.12019-1-jagan@amarulasolutions.com -Signed-off-by: Heiko Stuebner -(cherry picked from commit 75a0a65a301f557bf0306d7983f8cf31ac91de56) ---- - Documentation/devicetree/bindings/arm/rockchip.yaml | 6 +++++- - 1 file changed, 5 insertions(+), 1 deletion(-) - -diff --git a/Documentation/devicetree/bindings/arm/rockchip.yaml b/Documentation/devicetree/bindings/arm/rockchip.yaml -index db2e35796795..7025d00c06cc 100644 ---- a/Documentation/devicetree/bindings/arm/rockchip.yaml -+++ b/Documentation/devicetree/bindings/arm/rockchip.yaml -@@ -430,8 +430,12 @@ properties: - - const: radxa,rock - - const: rockchip,rk3188 - -- - description: Radxa ROCK Pi 4 -+ - description: Radxa ROCK Pi 4A/B/C - items: -+ - enum: -+ - radxa,rockpi4a -+ - radxa,rockpi4b -+ - radxa,rockpi4c - - const: radxa,rockpi4 - - const: rockchip,rk3399 - - -From bb10faf3729a3982ba5a85b39b416116e315f642 Mon Sep 17 00:00:00 2001 -From: Jagan Teki -Date: Fri, 7 Aug 2020 15:18:24 +0530 -Subject: [PATCH] arm64: dts: rockchip: Mark rock-pi-4 as rock-pi-4a dts - -ROCKPi 4 has 3 variants of hardware platforms called -RockPI 4A, 4B, and 4C. - -- ROCKPi 4A has no Wif/BT. -- ROCKPi 4B has AP6256 Wifi/BT, PoE. -- ROCKPi 4C has AP6256 Wifi/BT, PoE, miniDP, USB Host enabled - GPIO pin change compared to 4B, 4C - -So move common nodes, properties into dtsi file and include -on respective variant dts files. - -Signed-off-by: Jagan Teki -Link: https://lore.kernel.org/r/20200807094826.12019-2-jagan@amarulasolutions.com -Signed-off-by: Heiko Stuebner -(cherry picked from commit b5edb04673700125bfd1d13e6c14747b1ecba522) ---- - arch/arm64/boot/dts/rockchip/Makefile | 2 +- - .../{rk3399-rock-pi-4.dts => rk3399-rock-pi-4.dtsi} | 3 --- - arch/arm64/boot/dts/rockchip/rk3399-rock-pi-4a.dts | 13 +++++++++++++ - 3 files changed, 14 insertions(+), 4 deletions(-) - rename arch/arm64/boot/dts/rockchip/{rk3399-rock-pi-4.dts => rk3399-rock-pi-4.dtsi} (99%) - create mode 100644 arch/arm64/boot/dts/rockchip/rk3399-rock-pi-4a.dts - -diff --git a/arch/arm64/boot/dts/rockchip/Makefile b/arch/arm64/boot/dts/rockchip/Makefile -index b87b1f773083..42f9e1861461 100644 ---- a/arch/arm64/boot/dts/rockchip/Makefile -+++ b/arch/arm64/boot/dts/rockchip/Makefile -@@ -33,7 +33,7 @@ dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3399-pinebook-pro.dtb - dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3399-puma-haikou.dtb - dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3399-roc-pc.dtb - dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3399-roc-pc-mezzanine.dtb --dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3399-rock-pi-4.dtb -+dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3399-rock-pi-4a.dtb - dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3399-rock960.dtb - dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3399-rockpro64-v2.dtb - dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3399-rockpro64.dtb -diff --git a/arch/arm64/boot/dts/rockchip/rk3399-rock-pi-4.dts b/arch/arm64/boot/dts/rockchip/rk3399-rock-pi-4.dtsi -similarity index 99% -rename from arch/arm64/boot/dts/rockchip/rk3399-rock-pi-4.dts -rename to arch/arm64/boot/dts/rockchip/rk3399-rock-pi-4.dtsi -index 60f98a3e19d8..e163f438f836 100644 ---- a/arch/arm64/boot/dts/rockchip/rk3399-rock-pi-4.dts -+++ b/arch/arm64/boot/dts/rockchip/rk3399-rock-pi-4.dtsi -@@ -11,9 +11,6 @@ - #include "rk3399-opp.dtsi" - - / { -- model = "Radxa ROCK Pi 4"; -- compatible = "radxa,rockpi4", "rockchip,rk3399"; -- - chosen { - stdout-path = "serial2:1500000n8"; - }; -diff --git a/arch/arm64/boot/dts/rockchip/rk3399-rock-pi-4a.dts b/arch/arm64/boot/dts/rockchip/rk3399-rock-pi-4a.dts -new file mode 100644 -index 000000000000..89f2af5e111d ---- /dev/null -+++ b/arch/arm64/boot/dts/rockchip/rk3399-rock-pi-4a.dts -@@ -0,0 +1,13 @@ -+// SPDX-License-Identifier: (GPL-2.0+ OR MIT) -+/* -+ * Copyright (c) 2019 Akash Gajjar -+ * Copyright (c) 2019 Pragnesh Patel -+ */ -+ -+/dts-v1/; -+#include "rk3399-rock-pi-4.dtsi" -+ -+/ { -+ model = "Radxa ROCK Pi 4A"; -+ compatible = "radxa,rockpi4a", "radxa,rockpi4", "rockchip,rk3399"; -+}; - -From 54123d61cf3af2ae6b27e264a40c058eba9716c2 Mon Sep 17 00:00:00 2001 -From: Jagan Teki -Date: Fri, 7 Aug 2020 15:18:25 +0530 -Subject: [PATCH] arm64: dts: rockchip: Add Radxa ROCK Pi 4B support - -RockPI 4B has AP6256 Wifi/BT, so enable them in 4B dts -instead of enable in common dtsi. - -Signed-off-by: Jagan Teki -Link: https://lore.kernel.org/r/20200807094826.12019-3-jagan@amarulasolutions.com -Signed-off-by: Heiko Stuebner -(cherry picked from commit c1075b7fcca81f58ebc5d723f07b23f84ae93daa) ---- - arch/arm64/boot/dts/rockchip/Makefile | 1 + - arch/arm64/boot/dts/rockchip/rk3399-rock-pi-4.dtsi | 23 ------------ - arch/arm64/boot/dts/rockchip/rk3399-rock-pi-4b.dts | 42 ++++++++++++++++++++++ - 3 files changed, 43 insertions(+), 23 deletions(-) - create mode 100644 arch/arm64/boot/dts/rockchip/rk3399-rock-pi-4b.dts - -diff --git a/arch/arm64/boot/dts/rockchip/Makefile b/arch/arm64/boot/dts/rockchip/Makefile -index 42f9e1861461..8832d05c2571 100644 ---- a/arch/arm64/boot/dts/rockchip/Makefile -+++ b/arch/arm64/boot/dts/rockchip/Makefile -@@ -34,6 +34,7 @@ dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3399-puma-haikou.dtb - dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3399-roc-pc.dtb - dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3399-roc-pc-mezzanine.dtb - dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3399-rock-pi-4a.dtb -+dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3399-rock-pi-4b.dtb - dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3399-rock960.dtb - dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3399-rockpro64-v2.dtb - dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3399-rockpro64.dtb -diff --git a/arch/arm64/boot/dts/rockchip/rk3399-rock-pi-4.dtsi b/arch/arm64/boot/dts/rockchip/rk3399-rock-pi-4.dtsi -index e163f438f836..678a336010bf 100644 ---- a/arch/arm64/boot/dts/rockchip/rk3399-rock-pi-4.dtsi -+++ b/arch/arm64/boot/dts/rockchip/rk3399-rock-pi-4.dtsi -@@ -584,17 +584,6 @@ - pinctrl-names = "default"; - pinctrl-0 = <&sdio0_bus4 &sdio0_cmd &sdio0_clk>; - sd-uhs-sdr104; -- status = "okay"; -- -- brcmf: wifi@1 { -- compatible = "brcm,bcm4329-fmac"; -- reg = <1>; -- interrupt-parent = <&gpio0>; -- interrupts = ; -- interrupt-names = "host-wake"; -- pinctrl-names = "default"; -- pinctrl-0 = <&wifi_host_wake_l>; -- }; - }; - - &sdmmc { -@@ -663,18 +652,6 @@ - &uart0 { - pinctrl-names = "default"; - pinctrl-0 = <&uart0_xfer &uart0_cts &uart0_rts>; -- status = "okay"; -- -- bluetooth { -- compatible = "brcm,bcm43438-bt"; -- clocks = <&rk808 1>; -- clock-names = "ext_clock"; -- device-wakeup-gpios = <&gpio2 RK_PD3 GPIO_ACTIVE_HIGH>; -- host-wakeup-gpios = <&gpio0 RK_PA4 GPIO_ACTIVE_HIGH>; -- shutdown-gpios = <&gpio0 RK_PB1 GPIO_ACTIVE_HIGH>; -- pinctrl-names = "default"; -- pinctrl-0 = <&bt_host_wake_l &bt_wake_l &bt_enable_h>; -- }; - }; - - &uart2 { -diff --git a/arch/arm64/boot/dts/rockchip/rk3399-rock-pi-4b.dts b/arch/arm64/boot/dts/rockchip/rk3399-rock-pi-4b.dts -new file mode 100644 -index 000000000000..f0055ce2fda0 ---- /dev/null -+++ b/arch/arm64/boot/dts/rockchip/rk3399-rock-pi-4b.dts -@@ -0,0 +1,42 @@ -+// SPDX-License-Identifier: (GPL-2.0+ OR MIT) -+/* -+ * Copyright (c) 2019 Akash Gajjar -+ * Copyright (c) 2019 Pragnesh Patel -+ */ -+ -+/dts-v1/; -+#include "rk3399-rock-pi-4.dtsi" -+ -+/ { -+ model = "Radxa ROCK Pi 4B"; -+ compatible = "radxa,rockpi4b", "radxa,rockpi4", "rockchip,rk3399"; -+}; -+ -+&sdio0 { -+ status = "okay"; -+ -+ brcmf: wifi@1 { -+ compatible = "brcm,bcm4329-fmac"; -+ reg = <1>; -+ interrupt-parent = <&gpio0>; -+ interrupts = ; -+ interrupt-names = "host-wake"; -+ pinctrl-names = "default"; -+ pinctrl-0 = <&wifi_host_wake_l>; -+ }; -+}; -+ -+&uart0 { -+ status = "okay"; -+ -+ bluetooth { -+ compatible = "brcm,bcm43438-bt"; -+ clocks = <&rk808 1>; -+ clock-names = "ext_clock"; -+ device-wakeup-gpios = <&gpio2 RK_PD3 GPIO_ACTIVE_HIGH>; -+ host-wakeup-gpios = <&gpio0 RK_PA4 GPIO_ACTIVE_HIGH>; -+ shutdown-gpios = <&gpio0 RK_PB1 GPIO_ACTIVE_HIGH>; -+ pinctrl-names = "default"; -+ pinctrl-0 = <&bt_host_wake_l &bt_wake_l &bt_enable_h>; -+ }; -+}; - -From a28e4816e96a5b6f565fbe71e8d333e541a54227 Mon Sep 17 00:00:00 2001 -From: Jagan Teki -Date: Fri, 7 Aug 2020 15:18:26 +0530 -Subject: [PATCH] arm64: dts: rockchip: Add Radxa ROCK Pi 4C support - -Rock PI 4C has AP6256 Wifi/BT, PoE, miniDP, USB Host enabled -GPIO pin change compared to 4B, 4C. - -So, add or enable difference nodes/properties in 4C dts -by including common dtsi. - -Signed-off-by: Jagan Teki -Link: https://lore.kernel.org/r/20200807094826.12019-4-jagan@amarulasolutions.com -Signed-off-by: Heiko Stuebner -(cherry picked from commit 93e0e8ce5fdf549f1715dad00bfbb21b2f69ba8e) ---- - arch/arm64/boot/dts/rockchip/Makefile | 1 + - arch/arm64/boot/dts/rockchip/rk3399-rock-pi-4c.dts | 51 ++++++++++++++++++++++ - 2 files changed, 52 insertions(+) - create mode 100644 arch/arm64/boot/dts/rockchip/rk3399-rock-pi-4c.dts - -diff --git a/arch/arm64/boot/dts/rockchip/Makefile b/arch/arm64/boot/dts/rockchip/Makefile -index 8832d05c2571..02cdb3c4a6c1 100644 ---- a/arch/arm64/boot/dts/rockchip/Makefile -+++ b/arch/arm64/boot/dts/rockchip/Makefile -@@ -35,6 +35,7 @@ dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3399-roc-pc.dtb - dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3399-roc-pc-mezzanine.dtb - dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3399-rock-pi-4a.dtb - dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3399-rock-pi-4b.dtb -+dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3399-rock-pi-4c.dtb - dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3399-rock960.dtb - dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3399-rockpro64-v2.dtb - dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3399-rockpro64.dtb -diff --git a/arch/arm64/boot/dts/rockchip/rk3399-rock-pi-4c.dts b/arch/arm64/boot/dts/rockchip/rk3399-rock-pi-4c.dts -new file mode 100644 -index 000000000000..4c7ebb1c5d2d ---- /dev/null -+++ b/arch/arm64/boot/dts/rockchip/rk3399-rock-pi-4c.dts -@@ -0,0 +1,51 @@ -+// SPDX-License-Identifier: (GPL-2.0+ OR MIT) -+/* -+ * Copyright (c) 2019 Fuzhou Rockchip Electronics Co., Ltd -+ * Copyright (c) 2019 Radxa Limited -+ * Copyright (c) 2019 Amarula Solutions(India) -+ */ -+ -+/dts-v1/; -+#include "rk3399-rock-pi-4.dtsi" -+ -+/ { -+ model = "Radxa ROCK Pi 4C"; -+ compatible = "radxa,rockpi4c", "radxa,rockpi4", "rockchip,rk3399"; -+}; -+ -+&sdio0 { -+ status = "okay"; -+ -+ brcmf: wifi@1 { -+ compatible = "brcm,bcm4329-fmac"; -+ reg = <1>; -+ interrupt-parent = <&gpio0>; -+ interrupts = ; -+ interrupt-names = "host-wake"; -+ pinctrl-names = "default"; -+ pinctrl-0 = <&wifi_host_wake_l>; -+ }; -+}; -+ -+&uart0 { -+ status = "okay"; -+ -+ bluetooth { -+ compatible = "brcm,bcm43438-bt"; -+ clocks = <&rk808 1>; -+ clock-names = "ext_clock"; -+ device-wakeup-gpios = <&gpio2 RK_PD3 GPIO_ACTIVE_HIGH>; -+ host-wakeup-gpios = <&gpio0 RK_PA4 GPIO_ACTIVE_HIGH>; -+ shutdown-gpios = <&gpio0 RK_PB1 GPIO_ACTIVE_HIGH>; -+ pinctrl-names = "default"; -+ pinctrl-0 = <&bt_host_wake_l &bt_wake_l &bt_enable_h>; -+ }; -+}; -+ -+&vcc5v0_host { -+ gpio = <&gpio3 RK_PD6 GPIO_ACTIVE_HIGH>; -+}; -+ -+&vcc5v0_host_en { -+ rockchip,pins = <3 RK_PD6 RK_FUNC_GPIO &pcfg_pull_none>; -+}; - -From c89d84dcef9b307af733aaaedbf1614b4b266341 Mon Sep 17 00:00:00 2001 -From: Johan Jonker -Date: Sat, 8 Aug 2020 18:06:17 +0200 -Subject: [PATCH] dt-bindings: arm: rockchip: add Zkmagic A95X Z2 description - -Add Zkmagic A95X Z2 description for a board with rk3318 processor. - -Signed-off-by: Johan Jonker -Acked-by: Rob Herring -Link: https://lore.kernel.org/r/20200808160618.15445-3-jbx6244@gmail.com -Signed-off-by: Heiko Stuebner -(cherry picked from commit 0dc8c62c92d4df35a001b613ebe10f95e4ebf776) ---- - Documentation/devicetree/bindings/arm/rockchip.yaml | 5 +++++ - 1 file changed, 5 insertions(+) - -diff --git a/Documentation/devicetree/bindings/arm/rockchip.yaml b/Documentation/devicetree/bindings/arm/rockchip.yaml -index 7025d00c06cc..251c3ca22e1b 100644 ---- a/Documentation/devicetree/bindings/arm/rockchip.yaml -+++ b/Documentation/devicetree/bindings/arm/rockchip.yaml -@@ -559,4 +559,9 @@ properties: - items: - - const: tronsmart,orion-r68-meta - - const: rockchip,rk3368 -+ -+ - description: Zkmagic A95X Z2 -+ items: -+ - const: zkmagic,a95x-z2 -+ - const: rockchip,rk3318 - ... - -From a4d955617bdc633aa291642c54134dd30d0c1187 Mon Sep 17 00:00:00 2001 -From: Johan Jonker -Date: Sat, 8 Aug 2020 18:06:18 +0200 -Subject: [PATCH] arm64: dts: rockchip: add rk3318 A95X Z2 board - -The rk3318 A95X Z2 boards are sold as TV box. -No further documentation is given, but from the dts files -extracted it seems that the rk3318 processor is simulair -to the rk3328. This dts file contains only the basic nodes -that have support in the mainline kernel. - -Features: - -CPU: RK3318 Quad-Core Cortex-A53 -GPU: Mali-450 -RAM: 2/4GB DDR3 -ROM: EMMC 16/32/64GB -HDMI: HDMI 2.0a for 4k@60Hz -Ethernet: 10/100M standard RJ-45 -WiFi: 2.4G+5G WIFI, 802.11 b/g/n -Bluetooth: 4.0 -1 x USB 3.0 -1 x USB 2.0 -1 x Micro SD card slot -1 x SPDIF -1 x AV -1 x DC IN - -Signed-off-by: Johan Jonker -Link: https://lore.kernel.org/r/20200808160618.15445-4-jbx6244@gmail.com -Signed-off-by: Heiko Stuebner -(cherry picked from commit 964ed0807b5f7b42b8a6ad48531ae9312e19599d) ---- - arch/arm64/boot/dts/rockchip/Makefile | 1 + - arch/arm64/boot/dts/rockchip/rk3318-a95x-z2.dts | 374 ++++++++++++++++++++++++ - 2 files changed, 375 insertions(+) - create mode 100644 arch/arm64/boot/dts/rockchip/rk3318-a95x-z2.dts - -diff --git a/arch/arm64/boot/dts/rockchip/Makefile b/arch/arm64/boot/dts/rockchip/Makefile -index 02cdb3c4a6c1..d53efdf4cb5a 100644 ---- a/arch/arm64/boot/dts/rockchip/Makefile -+++ b/arch/arm64/boot/dts/rockchip/Makefile -@@ -2,6 +2,7 @@ - dtb-$(CONFIG_ARCH_ROCKCHIP) += px30-evb.dtb - dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3308-evb.dtb - dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3308-roc-cc.dtb -+dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3318-a95x-z2.dtb - dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3326-odroid-go2.dtb - dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3328-a1.dtb - dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3328-evb.dtb -diff --git a/arch/arm64/boot/dts/rockchip/rk3318-a95x-z2.dts b/arch/arm64/boot/dts/rockchip/rk3318-a95x-z2.dts -new file mode 100644 -index 000000000000..30c73ef25370 ---- /dev/null -+++ b/arch/arm64/boot/dts/rockchip/rk3318-a95x-z2.dts -@@ -0,0 +1,374 @@ -+// SPDX-License-Identifier: (GPL-2.0+ OR MIT) -+ -+/dts-v1/; -+#include -+#include "rk3328.dtsi" -+ -+/ { -+ model = "A95X Z2"; -+ compatible = "zkmagic,a95x-z2", "rockchip,rk3318"; -+ -+ chosen { -+ stdout-path = "serial2:1500000n8"; -+ }; -+ -+ adc-keys { -+ compatible = "adc-keys"; -+ io-channels = <&saradc 0>; -+ io-channel-names = "buttons"; -+ keyup-threshold-microvolt = <1800000>; -+ poll-interval = <100>; -+ -+ recovery { -+ label = "recovery"; -+ linux,code = ; -+ press-threshold-microvolt = <17000>; -+ }; -+ }; -+ -+ ir-receiver { -+ compatible = "gpio-ir-receiver"; -+ gpios = <&gpio2 RK_PA2 GPIO_ACTIVE_LOW>; -+ pinctrl-0 = <&ir_int>; -+ pinctrl-names = "default"; -+ }; -+ -+ leds { -+ compatible = "gpio-leds"; -+ pinctrl-0 = <&cyx_led_pin>; -+ pinctrl-names = "default"; -+ -+ cyx_led: led-0 { -+ default-state = "on"; -+ gpios = <&gpio2 RK_PC7 GPIO_ACTIVE_LOW>; -+ label = "CYX_LED"; -+ }; -+ }; -+ -+ sdio_pwrseq: sdio-pwrseq { -+ compatible = "mmc-pwrseq-simple"; -+ pinctrl-0 = <&wifi_enable_h>; -+ pinctrl-names = "default"; -+ reset-gpios = <&gpio1 RK_PC2 GPIO_ACTIVE_LOW>; -+ }; -+ -+ spdif-sound { -+ compatible = "simple-audio-card"; -+ simple-audio-card,name = "SPDIF"; -+ -+ simple-audio-card,cpu { -+ sound-dai = <&spdif>; -+ }; -+ -+ simple-audio-card,codec { -+ sound-dai = <&spdif_out>; -+ }; -+ }; -+ -+ spdif_out: spdif-out { -+ compatible = "linux,spdif-dit"; -+ #sound-dai-cells = <0>; -+ }; -+ -+ /* Power tree */ -+ vccio_1v8: vccio-1v8-regulator { -+ compatible = "regulator-fixed"; -+ regulator-name = "vccio_1v8"; -+ regulator-min-microvolt = <1800000>; -+ regulator-max-microvolt = <1800000>; -+ regulator-always-on; -+ }; -+ -+ vccio_3v3: vccio-3v3-regulator { -+ compatible = "regulator-fixed"; -+ regulator-name = "vccio_3v3"; -+ regulator-min-microvolt = <3300000>; -+ regulator-max-microvolt = <3300000>; -+ regulator-always-on; -+ }; -+ -+ vcc_otg_vbus: otg-vbus-regulator { -+ compatible = "regulator-fixed"; -+ gpio = <&gpio0 RK_PA2 GPIO_ACTIVE_HIGH>; -+ pinctrl-0 = <&otg_vbus_drv>; -+ pinctrl-names = "default"; -+ regulator-name = "vcc_otg_vbus"; -+ regulator-min-microvolt = <5000000>; -+ regulator-max-microvolt = <5000000>; -+ enable-active-high; -+ }; -+ -+ vcc_sd: sdmmc-regulator { -+ compatible = "regulator-fixed"; -+ gpio = <&gpio0 RK_PD6 GPIO_ACTIVE_LOW>; -+ pinctrl-0 = <&sdmmc0m1_pin>; -+ pinctrl-names = "default"; -+ regulator-name = "vcc_sd"; -+ regulator-min-microvolt = <3300000>; -+ regulator-max-microvolt = <3300000>; -+ vin-supply = <&vccio_3v3>; -+ }; -+ -+ vdd_arm: vdd-arm { -+ compatible = "pwm-regulator"; -+ pwms = <&pwm0 0 5000 1>; -+ regulator-name = "vdd_arm"; -+ regulator-min-microvolt = <950000>; -+ regulator-max-microvolt = <1400000>; -+ regulator-settling-time-up-us = <250>; -+ regulator-always-on; -+ regulator-boot-on; -+ }; -+ -+ vdd_log: vdd-log { -+ compatible = "pwm-regulator"; -+ pwms = <&pwm1 0 5000 1>; -+ regulator-name = "vdd_log"; -+ regulator-min-microvolt = <900000>; -+ regulator-max-microvolt = <1300000>; -+ regulator-settling-time-up-us = <250>; -+ regulator-always-on; -+ regulator-boot-on; -+ }; -+}; -+ -+&analog_sound { -+ status = "okay"; -+}; -+ -+&codec { -+ status = "okay"; -+}; -+ -+&cpu0 { -+ cpu-supply = <&vdd_arm>; -+}; -+ -+&cpu1 { -+ cpu-supply = <&vdd_arm>; -+}; -+ -+&cpu2 { -+ cpu-supply = <&vdd_arm>; -+}; -+ -+&cpu3 { -+ cpu-supply = <&vdd_arm>; -+}; -+ -+&cpu0_opp_table { -+ opp-1200000000 { -+ status = "disabled"; -+ }; -+ -+ opp-1296000000 { -+ status = "disabled"; -+ }; -+}; -+ -+&emmc { -+ bus-width = <8>; -+ cap-mmc-highspeed; -+ non-removable; -+ pinctrl-0 = <&emmc_clk &emmc_cmd &emmc_bus8>; -+ pinctrl-names = "default"; -+ status = "okay"; -+}; -+ -+&gmac2phy { -+ assigned-clock-parents = <&cru SCLK_MAC2PHY_SRC>; -+ assigned-clock-rate = <50000000>; -+ assigned-clocks = <&cru SCLK_MAC2PHY>; -+ clock_in_out = "output"; -+ status = "okay"; -+}; -+ -+&gpu { -+ mali-supply = <&vdd_log>; -+}; -+ -+&hdmi { -+ ddc-i2c-scl-high-time-ns = <9625>; -+ ddc-i2c-scl-low-time-ns = <10000>; -+ status = "okay"; -+}; -+ -+&hdmiphy { -+ status = "okay"; -+}; -+ -+&hdmi_sound { -+ status = "okay"; -+}; -+ -+&i2s0 { -+ status = "okay"; -+}; -+ -+&i2s1 { -+ status = "okay"; -+}; -+ -+&io_domains { -+ pmuio-supply = <&vccio_3v3>; -+ vccio1-supply = <&vccio_3v3>; -+ vccio2-supply = <&vccio_1v8>; -+ vccio3-supply = <&vccio_3v3>; -+ vccio4-supply = <&vccio_1v8>; -+ vccio5-supply = <&vccio_3v3>; -+ vccio6-supply = <&vccio_3v3>; -+ status = "okay"; -+}; -+ -+&pinctrl { -+ ir { -+ ir_int: ir-int { -+ rockchip,pins = <2 RK_PA2 RK_FUNC_GPIO &pcfg_pull_none>; -+ }; -+ }; -+ -+ leds { -+ cyx_led_pin: cyx-led-pin { -+ rockchip,pins = <2 RK_PC7 RK_FUNC_GPIO &pcfg_pull_none>; -+ }; -+ }; -+ -+ pwm0 { -+ pwm0_pin_pull_up: pwm0-pin-pull-up { -+ rockchip,pins = <2 RK_PA4 1 &pcfg_pull_up>; -+ }; -+ }; -+ -+ pwm1 { -+ pwm1_pin_pull_up: pwm1-pin-pull-up { -+ rockchip,pins = <2 RK_PA5 1 &pcfg_pull_up>; -+ }; -+ }; -+ -+ sdio-pwrseq { -+ wifi_enable_h: wifi-enable-h { -+ rockchip,pins = <1 RK_PC2 RK_FUNC_GPIO &pcfg_pull_none>; -+ }; -+ }; -+ -+ sdmmc1 { -+ clk_32k_out: clk-32k-out { -+ rockchip,pins = <1 RK_PD4 1 &pcfg_pull_none>; -+ }; -+ }; -+ -+ usb { -+ host_vbus_drv: host-vbus-drv { -+ rockchip,pins = <0 RK_PA0 RK_FUNC_GPIO &pcfg_pull_none>; -+ }; -+ -+ otg_vbus_drv: otg-vbus-drv { -+ rockchip,pins = <0 RK_PA2 RK_FUNC_GPIO &pcfg_pull_none>; -+ }; -+ }; -+}; -+ -+&pwm0 { -+ pinctrl-0 = <&pwm0_pin_pull_up>; -+ pinctrl-names = "active"; -+ status = "okay"; -+}; -+ -+&pwm1 { -+ pinctrl-0 = <&pwm1_pin_pull_up>; -+ pinctrl-names = "active"; -+ status = "okay"; -+}; -+ -+&saradc { -+ vref-supply = <&vccio_1v8>; -+ status = "okay"; -+}; -+ -+&sdio { -+ bus-width = <4>; -+ cap-sd-highspeed; -+ cap-sdio-irq; -+ keep-power-in-suspend; -+ max-frequency = <125000000>; -+ mmc-pwrseq = <&sdio_pwrseq>; -+ non-removable; -+ pinctrl-0 = <&sdmmc1_bus4 &sdmmc1_cmd &sdmmc1_clk &clk_32k_out>; -+ pinctrl-names = "default"; -+ sd-uhs-sdr104; -+ status = "okay"; -+}; -+ -+&sdmmc { -+ bus-width = <4>; -+ cap-sd-highspeed; -+ pinctrl-0 = <&sdmmc0_clk &sdmmc0_cmd &sdmmc0_dectn &sdmmc0_bus4>; -+ pinctrl-names = "default"; -+ vmmc-supply = <&vcc_sd>; -+ status = "okay"; -+}; -+ -+&spdif { -+ pinctrl-0 = <&spdifm0_tx>; -+ status = "okay"; -+}; -+ -+&soc_crit { -+ temperature = <115000>; /* millicelsius */ -+}; -+ -+&target { -+ temperature = <105000>; /* millicelsius */ -+}; -+ -+&threshold { -+ temperature = <90000>; /* millicelsius */ -+}; -+ -+&tsadc { -+ rockchip,hw-tshut-temp = <120000>; -+ status = "okay"; -+}; -+ -+&u2phy { -+ status = "okay"; -+}; -+ -+&u2phy_host { -+ status = "okay"; -+}; -+ -+&u2phy_otg { -+ phy-supply = <&vcc_otg_vbus>; -+ status = "okay"; -+}; -+ -+&uart0 { -+ pinctrl-0 = <&uart0_xfer &uart0_cts>; -+ status = "okay"; -+}; -+ -+&uart2 { -+ status = "okay"; -+}; -+ -+&usb20_otg { -+ dr_mode = "host"; -+ status = "okay"; -+}; -+ -+&usb_host0_ehci { -+ status = "okay"; -+}; -+ -+&usb_host0_ohci { -+ status = "okay"; -+}; -+ -+&vop { -+ status = "okay"; -+}; -+ -+&vop_mmu { -+ status = "okay"; -+}; - -From 739bf33933935649816771290e0f7e87ed9dcd44 Mon Sep 17 00:00:00 2001 -From: Johan Jonker -Date: Thu, 13 Aug 2020 20:17:11 +0200 -Subject: [PATCH] arm64: dts: rockchip: fix cpu-supply for rk3328-evb - -The property cpu-supply should be added to each cpu separately, -so fix that for rk3328-evb. - -Signed-off-by: Johan Jonker -Link: https://lore.kernel.org/r/20200813181711.15906-1-jbx6244@gmail.com -Signed-off-by: Heiko Stuebner -(cherry picked from commit 4be8df7b3bcd46a75f7e297ef310234975a437d8) ---- - arch/arm64/boot/dts/rockchip/rk3328-evb.dts | 12 ++++++++++++ - 1 file changed, 12 insertions(+) - -diff --git a/arch/arm64/boot/dts/rockchip/rk3328-evb.dts b/arch/arm64/boot/dts/rockchip/rk3328-evb.dts -index 1969dab84138..a48767931af6 100644 ---- a/arch/arm64/boot/dts/rockchip/rk3328-evb.dts -+++ b/arch/arm64/boot/dts/rockchip/rk3328-evb.dts -@@ -70,6 +70,18 @@ - cpu-supply = <&vdd_arm>; - }; - -+&cpu1 { -+ cpu-supply = <&vdd_arm>; -+}; -+ -+&cpu2 { -+ cpu-supply = <&vdd_arm>; -+}; -+ -+&cpu3 { -+ cpu-supply = <&vdd_arm>; -+}; -+ - &emmc { - bus-width = <8>; - cap-mmc-highspeed; - -From 4a30b39b5d073898b065e24af70688d0572bbacb Mon Sep 17 00:00:00 2001 -From: Johan Jonker -Date: Thu, 13 Aug 2020 20:02:41 +0200 -Subject: [PATCH] ARM: dts: rockchip: update cpu supplies on rk3288 - -The use of cpu0-supply for cpu0 alone is deprecated, -so add cpu-supply to each cpu separately and -update all existing rk3288 boards that use this property. - -Signed-off-by: Johan Jonker -Link: https://lore.kernel.org/r/20200813180241.14660-1-jbx6244@gmail.com -Signed-off-by: Heiko Stuebner -(cherry picked from commit b282ae0511cdb6f17cb5052de20288245a8ecd00) ---- - arch/arm/boot/dts/rk3288-miqi.dts | 14 +++++++++++++- - arch/arm/boot/dts/rk3288-popmetal.dts | 14 +++++++++++++- - arch/arm/boot/dts/rk3288-r89.dts | 14 +++++++++++++- - arch/arm/boot/dts/rk3288-vyasa.dts | 14 +++++++++++++- - 4 files changed, 52 insertions(+), 4 deletions(-) - -diff --git a/arch/arm/boot/dts/rk3288-miqi.dts b/arch/arm/boot/dts/rk3288-miqi.dts -index 213c9eb84f76..8a3992105151 100644 ---- a/arch/arm/boot/dts/rk3288-miqi.dts -+++ b/arch/arm/boot/dts/rk3288-miqi.dts -@@ -81,7 +81,19 @@ - }; - - &cpu0 { -- cpu0-supply = <&vdd_cpu>; -+ cpu-supply = <&vdd_cpu>; -+}; -+ -+&cpu1 { -+ cpu-supply = <&vdd_cpu>; -+}; -+ -+&cpu2 { -+ cpu-supply = <&vdd_cpu>; -+}; -+ -+&cpu3 { -+ cpu-supply = <&vdd_cpu>; - }; - - &emmc { -diff --git a/arch/arm/boot/dts/rk3288-popmetal.dts b/arch/arm/boot/dts/rk3288-popmetal.dts -index 6a51940398b5..160ed8b932fb 100644 ---- a/arch/arm/boot/dts/rk3288-popmetal.dts -+++ b/arch/arm/boot/dts/rk3288-popmetal.dts -@@ -103,7 +103,19 @@ - }; - - &cpu0 { -- cpu0-supply = <&vdd_cpu>; -+ cpu-supply = <&vdd_cpu>; -+}; -+ -+&cpu1 { -+ cpu-supply = <&vdd_cpu>; -+}; -+ -+&cpu2 { -+ cpu-supply = <&vdd_cpu>; -+}; -+ -+&cpu3 { -+ cpu-supply = <&vdd_cpu>; - }; - - &emmc { -diff --git a/arch/arm/boot/dts/rk3288-r89.dts b/arch/arm/boot/dts/rk3288-r89.dts -index a258c7ae5329..e5ba901c7dcb 100644 ---- a/arch/arm/boot/dts/rk3288-r89.dts -+++ b/arch/arm/boot/dts/rk3288-r89.dts -@@ -91,7 +91,19 @@ - }; - - &cpu0 { -- cpu0-supply = <&vdd_cpu>; -+ cpu-supply = <&vdd_cpu>; -+}; -+ -+&cpu1 { -+ cpu-supply = <&vdd_cpu>; -+}; -+ -+&cpu2 { -+ cpu-supply = <&vdd_cpu>; -+}; -+ -+&cpu3 { -+ cpu-supply = <&vdd_cpu>; - }; - - &gmac { -diff --git a/arch/arm/boot/dts/rk3288-vyasa.dts b/arch/arm/boot/dts/rk3288-vyasa.dts -index 1a20854a1317..aa50f8ed4ca0 100644 ---- a/arch/arm/boot/dts/rk3288-vyasa.dts -+++ b/arch/arm/boot/dts/rk3288-vyasa.dts -@@ -125,7 +125,19 @@ - }; - - &cpu0 { -- cpu0-supply = <&vdd_cpu>; -+ cpu-supply = <&vdd_cpu>; -+}; -+ -+&cpu1 { -+ cpu-supply = <&vdd_cpu>; -+}; -+ -+&cpu2 { -+ cpu-supply = <&vdd_cpu>; -+}; -+ -+&cpu3 { -+ cpu-supply = <&vdd_cpu>; - }; - - &emmc { - -From 23f9077620fd1f450589387e5951d0db36d2f6d4 Mon Sep 17 00:00:00 2001 -From: Johan Jonker -Date: Thu, 13 Aug 2020 19:24:50 +0200 -Subject: [PATCH] ARM: dts: rockchip: rk3066a: add label to cpu@1 - -Add label to cpu@1 for later use. - -Signed-off-by: Johan Jonker -Link: https://lore.kernel.org/r/20200813172451.13754-1-jbx6244@gmail.com -Signed-off-by: Heiko Stuebner -(cherry picked from commit 9ab4a7312bf31611f3a9c95470f15b3f2bcd83e3) ---- - arch/arm/boot/dts/rk3066a.dtsi | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/arch/arm/boot/dts/rk3066a.dtsi b/arch/arm/boot/dts/rk3066a.dtsi -index b599394d149d..252750c97f97 100644 ---- a/arch/arm/boot/dts/rk3066a.dtsi -+++ b/arch/arm/boot/dts/rk3066a.dtsi -@@ -36,7 +36,7 @@ - clock-latency = <40000>; - clocks = <&cru ARMCLK>; - }; -- cpu@1 { -+ cpu1: cpu@1 { - device_type = "cpu"; - compatible = "arm,cortex-a9"; - next-level-cache = <&L2>; - -From c9ab5671bc0bceac1179f1566daf964c12c4be03 Mon Sep 17 00:00:00 2001 -From: Johan Jonker -Date: Thu, 13 Aug 2020 19:24:51 +0200 -Subject: [PATCH] ARM: dts: rockchip: update cpu supplies on rk3066a - -The use of cpu0-supply for cpu0 alone is deprecated, -so add cpu-supply to each cpu separately and -update all existing rk3066a boards. - -Signed-off-by: Johan Jonker -Link: https://lore.kernel.org/r/20200813172451.13754-2-jbx6244@gmail.com -Signed-off-by: Heiko Stuebner -(cherry picked from commit 20e464c0f12a9b1930adb0365326037d5b060cee) ---- - arch/arm/boot/dts/rk3066a-bqcurie2.dts | 6 +++++- - arch/arm/boot/dts/rk3066a-marsboard.dts | 6 +++++- - arch/arm/boot/dts/rk3066a-rayeager.dts | 6 +++++- - 3 files changed, 15 insertions(+), 3 deletions(-) - -diff --git a/arch/arm/boot/dts/rk3066a-bqcurie2.dts b/arch/arm/boot/dts/rk3066a-bqcurie2.dts -index 0a56a2f1bc4d..eba7a1344976 100644 ---- a/arch/arm/boot/dts/rk3066a-bqcurie2.dts -+++ b/arch/arm/boot/dts/rk3066a-bqcurie2.dts -@@ -63,7 +63,11 @@ - }; - - &cpu0 { -- cpu0-supply = <&vdd_arm>; -+ cpu-supply = <&vdd_arm>; -+}; -+ -+&cpu1 { -+ cpu-supply = <&vdd_arm>; - }; - - &i2c1 { -diff --git a/arch/arm/boot/dts/rk3066a-marsboard.dts b/arch/arm/boot/dts/rk3066a-marsboard.dts -index 7e01f6406a86..6b121658d93c 100644 ---- a/arch/arm/boot/dts/rk3066a-marsboard.dts -+++ b/arch/arm/boot/dts/rk3066a-marsboard.dts -@@ -47,7 +47,11 @@ - }; - - &cpu0 { -- cpu0-supply = <&vdd_arm>; -+ cpu-supply = <&vdd_arm>; -+}; -+ -+&cpu1 { -+ cpu-supply = <&vdd_arm>; - }; - - &i2c1 { -diff --git a/arch/arm/boot/dts/rk3066a-rayeager.dts b/arch/arm/boot/dts/rk3066a-rayeager.dts -index f9db6bb9fa11..309518403d86 100644 ---- a/arch/arm/boot/dts/rk3066a-rayeager.dts -+++ b/arch/arm/boot/dts/rk3066a-rayeager.dts -@@ -128,7 +128,11 @@ - }; - - &cpu0 { -- cpu0-supply = <&vdd_arm>; -+ cpu-supply = <&vdd_arm>; -+}; -+ -+&cpu1 { -+ cpu-supply = <&vdd_arm>; - }; - - &emac { - -From 4b163a2456edff104e7c9e8d6852afb5aec99b7c Mon Sep 17 00:00:00 2001 -From: Adrian Schmutzler -Date: Sun, 30 Aug 2020 21:08:20 +0200 -Subject: [PATCH] ARM: dts: rockchip: replace status value "ok" by "okay" - -While the DT parser recognizes "ok" as a valid value for the -"status" property, it is actually mentioned nowhere. Use the -proper value "okay" instead, as done in the majority of files -already. - -Signed-off-by: Adrian Schmutzler -Link: https://lore.kernel.org/r/20200830190820.20583-1-freifunk@adrianschmutzler.de -Signed-off-by: Heiko Stuebner -(cherry picked from commit 0cf10e6f94335495f90fc62fb75d9569f6a603fb) ---- - arch/arm/boot/dts/rk3288-evb.dtsi | 2 +- - arch/arm/boot/dts/rk3288-firefly-reload-core.dtsi | 2 +- - arch/arm/boot/dts/rk3288-firefly.dtsi | 2 +- - arch/arm/boot/dts/rk3288-miqi.dts | 2 +- - arch/arm/boot/dts/rk3288-popmetal.dts | 2 +- - arch/arm/boot/dts/rk3288-r89.dts | 2 +- - arch/arm/boot/dts/rk3288-rock2-square.dts | 2 +- - arch/arm/boot/dts/rk3288-tinker.dtsi | 2 +- - 8 files changed, 8 insertions(+), 8 deletions(-) - -diff --git a/arch/arm/boot/dts/rk3288-evb.dtsi b/arch/arm/boot/dts/rk3288-evb.dtsi -index 018802df4c0e..c4ca73b40d4a 100644 ---- a/arch/arm/boot/dts/rk3288-evb.dtsi -+++ b/arch/arm/boot/dts/rk3288-evb.dtsi -@@ -247,7 +247,7 @@ - pinctrl-0 = <&rgmii_pins>; - tx_delay = <0x30>; - rx_delay = <0x10>; -- status = "ok"; -+ status = "okay"; - }; - - &gpu { -diff --git a/arch/arm/boot/dts/rk3288-firefly-reload-core.dtsi b/arch/arm/boot/dts/rk3288-firefly-reload-core.dtsi -index 61435d8ee37b..36efa36b7190 100644 ---- a/arch/arm/boot/dts/rk3288-firefly-reload-core.dtsi -+++ b/arch/arm/boot/dts/rk3288-firefly-reload-core.dtsi -@@ -61,7 +61,7 @@ - snps,reset-gpio = <&gpio4 RK_PB0 GPIO_ACTIVE_LOW>; - tx_delay = <0x30>; - rx_delay = <0x10>; -- status = "ok"; -+ status = "okay"; - }; - - &i2c0 { -diff --git a/arch/arm/boot/dts/rk3288-firefly.dtsi b/arch/arm/boot/dts/rk3288-firefly.dtsi -index e5c4fd4ea67e..7fb582302b32 100644 ---- a/arch/arm/boot/dts/rk3288-firefly.dtsi -+++ b/arch/arm/boot/dts/rk3288-firefly.dtsi -@@ -191,7 +191,7 @@ - snps,reset-gpio = <&gpio4 RK_PB0 GPIO_ACTIVE_LOW>; - tx_delay = <0x30>; - rx_delay = <0x10>; -- status = "ok"; -+ status = "okay"; - }; - - &gpu { -diff --git a/arch/arm/boot/dts/rk3288-miqi.dts b/arch/arm/boot/dts/rk3288-miqi.dts -index 8a3992105151..cf54d5ffff2f 100644 ---- a/arch/arm/boot/dts/rk3288-miqi.dts -+++ b/arch/arm/boot/dts/rk3288-miqi.dts -@@ -120,7 +120,7 @@ - snps,reset-gpio = <&gpio4 RK_PB0 GPIO_ACTIVE_LOW>; - tx_delay = <0x30>; - rx_delay = <0x10>; -- status = "ok"; -+ status = "okay"; - }; - - &hdmi { -diff --git a/arch/arm/boot/dts/rk3288-popmetal.dts b/arch/arm/boot/dts/rk3288-popmetal.dts -index 160ed8b932fb..8c7376d64bc4 100644 ---- a/arch/arm/boot/dts/rk3288-popmetal.dts -+++ b/arch/arm/boot/dts/rk3288-popmetal.dts -@@ -161,7 +161,7 @@ - pinctrl-0 = <&rgmii_pins>; - tx_delay = <0x30>; - rx_delay = <0x10>; -- status = "ok"; -+ status = "okay"; - }; - - &hdmi { -diff --git a/arch/arm/boot/dts/rk3288-r89.dts b/arch/arm/boot/dts/rk3288-r89.dts -index e5ba901c7dcb..55467bc30fa6 100644 ---- a/arch/arm/boot/dts/rk3288-r89.dts -+++ b/arch/arm/boot/dts/rk3288-r89.dts -@@ -119,7 +119,7 @@ - pinctrl-0 = <&rgmii_pins>; - tx_delay = <0x30>; - rx_delay = <0x10>; -- status = "ok"; -+ status = "okay"; - }; - - &hdmi { -diff --git a/arch/arm/boot/dts/rk3288-rock2-square.dts b/arch/arm/boot/dts/rk3288-rock2-square.dts -index 3cca4d0f9b09..c4d1d142d8c6 100644 ---- a/arch/arm/boot/dts/rk3288-rock2-square.dts -+++ b/arch/arm/boot/dts/rk3288-rock2-square.dts -@@ -156,7 +156,7 @@ - }; - - &gmac { -- status = "ok"; -+ status = "okay"; - }; - - &hdmi { -diff --git a/arch/arm/boot/dts/rk3288-tinker.dtsi b/arch/arm/boot/dts/rk3288-tinker.dtsi -index 90e9be443fe6..9c1e38c54eae 100644 ---- a/arch/arm/boot/dts/rk3288-tinker.dtsi -+++ b/arch/arm/boot/dts/rk3288-tinker.dtsi -@@ -137,7 +137,7 @@ - snps,reset-delays-us = <0 10000 1000000>; - tx_delay = <0x30>; - rx_delay = <0x10>; -- status = "ok"; -+ status = "okay"; - }; - - &gpu { - -From 26f3fea877d88bffe0cfbccafb3109a5b4700de9 Mon Sep 17 00:00:00 2001 -From: Adrian Schmutzler -Date: Sun, 30 Aug 2020 22:11:12 +0200 -Subject: [PATCH] arm64: dts: rockchip: replace status value "ok" by "okay" - -While the DT parser recognizes "ok" as a valid value for the -"status" property, it is actually mentioned nowhere. Use the -proper value "okay" instead, as done in the majority of files -already. - -Signed-off-by: Adrian Schmutzler -Link: https://lore.kernel.org/r/20200830201112.1934-1-freifunk@adrianschmutzler.de -Signed-off-by: Heiko Stuebner -(cherry picked from commit 9caff35d7eba8e15c996c694a282fd38b2ea345e) ---- - arch/arm64/boot/dts/rockchip/rk3368-evb.dtsi | 2 +- - arch/arm64/boot/dts/rockchip/rk3368-orion-r68-meta.dts | 2 +- - arch/arm64/boot/dts/rockchip/rk3368-r88.dts | 4 ++-- - 3 files changed, 4 insertions(+), 4 deletions(-) - -diff --git a/arch/arm64/boot/dts/rockchip/rk3368-evb.dtsi b/arch/arm64/boot/dts/rockchip/rk3368-evb.dtsi -index 1c52f47c43a6..87fabc64cc39 100644 ---- a/arch/arm64/boot/dts/rockchip/rk3368-evb.dtsi -+++ b/arch/arm64/boot/dts/rockchip/rk3368-evb.dtsi -@@ -134,7 +134,7 @@ - pinctrl-0 = <&rmii_pins>; - tx_delay = <0x30>; - rx_delay = <0x10>; -- status = "ok"; -+ status = "okay"; - }; - - &i2c0 { -diff --git a/arch/arm64/boot/dts/rockchip/rk3368-orion-r68-meta.dts b/arch/arm64/boot/dts/rockchip/rk3368-orion-r68-meta.dts -index b058ce999e3b..ecce16ecc9c3 100644 ---- a/arch/arm64/boot/dts/rockchip/rk3368-orion-r68-meta.dts -+++ b/arch/arm64/boot/dts/rockchip/rk3368-orion-r68-meta.dts -@@ -183,7 +183,7 @@ - snps,reset-delays-us = <0 10000 1000000>; - tx_delay = <0x30>; - rx_delay = <0x10>; -- status = "ok"; -+ status = "okay"; - }; - - &i2c0 { -diff --git a/arch/arm64/boot/dts/rockchip/rk3368-r88.dts b/arch/arm64/boot/dts/rockchip/rk3368-r88.dts -index 236ab0f1b206..2582fa4b90e2 100644 ---- a/arch/arm64/boot/dts/rockchip/rk3368-r88.dts -+++ b/arch/arm64/boot/dts/rockchip/rk3368-r88.dts -@@ -167,7 +167,7 @@ - pinctrl-0 = <&rmii_pins>; - tx_delay = <0x30>; - rx_delay = <0x10>; -- status = "ok"; -+ status = "okay"; - }; - - &i2c0 { -@@ -198,7 +198,7 @@ - }; - - &io_domains { -- status = "ok"; -+ status = "okay"; - - audio-supply = <&vcc_io>; - gpio30-supply = <&vcc_io>; - -From 28e7a5de4a188cb33017f93a025b3888bf09a74c Mon Sep 17 00:00:00 2001 -From: Krzysztof Kozlowski -Date: Fri, 28 Aug 2020 17:26:35 +0200 -Subject: [PATCH] dmaengine: pl330: Simplify with dev_err_probe() - -Common pattern of handling deferred probe can be simplified with -dev_err_probe(). Less code and the error value gets printed. - -Signed-off-by: Krzysztof Kozlowski -Link: https://lore.kernel.org/r/20200828152637.16903-1-krzk@kernel.org -Signed-off-by: Vinod Koul -(cherry picked from commit af53bef5636d92e81279f4a16f814f8dccf9bf89) ---- - drivers/dma/pl330.c | 9 +++------ - 1 file changed, 3 insertions(+), 6 deletions(-) - -diff --git a/drivers/dma/pl330.c b/drivers/dma/pl330.c -index 106f47298f9e..bb27338ec1ae 100644 ---- a/drivers/dma/pl330.c -+++ b/drivers/dma/pl330.c -@@ -3034,9 +3034,7 @@ pl330_probe(struct amba_device *adev, const struct amba_id *id) - - pl330->rstc = devm_reset_control_get_optional(&adev->dev, "dma"); - if (IS_ERR(pl330->rstc)) { -- if (PTR_ERR(pl330->rstc) != -EPROBE_DEFER) -- dev_err(&adev->dev, "Failed to get reset!\n"); -- return PTR_ERR(pl330->rstc); -+ return dev_err_probe(&adev->dev, PTR_ERR(pl330->rstc), "Failed to get reset!\n"); - } else { - ret = reset_control_deassert(pl330->rstc); - if (ret) { -@@ -3047,9 +3045,8 @@ pl330_probe(struct amba_device *adev, const struct amba_id *id) - - pl330->rstc_ocp = devm_reset_control_get_optional(&adev->dev, "dma-ocp"); - if (IS_ERR(pl330->rstc_ocp)) { -- if (PTR_ERR(pl330->rstc_ocp) != -EPROBE_DEFER) -- dev_err(&adev->dev, "Failed to get OCP reset!\n"); -- return PTR_ERR(pl330->rstc_ocp); -+ return dev_err_probe(&adev->dev, PTR_ERR(pl330->rstc_ocp), -+ "Failed to get OCP reset!\n"); - } else { - ret = reset_control_deassert(pl330->rstc_ocp); - if (ret) { - -From da47d555261d41660af9d1071f22b044079d8aff Mon Sep 17 00:00:00 2001 -From: Robin Murphy -Date: Thu, 3 Sep 2020 21:25:53 +0100 -Subject: [PATCH] dmaengine: pl330: Drop local dma_parms - -Since commit f458488425f1 ("amba: Initialize dma_parms for amba -devices"), struct amba_device already provides a dma_parms structure, -so we can save allocating another one. - -Signed-off-by: Robin Murphy -Link: https://lore.kernel.org/r/c9e58882e33f22f9b0a6d65a5507e24004512148.1599164692.git.robin.murphy@arm.com -Signed-off-by: Vinod Koul -(cherry picked from commit 2fc3cad287c62c6477ab674e4430662b470c3a22) ---- - drivers/dma/pl330.c | 5 ----- - 1 file changed, 5 deletions(-) - -diff --git a/drivers/dma/pl330.c b/drivers/dma/pl330.c -index bb27338ec1ae..000c3c4b4f7a 100644 ---- a/drivers/dma/pl330.c -+++ b/drivers/dma/pl330.c -@@ -460,9 +460,6 @@ struct pl330_dmac { - /* DMA-Engine Device */ - struct dma_device ddma; - -- /* Holds info about sg limitations */ -- struct device_dma_parameters dma_parms; -- - /* Pool of descriptors available for the DMAC's channels */ - struct list_head desc_pool; - /* To protect desc_pool manipulation */ -@@ -3151,8 +3148,6 @@ pl330_probe(struct amba_device *adev, const struct amba_id *id) - } - } - -- adev->dev.dma_parms = &pl330->dma_parms; -- - /* - * This is the limit for transfers with a buswidth of 1, larger - * buswidths will have larger limits. - -From 86d82ef8547894e41cfded4a7521c7dcb6f3dc54 Mon Sep 17 00:00:00 2001 -From: Tuo Li -Date: Mon, 7 Sep 2020 21:09:37 +0800 -Subject: [PATCH] ALSA: rockchip_i2s: fix a possible divide-by-zero bug in - rockchip_i2s_hw_params() - -The variable bclk_rate is checked in: - if (bclk_rate && mclk_rate % bclk_rate) - -This indicates that bclk_rate can be zero. -If so, a divide-by-zero bug will occur: - div_bclk = mclk_rate / bclk_rate; - -To fix this possible bug, the function returns -EINVAL when bclk_rate is -zero. - -Signed-off-by: Tuo Li -Link: https://lore.kernel.org/r/TY2PR04MB4029799E60A5BCAAD5B7B5BBB8280@TY2PR04MB4029.apcprd04.prod.outlook.com -Signed-off-by: Mark Brown -(cherry picked from commit 375e2c352582442783178e6a33c279d6bc9354a2) ---- - sound/soc/rockchip/rockchip_i2s.c | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/sound/soc/rockchip/rockchip_i2s.c b/sound/soc/rockchip/rockchip_i2s.c -index d1438753edb4..593299675b8c 100644 ---- a/sound/soc/rockchip/rockchip_i2s.c -+++ b/sound/soc/rockchip/rockchip_i2s.c -@@ -279,7 +279,7 @@ static int rockchip_i2s_hw_params(struct snd_pcm_substream *substream, - if (i2s->is_master_mode) { - mclk_rate = clk_get_rate(i2s->mclk); - bclk_rate = 2 * 32 * params_rate(params); -- if (bclk_rate && mclk_rate % bclk_rate) -+ if (bclk_rate == 0 || mclk_rate % bclk_rate) - return -EINVAL; - - div_bclk = mclk_rate / bclk_rate; - -From ddbd68d0a7bc4931238977a1a6b35741c77c550c Mon Sep 17 00:00:00 2001 -From: Allen Pais -Date: Mon, 31 Aug 2020 16:05:27 +0530 -Subject: [PATCH] dmaengine: pl330: convert tasklets to use new tasklet_setup() - API - -In preparation for unconditionally passing the -struct tasklet_struct pointer to all tasklet -callbacks, switch to using the new tasklet_setup() -and from_tasklet() to pass the tasklet pointer explicitly. - -Signed-off-by: Romain Perier -Signed-off-by: Allen Pais -Link: https://lore.kernel.org/r/20200831103542.305571-21-allen.lkml@gmail.com -Signed-off-by: Vinod Koul -(cherry picked from commit ab2a98ae4105d805383f840c54fabbb6560e2fc7) ---- - drivers/dma/pl330.c | 12 ++++++------ - 1 file changed, 6 insertions(+), 6 deletions(-) - -diff --git a/drivers/dma/pl330.c b/drivers/dma/pl330.c -index 000c3c4b4f7a..d98fb318dd2d 100644 ---- a/drivers/dma/pl330.c -+++ b/drivers/dma/pl330.c -@@ -1573,9 +1573,9 @@ static void dma_pl330_rqcb(struct dma_pl330_desc *desc, enum pl330_op_err err) - tasklet_schedule(&pch->task); - } - --static void pl330_dotask(unsigned long data) -+static void pl330_dotask(struct tasklet_struct *t) - { -- struct pl330_dmac *pl330 = (struct pl330_dmac *) data; -+ struct pl330_dmac *pl330 = from_tasklet(pl330, t, tasks); - unsigned long flags; - int i; - -@@ -1979,7 +1979,7 @@ static int pl330_add(struct pl330_dmac *pl330) - return ret; - } - -- tasklet_init(&pl330->tasks, pl330_dotask, (unsigned long) pl330); -+ tasklet_setup(&pl330->tasks, pl330_dotask); - - pl330->state = INIT; - -@@ -2062,9 +2062,9 @@ static inline void fill_queue(struct dma_pl330_chan *pch) - } - } - --static void pl330_tasklet(unsigned long data) -+static void pl330_tasklet(struct tasklet_struct *t) - { -- struct dma_pl330_chan *pch = (struct dma_pl330_chan *)data; -+ struct dma_pl330_chan *pch = from_tasklet(pch, t, task); - struct dma_pl330_desc *desc, *_dt; - unsigned long flags; - bool power_down = false; -@@ -2172,7 +2172,7 @@ static int pl330_alloc_chan_resources(struct dma_chan *chan) - return -ENOMEM; - } - -- tasklet_init(&pch->task, pl330_tasklet, (unsigned long) pch); -+ tasklet_setup(&pch->task, pl330_tasklet); - - spin_unlock_irqrestore(&pl330->lock, flags); - - -From 1004f7a89c69a41e05bfb0e50b855192eb13def4 Mon Sep 17 00:00:00 2001 -From: Krzysztof Kozlowski -Date: Wed, 16 Sep 2020 18:17:40 +0200 -Subject: [PATCH] clk: rockchip: rk3308: drop unused mux_timer_src_p -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -The parent names 'mux_timer_src_p' is not used: - - In file included from drivers/clk/rockchip/clk-rk3308.c:13:0: - drivers/clk/rockchip/clk-rk3308.c:136:7: warning: ‘mux_timer_src_p’ defined but not used [-Wunused-const-variable=] - -Signed-off-by: Krzysztof Kozlowski -Link: https://lore.kernel.org/r/20200916161740.14173-6-krzk@kernel.org -Signed-off-by: Heiko Stuebner -(cherry picked from commit 816e87253dec6686d2ef1bc2d84e82f033555046) ---- - drivers/clk/rockchip/clk-rk3308.c | 1 - - 1 file changed, 1 deletion(-) - -diff --git a/drivers/clk/rockchip/clk-rk3308.c b/drivers/clk/rockchip/clk-rk3308.c -index b0baf87a283e..5bf15f2a44b7 100644 ---- a/drivers/clk/rockchip/clk-rk3308.c -+++ b/drivers/clk/rockchip/clk-rk3308.c -@@ -133,7 +133,6 @@ PNAME(mux_uart1_p) = { "clk_uart1_src", "dummy", "clk_uart1_frac" }; - PNAME(mux_uart2_p) = { "clk_uart2_src", "dummy", "clk_uart2_frac" }; - PNAME(mux_uart3_p) = { "clk_uart3_src", "dummy", "clk_uart3_frac" }; - PNAME(mux_uart4_p) = { "clk_uart4_src", "dummy", "clk_uart4_frac" }; --PNAME(mux_timer_src_p) = { "xin24m", "clk_rtc32k" }; - PNAME(mux_dclk_vop_p) = { "dclk_vop_src", "dclk_vop_frac", "xin24m" }; - PNAME(mux_nandc_p) = { "clk_nandc_div", "clk_nandc_div50" }; - PNAME(mux_sdmmc_p) = { "clk_sdmmc_div", "clk_sdmmc_div50" }; - -From 61d1828ae692430d8b032376bae59602398fdb36 Mon Sep 17 00:00:00 2001 -From: Elaine Zhang -Date: Mon, 14 Sep 2020 10:22:20 +0800 -Subject: [PATCH] clk: rockchip: Use clk_hw_register_composite instead of - clk_register_composite calls - -clk_hw_register_composite it's already exported. -Preparation for compilation of rK common clock drivers into modules. - -Reported-by: kernel test robot -Signed-off-by: Elaine Zhang -Reviewed-by: Kever Yang -Reviewed-by: Heiko Stuebner -Reviewed-by: Stephen Boyd -Link: https://lore.kernel.org/r/20200914022225.23613-2-zhangqing@rock-chips.com -Signed-off-by: Heiko Stuebner -(cherry picked from commit 63207c37eac4f15fdebac14685a315c259c0a780) ---- - drivers/clk/rockchip/clk-half-divider.c | 18 +++++----- - drivers/clk/rockchip/clk.c | 61 ++++++++++++++++----------------- - 2 files changed, 40 insertions(+), 39 deletions(-) - -diff --git a/drivers/clk/rockchip/clk-half-divider.c b/drivers/clk/rockchip/clk-half-divider.c -index b333fc28c94b..e97fd3dfbae7 100644 ---- a/drivers/clk/rockchip/clk-half-divider.c -+++ b/drivers/clk/rockchip/clk-half-divider.c -@@ -166,7 +166,7 @@ struct clk *rockchip_clk_register_halfdiv(const char *name, - unsigned long flags, - spinlock_t *lock) - { -- struct clk *clk = ERR_PTR(-ENOMEM); -+ struct clk_hw *hw; - struct clk_mux *mux = NULL; - struct clk_gate *gate = NULL; - struct clk_divider *div = NULL; -@@ -212,16 +212,18 @@ struct clk *rockchip_clk_register_halfdiv(const char *name, - div_ops = &clk_half_divider_ops; - } - -- clk = clk_register_composite(NULL, name, parent_names, num_parents, -- mux ? &mux->hw : NULL, mux_ops, -- div ? &div->hw : NULL, div_ops, -- gate ? &gate->hw : NULL, gate_ops, -- flags); -+ hw = clk_hw_register_composite(NULL, name, parent_names, num_parents, -+ mux ? &mux->hw : NULL, mux_ops, -+ div ? &div->hw : NULL, div_ops, -+ gate ? &gate->hw : NULL, gate_ops, -+ flags); -+ if (IS_ERR(hw)) -+ goto err_div; - -- return clk; -+ return hw->clk; - err_div: - kfree(gate); - err_gate: - kfree(mux); -- return ERR_PTR(-ENOMEM); -+ return ERR_CAST(hw); - } -diff --git a/drivers/clk/rockchip/clk.c b/drivers/clk/rockchip/clk.c -index 546e810c3560..46409972983e 100644 ---- a/drivers/clk/rockchip/clk.c -+++ b/drivers/clk/rockchip/clk.c -@@ -43,7 +43,7 @@ static struct clk *rockchip_clk_register_branch(const char *name, - u8 gate_shift, u8 gate_flags, unsigned long flags, - spinlock_t *lock) - { -- struct clk *clk; -+ struct clk_hw *hw; - struct clk_mux *mux = NULL; - struct clk_gate *gate = NULL; - struct clk_divider *div = NULL; -@@ -100,20 +100,18 @@ static struct clk *rockchip_clk_register_branch(const char *name, - : &clk_divider_ops; - } - -- clk = clk_register_composite(NULL, name, parent_names, num_parents, -- mux ? &mux->hw : NULL, mux_ops, -- div ? &div->hw : NULL, div_ops, -- gate ? &gate->hw : NULL, gate_ops, -- flags); -- -- if (IS_ERR(clk)) { -- ret = PTR_ERR(clk); -- goto err_composite; -+ hw = clk_hw_register_composite(NULL, name, parent_names, num_parents, -+ mux ? &mux->hw : NULL, mux_ops, -+ div ? &div->hw : NULL, div_ops, -+ gate ? &gate->hw : NULL, gate_ops, -+ flags); -+ if (IS_ERR(hw)) { -+ kfree(div); -+ kfree(gate); -+ return ERR_CAST(hw); - } - -- return clk; --err_composite: -- kfree(div); -+ return hw->clk; - err_div: - kfree(gate); - err_gate: -@@ -214,8 +212,8 @@ static struct clk *rockchip_clk_register_frac_branch( - unsigned long flags, struct rockchip_clk_branch *child, - spinlock_t *lock) - { -+ struct clk_hw *hw; - struct rockchip_clk_frac *frac; -- struct clk *clk; - struct clk_gate *gate = NULL; - struct clk_fractional_divider *div = NULL; - const struct clk_ops *div_ops = NULL, *gate_ops = NULL; -@@ -255,14 +253,14 @@ static struct clk *rockchip_clk_register_frac_branch( - div->approximation = rockchip_fractional_approximation; - div_ops = &clk_fractional_divider_ops; - -- clk = clk_register_composite(NULL, name, parent_names, num_parents, -- NULL, NULL, -- &div->hw, div_ops, -- gate ? &gate->hw : NULL, gate_ops, -- flags | CLK_SET_RATE_UNGATE); -- if (IS_ERR(clk)) { -+ hw = clk_hw_register_composite(NULL, name, parent_names, num_parents, -+ NULL, NULL, -+ &div->hw, div_ops, -+ gate ? &gate->hw : NULL, gate_ops, -+ flags | CLK_SET_RATE_UNGATE); -+ if (IS_ERR(hw)) { - kfree(frac); -- return clk; -+ return ERR_CAST(hw); - } - - if (child) { -@@ -292,7 +290,7 @@ static struct clk *rockchip_clk_register_frac_branch( - mux_clk = clk_register(NULL, &frac_mux->hw); - if (IS_ERR(mux_clk)) { - kfree(frac); -- return clk; -+ return mux_clk; - } - - rockchip_clk_add_lookup(ctx, mux_clk, child->id); -@@ -301,7 +299,7 @@ static struct clk *rockchip_clk_register_frac_branch( - if (frac->mux_frac_idx >= 0) { - pr_debug("%s: found fractional parent in mux at pos %d\n", - __func__, frac->mux_frac_idx); -- ret = clk_notifier_register(clk, &frac->clk_nb); -+ ret = clk_notifier_register(hw->clk, &frac->clk_nb); - if (ret) - pr_err("%s: failed to register clock notifier for %s\n", - __func__, name); -@@ -311,7 +309,7 @@ static struct clk *rockchip_clk_register_frac_branch( - } - } - -- return clk; -+ return hw->clk; - } - - static struct clk *rockchip_clk_register_factor_branch(const char *name, -@@ -320,7 +318,7 @@ static struct clk *rockchip_clk_register_factor_branch(const char *name, - int gate_offset, u8 gate_shift, u8 gate_flags, - unsigned long flags, spinlock_t *lock) - { -- struct clk *clk; -+ struct clk_hw *hw; - struct clk_gate *gate = NULL; - struct clk_fixed_factor *fix = NULL; - -@@ -349,16 +347,17 @@ static struct clk *rockchip_clk_register_factor_branch(const char *name, - fix->mult = mult; - fix->div = div; - -- clk = clk_register_composite(NULL, name, parent_names, num_parents, -- NULL, NULL, -- &fix->hw, &clk_fixed_factor_ops, -- &gate->hw, &clk_gate_ops, flags); -- if (IS_ERR(clk)) { -+ hw = clk_hw_register_composite(NULL, name, parent_names, num_parents, -+ NULL, NULL, -+ &fix->hw, &clk_fixed_factor_ops, -+ &gate->hw, &clk_gate_ops, flags); -+ if (IS_ERR(hw)) { - kfree(fix); - kfree(gate); -+ return ERR_CAST(hw); - } - -- return clk; -+ return hw->clk; - } - - struct rockchip_clk_provider * __init rockchip_clk_init(struct device_node *np, - -From ec0b48760e3c0efb4522dfedf3a5088e538991c5 Mon Sep 17 00:00:00 2001 -From: Elaine Zhang -Date: Mon, 14 Sep 2020 10:22:21 +0800 -Subject: [PATCH] clk: rockchip: Export rockchip_clk_register_ddrclk() - -This is used by the Rockchip clk driver, export it to allow that -driver to be compiled as a module.. - -Signed-off-by: Elaine Zhang -Reviewed-by: Kever Yang -Reviewed-by: Stephen Boyd -Link: https://lore.kernel.org/r/20200914022225.23613-3-zhangqing@rock-chips.com -Signed-off-by: Heiko Stuebner -(cherry picked from commit f73907de3493b94d80af5122bcacc98f0e7b295b) ---- - drivers/clk/rockchip/clk-ddr.c | 1 + - 1 file changed, 1 insertion(+) - -diff --git a/drivers/clk/rockchip/clk-ddr.c b/drivers/clk/rockchip/clk-ddr.c -index 9273bce4d7b6..86718c54e56b 100644 ---- a/drivers/clk/rockchip/clk-ddr.c -+++ b/drivers/clk/rockchip/clk-ddr.c -@@ -136,3 +136,4 @@ struct clk *rockchip_clk_register_ddrclk(const char *name, int flags, - - return clk; - } -+EXPORT_SYMBOL_GPL(rockchip_clk_register_ddrclk); - -From e2b0bd39722ef935b30bacf97a23446297169ac7 Mon Sep 17 00:00:00 2001 -From: Elaine Zhang -Date: Mon, 14 Sep 2020 10:22:22 +0800 -Subject: [PATCH] clk: rockchip: Export rockchip_register_softrst() - -This is used by the Rockchip clk driver, export it to allow that -driver to be compiled as a module.. - -Signed-off-by: Elaine Zhang -Reviewed-by: Kever Yang -Reviewed-by: Stephen Boyd -Link: https://lore.kernel.org/r/20200914022225.23613-4-zhangqing@rock-chips.com -Signed-off-by: Heiko Stuebner -(cherry picked from commit 37353491d1a8c207685c138c3640bd43864b70d9) ---- - drivers/clk/rockchip/softrst.c | 7 ++++--- - 1 file changed, 4 insertions(+), 3 deletions(-) - -diff --git a/drivers/clk/rockchip/softrst.c b/drivers/clk/rockchip/softrst.c -index 5f1ff5e47c4f..5d07266745b8 100644 ---- a/drivers/clk/rockchip/softrst.c -+++ b/drivers/clk/rockchip/softrst.c -@@ -77,9 +77,9 @@ static const struct reset_control_ops rockchip_softrst_ops = { - .deassert = rockchip_softrst_deassert, - }; - --void __init rockchip_register_softrst(struct device_node *np, -- unsigned int num_regs, -- void __iomem *base, u8 flags) -+void rockchip_register_softrst(struct device_node *np, -+ unsigned int num_regs, -+ void __iomem *base, u8 flags) - { - struct rockchip_softrst *softrst; - int ret; -@@ -107,3 +107,4 @@ void __init rockchip_register_softrst(struct device_node *np, - kfree(softrst); - } - }; -+EXPORT_SYMBOL_GPL(rockchip_register_softrst); - -From 8af53c34ecbf759fccf3769fa03d43db2ac554cb Mon Sep 17 00:00:00 2001 -From: Elaine Zhang -Date: Mon, 14 Sep 2020 10:22:23 +0800 -Subject: [PATCH] clk: rockchip: Export some clock common APIs for module - drivers - -This is used by the Rockchip clk driver, export it to allow that -driver to be compiled as a module. - -Signed-off-by: Elaine Zhang -Reviewed-by: Kever Yang -Reviewed-by: Stephen Boyd -Link: https://lore.kernel.org/r/20200914022225.23613-5-zhangqing@rock-chips.com -Signed-off-by: Heiko Stuebner -(cherry picked from commit ea650c26611dd61adfcc8647d6144f2c9f453d90) ---- - drivers/clk/rockchip/clk.c | 52 ++++++++++++++++++++++++++-------------------- - 1 file changed, 30 insertions(+), 22 deletions(-) - -diff --git a/drivers/clk/rockchip/clk.c b/drivers/clk/rockchip/clk.c -index 46409972983e..b443169dd408 100644 ---- a/drivers/clk/rockchip/clk.c -+++ b/drivers/clk/rockchip/clk.c -@@ -360,8 +360,9 @@ static struct clk *rockchip_clk_register_factor_branch(const char *name, - return hw->clk; - } - --struct rockchip_clk_provider * __init rockchip_clk_init(struct device_node *np, -- void __iomem *base, unsigned long nr_clks) -+struct rockchip_clk_provider *rockchip_clk_init(struct device_node *np, -+ void __iomem *base, -+ unsigned long nr_clks) - { - struct rockchip_clk_provider *ctx; - struct clk **clk_table; -@@ -393,14 +394,16 @@ struct rockchip_clk_provider * __init rockchip_clk_init(struct device_node *np, - kfree(ctx); - return ERR_PTR(-ENOMEM); - } -+EXPORT_SYMBOL_GPL(rockchip_clk_init); - --void __init rockchip_clk_of_add_provider(struct device_node *np, -- struct rockchip_clk_provider *ctx) -+void rockchip_clk_of_add_provider(struct device_node *np, -+ struct rockchip_clk_provider *ctx) - { - if (of_clk_add_provider(np, of_clk_src_onecell_get, - &ctx->clk_data)) - pr_err("%s: could not register clk provider\n", __func__); - } -+EXPORT_SYMBOL_GPL(rockchip_clk_of_add_provider); - - void rockchip_clk_add_lookup(struct rockchip_clk_provider *ctx, - struct clk *clk, unsigned int id) -@@ -408,8 +411,9 @@ void rockchip_clk_add_lookup(struct rockchip_clk_provider *ctx, - if (ctx->clk_data.clks && id) - ctx->clk_data.clks[id] = clk; - } -+EXPORT_SYMBOL_GPL(rockchip_clk_add_lookup); - --void __init rockchip_clk_register_plls(struct rockchip_clk_provider *ctx, -+void rockchip_clk_register_plls(struct rockchip_clk_provider *ctx, - struct rockchip_pll_clock *list, - unsigned int nr_pll, int grf_lock_offset) - { -@@ -432,11 +436,11 @@ void __init rockchip_clk_register_plls(struct rockchip_clk_provider *ctx, - rockchip_clk_add_lookup(ctx, clk, list->id); - } - } -+EXPORT_SYMBOL_GPL(rockchip_clk_register_plls); - --void __init rockchip_clk_register_branches( -- struct rockchip_clk_provider *ctx, -- struct rockchip_clk_branch *list, -- unsigned int nr_clk) -+void rockchip_clk_register_branches(struct rockchip_clk_provider *ctx, -+ struct rockchip_clk_branch *list, -+ unsigned int nr_clk) - { - struct clk *clk = NULL; - unsigned int idx; -@@ -565,14 +569,15 @@ void __init rockchip_clk_register_branches( - rockchip_clk_add_lookup(ctx, clk, list->id); - } - } -- --void __init rockchip_clk_register_armclk(struct rockchip_clk_provider *ctx, -- unsigned int lookup_id, -- const char *name, const char *const *parent_names, -- u8 num_parents, -- const struct rockchip_cpuclk_reg_data *reg_data, -- const struct rockchip_cpuclk_rate_table *rates, -- int nrates) -+EXPORT_SYMBOL_GPL(rockchip_clk_register_branches); -+ -+void rockchip_clk_register_armclk(struct rockchip_clk_provider *ctx, -+ unsigned int lookup_id, -+ const char *name, const char *const *parent_names, -+ u8 num_parents, -+ const struct rockchip_cpuclk_reg_data *reg_data, -+ const struct rockchip_cpuclk_rate_table *rates, -+ int nrates) - { - struct clk *clk; - -@@ -587,9 +592,10 @@ void __init rockchip_clk_register_armclk(struct rockchip_clk_provider *ctx, - - rockchip_clk_add_lookup(ctx, clk, lookup_id); - } -+EXPORT_SYMBOL_GPL(rockchip_clk_register_armclk); - --void __init rockchip_clk_protect_critical(const char *const clocks[], -- int nclocks) -+void rockchip_clk_protect_critical(const char *const clocks[], -+ int nclocks) - { - int i; - -@@ -601,6 +607,7 @@ void __init rockchip_clk_protect_critical(const char *const clocks[], - clk_prepare_enable(clk); - } - } -+EXPORT_SYMBOL_GPL(rockchip_clk_protect_critical); - - static void __iomem *rst_base; - static unsigned int reg_restart; -@@ -620,10 +627,10 @@ static struct notifier_block rockchip_restart_handler = { - .priority = 128, - }; - --void __init -+void - rockchip_register_restart_notifier(struct rockchip_clk_provider *ctx, -- unsigned int reg, -- void (*cb)(void)) -+ unsigned int reg, -+ void (*cb)(void)) - { - int ret; - -@@ -635,3 +642,4 @@ rockchip_register_restart_notifier(struct rockchip_clk_provider *ctx, - pr_err("%s: cannot register restart handler, %d\n", - __func__, ret); - } -+EXPORT_SYMBOL_GPL(rockchip_register_restart_notifier); - -From c71d3c0979104408630b2c540ae383b1ff0d4dd3 Mon Sep 17 00:00:00 2001 -From: Elaine Zhang -Date: Mon, 14 Sep 2020 10:23:04 +0800 -Subject: [PATCH] clk: rockchip: fix the clk config to support module build - -use CONFIG_COMMON_CLK_ROCKCHIP for Rk common clk drivers. -use CONFIG_CLK_RKXX for Rk soc clk driver. -Mark CONFIG_CLK_RK3399 to "tristate", -to support building Rk3399 SoC clock driver as module. - -Signed-off-by: Elaine Zhang -Reviewed-by: Kever Yang -Reviewed-by: Stephen Boyd -Link: https://lore.kernel.org/r/20200914022304.23908-1-zhangqing@rock-chips.com -Signed-off-by: Heiko Stuebner -(cherry picked from commit 4d98ed1e126495016f2a3ef4db6379855c4aacf2) ---- - drivers/clk/Kconfig | 1 + - drivers/clk/rockchip/Kconfig | 78 +++++++++++++++++++++++++++++++++++++++++++ - drivers/clk/rockchip/Makefile | 42 ++++++++++++----------- - 3 files changed, 101 insertions(+), 20 deletions(-) - create mode 100644 drivers/clk/rockchip/Kconfig - -diff --git a/drivers/clk/Kconfig b/drivers/clk/Kconfig -index 4026fac9fac3..b41aaed9bd51 100644 ---- a/drivers/clk/Kconfig -+++ b/drivers/clk/Kconfig -@@ -373,6 +373,7 @@ source "drivers/clk/meson/Kconfig" - source "drivers/clk/mvebu/Kconfig" - source "drivers/clk/qcom/Kconfig" - source "drivers/clk/renesas/Kconfig" -+source "drivers/clk/rockchip/Kconfig" - source "drivers/clk/samsung/Kconfig" - source "drivers/clk/sifive/Kconfig" - source "drivers/clk/sprd/Kconfig" -diff --git a/drivers/clk/rockchip/Kconfig b/drivers/clk/rockchip/Kconfig -new file mode 100644 -index 000000000000..524b0e0df0a7 ---- /dev/null -+++ b/drivers/clk/rockchip/Kconfig -@@ -0,0 +1,78 @@ -+# SPDX-License-Identifier: GPL-2.0 -+# common clock support for ROCKCHIP SoC family. -+ -+config COMMON_CLK_ROCKCHIP -+ bool "Rockchip clock controller common support" -+ depends on ARCH_ROCKCHIP -+ default ARCH_ROCKCHIP -+ help -+ Say y here to enable common clock controller for Rockchip platforms. -+ -+if COMMON_CLK_ROCKCHIP -+config CLK_PX30 -+ bool "Rockchip PX30 clock controller support" -+ default y -+ help -+ Build the driver for PX30 Clock Driver. -+ -+config CLK_RV110X -+ bool "Rockchip RV110x clock controller support" -+ default y -+ help -+ Build the driver for RV110x Clock Driver. -+ -+config CLK_RK3036 -+ bool "Rockchip RK3036 clock controller support" -+ default y -+ help -+ Build the driver for RK3036 Clock Driver. -+ -+config CLK_RK312X -+ bool "Rockchip RK312x clock controller support" -+ default y -+ help -+ Build the driver for RK312x Clock Driver. -+ -+config CLK_RK3188 -+ bool "Rockchip RK3188 clock controller support" -+ default y -+ help -+ Build the driver for RK3188 Clock Driver. -+ -+config CLK_RK322X -+ bool "Rockchip RK322x clock controller support" -+ default y -+ help -+ Build the driver for RK322x Clock Driver. -+ -+config CLK_RK3288 -+ bool "Rockchip RK3288 clock controller support" -+ depends on ARM -+ default y -+ help -+ Build the driver for RK3288 Clock Driver. -+ -+config CLK_RK3308 -+ bool "Rockchip RK3308 clock controller support" -+ default y -+ help -+ Build the driver for RK3308 Clock Driver. -+ -+config CLK_RK3328 -+ bool "Rockchip RK3328 clock controller support" -+ default y -+ help -+ Build the driver for RK3328 Clock Driver. -+ -+config CLK_RK3368 -+ bool "Rockchip RK3368 clock controller support" -+ default y -+ help -+ Build the driver for RK3368 Clock Driver. -+ -+config CLK_RK3399 -+ bool "Rockchip RK3399 clock controller support" -+ default y -+ help -+ Build the driver for RK3399 Clock Driver. -+endif -diff --git a/drivers/clk/rockchip/Makefile b/drivers/clk/rockchip/Makefile -index 7c5b5813a87c..a99e4d9bbae1 100644 ---- a/drivers/clk/rockchip/Makefile -+++ b/drivers/clk/rockchip/Makefile -@@ -3,24 +3,26 @@ - # Rockchip Clock specific Makefile - # - --obj-y += clk.o --obj-y += clk-pll.o --obj-y += clk-cpu.o --obj-y += clk-half-divider.o --obj-y += clk-inverter.o --obj-y += clk-mmc-phase.o --obj-y += clk-muxgrf.o --obj-y += clk-ddr.o --obj-$(CONFIG_RESET_CONTROLLER) += softrst.o -+obj-$(CONFIG_COMMON_CLK_ROCKCHIP) += clk-rockchip.o - --obj-y += clk-px30.o --obj-y += clk-rv1108.o --obj-y += clk-rk3036.o --obj-y += clk-rk3128.o --obj-y += clk-rk3188.o --obj-y += clk-rk3228.o --obj-y += clk-rk3288.o --obj-y += clk-rk3308.o --obj-y += clk-rk3328.o --obj-y += clk-rk3368.o --obj-y += clk-rk3399.o -+clk-rockchip-y += clk.o -+clk-rockchip-y += clk-pll.o -+clk-rockchip-y += clk-cpu.o -+clk-rockchip-y += clk-half-divider.o -+clk-rockchip-y += clk-inverter.o -+clk-rockchip-y += clk-mmc-phase.o -+clk-rockchip-y += clk-muxgrf.o -+clk-rockchip-y += clk-ddr.o -+clk-rockchip-$(CONFIG_RESET_CONTROLLER) += softrst.o -+ -+obj-$(CONFIG_CLK_PX30) += clk-px30.o -+obj-$(CONFIG_CLK_RV110X) += clk-rv1108.o -+obj-$(CONFIG_CLK_RK3036) += clk-rk3036.o -+obj-$(CONFIG_CLK_RK312X) += clk-rk3128.o -+obj-$(CONFIG_CLK_RK3188) += clk-rk3188.o -+obj-$(CONFIG_CLK_RK322X) += clk-rk3228.o -+obj-$(CONFIG_CLK_RK3288) += clk-rk3288.o -+obj-$(CONFIG_CLK_RK3308) += clk-rk3308.o -+obj-$(CONFIG_CLK_RK3328) += clk-rk3328.o -+obj-$(CONFIG_CLK_RK3368) += clk-rk3368.o -+obj-$(CONFIG_CLK_RK3399) += clk-rk3399.o - -From 640cf0e121d7879899d26bce21b5c7d954f67b09 Mon Sep 17 00:00:00 2001 -From: Elaine Zhang -Date: Mon, 14 Sep 2020 10:23:16 +0800 -Subject: [PATCH] clk: rockchip: rk3399: Support module build - -support CLK_OF_DECLARE and builtin_platform_driver_probe -double clk init method. -add module author, description and license to support building -Soc Rk3399 clock driver as module. - -Signed-off-by: Elaine Zhang -Reviewed-by: Kever Yang -Reviewed-by: Stephen Boyd -Link: https://lore.kernel.org/r/20200914022316.24045-1-zhangqing@rock-chips.com -Signed-off-by: Heiko Stuebner -(cherry picked from commit 70d839e2761d22eba6facdb3b65faea4d57f355d) ---- - drivers/clk/rockchip/Kconfig | 2 +- - drivers/clk/rockchip/clk-rk3399.c | 56 +++++++++++++++++++++++++++++++++++++++ - 2 files changed, 57 insertions(+), 1 deletion(-) - -diff --git a/drivers/clk/rockchip/Kconfig b/drivers/clk/rockchip/Kconfig -index 524b0e0df0a7..47cd6c5de837 100644 ---- a/drivers/clk/rockchip/Kconfig -+++ b/drivers/clk/rockchip/Kconfig -@@ -71,7 +71,7 @@ config CLK_RK3368 - Build the driver for RK3368 Clock Driver. - - config CLK_RK3399 -- bool "Rockchip RK3399 clock controller support" -+ tristate "Rockchip RK3399 clock controller support" - default y - help - Build the driver for RK3399 Clock Driver. -diff --git a/drivers/clk/rockchip/clk-rk3399.c b/drivers/clk/rockchip/clk-rk3399.c -index ce1d2446f142..7df2f1e00347 100644 ---- a/drivers/clk/rockchip/clk-rk3399.c -+++ b/drivers/clk/rockchip/clk-rk3399.c -@@ -5,9 +5,11 @@ - */ - - #include -+#include - #include - #include - #include -+#include - #include - #include - #include -@@ -1600,3 +1602,57 @@ static void __init rk3399_pmu_clk_init(struct device_node *np) - rockchip_clk_of_add_provider(np, ctx); - } - CLK_OF_DECLARE(rk3399_cru_pmu, "rockchip,rk3399-pmucru", rk3399_pmu_clk_init); -+ -+struct clk_rk3399_inits { -+ void (*inits)(struct device_node *np); -+}; -+ -+static const struct clk_rk3399_inits clk_rk3399_pmucru_init = { -+ .inits = rk3399_pmu_clk_init, -+}; -+ -+static const struct clk_rk3399_inits clk_rk3399_cru_init = { -+ .inits = rk3399_clk_init, -+}; -+ -+static const struct of_device_id clk_rk3399_match_table[] = { -+ { -+ .compatible = "rockchip,rk3399-cru", -+ .data = &clk_rk3399_cru_init, -+ }, { -+ .compatible = "rockchip,rk3399-pmucru", -+ .data = &clk_rk3399_pmucru_init, -+ }, -+ { } -+}; -+MODULE_DEVICE_TABLE(of, clk_rk3399_match_table); -+ -+static int __init clk_rk3399_probe(struct platform_device *pdev) -+{ -+ struct device_node *np = pdev->dev.of_node; -+ const struct of_device_id *match; -+ const struct clk_rk3399_inits *init_data; -+ -+ match = of_match_device(clk_rk3399_match_table, &pdev->dev); -+ if (!match || !match->data) -+ return -EINVAL; -+ -+ init_data = match->data; -+ if (init_data->inits) -+ init_data->inits(np); -+ -+ return 0; -+} -+ -+static struct platform_driver clk_rk3399_driver = { -+ .driver = { -+ .name = "clk-rk3399", -+ .of_match_table = clk_rk3399_match_table, -+ .suppress_bind_attrs = true, -+ }, -+}; -+builtin_platform_driver_probe(clk_rk3399_driver, clk_rk3399_probe); -+ -+MODULE_DESCRIPTION("Rockchip RK3399 Clock Driver"); -+MODULE_LICENSE("GPL"); -+MODULE_ALIAS("platform:clk-rk3399"); - -From 2862d98b5f5d3682afe09bab8fc29c982e3ac0fe Mon Sep 17 00:00:00 2001 -From: David Bauer -Date: Sun, 20 Sep 2020 17:45:27 +0200 -Subject: [PATCH] dt-bindings: Add doc for FriendlyARM NanoPi R2S - -Add devicetree binding documentation for the FriendlyARM NanoPi R2S. - -Signed-off-by: David Bauer -Reviewed-by: Rob Herring -Link: https://lore.kernel.org/r/20200920154528.88185-1-mail@david-bauer.net -Signed-off-by: Heiko Stuebner -(cherry picked from commit 8cfcf3279419acbf2d2c471262bfb18d9e175fc9) ---- - Documentation/devicetree/bindings/arm/rockchip.yaml | 5 +++++ - 1 file changed, 5 insertions(+) - -diff --git a/Documentation/devicetree/bindings/arm/rockchip.yaml b/Documentation/devicetree/bindings/arm/rockchip.yaml -index 251c3ca22e1b..65b4cc2c63f7 100644 ---- a/Documentation/devicetree/bindings/arm/rockchip.yaml -+++ b/Documentation/devicetree/bindings/arm/rockchip.yaml -@@ -104,6 +104,11 @@ properties: - - firefly,roc-rk3399-pc-mezzanine - - const: rockchip,rk3399 - -+ - description: FriendlyElec NanoPi R2S -+ items: -+ - const: friendlyarm,nanopi-r2s -+ - const: rockchip,rk3328 -+ - - description: FriendlyElec NanoPi4 series boards - items: - - enum: - -From 6b865e0835b1517ed2e7d44feb819f83ce3bc138 Mon Sep 17 00:00:00 2001 -From: David Bauer -Date: Sun, 20 Sep 2020 17:45:28 +0200 -Subject: [PATCH] arm64: dts: rockchip: Add support for FriendlyARM NanoPi R2S - -This adds support for the NanoPi R2S from FriendlyARM. - -Rockchip RK3328 SoC -1GB DDR4 RAM -Gigabit Ethernet (WAN) -Gigabit Ethernet (USB3) (LAN) -USB 2.0 Host Port -MicroSD slot -Reset button -WAN - LAN - SYS LED - -Signed-off-by: David Bauer -Link: https://lore.kernel.org/r/20200920154528.88185-2-mail@david-bauer.net -[adapted from sdmmc0m1_gpio to renamed sdmmc0m1_pin] -Reported-by: kernel test robot -Signed-off-by: Heiko Stuebner -(cherry picked from commit f1ec83f880dbeaceb10d33c40c47aa1769b787e8) ---- - arch/arm64/boot/dts/rockchip/Makefile | 1 + - arch/arm64/boot/dts/rockchip/rk3328-nanopi-r2s.dts | 368 +++++++++++++++++++++ - 2 files changed, 369 insertions(+) - create mode 100644 arch/arm64/boot/dts/rockchip/rk3328-nanopi-r2s.dts - -diff --git a/arch/arm64/boot/dts/rockchip/Makefile b/arch/arm64/boot/dts/rockchip/Makefile -index d53efdf4cb5a..26661c7b736b 100644 ---- a/arch/arm64/boot/dts/rockchip/Makefile -+++ b/arch/arm64/boot/dts/rockchip/Makefile -@@ -6,6 +6,7 @@ dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3318-a95x-z2.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-nanopi-r2s.dtb - dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3328-rock64.dtb - dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3328-roc-cc.dtb - dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3368-evb-act8846.dtb -diff --git a/arch/arm64/boot/dts/rockchip/rk3328-nanopi-r2s.dts b/arch/arm64/boot/dts/rockchip/rk3328-nanopi-r2s.dts -new file mode 100644 -index 000000000000..be7a31d81632 ---- /dev/null -+++ b/arch/arm64/boot/dts/rockchip/rk3328-nanopi-r2s.dts -@@ -0,0 +1,368 @@ -+// SPDX-License-Identifier: (GPL-2.0+ OR MIT) -+/* -+ * Copyright (c) 2020 David Bauer -+ */ -+ -+/dts-v1/; -+ -+#include -+#include -+#include "rk3328.dtsi" -+ -+/ { -+ model = "FriendlyElec NanoPi R2S"; -+ compatible = "friendlyarm,nanopi-r2s", "rockchip,rk3328"; -+ -+ chosen { -+ stdout-path = "serial2:1500000n8"; -+ }; -+ -+ gmac_clk: gmac-clock { -+ compatible = "fixed-clock"; -+ clock-frequency = <125000000>; -+ clock-output-names = "gmac_clk"; -+ #clock-cells = <0>; -+ }; -+ -+ keys { -+ compatible = "gpio-keys"; -+ pinctrl-0 = <&reset_button_pin>; -+ pinctrl-names = "default"; -+ -+ reset { -+ label = "reset"; -+ gpios = <&gpio0 RK_PA0 GPIO_ACTIVE_LOW>; -+ linux,code = ; -+ debounce-interval = <50>; -+ }; -+ }; -+ -+ leds { -+ compatible = "gpio-leds"; -+ pinctrl-0 = <&lan_led_pin>, <&sys_led_pin>, <&wan_led_pin>; -+ pinctrl-names = "default"; -+ -+ lan_led: led-0 { -+ gpios = <&gpio2 RK_PB7 GPIO_ACTIVE_HIGH>; -+ label = "nanopi-r2s:green:lan"; -+ }; -+ -+ sys_led: led-1 { -+ gpios = <&gpio0 RK_PA2 GPIO_ACTIVE_HIGH>; -+ label = "nanopi-r2s:red:sys"; -+ }; -+ -+ wan_led: led-2 { -+ gpios = <&gpio2 RK_PC2 GPIO_ACTIVE_HIGH>; -+ label = "nanopi-r2s:green:wan"; -+ }; -+ }; -+ -+ vcc_io_sdio: sdmmcio-regulator { -+ compatible = "regulator-gpio"; -+ enable-active-high; -+ gpios = <&gpio1 RK_PD4 GPIO_ACTIVE_HIGH>; -+ pinctrl-0 = <&sdio_vcc_pin>; -+ pinctrl-names = "default"; -+ regulator-name = "vcc_io_sdio"; -+ regulator-always-on; -+ regulator-min-microvolt = <1800000>; -+ regulator-max-microvolt = <3300000>; -+ regulator-settling-time-us = <5000>; -+ regulator-type = "voltage"; -+ startup-delay-us = <2000>; -+ states = <1800000 0x1 -+ 3300000 0x0>; -+ vin-supply = <&vcc_io_33>; -+ }; -+ -+ vcc_sd: sdmmc-regulator { -+ compatible = "regulator-fixed"; -+ gpio = <&gpio0 RK_PD6 GPIO_ACTIVE_LOW>; -+ pinctrl-0 = <&sdmmc0m1_pin>; -+ pinctrl-names = "default"; -+ regulator-name = "vcc_sd"; -+ regulator-boot-on; -+ regulator-min-microvolt = <3300000>; -+ regulator-max-microvolt = <3300000>; -+ vin-supply = <&vcc_io_33>; -+ }; -+ -+ vdd_5v: vdd-5v { -+ compatible = "regulator-fixed"; -+ regulator-name = "vdd_5v"; -+ regulator-always-on; -+ regulator-boot-on; -+ regulator-min-microvolt = <5000000>; -+ regulator-max-microvolt = <5000000>; -+ }; -+}; -+ -+&cpu0 { -+ cpu-supply = <&vdd_arm>; -+}; -+ -+&cpu1 { -+ cpu-supply = <&vdd_arm>; -+}; -+ -+&cpu2 { -+ cpu-supply = <&vdd_arm>; -+}; -+ -+&cpu3 { -+ cpu-supply = <&vdd_arm>; -+}; -+ -+&gmac2io { -+ assigned-clocks = <&cru SCLK_MAC2IO>, <&cru SCLK_MAC2IO_EXT>; -+ assigned-clock-parents = <&gmac_clk>, <&gmac_clk>; -+ clock_in_out = "input"; -+ phy-handle = <&rtl8211e>; -+ phy-mode = "rgmii"; -+ phy-supply = <&vcc_io_33>; -+ pinctrl-0 = <&rgmiim1_pins>; -+ pinctrl-names = "default"; -+ rx_delay = <0x18>; -+ snps,aal; -+ tx_delay = <0x24>; -+ status = "okay"; -+ -+ mdio { -+ compatible = "snps,dwmac-mdio"; -+ #address-cells = <1>; -+ #size-cells = <0>; -+ -+ rtl8211e: ethernet-phy@1 { -+ reg = <1>; -+ pinctrl-0 = <ð_phy_reset_pin>; -+ pinctrl-names = "default"; -+ reset-assert-us = <10000>; -+ reset-deassert-us = <50000>; -+ reset-gpios = <&gpio1 RK_PC2 GPIO_ACTIVE_LOW>; -+ }; -+ }; -+}; -+ -+&i2c1 { -+ status = "okay"; -+ -+ rk805: pmic@18 { -+ compatible = "rockchip,rk805"; -+ reg = <0x18>; -+ interrupt-parent = <&gpio1>; -+ interrupts = <24 IRQ_TYPE_LEVEL_LOW>; -+ #clock-cells = <1>; -+ clock-output-names = "xin32k", "rk805-clkout2"; -+ gpio-controller; -+ #gpio-cells = <2>; -+ pinctrl-0 = <&pmic_int_l>; -+ pinctrl-names = "default"; -+ rockchip,system-power-controller; -+ wakeup-source; -+ -+ vcc1-supply = <&vdd_5v>; -+ vcc2-supply = <&vdd_5v>; -+ vcc3-supply = <&vdd_5v>; -+ vcc4-supply = <&vdd_5v>; -+ vcc5-supply = <&vcc_io_33>; -+ vcc6-supply = <&vdd_5v>; -+ -+ regulators { -+ vdd_log: DCDC_REG1 { -+ regulator-name = "vdd_log"; -+ regulator-always-on; -+ regulator-boot-on; -+ regulator-min-microvolt = <712500>; -+ regulator-max-microvolt = <1450000>; -+ regulator-ramp-delay = <12500>; -+ -+ regulator-state-mem { -+ regulator-on-in-suspend; -+ regulator-suspend-microvolt = <1000000>; -+ }; -+ }; -+ -+ vdd_arm: DCDC_REG2 { -+ regulator-name = "vdd_arm"; -+ regulator-always-on; -+ regulator-boot-on; -+ regulator-min-microvolt = <712500>; -+ regulator-max-microvolt = <1450000>; -+ regulator-ramp-delay = <12500>; -+ -+ regulator-state-mem { -+ regulator-on-in-suspend; -+ regulator-suspend-microvolt = <950000>; -+ }; -+ }; -+ -+ vcc_ddr: DCDC_REG3 { -+ regulator-name = "vcc_ddr"; -+ regulator-always-on; -+ regulator-boot-on; -+ -+ regulator-state-mem { -+ regulator-on-in-suspend; -+ }; -+ }; -+ -+ vcc_io_33: DCDC_REG4 { -+ regulator-name = "vcc_io_33"; -+ regulator-always-on; -+ regulator-boot-on; -+ regulator-min-microvolt = <3300000>; -+ regulator-max-microvolt = <3300000>; -+ -+ regulator-state-mem { -+ regulator-on-in-suspend; -+ regulator-suspend-microvolt = <3300000>; -+ }; -+ }; -+ -+ vcc_18: LDO_REG1 { -+ regulator-name = "vcc_18"; -+ regulator-always-on; -+ regulator-boot-on; -+ regulator-min-microvolt = <1800000>; -+ regulator-max-microvolt = <1800000>; -+ -+ regulator-state-mem { -+ regulator-on-in-suspend; -+ regulator-suspend-microvolt = <1800000>; -+ }; -+ }; -+ -+ vcc18_emmc: LDO_REG2 { -+ regulator-name = "vcc18_emmc"; -+ regulator-always-on; -+ regulator-boot-on; -+ regulator-min-microvolt = <1800000>; -+ regulator-max-microvolt = <1800000>; -+ -+ regulator-state-mem { -+ regulator-on-in-suspend; -+ regulator-suspend-microvolt = <1800000>; -+ }; -+ }; -+ -+ vdd_10: LDO_REG3 { -+ regulator-name = "vdd_10"; -+ regulator-always-on; -+ regulator-boot-on; -+ regulator-min-microvolt = <1000000>; -+ regulator-max-microvolt = <1000000>; -+ -+ regulator-state-mem { -+ regulator-on-in-suspend; -+ regulator-suspend-microvolt = <1000000>; -+ }; -+ }; -+ }; -+ }; -+}; -+ -+&io_domains { -+ pmuio-supply = <&vcc_io_33>; -+ vccio1-supply = <&vcc_io_33>; -+ vccio2-supply = <&vcc18_emmc>; -+ vccio3-supply = <&vcc_io_sdio>; -+ vccio4-supply = <&vcc_18>; -+ vccio5-supply = <&vcc_io_33>; -+ vccio6-supply = <&vcc_io_33>; -+ status = "okay"; -+}; -+ -+&pinctrl { -+ button { -+ reset_button_pin: reset-button-pin { -+ rockchip,pins = <0 RK_PA0 RK_FUNC_GPIO &pcfg_pull_none>; -+ }; -+ }; -+ -+ ethernet-phy { -+ eth_phy_reset_pin: eth-phy-reset-pin { -+ rockchip,pins = <1 RK_PC2 RK_FUNC_GPIO &pcfg_pull_down>; -+ }; -+ }; -+ -+ leds { -+ lan_led_pin: lan-led-pin { -+ rockchip,pins = <2 RK_PB7 RK_FUNC_GPIO &pcfg_pull_none>; -+ }; -+ -+ sys_led_pin: sys-led-pin { -+ rockchip,pins = <0 RK_PA2 RK_FUNC_GPIO &pcfg_pull_none>; -+ }; -+ -+ wan_led_pin: wan-led-pin { -+ rockchip,pins = <2 RK_PC2 RK_FUNC_GPIO &pcfg_pull_none>; -+ }; -+ }; -+ -+ pmic { -+ pmic_int_l: pmic-int-l { -+ rockchip,pins = <1 RK_PD0 RK_FUNC_GPIO &pcfg_pull_up>; -+ }; -+ }; -+ -+ sd { -+ sdio_vcc_pin: sdio-vcc-pin { -+ rockchip,pins = <1 RK_PD4 RK_FUNC_GPIO &pcfg_pull_up>; -+ }; -+ }; -+}; -+ -+&pwm2 { -+ status = "okay"; -+}; -+ -+&sdmmc { -+ bus-width = <4>; -+ cap-sd-highspeed; -+ disable-wp; -+ pinctrl-0 = <&sdmmc0_clk>, <&sdmmc0_cmd>, <&sdmmc0_dectn>, <&sdmmc0_bus4>; -+ pinctrl-names = "default"; -+ sd-uhs-sdr12; -+ sd-uhs-sdr25; -+ sd-uhs-sdr50; -+ sd-uhs-sdr104; -+ vmmc-supply = <&vcc_sd>; -+ vqmmc-supply = <&vcc_io_sdio>; -+ status = "okay"; -+}; -+ -+&tsadc { -+ rockchip,hw-tshut-mode = <0>; -+ rockchip,hw-tshut-polarity = <0>; -+ status = "okay"; -+}; -+ -+&u2phy { -+ status = "okay"; -+}; -+ -+&u2phy_host { -+ status = "okay"; -+}; -+ -+&u2phy_otg { -+ status = "okay"; -+}; -+ -+&uart2 { -+ status = "okay"; -+}; -+ -+&usb20_otg { -+ status = "okay"; -+ dr_mode = "host"; -+}; -+ -+&usb_host0_ehci { -+ status = "okay"; -+}; -+ -+&usb_host0_ohci { -+ status = "okay"; -+}; - -From f18092b21f3ea3ed7d134b274c64c8edde1fcb30 Mon Sep 17 00:00:00 2001 -From: Artem Lapkin -Date: Wed, 23 Sep 2020 21:08:22 +0800 -Subject: [PATCH] arm64: dts: rockchip: add spiflash node to rk3399-khadas-edge - -The Khadas Edge Boards uses winbond - w25q128 spi flash with 104Mhz - -Signed-off-by: Artem Lapkin -Link: https://lore.kernel.org/r/20200923130823.1612533-2-art@khadas.com -Signed-off-by: Heiko Stuebner -(cherry picked from commit 5d71f44569941386b419398463166fdf1785f4e2) ---- - arch/arm64/boot/dts/rockchip/rk3399-khadas-edge.dtsi | 10 ++++++++++ - 1 file changed, 10 insertions(+) - -diff --git a/arch/arm64/boot/dts/rockchip/rk3399-khadas-edge.dtsi b/arch/arm64/boot/dts/rockchip/rk3399-khadas-edge.dtsi -index e36837c04dc7..c67420578fac 100644 ---- a/arch/arm64/boot/dts/rockchip/rk3399-khadas-edge.dtsi -+++ b/arch/arm64/boot/dts/rockchip/rk3399-khadas-edge.dtsi -@@ -690,6 +690,16 @@ - status = "okay"; - }; - -+&spi1 { -+ status = "okay"; -+ -+ spiflash: flash@0 { -+ compatible = "winbond,w25q128fw", "jedec,spi-nor"; -+ reg = <0>; -+ spi-max-frequency = <104000000>; -+ }; -+}; -+ - &tcphy0 { - status = "okay"; - }; - -From e2cad982d40449e0839c6de164a34a1d2e23d694 Mon Sep 17 00:00:00 2001 -From: Artem Lapkin -Date: Wed, 23 Sep 2020 21:08:23 +0800 -Subject: [PATCH] arm64: dts: rockchip: add ir-receiver node to - rk3399-khadas-edge - -add missed ir-receiver and ir_rx pinctl nodes to rk3399-khadas-edge -Khadas Edge board uses gpio-ir-receiver on RK_PB6 gpio - -Signed-off-by: Artem Lapkin -Link: https://lore.kernel.org/r/20200923130823.1612533-3-art@khadas.com -Signed-off-by: Heiko Stuebner -(cherry picked from commit 30a9a8c16865d37bfc0f1859a398ba1b24eec569) ---- - arch/arm64/boot/dts/rockchip/rk3399-khadas-edge.dtsi | 14 ++++++++++++++ - 1 file changed, 14 insertions(+) - -diff --git a/arch/arm64/boot/dts/rockchip/rk3399-khadas-edge.dtsi b/arch/arm64/boot/dts/rockchip/rk3399-khadas-edge.dtsi -index c67420578fac..635afdd99122 100644 ---- a/arch/arm64/boot/dts/rockchip/rk3399-khadas-edge.dtsi -+++ b/arch/arm64/boot/dts/rockchip/rk3399-khadas-edge.dtsi -@@ -138,6 +138,14 @@ - }; - }; - -+ ir-receiver { -+ compatible = "gpio-ir-receiver"; -+ gpios = <&gpio1 RK_PB6 GPIO_ACTIVE_LOW>; -+ linux,rc-map-name = "rc-khadas"; -+ pinctrl-names = "default"; -+ pinctrl-0 = <&ir_rx>; -+ }; -+ - leds { - compatible = "gpio-leds"; - pinctrl-names = "default"; -@@ -585,6 +593,12 @@ - }; - }; - -+ ir { -+ ir_rx: ir-rx { -+ rockchip,pins = <1 RK_PB6 RK_FUNC_GPIO &pcfg_pull_none>; -+ }; -+ }; -+ - leds { - sys_led_pin: sys-led-pin { - rockchip,pins = <0 RK_PA6 RK_FUNC_GPIO &pcfg_pull_none>; - -From d9ffbaa89722fee3ef963646ea2423ac84f78854 Mon Sep 17 00:00:00 2001 -From: Stephen Boyd -Date: Wed, 23 Sep 2020 17:41:44 -0700 -Subject: [PATCH] clk: rockchip: Initialize hw to error to avoid undefined - behavior - -We can get down to this return value from ERR_CAST() without -initializing hw. Set it to -ENOMEM so that we always return something -sane. - -Fixes the following smatch warning: - -drivers/clk/rockchip/clk-half-divider.c:228 rockchip_clk_register_halfdiv() error: uninitialized symbol 'hw'. -drivers/clk/rockchip/clk-half-divider.c:228 rockchip_clk_register_halfdiv() warn: passing zero to 'ERR_CAST' - -Cc: Elaine Zhang -Cc: Heiko Stuebner -Fixes: 956060a52795 ("clk: rockchip: add support for half divider") -Signed-off-by: Stephen Boyd -(cherry picked from commit f8ac4db0e23c15baa3f379d4f7e007589d7710ed) ---- - drivers/clk/rockchip/clk-half-divider.c | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/drivers/clk/rockchip/clk-half-divider.c b/drivers/clk/rockchip/clk-half-divider.c -index e97fd3dfbae7..ccd5c270c213 100644 ---- a/drivers/clk/rockchip/clk-half-divider.c -+++ b/drivers/clk/rockchip/clk-half-divider.c -@@ -166,7 +166,7 @@ struct clk *rockchip_clk_register_halfdiv(const char *name, - unsigned long flags, - spinlock_t *lock) - { -- struct clk_hw *hw; -+ struct clk_hw *hw = ERR_PTR(-ENOMEM); - struct clk_mux *mux = NULL; - struct clk_gate *gate = NULL; - struct clk_divider *div = NULL; - -From aadd7a83a8a1e799653d9df0cc99bb0633515fbf Mon Sep 17 00:00:00 2001 -From: Vinod Koul -Date: Wed, 30 Sep 2020 17:47:35 +0530 -Subject: [PATCH] dmaengine: pl330: fix argument for tasklet - -Commit 59cd818763e8 ("dmaengine: fsl: convert tasklets to use new -tasklet_setup() API") converted the pl330 driver to use new tasklet -functions but missed that driver calls the tasklet function directly as -well, so update it. - -Fixes: 59cd818763e8 ("dmaengine: fsl: convert tasklets to use new tasklet_setup() API") -Reported-by: kernel test robot -Link: https://lore.kernel.org/r/20200930121735.49699-1-vkoul@kernel.org -Signed-off-by: Vinod Koul -(cherry picked from commit 86ae924a91a4a4297ad9f47e131f74b1dab6cb7a) ---- - drivers/dma/pl330.c | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/drivers/dma/pl330.c b/drivers/dma/pl330.c -index d98fb318dd2d..e9f0101d92fa 100644 ---- a/drivers/dma/pl330.c -+++ b/drivers/dma/pl330.c -@@ -2484,7 +2484,7 @@ static void pl330_issue_pending(struct dma_chan *chan) - list_splice_tail_init(&pch->submitted_list, &pch->work_list); - spin_unlock_irqrestore(&pch->lock, flags); - -- pl330_tasklet((unsigned long)pch); -+ pl330_tasklet(&pch->task); - } - - /* diff --git a/projects/Rockchip/patches/linux/default/linux-0001-rockchip-from-5.11.patch b/projects/Rockchip/patches/linux/default/linux-0001-rockchip-from-5.11.patch new file mode 100644 index 0000000000..27c10f1ff3 --- /dev/null +++ b/projects/Rockchip/patches/linux/default/linux-0001-rockchip-from-5.11.patch @@ -0,0 +1,3068 @@ +From 7bdda3f24987c034767b0834a63bd0379301553a Mon Sep 17 00:00:00 2001 +From: Robin Murphy +Date: Mon, 26 Oct 2020 11:17:20 +0000 +Subject: [PATCH] clk: rockchip: Add appropriate arch dependencies + +There's no point offering support for 32-bit platforms to users +configuring a 64-bit kernel - and vice-versa - unless they are +explicitly interested in compile-testing. + +Signed-off-by: Robin Murphy +Link: https://lore.kernel.org/r/72abb0f794b8ed77e274e8ee21c22e0bd3223dfd.1603710913.git.robin.murphy@arm.com +Signed-off-by: Heiko Stuebner +--- + drivers/clk/rockchip/Kconfig | 12 +++++++++++- + 1 file changed, 11 insertions(+), 1 deletion(-) + +diff --git a/drivers/clk/rockchip/Kconfig b/drivers/clk/rockchip/Kconfig +index 47cd6c5de837..effd05032e85 100644 +--- a/drivers/clk/rockchip/Kconfig ++++ b/drivers/clk/rockchip/Kconfig +@@ -11,67 +11,77 @@ config COMMON_CLK_ROCKCHIP + if COMMON_CLK_ROCKCHIP + config CLK_PX30 + bool "Rockchip PX30 clock controller support" ++ depends on (ARM64 || COMPILE_TEST) + default y + help + Build the driver for PX30 Clock Driver. + + config CLK_RV110X + bool "Rockchip RV110x clock controller support" ++ depends on (ARM || COMPILE_TEST) + default y + help + Build the driver for RV110x Clock Driver. + + config CLK_RK3036 + bool "Rockchip RK3036 clock controller support" ++ depends on (ARM || COMPILE_TEST) + default y + help + Build the driver for RK3036 Clock Driver. + + config CLK_RK312X + bool "Rockchip RK312x clock controller support" ++ depends on (ARM || COMPILE_TEST) + default y + help + Build the driver for RK312x Clock Driver. + + config CLK_RK3188 + bool "Rockchip RK3188 clock controller support" ++ depends on (ARM || COMPILE_TEST) + default y + help + Build the driver for RK3188 Clock Driver. + + config CLK_RK322X + bool "Rockchip RK322x clock controller support" ++ depends on (ARM || COMPILE_TEST) + default y + help + Build the driver for RK322x Clock Driver. + + config CLK_RK3288 + bool "Rockchip RK3288 clock controller support" +- depends on ARM ++ depends on (ARM || COMPILE_TEST) + default y + help + Build the driver for RK3288 Clock Driver. + + config CLK_RK3308 + bool "Rockchip RK3308 clock controller support" ++ depends on (ARM64 || COMPILE_TEST) + default y + help + Build the driver for RK3308 Clock Driver. + + config CLK_RK3328 + bool "Rockchip RK3328 clock controller support" ++ depends on (ARM64 || COMPILE_TEST) + default y + help + Build the driver for RK3328 Clock Driver. + + config CLK_RK3368 + bool "Rockchip RK3368 clock controller support" ++ depends on (ARM64 || COMPILE_TEST) + default y + help + Build the driver for RK3368 Clock Driver. + + config CLK_RK3399 + tristate "Rockchip RK3399 clock controller support" ++ depends on (ARM64 || COMPILE_TEST) + default y + help + Build the driver for RK3399 Clock Driver. + +From 7a9ce2f8a4e405c67287b076e07420766c33f1e6 Mon Sep 17 00:00:00 2001 +From: Xu Wang +Date: Fri, 27 Nov 2020 09:05:51 +0000 +Subject: [PATCH] clk: rockchip: Remove redundant null check before + clk_prepare_enable + +Because clk_prepare_enable() already checked NULL clock parameter, +so the additional check is unnecessary, just remove it. + +Signed-off-by: Xu Wang +Acked-by: Stephen Boyd +Link: https://lore.kernel.org/r/20201127090551.50254-1-vulab@iscas.ac.cn +Signed-off-by: Heiko Stuebner +--- + drivers/clk/rockchip/clk.c | 3 +-- + 1 file changed, 1 insertion(+), 2 deletions(-) + +diff --git a/drivers/clk/rockchip/clk.c b/drivers/clk/rockchip/clk.c +index b443169dd408..336481bc6cc7 100644 +--- a/drivers/clk/rockchip/clk.c ++++ b/drivers/clk/rockchip/clk.c +@@ -603,8 +603,7 @@ void rockchip_clk_protect_critical(const char *const clocks[], + for (i = 0; i < nclocks; i++) { + struct clk *clk = __clk_lookup(clocks[i]); + +- if (clk) +- clk_prepare_enable(clk); ++ clk_prepare_enable(clk); + } + } + EXPORT_SYMBOL_GPL(rockchip_clk_protect_critical); + +From 4e5568fccbf904926141cf11aa5ae5e6870ce1c8 Mon Sep 17 00:00:00 2001 +From: Johan Jonker +Date: Wed, 18 Nov 2020 14:58:16 +0100 +Subject: [PATCH] clk: rockchip: add CLK_SET_RATE_PARENT to sclk for rk3066a + i2s and uart clocks + +Add CLK_SET_RATE_PARENT to sclk for rk3066a i2s and uart clocks, +so that the parent COMPOSITE_FRACMUX and COMPOSITE_NOMUX +also update. + +Signed-off-by: Johan Jonker +Link: https://lore.kernel.org/r/20201118135822.9582-2-jbx6244@gmail.com +Signed-off-by: Heiko Stuebner +--- + drivers/clk/rockchip/clk-rk3188.c | 28 ++++++++++++++-------------- + 1 file changed, 14 insertions(+), 14 deletions(-) + +diff --git a/drivers/clk/rockchip/clk-rk3188.c b/drivers/clk/rockchip/clk-rk3188.c +index 730020fcc7fe..db8c588139de 100644 +--- a/drivers/clk/rockchip/clk-rk3188.c ++++ b/drivers/clk/rockchip/clk-rk3188.c +@@ -255,19 +255,19 @@ static struct rockchip_clk_branch common_spdif_fracmux __initdata = + RK2928_CLKSEL_CON(5), 8, 2, MFLAGS); + + static struct rockchip_clk_branch common_uart0_fracmux __initdata = +- MUX(SCLK_UART0, "sclk_uart0", mux_sclk_uart0_p, 0, ++ MUX(SCLK_UART0, "sclk_uart0", mux_sclk_uart0_p, CLK_SET_RATE_PARENT, + RK2928_CLKSEL_CON(13), 8, 2, MFLAGS); + + static struct rockchip_clk_branch common_uart1_fracmux __initdata = +- MUX(SCLK_UART1, "sclk_uart1", mux_sclk_uart1_p, 0, ++ MUX(SCLK_UART1, "sclk_uart1", mux_sclk_uart1_p, CLK_SET_RATE_PARENT, + RK2928_CLKSEL_CON(14), 8, 2, MFLAGS); + + static struct rockchip_clk_branch common_uart2_fracmux __initdata = +- MUX(SCLK_UART2, "sclk_uart2", mux_sclk_uart2_p, 0, ++ MUX(SCLK_UART2, "sclk_uart2", mux_sclk_uart2_p, CLK_SET_RATE_PARENT, + RK2928_CLKSEL_CON(15), 8, 2, MFLAGS); + + static struct rockchip_clk_branch common_uart3_fracmux __initdata = +- MUX(SCLK_UART3, "sclk_uart3", mux_sclk_uart3_p, 0, ++ MUX(SCLK_UART3, "sclk_uart3", mux_sclk_uart3_p, CLK_SET_RATE_PARENT, + RK2928_CLKSEL_CON(16), 8, 2, MFLAGS); + + static struct rockchip_clk_branch common_clk_branches[] __initdata = { +@@ -408,28 +408,28 @@ static struct rockchip_clk_branch common_clk_branches[] __initdata = { + COMPOSITE_NOMUX(0, "uart0_pre", "uart_src", 0, + RK2928_CLKSEL_CON(13), 0, 7, DFLAGS, + RK2928_CLKGATE_CON(1), 8, GFLAGS), +- COMPOSITE_FRACMUX(0, "uart0_frac", "uart0_pre", 0, ++ COMPOSITE_FRACMUX(0, "uart0_frac", "uart0_pre", CLK_SET_RATE_PARENT, + RK2928_CLKSEL_CON(17), 0, + RK2928_CLKGATE_CON(1), 9, GFLAGS, + &common_uart0_fracmux), + COMPOSITE_NOMUX(0, "uart1_pre", "uart_src", 0, + RK2928_CLKSEL_CON(14), 0, 7, DFLAGS, + RK2928_CLKGATE_CON(1), 10, GFLAGS), +- COMPOSITE_FRACMUX(0, "uart1_frac", "uart1_pre", 0, ++ COMPOSITE_FRACMUX(0, "uart1_frac", "uart1_pre", CLK_SET_RATE_PARENT, + RK2928_CLKSEL_CON(18), 0, + RK2928_CLKGATE_CON(1), 11, GFLAGS, + &common_uart1_fracmux), + COMPOSITE_NOMUX(0, "uart2_pre", "uart_src", 0, + RK2928_CLKSEL_CON(15), 0, 7, DFLAGS, + RK2928_CLKGATE_CON(1), 12, GFLAGS), +- COMPOSITE_FRACMUX(0, "uart2_frac", "uart2_pre", 0, ++ COMPOSITE_FRACMUX(0, "uart2_frac", "uart2_pre", CLK_SET_RATE_PARENT, + RK2928_CLKSEL_CON(19), 0, + RK2928_CLKGATE_CON(1), 13, GFLAGS, + &common_uart2_fracmux), + COMPOSITE_NOMUX(0, "uart3_pre", "uart_src", 0, + RK2928_CLKSEL_CON(16), 0, 7, DFLAGS, + RK2928_CLKGATE_CON(1), 14, GFLAGS), +- COMPOSITE_FRACMUX(0, "uart3_frac", "uart3_pre", 0, ++ COMPOSITE_FRACMUX(0, "uart3_frac", "uart3_pre", CLK_SET_RATE_PARENT, + RK2928_CLKSEL_CON(20), 0, + RK2928_CLKGATE_CON(1), 15, GFLAGS, + &common_uart3_fracmux), +@@ -543,15 +543,15 @@ static struct clk_div_table div_aclk_cpu_t[] = { + }; + + static struct rockchip_clk_branch rk3066a_i2s0_fracmux __initdata = +- MUX(SCLK_I2S0, "sclk_i2s0", mux_sclk_i2s0_p, 0, ++ MUX(SCLK_I2S0, "sclk_i2s0", mux_sclk_i2s0_p, CLK_SET_RATE_PARENT, + RK2928_CLKSEL_CON(2), 8, 2, MFLAGS); + + static struct rockchip_clk_branch rk3066a_i2s1_fracmux __initdata = +- MUX(SCLK_I2S1, "sclk_i2s1", mux_sclk_i2s1_p, 0, ++ MUX(SCLK_I2S1, "sclk_i2s1", mux_sclk_i2s1_p, CLK_SET_RATE_PARENT, + RK2928_CLKSEL_CON(3), 8, 2, MFLAGS); + + static struct rockchip_clk_branch rk3066a_i2s2_fracmux __initdata = +- MUX(SCLK_I2S2, "sclk_i2s2", mux_sclk_i2s2_p, 0, ++ MUX(SCLK_I2S2, "sclk_i2s2", mux_sclk_i2s2_p, CLK_SET_RATE_PARENT, + RK2928_CLKSEL_CON(4), 8, 2, MFLAGS); + + static struct rockchip_clk_branch rk3066a_clk_branches[] __initdata = { +@@ -615,21 +615,21 @@ static struct rockchip_clk_branch rk3066a_clk_branches[] __initdata = { + COMPOSITE_NOMUX(0, "i2s0_pre", "i2s_src", 0, + RK2928_CLKSEL_CON(2), 0, 7, DFLAGS, + RK2928_CLKGATE_CON(0), 7, GFLAGS), +- COMPOSITE_FRACMUX(0, "i2s0_frac", "i2s0_pre", 0, ++ COMPOSITE_FRACMUX(0, "i2s0_frac", "i2s0_pre", CLK_SET_RATE_PARENT, + RK2928_CLKSEL_CON(6), 0, + RK2928_CLKGATE_CON(0), 8, GFLAGS, + &rk3066a_i2s0_fracmux), + COMPOSITE_NOMUX(0, "i2s1_pre", "i2s_src", 0, + RK2928_CLKSEL_CON(3), 0, 7, DFLAGS, + RK2928_CLKGATE_CON(0), 9, GFLAGS), +- COMPOSITE_FRACMUX(0, "i2s1_frac", "i2s1_pre", 0, ++ COMPOSITE_FRACMUX(0, "i2s1_frac", "i2s1_pre", CLK_SET_RATE_PARENT, + RK2928_CLKSEL_CON(7), 0, + RK2928_CLKGATE_CON(0), 10, GFLAGS, + &rk3066a_i2s1_fracmux), + COMPOSITE_NOMUX(0, "i2s2_pre", "i2s_src", 0, + RK2928_CLKSEL_CON(4), 0, 7, DFLAGS, + RK2928_CLKGATE_CON(0), 11, GFLAGS), +- COMPOSITE_FRACMUX(0, "i2s2_frac", "i2s2_pre", 0, ++ COMPOSITE_FRACMUX(0, "i2s2_frac", "i2s2_pre", CLK_SET_RATE_PARENT, + RK2928_CLKSEL_CON(8), 0, + RK2928_CLKGATE_CON(0), 12, GFLAGS, + &rk3066a_i2s2_fracmux), + +From e09debc09e9dfe38b0347be56d5dc63e1a567f8b Mon Sep 17 00:00:00 2001 +From: Johan Jonker +Date: Wed, 18 Nov 2020 14:58:17 +0100 +Subject: [PATCH] clk: rockchip: fix i2s gate bits on rk3066 and rk3188 + +The Rockchip PX2/RK3066 uses these bits in CRU_CLKGATE7_CON: + +hclk_i2s_8ch_gate_en bit 4 (dtsi: i2s0) +hclk_i2s0_2ch_gate_en bit 2 (dtsi: i2s1) +hclk_i2s1_2ch_gate_en bit 3 (dtsi: i2s2) + +The Rockchip PX3/RK3188 uses this bit in CRU_CLKGATE7_CON: + +hclk_i2s_2ch_gate_en bit 2 (dtsi: i2s0) + +The bits got somehow mixed up in the clk-rk3188.c file. +The labels in the dtsi files are not suppose to change. +The sclk and hclk names should match for +"trace_event=clk_disable,clk_enable", +so remove GATE HCLK_I2S0 from the common clock tree and +fix the bits in the rk3066 and rk3188 clock tree. + +Signed-off-by: Johan Jonker +Link: https://lore.kernel.org/r/20201118135822.9582-3-jbx6244@gmail.com +Signed-off-by: Heiko Stuebner +--- + drivers/clk/rockchip/clk-rk3188.c | 7 ++++--- + 1 file changed, 4 insertions(+), 3 deletions(-) + +diff --git a/drivers/clk/rockchip/clk-rk3188.c b/drivers/clk/rockchip/clk-rk3188.c +index db8c588139de..0b76ad34de00 100644 +--- a/drivers/clk/rockchip/clk-rk3188.c ++++ b/drivers/clk/rockchip/clk-rk3188.c +@@ -449,7 +449,6 @@ static struct rockchip_clk_branch common_clk_branches[] __initdata = { + + /* hclk_cpu gates */ + GATE(HCLK_ROM, "hclk_rom", "hclk_cpu", 0, RK2928_CLKGATE_CON(5), 6, GFLAGS), +- GATE(HCLK_I2S0, "hclk_i2s0", "hclk_cpu", 0, RK2928_CLKGATE_CON(7), 2, GFLAGS), + GATE(HCLK_SPDIF, "hclk_spdif", "hclk_cpu", 0, RK2928_CLKGATE_CON(7), 1, GFLAGS), + GATE(0, "hclk_cpubus", "hclk_cpu", 0, RK2928_CLKGATE_CON(4), 8, GFLAGS), + /* hclk_ahb2apb is part of a clk branch */ +@@ -634,8 +633,9 @@ static struct rockchip_clk_branch rk3066a_clk_branches[] __initdata = { + RK2928_CLKGATE_CON(0), 12, GFLAGS, + &rk3066a_i2s2_fracmux), + +- GATE(HCLK_I2S1, "hclk_i2s1", "hclk_cpu", 0, RK2928_CLKGATE_CON(7), 3, GFLAGS), +- GATE(HCLK_I2S2, "hclk_i2s2", "hclk_cpu", 0, RK2928_CLKGATE_CON(7), 4, GFLAGS), ++ GATE(HCLK_I2S0, "hclk_i2s0", "hclk_cpu", 0, RK2928_CLKGATE_CON(7), 4, GFLAGS), ++ GATE(HCLK_I2S1, "hclk_i2s1", "hclk_cpu", 0, RK2928_CLKGATE_CON(7), 2, GFLAGS), ++ GATE(HCLK_I2S2, "hclk_i2s2", "hclk_cpu", 0, RK2928_CLKGATE_CON(7), 3, GFLAGS), + GATE(HCLK_CIF1, "hclk_cif1", "hclk_cpu", 0, RK2928_CLKGATE_CON(6), 6, GFLAGS), + GATE(HCLK_HDMI, "hclk_hdmi", "hclk_cpu", 0, RK2928_CLKGATE_CON(4), 14, GFLAGS), + +@@ -728,6 +728,7 @@ static struct rockchip_clk_branch rk3188_clk_branches[] __initdata = { + RK2928_CLKGATE_CON(0), 10, GFLAGS, + &rk3188_i2s0_fracmux), + ++ GATE(HCLK_I2S0, "hclk_i2s0", "hclk_cpu", 0, RK2928_CLKGATE_CON(7), 2, GFLAGS), + GATE(0, "hclk_imem0", "hclk_cpu", 0, RK2928_CLKGATE_CON(4), 14, GFLAGS), + GATE(0, "hclk_imem1", "hclk_cpu", 0, RK2928_CLKGATE_CON(4), 15, GFLAGS), + + +From c14cd8d58bb0d1b71a501d20b61752c0115aa1d6 Mon Sep 17 00:00:00 2001 +From: Alexandru Stan +Date: Wed, 21 Oct 2020 22:04:43 -0700 +Subject: [PATCH] ARM: dts: rockchip: Remove 0 point from brightness-levels on + rk3288-veyron + +The extra 0 only adds one point in the userspace visible range, +so this change is almost a noop with the current driver behavior. + +We don't need the 0% point, userspace seems to handle this just fine +because it uses the bl_power property to turn off the display. + +Furthermore after adding "backlight: pwm_bl: Fix interpolation" patch, +the backlight interpolation will work a little differently. So we need +to preemptively remove the 0-3 segment since otherwise we would have a +252 long interpolation that would slowly go between 0 and 3, looking +really bad in userspace. So it's almost a noop/cleanup now, but it will +be required in the future. + +Signed-off-by: Alexandru Stan +Reviewed-by: Douglas Anderson +Acked-by: Daniel Thompson +Link: https://lore.kernel.org/r/20201021220404.v3.1.I96b8d872ec51171f19274e43e96cadc092881271@changeid +Signed-off-by: Heiko Stuebner +--- + arch/arm/boot/dts/rk3288-veyron-jaq.dts | 2 +- + arch/arm/boot/dts/rk3288-veyron-minnie.dts | 2 +- + arch/arm/boot/dts/rk3288-veyron-tiger.dts | 2 +- + 3 files changed, 3 insertions(+), 3 deletions(-) + +diff --git a/arch/arm/boot/dts/rk3288-veyron-jaq.dts b/arch/arm/boot/dts/rk3288-veyron-jaq.dts +index af77ab20586d..4a148cf1defc 100644 +--- a/arch/arm/boot/dts/rk3288-veyron-jaq.dts ++++ b/arch/arm/boot/dts/rk3288-veyron-jaq.dts +@@ -20,7 +20,7 @@ / { + + &backlight { + /* Jaq panel PWM must be >= 3%, so start non-zero brightness at 8 */ +- brightness-levels = <0 8 255>; ++ brightness-levels = <8 255>; + num-interpolated-steps = <247>; + }; + +diff --git a/arch/arm/boot/dts/rk3288-veyron-minnie.dts b/arch/arm/boot/dts/rk3288-veyron-minnie.dts +index f8b69e0a16a0..82fc6fba9999 100644 +--- a/arch/arm/boot/dts/rk3288-veyron-minnie.dts ++++ b/arch/arm/boot/dts/rk3288-veyron-minnie.dts +@@ -39,7 +39,7 @@ volum_up { + + &backlight { + /* Minnie panel PWM must be >= 1%, so start non-zero brightness at 3 */ +- brightness-levels = <0 3 255>; ++ brightness-levels = <3 255>; + num-interpolated-steps = <252>; + }; + +diff --git a/arch/arm/boot/dts/rk3288-veyron-tiger.dts b/arch/arm/boot/dts/rk3288-veyron-tiger.dts +index 069f0c2c1fdf..52a84cbe7a90 100644 +--- a/arch/arm/boot/dts/rk3288-veyron-tiger.dts ++++ b/arch/arm/boot/dts/rk3288-veyron-tiger.dts +@@ -23,7 +23,7 @@ / { + + &backlight { + /* Tiger panel PWM must be >= 1%, so start non-zero brightness at 3 */ +- brightness-levels = <0 3 255>; ++ brightness-levels = <3 255>; + num-interpolated-steps = <252>; + }; + + +From f4993c1a24b4ecfc6253cc7e82a759bcc9891b1a Mon Sep 17 00:00:00 2001 +From: Johan Jonker +Date: Mon, 16 Nov 2020 16:07:56 +0100 +Subject: [PATCH] ARM: dts: rockchip: rename wdt nodename to watchdog on rv1108 + +A test with the command below gives for example this error: + +/arch/arm/boot/dts/rv1108-evb.dt.yaml: +wdt@10360000: $nodename:0: 'wdt@10360000' +does not match '^watchdog(@.*|-[0-9a-f])?$' + +Fix it by renaming the wdt nodename to watchdog +in the rv1108.dtsi file. + +make ARCH=arm dtbs_check +DT_SCHEMA_FILES=Documentation/devicetree/bindings/watchdog/snps,dw-wdt.yaml + +Signed-off-by: Johan Jonker +Link: https://lore.kernel.org/r/20201116150756.14265-1-jbx6244@gmail.com +Signed-off-by: Heiko Stuebner +--- + arch/arm/boot/dts/rv1108.dtsi | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/arch/arm/boot/dts/rv1108.dtsi b/arch/arm/boot/dts/rv1108.dtsi +index a1a08cb9364e..e491964b1c3d 100644 +--- a/arch/arm/boot/dts/rv1108.dtsi ++++ b/arch/arm/boot/dts/rv1108.dtsi +@@ -299,7 +299,7 @@ timer: timer@10350000 { + clock-names = "timer", "pclk"; + }; + +- watchdog: wdt@10360000 { ++ watchdog: watchdog@10360000 { + compatible = "snps,dw-wdt"; + reg = <0x10360000 0x100>; + interrupts = ; + +From 4d7bc6b808cb61c7803049b0dc71e93202089e1f Mon Sep 17 00:00:00 2001 +From: Jagan Teki +Date: Mon, 30 Nov 2020 14:28:14 +0100 +Subject: [PATCH] ARM: dts: rockchip: Add rtc node for VMARC SOM + +Add the hym8563 rtc found on the rk3288 variant of the VMARC SOM. + +Signed-off-by: Jagan Teki +Link: https://lore.kernel.org/r/20201023181814.220974-2-jagan@amarulasolutions.com +[split out of the original patch, as it was a change unrelated + to the commit description] +Signed-off-by: Heiko Stuebner +--- + arch/arm/boot/dts/rk3288-vmarc-som.dtsi | 23 +++++++++++++++++++++++ + 1 file changed, 23 insertions(+) + +diff --git a/arch/arm/boot/dts/rk3288-vmarc-som.dtsi b/arch/arm/boot/dts/rk3288-vmarc-som.dtsi +index 4a373f5aa600..da80bfd5f2d5 100644 +--- a/arch/arm/boot/dts/rk3288-vmarc-som.dtsi ++++ b/arch/arm/boot/dts/rk3288-vmarc-som.dtsi +@@ -231,6 +231,23 @@ regulator-state-mem { + }; + }; + ++&i2c1 { ++ clock-frequency = <400000>; ++ status = "okay"; ++ ++ hym8563: rtc@51 { ++ compatible = "haoyu,hym8563"; ++ reg = <0x51>; ++ interrupt-parent = <&gpio5>; ++ interrupts = ; ++ #clock-cells = <0>; ++ clock-frequency = <32768>; ++ clock-output-names = "hym8563"; ++ pinctrl-names = "default"; ++ pinctrl-0 = <&hym8563_int>; ++ }; ++}; ++ + &i2c5 { + status = "okay"; + }; +@@ -245,6 +262,12 @@ &io_domains { + }; + + &pinctrl { ++ hym8563 { ++ hym8563_int: hym8563-int { ++ rockchip,pins = <5 RK_PC3 RK_FUNC_GPIO &pcfg_pull_up>; ++ }; ++ }; ++ + pcfg_pull_none_drv_8ma: pcfg-pull-none-drv-8ma { + drive-strength = <8>; + }; + +From 2a67f75ad25fd99946aa142ff63c98bb98b8c11b Mon Sep 17 00:00:00 2001 +From: Jagan Teki +Date: Fri, 23 Oct 2020 23:48:14 +0530 +Subject: [PATCH] ARM: dts: rockchip: Add SDIO0 node for VMARC SOM + +Rockchip RK3288 and RK3399Pro based VMARC SOM has sdio0 for +connecting WiFi/BT devices as a pluggable card via M.2 E-Key. + +Add associated sdio0 nodes, properties. + +Signed-off-by: Jagan Teki +Link: https://lore.kernel.org/r/20201023181814.220974-2-jagan@amarulasolutions.com +[moved the unrelated rtc addition to a separate patch] +Signed-off-by: Heiko Stuebner +--- + arch/arm/boot/dts/rk3288-vmarc-som.dtsi | 17 +++++++++++++++ + .../dts/rockchip-radxa-dalang-carrier.dtsi | 21 +++++++++++++++++++ + .../dts/rockchip/rk3399pro-vmarc-som.dtsi | 16 ++++++++++++++ + 3 files changed, 54 insertions(+) + +diff --git a/arch/arm/boot/dts/rk3288-vmarc-som.dtsi b/arch/arm/boot/dts/rk3288-vmarc-som.dtsi +index da80bfd5f2d5..0ae2bd150e37 100644 +--- a/arch/arm/boot/dts/rk3288-vmarc-som.dtsi ++++ b/arch/arm/boot/dts/rk3288-vmarc-som.dtsi +@@ -258,6 +258,7 @@ &io_domains { + gpio1830-supply = <&vcc_18>; + gpio30-supply = <&vcc_io>; + sdcard-supply = <&vccio_sd>; ++ wifi-supply = <&vcc_wl>; + status = "okay"; + }; + +@@ -283,6 +284,12 @@ pmic_int: pmic-int { + }; + }; + ++ sdio-pwrseq { ++ wifi_enable_h: wifi-enable-h { ++ rockchip,pins = <4 RK_PD4 RK_FUNC_GPIO &pcfg_pull_none>; ++ }; ++ }; ++ + sdmmc { + sdmmc_bus4: sdmmc-bus4 { + rockchip,pins = +@@ -314,6 +321,16 @@ usb0_en_oc: usb0-en-oc { + }; + }; + ++&sdio_pwrseq { ++ /* ++ * On the module itself this is one of these (depending ++ * on the actual card populated): ++ * - SDIO_RESET_L_WL_REG_ON ++ * - PDN (power down when low) ++ */ ++ reset-gpios = <&gpio4 RK_PD4 GPIO_ACTIVE_LOW>; /* WIFI_REG_ON */ ++}; ++ + &usbphy { + status = "okay"; + }; +diff --git a/arch/arm/boot/dts/rockchip-radxa-dalang-carrier.dtsi b/arch/arm/boot/dts/rockchip-radxa-dalang-carrier.dtsi +index 26b53eac4706..da1d548b7330 100644 +--- a/arch/arm/boot/dts/rockchip-radxa-dalang-carrier.dtsi ++++ b/arch/arm/boot/dts/rockchip-radxa-dalang-carrier.dtsi +@@ -15,6 +15,14 @@ clkin_gmac: external-gmac-clock { + #clock-cells = <0>; + }; + ++ sdio_pwrseq: sdio-pwrseq { ++ compatible = "mmc-pwrseq-simple"; ++ clocks = <&hym8563>; ++ clock-names = "ext_clock"; ++ pinctrl-names = "default"; ++ pinctrl-0 = <&wifi_enable_h>; ++ }; ++ + vcc12v_dcin: vcc12v-dcin-regulator { + compatible = "regulator-fixed"; + regulator-name = "vcc12v_dcin"; +@@ -78,6 +86,19 @@ &pwm2 { + status = "okay"; + }; + ++&sdio0 { ++ bus-width = <4>; ++ cap-sd-highspeed; ++ cap-sdio-irq; ++ keep-power-in-suspend; ++ mmc-pwrseq = <&sdio_pwrseq>; ++ non-removable; ++ pinctrl-names = "default"; ++ pinctrl-0 = <&sdio0_bus4 &sdio0_cmd &sdio0_clk>; ++ sd-uhs-sdr104; ++ status = "okay"; ++}; ++ + &sdmmc { + bus-width = <4>; + cap-mmc-highspeed; +diff --git a/arch/arm64/boot/dts/rockchip/rk3399pro-vmarc-som.dtsi b/arch/arm64/boot/dts/rockchip/rk3399pro-vmarc-som.dtsi +index 5d087be04af8..7257494d2831 100644 +--- a/arch/arm64/boot/dts/rockchip/rk3399pro-vmarc-som.dtsi ++++ b/arch/arm64/boot/dts/rockchip/rk3399pro-vmarc-som.dtsi +@@ -353,6 +353,12 @@ pmic_int_l: pmic-int-l { + }; + }; + ++ sdio-pwrseq { ++ wifi_enable_h: wifi-enable-h { ++ rockchip,pins = <2 RK_PD3 RK_FUNC_GPIO &pcfg_pull_none>; ++ }; ++ }; ++ + vbus_host { + usb1_en_oc: usb1-en-oc { + rockchip,pins = <4 RK_PD1 RK_FUNC_GPIO &pcfg_pull_up>; +@@ -371,6 +377,16 @@ &pmu_io_domains { + pmu1830-supply = <&vcc_1v8>; + }; + ++&sdio_pwrseq { ++ /* ++ * On the module itself this is one of these (depending ++ * on the actual card populated): ++ * - SDIO_RESET_L_WL_REG_ON ++ * - PDN (power down when low) ++ */ ++ reset-gpios = <&gpio2 RK_PD3 GPIO_ACTIVE_LOW>; ++}; ++ + &sdhci { + bus-width = <8>; + mmc-hs400-1_8v; + +From cc4ce3fd56ab4a9a53e00c0b6f6e4b9435982d07 Mon Sep 17 00:00:00 2001 +From: Jagan Teki +Date: Mon, 9 Nov 2020 23:40:15 +0530 +Subject: [PATCH] arm64: defconfig: Enable ROCKCHIP_LVDS + +Now, some of the rockchip hardware platforms do enable +lvds in mainline tree. + +So, enable Rockchip LVDS driver via default defconfig. + +Signed-off-by: Jagan Teki +Link: https://lore.kernel.org/r/20201109181017.206834-8-jagan@amarulasolutions.com +Signed-off-by: Heiko Stuebner +--- + arch/arm64/configs/defconfig | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/arch/arm64/configs/defconfig b/arch/arm64/configs/defconfig +index 5cfe3cf6f2ac..3ebba7dcb98f 100644 +--- a/arch/arm64/configs/defconfig ++++ b/arch/arm64/configs/defconfig +@@ -646,6 +646,7 @@ CONFIG_ROCKCHIP_CDN_DP=y + CONFIG_ROCKCHIP_DW_HDMI=y + CONFIG_ROCKCHIP_DW_MIPI_DSI=y + CONFIG_ROCKCHIP_INNO_HDMI=y ++CONFIG_ROCKCHIP_LVDS=y + CONFIG_DRM_RCAR_DU=m + CONFIG_DRM_RCAR_DW_HDMI=m + CONFIG_DRM_SUN4I=m + +From e9eefe21625121fff49fdddfa20efb37e654045d Mon Sep 17 00:00:00 2001 +From: Jagan Teki +Date: Mon, 9 Nov 2020 23:40:16 +0530 +Subject: [PATCH] arm64: defconfig: Enable PHY_ROCKCHIP_INNO_DSIDPHY + +In order to work LDVS, DSI in mainline tree for Rockchip based +hardware platforms, the associated PHY driver has to enable +in default defconfig. + +Enable rockchip DSI phy driver. + +Signed-off-by: Jagan Teki +Link: https://lore.kernel.org/r/20201109181017.206834-9-jagan@amarulasolutions.com +Signed-off-by: Heiko Stuebner +--- + arch/arm64/configs/defconfig | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/arch/arm64/configs/defconfig b/arch/arm64/configs/defconfig +index 3ebba7dcb98f..d50826dd7d68 100644 +--- a/arch/arm64/configs/defconfig ++++ b/arch/arm64/configs/defconfig +@@ -1011,6 +1011,7 @@ CONFIG_PHY_RCAR_GEN3_USB3=m + CONFIG_PHY_ROCKCHIP_EMMC=y + CONFIG_PHY_ROCKCHIP_INNO_HDMI=m + CONFIG_PHY_ROCKCHIP_INNO_USB2=y ++CONFIG_PHY_ROCKCHIP_INNO_DSIDPHY=m + CONFIG_PHY_ROCKCHIP_PCIE=m + CONFIG_PHY_ROCKCHIP_TYPEC=y + CONFIG_PHY_UNIPHIER_USB2=y + +From 4ce70903bef3a7f5d45e4acdf744185ec0a468c6 Mon Sep 17 00:00:00 2001 +From: Jagan Teki +Date: Mon, 9 Nov 2020 23:40:17 +0530 +Subject: [PATCH] arm64: defconfig: Enable USB_SERIAL_CP210X + +Some hardware platforms required CP20x USB to Serial converter +in order to work onboard functionalities like Bluetooth. + +An example of such a platform is from Engicam's PX30 (ARM64). + +Mark it as module in defconfig. + +Signed-off-by: Jagan Teki +Link: https://lore.kernel.org/r/20201109181017.206834-10-jagan@amarulasolutions.com +Signed-off-by: Heiko Stuebner +--- + arch/arm64/configs/defconfig | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/arch/arm64/configs/defconfig b/arch/arm64/configs/defconfig +index d50826dd7d68..41a2d489f0a2 100644 +--- a/arch/arm64/configs/defconfig ++++ b/arch/arm64/configs/defconfig +@@ -751,6 +751,7 @@ CONFIG_USB_CHIPIDEA_UDC=y + CONFIG_USB_CHIPIDEA_HOST=y + CONFIG_USB_ISP1760=y + CONFIG_USB_SERIAL=m ++CONFIG_USB_SERIAL_CP210X=m + CONFIG_USB_SERIAL_FTDI_SIO=m + CONFIG_USB_HSIC_USB3503=y + CONFIG_NOP_USB_XCEIV=y + +From dba3d86aca8df97ebd24edde2522ab61833619f1 Mon Sep 17 00:00:00 2001 +From: Jagan Teki +Date: Fri, 23 Oct 2020 23:48:13 +0530 +Subject: [PATCH] arm64: defconfig: Enable RTC_DRV_HYM8563 + +RTC HYM8563 used in the ARM64 Rockchip SoC's SDIO power +sequence enablement. + +Enable it as module. + +Signed-off-by: Jagan Teki +Link: https://lore.kernel.org/r/20201023181814.220974-1-jagan@amarulasolutions.com +Signed-off-by: Heiko Stuebner +--- + arch/arm64/configs/defconfig | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/arch/arm64/configs/defconfig b/arch/arm64/configs/defconfig +index 41a2d489f0a2..699c204090b8 100644 +--- a/arch/arm64/configs/defconfig ++++ b/arch/arm64/configs/defconfig +@@ -816,6 +816,7 @@ CONFIG_EDAC=y + CONFIG_EDAC_GHES=y + CONFIG_RTC_CLASS=y + CONFIG_RTC_DRV_DS1307=m ++CONFIG_RTC_DRV_HYM8563=m + CONFIG_RTC_DRV_MAX77686=y + CONFIG_RTC_DRV_RK808=m + CONFIG_RTC_DRV_PCF85363=m + +From 1df05ffbdb8550fa30547574f785c76e8036beb8 Mon Sep 17 00:00:00 2001 +From: Lee Jones +Date: Tue, 3 Nov 2020 15:28:18 +0000 +Subject: [PATCH] soc: rockchip: io-domain: Remove incorrect and incomplete + comment header + +Fixes the following W=1 kernel build warning(s): + + drivers/soc/rockchip/io-domain.c:57: warning: Cannot understand * @supplies: voltage settings matching the register bits. + +Signed-off-by: Lee Jones +Cc: Heiko Stuebner +Cc: Liam Girdwood +Cc: Mark Brown +Cc: "Rafael J. Wysocki" +Cc: Doug Anderson +Cc: linux-rockchip@lists.infradead.org +Link: https://lore.kernel.org/r/20201103152838.1290217-6-lee.jones@linaro.org +Signed-off-by: Heiko Stuebner +--- + drivers/soc/rockchip/io-domain.c | 3 --- + 1 file changed, 3 deletions(-) + +diff --git a/drivers/soc/rockchip/io-domain.c b/drivers/soc/rockchip/io-domain.c +index b29e829e815e..cf8182fc3642 100644 +--- a/drivers/soc/rockchip/io-domain.c ++++ b/drivers/soc/rockchip/io-domain.c +@@ -53,9 +53,6 @@ + + struct rockchip_iodomain; + +-/** +- * @supplies: voltage settings matching the register bits. +- */ + struct rockchip_iodomain_soc_data { + int grf_offset; + const char *supply_names[MAX_SUPPLIES]; + +From 6393923881cab6d3a4abacb56b742d386d24eb63 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Uwe=20Kleine-K=C3=B6nig?= +Date: Wed, 14 Oct 2020 22:00:29 +0200 +Subject: [PATCH] dt-bindings: vendor-prefixes: Add kobol prefix +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +The prefix is already used in arm/armada-388-helios4.dts. + +Signed-off-by: Uwe Kleine-König +Acked-by: Rob Herring +Link: https://lore.kernel.org/r/20201014200030.845759-2-uwe@kleine-koenig.org +Signed-off-by: Heiko Stuebner +--- + Documentation/devicetree/bindings/vendor-prefixes.yaml | 2 ++ + 1 file changed, 2 insertions(+) + +diff --git a/Documentation/devicetree/bindings/vendor-prefixes.yaml b/Documentation/devicetree/bindings/vendor-prefixes.yaml +index 2735be1a8470..259faf1b382c 100644 +--- a/Documentation/devicetree/bindings/vendor-prefixes.yaml ++++ b/Documentation/devicetree/bindings/vendor-prefixes.yaml +@@ -553,6 +553,8 @@ patternProperties: + description: Kionix, Inc. + "^kobo,.*": + description: Rakuten Kobo Inc. ++ "^kobol,.*": ++ description: Kobol Innovations Pte. Ltd. + "^koe,.*": + description: Kaohsiung Opto-Electronics Inc. + "^kontron,.*": + +From e4550a0485dc0f693a28e1280e89f279ced3bcd8 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Uwe=20Kleine-K=C3=B6nig?= +Date: Wed, 14 Oct 2020 22:00:30 +0200 +Subject: [PATCH] arm64: dts: rockchip: Add basic support for Kobol's Helios64 +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +The hardware is described in detail on Kobol's wiki at +https://wiki.kobol.io/helios64/intro/. + +Up to now the following peripherals are working: + + - UART + - Micro-SD card + - eMMC + - ethernet port 1 + - status LED + - temperature sensor on i2c bus 2 + +Signed-off-by: Uwe Kleine-König +Link: https://lore.kernel.org/r/20201014200030.845759-3-uwe@kleine-koenig.org +Signed-off-by: Heiko Stuebner +--- + arch/arm64/boot/dts/rockchip/Makefile | 1 + + .../dts/rockchip/rk3399-kobol-helios64.dts | 372 ++++++++++++++++++ + 2 files changed, 373 insertions(+) + create mode 100644 arch/arm64/boot/dts/rockchip/rk3399-kobol-helios64.dts + +diff --git a/arch/arm64/boot/dts/rockchip/Makefile b/arch/arm64/boot/dts/rockchip/Makefile +index 26661c7b736b..28b26a874313 100644 +--- a/arch/arm64/boot/dts/rockchip/Makefile ++++ b/arch/arm64/boot/dts/rockchip/Makefile +@@ -26,6 +26,7 @@ dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3399-hugsun-x99.dtb + dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3399-khadas-edge.dtb + dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3399-khadas-edge-captain.dtb + dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3399-khadas-edge-v.dtb ++dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3399-kobol-helios64.dtb + dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3399-leez-p710.dtb + dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3399-nanopc-t4.dtb + dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3399-nanopi-m4.dtb +diff --git a/arch/arm64/boot/dts/rockchip/rk3399-kobol-helios64.dts b/arch/arm64/boot/dts/rockchip/rk3399-kobol-helios64.dts +new file mode 100644 +index 000000000000..2a561be724b2 +--- /dev/null ++++ b/arch/arm64/boot/dts/rockchip/rk3399-kobol-helios64.dts +@@ -0,0 +1,372 @@ ++// SPDX-License-Identifier: (GPL-2.0+ OR MIT) ++/* ++ * Copyright (c) 2020 Aditya Prayoga ++ */ ++ ++/* ++ * The Kobol Helios64 is a board designed to operate as a NAS and optionally ++ * ships with an enclosing that can host five 2.5" hard disks. ++ * ++ * See https://wiki.kobol.io/helios64/intro/ for further details. ++ */ ++ ++/dts-v1/; ++#include "rk3399.dtsi" ++#include "rk3399-opp.dtsi" ++ ++/ { ++ model = "Kobol Helios64"; ++ compatible = "kobol,helios64", "rockchip,rk3399"; ++ ++ avdd_1v8_s0: avdd-1v8-s0 { ++ compatible = "regulator-fixed"; ++ regulator-name = "avdd_1v8_s0"; ++ regulator-always-on; ++ regulator-boot-on; ++ regulator-min-microvolt = <1800000>; ++ regulator-max-microvolt = <1800000>; ++ vin-supply = <&vcc3v3_sys_s3>; ++ }; ++ ++ clkin_gmac: external-gmac-clock { ++ compatible = "fixed-clock"; ++ clock-frequency = <125000000>; ++ clock-output-names = "clkin_gmac"; ++ #clock-cells = <0>; ++ }; ++ ++ leds { ++ compatible = "gpio-leds"; ++ pinctrl-names = "default"; ++ pinctrl-0 = <&sys_grn_led_on &sys_red_led_on>; ++ ++ led-0 { ++ label = "helios64:green:status"; ++ gpios = <&gpio0 RK_PB4 GPIO_ACTIVE_HIGH>; ++ default-state = "on"; ++ }; ++ ++ led-1 { ++ label = "helios64:red:fault"; ++ gpios = <&gpio0 RK_PB5 GPIO_ACTIVE_HIGH>; ++ default-state = "keep"; ++ }; ++ }; ++ ++ vcc1v8_sys_s0: vcc1v8-sys-s0 { ++ compatible = "regulator-fixed"; ++ regulator-name = "vcc1v8_sys_s0"; ++ regulator-always-on; ++ regulator-boot-on; ++ regulator-min-microvolt = <1800000>; ++ regulator-max-microvolt = <1800000>; ++ vin-supply = <&vcc1v8_sys_s3>; ++ }; ++ ++ vcc3v0_sd: vcc3v0-sd { ++ compatible = "regulator-fixed"; ++ enable-active-high; ++ gpio = <&gpio0 RK_PA1 GPIO_ACTIVE_HIGH>; ++ regulator-name = "vcc3v0_sd"; ++ regulator-boot-on; ++ regulator-min-microvolt = <3000000>; ++ regulator-max-microvolt = <3000000>; ++ pinctrl-names = "default"; ++ pinctrl-0 = <&sdmmc0_pwr_h>; ++ vin-supply = <&vcc3v3_sys_s3>; ++ }; ++ ++ vcc3v3_sys_s3: vcc_lan: vcc3v3-sys-s3 { ++ compatible = "regulator-fixed"; ++ regulator-name = "vcc3v3_sys_s3"; ++ regulator-always-on; ++ regulator-boot-on; ++ regulator-min-microvolt = <3300000>; ++ regulator-max-microvolt = <3300000>; ++ vin-supply = <&vcc5v0_sys>; ++ ++ regulator-state-mem { ++ regulator-on-in-suspend; ++ }; ++ }; ++ ++ vcc5v0_sys: vcc5v0-sys { ++ compatible = "regulator-fixed"; ++ regulator-name = "vcc5v0_sys"; ++ regulator-always-on; ++ regulator-boot-on; ++ regulator-min-microvolt = <5000000>; ++ regulator-max-microvolt = <5000000>; ++ vin-supply = <&vcc12v_dcin_bkup>; ++ ++ regulator-state-mem { ++ regulator-on-in-suspend; ++ }; ++ }; ++ ++ vcc12v_dcin: vcc12v-dcin { ++ compatible = "regulator-fixed"; ++ regulator-name = "vcc12v_dcin"; ++ regulator-always-on; ++ regulator-boot-on; ++ regulator-min-microvolt = <12000000>; ++ regulator-max-microvolt = <12000000>; ++ }; ++ ++ vcc12v_dcin_bkup: vcc12v-dcin-bkup { ++ compatible = "regulator-fixed"; ++ regulator-name = "vcc12v_dcin_bkup"; ++ regulator-always-on; ++ regulator-boot-on; ++ regulator-min-microvolt = <12000000>; ++ regulator-max-microvolt = <12000000>; ++ vin-supply = <&vcc12v_dcin>; ++ }; ++}; ++ ++/* ++ * The system doesn't run stable with cpu freq enabled, so disallow the lower ++ * frequencies until this problem is properly understood and resolved. ++ */ ++&cluster0_opp { ++ /delete-node/ opp00; ++ /delete-node/ opp01; ++ /delete-node/ opp02; ++ /delete-node/ opp03; ++ /delete-node/ opp04; ++}; ++ ++&cluster1_opp { ++ /delete-node/ opp00; ++ /delete-node/ opp01; ++ /delete-node/ opp02; ++ /delete-node/ opp03; ++ /delete-node/ opp04; ++ /delete-node/ opp05; ++ /delete-node/ opp06; ++}; ++ ++&cpu_b0 { ++ cpu-supply = <&vdd_cpu_b>; ++}; ++ ++&cpu_b1 { ++ cpu-supply = <&vdd_cpu_b>; ++}; ++ ++&cpu_l0 { ++ cpu-supply = <&vdd_cpu_l>; ++}; ++ ++&cpu_l1 { ++ cpu-supply = <&vdd_cpu_l>; ++}; ++ ++&cpu_l2 { ++ cpu-supply = <&vdd_cpu_l>; ++}; ++ ++&cpu_l3 { ++ cpu-supply = <&vdd_cpu_l>; ++}; ++ ++&emmc_phy { ++ status = "okay"; ++}; ++ ++&gmac { ++ assigned-clock-parents = <&clkin_gmac>; ++ assigned-clocks = <&cru SCLK_RMII_SRC>; ++ clock_in_out = "input"; ++ phy-mode = "rgmii"; ++ phy-supply = <&vcc_lan>; ++ pinctrl-names = "default"; ++ pinctrl-0 = <&rgmii_pins &gphy_reset>; ++ rx_delay = <0x20>; ++ tx_delay = <0x28>; ++ snps,reset-active-low; ++ snps,reset-delays-us = <0 10000 50000>; ++ snps,reset-gpio = <&gpio3 RK_PB7 GPIO_ACTIVE_LOW>; ++ status = "okay"; ++}; ++ ++&i2c0 { ++ clock-frequency = <400000>; ++ i2c-scl-rising-time-ns = <168>; ++ i2c-scl-falling-time-ns = <4>; ++ status = "okay"; ++ ++ rk808: pmic@1b { ++ compatible = "rockchip,rk808"; ++ reg = <0x1b>; ++ interrupt-parent = <&gpio0>; ++ interrupts = <10 IRQ_TYPE_LEVEL_LOW>; ++ clock-output-names = "xin32k", "rk808-clkout2"; ++ pinctrl-names = "default"; ++ pinctrl-0 = <&pmic_int_l>; ++ vcc1-supply = <&vcc5v0_sys>; ++ vcc2-supply = <&vcc5v0_sys>; ++ vcc3-supply = <&vcc5v0_sys>; ++ vcc4-supply = <&vcc5v0_sys>; ++ vcc6-supply = <&vcc5v0_sys>; ++ vcc7-supply = <&vcc5v0_sys>; ++ vcc8-supply = <&vcc3v3_sys_s3>; ++ vcc9-supply = <&vcc5v0_sys>; ++ vcc10-supply = <&vcc5v0_sys>; ++ vcc11-supply = <&vcc5v0_sys>; ++ vcc12-supply = <&vcc3v3_sys_s3>; ++ vddio-supply = <&vcc3v0_s3>; ++ wakeup-source; ++ #clock-cells = <1>; ++ ++ regulators { ++ vdd_cpu_l: DCDC_REG2 { ++ regulator-name = "vdd_cpu_l"; ++ regulator-always-on; ++ regulator-boot-on; ++ regulator-min-microvolt = <750000>; ++ regulator-max-microvolt = <1350000>; ++ regulator-ramp-delay = <6001>; ++ ++ regulator-state-mem { ++ regulator-off-in-suspend; ++ }; ++ }; ++ ++ vcc1v8_sys_s3: DCDC_REG4 { ++ regulator-name = "vcc1v8_sys_s3"; ++ regulator-always-on; ++ regulator-boot-on; ++ regulator-min-microvolt = <1800000>; ++ regulator-max-microvolt = <1800000>; ++ ++ regulator-state-mem { ++ regulator-on-in-suspend; ++ regulator-suspend-microvolt = <1800000>; ++ }; ++ }; ++ ++ vcc_sdio_s0: LDO_REG4 { ++ regulator-name = "vcc_sdio_s0"; ++ regulator-always-on; ++ regulator-boot-on; ++ regulator-min-microvolt = <1800000>; ++ regulator-max-microvolt = <3000000>; ++ ++ regulator-state-mem { ++ regulator-on-in-suspend; ++ regulator-suspend-microvolt = <3000000>; ++ }; ++ }; ++ ++ vcc3v0_s3: LDO_REG8 { ++ regulator-name = "vcc3v0_s3"; ++ regulator-always-on; ++ regulator-boot-on; ++ regulator-min-microvolt = <3000000>; ++ regulator-max-microvolt = <3000000>; ++ ++ regulator-state-mem { ++ regulator-on-in-suspend; ++ regulator-suspend-microvolt = <3000000>; ++ }; ++ }; ++ }; ++ }; ++ ++ vdd_cpu_b: regulator@40 { ++ compatible = "silergy,syr827"; ++ reg = <0x40>; ++ fcs,suspend-voltage-selector = <1>; ++ regulator-name = "vdd_cpu_b"; ++ regulator-always-on; ++ regulator-boot-on; ++ regulator-min-microvolt = <712500>; ++ regulator-max-microvolt = <1500000>; ++ regulator-ramp-delay = <1000>; ++ vin-supply = <&vcc5v0_sys>; ++ ++ regulator-state-mem { ++ regulator-off-in-suspend; ++ }; ++ }; ++}; ++ ++&i2c2 { ++ clock-frequency = <400000>; ++ i2c-scl-rising-time-ns = <160>; ++ i2c-scl-falling-time-ns = <30>; ++ status = "okay"; ++ ++ temp@4c { ++ compatible = "national,lm75"; ++ reg = <0x4c>; ++ }; ++}; ++ ++&io_domains { ++ audio-supply = <&vcc1v8_sys_s0>; ++ bt656-supply = <&vcc1v8_sys_s0>; ++ gpio1830-supply = <&vcc3v0_s3>; ++ sdmmc-supply = <&vcc_sdio_s0>; ++ status = "okay"; ++}; ++ ++&pinctrl { ++ gmac { ++ gphy_reset: gphy-reset { ++ rockchip,pins = <3 RK_PB7 RK_FUNC_GPIO &pcfg_output_low>; ++ }; ++ }; ++ ++ leds { ++ sys_grn_led_on: sys-grn-led-on { ++ rockchip,pins = <0 RK_PB4 RK_FUNC_GPIO &pcfg_pull_down>; ++ }; ++ ++ sys_red_led_on: sys-red-led-on { ++ rockchip,pins = <0 RK_PB5 RK_FUNC_GPIO &pcfg_pull_down>; ++ }; ++ }; ++ ++ pmic { ++ pmic_int_l: pmic-int-l { ++ rockchip,pins = <0 RK_PB2 RK_FUNC_GPIO &pcfg_pull_up>; ++ }; ++ }; ++ ++ vcc3v0-sd { ++ sdmmc0_pwr_h: sdmmc0-pwr-h { ++ rockchip,pins = <0 RK_PA1 RK_FUNC_GPIO &pcfg_pull_up>; ++ }; ++ }; ++}; ++ ++&pmu_io_domains { ++ pmu1830-supply = <&vcc3v0_s3>; ++ status = "okay"; ++}; ++ ++&sdhci { ++ bus-width = <8>; ++ mmc-hs200-1_8v; ++ non-removable; ++ vqmmc-supply = <&vcc1v8_sys_s0>; ++ status = "okay"; ++}; ++ ++&sdmmc { ++ bus-width = <4>; ++ cap-sd-highspeed; ++ cd-gpios = <&gpio0 RK_PA7 GPIO_ACTIVE_LOW>; ++ disable-wp; ++ pinctrl-names = "default"; ++ pinctrl-0 = <&sdmmc_clk &sdmmc_cmd &sdmmc_cd &sdmmc_bus4>; ++ vmmc-supply = <&vcc3v0_sd>; ++ vqmmc-supply = <&vcc_sdio_s0>; ++ status = "okay"; ++}; ++ ++&uart2 { ++ status = "okay"; ++}; + +From 5cdadd99fc57ce819d00a6bcf5720d920c64d9f9 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Uwe=20Kleine-K=C3=B6nig?= +Date: Mon, 2 Nov 2020 16:06:58 +0100 +Subject: [PATCH] dt-bindings: arm: rockchip: Add Kobol Helios64 +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Document the new board by Kobol introduced recently in +rockchip/rk3399-kobol-helios64.dts. + +Signed-off-by: Uwe Kleine-König +Acked-by: Rob Herring +Link: https://lore.kernel.org/r/20201102150658.167161-1-uwe@kleine-koenig.org +Signed-off-by: Heiko Stuebner +--- + Documentation/devicetree/bindings/arm/rockchip.yaml | 5 +++++ + 1 file changed, 5 insertions(+) + +diff --git a/Documentation/devicetree/bindings/arm/rockchip.yaml b/Documentation/devicetree/bindings/arm/rockchip.yaml +index b621752aaa65..ad1dbf349c33 100644 +--- a/Documentation/devicetree/bindings/arm/rockchip.yaml ++++ b/Documentation/devicetree/bindings/arm/rockchip.yaml +@@ -381,6 +381,11 @@ properties: + - khadas,edge-v + - const: rockchip,rk3399 + ++ - description: Kobol Helios64 ++ items: ++ - const: kobol,helios64 ++ - const: rockchip,rk3399 ++ + - description: Mecer Xtreme Mini S6 + items: + - const: mecer,xms6 + +From e648ff565eca99a4c7f73861d5e00f5999ef1afb Mon Sep 17 00:00:00 2001 +From: Heiko Stuebner +Date: Sat, 4 Jul 2020 00:14:13 +0200 +Subject: [PATCH] arm64: dts: rockchip: add adc joystick to Odroid Go Advance + +Add the now usable adc-joystick node that describes the analog +joystick connected to two saradc channels from the rk3326 soc. + +Signed-off-by: Heiko Stuebner +Link: https://lore.kernel.org/r/20200703221413.269800-1-heiko@sntech.de +--- + .../boot/dts/rockchip/rk3326-odroid-go2.dts | 24 +++++++++++++++++++ + 1 file changed, 24 insertions(+) + +diff --git a/arch/arm64/boot/dts/rockchip/rk3326-odroid-go2.dts b/arch/arm64/boot/dts/rockchip/rk3326-odroid-go2.dts +index 337681038519..97fb93e1cc00 100644 +--- a/arch/arm64/boot/dts/rockchip/rk3326-odroid-go2.dts ++++ b/arch/arm64/boot/dts/rockchip/rk3326-odroid-go2.dts +@@ -18,6 +18,30 @@ chosen { + stdout-path = "serial2:115200n8"; + }; + ++ adc-joystick { ++ compatible = "adc-joystick"; ++ io-channels = <&saradc 1>, ++ <&saradc 2>; ++ #address-cells = <1>; ++ #size-cells = <0>; ++ ++ axis@0 { ++ reg = <0>; ++ abs-flat = <10>; ++ abs-fuzz = <10>; ++ abs-range = <172 772>; ++ linux,code = ; ++ }; ++ ++ axis@1 { ++ reg = <1>; ++ abs-flat = <10>; ++ abs-fuzz = <10>; ++ abs-range = <278 815>; ++ linux,code = ; ++ }; ++ }; ++ + backlight: backlight { + compatible = "pwm-backlight"; + power-supply = <&vcc_bl>; + +From ab1d9b1011a0715b1b8e9f7509af5595978c636d Mon Sep 17 00:00:00 2001 +From: Jagan Teki +Date: Tue, 29 Sep 2020 14:02:11 +0530 +Subject: [PATCH] dt-bindings: arm: rockchip: Add Engicam PX30.Core EDIMM2.2 + Starter Kit + +PX30.Core is an EDIMM SOM based on Rockchip PX30 from Engicam. + +EDIMM2.2 Starter Kit is an EDIMM 2.2 Form Factor Capacitive +Evaluation Board from Engicam. + +PX30.Core needs to mount on top of this Evaluation board for +creating complete PX30.Core EDIMM2.2 Starter Kit. + +Add bindings for it. + +Signed-off-by: Jagan Teki +Acked-by: Rob Herring +Link: https://lore.kernel.org/r/20200929083217.25406-2-jagan@amarulasolutions.com +Signed-off-by: Heiko Stuebner +--- + Documentation/devicetree/bindings/arm/rockchip.yaml | 6 ++++++ + 1 file changed, 6 insertions(+) + +diff --git a/Documentation/devicetree/bindings/arm/rockchip.yaml b/Documentation/devicetree/bindings/arm/rockchip.yaml +index ad1dbf349c33..cef95eb26ca6 100644 +--- a/Documentation/devicetree/bindings/arm/rockchip.yaml ++++ b/Documentation/devicetree/bindings/arm/rockchip.yaml +@@ -70,6 +70,12 @@ properties: + - const: elgin,rv1108-r1 + - const: rockchip,rv1108 + ++ - description: Engicam PX30.Core EDIMM2.2 Starter Kit ++ items: ++ - const: engicam,px30-core-edimm2.2 ++ - const: engicam,px30-core ++ - const: rockchip,px30 ++ + - description: Firefly Firefly-RK3288 + items: + - enum: + +From 8efa7701f53539842009e63eab1c44d4c25f27a0 Mon Sep 17 00:00:00 2001 +From: Jagan Teki +Date: Tue, 29 Sep 2020 14:02:12 +0530 +Subject: [PATCH] arm64: dts: rockchip: Add Engicam EDIMM2.2 Starter Kit + +Engicam EDIMM2.2 Starter Kit is an EDIMM 2.2 Form Factor Capacitive +Evaluation Board. + +Genaral features: +- LCD 7" C.Touch +- microSD slot +- Ethernet 1Gb +- Wifi/BT +- 2x LVDS Full HD interfaces +- 3x USB 2.0 +- 1x USB 3.0 +- HDMI Out +- Mini PCIe +- MIPI CSI +- 2x CAN +- Audio Out + +SOM's like PX30.Core needs to mount on top of this Evaluation board +for creating complete PX30.Core EDIMM2.2 Starter Kit. + +Add support for it. + +Signed-off-by: Jagan Teki +Signed-off-by: Michael Trimarchi +Link: https://lore.kernel.org/r/20200929083217.25406-3-jagan@amarulasolutions.com +Signed-off-by: Heiko Stuebner +--- + .../dts/rockchip/px30-engicam-common.dtsi | 39 +++++++++++++++++++ + .../dts/rockchip/px30-engicam-edimm2.2.dtsi | 7 ++++ + 2 files changed, 46 insertions(+) + create mode 100644 arch/arm64/boot/dts/rockchip/px30-engicam-common.dtsi + create mode 100644 arch/arm64/boot/dts/rockchip/px30-engicam-edimm2.2.dtsi + +diff --git a/arch/arm64/boot/dts/rockchip/px30-engicam-common.dtsi b/arch/arm64/boot/dts/rockchip/px30-engicam-common.dtsi +new file mode 100644 +index 000000000000..bd5bde989e8d +--- /dev/null ++++ b/arch/arm64/boot/dts/rockchip/px30-engicam-common.dtsi +@@ -0,0 +1,39 @@ ++// SPDX-License-Identifier: (GPL-2.0+ OR MIT) ++/* ++ * Copyright (c) 2020 Engicam srl ++ * Copyright (c) 2020 Amarula Solutions ++ * Copyright (c) 2020 Amarula Solutions(India) ++ */ ++ ++/ { ++ vcc5v0_sys: vcc5v0-sys { ++ compatible = "regulator-fixed"; ++ regulator-name = "vcc5v0_sys"; /* +5V */ ++ regulator-always-on; ++ regulator-boot-on; ++ regulator-min-microvolt = <5000000>; ++ regulator-max-microvolt = <5000000>; ++ }; ++}; ++ ++&gmac { ++ clock_in_out = "output"; ++ phy-supply = <&vcc_3v3>; /* +3V3_SOM */ ++ snps,reset-active-low; ++ snps,reset-delays-us = <0 50000 50000>; ++ snps,reset-gpio = <&gpio2 RK_PB5 GPIO_ACTIVE_HIGH>; ++ status = "okay"; ++}; ++ ++&sdmmc { ++ cap-sd-highspeed; ++ card-detect-delay = <800>; ++ vmmc-supply = <&vcc_3v3>; /* +3V3_SOM */ ++ vqmmc-supply = <&vcc_3v3>; ++ status = "okay"; ++}; ++ ++&uart2 { ++ pinctrl-0 = <&uart2m1_xfer>; ++ status = "okay"; ++}; +diff --git a/arch/arm64/boot/dts/rockchip/px30-engicam-edimm2.2.dtsi b/arch/arm64/boot/dts/rockchip/px30-engicam-edimm2.2.dtsi +new file mode 100644 +index 000000000000..cb00988953e9 +--- /dev/null ++++ b/arch/arm64/boot/dts/rockchip/px30-engicam-edimm2.2.dtsi +@@ -0,0 +1,7 @@ ++// SPDX-License-Identifier: (GPL-2.0+ OR MIT) ++/* ++ * Copyright (c) 2020 Engicam srl ++ * Copyright (c) 2020 Amarula Solutions(India) ++ */ ++ ++#include "px30-engicam-common.dtsi" + +From 37f0dd7a1a5ccfdf31502abf3099eb0ba84bc2e0 Mon Sep 17 00:00:00 2001 +From: Michael Trimarchi +Date: Tue, 29 Sep 2020 14:02:13 +0530 +Subject: [PATCH] arm64: dts: rockchip: Add Engicam PX30.Core SOM + +PX30.Core is an EDIMM SOM based on Rockchip PX30 from Engicam. + +General features: +- Rockchip PX30 +- Up to 2GB DDR4 +- eMMC 4 GB expandible +- rest of PX30 features + +PX30.Core needs to mount on top of Engicam baseboards for creating +complete platform boards. + +Possible baseboards are, +- EDIMM2.2 +- C.TOUCH 2.0 + +Add support for it. + +Signed-off-by: Jagan Teki +Signed-off-by: Michael Trimarchi +Link: https://lore.kernel.org/r/20200929083217.25406-4-jagan@amarulasolutions.com +Signed-off-by: Heiko Stuebner +--- + .../dts/rockchip/px30-engicam-px30-core.dtsi | 232 ++++++++++++++++++ + 1 file changed, 232 insertions(+) + create mode 100644 arch/arm64/boot/dts/rockchip/px30-engicam-px30-core.dtsi + +diff --git a/arch/arm64/boot/dts/rockchip/px30-engicam-px30-core.dtsi b/arch/arm64/boot/dts/rockchip/px30-engicam-px30-core.dtsi +new file mode 100644 +index 000000000000..db22f776c68f +--- /dev/null ++++ b/arch/arm64/boot/dts/rockchip/px30-engicam-px30-core.dtsi +@@ -0,0 +1,232 @@ ++// SPDX-License-Identifier: (GPL-2.0+ OR MIT) ++/* ++ * Copyright (c) 2020 Fuzhou Rockchip Electronics Co., Ltd ++ * Copyright (c) 2020 Engicam srl ++ * Copyright (c) 2020 Amarula Solutons ++ * Copyright (c) 2020 Amarula Solutons(India) ++ */ ++ ++#include ++#include ++ ++/ { ++ compatible = "engicam,px30-core", "rockchip,px30"; ++}; ++ ++&cpu0 { ++ cpu-supply = <&vdd_arm>; ++}; ++ ++&cpu1 { ++ cpu-supply = <&vdd_arm>; ++}; ++ ++&cpu2 { ++ cpu-supply = <&vdd_arm>; ++}; ++ ++&cpu3 { ++ cpu-supply = <&vdd_arm>; ++}; ++ ++&emmc { ++ cap-mmc-highspeed; ++ mmc-hs200-1_8v; ++ non-removable; ++ status = "okay"; ++}; ++ ++&i2c0 { ++ status = "okay"; ++ ++ rk809: pmic@20 { ++ compatible = "rockchip,rk809"; ++ reg = <0x20>; ++ interrupt-parent = <&gpio0>; ++ interrupts = ; ++ pinctrl-names = "default"; ++ pinctrl-0 = <&pmic_int>; ++ rockchip,system-power-controller; ++ wakeup-source; ++ #clock-cells = <1>; ++ clock-output-names = "rk808-clkout1", "rk808-clkout2"; ++ ++ vcc1-supply = <&vcc5v0_sys>; ++ vcc2-supply = <&vcc5v0_sys>; ++ vcc3-supply = <&vcc5v0_sys>; ++ vcc4-supply = <&vcc5v0_sys>; ++ vcc5-supply = <&vcc3v3_sys>; ++ vcc6-supply = <&vcc3v3_sys>; ++ vcc7-supply = <&vcc3v3_sys>; ++ vcc8-supply = <&vcc3v3_sys>; ++ vcc9-supply = <&vcc5v0_sys>; ++ ++ regulators { ++ vdd_log: DCDC_REG1 { ++ regulator-name = "vdd_log"; ++ regulator-always-on; ++ regulator-boot-on; ++ regulator-min-microvolt = <950000>; ++ regulator-max-microvolt = <1350000>; ++ regulator-ramp-delay = <6001>; ++ ++ regulator-state-mem { ++ regulator-on-in-suspend; ++ regulator-suspend-microvolt = <950000>; ++ }; ++ }; ++ ++ vdd_arm: DCDC_REG2 { ++ regulator-name = "vdd_arm"; ++ regulator-always-on; ++ regulator-boot-on; ++ regulator-min-microvolt = <950000>; ++ regulator-max-microvolt = <1350000>; ++ regulator-ramp-delay = <6001>; ++ ++ regulator-state-mem { ++ regulator-off-in-suspend; ++ regulator-suspend-microvolt = <950000>; ++ }; ++ }; ++ ++ vcc_ddr: DCDC_REG3 { ++ regulator-name = "vcc_ddr"; ++ regulator-always-on; ++ regulator-boot-on; ++ ++ regulator-state-mem { ++ regulator-on-in-suspend; ++ }; ++ }; ++ ++ vcc_3v3: DCDC_REG4 { ++ regulator-name = "vcc_3v3"; ++ regulator-always-on; ++ regulator-boot-on; ++ regulator-min-microvolt = <3300000>; ++ regulator-max-microvolt = <3300000>; ++ ++ regulator-state-mem { ++ regulator-on-in-suspend; ++ regulator-suspend-microvolt = <3300000>; ++ }; ++ }; ++ ++ vcc3v3_sys: DCDC_REG5 { ++ regulator-name = "vcc3v3_sys"; ++ regulator-always-on; ++ regulator-boot-on; ++ regulator-min-microvolt = <3300000>; ++ regulator-max-microvolt = <3300000>; ++ ++ regulator-state-mem { ++ regulator-on-in-suspend; ++ regulator-suspend-microvolt = <3300000>; ++ }; ++ }; ++ ++ vcc_1v0: LDO_REG1 { ++ regulator-name = "vcc_1v0"; ++ regulator-always-on; ++ regulator-boot-on; ++ regulator-min-microvolt = <1000000>; ++ regulator-max-microvolt = <1000000>; ++ ++ regulator-state-mem { ++ regulator-on-in-suspend; ++ regulator-suspend-microvolt = <1000000>; ++ }; ++ }; ++ ++ vcc_1v8: LDO_REG2 { ++ regulator-name = "vcc_1v8"; ++ regulator-always-on; ++ regulator-boot-on; ++ regulator-min-microvolt = <1800000>; ++ regulator-max-microvolt = <1800000>; ++ ++ regulator-state-mem { ++ regulator-on-in-suspend; ++ regulator-suspend-microvolt = <1800000>; ++ }; ++ }; ++ ++ vdd_1v0: LDO_REG3 { ++ regulator-name = "vdd_1v0"; ++ regulator-always-on; ++ regulator-boot-on; ++ regulator-min-microvolt = <1000000>; ++ regulator-max-microvolt = <1000000>; ++ ++ regulator-state-mem { ++ regulator-on-in-suspend; ++ regulator-suspend-microvolt = <1000000>; ++ }; ++ }; ++ ++ vcc3v0_pmu: LDO_REG4 { ++ regulator-name = "vcc3v0_pmu"; ++ regulator-always-on; ++ regulator-boot-on; ++ regulator-min-microvolt = <3300000>; ++ regulator-max-microvolt = <3300000>; ++ ++ regulator-state-mem { ++ regulator-on-in-suspend; ++ regulator-suspend-microvolt = <3300000>; ++ ++ }; ++ }; ++ ++ vccio_sd: LDO_REG5 { ++ regulator-name = "vccio_sd"; ++ regulator-always-on; ++ regulator-boot-on; ++ regulator-min-microvolt = <1800000>; ++ regulator-max-microvolt = <3300000>; ++ ++ regulator-state-mem { ++ regulator-on-in-suspend; ++ regulator-suspend-microvolt = <3300000>; ++ }; ++ }; ++ ++ vcc5v0_host: SWITCH_REG2 { ++ regulator-name = "vcc5v0_host"; ++ regulator-always-on; ++ regulator-boot-on; ++ }; ++ }; ++ }; ++}; ++ ++&io_domains { ++ vccio1-supply = <&vcc_3v3>; ++ vccio2-supply = <&vcc_3v3>; ++ vccio3-supply = <&vcc_3v3>; ++ vccio4-supply = <&vcc_3v3>; ++ vccio5-supply = <&vcc_3v3>; ++ vccio6-supply = <&vcc_1v8>; ++ status = "okay"; ++}; ++ ++&pinctrl { ++ pmic { ++ pmic_int: pmic_int { ++ rockchip,pins = <0 RK_PA7 RK_FUNC_GPIO &pcfg_pull_up>; ++ }; ++ }; ++}; ++ ++&pmu_io_domains { ++ pmuio1-supply = <&vcc_3v3>; ++ pmuio2-supply = <&vcc_3v3>; ++ status = "okay"; ++}; ++ ++&tsadc { ++ rockchip,hw-tshut-mode = <1>; ++ rockchip,hw-tshut-polarity = <1>; ++ status = "okay"; ++}; + +From d51f542ce24362ea0664a5eb7f5dbda84b577810 Mon Sep 17 00:00:00 2001 +From: Jagan Teki +Date: Tue, 29 Sep 2020 14:02:14 +0530 +Subject: [PATCH] arm64: dts: rockchip: Add Engicam PX30.Core EDIMM2.2 Starter + Kit + +PX30.Core is an EDIMM SOM based on Rockchip PX30 from Engicam. + +EDIMM2.2 Starter Kit is an EDIMM 2.2 Form Factor Capacitive +Evaluation Board from Engicam. + +PX30.Core needs to mount on top of this Evaluation board for +creating complete PX30.Core EDIMM2.2 Starter Kit. + +Add support for it. + +Signed-off-by: Jagan Teki +Link: https://lore.kernel.org/r/20200929083217.25406-5-jagan@amarulasolutions.com +Signed-off-by: Heiko Stuebner +--- + arch/arm64/boot/dts/rockchip/Makefile | 1 + + .../px30-engicam-px30-core-edimm2.2.dts | 21 +++++++++++++++++++ + 2 files changed, 22 insertions(+) + create mode 100644 arch/arm64/boot/dts/rockchip/px30-engicam-px30-core-edimm2.2.dts + +diff --git a/arch/arm64/boot/dts/rockchip/Makefile b/arch/arm64/boot/dts/rockchip/Makefile +index 28b26a874313..abf9dc621314 100644 +--- a/arch/arm64/boot/dts/rockchip/Makefile ++++ b/arch/arm64/boot/dts/rockchip/Makefile +@@ -1,5 +1,6 @@ + # SPDX-License-Identifier: GPL-2.0 + dtb-$(CONFIG_ARCH_ROCKCHIP) += px30-evb.dtb ++dtb-$(CONFIG_ARCH_ROCKCHIP) += px30-engicam-px30-core-edimm2.2.dtb + dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3308-evb.dtb + dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3308-roc-cc.dtb + dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3318-a95x-z2.dtb +diff --git a/arch/arm64/boot/dts/rockchip/px30-engicam-px30-core-edimm2.2.dts b/arch/arm64/boot/dts/rockchip/px30-engicam-px30-core-edimm2.2.dts +new file mode 100644 +index 000000000000..e54d1e480daa +--- /dev/null ++++ b/arch/arm64/boot/dts/rockchip/px30-engicam-px30-core-edimm2.2.dts +@@ -0,0 +1,21 @@ ++// SPDX-License-Identifier: (GPL-2.0+ OR MIT) ++/* ++ * Copyright (c) 2020 Fuzhou Rockchip Electronics Co., Ltd ++ * Copyright (c) 2020 Engicam srl ++ * Copyright (c) 2020 Amarula Solutions(India) ++ */ ++ ++/dts-v1/; ++#include "px30.dtsi" ++#include "px30-engicam-edimm2.2.dtsi" ++#include "px30-engicam-px30-core.dtsi" ++ ++/ { ++ model = "Engicam PX30.Core EDIMM2.2 Starter Kit"; ++ compatible = "engicam,px30-core-edimm2.2", "engicam,px30-core", ++ "rockchip,px30"; ++ ++ chosen { ++ stdout-path = "serial2:115200n8"; ++ }; ++}; + +From 178762dcff60848615f72c18987247416633ad8f Mon Sep 17 00:00:00 2001 +From: Jagan Teki +Date: Tue, 29 Sep 2020 14:02:15 +0530 +Subject: [PATCH] dt-bindings: arm: rockchip: Add Engicam PX30.Core C.TOUCH 2.0 + +PX30.Core is an EDIMM SOM based on Rockchip PX30 from Engicam. + +C.TOUCH 2.0 is a general purpose carrier board with capacitive +touch interface support. + +PX30.Core needs to mount on top of this Carrier board for creating +complete PX30.Core C.TOUCH 2.0 board. + +Add bindings for it. + +Signed-off-by: Jagan Teki +Acked-by: Rob Herring +Link: https://lore.kernel.org/r/20200929083217.25406-6-jagan@amarulasolutions.com +Signed-off-by: Heiko Stuebner +--- + Documentation/devicetree/bindings/arm/rockchip.yaml | 6 ++++++ + 1 file changed, 6 insertions(+) + +diff --git a/Documentation/devicetree/bindings/arm/rockchip.yaml b/Documentation/devicetree/bindings/arm/rockchip.yaml +index cef95eb26ca6..37fd456170d2 100644 +--- a/Documentation/devicetree/bindings/arm/rockchip.yaml ++++ b/Documentation/devicetree/bindings/arm/rockchip.yaml +@@ -70,6 +70,12 @@ properties: + - const: elgin,rv1108-r1 + - const: rockchip,rv1108 + ++ - description: Engicam PX30.Core C.TOUCH 2.0 ++ items: ++ - const: engicam,px30-core-ctouch2 ++ - const: engicam,px30-core ++ - const: rockchip,px30 ++ + - description: Engicam PX30.Core EDIMM2.2 Starter Kit + items: + - const: engicam,px30-core-edimm2.2 + +From 3a0333a1c43aeda0a7eabd3ce97f93b546fc63e1 Mon Sep 17 00:00:00 2001 +From: Jagan Teki +Date: Tue, 29 Sep 2020 14:02:16 +0530 +Subject: [PATCH] arm64: dts: rockchip: Add Engicam C.TOUCH 2.0 + +Engicam C.TOUCH 2.0 is an EDIMM compliant general purpose +carrier board with capacitive touch interface. + +Genaral features: +- TFT 10.1" industrial, 1280x800 LVDS display +- Ethernet 10/100 +- Wifi/BT +- USB Type A/OTG +- Audio Out +- CAN +- LVDS panel connector + +SOM's like PX30.Core needs to mount on top of this Carrier board +for creating complete PX30.Core C.TOUCH 2.0 board. + +Add support for it. + +Signed-off-by: Jagan Teki +Signed-off-by: Michael Trimarchi +Link: https://lore.kernel.org/r/20200929083217.25406-7-jagan@amarulasolutions.com +Signed-off-by: Heiko Stuebner +--- + arch/arm64/boot/dts/rockchip/px30-engicam-ctouch2.dtsi | 8 ++++++++ + 1 file changed, 8 insertions(+) + create mode 100644 arch/arm64/boot/dts/rockchip/px30-engicam-ctouch2.dtsi + +diff --git a/arch/arm64/boot/dts/rockchip/px30-engicam-ctouch2.dtsi b/arch/arm64/boot/dts/rockchip/px30-engicam-ctouch2.dtsi +new file mode 100644 +index 000000000000..58425b1e559f +--- /dev/null ++++ b/arch/arm64/boot/dts/rockchip/px30-engicam-ctouch2.dtsi +@@ -0,0 +1,8 @@ ++// SPDX-License-Identifier: (GPL-2.0+ OR MIT) ++/* ++ * Copyright (c) 2020 Engicam srl ++ * Copyright (c) 2020 Amarula Solutions ++ * Copyright (c) 2020 Amarula Solutions(India) ++ */ ++ ++#include "px30-engicam-common.dtsi" + +From 32a432c01b10885659d2dcd24975e991f1e0cf89 Mon Sep 17 00:00:00 2001 +From: Jagan Teki +Date: Tue, 29 Sep 2020 14:02:17 +0530 +Subject: [PATCH] arm64: dts: rockchip: Add Engicam PX30.Core C.TOUCH 2.0 + +PX30.Core is an EDIMM SOM based on Rockchip PX30 from Engicam. + +C.TOUCH 2.0 is a general purpose carrier board with capacitive +touch interface support. + +PX30.Core needs to mount on top of this Carrier board for creating +complete PX30.Core C.TOUCH 2.0 board. + +Add support for it. + +Signed-off-by: Jagan Teki +Signed-off-by: Michael Trimarchi +Link: https://lore.kernel.org/r/20200929083217.25406-8-jagan@amarulasolutions.com +Signed-off-by: Heiko Stuebner +--- + arch/arm64/boot/dts/rockchip/Makefile | 1 + + .../px30-engicam-px30-core-ctouch2.dts | 22 +++++++++++++++++++ + 2 files changed, 23 insertions(+) + create mode 100644 arch/arm64/boot/dts/rockchip/px30-engicam-px30-core-ctouch2.dts + +diff --git a/arch/arm64/boot/dts/rockchip/Makefile b/arch/arm64/boot/dts/rockchip/Makefile +index abf9dc621314..5a53979b7057 100644 +--- a/arch/arm64/boot/dts/rockchip/Makefile ++++ b/arch/arm64/boot/dts/rockchip/Makefile +@@ -1,5 +1,6 @@ + # SPDX-License-Identifier: GPL-2.0 + dtb-$(CONFIG_ARCH_ROCKCHIP) += px30-evb.dtb ++dtb-$(CONFIG_ARCH_ROCKCHIP) += px30-engicam-px30-core-ctouch2.dtb + dtb-$(CONFIG_ARCH_ROCKCHIP) += px30-engicam-px30-core-edimm2.2.dtb + dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3308-evb.dtb + dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3308-roc-cc.dtb +diff --git a/arch/arm64/boot/dts/rockchip/px30-engicam-px30-core-ctouch2.dts b/arch/arm64/boot/dts/rockchip/px30-engicam-px30-core-ctouch2.dts +new file mode 100644 +index 000000000000..5a0ecb8faecf +--- /dev/null ++++ b/arch/arm64/boot/dts/rockchip/px30-engicam-px30-core-ctouch2.dts +@@ -0,0 +1,22 @@ ++// SPDX-License-Identifier: (GPL-2.0+ OR MIT) ++/* ++ * Copyright (c) 2020 Fuzhou Rockchip Electronics Co., Ltd ++ * Copyright (c) 2020 Engicam srl ++ * Copyright (c) 2020 Amarula Solutions ++ * Copyright (c) 2020 Amarula Solutions(India) ++ */ ++ ++/dts-v1/; ++#include "px30.dtsi" ++#include "px30-engicam-ctouch2.dtsi" ++#include "px30-engicam-px30-core.dtsi" ++ ++/ { ++ model = "Engicam PX30.Core C.TOUCH 2.0"; ++ compatible = "engicam,px30-core-ctouch2", "engicam,px30-core", ++ "rockchip,px30"; ++ ++ chosen { ++ stdout-path = "serial2:115200n8"; ++ }; ++}; + +From 4402111ed3efffe40616658af7cd677de5954776 Mon Sep 17 00:00:00 2001 +From: Chen-Yu Tsai +Date: Thu, 26 Nov 2020 15:33:35 +0800 +Subject: [PATCH] arm64: dts: rockchip: Enable HDMI audio on rk3328-roc-cc + +The RK3328-ROC-CC already has HDMI display output enabled. Now that +audio for the HDMI controller is supported, it can be enabled as well. + +Enable the simple-audio-card, and the I2S interface the audio is fed +from. + +Signed-off-by: Chen-Yu Tsai +Link: https://lore.kernel.org/r/20201126073336.30794-3-wens@kernel.org +Signed-off-by: Heiko Stuebner +--- + arch/arm64/boot/dts/rockchip/rk3328-roc-cc.dts | 8 ++++++++ + 1 file changed, 8 insertions(+) + +diff --git a/arch/arm64/boot/dts/rockchip/rk3328-roc-cc.dts b/arch/arm64/boot/dts/rockchip/rk3328-roc-cc.dts +index b76282e704de..697fce709031 100644 +--- a/arch/arm64/boot/dts/rockchip/rk3328-roc-cc.dts ++++ b/arch/arm64/boot/dts/rockchip/rk3328-roc-cc.dts +@@ -161,6 +161,10 @@ &hdmiphy { + status = "okay"; + }; + ++&hdmi_sound { ++ status = "okay"; ++}; ++ + &i2c1 { + status = "okay"; + +@@ -270,6 +274,10 @@ regulator-state-mem { + }; + }; + ++&i2s0 { ++ status = "okay"; ++}; ++ + &io_domains { + status = "okay"; + + +From 755eed3a0181ab31177162799c6cbe3ed3c85593 Mon Sep 17 00:00:00 2001 +From: Chen-Yu Tsai +Date: Thu, 26 Nov 2020 15:33:36 +0800 +Subject: [PATCH] arm64: dts: rockchip: Enable analog audio on rk3328-roc-cc + +Now that driver support for the RK3328's audio codec, and the plumbing +is defined at the SoC level, we can enable analog audio at the board +level. + +Enable analog audio by enabling the codec and the I2S interface +connected and the simple-audio-card that binds them together. + +Signed-off-by: Chen-Yu Tsai +Link: https://lore.kernel.org/r/20201126073336.30794-4-wens@kernel.org +Signed-off-by: Heiko Stuebner +--- + arch/arm64/boot/dts/rockchip/rk3328-roc-cc.dts | 12 ++++++++++++ + 1 file changed, 12 insertions(+) + +diff --git a/arch/arm64/boot/dts/rockchip/rk3328-roc-cc.dts b/arch/arm64/boot/dts/rockchip/rk3328-roc-cc.dts +index 697fce709031..19959bfba451 100644 +--- a/arch/arm64/boot/dts/rockchip/rk3328-roc-cc.dts ++++ b/arch/arm64/boot/dts/rockchip/rk3328-roc-cc.dts +@@ -104,6 +104,14 @@ user_led: led-1 { + }; + }; + ++&analog_sound { ++ status = "okay"; ++}; ++ ++&codec { ++ status = "okay"; ++}; ++ + &cpu0 { + cpu-supply = <&vdd_arm>; + }; +@@ -278,6 +286,10 @@ &i2s0 { + status = "okay"; + }; + ++&i2s1 { ++ status = "okay"; ++}; ++ + &io_domains { + status = "okay"; + + +From 0ec396b3ae638938f6b138e1555afb1d4b1aebed Mon Sep 17 00:00:00 2001 +From: Johan Jonker +Date: Mon, 16 Nov 2020 14:23:11 +0100 +Subject: [PATCH] arm64: dts: rockchip: rename sdhci nodename to mmc on rk3399 + +A test with the command below gives for example this error: + +/arch/arm64/boot/dts/rockchip/rk3399-evb.dt.yaml: +sdhci@fe330000: $nodename:0: 'sdhci@fe330000' +does not match '^mmc(@.*)?$' + +Fix it by renaming sdhci to mmc. + +make ARCH=arm64 dtbs_check +DT_SCHEMA_FILES=Documentation/devicetree/bindings/ +mmc/arasan,sdhci.yaml + +Signed-off-by: Johan Jonker +Link: https://lore.kernel.org/r/20201116132311.8318-1-jbx6244@gmail.com +Signed-off-by: Heiko Stuebner +--- + arch/arm64/boot/dts/rockchip/rk3399.dtsi | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/arch/arm64/boot/dts/rockchip/rk3399.dtsi b/arch/arm64/boot/dts/rockchip/rk3399.dtsi +index 7a9a7aca86c6..865729ec867f 100644 +--- a/arch/arm64/boot/dts/rockchip/rk3399.dtsi ++++ b/arch/arm64/boot/dts/rockchip/rk3399.dtsi +@@ -331,7 +331,7 @@ sdmmc: mmc@fe320000 { + status = "disabled"; + }; + +- sdhci: sdhci@fe330000 { ++ sdhci: mmc@fe330000 { + compatible = "rockchip,rk3399-sdhci-5.1", "arasan,sdhci-5.1"; + reg = <0x0 0xfe330000 0x0 0x10000>; + interrupts = ; + +From 788de7c2c761d7d34879de0f31d46a26071318e7 Mon Sep 17 00:00:00 2001 +From: Jagan Teki +Date: Mon, 9 Nov 2020 23:40:09 +0530 +Subject: [PATCH] arm64: dts: rockchip: Enable USB Host, OTG on px30-enagicam + +Engicam EDIMM2.2 and C.Touch 2.0 Kits support USB Host +and OTG ports. + +Add support to enable USB on these kits while mounting +px30-core SOM. + +Signed-off-by: Jagan Teki +Link: https://lore.kernel.org/r/20201109181017.206834-2-jagan@amarulasolutions.com +Signed-off-by: Heiko Stuebner +--- + .../dts/rockchip/px30-engicam-common.dtsi | 24 +++++++++++++++++++ + 1 file changed, 24 insertions(+) + +diff --git a/arch/arm64/boot/dts/rockchip/px30-engicam-common.dtsi b/arch/arm64/boot/dts/rockchip/px30-engicam-common.dtsi +index bd5bde989e8d..fbbdbb0a40af 100644 +--- a/arch/arm64/boot/dts/rockchip/px30-engicam-common.dtsi ++++ b/arch/arm64/boot/dts/rockchip/px30-engicam-common.dtsi +@@ -33,7 +33,31 @@ &sdmmc { + status = "okay"; + }; + ++&u2phy { ++ status = "okay"; ++ ++ u2phy_host: host-port { ++ status = "okay"; ++ }; ++ ++ u2phy_otg: otg-port { ++ status = "okay"; ++ }; ++}; ++ + &uart2 { + pinctrl-0 = <&uart2m1_xfer>; + status = "okay"; + }; ++ ++&usb20_otg { ++ status = "okay"; ++}; ++ ++&usb_host0_ehci { ++ status = "okay"; ++}; ++ ++&usb_host0_ohci { ++ status = "okay"; ++}; + +From 2b8ed7f5f189cacd9465e725d80949993a4af67a Mon Sep 17 00:00:00 2001 +From: Jagan Teki +Date: Mon, 9 Nov 2020 23:40:10 +0530 +Subject: [PATCH] arm64: dts: rockchip: Enable LVDS panel on + px30-engicam-edimm2.2 + +Engicam PX30.Core EDIMM2.2 developement Kit has on board 10" LVDS +panel from yes-optoelectronics. + +This patch adds panel enablement nodes on respective dts(i) files. + +Signed-off-by: Jagan Teki +Link: https://lore.kernel.org/r/20201109181017.206834-3-jagan@amarulasolutions.com +Signed-off-by: Heiko Stuebner +--- + .../dts/rockchip/px30-engicam-common.dtsi | 4 ++ + .../dts/rockchip/px30-engicam-edimm2.2.dtsi | 59 +++++++++++++++++++ + .../dts/rockchip/px30-engicam-px30-core.dtsi | 5 ++ + 3 files changed, 68 insertions(+) + +diff --git a/arch/arm64/boot/dts/rockchip/px30-engicam-common.dtsi b/arch/arm64/boot/dts/rockchip/px30-engicam-common.dtsi +index fbbdbb0a40af..8fdd7ff2fdf9 100644 +--- a/arch/arm64/boot/dts/rockchip/px30-engicam-common.dtsi ++++ b/arch/arm64/boot/dts/rockchip/px30-engicam-common.dtsi +@@ -25,6 +25,10 @@ &gmac { + status = "okay"; + }; + ++&pwm0 { ++ status = "okay"; ++}; ++ + &sdmmc { + cap-sd-highspeed; + card-detect-delay = <800>; +diff --git a/arch/arm64/boot/dts/rockchip/px30-engicam-edimm2.2.dtsi b/arch/arm64/boot/dts/rockchip/px30-engicam-edimm2.2.dtsi +index cb00988953e9..449b8eb6454e 100644 +--- a/arch/arm64/boot/dts/rockchip/px30-engicam-edimm2.2.dtsi ++++ b/arch/arm64/boot/dts/rockchip/px30-engicam-edimm2.2.dtsi +@@ -5,3 +5,62 @@ + */ + + #include "px30-engicam-common.dtsi" ++ ++/ { ++ backlight: backlight { ++ compatible = "pwm-backlight"; ++ pwms = <&pwm0 0 25000 0>; ++ }; ++ ++ panel { ++ compatible = "yes-optoelectronics,ytc700tlag-05-201c"; ++ backlight = <&backlight>; ++ data-mapping = "vesa-24"; ++ power-supply = <&vcc3v3_lcd>; ++ ++ port { ++ panel_in_lvds: endpoint { ++ remote-endpoint = <&lvds_out_panel>; ++ }; ++ }; ++ }; ++}; ++ ++&display_subsystem { ++ status = "okay"; ++}; ++ ++&dsi_dphy { ++ status = "okay"; ++}; ++ ++/* LVDS_B(secondary) */ ++&lvds { ++ status = "okay"; ++ ++ ports { ++ port@1 { ++ reg = <1>; ++ ++ lvds_out_panel: endpoint { ++ remote-endpoint = <&panel_in_lvds>; ++ }; ++ }; ++ }; ++}; ++ ++&vopb { ++ status = "okay"; ++}; ++ ++&vopb_mmu { ++ status = "okay"; ++}; ++ ++&vopl { ++ status = "okay"; ++}; ++ ++&vopl_mmu { ++ status = "okay"; ++}; +diff --git a/arch/arm64/boot/dts/rockchip/px30-engicam-px30-core.dtsi b/arch/arm64/boot/dts/rockchip/px30-engicam-px30-core.dtsi +index db22f776c68f..cdacd3483600 100644 +--- a/arch/arm64/boot/dts/rockchip/px30-engicam-px30-core.dtsi ++++ b/arch/arm64/boot/dts/rockchip/px30-engicam-px30-core.dtsi +@@ -192,6 +192,11 @@ regulator-state-mem { + }; + }; + ++ vcc3v3_lcd: SWITCH_REG1 { ++ regulator-boot-on; ++ regulator-name = "vcc3v3_lcd"; ++ }; ++ + vcc5v0_host: SWITCH_REG2 { + regulator-name = "vcc5v0_host"; + regulator-always-on; + +From 3d6d9cbc1bf596ac6f78d63ed8dbdf94849517ba Mon Sep 17 00:00:00 2001 +From: Jagan Teki +Date: Mon, 9 Nov 2020 23:40:11 +0530 +Subject: [PATCH] dt-bindings: arm: rockchip: Add Engicam PX30.Core C.TOUCH 2.0 + 10.1" OF + +PX30.Core is an EDIMM SOM based on Rockchip PX30 from Engicam. + +C.TOUCH 2.0 is a general purpose carrier board with capacitive +touch interface support. + +10.1" OF is a capacitive touch 10.1" Open Frame panel solutions. + +PX30.Core needs to mount on top of C.TOUCH 2.0 carrier with pluged +10.1" OF for creating complete PX30.Core C.TOUCH 2.0 10.1" Open Frame. + +Add bindings for it. + +Acked-by: Rob Herring +Signed-off-by: Jagan Teki +Link: https://lore.kernel.org/r/20201109181017.206834-4-jagan@amarulasolutions.com +Signed-off-by: Heiko Stuebner +--- + Documentation/devicetree/bindings/arm/rockchip.yaml | 6 ++++++ + 1 file changed, 6 insertions(+) + +diff --git a/Documentation/devicetree/bindings/arm/rockchip.yaml b/Documentation/devicetree/bindings/arm/rockchip.yaml +index 37fd456170d2..ef4544ad6f82 100644 +--- a/Documentation/devicetree/bindings/arm/rockchip.yaml ++++ b/Documentation/devicetree/bindings/arm/rockchip.yaml +@@ -76,6 +76,12 @@ properties: + - const: engicam,px30-core + - const: rockchip,px30 + ++ - description: Engicam PX30.Core C.TOUCH 2.0 10.1" Open Frame ++ items: ++ - const: engicam,px30-core-ctouch2-of10 ++ - const: engicam,px30-core ++ - const: rockchip,px30 ++ + - description: Engicam PX30.Core EDIMM2.2 Starter Kit + items: + - const: engicam,px30-core-edimm2.2 + +From 5125b003599a79b52ec2f9d7f4c56be4d65d9f9a Mon Sep 17 00:00:00 2001 +From: Jagan Teki +Date: Mon, 9 Nov 2020 23:40:12 +0530 +Subject: [PATCH] arm64: dts: rockchip: Add Engicam PX30.Core C.TOUCH 2.0 10.1" + OF + +PX30.Core is an EDIMM SOM based on Rockchip PX30 from Engicam. + +C.TOUCH 2.0 is a general purpose carrier board with capacitive +touch interface support. + +10.1" OF is a capacitive touch 10.1" Open Frame panel solutions. + +PX30.Core needs to mount on top of C.TOUCH 2.0 carrier with pluged +10.1" OF for creating complete PX30.Core C.TOUCH 2.0 10.1" Open Frame. + +Add support for it. + +Signed-off-by: Jagan Teki +Link: https://lore.kernel.org/r/20201109181017.206834-5-jagan@amarulasolutions.com +Signed-off-by: Heiko Stuebner +--- + arch/arm64/boot/dts/rockchip/Makefile | 1 + + .../px30-engicam-px30-core-ctouch2-of10.dts | 77 +++++++++++++++++++ + 2 files changed, 78 insertions(+) + create mode 100644 arch/arm64/boot/dts/rockchip/px30-engicam-px30-core-ctouch2-of10.dts + +diff --git a/arch/arm64/boot/dts/rockchip/Makefile b/arch/arm64/boot/dts/rockchip/Makefile +index 5a53979b7057..1ab55a124a87 100644 +--- a/arch/arm64/boot/dts/rockchip/Makefile ++++ b/arch/arm64/boot/dts/rockchip/Makefile +@@ -1,6 +1,7 @@ + # SPDX-License-Identifier: GPL-2.0 + dtb-$(CONFIG_ARCH_ROCKCHIP) += px30-evb.dtb + dtb-$(CONFIG_ARCH_ROCKCHIP) += px30-engicam-px30-core-ctouch2.dtb ++dtb-$(CONFIG_ARCH_ROCKCHIP) += px30-engicam-px30-core-ctouch2-of10.dtb + dtb-$(CONFIG_ARCH_ROCKCHIP) += px30-engicam-px30-core-edimm2.2.dtb + dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3308-evb.dtb + dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3308-roc-cc.dtb +diff --git a/arch/arm64/boot/dts/rockchip/px30-engicam-px30-core-ctouch2-of10.dts b/arch/arm64/boot/dts/rockchip/px30-engicam-px30-core-ctouch2-of10.dts +new file mode 100644 +index 000000000000..47aa30505a42 +--- /dev/null ++++ b/arch/arm64/boot/dts/rockchip/px30-engicam-px30-core-ctouch2-of10.dts +@@ -0,0 +1,77 @@ ++// SPDX-License-Identifier: (GPL-2.0+ OR MIT) ++/* ++ * Copyright (c) 2020 Fuzhou Rockchip Electronics Co., Ltd ++ * Copyright (c) 2020 Engicam srl ++ * Copyright (c) 2020 Amarula Solutions(India) ++ */ ++ ++/dts-v1/; ++#include "px30.dtsi" ++#include "px30-engicam-ctouch2.dtsi" ++#include "px30-engicam-px30-core.dtsi" ++ ++/ { ++ model = "Engicam PX30.Core C.TOUCH 2.0 10.1\" Open Frame"; ++ compatible = "engicam,px30-core-ctouch2-of10", "engicam,px30-core", ++ "rockchip,px30"; ++ ++ backlight: backlight { ++ compatible = "pwm-backlight"; ++ pwms = <&pwm0 0 25000 0>; ++ }; ++ ++ chosen { ++ stdout-path = "serial2:115200n8"; ++ }; ++ ++ panel { ++ compatible = "ampire,am-1280800n3tzqw-t00h"; ++ backlight = <&backlight>; ++ power-supply = <&vcc3v3_lcd>; ++ data-mapping = "vesa-24"; ++ ++ port { ++ panel_in_lvds: endpoint { ++ remote-endpoint = <&lvds_out_panel>; ++ }; ++ }; ++ }; ++}; ++ ++&display_subsystem { ++ status = "okay"; ++}; ++ ++&dsi_dphy { ++ status = "okay"; ++}; ++ ++&lvds { ++ status = "okay"; ++ ++ ports { ++ port@1 { ++ reg = <1>; ++ ++ lvds_out_panel: endpoint { ++ remote-endpoint = <&panel_in_lvds>; ++ }; ++ }; ++ }; ++}; ++ ++&vopb { ++ status = "okay"; ++}; ++ ++&vopb_mmu { ++ status = "okay"; ++}; ++ ++&vopl { ++ status = "okay"; ++}; ++ ++&vopl_mmu { ++ status = "okay"; ++}; + +From d22f3ec04013a401a7a6ac43ceab6cc9d6b0c2ae Mon Sep 17 00:00:00 2001 +From: Suniel Mahesh +Date: Mon, 9 Nov 2020 23:40:13 +0530 +Subject: [PATCH] arm64: dts: rockchip: Add WiFi support on px30-engicam + +Engicam PX30 carrier boards like EDIMM2.2 and C.TOUCH2.0 have +an onboard Sterling-LWD Wifi/BT chip based on BCM43430 connected +on the SDIO bus. + +The SDIO power sequnce is connacted with exteernal 32KHz oscillator +and it require 3V3 regulator input. + +This patch adds WiFi enablement nodes for these respective boards. + +Signed-off-by: Michael Trimarchi +Signed-off-by: Suniel Mahesh +Signed-off-by: Jagan Teki +Link: https://lore.kernel.org/r/20201109181017.206834-6-jagan@amarulasolutions.com +Signed-off-by: Heiko Stuebner +--- + .../dts/rockchip/px30-engicam-common.dtsi | 45 +++++++++++++++++++ + .../dts/rockchip/px30-engicam-ctouch2.dtsi | 12 +++++ + .../px30-engicam-px30-core-edimm2.2.dts | 12 +++++ + 3 files changed, 69 insertions(+) + +diff --git a/arch/arm64/boot/dts/rockchip/px30-engicam-common.dtsi b/arch/arm64/boot/dts/rockchip/px30-engicam-common.dtsi +index 8fdd7ff2fdf9..0e1a93ec3234 100644 +--- a/arch/arm64/boot/dts/rockchip/px30-engicam-common.dtsi ++++ b/arch/arm64/boot/dts/rockchip/px30-engicam-common.dtsi +@@ -14,6 +14,51 @@ vcc5v0_sys: vcc5v0-sys { + regulator-min-microvolt = <5000000>; + regulator-max-microvolt = <5000000>; + }; ++ ++ sdio_pwrseq: sdio-pwrseq { ++ compatible = "mmc-pwrseq-simple"; ++ clocks = <&xin32k>; ++ clock-names = "ext_clock"; ++ post-power-on-delay-ms = <80>; ++ pinctrl-names = "default"; ++ pinctrl-0 = <&wifi_enable_h>; ++ }; ++ ++ vcc3v3_rf_aux_mod: vcc3v3-rf-aux-mod { ++ compatible = "regulator-fixed"; ++ regulator-name = "vcc3v3_rf_aux_mod"; ++ regulator-min-microvolt = <3300000>; ++ regulator-max-microvolt = <3300000>; ++ regulator-always-on; ++ regulator-boot-on; ++ vin-supply = <&vcc5v0_sys>; ++ }; ++ ++ xin32k: xin32k { ++ compatible = "fixed-clock"; ++ #clock-cells = <0>; ++ clock-frequency = <32768>; ++ clock-output-names = "xin32k"; ++ }; ++}; ++ ++&sdio { ++ #address-cells = <1>; ++ #size-cells = <0>; ++ bus-width = <4>; ++ clock-frequency = <50000000>; ++ cap-sdio-irq; ++ cap-sd-highspeed; ++ keep-power-in-suspend; ++ mmc-pwrseq = <&sdio_pwrseq>; ++ non-removable; ++ sd-uhs-sdr104; ++ status = "okay"; ++ ++ brcmf: wifi@1 { ++ compatible = "brcm,bcm4329-fmac"; ++ reg = <1>; ++ }; + }; + + &gmac { +diff --git a/arch/arm64/boot/dts/rockchip/px30-engicam-ctouch2.dtsi b/arch/arm64/boot/dts/rockchip/px30-engicam-ctouch2.dtsi +index 58425b1e559f..d5708779c285 100644 +--- a/arch/arm64/boot/dts/rockchip/px30-engicam-ctouch2.dtsi ++++ b/arch/arm64/boot/dts/rockchip/px30-engicam-ctouch2.dtsi +@@ -6,3 +6,15 @@ + */ + + #include "px30-engicam-common.dtsi" ++ ++&pinctrl { ++ sdio-pwrseq { ++ wifi_enable_h: wifi-enable-h { ++ rockchip,pins = <1 RK_PC2 RK_FUNC_GPIO &pcfg_pull_none>; ++ }; ++ }; ++}; ++ ++&sdio_pwrseq { ++ reset-gpios = <&gpio1 RK_PC2 GPIO_ACTIVE_LOW>; ++}; +diff --git a/arch/arm64/boot/dts/rockchip/px30-engicam-px30-core-edimm2.2.dts b/arch/arm64/boot/dts/rockchip/px30-engicam-px30-core-edimm2.2.dts +index e54d1e480daa..913444548b59 100644 +--- a/arch/arm64/boot/dts/rockchip/px30-engicam-px30-core-edimm2.2.dts ++++ b/arch/arm64/boot/dts/rockchip/px30-engicam-px30-core-edimm2.2.dts +@@ -19,3 +19,15 @@ chosen { + stdout-path = "serial2:115200n8"; + }; + }; ++ ++&pinctrl { ++ sdio-pwrseq { ++ wifi_enable_h: wifi-enable-h { ++ rockchip,pins = <1 RK_PC3 RK_FUNC_GPIO &pcfg_pull_none>; ++ }; ++ }; ++}; ++ ++&sdio_pwrseq { ++ reset-gpios = <&gpio1 RK_PC3 GPIO_ACTIVE_LOW>; ++}; + +From bd5babdc346d5b6e14e73f710eb7dceb7c353b34 Mon Sep 17 00:00:00 2001 +From: Suniel Mahesh +Date: Mon, 9 Nov 2020 23:40:14 +0530 +Subject: [PATCH] arm64: dts: rockchip: Add BT support on px30-engicam + +Engicam PX30 carrier boards like EDIMM2.2 and C.TOUCH2.0 have +an onboard Sterling-LWD Wifi/BT chip based on BCM43430 connected +on the UART bus. + +UART bus on the design routed via USB to UART CP20x bridge. This +bridge powered from 3V3 regualtor gpio. + +This patch adds BT enablement nodes for these respective boards. + +Signed-off-by: Michael Trimarchi +Signed-off-by: Suniel Mahesh +Signed-off-by: Jagan Teki +Link: https://lore.kernel.org/r/20201109181017.206834-7-jagan@amarulasolutions.com +Signed-off-by: Heiko Stuebner +--- + .../arm64/boot/dts/rockchip/px30-engicam-common.dtsi | 12 ++++++++++++ + .../boot/dts/rockchip/px30-engicam-ctouch2.dtsi | 10 ++++++++++ + .../dts/rockchip/px30-engicam-px30-core-edimm2.2.dts | 10 ++++++++++ + 3 files changed, 32 insertions(+) + +diff --git a/arch/arm64/boot/dts/rockchip/px30-engicam-common.dtsi b/arch/arm64/boot/dts/rockchip/px30-engicam-common.dtsi +index 0e1a93ec3234..08b0b9fbcbc9 100644 +--- a/arch/arm64/boot/dts/rockchip/px30-engicam-common.dtsi ++++ b/arch/arm64/boot/dts/rockchip/px30-engicam-common.dtsi +@@ -24,6 +24,18 @@ sdio_pwrseq: sdio-pwrseq { + pinctrl-0 = <&wifi_enable_h>; + }; + ++ vcc3v3_btreg: vcc3v3-btreg { ++ compatible = "regulator-gpio"; ++ enable-active-high; ++ pinctrl-names = "default"; ++ pinctrl-0 = <&bt_enable_h>; ++ regulator-name = "btreg-gpio-supply"; ++ regulator-min-microvolt = <3300000>; ++ regulator-max-microvolt = <3300000>; ++ regulator-always-on; ++ states = <3300000 0x0>; ++ }; ++ + vcc3v3_rf_aux_mod: vcc3v3-rf-aux-mod { + compatible = "regulator-fixed"; + regulator-name = "vcc3v3_rf_aux_mod"; +diff --git a/arch/arm64/boot/dts/rockchip/px30-engicam-ctouch2.dtsi b/arch/arm64/boot/dts/rockchip/px30-engicam-ctouch2.dtsi +index d5708779c285..bf10a3d29fca 100644 +--- a/arch/arm64/boot/dts/rockchip/px30-engicam-ctouch2.dtsi ++++ b/arch/arm64/boot/dts/rockchip/px30-engicam-ctouch2.dtsi +@@ -8,6 +8,12 @@ + #include "px30-engicam-common.dtsi" + + &pinctrl { ++ bt { ++ bt_enable_h: bt-enable-h { ++ rockchip,pins = <1 RK_PC3 RK_FUNC_GPIO &pcfg_pull_none>; ++ }; ++ }; ++ + sdio-pwrseq { + wifi_enable_h: wifi-enable-h { + rockchip,pins = <1 RK_PC2 RK_FUNC_GPIO &pcfg_pull_none>; +@@ -18,3 +24,7 @@ wifi_enable_h: wifi-enable-h { + &sdio_pwrseq { + reset-gpios = <&gpio1 RK_PC2 GPIO_ACTIVE_LOW>; + }; ++ ++&vcc3v3_btreg { ++ enable-gpio = <&gpio1 RK_PC3 GPIO_ACTIVE_HIGH>; ++}; +diff --git a/arch/arm64/boot/dts/rockchip/px30-engicam-px30-core-edimm2.2.dts b/arch/arm64/boot/dts/rockchip/px30-engicam-px30-core-edimm2.2.dts +index 913444548b59..d759478e1c84 100644 +--- a/arch/arm64/boot/dts/rockchip/px30-engicam-px30-core-edimm2.2.dts ++++ b/arch/arm64/boot/dts/rockchip/px30-engicam-px30-core-edimm2.2.dts +@@ -21,6 +21,12 @@ chosen { + }; + + &pinctrl { ++ bt { ++ bt_enable_h: bt-enable-h { ++ rockchip,pins = <1 RK_PC2 RK_FUNC_GPIO &pcfg_pull_none>; ++ }; ++ }; ++ + sdio-pwrseq { + wifi_enable_h: wifi-enable-h { + rockchip,pins = <1 RK_PC3 RK_FUNC_GPIO &pcfg_pull_none>; +@@ -31,3 +37,7 @@ wifi_enable_h: wifi-enable-h { + &sdio_pwrseq { + reset-gpios = <&gpio1 RK_PC3 GPIO_ACTIVE_LOW>; + }; ++ ++&vcc3v3_btreg { ++ enable-gpio = <&gpio1 RK_PC2 GPIO_ACTIVE_HIGH>; ++}; + +From e885634c25872114d576907e82b682ac9826157c Mon Sep 17 00:00:00 2001 +From: Alexis Ballier +Date: Thu, 22 Oct 2020 13:35:32 +0200 +Subject: [PATCH] arm64: dts: rockchip: Properly define the type C connector on + rk3399-orangepi + +Tested: +- USB3 Gigabit adapter +- USB2 mass storage + +The wiring is the same as the pinebook pro according to the schematics, +thus this patch is heavily based on its dts. + +Signed-off-by: Alexis Ballier +Cc: devicetree@vger.kernel.org +Cc: Heiko Stuebner +Cc: linux-arm-kernel@lists.infradead.org +Cc: linux-rockchip@lists.infradead.org +Cc: linux-kernel@vger.kernel.org +Link: https://lore.kernel.org/r/20201022113532.18470-1-aballier@gentoo.org +Signed-off-by: Heiko Stuebner +--- + .../boot/dts/rockchip/rk3399-orangepi.dts | 62 ++++++++++++++++++- + 1 file changed, 61 insertions(+), 1 deletion(-) + +diff --git a/arch/arm64/boot/dts/rockchip/rk3399-orangepi.dts b/arch/arm64/boot/dts/rockchip/rk3399-orangepi.dts +index 6163ae8063a7..ad7c4d00888f 100644 +--- a/arch/arm64/boot/dts/rockchip/rk3399-orangepi.dts ++++ b/arch/arm64/boot/dts/rockchip/rk3399-orangepi.dts +@@ -7,6 +7,7 @@ + + #include "dt-bindings/pwm/pwm.h" + #include "dt-bindings/input/input.h" ++#include "dt-bindings/usb/pd.h" + #include "rk3399.dtsi" + #include "rk3399-opp.dtsi" + +@@ -531,6 +532,43 @@ fusb302@22 { + pinctrl-names = "default"; + pinctrl-0 = <&chg_cc_int_l>; + vbus-supply = <&vbus_typec>; ++ ++ typec_con: connector { ++ compatible = "usb-c-connector"; ++ data-role = "host"; ++ label = "USB-C"; ++ op-sink-microwatt = <1000000>; ++ power-role = "dual"; ++ sink-pdos = ++ ; ++ source-pdos = ++ ; ++ try-power-role = "sink"; ++ ++ ports { ++ #address-cells = <1>; ++ #size-cells = <0>; ++ ++ port@0 { ++ reg = <0>; ++ typec_hs: endpoint { ++ remote-endpoint = <&u2phy0_typec_hs>; ++ }; ++ }; ++ port@1 { ++ reg = <1>; ++ typec_ss: endpoint { ++ remote-endpoint = <&tcphy0_typec_ss>; ++ }; ++ }; ++ port@2 { ++ reg = <2>; ++ typec_dp: endpoint { ++ remote-endpoint = <&tcphy0_typec_dp>; ++ }; ++ }; ++ }; ++ }; + }; + }; + +@@ -717,6 +755,22 @@ &tcphy0 { + status = "okay"; + }; + ++&tcphy0_dp { ++ port { ++ tcphy0_typec_dp: endpoint { ++ remote-endpoint = <&typec_dp>; ++ }; ++ }; ++}; ++ ++&tcphy0_usb3 { ++ port { ++ tcphy0_typec_ss: endpoint { ++ remote-endpoint = <&typec_ss>; ++ }; ++ }; ++}; ++ + &tcphy1 { + status = "okay"; + }; +@@ -739,6 +793,12 @@ u2phy0_host: host-port { + phy-supply = <&vcc5v0_host>; + status = "okay"; + }; ++ ++ port { ++ u2phy0_typec_hs: endpoint { ++ remote-endpoint = <&typec_hs>; ++ }; ++ }; + }; + + &u2phy1 { +@@ -799,7 +859,7 @@ &usbdrd3_0 { + + &usbdrd_dwc3_0 { + status = "okay"; +- dr_mode = "otg"; ++ dr_mode = "host"; + }; + + &usbdrd3_1 { + +From cac94f9e5d1735e2c0fc37d164e7a24eb09a01cf Mon Sep 17 00:00:00 2001 +From: Shunqian Zheng +Date: Tue, 20 Oct 2020 16:38:49 -0300 +Subject: [PATCH] arm64: dts: rockchip: add isp0 node for rk3399 + +RK3399 has two ISPs, but only isp0 was tested. +Add isp0 node in rk3399 dtsi + +Verified with: +make ARCH=arm64 dtbs_check DT_SCHEMA_FILES=Documentation/devicetree/bindings/media/rockchip-isp1.yaml + +Signed-off-by: Shunqian Zheng +Signed-off-by: Jacob Chen +Signed-off-by: Helen Koike +Link: https://lore.kernel.org/r/20201020193850.1460644-9-helen.koike@collabora.com +Signed-off-by: Heiko Stuebner +--- + arch/arm64/boot/dts/rockchip/rk3399.dtsi | 26 ++++++++++++++++++++++++ + 1 file changed, 26 insertions(+) + +diff --git a/arch/arm64/boot/dts/rockchip/rk3399.dtsi b/arch/arm64/boot/dts/rockchip/rk3399.dtsi +index 865729ec867f..f5dee5f447bb 100644 +--- a/arch/arm64/boot/dts/rockchip/rk3399.dtsi ++++ b/arch/arm64/boot/dts/rockchip/rk3399.dtsi +@@ -1726,6 +1726,32 @@ vopb_mmu: iommu@ff903f00 { + status = "disabled"; + }; + ++ isp0: isp0@ff910000 { ++ compatible = "rockchip,rk3399-cif-isp"; ++ reg = <0x0 0xff910000 0x0 0x4000>; ++ interrupts = ; ++ clocks = <&cru SCLK_ISP0>, ++ <&cru ACLK_ISP0_WRAPPER>, ++ <&cru HCLK_ISP0_WRAPPER>; ++ clock-names = "isp", "aclk", "hclk"; ++ iommus = <&isp0_mmu>; ++ phys = <&mipi_dphy_rx0>; ++ phy-names = "dphy"; ++ power-domains = <&power RK3399_PD_ISP0>; ++ status = "disabled"; ++ ++ ports { ++ #address-cells = <1>; ++ #size-cells = <0>; ++ ++ port@0 { ++ reg = <0>; ++ #address-cells = <1>; ++ #size-cells = <0>; ++ }; ++ }; ++ }; ++ + isp0_mmu: iommu@ff914000 { + compatible = "rockchip,iommu"; + reg = <0x0 0xff914000 0x0 0x100>, <0x0 0xff915000 0x0 0x100>; + +From 8cba14e3889a8c6695e90bdeb698a7998788b153 Mon Sep 17 00:00:00 2001 +From: Eddie Cai +Date: Tue, 20 Oct 2020 16:38:50 -0300 +Subject: [PATCH] arm64: dts: rockchip: add isp and sensors for Scarlet + +Enable ISP and camera sensor ov2685 and ov5695 for Scarlet Chromebook + +Verified with: + make ARCH=arm64 dtbs_check + +Signed-off-by: Shunqian Zheng +Signed-off-by: Eddie Cai +Signed-off-by: Tomasz Figa +Signed-off-by: Helen Koike +Reviewed-by: Tomasz Figa +Link: https://lore.kernel.org/r/20201020193850.1460644-10-helen.koike@collabora.com +Signed-off-by: Heiko Stuebner +--- + .../boot/dts/rockchip/rk3399-gru-scarlet.dtsi | 74 +++++++++++++++++++ + 1 file changed, 74 insertions(+) + +diff --git a/arch/arm64/boot/dts/rockchip/rk3399-gru-scarlet.dtsi b/arch/arm64/boot/dts/rockchip/rk3399-gru-scarlet.dtsi +index 60cd1c18cd4e..beee5fbb3443 100644 +--- a/arch/arm64/boot/dts/rockchip/rk3399-gru-scarlet.dtsi ++++ b/arch/arm64/boot/dts/rockchip/rk3399-gru-scarlet.dtsi +@@ -296,6 +296,52 @@ camera: &i2c7 { + + /* 24M mclk is shared between world and user cameras */ + pinctrl-0 = <&i2c7_xfer &test_clkout1>; ++ ++ /* Rear-facing camera */ ++ wcam: camera@36 { ++ compatible = "ovti,ov5695"; ++ reg = <0x36>; ++ pinctrl-names = "default"; ++ pinctrl-0 = <&wcam_rst>; ++ ++ clocks = <&cru SCLK_TESTCLKOUT1>; ++ clock-names = "xvclk"; ++ ++ avdd-supply = <&pp2800_cam>; ++ dvdd-supply = <&pp1250_cam>; ++ dovdd-supply = <&pp1800_s0>; ++ reset-gpios = <&gpio2 5 GPIO_ACTIVE_LOW>; ++ ++ port { ++ wcam_out: endpoint { ++ remote-endpoint = <&mipi_in_wcam>; ++ data-lanes = <1 2>; ++ }; ++ }; ++ }; ++ ++ /* Front-facing camera */ ++ ucam: camera@3c { ++ compatible = "ovti,ov2685"; ++ reg = <0x3c>; ++ pinctrl-names = "default"; ++ pinctrl-0 = <&ucam_rst>; ++ ++ clocks = <&cru SCLK_TESTCLKOUT1>; ++ clock-names = "xvclk"; ++ ++ avdd-supply = <&pp2800_cam>; ++ dovdd-supply = <&pp1800_s0>; ++ dvdd-supply = <&pp1800_s0>; ++ reset-gpios = <&gpio2 3 GPIO_ACTIVE_LOW>; ++ ++ port { ++ ucam_out: endpoint { ++ remote-endpoint = <&mipi_in_ucam>; ++ data-lanes = <1>; ++ }; ++ }; ++ }; + }; + + &cdn_dp { +@@ -353,10 +399,38 @@ &io_domains { + gpio1830-supply = <&pp1800_s0>; /* APIO4_VDD; 4c 4d */ + }; + ++&isp0 { ++ status = "okay"; ++ ++ ports { ++ port@0 { ++ mipi_in_wcam: endpoint@0 { ++ reg = <0>; ++ remote-endpoint = <&wcam_out>; ++ data-lanes = <1 2>; ++ }; ++ ++ mipi_in_ucam: endpoint@1 { ++ reg = <1>; ++ remote-endpoint = <&ucam_out>; ++ data-lanes = <1>; ++ }; ++ }; ++ }; ++}; ++ ++&isp0_mmu { ++ status = "okay"; ++}; ++ + &max98357a { + sdmode-gpios = <&gpio0 2 GPIO_ACTIVE_HIGH>; + }; + ++&mipi_dphy_rx0 { ++ status = "okay"; ++}; ++ + &mipi_dsi { + status = "okay"; + clock-master; + +From 61526438d1bb6f241861b6caddffcdbde4092a09 Mon Sep 17 00:00:00 2001 +From: Vicente Bergas +Date: Tue, 1 Dec 2020 16:41:30 +0100 +Subject: [PATCH] arm64: dts: rockchip: fix supplies on rk3399-rock-pi-4 + +Based on the board schematics at +https://dl.radxa.com/rockpi4/docs/hw/rockpi4/rockpi_4c_v12_sch_20200620.pdf +on page 18: +vcc_lan is not controllable by software, it is just an analog LC filter. +Because of this, it can not be turned off-in-suspend. + +and on page 17: +vcc_cam and vcc_mipi are not voltage regulators, they are just switches. +So, the voltage range is not applicable. +This silences an error message about not being able to adjust the voltage. + +Signed-off-by: Vicente Bergas +Link: https://lore.kernel.org/r/20201201154132.1286-2-vicencb@gmail.com +Signed-off-by: Heiko Stuebner +--- + arch/arm64/boot/dts/rockchip/rk3399-rock-pi-4.dtsi | 8 -------- + 1 file changed, 8 deletions(-) + +diff --git a/arch/arm64/boot/dts/rockchip/rk3399-rock-pi-4.dtsi b/arch/arm64/boot/dts/rockchip/rk3399-rock-pi-4.dtsi +index 678a336010bf..06df2397bbb4 100644 +--- a/arch/arm64/boot/dts/rockchip/rk3399-rock-pi-4.dtsi ++++ b/arch/arm64/boot/dts/rockchip/rk3399-rock-pi-4.dtsi +@@ -111,10 +111,6 @@ vcc_lan: vcc3v3-phy-regulator { + regulator-boot-on; + regulator-min-microvolt = <3300000>; + regulator-max-microvolt = <3300000>; +- +- regulator-state-mem { +- regulator-off-in-suspend; +- }; + }; + + vdd_log: vdd-log { +@@ -362,8 +358,6 @@ vcc_cam: SWITCH_REG1 { + regulator-name = "vcc_cam"; + regulator-always-on; + regulator-boot-on; +- regulator-min-microvolt = <3300000>; +- regulator-max-microvolt = <3300000>; + regulator-state-mem { + regulator-off-in-suspend; + }; +@@ -373,8 +367,6 @@ vcc_mipi: SWITCH_REG2 { + regulator-name = "vcc_mipi"; + regulator-always-on; + regulator-boot-on; +- regulator-min-microvolt = <3300000>; +- regulator-max-microvolt = <3300000>; + regulator-state-mem { + regulator-off-in-suspend; + }; + +From befac22c7d52bd4b312cd00ed30716406a531661 Mon Sep 17 00:00:00 2001 +From: Vicente Bergas +Date: Tue, 1 Dec 2020 16:41:31 +0100 +Subject: [PATCH] arm64: dts: rockchip: fix I2S conflict on rk3399-rock-pi-4 + +Based on the board schematics at +https://dl.radxa.com/rockpi4/docs/hw/rockpi4/rockpi_4c_v12_sch_20200620.pdf +on page 14: +Only two channels of I2S are connected and the extra +I2S pins are in conflict with other functions like USB power. + +Signed-off-by: Vicente Bergas +Link: https://lore.kernel.org/r/20201201154132.1286-3-vicencb@gmail.com +Signed-off-by: Heiko Stuebner +--- + arch/arm64/boot/dts/rockchip/rk3399-rock-pi-4.dtsi | 5 +++-- + 1 file changed, 3 insertions(+), 2 deletions(-) + +diff --git a/arch/arm64/boot/dts/rockchip/rk3399-rock-pi-4.dtsi b/arch/arm64/boot/dts/rockchip/rk3399-rock-pi-4.dtsi +index 06df2397bbb4..63b029a543c1 100644 +--- a/arch/arm64/boot/dts/rockchip/rk3399-rock-pi-4.dtsi ++++ b/arch/arm64/boot/dts/rockchip/rk3399-rock-pi-4.dtsi +@@ -432,8 +432,9 @@ &i2c4 { + }; + + &i2s0 { +- rockchip,playback-channels = <8>; +- rockchip,capture-channels = <8>; ++ pinctrl-0 = <&i2s0_2ch_bus>; ++ rockchip,capture-channels = <2>; ++ rockchip,playback-channels = <2>; + status = "okay"; + }; + + +From c46c72e0ec62b22655a178f3841b541956b3976d Mon Sep 17 00:00:00 2001 +From: Vicente Bergas +Date: Tue, 1 Dec 2020 16:41:32 +0100 +Subject: [PATCH] arm64: dts: rockchip: use USB host by default on + rk3399-rock-pi-4 + +Based on the board schematics at +https://dl.radxa.com/rockpi4/docs/hw/rockpi4/rockpi_4c_v12_sch_20200620.pdf +on page 19 there is an USB Type-A receptacle being used as an USB-OTG port. + +But the Type-A connector is not valid for OTG operation, for this reason +there is a switch to select host or device role. +This is non-compliant and error prone because switching is manual. +So, use host mode as it corresponds for a Type-A receptacle. + +Signed-off-by: Vicente Bergas +Link: https://lore.kernel.org/r/20201201154132.1286-4-vicencb@gmail.com +Signed-off-by: Heiko Stuebner +--- + arch/arm64/boot/dts/rockchip/rk3399-rock-pi-4.dtsi | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/arch/arm64/boot/dts/rockchip/rk3399-rock-pi-4.dtsi b/arch/arm64/boot/dts/rockchip/rk3399-rock-pi-4.dtsi +index 63b029a543c1..fb7599f07af4 100644 +--- a/arch/arm64/boot/dts/rockchip/rk3399-rock-pi-4.dtsi ++++ b/arch/arm64/boot/dts/rockchip/rk3399-rock-pi-4.dtsi +@@ -673,7 +673,7 @@ &usbdrd3_0 { + + &usbdrd_dwc3_0 { + status = "okay"; +- dr_mode = "otg"; ++ dr_mode = "host"; + }; + + &usbdrd3_1 { diff --git a/projects/Rockchip/patches/linux/default/linux-0002-MiQi-Add-missing-GPU-CPU-nodes-in-dts.patch b/projects/Rockchip/patches/linux/default/linux-0002-MiQi-Add-missing-GPU-CPU-nodes-in-dts.patch deleted file mode 100644 index 779fa2c424..0000000000 --- a/projects/Rockchip/patches/linux/default/linux-0002-MiQi-Add-missing-GPU-CPU-nodes-in-dts.patch +++ /dev/null @@ -1,42 +0,0 @@ -From 42d58e8986d6fce9972c7f4bac614f06d28b0b8f Mon Sep 17 00:00:00 2001 -From: Ntemis -Date: Wed, 30 Dec 2020 00:31:42 +0200 -Subject: [PATCH] MiQi: Add missing GPU&CPU nodes in dts - ---- - arch/arm/boot/dts/rk3288-miqi.dts | 12 ++++++++++++ - 1 file changed, 12 insertions(+) - -diff --git a/arch/arm/boot/dts/rk3288-miqi.dts b/arch/arm/boot/dts/rk3288-miqi.dts -index cf54d5fff..40beaba54 100644 ---- a/arch/arm/boot/dts/rk3288-miqi.dts -+++ b/arch/arm/boot/dts/rk3288-miqi.dts -@@ -96,6 +96,13 @@ &cpu3 { - cpu-supply = <&vdd_cpu>; - }; - -+&cpu_opp_table { -+ opp-1704000000 { -+ opp-hz = /bits/ 64 <1704000000>; -+ opp-microvolt = <1350000>; -+ }; -+}; -+ - &emmc { - bus-width = <8>; - cap-mmc-highspeed; -@@ -123,6 +130,11 @@ &gmac { - status = "okay"; - }; - -+&gpu { -+ mali-supply = <&vdd_gpu>; -+ status = "okay"; -+}; -+ - &hdmi { - ddc-i2c-bus = <&i2c5>; - status = "okay"; --- -2.25.1 - diff --git a/projects/Rockchip/patches/linux/default/linux-0002-rockchip-from-next.patch b/projects/Rockchip/patches/linux/default/linux-0002-rockchip-from-next.patch new file mode 100644 index 0000000000..595923dba6 --- /dev/null +++ b/projects/Rockchip/patches/linux/default/linux-0002-rockchip-from-next.patch @@ -0,0 +1,949 @@ +From e701d077fd4d4c60d9a9d886665f91bf9e81372d Mon Sep 17 00:00:00 2001 +From: Sandy Huang +Date: Fri, 8 Jan 2021 12:06:27 +0100 +Subject: [PATCH] arm64: dts: rockchip: fix vopl iommu irq on px30 + +The vop-mmu shares the irq with its matched vop but not the vpu. + +Fixes: 7053e06b1422 ("arm64: dts: rockchip: add core dtsi file for PX30 SoCs") +Signed-off-by: Sandy Huang +Signed-off-by: Heiko Stuebner +Reviewed-by: Ezequiel Garcia +Reviewed-by: Paul Kocialkowski +Tested-by: Paul Kocialkowski +Link: https://lore.kernel.org/r/20210108110627.3231226-1-heiko@sntech.de +--- + arch/arm64/boot/dts/rockchip/px30.dtsi | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/arch/arm64/boot/dts/rockchip/px30.dtsi b/arch/arm64/boot/dts/rockchip/px30.dtsi +index 2695ea8cda14..64193292d26c 100644 +--- a/arch/arm64/boot/dts/rockchip/px30.dtsi ++++ b/arch/arm64/boot/dts/rockchip/px30.dtsi +@@ -1097,7 +1097,7 @@ vopl_out_lvds: endpoint@1 { + vopl_mmu: iommu@ff470f00 { + compatible = "rockchip,iommu"; + reg = <0x0 0xff470f00 0x0 0x100>; +- interrupts = ; ++ interrupts = ; + interrupt-names = "vopl_mmu"; + clocks = <&cru ACLK_VOPL>, <&cru HCLK_VOPL>; + clock-names = "aclk", "iface"; + +From 812e234c9503218da7a1bf328d130f7826054dd7 Mon Sep 17 00:00:00 2001 +From: Demetris Ierokipides +Date: Fri, 8 Jan 2021 17:10:35 +0200 +Subject: [PATCH] ARM: dts: rockchip: add gpu node to rk3288-miqi + +Add the Mali GPU node to the MiQi device-tree. + +Signed-off-by: Demetris Ierokipides +Link: https://lore.kernel.org/r/20210108151036.36434-2-ierokipides.dem@gmail.com +Signed-off-by: Heiko Stuebner +--- + arch/arm/boot/dts/rk3288-miqi.dts | 5 +++++ + 1 file changed, 5 insertions(+) + +diff --git a/arch/arm/boot/dts/rk3288-miqi.dts b/arch/arm/boot/dts/rk3288-miqi.dts +index cf54d5ffff2f..713f55e143c6 100644 +--- a/arch/arm/boot/dts/rk3288-miqi.dts ++++ b/arch/arm/boot/dts/rk3288-miqi.dts +@@ -123,6 +123,11 @@ &gmac { + status = "okay"; + }; + ++&gpu { ++ mali-supply = <&vdd_gpu>; ++ status = "okay"; ++}; ++ + &hdmi { + ddc-i2c-bus = <&i2c5>; + status = "okay"; + +From 2bdfcd8cbb80d7c1f617b780199117d68d80a015 Mon Sep 17 00:00:00 2001 +From: Johan Jonker +Date: Sat, 19 Dec 2020 22:05:00 +0100 +Subject: [PATCH] arm64: dts: rockchip: assign a fixed index to mmc devices on + rk3328 boards + +Recently introduced async probe on mmc devices can shuffle block IDs. +Pin them to fixed values to ease booting in environments where UUIDs +are not practical. Use newly introduced aliases for mmcblk devices from [1]. + +[1] https://patchwork.kernel.org/patch/11747669/ + +Signed-off-by: Johan Jonker +Link: https://lore.kernel.org/r/20201219210500.3855-1-jbx6244@gmail.com +Signed-off-by: Heiko Stuebner +--- + arch/arm64/boot/dts/rockchip/rk3328.dtsi | 3 +++ + 1 file changed, 3 insertions(+) + +diff --git a/arch/arm64/boot/dts/rockchip/rk3328.dtsi b/arch/arm64/boot/dts/rockchip/rk3328.dtsi +index db0d5c8e5f96..56b5ee7e54c4 100644 +--- a/arch/arm64/boot/dts/rockchip/rk3328.dtsi ++++ b/arch/arm64/boot/dts/rockchip/rk3328.dtsi +@@ -27,6 +27,9 @@ aliases { + i2c1 = &i2c1; + i2c2 = &i2c2; + i2c3 = &i2c3; ++ mmc0 = &sdmmc; ++ mmc1 = &sdio; ++ mmc2 = &emmc; + ethernet0 = &gmac2io; + ethernet1 = &gmac2phy; + }; + +From 9d48adb46a3a770ca2a9fd908aff32ced094ea58 Mon Sep 17 00:00:00 2001 +From: Jagan Teki +Date: Fri, 31 Jul 2020 21:33:24 +0530 +Subject: [PATCH] arm64: defconfig: Enable REGULATOR_MP8859 + +RK3399 boards like ROC-RK3399-PC is using MP8859 DC/DC converter +for 12V supply. + +roc-rk3399-pc initially used 12V fixed regulator for this supply, +but the below commit has switched to use MP8859. + +commit <1fc61ed04d309b0b8b3562acf701ab988eee12de> "arm64: dts: rockchip: +Enable mp8859 regulator on rk3399-roc-pc" + +So, enable by default on the defconfig. + +Signed-off-by: Jagan Teki +Tested-by: Suniel Mahesh +Link: https://lore.kernel.org/r/20200731160324.142097-1-jagan@amarulasolutions.com +Signed-off-by: Heiko Stuebner +--- + arch/arm64/configs/defconfig | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/arch/arm64/configs/defconfig b/arch/arm64/configs/defconfig +index 699c204090b8..9365213589bb 100644 +--- a/arch/arm64/configs/defconfig ++++ b/arch/arm64/configs/defconfig +@@ -588,6 +588,7 @@ CONFIG_REGULATOR_HI6421V530=y + CONFIG_REGULATOR_HI655X=y + CONFIG_REGULATOR_MAX77620=y + CONFIG_REGULATOR_MAX8973=y ++CONFIG_REGULATOR_MP8859=y + CONFIG_REGULATOR_PCA9450=y + CONFIG_REGULATOR_PFUZE100=y + CONFIG_REGULATOR_PWM=y + +From ce1b6881feca75f071dc2d90157c54d4f3977ce4 Mon Sep 17 00:00:00 2001 +From: Johan Jonker +Date: Sun, 6 Dec 2020 11:37:08 +0100 +Subject: [PATCH] ARM: dts: rockchip: add QoS register compatibles for + rk3066/rk3188 + +With the conversion of syscon.yaml minItems for compatibles +was set to 2. Current Rockchip dtsi files only use "syscon" for +QoS registers. Add Rockchip QoS compatibles for rk3066/rk3188 +to reduce notifications produced with: + +make ARCH=arm dtbs_check +DT_SCHEMA_FILES=Documentation/devicetree/bindings/mfd/syscon.yaml + +Signed-off-by: Johan Jonker +Link: https://lore.kernel.org/r/20201206103711.7465-1-jbx6244@gmail.com +Signed-off-by: Heiko Stuebner +--- + arch/arm/boot/dts/rk3xxx.dtsi | 16 ++++++++-------- + 1 file changed, 8 insertions(+), 8 deletions(-) + +diff --git a/arch/arm/boot/dts/rk3xxx.dtsi b/arch/arm/boot/dts/rk3xxx.dtsi +index 859a7477909f..49bcdf46d03c 100644 +--- a/arch/arm/boot/dts/rk3xxx.dtsi ++++ b/arch/arm/boot/dts/rk3xxx.dtsi +@@ -151,42 +151,42 @@ uart1: serial@10126000 { + }; + + qos_gpu: qos@1012d000 { +- compatible = "syscon"; ++ compatible = "rockchip,rk3066-qos", "syscon"; + reg = <0x1012d000 0x20>; + }; + + qos_vpu: qos@1012e000 { +- compatible = "syscon"; ++ compatible = "rockchip,rk3066-qos", "syscon"; + reg = <0x1012e000 0x20>; + }; + + qos_lcdc0: qos@1012f000 { +- compatible = "syscon"; ++ compatible = "rockchip,rk3066-qos", "syscon"; + reg = <0x1012f000 0x20>; + }; + + qos_cif0: qos@1012f080 { +- compatible = "syscon"; ++ compatible = "rockchip,rk3066-qos", "syscon"; + reg = <0x1012f080 0x20>; + }; + + qos_ipp: qos@1012f100 { +- compatible = "syscon"; ++ compatible = "rockchip,rk3066-qos", "syscon"; + reg = <0x1012f100 0x20>; + }; + + qos_lcdc1: qos@1012f180 { +- compatible = "syscon"; ++ compatible = "rockchip,rk3066-qos", "syscon"; + reg = <0x1012f180 0x20>; + }; + + qos_cif1: qos@1012f200 { +- compatible = "syscon"; ++ compatible = "rockchip,rk3066-qos", "syscon"; + reg = <0x1012f200 0x20>; + }; + + qos_rga: qos@1012f280 { +- compatible = "syscon"; ++ compatible = "rockchip,rk3066-qos", "syscon"; + reg = <0x1012f280 0x20>; + }; + + +From 1a5c445dcef00ea302140df8db253669bcebb7e1 Mon Sep 17 00:00:00 2001 +From: Johan Jonker +Date: Sun, 6 Dec 2020 11:37:09 +0100 +Subject: [PATCH] ARM: dts: rockchip: add QoS register compatibles for rk3288 + +With the conversion of syscon.yaml minItems for compatibles +was set to 2. Current Rockchip dtsi files only use "syscon" for +QoS registers. Add Rockchip QoS compatibles for rk3288 +to reduce notifications produced with: + +make ARCH=arm dtbs_check +DT_SCHEMA_FILES=Documentation/devicetree/bindings/mfd/syscon.yaml + +Signed-off-by: Johan Jonker +Link: https://lore.kernel.org/r/20201206103711.7465-2-jbx6244@gmail.com +Signed-off-by: Heiko Stuebner +--- + arch/arm/boot/dts/rk3288.dtsi | 28 ++++++++++++++-------------- + 1 file changed, 14 insertions(+), 14 deletions(-) + +diff --git a/arch/arm/boot/dts/rk3288.dtsi b/arch/arm/boot/dts/rk3288.dtsi +index 68d5a58cfe88..01ea1f170f77 100644 +--- a/arch/arm/boot/dts/rk3288.dtsi ++++ b/arch/arm/boot/dts/rk3288.dtsi +@@ -1329,72 +1329,72 @@ opp-600000000 { + }; + + qos_gpu_r: qos@ffaa0000 { +- compatible = "syscon"; ++ compatible = "rockchip,rk3288-qos", "syscon"; + reg = <0x0 0xffaa0000 0x0 0x20>; + }; + + qos_gpu_w: qos@ffaa0080 { +- compatible = "syscon"; ++ compatible = "rockchip,rk3288-qos", "syscon"; + reg = <0x0 0xffaa0080 0x0 0x20>; + }; + + qos_vio1_vop: qos@ffad0000 { +- compatible = "syscon"; ++ compatible = "rockchip,rk3288-qos", "syscon"; + reg = <0x0 0xffad0000 0x0 0x20>; + }; + + qos_vio1_isp_w0: qos@ffad0100 { +- compatible = "syscon"; ++ compatible = "rockchip,rk3288-qos", "syscon"; + reg = <0x0 0xffad0100 0x0 0x20>; + }; + + qos_vio1_isp_w1: qos@ffad0180 { +- compatible = "syscon"; ++ compatible = "rockchip,rk3288-qos", "syscon"; + reg = <0x0 0xffad0180 0x0 0x20>; + }; + + qos_vio0_vop: qos@ffad0400 { +- compatible = "syscon"; ++ compatible = "rockchip,rk3288-qos", "syscon"; + reg = <0x0 0xffad0400 0x0 0x20>; + }; + + qos_vio0_vip: qos@ffad0480 { +- compatible = "syscon"; ++ compatible = "rockchip,rk3288-qos", "syscon"; + reg = <0x0 0xffad0480 0x0 0x20>; + }; + + qos_vio0_iep: qos@ffad0500 { +- compatible = "syscon"; ++ compatible = "rockchip,rk3288-qos", "syscon"; + reg = <0x0 0xffad0500 0x0 0x20>; + }; + + qos_vio2_rga_r: qos@ffad0800 { +- compatible = "syscon"; ++ compatible = "rockchip,rk3288-qos", "syscon"; + reg = <0x0 0xffad0800 0x0 0x20>; + }; + + qos_vio2_rga_w: qos@ffad0880 { +- compatible = "syscon"; ++ compatible = "rockchip,rk3288-qos", "syscon"; + reg = <0x0 0xffad0880 0x0 0x20>; + }; + + qos_vio1_isp_r: qos@ffad0900 { +- compatible = "syscon"; ++ compatible = "rockchip,rk3288-qos", "syscon"; + reg = <0x0 0xffad0900 0x0 0x20>; + }; + + qos_video: qos@ffae0000 { +- compatible = "syscon"; ++ compatible = "rockchip,rk3288-qos", "syscon"; + reg = <0x0 0xffae0000 0x0 0x20>; + }; + + qos_hevc_r: qos@ffaf0000 { +- compatible = "syscon"; ++ compatible = "rockchip,rk3288-qos", "syscon"; + reg = <0x0 0xffaf0000 0x0 0x20>; + }; + + qos_hevc_w: qos@ffaf0080 { +- compatible = "syscon"; ++ compatible = "rockchip,rk3288-qos", "syscon"; + reg = <0x0 0xffaf0080 0x0 0x20>; + }; + + +From e73e7d1c7cf928b706c0f2d3eaf9fbf7c7b7205f Mon Sep 17 00:00:00 2001 +From: Johan Jonker +Date: Sun, 6 Dec 2020 11:37:10 +0100 +Subject: [PATCH] arm64: dts: rockchip: add QoS register compatibles for rk3399 + +With the conversion of syscon.yaml minItems for compatibles +was set to 2. Current Rockchip dtsi files only use "syscon" for +QoS registers. Add Rockchip QoS compatibles for rk3399 +to reduce notifications produced with: + +make ARCH=arm64 dtbs_check +DT_SCHEMA_FILES=Documentation/devicetree/bindings/mfd/syscon.yaml + +Signed-off-by: Johan Jonker +Link: https://lore.kernel.org/r/20201206103711.7465-3-jbx6244@gmail.com +Signed-off-by: Heiko Stuebner +--- + arch/arm64/boot/dts/rockchip/rk3399.dtsi | 50 ++++++++++++------------ + 1 file changed, 25 insertions(+), 25 deletions(-) + +diff --git a/arch/arm64/boot/dts/rockchip/rk3399.dtsi b/arch/arm64/boot/dts/rockchip/rk3399.dtsi +index f5dee5f447bb..cd9fbd3cfcaf 100644 +--- a/arch/arm64/boot/dts/rockchip/rk3399.dtsi ++++ b/arch/arm64/boot/dts/rockchip/rk3399.dtsi +@@ -858,127 +858,127 @@ tsadc: tsadc@ff260000 { + }; + + qos_emmc: qos@ffa58000 { +- compatible = "syscon"; ++ compatible = "rockchip,rk3399-qos", "syscon"; + reg = <0x0 0xffa58000 0x0 0x20>; + }; + + qos_gmac: qos@ffa5c000 { +- compatible = "syscon"; ++ compatible = "rockchip,rk3399-qos", "syscon"; + reg = <0x0 0xffa5c000 0x0 0x20>; + }; + + qos_pcie: qos@ffa60080 { +- compatible = "syscon"; ++ compatible = "rockchip,rk3399-qos", "syscon"; + reg = <0x0 0xffa60080 0x0 0x20>; + }; + + qos_usb_host0: qos@ffa60100 { +- compatible = "syscon"; ++ compatible = "rockchip,rk3399-qos", "syscon"; + reg = <0x0 0xffa60100 0x0 0x20>; + }; + + qos_usb_host1: qos@ffa60180 { +- compatible = "syscon"; ++ compatible = "rockchip,rk3399-qos", "syscon"; + reg = <0x0 0xffa60180 0x0 0x20>; + }; + + qos_usb_otg0: qos@ffa70000 { +- compatible = "syscon"; ++ compatible = "rockchip,rk3399-qos", "syscon"; + reg = <0x0 0xffa70000 0x0 0x20>; + }; + + qos_usb_otg1: qos@ffa70080 { +- compatible = "syscon"; ++ compatible = "rockchip,rk3399-qos", "syscon"; + reg = <0x0 0xffa70080 0x0 0x20>; + }; + + qos_sd: qos@ffa74000 { +- compatible = "syscon"; ++ compatible = "rockchip,rk3399-qos", "syscon"; + reg = <0x0 0xffa74000 0x0 0x20>; + }; + + qos_sdioaudio: qos@ffa76000 { +- compatible = "syscon"; ++ compatible = "rockchip,rk3399-qos", "syscon"; + reg = <0x0 0xffa76000 0x0 0x20>; + }; + + qos_hdcp: qos@ffa90000 { +- compatible = "syscon"; ++ compatible = "rockchip,rk3399-qos", "syscon"; + reg = <0x0 0xffa90000 0x0 0x20>; + }; + + qos_iep: qos@ffa98000 { +- compatible = "syscon"; ++ compatible = "rockchip,rk3399-qos", "syscon"; + reg = <0x0 0xffa98000 0x0 0x20>; + }; + + qos_isp0_m0: qos@ffaa0000 { +- compatible = "syscon"; ++ compatible = "rockchip,rk3399-qos", "syscon"; + reg = <0x0 0xffaa0000 0x0 0x20>; + }; + + qos_isp0_m1: qos@ffaa0080 { +- compatible = "syscon"; ++ compatible = "rockchip,rk3399-qos", "syscon"; + reg = <0x0 0xffaa0080 0x0 0x20>; + }; + + qos_isp1_m0: qos@ffaa8000 { +- compatible = "syscon"; ++ compatible = "rockchip,rk3399-qos", "syscon"; + reg = <0x0 0xffaa8000 0x0 0x20>; + }; + + qos_isp1_m1: qos@ffaa8080 { +- compatible = "syscon"; ++ compatible = "rockchip,rk3399-qos", "syscon"; + reg = <0x0 0xffaa8080 0x0 0x20>; + }; + + qos_rga_r: qos@ffab0000 { +- compatible = "syscon"; ++ compatible = "rockchip,rk3399-qos", "syscon"; + reg = <0x0 0xffab0000 0x0 0x20>; + }; + + qos_rga_w: qos@ffab0080 { +- compatible = "syscon"; ++ compatible = "rockchip,rk3399-qos", "syscon"; + reg = <0x0 0xffab0080 0x0 0x20>; + }; + + qos_video_m0: qos@ffab8000 { +- compatible = "syscon"; ++ compatible = "rockchip,rk3399-qos", "syscon"; + reg = <0x0 0xffab8000 0x0 0x20>; + }; + + qos_video_m1_r: qos@ffac0000 { +- compatible = "syscon"; ++ compatible = "rockchip,rk3399-qos", "syscon"; + reg = <0x0 0xffac0000 0x0 0x20>; + }; + + qos_video_m1_w: qos@ffac0080 { +- compatible = "syscon"; ++ compatible = "rockchip,rk3399-qos", "syscon"; + reg = <0x0 0xffac0080 0x0 0x20>; + }; + + qos_vop_big_r: qos@ffac8000 { +- compatible = "syscon"; ++ compatible = "rockchip,rk3399-qos", "syscon"; + reg = <0x0 0xffac8000 0x0 0x20>; + }; + + qos_vop_big_w: qos@ffac8080 { +- compatible = "syscon"; ++ compatible = "rockchip,rk3399-qos", "syscon"; + reg = <0x0 0xffac8080 0x0 0x20>; + }; + + qos_vop_little: qos@ffad0000 { +- compatible = "syscon"; ++ compatible = "rockchip,rk3399-qos", "syscon"; + reg = <0x0 0xffad0000 0x0 0x20>; + }; + + qos_perihp: qos@ffad8080 { +- compatible = "syscon"; ++ compatible = "rockchip,rk3399-qos", "syscon"; + reg = <0x0 0xffad8080 0x0 0x20>; + }; + + qos_gpu: qos@ffae0000 { +- compatible = "syscon"; ++ compatible = "rockchip,rk3399-qos", "syscon"; + reg = <0x0 0xffae0000 0x0 0x20>; + }; + + +From 96c2b52bf2175c5e3ee0bf37ac9fcfcb07d7517a Mon Sep 17 00:00:00 2001 +From: Johan Jonker +Date: Sun, 6 Dec 2020 11:37:11 +0100 +Subject: [PATCH] arm64: dts: rockchip: add QoS register compatibles for px30 + +With the conversion of syscon.yaml minItems for compatibles +was set to 2. Current Rockchip dtsi files only use "syscon" for +QoS registers. Add Rockchip QoS compatibles for px30 +to reduce notifications produced with: + +make ARCH=arm64 dtbs_check +DT_SCHEMA_FILES=Documentation/devicetree/bindings/mfd/syscon.yaml + +Signed-off-by: Johan Jonker +Link: https://lore.kernel.org/r/20201206103711.7465-4-jbx6244@gmail.com +Signed-off-by: Heiko Stuebner +--- + arch/arm64/boot/dts/rockchip/px30.dtsi | 40 +++++++++++++------------- + 1 file changed, 20 insertions(+), 20 deletions(-) + +diff --git a/arch/arm64/boot/dts/rockchip/px30.dtsi b/arch/arm64/boot/dts/rockchip/px30.dtsi +index 64193292d26c..d8b673b486c9 100644 +--- a/arch/arm64/boot/dts/rockchip/px30.dtsi ++++ b/arch/arm64/boot/dts/rockchip/px30.dtsi +@@ -1107,102 +1107,102 @@ vopl_mmu: iommu@ff470f00 { + }; + + qos_gmac: qos@ff518000 { +- compatible = "syscon"; ++ compatible = "rockchip,px30-qos", "syscon"; + reg = <0x0 0xff518000 0x0 0x20>; + }; + + qos_gpu: qos@ff520000 { +- compatible = "syscon"; ++ compatible = "rockchip,px30-qos", "syscon"; + reg = <0x0 0xff520000 0x0 0x20>; + }; + + qos_sdmmc: qos@ff52c000 { +- compatible = "syscon"; ++ compatible = "rockchip,px30-qos", "syscon"; + reg = <0x0 0xff52c000 0x0 0x20>; + }; + + qos_emmc: qos@ff538000 { +- compatible = "syscon"; ++ compatible = "rockchip,px30-qos", "syscon"; + reg = <0x0 0xff538000 0x0 0x20>; + }; + + qos_nand: qos@ff538080 { +- compatible = "syscon"; ++ compatible = "rockchip,px30-qos", "syscon"; + reg = <0x0 0xff538080 0x0 0x20>; + }; + + qos_sdio: qos@ff538100 { +- compatible = "syscon"; ++ compatible = "rockchip,px30-qos", "syscon"; + reg = <0x0 0xff538100 0x0 0x20>; + }; + + qos_sfc: qos@ff538180 { +- compatible = "syscon"; ++ compatible = "rockchip,px30-qos", "syscon"; + reg = <0x0 0xff538180 0x0 0x20>; + }; + + qos_usb_host: qos@ff540000 { +- compatible = "syscon"; ++ compatible = "rockchip,px30-qos", "syscon"; + reg = <0x0 0xff540000 0x0 0x20>; + }; + + qos_usb_otg: qos@ff540080 { +- compatible = "syscon"; ++ compatible = "rockchip,px30-qos", "syscon"; + reg = <0x0 0xff540080 0x0 0x20>; + }; + + qos_isp_128: qos@ff548000 { +- compatible = "syscon"; ++ compatible = "rockchip,px30-qos", "syscon"; + reg = <0x0 0xff548000 0x0 0x20>; + }; + + qos_isp_rd: qos@ff548080 { +- compatible = "syscon"; ++ compatible = "rockchip,px30-qos", "syscon"; + reg = <0x0 0xff548080 0x0 0x20>; + }; + + qos_isp_wr: qos@ff548100 { +- compatible = "syscon"; ++ compatible = "rockchip,px30-qos", "syscon"; + reg = <0x0 0xff548100 0x0 0x20>; + }; + + qos_isp_m1: qos@ff548180 { +- compatible = "syscon"; ++ compatible = "rockchip,px30-qos", "syscon"; + reg = <0x0 0xff548180 0x0 0x20>; + }; + + qos_vip: qos@ff548200 { +- compatible = "syscon"; ++ compatible = "rockchip,px30-qos", "syscon"; + reg = <0x0 0xff548200 0x0 0x20>; + }; + + qos_rga_rd: qos@ff550000 { +- compatible = "syscon"; ++ compatible = "rockchip,px30-qos", "syscon"; + reg = <0x0 0xff550000 0x0 0x20>; + }; + + qos_rga_wr: qos@ff550080 { +- compatible = "syscon"; ++ compatible = "rockchip,px30-qos", "syscon"; + reg = <0x0 0xff550080 0x0 0x20>; + }; + + qos_vop_m0: qos@ff550100 { +- compatible = "syscon"; ++ compatible = "rockchip,px30-qos", "syscon"; + reg = <0x0 0xff550100 0x0 0x20>; + }; + + qos_vop_m1: qos@ff550180 { +- compatible = "syscon"; ++ compatible = "rockchip,px30-qos", "syscon"; + reg = <0x0 0xff550180 0x0 0x20>; + }; + + qos_vpu: qos@ff558000 { +- compatible = "syscon"; ++ compatible = "rockchip,px30-qos", "syscon"; + reg = <0x0 0xff558000 0x0 0x20>; + }; + + qos_vpu_r128: qos@ff558080 { +- compatible = "syscon"; ++ compatible = "rockchip,px30-qos", "syscon"; + reg = <0x0 0xff558080 0x0 0x20>; + }; + + +From ee48fd6cdd11156b2bdf4f8f56280d3abe249300 Mon Sep 17 00:00:00 2001 +From: Simon South +Date: Wed, 30 Sep 2020 14:56:27 -0400 +Subject: [PATCH] arm64: dts: rockchip: Use only supported PCIe link speed on + Pinebook Pro + +On Pinebook Pro laptops with an NVMe SSD installed, prevent random +crashes in the NVMe driver by not attempting to use a PCIe link speed +higher than that supported by the RK3399 SoC. + +See commit 712fa1777207 ("arm64: dts: rockchip: add max-link-speed for +rk3399"). + +Fixes: 5a65505a6988 ("arm64: dts: rockchip: Add initial support for Pinebook Pro") +Signed-off-by: Simon South +Link: https://lore.kernel.org/r/20200930185627.5918-1-simon@simonsouth.net +Signed-off-by: Heiko Stuebner +--- + arch/arm64/boot/dts/rockchip/rk3399-pinebook-pro.dts | 1 - + 1 file changed, 1 deletion(-) + +diff --git a/arch/arm64/boot/dts/rockchip/rk3399-pinebook-pro.dts b/arch/arm64/boot/dts/rockchip/rk3399-pinebook-pro.dts +index 06d48338c836..219b7507a10f 100644 +--- a/arch/arm64/boot/dts/rockchip/rk3399-pinebook-pro.dts ++++ b/arch/arm64/boot/dts/rockchip/rk3399-pinebook-pro.dts +@@ -790,7 +790,6 @@ &pcie_phy { + &pcie0 { + bus-scan-delay-ms = <1000>; + ep-gpios = <&gpio2 RK_PD4 GPIO_ACTIVE_HIGH>; +- max-link-speed = <2>; + num-lanes = <4>; + pinctrl-names = "default"; + pinctrl-0 = <&pcie_clkreqn_cpm>; + +From 2fa6252a57ffdbb0b31b5687953b868eb4fe11fb Mon Sep 17 00:00:00 2001 +From: Katsuhiro Suzuki +Date: Mon, 3 Aug 2020 00:42:31 +0900 +Subject: [PATCH] arm64: dts: rockchip: enable HDMI sound nodes for + rk3328-rock64 + +This patch enables HDMI sound (I2S0) and Analog sound (I2S1) which +are defined in rk3328.dtsi, and replace SPDIF nodes. + +We can use SPDIF pass-through with suitable ALSA settings and on +mpv or other media players. + - Settings: https://github.com/LibreELEC/LibreELEC.tv/blob/master/projects/Rockchip/filesystem/usr/share/alsa/cards/SPDIF.conf + - Ex.: mpv foo.ac3 --audio-spdif=ac3 --audio-device='alsa/SPDIF.pcm.iec958.0:SPDIF' + +[Why use simple-audio-card for SPDIF?] + +For newly adding nodes, ASoC guys recommend to use audio-graph-card. +But all other sound nodes for rk3328 have already been defined by +simple-audio-card. In this time, I chose for consistent sound nodes. + +[DMA allocation problem] + +After this patch is applied, UART2 will fail to allocate DMA resources +but UART driver can work fine without DMA. + +This error is related to the DMAC of rk3328 (pl330 or compatible). +DMAC connected to 16 DMA sources. Each sources have ID number that is +called 'Req number' in rk3328 TRM. After this patch is applied total 7 +of DMA sources will be activated as follows: + +| Req number | Source | Required | +| | | channels | +|------------+--------+-----------| +| 8, 9 | SPI0 | 2ch | +| 11, 12 | I2S0 | 2ch | +| 14, 15 | I2S1 | 2ch | +| 10 | SPDIF | 1ch | +|------------+--------+-----------| +| | Total | 7ch | +|------------+--------+-----------| +| 6, 7 | UART2 | 2ch | -> cannot get DMA channels + +Due to rk3328 DMAC specification we can use max 8 channels at same +time. If SPI0/I2S0/I2S1/SPDIF will be activated by this patch, +required DMAC channels reach to 7. So the last two channels (for +UART2) cannot get DMA resources. + +Virt-dma mechanism for pl0330 DMAC driver is needed to fix this +problem. + +Signed-off-by: Katsuhiro Suzuki +Link: https://lore.kernel.org/r/20200802154231.2639186-1-katsuhiro@katsuster.net +Signed-off-by: Heiko Stuebner +--- + .../arm64/boot/dts/rockchip/rk3328-rock64.dts | 56 ++++++++----------- + 1 file changed, 24 insertions(+), 32 deletions(-) + +diff --git a/arch/arm64/boot/dts/rockchip/rk3328-rock64.dts b/arch/arm64/boot/dts/rockchip/rk3328-rock64.dts +index 86cfb5c50a94..c984662043da 100644 +--- a/arch/arm64/boot/dts/rockchip/rk3328-rock64.dts ++++ b/arch/arm64/boot/dts/rockchip/rk3328-rock64.dts +@@ -84,34 +84,32 @@ standby_led: led-1 { + }; + }; + +- sound { +- compatible = "audio-graph-card"; +- label = "rockchip,rk3328"; +- dais = <&i2s1_p0 +- &spdif_p0>; ++ spdif_sound: spdif-sound { ++ compatible = "simple-audio-card"; ++ simple-audio-card,name = "SPDIF"; ++ ++ simple-audio-card,cpu { ++ sound-dai = <&spdif>; ++ }; ++ ++ simple-audio-card,codec { ++ sound-dai = <&spdif_dit>; ++ }; + }; + +- spdif-dit { ++ spdif_dit: spdif-dit { + compatible = "linux,spdif-dit"; + #sound-dai-cells = <0>; +- +- port { +- dit_p0_0: endpoint { +- remote-endpoint = <&spdif_p0_0>; +- }; +- }; + }; + }; + ++&analog_sound { ++ status = "okay"; ++}; ++ + &codec { + mute-gpios = <&grf_gpio 0 GPIO_ACTIVE_LOW>; + status = "okay"; +- +- port@0 { +- codec_p0_0: endpoint { +- remote-endpoint = <&i2s1_p0_0>; +- }; +- }; + }; + + &cpu0 { +@@ -163,6 +161,10 @@ &hdmi { + status = "okay"; + }; + ++&hdmi_sound { ++ status = "okay"; ++}; ++ + &hdmiphy { + status = "okay"; + }; +@@ -278,16 +280,12 @@ regulator-state-mem { + }; + }; + +-&i2s1 { ++&i2s0 { + status = "okay"; ++}; + +- i2s1_p0: port { +- i2s1_p0_0: endpoint { +- dai-format = "i2s"; +- mclk-fs = <256>; +- remote-endpoint = <&codec_p0_0>; +- }; +- }; ++&i2s1 { ++ status = "okay"; + }; + + &io_domains { +@@ -337,12 +335,6 @@ &sdmmc { + &spdif { + pinctrl-0 = <&spdifm0_tx>; + status = "okay"; +- +- spdif_p0: port { +- spdif_p0_0: endpoint { +- remote-endpoint = <&dit_p0_0>; +- }; +- }; + }; + + &spi0 { + +From 2396b9c1b8eb91c552fc1186d7845911fed1650a Mon Sep 17 00:00:00 2001 +From: Katsuhiro Suzuki +Date: Mon, 10 Aug 2020 18:16:19 +0900 +Subject: [PATCH] arm64: dts: rockchip: add SPDIF node for rk3399-rockpro64 + +This patch adds 'disabled' SPDIF sound node and related settings +for rk3399-rockpro64. + +There are 2 reasons: + - All RK3399 dma-bus channels have been already used by I2S0/1/2 + - RockPro64 does not have SPDIF optical nor coaxial connector, + just have 3pins + +Signed-off-by: Katsuhiro Suzuki +Link: https://lore.kernel.org/r/20200810091619.3170534-1-katsuhiro@katsuster.net +Signed-off-by: Heiko Stuebner +--- + .../boot/dts/rockchip/rk3399-rockpro64.dtsi | 27 +++++++++++++++++++ + 1 file changed, 27 insertions(+) + +diff --git a/arch/arm64/boot/dts/rockchip/rk3399-rockpro64.dtsi b/arch/arm64/boot/dts/rockchip/rk3399-rockpro64.dtsi +index 6e553ff47534..58097245994a 100644 +--- a/arch/arm64/boot/dts/rockchip/rk3399-rockpro64.dtsi ++++ b/arch/arm64/boot/dts/rockchip/rk3399-rockpro64.dtsi +@@ -76,6 +76,23 @@ sound { + dais = <&i2s1_p0>; + }; + ++ sound-dit { ++ compatible = "audio-graph-card"; ++ label = "rockchip,rk3399"; ++ dais = <&spdif_p0>; ++ }; ++ ++ spdif-dit { ++ compatible = "linux,spdif-dit"; ++ #sound-dai-cells = <0>; ++ ++ port { ++ dit_p0_0: endpoint { ++ remote-endpoint = <&spdif_p0_0>; ++ }; ++ }; ++ }; ++ + vcc12v_dcin: vcc12v-dcin { + compatible = "regulator-fixed"; + regulator-name = "vcc12v_dcin"; +@@ -698,6 +715,16 @@ &sdhci { + status = "okay"; + }; + ++&spdif { ++ pinctrl-0 = <&spdif_bus_1>; ++ ++ spdif_p0: port { ++ spdif_p0_0: endpoint { ++ remote-endpoint = <&dit_p0_0>; ++ }; ++ }; ++}; ++ + &spi1 { + status = "okay"; + + +From 0e089a16f0d0f926491689e11d01a0bbc8b91f2f Mon Sep 17 00:00:00 2001 +From: Marc Zyngier +Date: Sat, 15 Aug 2020 13:51:12 +0100 +Subject: [PATCH] arm64: dts: rockchip: Fix PCIe DT properties on rk3399 + +It recently became apparent that the lack of a 'device_type = "pci"' +in the PCIe root complex node for rk3399 is a violation of the PCI +binding, as documented in IEEE Std 1275-1994. Changes to the kernel's +parsing of the DT made such violation fatal, as drivers cannot +probe the controller anymore. + +Add the missing property makes the PCIe node compliant. While we +are at it, drop the pointless linux,pci-domain property, which only +makes sense when there are multiple host bridges. + +Signed-off-by: Marc Zyngier +Link: https://lore.kernel.org/r/20200815125112.462652-3-maz@kernel.org +Signed-off-by: Heiko Stuebner +--- + arch/arm64/boot/dts/rockchip/rk3399.dtsi | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/arch/arm64/boot/dts/rockchip/rk3399.dtsi b/arch/arm64/boot/dts/rockchip/rk3399.dtsi +index cd9fbd3cfcaf..a855805649ef 100644 +--- a/arch/arm64/boot/dts/rockchip/rk3399.dtsi ++++ b/arch/arm64/boot/dts/rockchip/rk3399.dtsi +@@ -234,6 +234,7 @@ pcie0: pcie@f8000000 { + reg = <0x0 0xf8000000 0x0 0x2000000>, + <0x0 0xfd000000 0x0 0x1000000>; + reg-names = "axi-base", "apb-base"; ++ device_type = "pci"; + #address-cells = <3>; + #size-cells = <2>; + #interrupt-cells = <1>; +@@ -252,7 +253,6 @@ pcie0: pcie@f8000000 { + <0 0 0 2 &pcie0_intc 1>, + <0 0 0 3 &pcie0_intc 2>, + <0 0 0 4 &pcie0_intc 3>; +- linux,pci-domain = <0>; + max-link-speed = <1>; + msi-map = <0x0 &its 0x0 0x1000>; + phys = <&pcie_phy 0>, <&pcie_phy 1>, diff --git a/projects/Rockchip/patches/linux/default/linux-0003-rockchip-from-list.patch b/projects/Rockchip/patches/linux/default/linux-0003-rockchip-from-list.patch new file mode 100644 index 0000000000..fbfddf6af9 --- /dev/null +++ b/projects/Rockchip/patches/linux/default/linux-0003-rockchip-from-list.patch @@ -0,0 +1,1369 @@ +From a2c7d649c4d8d083c50bb041afb72c44f6303c3f Mon Sep 17 00:00:00 2001 +From: Jonas Karlman +Date: Sat, 10 Oct 2020 15:32:18 +0000 +Subject: [PATCH] phy/rockchip: inno-hdmi: use correct vco_div_5 macro on + rk3328 + +inno_hdmi_phy_rk3328_clk_set_rate() is using the RK3228 macro +when configuring vco_div_5 on RK3328. + +Fix this by using correct vco_div_5 macro for RK3328. + +Fixes: 53706a116863 ("phy: add Rockchip Innosilicon hdmi phy") +Signed-off-by: Jonas Karlman +--- + drivers/phy/rockchip/phy-rockchip-inno-hdmi.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +diff --git a/drivers/phy/rockchip/phy-rockchip-inno-hdmi.c b/drivers/phy/rockchip/phy-rockchip-inno-hdmi.c +index 9ca20c947283..b0ac1d3ee390 100644 +--- a/drivers/phy/rockchip/phy-rockchip-inno-hdmi.c ++++ b/drivers/phy/rockchip/phy-rockchip-inno-hdmi.c +@@ -790,8 +790,8 @@ static int inno_hdmi_phy_rk3328_clk_set_rate(struct clk_hw *hw, + RK3328_PRE_PLL_POWER_DOWN); + + /* Configure pre-pll */ +- inno_update_bits(inno, 0xa0, RK3228_PCLK_VCO_DIV_5_MASK, +- RK3228_PCLK_VCO_DIV_5(cfg->vco_div_5_en)); ++ inno_update_bits(inno, 0xa0, RK3328_PCLK_VCO_DIV_5_MASK, ++ RK3328_PCLK_VCO_DIV_5(cfg->vco_div_5_en)); + inno_write(inno, 0xa1, RK3328_PRE_PLL_PRE_DIV(cfg->prediv)); + + val = RK3328_SPREAD_SPECTRUM_MOD_DISABLE; + +From c8eed3a33d805f63465766f2b0ae75f3e824ec12 Mon Sep 17 00:00:00 2001 +From: Zheng Yang +Date: Sat, 10 Oct 2020 15:32:18 +0000 +Subject: [PATCH] phy/rockchip: inno-hdmi: round fractal pixclock in rk3328 + recalc_rate + +inno_hdmi_phy_rk3328_clk_recalc_rate() is returning a rate not found +in the pre pll config table when the fractal divider is used. +This can prevent proper power_on because a tmdsclock for the new rate +is not found in the pre pll config table. + +Fix this by saving and returning a rounded pixel rate that exist +in the pre pll config table. + +Fixes: 53706a116863 ("phy: add Rockchip Innosilicon hdmi phy") +Signed-off-by: Zheng Yang +Signed-off-by: Jonas Karlman +--- + drivers/phy/rockchip/phy-rockchip-inno-hdmi.c | 8 +++++--- + 1 file changed, 5 insertions(+), 3 deletions(-) + +diff --git a/drivers/phy/rockchip/phy-rockchip-inno-hdmi.c b/drivers/phy/rockchip/phy-rockchip-inno-hdmi.c +index b0ac1d3ee390..093d2334e8cd 100644 +--- a/drivers/phy/rockchip/phy-rockchip-inno-hdmi.c ++++ b/drivers/phy/rockchip/phy-rockchip-inno-hdmi.c +@@ -745,10 +745,12 @@ unsigned long inno_hdmi_phy_rk3328_clk_recalc_rate(struct clk_hw *hw, + do_div(vco, (nd * (no_a == 1 ? no_b : no_a) * no_d * 2)); + } + +- inno->pixclock = vco; +- dev_dbg(inno->dev, "%s rate %lu\n", __func__, inno->pixclock); ++ inno->pixclock = DIV_ROUND_CLOSEST((unsigned long)vco, 1000) * 1000; + +- return vco; ++ dev_dbg(inno->dev, "%s rate %lu vco %llu\n", ++ __func__, inno->pixclock, vco); ++ ++ return inno->pixclock; + } + + static long inno_hdmi_phy_rk3328_clk_round_rate(struct clk_hw *hw, + +From 1f9e6c5cc70cb9fa6e3751b149d88ef7289b2783 Mon Sep 17 00:00:00 2001 +From: Jonas Karlman +Date: Sat, 10 Oct 2020 15:32:19 +0000 +Subject: [PATCH] phy/rockchip: inno-hdmi: remove unused no_c from rk3328 + recalc_rate + +no_c is not used in any calculation, lets remove it. + +Signed-off-by: Jonas Karlman +--- + drivers/phy/rockchip/phy-rockchip-inno-hdmi.c | 5 +---- + 1 file changed, 1 insertion(+), 4 deletions(-) + +diff --git a/drivers/phy/rockchip/phy-rockchip-inno-hdmi.c b/drivers/phy/rockchip/phy-rockchip-inno-hdmi.c +index 093d2334e8cd..06db69c8373e 100644 +--- a/drivers/phy/rockchip/phy-rockchip-inno-hdmi.c ++++ b/drivers/phy/rockchip/phy-rockchip-inno-hdmi.c +@@ -714,7 +714,7 @@ unsigned long inno_hdmi_phy_rk3328_clk_recalc_rate(struct clk_hw *hw, + { + struct inno_hdmi_phy *inno = to_inno_hdmi_phy(hw); + unsigned long frac; +- u8 nd, no_a, no_b, no_c, no_d; ++ u8 nd, no_a, no_b, no_d; + u64 vco; + u16 nf; + +@@ -737,9 +737,6 @@ unsigned long inno_hdmi_phy_rk3328_clk_recalc_rate(struct clk_hw *hw, + no_b = inno_read(inno, 0xa5) & RK3328_PRE_PLL_PCLK_DIV_B_MASK; + no_b >>= RK3328_PRE_PLL_PCLK_DIV_B_SHIFT; + no_b += 2; +- no_c = inno_read(inno, 0xa6) & RK3328_PRE_PLL_PCLK_DIV_C_MASK; +- no_c >>= RK3328_PRE_PLL_PCLK_DIV_C_SHIFT; +- no_c = 1 << no_c; + no_d = inno_read(inno, 0xa6) & RK3328_PRE_PLL_PCLK_DIV_D_MASK; + + do_div(vco, (nd * (no_a == 1 ? no_b : no_a) * no_d * 2)); + +From 97cae140efa904b9184f729f6a7de4b5ec48b4b0 Mon Sep 17 00:00:00 2001 +From: Jonas Karlman +Date: Sat, 10 Oct 2020 15:32:19 +0000 +Subject: [PATCH] phy/rockchip: inno-hdmi: do not power on rk3328 post pll on + reg write + +inno_write is used to configure 0xaa reg, that also hold the +POST_PLL_POWER_DOWN bit. +When POST_PLL_REFCLK_SEL_TMDS is configured the power down bit is not +taken into consideration. + +Fix this by keeping the power down bit until configuration is complete. +Also reorder the reg write order for consistency. + +Fixes: 53706a116863 ("phy: add Rockchip Innosilicon hdmi phy") +Signed-off-by: Jonas Karlman +--- + drivers/phy/rockchip/phy-rockchip-inno-hdmi.c | 6 ++++-- + 1 file changed, 4 insertions(+), 2 deletions(-) + +diff --git a/drivers/phy/rockchip/phy-rockchip-inno-hdmi.c b/drivers/phy/rockchip/phy-rockchip-inno-hdmi.c +index 06db69c8373e..3a59a6da0440 100644 +--- a/drivers/phy/rockchip/phy-rockchip-inno-hdmi.c ++++ b/drivers/phy/rockchip/phy-rockchip-inno-hdmi.c +@@ -1020,9 +1020,10 @@ inno_hdmi_phy_rk3328_power_on(struct inno_hdmi_phy *inno, + + inno_write(inno, 0xac, RK3328_POST_PLL_FB_DIV_7_0(cfg->fbdiv)); + if (cfg->postdiv == 1) { +- inno_write(inno, 0xaa, RK3328_POST_PLL_REFCLK_SEL_TMDS); + inno_write(inno, 0xab, RK3328_POST_PLL_FB_DIV_8(cfg->fbdiv) | + RK3328_POST_PLL_PRE_DIV(cfg->prediv)); ++ inno_write(inno, 0xaa, RK3328_POST_PLL_REFCLK_SEL_TMDS | ++ RK3328_POST_PLL_POWER_DOWN); + } else { + v = (cfg->postdiv / 2) - 1; + v &= RK3328_POST_PLL_POST_DIV_MASK; +@@ -1030,7 +1031,8 @@ inno_hdmi_phy_rk3328_power_on(struct inno_hdmi_phy *inno, + inno_write(inno, 0xab, RK3328_POST_PLL_FB_DIV_8(cfg->fbdiv) | + RK3328_POST_PLL_PRE_DIV(cfg->prediv)); + inno_write(inno, 0xaa, RK3328_POST_PLL_POST_DIV_ENABLE | +- RK3328_POST_PLL_REFCLK_SEL_TMDS); ++ RK3328_POST_PLL_REFCLK_SEL_TMDS | ++ RK3328_POST_PLL_POWER_DOWN); + } + + for (v = 0; v < 14; v++) + +From bfa07944b40b99cc9e23e808107b0a7d0f4cbfde Mon Sep 17 00:00:00 2001 +From: Huicong Xu +Date: Sat, 10 Oct 2020 15:32:20 +0000 +Subject: [PATCH] phy/rockchip: inno-hdmi: force set_rate on power_on + +Regular 8-bit and Deep Color video formats mainly differ in TMDS rate and +not in pixel clock rate. +When the hdmiphy clock is configured with the same pixel clock rate using +clk_set_rate() the clock framework do not signal the hdmi phy driver +to set_rate when switching between 8-bit and Deep Color. +This result in pre/post pll not being re-configured when switching between +regular 8-bit and Deep Color video formats. + +Fix this by calling set_rate in power_on to force pre pll re-configuration. + +Signed-off-by: Huicong Xu +Signed-off-by: Jonas Karlman +--- + drivers/phy/rockchip/phy-rockchip-inno-hdmi.c | 13 +++++++++++++ + 1 file changed, 13 insertions(+) + +diff --git a/drivers/phy/rockchip/phy-rockchip-inno-hdmi.c b/drivers/phy/rockchip/phy-rockchip-inno-hdmi.c +index 3a59a6da0440..3719309ad0d0 100644 +--- a/drivers/phy/rockchip/phy-rockchip-inno-hdmi.c ++++ b/drivers/phy/rockchip/phy-rockchip-inno-hdmi.c +@@ -245,6 +245,7 @@ struct inno_hdmi_phy { + struct clk_hw hw; + struct clk *phyclk; + unsigned long pixclock; ++ unsigned long tmdsclock; + }; + + struct pre_pll_config { +@@ -485,6 +486,8 @@ static int inno_hdmi_phy_power_on(struct phy *phy) + + dev_dbg(inno->dev, "Inno HDMI PHY Power On\n"); + ++ inno->plat_data->clk_ops->set_rate(&inno->hw, inno->pixclock, 24000000); ++ + ret = clk_prepare_enable(inno->phyclk); + if (ret) + return ret; +@@ -509,6 +512,8 @@ static int inno_hdmi_phy_power_off(struct phy *phy) + + clk_disable_unprepare(inno->phyclk); + ++ inno->tmdsclock = 0; ++ + dev_dbg(inno->dev, "Inno HDMI PHY Power Off\n"); + + return 0; +@@ -628,6 +633,9 @@ static int inno_hdmi_phy_rk3228_clk_set_rate(struct clk_hw *hw, + dev_dbg(inno->dev, "%s rate %lu tmdsclk %lu\n", + __func__, rate, tmdsclock); + ++ if (inno->pixclock == rate && inno->tmdsclock == tmdsclock) ++ return 0; ++ + cfg = inno_hdmi_phy_get_pre_pll_cfg(inno, rate); + if (IS_ERR(cfg)) + return PTR_ERR(cfg); +@@ -670,6 +678,7 @@ static int inno_hdmi_phy_rk3228_clk_set_rate(struct clk_hw *hw, + } + + inno->pixclock = rate; ++ inno->tmdsclock = tmdsclock; + + return 0; + } +@@ -781,6 +790,9 @@ static int inno_hdmi_phy_rk3328_clk_set_rate(struct clk_hw *hw, + dev_dbg(inno->dev, "%s rate %lu tmdsclk %lu\n", + __func__, rate, tmdsclock); + ++ if (inno->pixclock == rate && inno->tmdsclock == tmdsclock) ++ return 0; ++ + cfg = inno_hdmi_phy_get_pre_pll_cfg(inno, rate); + if (IS_ERR(cfg)) + return PTR_ERR(cfg); +@@ -820,6 +832,7 @@ static int inno_hdmi_phy_rk3328_clk_set_rate(struct clk_hw *hw, + } + + inno->pixclock = rate; ++ inno->tmdsclock = tmdsclock; + + return 0; + } + +From 3adb263b709113431ff97d17646c422293122e15 Mon Sep 17 00:00:00 2001 +From: Algea Cao +Date: Sat, 10 Oct 2020 15:32:20 +0000 +Subject: [PATCH] phy/rockchip: inno-hdmi: Support more pre-pll configuration + +Adding the following freq cfg in 8-bit and 10-bit color depth: + +{ + 40000000, 65000000, 71000000, 83500000, 85750000, + 88750000, 108000000, 119000000, 162000000 +} + +New freq has been validated by quantumdata 980. + +For some freq which can't be got by only using integer freq div, +frac freq div is needed, Such as 88.75Mhz 10-bit. But The actual +freq is different from the target freq, We must try to narrow +the gap between them. RK322X only support integer freq div. + +The VCO of pre-PLL must be more than 2Ghz, otherwise PLL may be +unlocked. + +Signed-off-by: Algea Cao +Signed-off-by: Jonas Karlman +Acked-by: Heiko Stuebner +--- + drivers/phy/rockchip/phy-rockchip-inno-hdmi.c | 74 ++++++++++++------- + 1 file changed, 49 insertions(+), 25 deletions(-) + +diff --git a/drivers/phy/rockchip/phy-rockchip-inno-hdmi.c b/drivers/phy/rockchip/phy-rockchip-inno-hdmi.c +index 3719309ad0d0..bb8bdf5e3301 100644 +--- a/drivers/phy/rockchip/phy-rockchip-inno-hdmi.c ++++ b/drivers/phy/rockchip/phy-rockchip-inno-hdmi.c +@@ -291,32 +291,56 @@ struct inno_hdmi_phy_drv_data { + const struct phy_config *phy_cfg_table; + }; + ++/* ++ * If only using integer freq div can't get frequency we want, frac ++ * freq div is needed. For example, pclk 88.75 Mhz and tmdsclk ++ * 110.9375 Mhz must use frac div 0xF00000. The actual frequency is different ++ * from the target frequency. Such as the tmds clock 110.9375 Mhz, ++ * the actual tmds clock we get is 110.93719 Mhz. It is important ++ * to note that RK322X platforms do not support frac div. ++ */ + static const struct pre_pll_config pre_pll_cfg_table[] = { +- { 27000000, 27000000, 1, 90, 3, 2, 2, 10, 3, 3, 4, 0, 0}, +- { 27000000, 33750000, 1, 90, 1, 3, 3, 10, 3, 3, 4, 0, 0}, +- { 40000000, 40000000, 1, 80, 2, 2, 2, 12, 2, 2, 2, 0, 0}, +- { 59341000, 59341000, 1, 98, 3, 1, 2, 1, 3, 3, 4, 0, 0xE6AE6B}, +- { 59400000, 59400000, 1, 99, 3, 1, 1, 1, 3, 3, 4, 0, 0}, +- { 59341000, 74176250, 1, 98, 0, 3, 3, 1, 3, 3, 4, 0, 0xE6AE6B}, +- { 59400000, 74250000, 1, 99, 1, 2, 2, 1, 3, 3, 4, 0, 0}, +- { 74176000, 74176000, 1, 98, 1, 2, 2, 1, 2, 3, 4, 0, 0xE6AE6B}, +- { 74250000, 74250000, 1, 99, 1, 2, 2, 1, 2, 3, 4, 0, 0}, +- { 74176000, 92720000, 4, 494, 1, 2, 2, 1, 3, 3, 4, 0, 0x816817}, +- { 74250000, 92812500, 4, 495, 1, 2, 2, 1, 3, 3, 4, 0, 0}, +- {148352000, 148352000, 1, 98, 1, 1, 1, 1, 2, 2, 2, 0, 0xE6AE6B}, +- {148500000, 148500000, 1, 99, 1, 1, 1, 1, 2, 2, 2, 0, 0}, +- {148352000, 185440000, 4, 494, 0, 2, 2, 1, 3, 2, 2, 0, 0x816817}, +- {148500000, 185625000, 4, 495, 0, 2, 2, 1, 3, 2, 2, 0, 0}, +- {296703000, 296703000, 1, 98, 0, 1, 1, 1, 0, 2, 2, 0, 0xE6AE6B}, +- {297000000, 297000000, 1, 99, 0, 1, 1, 1, 0, 2, 2, 0, 0}, +- {296703000, 370878750, 4, 494, 1, 2, 0, 1, 3, 1, 1, 0, 0x816817}, +- {297000000, 371250000, 4, 495, 1, 2, 0, 1, 3, 1, 1, 0, 0}, +- {593407000, 296703500, 1, 98, 0, 1, 1, 1, 0, 2, 1, 0, 0xE6AE6B}, +- {594000000, 297000000, 1, 99, 0, 1, 1, 1, 0, 2, 1, 0, 0}, +- {593407000, 370879375, 4, 494, 1, 2, 0, 1, 3, 1, 1, 1, 0x816817}, +- {594000000, 371250000, 4, 495, 1, 2, 0, 1, 3, 1, 1, 1, 0}, +- {593407000, 593407000, 1, 98, 0, 2, 0, 1, 0, 1, 1, 0, 0xE6AE6B}, +- {594000000, 594000000, 1, 99, 0, 2, 0, 1, 0, 1, 1, 0, 0}, ++ { 27000000, 27000000, 1, 90, 3, 2, 2, 10, 3, 3, 4, 0, 0}, ++ { 27000000, 33750000, 1, 90, 1, 3, 3, 10, 3, 3, 4, 0, 0}, ++ { 40000000, 40000000, 1, 80, 2, 2, 2, 12, 2, 2, 2, 0, 0}, ++ { 40000000, 50000000, 1, 100, 2, 2, 2, 1, 0, 0, 15, 0, 0}, ++ { 59341000, 59341000, 1, 98, 3, 1, 2, 1, 3, 3, 4, 0, 0xE6AE6B}, ++ { 59400000, 59400000, 1, 99, 3, 1, 1, 1, 3, 3, 4, 0, 0}, ++ { 59341000, 74176250, 1, 98, 0, 3, 3, 1, 3, 3, 4, 0, 0xE6AE6B}, ++ { 59400000, 74250000, 1, 99, 1, 2, 2, 1, 3, 3, 4, 0, 0}, ++ { 65000000, 65000000, 1, 130, 2, 2, 2, 1, 0, 0, 12, 0, 0}, ++ { 65000000, 81250000, 3, 325, 0, 3, 3, 1, 0, 0, 10, 0, 0}, ++ { 71000000, 71000000, 3, 284, 0, 3, 3, 1, 0, 0, 8, 0, 0}, ++ { 71000000, 88750000, 3, 355, 0, 3, 3, 1, 0, 0, 10, 0, 0}, ++ { 74176000, 74176000, 1, 98, 1, 2, 2, 1, 2, 3, 4, 0, 0xE6AE6B}, ++ { 74250000, 74250000, 1, 99, 1, 2, 2, 1, 2, 3, 4, 0, 0}, ++ { 74176000, 92720000, 4, 494, 1, 2, 2, 1, 3, 3, 4, 0, 0x816817}, ++ { 74250000, 92812500, 4, 495, 1, 2, 2, 1, 3, 3, 4, 0, 0}, ++ { 83500000, 83500000, 2, 167, 2, 1, 1, 1, 0, 0, 6, 0, 0}, ++ { 83500000, 104375000, 1, 104, 2, 1, 1, 1, 1, 0, 5, 0, 0x600000}, ++ { 85750000, 85750000, 3, 343, 0, 3, 3, 1, 0, 0, 8, 0, 0}, ++ { 88750000, 88750000, 3, 355, 0, 3, 3, 1, 0, 0, 8, 0, 0}, ++ { 88750000, 110937500, 1, 110, 2, 1, 1, 1, 1, 0, 5, 0, 0xF00000}, ++ {108000000, 108000000, 1, 90, 3, 0, 0, 1, 0, 0, 5, 0, 0}, ++ {108000000, 135000000, 1, 90, 0, 2, 2, 1, 0, 0, 5, 0, 0}, ++ {119000000, 119000000, 1, 119, 2, 1, 1, 1, 0, 0, 6, 0, 0}, ++ {119000000, 148750000, 1, 99, 0, 2, 2, 1, 0, 0, 5, 0, 0x2AAAAA}, ++ {148352000, 148352000, 1, 98, 1, 1, 1, 1, 2, 2, 2, 0, 0xE6AE6B}, ++ {148500000, 148500000, 1, 99, 1, 1, 1, 1, 2, 2, 2, 0, 0}, ++ {148352000, 185440000, 4, 494, 0, 2, 2, 1, 3, 2, 2, 0, 0x816817}, ++ {148500000, 185625000, 4, 495, 0, 2, 2, 1, 3, 2, 2, 0, 0}, ++ {162000000, 162000000, 1, 108, 0, 2, 2, 1, 0, 0, 4, 0, 0}, ++ {162000000, 202500000, 1, 135, 0, 2, 2, 1, 0, 0, 5, 0, 0}, ++ {296703000, 296703000, 1, 98, 0, 1, 1, 1, 0, 2, 2, 0, 0xE6AE6B}, ++ {297000000, 297000000, 1, 99, 0, 1, 1, 1, 0, 2, 2, 0, 0}, ++ {296703000, 370878750, 4, 494, 1, 2, 0, 1, 3, 1, 1, 0, 0x816817}, ++ {297000000, 371250000, 4, 495, 1, 2, 0, 1, 3, 1, 1, 0, 0}, ++ {593407000, 296703500, 1, 98, 0, 1, 1, 1, 0, 2, 1, 0, 0xE6AE6B}, ++ {594000000, 297000000, 1, 99, 0, 1, 1, 1, 0, 2, 1, 0, 0}, ++ {593407000, 370879375, 4, 494, 1, 2, 0, 1, 3, 1, 1, 1, 0x816817}, ++ {594000000, 371250000, 4, 495, 1, 2, 0, 1, 3, 1, 1, 1, 0}, ++ {593407000, 593407000, 1, 98, 0, 2, 0, 1, 0, 1, 1, 0, 0xE6AE6B}, ++ {594000000, 594000000, 1, 99, 0, 2, 0, 1, 0, 1, 1, 0, 0}, + { /* sentinel */ } + }; + + +From 70934586d1194bd7a5ef2ec0c81c7319b45daf39 Mon Sep 17 00:00:00 2001 +From: Peter Geis +Date: Mon, 16 Nov 2020 15:17:33 +0000 +Subject: [PATCH] phy: rockchip: add rockchip usb3 innosilicon phy driver + +The innosilicon based usb3 phy used in rockchip devices such as the rk3328 is bugged, requiring special handling. +The following erata have been observed: + - usb3 device disconnect events are not detected by the controller + - usb2 hubs with no devices attached do not trigger disconnect events when removed + - interrupts are not reliable + +To work around these issue we implement polling of the usb2 and usb3 status. +On usb3 disconnection we reset the usb3 phy which triggers the disconnect event. +On usb2 disconnection we have to force reset the whole controller. +This requires a handoff to a special dwc3 device driver. + +This has been tested on the rk3328-roc-cc board with the following devices: + - usb2 only device + - usb3 only device + - usb2 only hub without devices + - usb3 hub without devices + - usb2 hub with devices + - usb3 hub with devices + +Signed-off-by: Peter Geis +--- + drivers/phy/rockchip/Kconfig | 9 + + drivers/phy/rockchip/Makefile | 1 + + drivers/phy/rockchip/phy-rockchip-inno-usb3.c | 425 ++++++++++++++++++ + 3 files changed, 435 insertions(+) + create mode 100644 drivers/phy/rockchip/phy-rockchip-inno-usb3.c + +diff --git a/drivers/phy/rockchip/Kconfig b/drivers/phy/rockchip/Kconfig +index c2f22f90736c..ce16e0877354 100644 +--- a/drivers/phy/rockchip/Kconfig ++++ b/drivers/phy/rockchip/Kconfig +@@ -47,6 +47,15 @@ config PHY_ROCKCHIP_INNO_USB2 + help + Support for Rockchip USB2.0 PHY with Innosilicon IP block. + ++config PHY_ROCKCHIP_INNO_USB3 ++ tristate "Rockchip INNO USB3PHY Driver" ++ depends on (ARCH_ROCKCHIP || COMPILE_TEST) && OF ++ depends on COMMON_CLK ++ depends on USB_SUPPORT ++ select USB_COMMON ++ help ++ Support for Rockchip USB3.0 PHY with Innosilicon IP block. ++ + config PHY_ROCKCHIP_INNO_DSIDPHY + tristate "Rockchip Innosilicon MIPI/LVDS/TTL PHY driver" + depends on (ARCH_ROCKCHIP || COMPILE_TEST) && OF +diff --git a/drivers/phy/rockchip/Makefile b/drivers/phy/rockchip/Makefile +index c3cfc7f0af5c..738e3574a722 100644 +--- a/drivers/phy/rockchip/Makefile ++++ b/drivers/phy/rockchip/Makefile +@@ -5,6 +5,7 @@ obj-$(CONFIG_PHY_ROCKCHIP_EMMC) += phy-rockchip-emmc.o + obj-$(CONFIG_PHY_ROCKCHIP_INNO_DSIDPHY) += phy-rockchip-inno-dsidphy.o + obj-$(CONFIG_PHY_ROCKCHIP_INNO_HDMI) += phy-rockchip-inno-hdmi.o + obj-$(CONFIG_PHY_ROCKCHIP_INNO_USB2) += phy-rockchip-inno-usb2.o ++obj-$(CONFIG_PHY_ROCKCHIP_INNO_USB3) += phy-rockchip-inno-usb3.o + obj-$(CONFIG_PHY_ROCKCHIP_PCIE) += phy-rockchip-pcie.o + obj-$(CONFIG_PHY_ROCKCHIP_TYPEC) += phy-rockchip-typec.o + obj-$(CONFIG_PHY_ROCKCHIP_USB) += phy-rockchip-usb.o +diff --git a/drivers/phy/rockchip/phy-rockchip-inno-usb3.c b/drivers/phy/rockchip/phy-rockchip-inno-usb3.c +new file mode 100644 +index 000000000000..6e4aa2f0ba46 +--- /dev/null ++++ b/drivers/phy/rockchip/phy-rockchip-inno-usb3.c +@@ -0,0 +1,425 @@ ++// SPDX-License-Identifier: GPL-2.0+ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#define USB3_STATUS_REG 0x284 ++#define USB2_STATUS_REG 0x30 ++#define USB3_CONN_BIT BIT(0) ++#define USB2_CONN_BIT BIT(7) ++#define USB2_STATE_SHIFT 6 ++#define REG_WRITE_MASK GENMASK(31, 16) ++ ++struct rockchip_usb3phy_port{ ++ struct device *dev; ++ struct regmap *regmap; ++ struct usb_phy phy; ++ struct rockchip_usb3phy *parent; ++ unsigned char type; ++}; ++ ++enum usb3phy_mode { ++ PHY_IDLE = 0, ++ PHY_USB3, ++ PHY_USB2, ++ PHY_COMBO ++}; ++ ++struct rockchip_usb3phy { ++ struct device *dev; ++ struct regmap *regmap; ++ struct clk *clk_pipe; ++ struct clk *clk_otg; ++ struct reset_control *u3por_rst; ++ struct reset_control *u2por_rst; ++ struct reset_control *pipe_rst; ++ struct reset_control *utmi_rst; ++ struct reset_control *pipe_apb_rst; ++ struct reset_control *utmi_apb_rst; ++ struct rockchip_usb3phy_port port_pipe; ++ struct rockchip_usb3phy_port port_utmi; ++ struct work_struct usb_phy_work; ++ struct notifier_block nb; ++ enum usb3phy_mode mode; ++ struct mutex lock; ++}; ++ ++static int rockchip_usb3phy_reset(struct rockchip_usb3phy *usb3phy, bool reset, enum usb3phy_mode mode) ++{ ++ if (reset == true) { ++ if ((mode == PHY_USB2) | (mode == PHY_COMBO)){ ++ clk_disable_unprepare(usb3phy->clk_otg); ++ reset_control_assert(usb3phy->utmi_rst); ++ reset_control_assert(usb3phy->u2por_rst); ++ } ++ if ((mode == PHY_USB3) | (mode == PHY_COMBO)){ ++ clk_disable_unprepare(usb3phy->clk_pipe); ++ reset_control_assert(usb3phy->pipe_rst); ++ reset_control_assert(usb3phy->u3por_rst); ++ } ++ } ++ ++ if (reset == false) { ++ if ((mode == PHY_USB2) | (mode == PHY_COMBO)){ ++ reset_control_deassert(usb3phy->u2por_rst); ++ udelay(1000); ++ clk_prepare_enable(usb3phy->clk_otg); ++ udelay(500); ++ reset_control_deassert(usb3phy->utmi_rst); ++ } ++ if ((mode == PHY_USB3) | (mode == PHY_COMBO)){ ++ reset_control_deassert(usb3phy->u3por_rst); ++ udelay(500); ++ clk_prepare_enable(usb3phy->clk_pipe); ++ udelay(1000); ++ reset_control_deassert(usb3phy->pipe_rst); ++ } ++ } ++ ++ return 0; ++} ++ ++static void rockchip_usb3phy_work(struct work_struct *work) ++{ ++ struct rockchip_usb3phy *usb3phy = container_of(work, struct rockchip_usb3phy, usb_phy_work); ++ struct rockchip_usb3phy_port *port_pipe = &usb3phy->port_pipe; ++ struct rockchip_usb3phy_port *port_utmi = &usb3phy->port_utmi; ++ int usb2, usb3, tmp, state; ++ ++ mutex_lock(&usb3phy->lock); ++ ++ regmap_read(port_pipe->regmap, USB3_STATUS_REG, &tmp); ++ usb3 = tmp & USB3_CONN_BIT; ++ regmap_read(usb3phy->regmap, USB2_STATUS_REG, &tmp); ++ usb2 = ((tmp & USB2_CONN_BIT) ^ USB2_CONN_BIT ) >> USB2_STATE_SHIFT; ++ state = (usb3 | usb2); ++ dev_dbg(usb3phy->dev, "mode %i, state %i\n", usb3phy->mode, state); ++ ++ if (usb3phy->mode == state) ++ /* not our device */ ++ goto out; ++ ++ if (usb2) { ++ usb3phy->mode = PHY_USB2; ++ dev_dbg(usb3phy->dev, "usb3phy utmi polling started\n"); ++ regmap_read_poll_timeout(usb3phy->regmap, USB2_STATUS_REG, tmp, (tmp & USB2_CONN_BIT), 2000, 0); ++ state = ((tmp & USB2_CONN_BIT) ^ USB2_CONN_BIT ) >> USB2_STATE_SHIFT; ++ dev_dbg(usb3phy->dev, "usb3phy utmi polling completed\n"); ++ ++ atomic_notifier_call_chain(&port_utmi->phy.notifier, 0, NULL); ++ goto out; ++ } ++ ++ if (usb3) { ++ dev_dbg(usb3phy->dev, "usb3phy pipe polling started\n"); ++ regmap_read_poll_timeout(port_pipe->regmap, USB3_STATUS_REG, tmp, !(tmp & USB3_CONN_BIT), 2000, 0); ++ dev_dbg(usb3phy->dev, "usb3phy pipe polling completed\n"); ++ ++ rockchip_usb3phy_reset(usb3phy, true, PHY_USB3); ++ udelay(500); ++ rockchip_usb3phy_reset(usb3phy, false, PHY_USB3); ++ udelay(500); ++ ++ goto out; ++ } ++ ++out: ++ usb3phy->mode = PHY_IDLE; ++ mutex_unlock(&usb3phy->lock); ++ return; ++} ++ ++static int rockchip_usb3phy_parse_dt(struct rockchip_usb3phy *usb3phy, struct device *dev) ++{ ++ usb3phy->clk_pipe = devm_clk_get(dev, "usb3phy-pipe"); ++ if (IS_ERR(usb3phy->clk_pipe)) { ++ dev_err(dev, "could not get usb3phy pipe clock\n"); ++ return PTR_ERR(usb3phy->clk_pipe); ++ } ++ ++ usb3phy->clk_otg = devm_clk_get(dev, "usb3phy-otg"); ++ if (IS_ERR(usb3phy->clk_otg)) { ++ dev_err(dev, "could not get usb3phy otg clock\n"); ++ return PTR_ERR(usb3phy->clk_otg); ++ } ++ ++ usb3phy->u2por_rst = devm_reset_control_get(dev, "usb3phy-u2-por"); ++ if (IS_ERR(usb3phy->u2por_rst)) { ++ dev_err(dev, "no usb3phy-u2-por reset control found\n"); ++ return PTR_ERR(usb3phy->u2por_rst); ++ } ++ ++ usb3phy->u3por_rst = devm_reset_control_get(dev, "usb3phy-u3-por"); ++ if (IS_ERR(usb3phy->u3por_rst)) { ++ dev_err(dev, "no usb3phy-u3-por reset control found\n"); ++ return PTR_ERR(usb3phy->u3por_rst); ++ } ++ ++ usb3phy->pipe_rst = devm_reset_control_get(dev, "usb3phy-pipe-mac"); ++ if (IS_ERR(usb3phy->pipe_rst)) { ++ dev_err(dev, "no usb3phy_pipe_mac reset control found\n"); ++ return PTR_ERR(usb3phy->pipe_rst); ++ } ++ ++ usb3phy->utmi_rst = devm_reset_control_get(dev, "usb3phy-utmi-mac"); ++ if (IS_ERR(usb3phy->utmi_rst)) { ++ dev_err(dev, "no usb3phy-utmi-mac reset control found\n"); ++ return PTR_ERR(usb3phy->utmi_rst); ++ } ++ ++ usb3phy->pipe_apb_rst = devm_reset_control_get(dev, "usb3phy-pipe-apb"); ++ if (IS_ERR(usb3phy->pipe_apb_rst)) { ++ dev_err(dev, "no usb3phy-pipe-apb reset control found\n"); ++ return PTR_ERR(usb3phy->pipe_apb_rst); ++ } ++ ++ usb3phy->utmi_apb_rst = devm_reset_control_get(dev, "usb3phy-utmi-apb"); ++ if (IS_ERR(usb3phy->utmi_apb_rst)) { ++ dev_err(dev, "no usb3phy-utmi-apb reset control found\n"); ++ return PTR_ERR(usb3phy->utmi_apb_rst); ++ } ++ ++ return 0; ++} ++ ++static int rockchip_usb3phy_notify(struct notifier_block *nb, unsigned long action, void *data) ++{ ++ struct rockchip_usb3phy *usb3phy = container_of(nb, struct rockchip_usb3phy, nb); ++ switch (action) { ++ case USB_DEVICE_ADD: ++ dev_dbg(usb3phy->dev, "notified of device add\n"); ++ if (!(mutex_is_locked(&usb3phy->lock))) ++ schedule_work(&usb3phy->usb_phy_work); ++ return NOTIFY_OK; ++ } ++ return NOTIFY_DONE; ++} ++ ++static int rockchip_usb3phy_init(struct usb_phy *phy) ++{ ++ struct rockchip_usb3phy_port *usb3phy_port = container_of(phy, struct rockchip_usb3phy_port, phy); ++ struct rockchip_usb3phy *usb3phy = usb3phy_port->parent; ++ ++ dev_warn(usb3phy->dev, "usb3phy_init %s\n", phy->label); ++ if (phy->type == USB_PHY_TYPE_USB3){ ++ rockchip_usb3phy_reset(usb3phy, false, PHY_USB3); ++ udelay(100); /* let it stabilize */ ++ usb3phy->nb.notifier_call = rockchip_usb3phy_notify; ++ usb_register_notify(&usb3phy->nb); ++ } ++ if (phy->type == USB_PHY_TYPE_USB2){ ++ rockchip_usb3phy_reset(usb3phy, false, PHY_USB2); ++ udelay(100); /* let it stabilize */ ++ } ++ ++ return 0; ++} ++ ++static void rockchip_usb3phy_shutdown(struct usb_phy *phy) ++{ ++ struct rockchip_usb3phy_port *usb3phy_port = container_of(phy, struct rockchip_usb3phy_port, phy); ++ struct rockchip_usb3phy *usb3phy = usb3phy_port->parent; ++ ++ dev_dbg(usb3phy->dev, "usb3phy_shutdown\n"); ++ if (phy->type == USB_PHY_TYPE_USB3){ ++ rockchip_usb3phy_reset(usb3phy, false, PHY_USB3); ++ usb_unregister_notify(&usb3phy->nb); ++ } ++ if (phy->type == USB_PHY_TYPE_USB2){ ++ rockchip_usb3phy_reset(usb3phy, false, PHY_USB2); ++ } ++} ++ ++static const struct regmap_config rockchip_usb3phy_port_regmap_config = { ++ .reg_bits = 32, ++ .val_bits = 32, ++ .reg_stride = 4, ++ .max_register = 0x1000, ++}; ++ ++static const struct regmap_config rockchip_usb3phy_regmap_config = { ++ .reg_bits = 32, ++ .val_bits = 32, ++ .reg_stride = 4, ++ .max_register = 0x1000, ++ .write_flag_mask = REG_WRITE_MASK, ++}; ++ ++static int rockchip_usb3phy_probe(struct platform_device *pdev) ++{ ++ struct device *dev = &pdev->dev; ++ struct device_node *np = dev->of_node; ++ struct rockchip_usb3phy *usb3phy; ++ struct rockchip_usb3phy_port *usb3phy_port; ++ struct regmap_config regmap_config = rockchip_usb3phy_regmap_config; ++ struct regmap_config regmap_port_config = rockchip_usb3phy_port_regmap_config; ++ const struct of_device_id *match; ++ void __iomem *base; ++ int ret; ++ ++ match = of_match_device(dev->driver->of_match_table, dev); ++ if (!match) { ++ dev_err(dev, "phy node not assigned\n"); ++ return -EINVAL; ++ } ++ ++ if (of_node_name_eq(np, "usb3-phy")) { ++ dev_dbg(dev, "Probe usb3phy main block\n"); ++ ++ usb3phy = devm_kzalloc(dev, sizeof(*usb3phy), GFP_KERNEL); ++ if (!usb3phy) ++ return -ENOMEM; ++ ++ ret = rockchip_usb3phy_parse_dt(usb3phy, dev); ++ if (ret) { ++ dev_err(dev, "parse dt failed %i\n", ret); ++ return ret; ++ } ++ ++ base = devm_of_iomap(dev, np, 0, NULL); ++ if (IS_ERR(base)) { ++ dev_err(dev, "failed port ioremap\n"); ++ return PTR_ERR(base); ++ } ++ ++ regmap_config.name = np->name; ++ ++ usb3phy->regmap = devm_regmap_init_mmio(dev, base, ®map_config); ++ if (IS_ERR(usb3phy->regmap)) { ++ dev_err(dev, "regmap init failed\n"); ++ return PTR_ERR(usb3phy->regmap); ++ } ++ ++ usb3phy->dev = dev; ++ platform_set_drvdata(pdev, usb3phy); ++ ++ /* place block in reset */ ++ reset_control_assert(usb3phy->pipe_rst); ++ reset_control_assert(usb3phy->utmi_rst); ++ reset_control_assert(usb3phy->u3por_rst); ++ reset_control_assert(usb3phy->u2por_rst); ++ reset_control_assert(usb3phy->pipe_apb_rst); ++ reset_control_assert(usb3phy->utmi_apb_rst); ++ ++ udelay(20); ++ ++ /* take apb interface out of reset */ ++ reset_control_deassert(usb3phy->utmi_apb_rst); ++ reset_control_deassert(usb3phy->pipe_apb_rst); ++ ++ usb3phy->mode = PHY_IDLE; ++ INIT_WORK(&usb3phy->usb_phy_work, rockchip_usb3phy_work); ++ dev_dbg(dev, "Completed usb3phy core probe \n"); ++ ++ return devm_of_platform_populate(&pdev->dev); ++ } ++ ++ /* probe the actual ports */ ++ usb3phy = platform_get_drvdata(of_find_device_by_node(np->parent)); ++ ++ if (of_node_name_eq(np, "utmi")) { ++ usb3phy_port = &usb3phy->port_utmi; ++ usb3phy_port->phy.label = "usb2-phy"; ++ usb3phy_port->phy.type = USB_PHY_TYPE_USB2; ++ } ++ else if (of_node_name_eq(np, "pipe")) { ++ usb3phy_port = &usb3phy->port_pipe; ++ usb3phy_port->phy.label = "usb3-phy"; ++ usb3phy_port->phy.type = USB_PHY_TYPE_USB3; ++ } ++ else { ++ dev_err(dev, "unknown child node port type %s\n", np->name); ++ return -EINVAL; ++ } ++ ++ usb3phy_port->dev = dev; ++ ++ base = devm_of_iomap(dev, np, 0, NULL); ++ if (IS_ERR(base)) { ++ dev_err(dev, "failed port ioremap\n"); ++ return PTR_ERR(base); ++ } ++ ++ regmap_port_config.name = np->name; ++ ++ usb3phy_port->regmap = devm_regmap_init_mmio(dev, base, ®map_port_config); ++ if (IS_ERR(usb3phy_port->regmap)) { ++ dev_err(dev, "regmap init failed\n"); ++ return PTR_ERR(usb3phy_port->regmap); ++ } ++ ++ usb3phy_port->phy.dev = dev; ++ usb3phy_port->phy.init = rockchip_usb3phy_init; ++ usb3phy_port->phy.shutdown = rockchip_usb3phy_shutdown; ++ usb3phy_port->parent = usb3phy; ++ ++ ret = usb_add_phy_dev(&usb3phy_port->phy); ++ if (ret) { ++ dev_err(dev, "add usb phy failed %i\n", ret); ++ return ret; ++ } ++ ++ mutex_init(&usb3phy->lock); ++ ++ dev_info(dev, "Completed usb3phy %s port init\n", usb3phy_port->phy.label); ++ return 0; ++} ++ ++ ++static int rockchip_usb3phy_remove(struct platform_device *pdev) ++{ ++ struct rockchip_usb3phy *usb3phy = platform_get_drvdata(pdev); ++ struct rockchip_usb3phy_port *port_pipe = &usb3phy->port_pipe; ++ struct rockchip_usb3phy_port *port_utmi = &usb3phy->port_utmi; ++ ++ if (&port_pipe->phy.head) ++ usb_remove_phy(&port_pipe->phy); ++ if (&port_utmi->phy.head) ++ usb_remove_phy(&port_utmi->phy); ++ ++ reset_control_assert(usb3phy->pipe_apb_rst); ++ reset_control_assert(usb3phy->utmi_apb_rst); ++ ++ return 0; ++} ++ ++static const struct of_device_id rockchip_usb3phy_dt_ids[] = { ++ { .compatible = "rockchip,rk3328-usb3phy", }, ++ { .compatible = "rockchip,rk3328-usb3phy-utmi", }, ++ { .compatible = "rockchip,rk3328-usb3phy-pipe", }, ++ { /* sentinel */ } ++}; ++ ++MODULE_DEVICE_TABLE(of, rockchip_usb3phy_dt_ids); ++ ++static struct platform_driver rockchip_usb3phy_driver = { ++ .probe = rockchip_usb3phy_probe, ++ .remove = rockchip_usb3phy_remove, ++ .driver = { ++ .name = "rockchip-usb3-phy", ++ .of_match_table = rockchip_usb3phy_dt_ids, ++ }, ++}; ++ ++module_platform_driver(rockchip_usb3phy_driver); ++ ++MODULE_AUTHOR("Peter Geis "); ++MODULE_DESCRIPTION("Rockchip USB 3 PHY driver"); ++MODULE_LICENSE("GPL v2"); + +From 047efbf9fa61b63d9bc20f22c76ea3e67a49f2cb Mon Sep 17 00:00:00 2001 +From: Peter Geis +Date: Mon, 16 Nov 2020 15:17:34 +0000 +Subject: [PATCH] usb: dwc3: add rockchip innosilicon usb3 glue layer + +This adds the handler glue for the rockchip usb3 innosilicon phy driver. +This driver attaches to the phy driver through the notification system. +When a usb2 disconnect event occurs this driver tears down the hcd and rebuilds it manually. +This is to work around the usb2 controller becoming wedged and not detecting any usb2 devices after a usb2 hub is removed. + +It is based off work originally done by rockchip. + +Signed-off-by: Peter Geis +--- + drivers/usb/dwc3/Kconfig | 10 + + drivers/usb/dwc3/Makefile | 1 + + drivers/usb/dwc3/dwc3-rockchip-inno.c | 271 ++++++++++++++++++++++++++ + 3 files changed, 282 insertions(+) + create mode 100644 drivers/usb/dwc3/dwc3-rockchip-inno.c + +diff --git a/drivers/usb/dwc3/Kconfig b/drivers/usb/dwc3/Kconfig +index 7a2304565a73..2e33a45f55ff 100644 +--- a/drivers/usb/dwc3/Kconfig ++++ b/drivers/usb/dwc3/Kconfig +@@ -139,4 +139,14 @@ config USB_DWC3_QCOM + for peripheral mode support. + Say 'Y' or 'M' if you have one such device. + ++config USB_DWC3_ROCKCHIP_INNO ++ tristate "Rockchip Platforms with INNO PHY" ++ depends on OF && COMMON_CLK && ARCH_ROCKCHIP ++ depends on USB=y || USB=USB_DWC3 ++ default USB_DWC3 ++ help ++ Support of USB2/3 functionality in Rockchip platforms ++ with INNO USB 3.0 PHY IP inside. ++ say 'Y' or 'M' if you have one such device. ++ + endif +diff --git a/drivers/usb/dwc3/Makefile b/drivers/usb/dwc3/Makefile +index ae86da0dc5bd..f5eb7de10128 100644 +--- a/drivers/usb/dwc3/Makefile ++++ b/drivers/usb/dwc3/Makefile +@@ -51,3 +51,4 @@ obj-$(CONFIG_USB_DWC3_MESON_G12A) += dwc3-meson-g12a.o + obj-$(CONFIG_USB_DWC3_OF_SIMPLE) += dwc3-of-simple.o + obj-$(CONFIG_USB_DWC3_ST) += dwc3-st.o + obj-$(CONFIG_USB_DWC3_QCOM) += dwc3-qcom.o ++obj-$(CONFIG_USB_DWC3_ROCKCHIP_INNO) += dwc3-rockchip-inno.o +diff --git a/drivers/usb/dwc3/dwc3-rockchip-inno.c b/drivers/usb/dwc3/dwc3-rockchip-inno.c +new file mode 100644 +index 000000000000..7007ddbcbdae +--- /dev/null ++++ b/drivers/usb/dwc3/dwc3-rockchip-inno.c +@@ -0,0 +1,271 @@ ++// SPDX-License-Identifier: GPL-2.0 ++/* ++ * dwc3-rockchip-inno.c - DWC3 glue layer for Rockchip devices with Innosilicon based PHY ++ * ++ * Based on dwc3-of-simple.c ++ */ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#include ++#include ++#include ++#include ++ ++#include "core.h" ++#include "../host/xhci.h" ++ ++ ++struct dwc3_rk_inno { ++ struct device *dev; ++ struct clk_bulk_data *clks; ++ struct dwc3 *dwc; ++ struct usb_phy *phy; ++ struct notifier_block reset_nb; ++ struct work_struct reset_work; ++ struct mutex lock; ++ int num_clocks; ++ struct reset_control *resets; ++}; ++ ++static int dwc3_rk_inno_host_reset_notifier(struct notifier_block *nb, unsigned long event, void *data) ++{ ++ struct dwc3_rk_inno *rk_inno = container_of(nb, struct dwc3_rk_inno, reset_nb); ++ ++ schedule_work(&rk_inno->reset_work); ++ ++ return NOTIFY_DONE; ++} ++ ++static void dwc3_rk_inno_host_reset_work(struct work_struct *work) ++{ ++ struct dwc3_rk_inno *rk_inno = container_of(work, struct dwc3_rk_inno, reset_work); ++ struct usb_hcd *hcd = dev_get_drvdata(&rk_inno->dwc->xhci->dev); ++ struct usb_hcd *shared_hcd = hcd->shared_hcd; ++ struct xhci_hcd *xhci = hcd_to_xhci(hcd); ++ unsigned int count = 0; ++ ++ mutex_lock(&rk_inno->lock); ++ ++ if (hcd->state != HC_STATE_HALT) { ++ usb_remove_hcd(shared_hcd); ++ usb_remove_hcd(hcd); ++ } ++ ++ if (rk_inno->phy) ++ usb_phy_shutdown(rk_inno->phy); ++ ++ while (hcd->state != HC_STATE_HALT) { ++ if (++count > 1000) { ++ dev_err(rk_inno->dev, "wait for HCD remove 1s timeout!\n"); ++ break; ++ } ++ usleep_range(1000, 1100); ++ } ++ ++ if (hcd->state == HC_STATE_HALT) { ++ xhci->shared_hcd = shared_hcd; ++ usb_add_hcd(hcd, hcd->irq, IRQF_SHARED); ++ usb_add_hcd(shared_hcd, hcd->irq, IRQF_SHARED); ++ } ++ ++ if (rk_inno->phy) ++ usb_phy_init(rk_inno->phy); ++ ++ mutex_unlock(&rk_inno->lock); ++ dev_dbg(rk_inno->dev, "host reset complete\n"); ++} ++ ++static int dwc3_rk_inno_probe(struct platform_device *pdev) ++{ ++ struct dwc3_rk_inno *rk_inno; ++ struct device *dev = &pdev->dev; ++ struct device_node *np = dev->of_node, *child, *node; ++ struct platform_device *child_pdev; ++ ++ int ret; ++ ++ rk_inno = devm_kzalloc(dev, sizeof(*rk_inno), GFP_KERNEL); ++ if (!rk_inno) ++ return -ENOMEM; ++ ++ platform_set_drvdata(pdev, rk_inno); ++ rk_inno->dev = dev; ++ ++ rk_inno->resets = of_reset_control_array_get(np, false, true, ++ true); ++ if (IS_ERR(rk_inno->resets)) { ++ ret = PTR_ERR(rk_inno->resets); ++ dev_err(dev, "failed to get device resets, err=%d\n", ret); ++ return ret; ++ } ++ ++ ret = reset_control_deassert(rk_inno->resets); ++ if (ret) ++ goto err_resetc_put; ++ ++ ret = clk_bulk_get_all(rk_inno->dev, &rk_inno->clks); ++ if (ret < 0) ++ goto err_resetc_assert; ++ ++ rk_inno->num_clocks = ret; ++ ret = clk_bulk_prepare_enable(rk_inno->num_clocks, rk_inno->clks); ++ if (ret) ++ goto err_resetc_assert; ++ ++ ret = of_platform_populate(np, NULL, NULL, dev); ++ if (ret) ++ goto err_clk_put; ++ ++ child = of_get_child_by_name(np, "dwc3"); ++ if (!child) { ++ dev_err(dev, "failed to find dwc3 core node\n"); ++ ret = -ENODEV; ++ goto err_plat_depopulate; ++ } ++ ++ child_pdev = of_find_device_by_node(child); ++ if (!child_pdev) { ++ dev_err(dev, "failed to get dwc3 core device\n"); ++ ret = -ENODEV; ++ goto err_plat_depopulate; ++ } ++ ++ rk_inno->dwc = platform_get_drvdata(child_pdev); ++ if (!rk_inno->dwc || !rk_inno->dwc->xhci) { ++ ret = -EPROBE_DEFER; ++ goto err_plat_depopulate; ++ } ++ ++ node = of_parse_phandle(child, "usb-phy", 0); ++ INIT_WORK(&rk_inno->reset_work, dwc3_rk_inno_host_reset_work); ++ rk_inno->reset_nb.notifier_call = dwc3_rk_inno_host_reset_notifier; ++ rk_inno->phy = devm_usb_get_phy_by_node(dev, node, &rk_inno->reset_nb); ++ of_node_put(node); ++ mutex_init(&rk_inno->lock); ++ ++ pm_runtime_set_active(dev); ++ pm_runtime_enable(dev); ++ pm_runtime_get_sync(dev); ++ ++ return 0; ++ ++err_plat_depopulate: ++ of_platform_depopulate(dev); ++ ++err_clk_put: ++ clk_bulk_disable_unprepare(rk_inno->num_clocks, rk_inno->clks); ++ clk_bulk_put_all(rk_inno->num_clocks, rk_inno->clks); ++ ++err_resetc_assert: ++ reset_control_assert(rk_inno->resets); ++ ++err_resetc_put: ++ reset_control_put(rk_inno->resets); ++ return ret; ++} ++ ++static void __dwc3_rk_inno_teardown(struct dwc3_rk_inno *rk_inno) ++{ ++ of_platform_depopulate(rk_inno->dev); ++ ++ clk_bulk_disable_unprepare(rk_inno->num_clocks, rk_inno->clks); ++ clk_bulk_put_all(rk_inno->num_clocks, rk_inno->clks); ++ rk_inno->num_clocks = 0; ++ ++ reset_control_assert(rk_inno->resets); ++ ++ reset_control_put(rk_inno->resets); ++ ++ pm_runtime_disable(rk_inno->dev); ++ pm_runtime_put_noidle(rk_inno->dev); ++ pm_runtime_set_suspended(rk_inno->dev); ++} ++ ++static int dwc3_rk_inno_remove(struct platform_device *pdev) ++{ ++ struct dwc3_rk_inno *rk_inno = platform_get_drvdata(pdev); ++ ++ __dwc3_rk_inno_teardown(rk_inno); ++ ++ return 0; ++} ++ ++static void dwc3_rk_inno_shutdown(struct platform_device *pdev) ++{ ++ struct dwc3_rk_inno *rk_inno = platform_get_drvdata(pdev); ++ ++ __dwc3_rk_inno_teardown(rk_inno); ++} ++ ++static int __maybe_unused dwc3_rk_inno_runtime_suspend(struct device *dev) ++{ ++ struct dwc3_rk_inno *rk_inno = dev_get_drvdata(dev); ++ ++ clk_bulk_disable(rk_inno->num_clocks, rk_inno->clks); ++ ++ return 0; ++} ++ ++static int __maybe_unused dwc3_rk_inno_runtime_resume(struct device *dev) ++{ ++ struct dwc3_rk_inno *rk_inno = dev_get_drvdata(dev); ++ ++ return clk_bulk_enable(rk_inno->num_clocks, rk_inno->clks); ++} ++ ++static int __maybe_unused dwc3_rk_inno_suspend(struct device *dev) ++{ ++ struct dwc3_rk_inno *rk_inno = dev_get_drvdata(dev); ++ ++ reset_control_assert(rk_inno->resets); ++ ++ return 0; ++} ++ ++static int __maybe_unused dwc3_rk_inno_resume(struct device *dev) ++{ ++ struct dwc3_rk_inno *rk_inno = dev_get_drvdata(dev); ++ ++ reset_control_deassert(rk_inno->resets); ++ ++ return 0; ++} ++ ++static const struct dev_pm_ops dwc3_rk_inno_dev_pm_ops = { ++ SET_SYSTEM_SLEEP_PM_OPS(dwc3_rk_inno_suspend, dwc3_rk_inno_resume) ++ SET_RUNTIME_PM_OPS(dwc3_rk_inno_runtime_suspend, ++ dwc3_rk_inno_runtime_resume, NULL) ++}; ++ ++static const struct of_device_id of_dwc3_rk_inno_match[] = { ++ { .compatible = "rockchip,rk3328-dwc3" }, ++ { /* Sentinel */ } ++}; ++MODULE_DEVICE_TABLE(of, of_dwc3_rk_inno_match); ++ ++static struct platform_driver dwc3_rk_inno_driver = { ++ .probe = dwc3_rk_inno_probe, ++ .remove = dwc3_rk_inno_remove, ++ .shutdown = dwc3_rk_inno_shutdown, ++ .driver = { ++ .name = "dwc3-rk-inno", ++ .of_match_table = of_dwc3_rk_inno_match, ++ .pm = &dwc3_rk_inno_dev_pm_ops, ++ }, ++}; ++ ++module_platform_driver(dwc3_rk_inno_driver); ++MODULE_LICENSE("GPL v2"); ++MODULE_DESCRIPTION("DesignWare USB3 Rockchip Innosilicon Glue Layer"); ++MODULE_AUTHOR("Peter Geis "); + +From ddc2e7643489b827c4d933f7145a6a0c5a7ca680 Mon Sep 17 00:00:00 2001 +From: Peter Geis +Date: Mon, 16 Nov 2020 15:17:35 +0000 +Subject: [PATCH] arm64: dts: rockchip: add rk3328 usb3 and usb3phy nodes + +Add the usb3 controller and usb3 phy nodes to the rk3328. + +Signed-off-by: Peter Geis +--- + arch/arm64/boot/dts/rockchip/rk3328.dtsi | 65 ++++++++++++++++++++++++ + 1 file changed, 65 insertions(+) + +diff --git a/arch/arm64/boot/dts/rockchip/rk3328.dtsi b/arch/arm64/boot/dts/rockchip/rk3328.dtsi +index 56b5ee7e54c4..72f34205fd20 100644 +--- a/arch/arm64/boot/dts/rockchip/rk3328.dtsi ++++ b/arch/arm64/boot/dts/rockchip/rk3328.dtsi +@@ -856,6 +856,40 @@ u2phy_host: host-port { + }; + }; + ++ usb3phy: usb3-phy@ff470000 { ++ compatible = "rockchip,rk3328-usb3phy"; ++ reg = <0x0 0xff460000 0x0 0x10000>; ++ clocks = <&cru PCLK_USB3PHY_OTG>, <&cru PCLK_USB3PHY_PIPE>; ++ clock-names = "usb3phy-otg", "usb3phy-pipe"; ++ resets = <&cru SRST_USB3PHY_U2>, ++ <&cru SRST_USB3PHY_U3>, ++ <&cru SRST_USB3PHY_PIPE>, ++ <&cru SRST_USB3OTG_UTMI>, ++ <&cru SRST_USB3PHY_OTG_P>, ++ <&cru SRST_USB3PHY_PIPE_P>; ++ reset-names = "usb3phy-u2-por", "usb3phy-u3-por", ++ "usb3phy-pipe-mac", "usb3phy-utmi-mac", ++ "usb3phy-utmi-apb", "usb3phy-pipe-apb"; ++ #address-cells = <2>; ++ #size-cells = <2>; ++ ranges; ++ status = "disabled"; ++ ++ usb3phy_utmi: utmi@ff470000 { ++ compatible = "rockchip,rk3328-usb3phy-utmi"; ++ reg = <0x0 0xff470000 0x0 0x8000>; ++ #phy-cells = <0>; ++ status = "disabled"; ++ }; ++ ++ usb3phy_pipe: pipe@ff478000 { ++ compatible = "rockchip,rk3328-usb3phy-pipe"; ++ reg = <0x0 0xff478000 0x0 0x8000>; ++ #phy-cells = <0>; ++ status = "disabled"; ++ }; ++ }; ++ + sdmmc: mmc@ff500000 { + compatible = "rockchip,rk3328-dw-mshc", "rockchip,rk3288-dw-mshc"; + reg = <0x0 0xff500000 0x0 0x4000>; +@@ -986,6 +1020,37 @@ usb_host0_ohci: usb@ff5d0000 { + status = "disabled"; + }; + ++ usbdrd3: usb@ff600000 { ++ compatible = "rockchip,rk3328-dwc3"; ++ clocks = <&cru SCLK_USB3OTG_REF>, <&cru ACLK_USB3OTG>, ++ <&cru SCLK_USB3OTG_SUSPEND>; ++ clock-names = "ref", "bus_early", "suspend"; ++ #address-cells = <2>; ++ #size-cells = <2>; ++ ranges; ++ status = "disabled"; ++ ++ usbdrd_dwc3: dwc3@ff600000 { ++ compatible = "snps,dwc3"; ++ reg = <0x0 0xff600000 0x0 0x100000>; ++ interrupts = ; ++ clocks = <&cru SCLK_USB3OTG_REF>, <&cru ACLK_USB3OTG>, ++ <&cru SCLK_USB3OTG_SUSPEND>; ++ clock-names = "ref", "bus_early", "suspend"; ++ dr_mode = "host"; ++ usb-phy = <&usb3phy_utmi>, <&usb3phy_pipe>; ++ phy_type = "utmi_wide"; ++ snps,dis_enblslpm_quirk; ++ snps,dis-u2-freeclk-exists-quirk; ++ snps,dis_u2_susphy_quirk; ++ snps,dis_u3_susphy_quirk; ++ snps,dis-del-phy-power-chg-quirk; ++ snps,dis-tx-ipgap-linecheck-quirk; ++ snps,xhci-trb-ent-quirk; ++ status = "disabled"; ++ }; ++ }; ++ + gic: interrupt-controller@ff811000 { + compatible = "arm,gic-400"; + #interrupt-cells = <3>; + +From 2f018d8d16dca79078a66816490070bd97ddd882 Mon Sep 17 00:00:00 2001 +From: Peter Geis +Date: Mon, 16 Nov 2020 15:17:36 +0000 +Subject: [PATCH] arm64: dts: rockchip: enable usb3 on rk3328-roc-cc board + +Enable the usb3 controller and usb3 phy nodes on the rk3328-roc-cc board file. + +Signed-off-by: Peter Geis +--- + .../arm64/boot/dts/rockchip/rk3328-roc-cc.dts | 21 +++++++++++++++++++ + 1 file changed, 21 insertions(+) + +diff --git a/arch/arm64/boot/dts/rockchip/rk3328-roc-cc.dts b/arch/arm64/boot/dts/rockchip/rk3328-roc-cc.dts +index 19959bfba451..3ac876c08d61 100644 +--- a/arch/arm64/boot/dts/rockchip/rk3328-roc-cc.dts ++++ b/arch/arm64/boot/dts/rockchip/rk3328-roc-cc.dts +@@ -366,6 +366,27 @@ &usb_host0_ohci { + status = "okay"; + }; + ++&usbdrd3 { ++ status = "okay"; ++}; ++ ++&usbdrd_dwc3 { ++ dr_mode = "host"; ++ status = "okay"; ++}; ++ ++&usb3phy { ++ status = "okay"; ++}; ++ ++&usb3phy_utmi { ++ status = "okay"; ++}; ++ ++&usb3phy_pipe { ++ status = "okay"; ++}; ++ + &vop { + status = "okay"; + }; + +From 633ca45797f43ada99df0cdc0cbd57093fc56ed5 Mon Sep 17 00:00:00 2001 +From: Jonas Karlman +Date: Sun, 17 Feb 2019 22:14:38 +0000 +Subject: [PATCH] mmc: core: set initial signal voltage on power off + +Some boards have SD card connectors where the power rail cannot be switched +off by the driver. If the card has not been power cycled, it may still be +using 1.8V signaling after a warm re-boot. Bootroms expecting 3.3V signaling +will fail to boot from a UHS card that continue to use 1.8V signaling. + +Set initial signal voltage in mmc_power_off() to allow re-boot to function. + +This fixes re-boot with UHS cards on Asus Tinker Board (Rockchip RK3288), +same issue have been seen on some Rockchip RK3399 boards. + +I am sending this as a RFC because I have no insights into SD/MMC subsystem, +this change fix a re-boot issue on my boards and does not break emmc/sdio. +Is this an acceptable workaround? Any advice is appreciated. + +Signed-off-by: Jonas Karlman +--- + drivers/mmc/core/core.c | 8 ++++++++ + 1 file changed, 8 insertions(+) + +diff --git a/drivers/mmc/core/core.c b/drivers/mmc/core/core.c +index d42037f0f10d..019dc355509b 100644 +--- a/drivers/mmc/core/core.c ++++ b/drivers/mmc/core/core.c +@@ -1349,6 +1349,14 @@ void mmc_power_off(struct mmc_host *host) + if (host->ios.power_mode == MMC_POWER_OFF) + return; + ++ mmc_set_initial_signal_voltage(host); ++ ++ /* ++ * This delay should be sufficient to allow the power supply ++ * to reach the minimum voltage. ++ */ ++ mmc_delay(host->ios.power_delay_ms); ++ + mmc_pwrseq_power_off(host); + + host->ios.clock = 0; diff --git a/projects/Rockchip/patches/linux/default/linux-0010-v4l2-from-list.patch b/projects/Rockchip/patches/linux/default/linux-0010-v4l2-from-list.patch new file mode 100644 index 0000000000..0fd1743257 --- /dev/null +++ b/projects/Rockchip/patches/linux/default/linux-0010-v4l2-from-list.patch @@ -0,0 +1,1039 @@ +From 1bb6ee3818b2498bc6076e1d1e19d0ab9300e8c4 Mon Sep 17 00:00:00 2001 +From: Jonas Karlman +Date: Mon, 6 Jul 2020 21:54:33 +0000 +Subject: [PATCH] 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 7cc3b478a5f4..054d2e3eed67 100644 +--- a/drivers/staging/media/rkvdec/rkvdec-h264.c ++++ b/drivers/staging/media/rkvdec/rkvdec-h264.c +@@ -752,7 +752,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 < dec_params->frame_num) { ++ dpb[i].frame_num <= dec_params->frame_num) { + p[i] = dpb[i].frame_num; + continue; + } + +From 489cc1e35036e0bca7a1d47d7b2e0b5ae432bf3a Mon Sep 17 00:00:00 2001 +From: Jonas Karlman +Date: Mon, 6 Jul 2020 21:54:34 +0000 +Subject: [PATCH] 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 d25c4a37e2af..b3e067031c83 100644 +--- a/drivers/staging/media/rkvdec/rkvdec.c ++++ b/drivers/staging/media/rkvdec/rkvdec.c +@@ -223,6 +223,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); + +From b5f6aa3c9e10de3f67c567b0cda96538470029ed Mon Sep 17 00:00:00 2001 +From: Jonas Karlman +Date: Mon, 6 Jul 2020 21:54:34 +0000 +Subject: [PATCH] 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 054d2e3eed67..d46424ba88e8 100644 +--- a/drivers/staging/media/rkvdec/rkvdec-h264.c ++++ b/drivers/staging/media/rkvdec/rkvdec-h264.c +@@ -671,8 +671,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 b3e067031c83..06fc58440cd3 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_h264_sps; ++ 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; + } + +From 66d25229f5b9eb4f3e4bd0085959546a368bc2f0 Mon Sep 17 00:00:00 2001 +From: Jonas Karlman +Date: Mon, 6 Jul 2020 21:54:35 +0000 +Subject: [PATCH] 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 d46424ba88e8..6536cf0d6054 100644 +--- a/drivers/staging/media/rkvdec/rkvdec-h264.c ++++ b/drivers/staging/media/rkvdec/rkvdec-h264.c +@@ -661,8 +661,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); + +From 80d1a0b261701bae31e8134a62515de371a3dc93 Mon Sep 17 00:00:00 2001 +From: Jonas Karlman +Date: Mon, 6 Jul 2020 21:54:35 +0000 +Subject: [PATCH] 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 6536cf0d6054..bf632d45282b 100644 +--- a/drivers/staging/media/rkvdec/rkvdec-h264.c ++++ b/drivers/staging/media/rkvdec/rkvdec-h264.c +@@ -1015,8 +1015,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; + } + + +From 586ea81ae0aa1460d1254c0c2582198edc7a9a3d Mon Sep 17 00:00:00 2001 +From: Jonas Karlman +Date: Mon, 6 Jul 2020 21:54:35 +0000 +Subject: [PATCH] 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); + +From 3c324e26bcb846db37a27b897f778a3cd1ce2a22 Mon Sep 17 00:00:00 2001 +From: Jonas Karlman +Date: Mon, 6 Jul 2020 21:54:36 +0000 +Subject: [PATCH] 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 4a05a105a9e6..e08e5dbdacea 100644 +--- a/Documentation/userspace-api/media/v4l/yuv-formats.rst ++++ b/Documentation/userspace-api/media/v4l/yuv-formats.rst +@@ -54,4 +54,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 eeff398fbdcc..80cb42450a1b 100644 +--- a/drivers/media/v4l2-core/v4l2-ioctl.c ++++ b/drivers/media/v4l2-core/v4l2-ioctl.c +@@ -1319,6 +1319,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 534eaa4d39bc..f21eba15ceae 100644 +--- a/include/uapi/linux/videodev2.h ++++ b/include/uapi/linux/videodev2.h +@@ -609,6 +609,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 */ + +From 0eb43246390d241064a85fd6e87494a07216419c Mon Sep 17 00:00:00 2001 +From: Jonas Karlman +Date: Mon, 6 Jul 2020 21:54:36 +0000 +Subject: [PATCH] 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 bf632d45282b..6f2d41b2e076 100644 +--- a/drivers/staging/media/rkvdec/rkvdec-h264.c ++++ b/drivers/staging/media/rkvdec/rkvdec-h264.c +@@ -893,9 +893,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; +@@ -906,8 +906,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) + +From f6cf51a6bb6a09099020ce9808768fae12931cd2 Mon Sep 17 00:00:00 2001 +From: Jonas Karlman +Date: Mon, 6 Jul 2020 21:54:37 +0000 +Subject: [PATCH] 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 06fc58440cd3..dc16bf8d57a9 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); +@@ -167,13 +178,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, +@@ -239,13 +246,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; + } + +From 1791908ad4ef99aa4e6054f7e75cc274ddeada14 Mon Sep 17 00:00:00 2001 +From: Jonas Karlman +Date: Mon, 6 Jul 2020 21:54:37 +0000 +Subject: [PATCH] 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 dc16bf8d57a9..6b2a2f4164b2 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[] = { +@@ -176,6 +209,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; +@@ -231,13 +265,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); +@@ -312,6 +350,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; + } + +@@ -401,6 +440,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 77a137cca88e..e95c52e3168a 100644 +--- a/drivers/staging/media/rkvdec/rkvdec.h ++++ b/drivers/staging/media/rkvdec/rkvdec.h +@@ -63,6 +63,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); +@@ -96,6 +97,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; + +From f7f8f5e4c78dce83a53218869da9a49d67620b12 Mon Sep 17 00:00:00 2001 +From: Jonas Karlman +Date: Mon, 6 Jul 2020 21:54:37 +0000 +Subject: [PATCH] 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 6f2d41b2e076..c115cd362a7f 100644 +--- a/drivers/staging/media/rkvdec/rkvdec-h264.c ++++ b/drivers/staging/media/rkvdec/rkvdec-h264.c +@@ -1021,6 +1021,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_h264_sps; ++ ++ 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; +@@ -1124,6 +1143,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 6b2a2f4164b2..bd8ec2915fe9 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_h264_sps; + 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)) +@@ -145,6 +141,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[] = { + +From 5c4ee34ae7c5ff491601d236109f89df4f4ae422 Mon Sep 17 00:00:00 2001 +From: Jonas Karlman +Date: Mon, 6 Jul 2020 21:54:38 +0000 +Subject: [PATCH] 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 bd8ec2915fe9..87987a782d75 100644 +--- a/drivers/staging/media/rkvdec/rkvdec.c ++++ b/drivers/staging/media/rkvdec/rkvdec.c +@@ -132,6 +132,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_CONSTRAINED_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 = { diff --git a/projects/Rockchip/patches/linux/default/linux-0011-v4l2-from-5.10.patch b/projects/Rockchip/patches/linux/default/linux-0011-v4l2-from-5.10.patch deleted file mode 100644 index d9f3118030..0000000000 --- a/projects/Rockchip/patches/linux/default/linux-0011-v4l2-from-5.10.patch +++ /dev/null @@ -1,2632 +0,0 @@ -From aac4c6e6f64b7bc56f8265cba1374a01322e3262 Mon Sep 17 00:00:00 2001 -From: Pi-Hsun Shih -Date: Fri, 14 Aug 2020 09:11:40 +0200 -Subject: [PATCH] media: v4l2-mem2mem: add v4l2_m2m_suspend, v4l2_m2m_resume - -Add two functions that can be used to stop new jobs from being queued / -continue running queued job. This can be used while a driver using m2m -helper is going to suspend / wake up from resume, and can ensure that -there's no job running in suspend process. - -Signed-off-by: Pi-Hsun Shih -Signed-off-by: Jerry-ch Chen -Reviewed-by: Tomasz Figa -Signed-off-by: Hans Verkuil -Signed-off-by: Mauro Carvalho Chehab -(cherry picked from commit 911ea8ec42dea0e28083a6e92b1b4a5a0ad5acca) ---- - drivers/media/v4l2-core/v4l2-mem2mem.c | 41 ++++++++++++++++++++++++++++++++++ - include/media/v4l2-mem2mem.h | 22 ++++++++++++++++++ - 2 files changed, 63 insertions(+) - -diff --git a/drivers/media/v4l2-core/v4l2-mem2mem.c b/drivers/media/v4l2-core/v4l2-mem2mem.c -index 95a8f2dc5341..6a80240e9228 100644 ---- a/drivers/media/v4l2-core/v4l2-mem2mem.c -+++ b/drivers/media/v4l2-core/v4l2-mem2mem.c -@@ -43,6 +43,10 @@ module_param(debug, bool, 0644); - #define TRANS_ABORT (1 << 2) - - -+/* The job queue is not running new jobs */ -+#define QUEUE_PAUSED (1 << 0) -+ -+ - /* Offset base for buffers on the destination queue - used to distinguish - * between source and destination buffers when mmapping - they receive the same - * offsets but for different queues */ -@@ -84,6 +88,7 @@ static const char * const m2m_entity_name[] = { - * @job_queue: instances queued to run - * @job_spinlock: protects job_queue - * @job_work: worker to run queued jobs. -+ * @job_queue_flags: flags of the queue status, %QUEUE_PAUSED. - * @m2m_ops: driver callbacks - */ - struct v4l2_m2m_dev { -@@ -101,6 +106,7 @@ struct v4l2_m2m_dev { - struct list_head job_queue; - spinlock_t job_spinlock; - struct work_struct job_work; -+ unsigned long job_queue_flags; - - const struct v4l2_m2m_ops *m2m_ops; - }; -@@ -263,6 +269,12 @@ static void v4l2_m2m_try_run(struct v4l2_m2m_dev *m2m_dev) - return; - } - -+ if (m2m_dev->job_queue_flags & QUEUE_PAUSED) { -+ spin_unlock_irqrestore(&m2m_dev->job_spinlock, flags); -+ dprintk("Running new jobs is paused\n"); -+ return; -+ } -+ - m2m_dev->curr_ctx = list_first_entry(&m2m_dev->job_queue, - struct v4l2_m2m_ctx, queue); - m2m_dev->curr_ctx->job_flags |= TRANS_RUNNING; -@@ -504,6 +516,7 @@ void v4l2_m2m_buf_done_and_job_finish(struct v4l2_m2m_dev *m2m_dev, - - if (WARN_ON(!src_buf || !dst_buf)) - goto unlock; -+ v4l2_m2m_buf_done(src_buf, state); - dst_buf->is_held = src_buf->flags & V4L2_BUF_FLAG_M2M_HOLD_CAPTURE_BUF; - if (!dst_buf->is_held) { - v4l2_m2m_dst_buf_remove(m2m_ctx); -@@ -528,6 +541,34 @@ void v4l2_m2m_buf_done_and_job_finish(struct v4l2_m2m_dev *m2m_dev, - } - EXPORT_SYMBOL(v4l2_m2m_buf_done_and_job_finish); - -+void v4l2_m2m_suspend(struct v4l2_m2m_dev *m2m_dev) -+{ -+ unsigned long flags; -+ struct v4l2_m2m_ctx *curr_ctx; -+ -+ spin_lock_irqsave(&m2m_dev->job_spinlock, flags); -+ m2m_dev->job_queue_flags |= QUEUE_PAUSED; -+ curr_ctx = m2m_dev->curr_ctx; -+ spin_unlock_irqrestore(&m2m_dev->job_spinlock, flags); -+ -+ if (curr_ctx) -+ wait_event(curr_ctx->finished, -+ !(curr_ctx->job_flags & TRANS_RUNNING)); -+} -+EXPORT_SYMBOL(v4l2_m2m_suspend); -+ -+void v4l2_m2m_resume(struct v4l2_m2m_dev *m2m_dev) -+{ -+ unsigned long flags; -+ -+ spin_lock_irqsave(&m2m_dev->job_spinlock, flags); -+ m2m_dev->job_queue_flags &= ~QUEUE_PAUSED; -+ spin_unlock_irqrestore(&m2m_dev->job_spinlock, flags); -+ -+ v4l2_m2m_try_run(m2m_dev); -+} -+EXPORT_SYMBOL(v4l2_m2m_resume); -+ - int v4l2_m2m_reqbufs(struct file *file, struct v4l2_m2m_ctx *m2m_ctx, - struct v4l2_requestbuffers *reqbufs) - { -diff --git a/include/media/v4l2-mem2mem.h b/include/media/v4l2-mem2mem.h -index 98753f00df7e..5a91b548ecc0 100644 ---- a/include/media/v4l2-mem2mem.h -+++ b/include/media/v4l2-mem2mem.h -@@ -304,6 +304,28 @@ v4l2_m2m_is_last_draining_src_buf(struct v4l2_m2m_ctx *m2m_ctx, - void v4l2_m2m_last_buffer_done(struct v4l2_m2m_ctx *m2m_ctx, - struct vb2_v4l2_buffer *vbuf); - -+/** -+ * v4l2_m2m_suspend() - stop new jobs from being run and wait for current job -+ * to finish -+ * -+ * @m2m_dev: opaque pointer to the internal data to handle M2M context -+ * -+ * Called by a driver in the suspend hook. Stop new jobs from being run, and -+ * wait for current running job to finish. -+ */ -+void v4l2_m2m_suspend(struct v4l2_m2m_dev *m2m_dev); -+ -+/** -+ * v4l2_m2m_resume() - resume job running and try to run a queued job -+ * -+ * @m2m_dev: opaque pointer to the internal data to handle M2M context -+ * -+ * Called by a driver in the resume hook. This reverts the operation of -+ * v4l2_m2m_suspend() and allows job to be run. Also try to run a queued job if -+ * there is any. -+ */ -+void v4l2_m2m_resume(struct v4l2_m2m_dev *m2m_dev); -+ - /** - * v4l2_m2m_reqbufs() - multi-queue-aware REQBUFS multiplexer - * - -From ea3a9782bc2717375bf236f11738c02d5148b8a8 Mon Sep 17 00:00:00 2001 -From: Jernej Skrabec -Date: Tue, 25 Aug 2020 05:52:27 +0200 -Subject: [PATCH] media: uapi: h264: Update reference lists - -When dealing with interlaced frames, reference lists must tell if -each particular reference is meant for top or bottom field. This info -is currently not provided at all in the H264 related controls. - -Change reference lists to hold a structure, which specifies -an index into the DPB array and the field/frame specification -for the picture. - -Currently the only user of these lists is Cedrus which is just compile -fixed here. Actual usage of will come in a following commit. - -Signed-off-by: Jernej Skrabec -Signed-off-by: Ezequiel Garcia -Tested-by: Jonas Karlman -Signed-off-by: Hans Verkuil -Signed-off-by: Mauro Carvalho Chehab -(cherry picked from commit e000e1fa4bdbd783149e7f97cf3be61e1c0bab8c) ---- - .../userspace-api/media/v4l/ext-ctrls-codec.rst | 44 +++++++++++++++++++++- - drivers/staging/media/sunxi/cedrus/cedrus_h264.c | 6 +-- - include/media/h264-ctrls.h | 21 ++++++++--- - 3 files changed, 60 insertions(+), 11 deletions(-) - -diff --git a/Documentation/userspace-api/media/v4l/ext-ctrls-codec.rst b/Documentation/userspace-api/media/v4l/ext-ctrls-codec.rst -index d0d506a444b1..df1c4fc5cb48 100644 ---- a/Documentation/userspace-api/media/v4l/ext-ctrls-codec.rst -+++ b/Documentation/userspace-api/media/v4l/ext-ctrls-codec.rst -@@ -1843,10 +1843,10 @@ enum v4l2_mpeg_video_h264_hierarchical_coding_type - - * - __u32 - - ``slice_group_change_cycle`` - - -- * - __u8 -+ * - struct :c:type:`v4l2_h264_reference` - - ``ref_pic_list0[32]`` - - Reference picture list after applying the per-slice modifications -- * - __u8 -+ * - struct :c:type:`v4l2_h264_reference` - - ``ref_pic_list1[32]`` - - Reference picture list after applying the per-slice modifications - * - __u32 -@@ -1926,6 +1926,46 @@ enum v4l2_mpeg_video_h264_hierarchical_coding_type - - - ``chroma_offset[32][2]`` - - - -+``Picture Reference`` -+ -+.. c:type:: v4l2_h264_reference -+ -+.. cssclass:: longtable -+ -+.. flat-table:: struct v4l2_h264_reference -+ :header-rows: 0 -+ :stub-columns: 0 -+ :widths: 1 1 2 -+ -+ * - __u8 -+ - ``fields`` -+ - Specifies how the picture is referenced. See :ref:`Reference Fields ` -+ * - __u8 -+ - ``index`` -+ - Index into the :c:type:`v4l2_ctrl_h264_decode_params`.dpb array. -+ -+.. _h264_ref_fields: -+ -+``Reference Fields`` -+ -+.. cssclass:: longtable -+ -+.. flat-table:: -+ :header-rows: 0 -+ :stub-columns: 0 -+ :widths: 1 1 2 -+ -+ * - ``V4L2_H264_TOP_FIELD_REF`` -+ - 0x1 -+ - The top field in field pair is used for short-term reference. -+ * - ``V4L2_H264_BOTTOM_FIELD_REF`` -+ - 0x2 -+ - The bottom field in field pair is used for short-term reference. -+ * - ``V4L2_H264_FRAME_REF`` -+ - 0x3 -+ - The frame (or the top/bottom fields, if it's a field pair) -+ is used for short-term reference. -+ - ``V4L2_CID_MPEG_VIDEO_H264_DECODE_PARAMS (struct)`` - Specifies the decode parameters (as extracted from the bitstream) - for the associated H264 slice data. This includes the necessary -diff --git a/drivers/staging/media/sunxi/cedrus/cedrus_h264.c b/drivers/staging/media/sunxi/cedrus/cedrus_h264.c -index 54ee2aa423e2..cce527bbdf86 100644 ---- a/drivers/staging/media/sunxi/cedrus/cedrus_h264.c -+++ b/drivers/staging/media/sunxi/cedrus/cedrus_h264.c -@@ -166,8 +166,8 @@ static void cedrus_write_frame_list(struct cedrus_ctx *ctx, - - static void _cedrus_write_ref_list(struct cedrus_ctx *ctx, - struct cedrus_run *run, -- const u8 *ref_list, u8 num_ref, -- enum cedrus_h264_sram_off sram) -+ const struct v4l2_h264_reference *ref_list, -+ u8 num_ref, enum cedrus_h264_sram_off sram) - { - const struct v4l2_ctrl_h264_decode_params *decode = run->h264.decode_params; - struct vb2_queue *cap_q; -@@ -188,7 +188,7 @@ static void _cedrus_write_ref_list(struct cedrus_ctx *ctx, - int buf_idx; - u8 dpb_idx; - -- dpb_idx = ref_list[i]; -+ dpb_idx = ref_list[i].index; - dpb = &decode->dpb[dpb_idx]; - - if (!(dpb->flags & V4L2_H264_DPB_ENTRY_FLAG_ACTIVE)) -diff --git a/include/media/h264-ctrls.h b/include/media/h264-ctrls.h -index 080fd1293c42..3c613b84e5ae 100644 ---- a/include/media/h264-ctrls.h -+++ b/include/media/h264-ctrls.h -@@ -19,6 +19,8 @@ - */ - #define V4L2_H264_NUM_DPB_ENTRIES 16 - -+#define V4L2_H264_REF_LIST_LEN (2 * V4L2_H264_NUM_DPB_ENTRIES) -+ - /* Our pixel format isn't stable at the moment */ - #define V4L2_PIX_FMT_H264_SLICE v4l2_fourcc('S', '2', '6', '4') /* H264 parsed slices */ - -@@ -140,6 +142,17 @@ struct v4l2_h264_pred_weight_table { - #define V4L2_H264_SLICE_FLAG_DIRECT_SPATIAL_MV_PRED 0x04 - #define V4L2_H264_SLICE_FLAG_SP_FOR_SWITCH 0x08 - -+#define V4L2_H264_TOP_FIELD_REF 0x1 -+#define V4L2_H264_BOTTOM_FIELD_REF 0x2 -+#define V4L2_H264_FRAME_REF 0x3 -+ -+struct v4l2_h264_reference { -+ __u8 fields; -+ -+ /* Index into v4l2_ctrl_h264_decode_params.dpb[] */ -+ __u8 index; -+}; -+ - struct v4l2_ctrl_h264_slice_params { - /* Size in bytes, including header */ - __u32 size; -@@ -178,12 +191,8 @@ struct v4l2_ctrl_h264_slice_params { - __u8 num_ref_idx_l1_active_minus1; - __u32 slice_group_change_cycle; - -- /* -- * Entries on each list are indices into -- * v4l2_ctrl_h264_decode_params.dpb[]. -- */ -- __u8 ref_pic_list0[32]; -- __u8 ref_pic_list1[32]; -+ struct v4l2_h264_reference ref_pic_list0[V4L2_H264_REF_LIST_LEN]; -+ struct v4l2_h264_reference ref_pic_list1[V4L2_H264_REF_LIST_LEN]; - - __u32 flags; - }; - -From 2abf5d0e3f8c932002c0aa44f486f53e8225e1d3 Mon Sep 17 00:00:00 2001 -From: Ezequiel Garcia -Date: Tue, 25 Aug 2020 05:52:28 +0200 -Subject: [PATCH] media: uapi: h264: Further clarify scaling lists order - -Commit 0b0393d59eb4a ("media: uapi: h264: clarify -expected scaling_list_4x4/8x8 order") improved the -documentation on H264 scaling lists order. - -This commit improves the documentation by clarifying -that the lists themselves are expected in raster scan order. - -Signed-off-by: Ezequiel Garcia -Tested-by: Jonas Karlman -Signed-off-by: Hans Verkuil -Signed-off-by: Mauro Carvalho Chehab -(cherry picked from commit cefdf805844b551e08858971e1f64e3af378d697) ---- - Documentation/userspace-api/media/v4l/ext-ctrls-codec.rst | 6 ++++-- - 1 file changed, 4 insertions(+), 2 deletions(-) - -diff --git a/Documentation/userspace-api/media/v4l/ext-ctrls-codec.rst b/Documentation/userspace-api/media/v4l/ext-ctrls-codec.rst -index df1c4fc5cb48..2cce412f5be1 100644 ---- a/Documentation/userspace-api/media/v4l/ext-ctrls-codec.rst -+++ b/Documentation/userspace-api/media/v4l/ext-ctrls-codec.rst -@@ -1725,12 +1725,14 @@ enum v4l2_mpeg_video_h264_hierarchical_coding_type - - - ``scaling_list_4x4[6][16]`` - - Scaling matrix after applying the inverse scanning process. - Expected list order is Intra Y, Intra Cb, Intra Cr, Inter Y, -- Inter Cb, Inter Cr. -+ Inter Cb, Inter Cr. The values on each scaling list are -+ expected in raster scan order. - * - __u8 - - ``scaling_list_8x8[6][64]`` - - Scaling matrix after applying the inverse scanning process. - Expected list order is Intra Y, Inter Y, Intra Cb, Inter Cb, -- Intra Cr, Inter Cr. -+ Intra Cr, Inter Cr. The values on each scaling list are -+ expected in raster scan order. - - ``V4L2_CID_MPEG_VIDEO_H264_SLICE_PARAMS (struct)`` - Specifies the slice parameters (as extracted from the bitstream) - -From 10ca864bd5385e820849556513562b879974bd95 Mon Sep 17 00:00:00 2001 -From: Ezequiel Garcia -Date: Tue, 25 Aug 2020 05:52:29 +0200 -Subject: [PATCH] media: uapi: h264: Split prediction weight parameters - -The prediction weight parameters are only required under -certain conditions, which depend on slice header parameters. - -As specified in section 7.3.3 Slice header syntax, the prediction -weight table is present if: - -((weighted_pred_flag && (slice_type == P || slice_type == SP)) || \ -(weighted_bipred_idc == 1 && slice_type == B)) - -Given its size, it makes sense to move this table to its control, -so applications can avoid passing it if the slice doesn't specify it. - -Before this change struct v4l2_ctrl_h264_slice_params was 960 bytes. -With this change, it's 188 bytes and struct v4l2_ctrl_h264_pred_weight -is 772 bytes. - -Signed-off-by: Ezequiel Garcia -Tested-by: Jonas Karlman -Signed-off-by: Hans Verkuil -Signed-off-by: Mauro Carvalho Chehab -(cherry picked from commit eb44c6c9c236b1568985816254faf520fde21776) ---- - .../userspace-api/media/v4l/ext-ctrls-codec.rst | 19 ++++++++++++------- - drivers/media/v4l2-core/v4l2-ctrls.c | 8 ++++++++ - drivers/staging/media/sunxi/cedrus/cedrus.c | 7 +++++++ - drivers/staging/media/sunxi/cedrus/cedrus.h | 1 + - drivers/staging/media/sunxi/cedrus/cedrus_dec.c | 2 ++ - drivers/staging/media/sunxi/cedrus/cedrus_h264.c | 12 +++--------- - include/media/h264-ctrls.h | 12 ++++++++++-- - include/media/v4l2-ctrls.h | 2 ++ - 8 files changed, 45 insertions(+), 18 deletions(-) - -diff --git a/Documentation/userspace-api/media/v4l/ext-ctrls-codec.rst b/Documentation/userspace-api/media/v4l/ext-ctrls-codec.rst -index 2cce412f5be1..9e4421a7c6a6 100644 ---- a/Documentation/userspace-api/media/v4l/ext-ctrls-codec.rst -+++ b/Documentation/userspace-api/media/v4l/ext-ctrls-codec.rst -@@ -1879,18 +1879,23 @@ enum v4l2_mpeg_video_h264_hierarchical_coding_type - - - 0x00000008 - - - --``Prediction Weight Table`` -+``V4L2_CID_MPEG_VIDEO_H264_PRED_WEIGHTS (struct)`` -+ Prediction weight table defined according to :ref:`h264`, -+ section 7.4.3.2 "Prediction Weight Table Semantics". -+ The prediction weight table must be passed by applications -+ under the conditions explained in section 7.3.3 "Slice header -+ syntax". - -- The bitstream parameters are defined according to :ref:`h264`, -- section 7.4.3.2 "Prediction Weight Table Semantics". For further -- documentation, refer to the above specification, unless there is -- an explicit comment stating otherwise. -+ .. note:: -+ -+ This compound control is not yet part of the public kernel API and -+ it is expected to change. - --.. c:type:: v4l2_h264_pred_weight_table -+.. c:type:: v4l2_ctrl_h264_pred_weights - - .. cssclass:: longtable - --.. flat-table:: struct v4l2_h264_pred_weight_table -+.. flat-table:: struct v4l2_ctrl_h264_pred_weights - :header-rows: 0 - :stub-columns: 0 - :widths: 1 1 2 -diff --git a/drivers/media/v4l2-core/v4l2-ctrls.c b/drivers/media/v4l2-core/v4l2-ctrls.c -index 45a2403aa039..ae0bf3f36c4a 100644 ---- a/drivers/media/v4l2-core/v4l2-ctrls.c -+++ b/drivers/media/v4l2-core/v4l2-ctrls.c -@@ -897,6 +897,7 @@ const char *v4l2_ctrl_get_name(u32 id) - case V4L2_CID_MPEG_VIDEO_H264_DECODE_PARAMS: return "H264 Decode Parameters"; - case V4L2_CID_MPEG_VIDEO_H264_DECODE_MODE: return "H264 Decode Mode"; - case V4L2_CID_MPEG_VIDEO_H264_START_CODE: return "H264 Start Code"; -+ case V4L2_CID_MPEG_VIDEO_H264_PRED_WEIGHTS: return "H264 Prediction Weight Table"; - case V4L2_CID_MPEG_VIDEO_MPEG2_LEVEL: return "MPEG2 Level"; - case V4L2_CID_MPEG_VIDEO_MPEG2_PROFILE: return "MPEG2 Profile"; - case V4L2_CID_MPEG_VIDEO_MPEG4_I_FRAME_QP: return "MPEG4 I-Frame QP Value"; -@@ -1412,6 +1413,9 @@ void v4l2_ctrl_fill(u32 id, const char **name, enum v4l2_ctrl_type *type, - case V4L2_CID_MPEG_VIDEO_H264_DECODE_PARAMS: - *type = V4L2_CTRL_TYPE_H264_DECODE_PARAMS; - break; -+ case V4L2_CID_MPEG_VIDEO_H264_PRED_WEIGHTS: -+ *type = V4L2_CTRL_TYPE_H264_PRED_WEIGHTS; -+ break; - case V4L2_CID_MPEG_VIDEO_VP8_FRAME_HEADER: - *type = V4L2_CTRL_TYPE_VP8_FRAME_HEADER; - break; -@@ -1790,6 +1794,7 @@ static int std_validate_compound(const struct v4l2_ctrl *ctrl, u32 idx, - case V4L2_CTRL_TYPE_H264_SPS: - case V4L2_CTRL_TYPE_H264_PPS: - case V4L2_CTRL_TYPE_H264_SCALING_MATRIX: -+ case V4L2_CTRL_TYPE_H264_PRED_WEIGHTS: - case V4L2_CTRL_TYPE_H264_SLICE_PARAMS: - case V4L2_CTRL_TYPE_H264_DECODE_PARAMS: - break; -@@ -2553,6 +2558,9 @@ static struct v4l2_ctrl *v4l2_ctrl_new(struct v4l2_ctrl_handler *hdl, - case V4L2_CTRL_TYPE_H264_DECODE_PARAMS: - elem_size = sizeof(struct v4l2_ctrl_h264_decode_params); - break; -+ case V4L2_CTRL_TYPE_H264_PRED_WEIGHTS: -+ elem_size = sizeof(struct v4l2_ctrl_h264_pred_weights); -+ break; - case V4L2_CTRL_TYPE_VP8_FRAME_HEADER: - elem_size = sizeof(struct v4l2_ctrl_vp8_frame_header); - break; -diff --git a/drivers/staging/media/sunxi/cedrus/cedrus.c b/drivers/staging/media/sunxi/cedrus/cedrus.c -index 7c6b91f0e780..5d41d3357663 100644 ---- a/drivers/staging/media/sunxi/cedrus/cedrus.c -+++ b/drivers/staging/media/sunxi/cedrus/cedrus.c -@@ -78,6 +78,13 @@ static const struct cedrus_control cedrus_controls[] = { - .codec = CEDRUS_CODEC_H264, - .required = true, - }, -+ { -+ .cfg = { -+ .id = V4L2_CID_MPEG_VIDEO_H264_PRED_WEIGHTS, -+ }, -+ .codec = CEDRUS_CODEC_H264, -+ .required = false, -+ }, - { - .cfg = { - .id = V4L2_CID_MPEG_VIDEO_H264_DECODE_MODE, -diff --git a/drivers/staging/media/sunxi/cedrus/cedrus.h b/drivers/staging/media/sunxi/cedrus/cedrus.h -index 96765555ab8a..93c843ae14bb 100644 ---- a/drivers/staging/media/sunxi/cedrus/cedrus.h -+++ b/drivers/staging/media/sunxi/cedrus/cedrus.h -@@ -62,6 +62,7 @@ struct cedrus_h264_run { - const struct v4l2_ctrl_h264_scaling_matrix *scaling_matrix; - const struct v4l2_ctrl_h264_slice_params *slice_params; - const struct v4l2_ctrl_h264_sps *sps; -+ const struct v4l2_ctrl_h264_pred_weights *pred_weights; - }; - - struct cedrus_mpeg2_run { -diff --git a/drivers/staging/media/sunxi/cedrus/cedrus_dec.c b/drivers/staging/media/sunxi/cedrus/cedrus_dec.c -index 58c48e4fdfe9..6385026d1b6b 100644 ---- a/drivers/staging/media/sunxi/cedrus/cedrus_dec.c -+++ b/drivers/staging/media/sunxi/cedrus/cedrus_dec.c -@@ -57,6 +57,8 @@ void cedrus_device_run(void *priv) - V4L2_CID_MPEG_VIDEO_H264_SLICE_PARAMS); - run.h264.sps = cedrus_find_control_data(ctx, - V4L2_CID_MPEG_VIDEO_H264_SPS); -+ run.h264.pred_weights = cedrus_find_control_data(ctx, -+ V4L2_CID_MPEG_VIDEO_H264_PRED_WEIGHTS); - break; - - case V4L2_PIX_FMT_HEVC_SLICE: -diff --git a/drivers/staging/media/sunxi/cedrus/cedrus_h264.c b/drivers/staging/media/sunxi/cedrus/cedrus_h264.c -index cce527bbdf86..d5636dbbb622 100644 ---- a/drivers/staging/media/sunxi/cedrus/cedrus_h264.c -+++ b/drivers/staging/media/sunxi/cedrus/cedrus_h264.c -@@ -256,10 +256,8 @@ static void cedrus_write_scaling_lists(struct cedrus_ctx *ctx, - static void cedrus_write_pred_weight_table(struct cedrus_ctx *ctx, - struct cedrus_run *run) - { -- const struct v4l2_ctrl_h264_slice_params *slice = -- run->h264.slice_params; -- const struct v4l2_h264_pred_weight_table *pred_weight = -- &slice->pred_weight_table; -+ const struct v4l2_ctrl_h264_pred_weights *pred_weight = -+ run->h264.pred_weights; - struct cedrus_dev *dev = ctx->dev; - int i, j, k; - -@@ -367,11 +365,7 @@ static void cedrus_set_params(struct cedrus_ctx *ctx, - - cedrus_skip_bits(dev, slice->header_bit_size); - -- if (((pps->flags & V4L2_H264_PPS_FLAG_WEIGHTED_PRED) && -- (slice->slice_type == V4L2_H264_SLICE_TYPE_P || -- slice->slice_type == V4L2_H264_SLICE_TYPE_SP)) || -- (pps->weighted_bipred_idc == 1 && -- slice->slice_type == V4L2_H264_SLICE_TYPE_B)) -+ if (V4L2_H264_CTRL_PRED_WEIGHTS_REQUIRED(pps, slice)) - cedrus_write_pred_weight_table(ctx, run); - - if ((slice->slice_type == V4L2_H264_SLICE_TYPE_P) || -diff --git a/include/media/h264-ctrls.h b/include/media/h264-ctrls.h -index 3c613b84e5ae..31c6f4c5963b 100644 ---- a/include/media/h264-ctrls.h -+++ b/include/media/h264-ctrls.h -@@ -36,6 +36,7 @@ - #define V4L2_CID_MPEG_VIDEO_H264_DECODE_PARAMS (V4L2_CID_MPEG_BASE+1004) - #define V4L2_CID_MPEG_VIDEO_H264_DECODE_MODE (V4L2_CID_MPEG_BASE+1005) - #define V4L2_CID_MPEG_VIDEO_H264_START_CODE (V4L2_CID_MPEG_BASE+1006) -+#define V4L2_CID_MPEG_VIDEO_H264_PRED_WEIGHTS (V4L2_CID_MPEG_BASE+1007) - - /* enum v4l2_ctrl_type type values */ - #define V4L2_CTRL_TYPE_H264_SPS 0x0110 -@@ -43,6 +44,7 @@ - #define V4L2_CTRL_TYPE_H264_SCALING_MATRIX 0x0112 - #define V4L2_CTRL_TYPE_H264_SLICE_PARAMS 0x0113 - #define V4L2_CTRL_TYPE_H264_DECODE_PARAMS 0x0114 -+#define V4L2_CTRL_TYPE_H264_PRED_WEIGHTS 0x0115 - - enum v4l2_mpeg_video_h264_decode_mode { - V4L2_MPEG_VIDEO_H264_DECODE_MODE_SLICE_BASED, -@@ -125,7 +127,14 @@ struct v4l2_h264_weight_factors { - __s16 chroma_offset[32][2]; - }; - --struct v4l2_h264_pred_weight_table { -+#define V4L2_H264_CTRL_PRED_WEIGHTS_REQUIRED(pps, slice) \ -+ ((((pps)->flags & V4L2_H264_PPS_FLAG_WEIGHTED_PRED) && \ -+ ((slice)->slice_type == V4L2_H264_SLICE_TYPE_P || \ -+ (slice)->slice_type == V4L2_H264_SLICE_TYPE_SP)) || \ -+ ((pps)->weighted_bipred_idc == 1 && \ -+ (slice)->slice_type == V4L2_H264_SLICE_TYPE_B)) -+ -+struct v4l2_ctrl_h264_pred_weights { - __u16 luma_log2_weight_denom; - __u16 chroma_log2_weight_denom; - struct v4l2_h264_weight_factors weight_factors[2]; -@@ -175,7 +184,6 @@ struct v4l2_ctrl_h264_slice_params { - __s32 delta_pic_order_cnt0; - __s32 delta_pic_order_cnt1; - -- struct v4l2_h264_pred_weight_table pred_weight_table; - /* Size in bits of dec_ref_pic_marking() syntax element. */ - __u32 dec_ref_pic_marking_bit_size; - /* Size in bits of pic order count syntax. */ -diff --git a/include/media/v4l2-ctrls.h b/include/media/v4l2-ctrls.h -index f40e2cbb21d3..cb25f345e9ad 100644 ---- a/include/media/v4l2-ctrls.h -+++ b/include/media/v4l2-ctrls.h -@@ -51,6 +51,7 @@ struct video_device; - * @p_h264_scaling_matrix: Pointer to a struct v4l2_ctrl_h264_scaling_matrix. - * @p_h264_slice_params: Pointer to a struct v4l2_ctrl_h264_slice_params. - * @p_h264_decode_params: Pointer to a struct v4l2_ctrl_h264_decode_params. -+ * @p_h264_pred_weights: Pointer to a struct v4l2_ctrl_h264_pred_weights. - * @p_vp8_frame_header: Pointer to a VP8 frame header structure. - * @p_hevc_sps: Pointer to an HEVC sequence parameter set structure. - * @p_hevc_pps: Pointer to an HEVC picture parameter set structure. -@@ -74,6 +75,7 @@ union v4l2_ctrl_ptr { - struct v4l2_ctrl_h264_scaling_matrix *p_h264_scaling_matrix; - struct v4l2_ctrl_h264_slice_params *p_h264_slice_params; - struct v4l2_ctrl_h264_decode_params *p_h264_decode_params; -+ struct v4l2_ctrl_h264_pred_weights *p_h264_pred_weights; - struct v4l2_ctrl_vp8_frame_header *p_vp8_frame_header; - struct v4l2_ctrl_hevc_sps *p_hevc_sps; - struct v4l2_ctrl_hevc_pps *p_hevc_pps; - -From b9ab1fbb981ac04f89e2a2a8c22a3e79d9089718 Mon Sep 17 00:00:00 2001 -From: Philipp Zabel -Date: Tue, 25 Aug 2020 05:52:30 +0200 -Subject: [PATCH] media: uapi: h264: Clarify pic_order_cnt_bit_size field - -Since pic_order_cnt_bit_size is not a syntax element itself, explicitly -state that it is the total size in bits of the pic_order_cnt_lsb, -delta_pic_order_cnt_bottom, delta_pic_order_cnt[0], and -delta_pic_order_cnt[1] syntax elements contained in the slice. - -[Ezequiel: rebase] - -Signed-off-by: Philipp Zabel -Signed-off-by: Ezequiel Garcia -Reviewed-by: Nicolas Dufresne -Tested-by: Jonas Karlman -Signed-off-by: Hans Verkuil -Signed-off-by: Mauro Carvalho Chehab -(cherry picked from commit fb92c56312d4e3a5c30de963e459a040a4761665) ---- - Documentation/userspace-api/media/v4l/ext-ctrls-codec.rst | 4 +++- - 1 file changed, 3 insertions(+), 1 deletion(-) - -diff --git a/Documentation/userspace-api/media/v4l/ext-ctrls-codec.rst b/Documentation/userspace-api/media/v4l/ext-ctrls-codec.rst -index 9e4421a7c6a6..591d3d35c429 100644 ---- a/Documentation/userspace-api/media/v4l/ext-ctrls-codec.rst -+++ b/Documentation/userspace-api/media/v4l/ext-ctrls-codec.rst -@@ -1815,7 +1815,9 @@ enum v4l2_mpeg_video_h264_hierarchical_coding_type - - - Size in bits of the dec_ref_pic_marking() syntax element. - * - __u32 - - ``pic_order_cnt_bit_size`` -- - -+ - Combined size in bits of the picture order count related syntax -+ elements: pic_order_cnt_lsb, delta_pic_order_cnt_bottom, -+ delta_pic_order_cnt0, and delta_pic_order_cnt1. - * - __u8 - - ``cabac_init_idc`` - - - -From 49086ddc8b141ed75f1023e3ebcb87a7d0c224c0 Mon Sep 17 00:00:00 2001 -From: Ezequiel Garcia -Date: Tue, 25 Aug 2020 05:52:31 +0200 -Subject: [PATCH] media: uapi: h264: Increase size of 'first_mb_in_slice' field - -Slice header syntax element 'first_mb_in_slice' can point -to the last macroblock, currently the field can only reference -65536 macroblocks which is insufficient for 8K videos. - -Although unlikely, a 8192x4320 video (where macroblocks are 16x16), -would contain 138240 macroblocks on a frame. - -As per the H264 specification, 'first_mb_in_slice' can be up to -PicSizeInMbs - 1, so increase the size of the field to 32-bits. - -Note that v4l2_ctrl_h264_slice_params struct will be modified -in a follow-up commit, and so we defer its 64-bit padding. - -Signed-off-by: Ezequiel Garcia -Tested-by: Jonas Karlman -Signed-off-by: Hans Verkuil -Signed-off-by: Mauro Carvalho Chehab -(cherry picked from commit 4245232fa6ca58f79710732bd16cefe78b8b8bc4) ---- - Documentation/userspace-api/media/v4l/ext-ctrls-codec.rst | 2 +- - include/media/h264-ctrls.h | 3 ++- - 2 files changed, 3 insertions(+), 2 deletions(-) - -diff --git a/Documentation/userspace-api/media/v4l/ext-ctrls-codec.rst b/Documentation/userspace-api/media/v4l/ext-ctrls-codec.rst -index 591d3d35c429..a417a1ae50d5 100644 ---- a/Documentation/userspace-api/media/v4l/ext-ctrls-codec.rst -+++ b/Documentation/userspace-api/media/v4l/ext-ctrls-codec.rst -@@ -1774,7 +1774,7 @@ enum v4l2_mpeg_video_h264_hierarchical_coding_type - - * - __u32 - - ``header_bit_size`` - - -- * - __u16 -+ * - __u32 - - ``first_mb_in_slice`` - - - * - __u8 -diff --git a/include/media/h264-ctrls.h b/include/media/h264-ctrls.h -index 31c6f4c5963b..9a6722edf004 100644 ---- a/include/media/h264-ctrls.h -+++ b/include/media/h264-ctrls.h -@@ -172,7 +172,8 @@ struct v4l2_ctrl_h264_slice_params { - /* Offset in bits to slice_data() from the beginning of this slice. */ - __u32 header_bit_size; - -- __u16 first_mb_in_slice; -+ __u32 first_mb_in_slice; -+ - __u8 slice_type; - __u8 pic_parameter_set_id; - __u8 colour_plane_id; - -From d1bcf7e7272530af2327ee7c6bcbf9de3bddf697 Mon Sep 17 00:00:00 2001 -From: Ezequiel Garcia -Date: Tue, 25 Aug 2020 05:52:32 +0200 -Subject: [PATCH] media: uapi: h264: Clean DPB entry interface - -As discussed recently, the current interface for the -Decoded Picture Buffer is not enough to properly -support field coding. - -This commit introduces enough semantics to support -frame and field coding, and to signal how DPB entries -are "used for reference". - -Reserved fields will be added by a follow-up commit. - -Signed-off-by: Ezequiel Garcia -Tested-by: Jonas Karlman -Signed-off-by: Hans Verkuil -Signed-off-by: Mauro Carvalho Chehab -(cherry picked from commit c02ff21952a6a19ca375b9dc4f9a5609616a82b8) ---- - .../userspace-api/media/v4l/ext-ctrls-codec.rst | 24 +++++++--------------- - drivers/media/v4l2-core/v4l2-h264.c | 4 ++-- - drivers/staging/media/rkvdec/rkvdec-h264.c | 17 +++++++-------- - include/media/h264-ctrls.h | 2 +- - 4 files changed, 19 insertions(+), 28 deletions(-) - -diff --git a/Documentation/userspace-api/media/v4l/ext-ctrls-codec.rst b/Documentation/userspace-api/media/v4l/ext-ctrls-codec.rst -index a417a1ae50d5..49febae8fd0f 100644 ---- a/Documentation/userspace-api/media/v4l/ext-ctrls-codec.rst -+++ b/Documentation/userspace-api/media/v4l/ext-ctrls-codec.rst -@@ -2057,6 +2057,9 @@ enum v4l2_mpeg_video_h264_hierarchical_coding_type - - * - __u16 - - ``pic_num`` - - -+ * - __u8 -+ - ``fields`` -+ - Specifies how the DPB entry is referenced. See :ref:`Reference Fields ` - * - __s32 - - ``top_field_order_cnt`` - - -@@ -2080,29 +2083,16 @@ enum v4l2_mpeg_video_h264_hierarchical_coding_type - - - * - ``V4L2_H264_DPB_ENTRY_FLAG_VALID`` - - 0x00000001 -- - The DPB entry is valid and should be considered -+ - The DPB entry is valid (non-empty) and should be considered. - * - ``V4L2_H264_DPB_ENTRY_FLAG_ACTIVE`` - - 0x00000002 -- - The DPB entry is currently being used as a reference frame -+ - The DPB entry is used for reference. - * - ``V4L2_H264_DPB_ENTRY_FLAG_LONG_TERM`` - - 0x00000004 -- - The DPB entry is a long term reference frame -+ - The DPB entry is used for long-term reference. - * - ``V4L2_H264_DPB_ENTRY_FLAG_FIELD`` - - 0x00000008 -- - The DPB entry is a field reference, which means only one of the field -- will be used when decoding the new frame/field. When not set the DPB -- entry is a frame reference (both fields will be used). Note that this -- flag does not say anything about the number of fields contained in the -- reference frame, it just describes the one used to decode the new -- field/frame -- * - ``V4L2_H264_DPB_ENTRY_FLAG_BOTTOM_FIELD`` -- - 0x00000010 -- - The DPB entry is a bottom field reference (only the bottom field of the -- reference frame is needed to decode the new frame/field). Only valid if -- V4L2_H264_DPB_ENTRY_FLAG_FIELD is set. When -- V4L2_H264_DPB_ENTRY_FLAG_FIELD is set but -- V4L2_H264_DPB_ENTRY_FLAG_BOTTOM_FIELD is not, that means the -- DPB entry is a top field reference -+ - The DPB entry is a single field or a complementary field pair. - - ``V4L2_CID_MPEG_VIDEO_H264_DECODE_MODE (enum)`` - Specifies the decoding mode to use. Currently exposes slice-based and -diff --git a/drivers/media/v4l2-core/v4l2-h264.c b/drivers/media/v4l2-core/v4l2-h264.c -index edf6225f0522..f4742408436b 100644 ---- a/drivers/media/v4l2-core/v4l2-h264.c -+++ b/drivers/media/v4l2-core/v4l2-h264.c -@@ -66,10 +66,10 @@ v4l2_h264_init_reflist_builder(struct v4l2_h264_reflist_builder *b, - else - b->refs[i].frame_num = dpb[i].frame_num; - -- if (!(dpb[i].flags & V4L2_H264_DPB_ENTRY_FLAG_FIELD)) -+ if (dpb[i].fields == V4L2_H264_FRAME_REF) - 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) -+ else if (dpb[i].fields & V4L2_H264_BOTTOM_FIELD_REF) - pic_order_count = dpb[i].bottom_field_order_cnt; - else - pic_order_count = dpb[i].top_field_order_cnt; -diff --git a/drivers/staging/media/rkvdec/rkvdec-h264.c b/drivers/staging/media/rkvdec/rkvdec-h264.c -index 7b66e2743a4f..d1f2715f30ae 100644 ---- a/drivers/staging/media/rkvdec/rkvdec-h264.c -+++ b/drivers/staging/media/rkvdec/rkvdec-h264.c -@@ -949,16 +949,17 @@ static void config_registers(struct rkvdec_ctx *ctx, - 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; -+ refer_addr = vb2_dma_contig_plane_dma_addr(vb_buf, 0); - -- 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 -+ if (dpb[i].flags & V4L2_H264_DPB_ENTRY_FLAG_ACTIVE) -+ refer_addr |= RKVDEC_COLMV_USED_FLAG_REF; -+ if (dpb[i].flags & V4L2_H264_DPB_ENTRY_FLAG_FIELD) -+ refer_addr |= RKVDEC_FIELD_REF; -+ -+ if (dpb[i].fields & V4L2_H264_TOP_FIELD_REF) - refer_addr |= RKVDEC_TOPFIELD_USED_REF; -+ if (dpb[i].fields & V4L2_H264_BOTTOM_FIELD_REF) -+ refer_addr |= RKVDEC_BOTFIELD_USED_REF; - - writel_relaxed(dpb[i].top_field_order_cnt, - rkvdec->regs + poc_reg_tbl_top_field[i]); -diff --git a/include/media/h264-ctrls.h b/include/media/h264-ctrls.h -index 9a6722edf004..0529e75cce5f 100644 ---- a/include/media/h264-ctrls.h -+++ b/include/media/h264-ctrls.h -@@ -210,12 +210,12 @@ struct v4l2_ctrl_h264_slice_params { - #define V4L2_H264_DPB_ENTRY_FLAG_ACTIVE 0x02 - #define V4L2_H264_DPB_ENTRY_FLAG_LONG_TERM 0x04 - #define V4L2_H264_DPB_ENTRY_FLAG_FIELD 0x08 --#define V4L2_H264_DPB_ENTRY_FLAG_BOTTOM_FIELD 0x10 - - struct v4l2_h264_dpb_entry { - __u64 reference_ts; - __u16 frame_num; - __u16 pic_num; -+ __u8 fields; - /* Note that field is indicated by v4l2_buffer.field */ - __s32 top_field_order_cnt; - __s32 bottom_field_order_cnt; - -From 44d417cc4d3f820149995948f9cb0d2ef02c7562 Mon Sep 17 00:00:00 2001 -From: Ezequiel Garcia -Date: Tue, 25 Aug 2020 05:52:33 +0200 -Subject: [PATCH] media: uapi: h264: Increase size of DPB entry pic_num - -DPB entry PicNum maximum value is 2*MaxFrameNum for interlaced -content (field_pic_flag=1). - -As specified, MaxFrameNum is 2^(log2_max_frame_num_minus4 + 4) -and log2_max_frame_num_minus4 is in the range of 0 to 12, -which means pic_num should be a 32-bit field. - -The v4l2_h264_dpb_entry struct needs to be padded to avoid a hole, -which might be also useful to allow future uAPI extensions. - -Signed-off-by: Ezequiel Garcia -Tested-by: Jonas Karlman -Signed-off-by: Hans Verkuil -Signed-off-by: Mauro Carvalho Chehab -(cherry picked from commit f9879eb378295e8a912d2d10c872c45f3e19421b) ---- - Documentation/userspace-api/media/v4l/ext-ctrls-codec.rst | 9 ++++++--- - drivers/media/v4l2-core/v4l2-ctrls.c | 13 +++++++++++++ - include/media/h264-ctrls.h | 3 ++- - include/media/v4l2-h264.h | 2 +- - 4 files changed, 22 insertions(+), 5 deletions(-) - -diff --git a/Documentation/userspace-api/media/v4l/ext-ctrls-codec.rst b/Documentation/userspace-api/media/v4l/ext-ctrls-codec.rst -index 49febae8fd0f..3808c46718ad 100644 ---- a/Documentation/userspace-api/media/v4l/ext-ctrls-codec.rst -+++ b/Documentation/userspace-api/media/v4l/ext-ctrls-codec.rst -@@ -2051,15 +2051,18 @@ enum v4l2_mpeg_video_h264_hierarchical_coding_type - - ``timestamp`` field in struct :c:type:`v4l2_buffer`. Use the - :c:func:`v4l2_timeval_to_ns()` function to convert the struct - :c:type:`timeval` in struct :c:type:`v4l2_buffer` to a __u64. -- * - __u16 -- - ``frame_num`` -+ * - __u32 -+ - ``pic_num`` - - - * - __u16 -- - ``pic_num`` -+ - ``frame_num`` - - - * - __u8 - - ``fields`` - - Specifies how the DPB entry is referenced. See :ref:`Reference Fields ` -+ * - __u8 -+ - ``reserved[5]`` -+ - Applications and drivers must set this to zero. - * - __s32 - - ``top_field_order_cnt`` - - -diff --git a/drivers/media/v4l2-core/v4l2-ctrls.c b/drivers/media/v4l2-core/v4l2-ctrls.c -index ae0bf3f36c4a..31dbe4222091 100644 ---- a/drivers/media/v4l2-core/v4l2-ctrls.c -+++ b/drivers/media/v4l2-core/v4l2-ctrls.c -@@ -1725,6 +1725,8 @@ static void std_log(const struct v4l2_ctrl *ctrl) - - #define zero_padding(s) \ - memset(&(s).padding, 0, sizeof((s).padding)) -+#define zero_reserved(s) \ -+ memset(&(s).reserved, 0, sizeof((s).reserved)) - - /* - * Compound controls validation requires setting unused fields/flags to zero -@@ -1735,6 +1737,7 @@ static int std_validate_compound(const struct v4l2_ctrl *ctrl, u32 idx, - { - struct v4l2_ctrl_mpeg2_slice_params *p_mpeg2_slice_params; - struct v4l2_ctrl_vp8_frame_header *p_vp8_frame_header; -+ struct v4l2_ctrl_h264_decode_params *p_h264_dec_params; - struct v4l2_ctrl_hevc_sps *p_hevc_sps; - struct v4l2_ctrl_hevc_pps *p_hevc_pps; - struct v4l2_ctrl_hevc_slice_params *p_hevc_slice_params; -@@ -1796,7 +1799,17 @@ static int std_validate_compound(const struct v4l2_ctrl *ctrl, u32 idx, - case V4L2_CTRL_TYPE_H264_SCALING_MATRIX: - case V4L2_CTRL_TYPE_H264_PRED_WEIGHTS: - case V4L2_CTRL_TYPE_H264_SLICE_PARAMS: -+ break; -+ - case V4L2_CTRL_TYPE_H264_DECODE_PARAMS: -+ p_h264_dec_params = p; -+ -+ for (i = 0; i < V4L2_H264_NUM_DPB_ENTRIES; i++) { -+ struct v4l2_h264_dpb_entry *dpb_entry = -+ &p_h264_dec_params->dpb[i]; -+ -+ zero_reserved(*dpb_entry); -+ } - break; - - case V4L2_CTRL_TYPE_VP8_FRAME_HEADER: -diff --git a/include/media/h264-ctrls.h b/include/media/h264-ctrls.h -index 0529e75cce5f..91f6f0d43e11 100644 ---- a/include/media/h264-ctrls.h -+++ b/include/media/h264-ctrls.h -@@ -213,9 +213,10 @@ struct v4l2_ctrl_h264_slice_params { - - struct v4l2_h264_dpb_entry { - __u64 reference_ts; -+ __u32 pic_num; - __u16 frame_num; -- __u16 pic_num; - __u8 fields; -+ __u8 reserved[5]; - /* Note that field is indicated by v4l2_buffer.field */ - __s32 top_field_order_cnt; - __s32 bottom_field_order_cnt; -diff --git a/include/media/v4l2-h264.h b/include/media/v4l2-h264.h -index bc9ebb560ccf..1a5f26fc2a9a 100644 ---- a/include/media/v4l2-h264.h -+++ b/include/media/v4l2-h264.h -@@ -33,7 +33,7 @@ struct v4l2_h264_reflist_builder { - struct { - s32 pic_order_count; - int frame_num; -- u16 pic_num; -+ u32 pic_num; - u16 longterm : 1; - } refs[V4L2_H264_NUM_DPB_ENTRIES]; - s32 cur_pic_order_count; - -From cc7011362e4d3327874deb6d585c610558a10bc4 Mon Sep 17 00:00:00 2001 -From: Ezequiel Garcia -Date: Tue, 25 Aug 2020 05:52:34 +0200 -Subject: [PATCH] media: uapi: h264: Drop SLICE_PARAMS 'size' field - -The SLICE_PARAMS control is intended for slice-based -devices. In this mode, the OUTPUT buffer contains -a single slice, and so the buffer's plane payload size -can be used to query the slice size. - -To reduce the API surface drop the size from the -SLICE_PARAMS control. - -A follow-up change will remove other members in SLICE_PARAMS -so we don't need to add padding fields here. - -Signed-off-by: Ezequiel Garcia -Tested-by: Jonas Karlman -Signed-off-by: Hans Verkuil -Signed-off-by: Mauro Carvalho Chehab -(cherry picked from commit f6f0d58edfa77d18c41777740958f467de615728) ---- - Documentation/userspace-api/media/v4l/ext-ctrls-codec.rst | 3 --- - drivers/staging/media/sunxi/cedrus/cedrus_h264.c | 7 +++---- - include/media/h264-ctrls.h | 3 --- - 3 files changed, 3 insertions(+), 10 deletions(-) - -diff --git a/Documentation/userspace-api/media/v4l/ext-ctrls-codec.rst b/Documentation/userspace-api/media/v4l/ext-ctrls-codec.rst -index 3808c46718ad..e74a2531ab67 100644 ---- a/Documentation/userspace-api/media/v4l/ext-ctrls-codec.rst -+++ b/Documentation/userspace-api/media/v4l/ext-ctrls-codec.rst -@@ -1760,9 +1760,6 @@ enum v4l2_mpeg_video_h264_hierarchical_coding_type - - :stub-columns: 0 - :widths: 1 1 2 - -- * - __u32 -- - ``size`` -- - - * - __u32 - - ``start_byte_offset`` - Offset (in bytes) from the beginning of the OUTPUT buffer to the start -diff --git a/drivers/staging/media/sunxi/cedrus/cedrus_h264.c b/drivers/staging/media/sunxi/cedrus/cedrus_h264.c -index d5636dbbb622..7d9bd5860a1b 100644 ---- a/drivers/staging/media/sunxi/cedrus/cedrus_h264.c -+++ b/drivers/staging/media/sunxi/cedrus/cedrus_h264.c -@@ -324,17 +324,16 @@ static void cedrus_set_params(struct cedrus_ctx *ctx, - struct vb2_buffer *src_buf = &run->src->vb2_buf; - struct cedrus_dev *dev = ctx->dev; - dma_addr_t src_buf_addr; -- u32 len = slice->size * 8; -+ size_t slice_bytes = vb2_get_plane_payload(src_buf, 0); - unsigned int pic_width_in_mbs; - bool mbaff_pic; - u32 reg; - -- cedrus_write(dev, VE_H264_VLD_LEN, len); -+ cedrus_write(dev, VE_H264_VLD_LEN, slice_bytes * 8); - cedrus_write(dev, VE_H264_VLD_OFFSET, 0); - - src_buf_addr = vb2_dma_contig_plane_dma_addr(src_buf, 0); -- cedrus_write(dev, VE_H264_VLD_END, -- src_buf_addr + vb2_get_plane_payload(src_buf, 0)); -+ cedrus_write(dev, VE_H264_VLD_END, src_buf_addr + slice_bytes); - cedrus_write(dev, VE_H264_VLD_ADDR, - VE_H264_VLD_ADDR_VAL(src_buf_addr) | - VE_H264_VLD_ADDR_FIRST | VE_H264_VLD_ADDR_VALID | -diff --git a/include/media/h264-ctrls.h b/include/media/h264-ctrls.h -index 91f6f0d43e11..77d0ec51ae43 100644 ---- a/include/media/h264-ctrls.h -+++ b/include/media/h264-ctrls.h -@@ -163,9 +163,6 @@ struct v4l2_h264_reference { - }; - - struct v4l2_ctrl_h264_slice_params { -- /* Size in bytes, including header */ -- __u32 size; -- - /* Offset in bytes to the start of slice in the OUTPUT buffer. */ - __u32 start_byte_offset; - - -From 8a51555783ee2d5cd3471c4fc88f666399bd52e3 Mon Sep 17 00:00:00 2001 -From: Ezequiel Garcia -Date: Tue, 25 Aug 2020 05:52:35 +0200 -Subject: [PATCH] media: uapi: h264: Clarify SLICE_BASED mode - -Currently, the SLICE_BASED and FRAME_BASED modes documentation -is misleading and not matching the intended use-cases. - -Drop non-required fields SLICE_PARAMS 'start_byte_offset' and -DECODE_PARAMS 'num_slices' and clarify the decoding modes in the -documentation. - -On SLICE_BASED mode, a single slice is expected per OUTPUT buffer, -and therefore 'start_byte_offset' is not needed (since the offset -to the slice is the start of the buffer). - -This mode requires the use of CAPTURE buffer holding, and so -the number of slices shall not be required. - -On FRAME_BASED mode, the devices are expected to take care of slice -parsing. Neither SLICE_PARAMS are required (and shouldn't be -exposed by frame-based drivers), nor the number of slices. - -Signed-off-by: Ezequiel Garcia -Tested-by: Jonas Karlman -Signed-off-by: Hans Verkuil -Signed-off-by: Mauro Carvalho Chehab -(cherry picked from commit 2287c5e65cbcc99633c412dbfe1d39bd9f7bf1ce) ---- - .../userspace-api/media/v4l/ext-ctrls-codec.rst | 39 ++++++---------------- - include/media/h264-ctrls.h | 4 --- - 2 files changed, 10 insertions(+), 33 deletions(-) - -diff --git a/Documentation/userspace-api/media/v4l/ext-ctrls-codec.rst b/Documentation/userspace-api/media/v4l/ext-ctrls-codec.rst -index e74a2531ab67..304b6012b358 100644 ---- a/Documentation/userspace-api/media/v4l/ext-ctrls-codec.rst -+++ b/Documentation/userspace-api/media/v4l/ext-ctrls-codec.rst -@@ -1748,9 +1748,6 @@ enum v4l2_mpeg_video_h264_hierarchical_coding_type - - This compound control is not yet part of the public kernel API - and it is expected to change. - -- This structure is expected to be passed as an array, with one -- entry for each slice included in the bitstream buffer. -- - .. c:type:: v4l2_ctrl_h264_slice_params - - .. cssclass:: longtable -@@ -1760,17 +1757,9 @@ enum v4l2_mpeg_video_h264_hierarchical_coding_type - - :stub-columns: 0 - :widths: 1 1 2 - -- * - __u32 -- - ``start_byte_offset`` -- Offset (in bytes) from the beginning of the OUTPUT buffer to the start -- of the slice. If the slice starts with a start code, then this is the -- offset to such start code. When operating in slice-based decoding mode -- (see :c:type:`v4l2_mpeg_video_h264_decode_mode`), this field should -- be set to 0. When operating in frame-based decoding mode, this field -- should be 0 for the first slice. - * - __u32 - - ``header_bit_size`` -- - -+ - Offset in bits to slice_data() from the beginning of this slice. - * - __u32 - - ``first_mb_in_slice`` - - -@@ -1998,12 +1987,6 @@ enum v4l2_mpeg_video_h264_hierarchical_coding_type - - * - struct :c:type:`v4l2_h264_dpb_entry` - - ``dpb[16]`` - - -- * - __u16 -- - ``num_slices`` -- - Number of slices needed to decode the current frame/field. When -- operating in slice-based decoding mode (see -- :c:type:`v4l2_mpeg_video_h264_decode_mode`), this field -- should always be set to one. - * - __u16 - - ``nal_ref_idc`` - - NAL reference ID value coming from the NAL Unit header -@@ -2121,22 +2104,20 @@ enum v4l2_mpeg_video_h264_hierarchical_coding_type - - * - ``V4L2_MPEG_VIDEO_H264_DECODE_MODE_SLICE_BASED`` - - 0 - - Decoding is done at the slice granularity. -- In this mode, ``num_slices`` field in struct -- :c:type:`v4l2_ctrl_h264_decode_params` should be set to 1, -- and ``start_byte_offset`` in struct -- :c:type:`v4l2_ctrl_h264_slice_params` should be set to 0. - The OUTPUT buffer must contain a single slice. -+ When this mode is selected, the ``V4L2_CID_MPEG_VIDEO_H264_SLICE_PARAMS`` -+ control shall be set. When multiple slices compose a frame, -+ use of ``V4L2_BUF_CAP_SUPPORTS_M2M_HOLD_CAPTURE_BUF`` flag -+ is required. - * - ``V4L2_MPEG_VIDEO_H264_DECODE_MODE_FRAME_BASED`` - - 1 -- - Decoding is done at the frame granularity. -- In this mode, ``num_slices`` field in struct -- :c:type:`v4l2_ctrl_h264_decode_params` should be set to the number -- of slices in the frame, and ``start_byte_offset`` in struct -- :c:type:`v4l2_ctrl_h264_slice_params` should be set accordingly -- for each slice. For the first slice, ``start_byte_offset`` should -- be zero. -+ - Decoding is done at the frame granularity, - The OUTPUT buffer must contain all slices needed to decode the - frame. The OUTPUT buffer must also contain both fields. -+ This mode will be supported by devices that -+ parse the slice(s) header(s) in hardware. When this mode is -+ selected, the ``V4L2_CID_MPEG_VIDEO_H264_SLICE_PARAMS`` -+ control shall not be set. - - ``V4L2_CID_MPEG_VIDEO_H264_START_CODE (enum)`` - Specifies the H264 slice start code expected for each slice. -diff --git a/include/media/h264-ctrls.h b/include/media/h264-ctrls.h -index 77d0ec51ae43..e4cae02a765f 100644 ---- a/include/media/h264-ctrls.h -+++ b/include/media/h264-ctrls.h -@@ -163,9 +163,6 @@ struct v4l2_h264_reference { - }; - - struct v4l2_ctrl_h264_slice_params { -- /* Offset in bytes to the start of slice in the OUTPUT buffer. */ -- __u32 start_byte_offset; -- - /* Offset in bits to slice_data() from the beginning of this slice. */ - __u32 header_bit_size; - -@@ -224,7 +221,6 @@ struct v4l2_h264_dpb_entry { - - struct v4l2_ctrl_h264_decode_params { - struct v4l2_h264_dpb_entry dpb[V4L2_H264_NUM_DPB_ENTRIES]; -- __u16 num_slices; - __u16 nal_ref_idc; - __s32 top_field_order_cnt; - __s32 bottom_field_order_cnt; - -From 0ed1639eb2c39ddca4a54bf6132657d3e4e6c184 Mon Sep 17 00:00:00 2001 -From: Ezequiel Garcia -Date: Tue, 25 Aug 2020 05:52:36 +0200 -Subject: [PATCH] media: uapi: h264: Clean slice invariants syntax elements - -The H.264 specification requires in section 7.4.3 "Slice header semantics", -that the following values shall be the same in all slice headers: - - pic_parameter_set_id - frame_num - field_pic_flag - bottom_field_flag - idr_pic_id - pic_order_cnt_lsb - delta_pic_order_cnt_bottom - delta_pic_order_cnt[ 0 ] - delta_pic_order_cnt[ 1 ] - sp_for_switch_flag - slice_group_change_cycle - -These bitstream fields are part of the slice header, and therefore -passed redundantly on each slice. The purpose of the redundancy -is to make the codec fault-tolerant in network scenarios. - -This is of course not needed to be reflected in the V4L2 controls, -given the bitstream has already been parsed by applications. -Therefore, move the redundant fields to the per-frame decode -parameters control (DECODE_PARAMS). - -Field 'pic_parameter_set_id' is simply removed in this case, -because the PPS control must currently contain the active PPS. - -Syntax elements dec_ref_pic_marking() and those related -to pic order count, remain invariant as well, and therefore, -the fields dec_ref_pic_marking_bit_size and pic_order_cnt_bit_size -are also common to all slices. - -Signed-off-by: Ezequiel Garcia -Reviewed-by: Nicolas Dufresne -Tested-by: Jonas Karlman -Signed-off-by: Hans Verkuil -Signed-off-by: Mauro Carvalho Chehab -(cherry picked from commit d9358563179a7f01f9020ebbe201c7e54ba3af48) ---- - .../userspace-api/media/v4l/ext-ctrls-codec.rst | 86 +++++++++++----------- - drivers/media/v4l2-core/v4l2-ctrls.c | 7 ++ - drivers/media/v4l2-core/v4l2-h264.c | 8 +- - drivers/staging/media/hantro/hantro_g1_h264_dec.c | 21 +++--- - drivers/staging/media/hantro/hantro_h264.c | 3 +- - drivers/staging/media/rkvdec/rkvdec-h264.c | 6 +- - drivers/staging/media/sunxi/cedrus/cedrus_h264.c | 9 +-- - include/media/h264-ctrls.h | 39 +++++----- - include/media/v4l2-h264.h | 1 - - 9 files changed, 90 insertions(+), 90 deletions(-) - -diff --git a/Documentation/userspace-api/media/v4l/ext-ctrls-codec.rst b/Documentation/userspace-api/media/v4l/ext-ctrls-codec.rst -index 304b6012b358..4cd9fd9c5a89 100644 ---- a/Documentation/userspace-api/media/v4l/ext-ctrls-codec.rst -+++ b/Documentation/userspace-api/media/v4l/ext-ctrls-codec.rst -@@ -1766,44 +1766,12 @@ enum v4l2_mpeg_video_h264_hierarchical_coding_type - - * - __u8 - - ``slice_type`` - - -- * - __u8 -- - ``pic_parameter_set_id`` -- - - * - __u8 - - ``colour_plane_id`` - - - * - __u8 - - ``redundant_pic_cnt`` - - -- * - __u16 -- - ``frame_num`` -- - -- * - __u16 -- - ``idr_pic_id`` -- - -- * - __u16 -- - ``pic_order_cnt_lsb`` -- - -- * - __s32 -- - ``delta_pic_order_cnt_bottom`` -- - -- * - __s32 -- - ``delta_pic_order_cnt0`` -- - -- * - __s32 -- - ``delta_pic_order_cnt1`` -- - -- * - struct :c:type:`v4l2_h264_pred_weight_table` -- - ``pred_weight_table`` -- - -- * - __u32 -- - ``dec_ref_pic_marking_bit_size`` -- - Size in bits of the dec_ref_pic_marking() syntax element. -- * - __u32 -- - ``pic_order_cnt_bit_size`` -- - Combined size in bits of the picture order count related syntax -- elements: pic_order_cnt_lsb, delta_pic_order_cnt_bottom, -- delta_pic_order_cnt0, and delta_pic_order_cnt1. - * - __u8 - - ``cabac_init_idc`` - - -@@ -1830,9 +1798,9 @@ enum v4l2_mpeg_video_h264_hierarchical_coding_type - - - ``num_ref_idx_l1_active_minus1`` - - If num_ref_idx_active_override_flag is not set, this field must be - set to the value of num_ref_idx_l1_default_active_minus1. -- * - __u32 -- - ``slice_group_change_cycle`` -- - -+ * - __u8 -+ - ``reserved`` -+ - Applications and drivers must set this to zero. - * - struct :c:type:`v4l2_h264_reference` - - ``ref_pic_list0[32]`` - - Reference picture list after applying the per-slice modifications -@@ -1854,17 +1822,11 @@ enum v4l2_mpeg_video_h264_hierarchical_coding_type - - :stub-columns: 0 - :widths: 1 1 2 - -- * - ``V4L2_H264_SLICE_FLAG_FIELD_PIC`` -- - 0x00000001 -- - -- * - ``V4L2_H264_SLICE_FLAG_BOTTOM_FIELD`` -- - 0x00000002 -- - - * - ``V4L2_H264_SLICE_FLAG_DIRECT_SPATIAL_MV_PRED`` -- - 0x00000004 -+ - 0x00000001 - - - * - ``V4L2_H264_SLICE_FLAG_SP_FOR_SWITCH`` -- - 0x00000008 -+ - 0x00000002 - - - - ``V4L2_CID_MPEG_VIDEO_H264_PRED_WEIGHTS (struct)`` -@@ -1990,12 +1952,44 @@ enum v4l2_mpeg_video_h264_hierarchical_coding_type - - * - __u16 - - ``nal_ref_idc`` - - NAL reference ID value coming from the NAL Unit header -+ * - __u16 -+ - ``frame_num`` -+ - - * - __s32 - - ``top_field_order_cnt`` - - Picture Order Count for the coded top field - * - __s32 - - ``bottom_field_order_cnt`` - - Picture Order Count for the coded bottom field -+ * - __u16 -+ - ``idr_pic_id`` -+ - -+ * - __u16 -+ - ``pic_order_cnt_lsb`` -+ - -+ * - __s32 -+ - ``delta_pic_order_cnt_bottom`` -+ - -+ * - __s32 -+ - ``delta_pic_order_cnt0`` -+ - -+ * - __s32 -+ - ``delta_pic_order_cnt1`` -+ - -+ * - __u32 -+ - ``dec_ref_pic_marking_bit_size`` -+ - Size in bits of the dec_ref_pic_marking() syntax element. -+ * - __u32 -+ - ``pic_order_cnt_bit_size`` -+ - Combined size in bits of the picture order count related syntax -+ elements: pic_order_cnt_lsb, delta_pic_order_cnt_bottom, -+ delta_pic_order_cnt0, and delta_pic_order_cnt1. -+ * - __u32 -+ - ``slice_group_change_cycle`` -+ - -+ * - __u32 -+ - ``reserved`` -+ - Applications and drivers must set this to zero. - * - __u32 - - ``flags`` - - See :ref:`Decode Parameters Flags ` -@@ -2014,6 +2008,12 @@ enum v4l2_mpeg_video_h264_hierarchical_coding_type - - * - ``V4L2_H264_DECODE_PARAM_FLAG_IDR_PIC`` - - 0x00000001 - - That picture is an IDR picture -+ * - ``V4L2_H264_DECODE_PARAM_FLAG_FIELD_PIC`` -+ - 0x00000002 -+ - -+ * - ``V4L2_H264_DECODE_PARAM_FLAG_BOTTOM_FIELD`` -+ - 0x00000004 -+ - - - .. c:type:: v4l2_h264_dpb_entry - -diff --git a/drivers/media/v4l2-core/v4l2-ctrls.c b/drivers/media/v4l2-core/v4l2-ctrls.c -index 31dbe4222091..d4a6c0346c2a 100644 ---- a/drivers/media/v4l2-core/v4l2-ctrls.c -+++ b/drivers/media/v4l2-core/v4l2-ctrls.c -@@ -1737,6 +1737,7 @@ static int std_validate_compound(const struct v4l2_ctrl *ctrl, u32 idx, - { - struct v4l2_ctrl_mpeg2_slice_params *p_mpeg2_slice_params; - struct v4l2_ctrl_vp8_frame_header *p_vp8_frame_header; -+ struct v4l2_ctrl_h264_slice_params *p_h264_slice_params; - struct v4l2_ctrl_h264_decode_params *p_h264_dec_params; - struct v4l2_ctrl_hevc_sps *p_hevc_sps; - struct v4l2_ctrl_hevc_pps *p_hevc_pps; -@@ -1798,7 +1799,12 @@ static int std_validate_compound(const struct v4l2_ctrl *ctrl, u32 idx, - case V4L2_CTRL_TYPE_H264_PPS: - case V4L2_CTRL_TYPE_H264_SCALING_MATRIX: - case V4L2_CTRL_TYPE_H264_PRED_WEIGHTS: -+ break; -+ - case V4L2_CTRL_TYPE_H264_SLICE_PARAMS: -+ p_h264_slice_params = p; -+ -+ zero_reserved(*p_h264_slice_params); - break; - - case V4L2_CTRL_TYPE_H264_DECODE_PARAMS: -@@ -1810,6 +1816,7 @@ static int std_validate_compound(const struct v4l2_ctrl *ctrl, u32 idx, - - zero_reserved(*dpb_entry); - } -+ zero_reserved(*p_h264_dec_params); - break; - - case V4L2_CTRL_TYPE_VP8_FRAME_HEADER: -diff --git a/drivers/media/v4l2-core/v4l2-h264.c b/drivers/media/v4l2-core/v4l2-h264.c -index f4742408436b..5633a242520a 100644 ---- a/drivers/media/v4l2-core/v4l2-h264.c -+++ b/drivers/media/v4l2-core/v4l2-h264.c -@@ -18,14 +18,12 @@ - * - * @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]) - { -@@ -33,13 +31,13 @@ v4l2_h264_init_reflist_builder(struct v4l2_h264_reflist_builder *b, - unsigned int i; - - max_frame_num = 1 << (sps->log2_max_frame_num_minus4 + 4); -- cur_frame_num = slice_params->frame_num; -+ cur_frame_num = dec_params->frame_num; - - memset(b, 0, sizeof(*b)); -- if (!(slice_params->flags & V4L2_H264_SLICE_FLAG_FIELD_PIC)) -+ if (!(dec_params->flags & V4L2_H264_DECODE_PARAM_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) -+ else if (dec_params->flags & V4L2_H264_DECODE_PARAM_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; -diff --git a/drivers/staging/media/hantro/hantro_g1_h264_dec.c b/drivers/staging/media/hantro/hantro_g1_h264_dec.c -index 424c648ce9fc..f9839e9c6da5 100644 ---- a/drivers/staging/media/hantro/hantro_g1_h264_dec.c -+++ b/drivers/staging/media/hantro/hantro_g1_h264_dec.c -@@ -23,7 +23,6 @@ static void set_params(struct hantro_ctx *ctx) - { - const struct hantro_h264_dec_ctrls *ctrls = &ctx->h264_dec.ctrls; - const struct v4l2_ctrl_h264_decode_params *dec_param = ctrls->decode; -- const struct v4l2_ctrl_h264_slice_params *slices = ctrls->slices; - const struct v4l2_ctrl_h264_sps *sps = ctrls->sps; - const struct v4l2_ctrl_h264_pps *pps = ctrls->pps; - struct vb2_v4l2_buffer *src_buf = hantro_get_src_buf(ctx); -@@ -42,11 +41,11 @@ static void set_params(struct hantro_ctx *ctx) - - if (!(sps->flags & V4L2_H264_SPS_FLAG_FRAME_MBS_ONLY) && - (sps->flags & V4L2_H264_SPS_FLAG_MB_ADAPTIVE_FRAME_FIELD || -- slices[0].flags & V4L2_H264_SLICE_FLAG_FIELD_PIC)) -+ dec_param->flags & V4L2_H264_DECODE_PARAM_FLAG_FIELD_PIC)) - reg |= G1_REG_DEC_CTRL0_PIC_INTERLACE_E; -- if (slices[0].flags & V4L2_H264_SLICE_FLAG_FIELD_PIC) -+ if (dec_param->flags & V4L2_H264_DECODE_PARAM_FLAG_FIELD_PIC) - reg |= G1_REG_DEC_CTRL0_PIC_FIELDMODE_E; -- if (!(slices[0].flags & V4L2_H264_SLICE_FLAG_BOTTOM_FIELD)) -+ if (!(dec_param->flags & V4L2_H264_DECODE_PARAM_FLAG_BOTTOM_FIELD)) - reg |= G1_REG_DEC_CTRL0_PIC_TOPFIELD_E; - vdpu_write_relaxed(vpu, reg, G1_REG_DEC_CTRL0); - -@@ -75,7 +74,7 @@ static void set_params(struct hantro_ctx *ctx) - - /* Decoder control register 4. */ - reg = G1_REG_DEC_CTRL4_FRAMENUM_LEN(sps->log2_max_frame_num_minus4 + 4) | -- G1_REG_DEC_CTRL4_FRAMENUM(slices[0].frame_num) | -+ G1_REG_DEC_CTRL4_FRAMENUM(dec_param->frame_num) | - G1_REG_DEC_CTRL4_WEIGHT_BIPR_IDC(pps->weighted_bipred_idc); - if (pps->flags & V4L2_H264_PPS_FLAG_ENTROPY_CODING_MODE) - reg |= G1_REG_DEC_CTRL4_CABAC_E; -@@ -88,8 +87,8 @@ static void set_params(struct hantro_ctx *ctx) - vdpu_write_relaxed(vpu, reg, G1_REG_DEC_CTRL4); - - /* Decoder control register 5. */ -- reg = G1_REG_DEC_CTRL5_REFPIC_MK_LEN(slices[0].dec_ref_pic_marking_bit_size) | -- G1_REG_DEC_CTRL5_IDR_PIC_ID(slices[0].idr_pic_id); -+ reg = G1_REG_DEC_CTRL5_REFPIC_MK_LEN(dec_param->dec_ref_pic_marking_bit_size) | -+ G1_REG_DEC_CTRL5_IDR_PIC_ID(dec_param->idr_pic_id); - if (pps->flags & V4L2_H264_PPS_FLAG_CONSTRAINED_INTRA_PRED) - reg |= G1_REG_DEC_CTRL5_CONST_INTRA_E; - if (pps->flags & V4L2_H264_PPS_FLAG_DEBLOCKING_FILTER_CONTROL_PRESENT) -@@ -103,10 +102,10 @@ static void set_params(struct hantro_ctx *ctx) - vdpu_write_relaxed(vpu, reg, G1_REG_DEC_CTRL5); - - /* Decoder control register 6. */ -- reg = G1_REG_DEC_CTRL6_PPS_ID(slices[0].pic_parameter_set_id) | -+ reg = G1_REG_DEC_CTRL6_PPS_ID(pps->pic_parameter_set_id) | - G1_REG_DEC_CTRL6_REFIDX0_ACTIVE(pps->num_ref_idx_l0_default_active_minus1 + 1) | - G1_REG_DEC_CTRL6_REFIDX1_ACTIVE(pps->num_ref_idx_l1_default_active_minus1 + 1) | -- G1_REG_DEC_CTRL6_POC_LENGTH(slices[0].pic_order_cnt_bit_size); -+ G1_REG_DEC_CTRL6_POC_LENGTH(dec_param->pic_order_cnt_bit_size); - vdpu_write_relaxed(vpu, reg, G1_REG_DEC_CTRL6); - - /* Error concealment register. */ -@@ -246,7 +245,7 @@ static void set_buffers(struct hantro_ctx *ctx) - /* Destination (decoded frame) buffer. */ - dst_dma = hantro_get_dec_buf_addr(ctx, &dst_buf->vb2_buf); - /* Adjust dma addr to start at second line for bottom field */ -- if (ctrls->slices[0].flags & V4L2_H264_SLICE_FLAG_BOTTOM_FIELD) -+ if (ctrls->decode->flags & V4L2_H264_DECODE_PARAM_FLAG_BOTTOM_FIELD) - offset = ALIGN(ctx->src_fmt.width, MB_DIM); - vdpu_write_relaxed(vpu, dst_dma + offset, G1_REG_ADDR_DST); - -@@ -265,7 +264,7 @@ static void set_buffers(struct hantro_ctx *ctx) - * DMV buffer is split in two for field encoded frames, - * adjust offset for bottom field - */ -- if (ctrls->slices[0].flags & V4L2_H264_SLICE_FLAG_BOTTOM_FIELD) -+ if (ctrls->decode->flags & V4L2_H264_DECODE_PARAM_FLAG_BOTTOM_FIELD) - offset += 32 * MB_WIDTH(ctx->src_fmt.width) * - MB_HEIGHT(ctx->src_fmt.height); - vdpu_write_relaxed(vpu, dst_dma + offset, G1_REG_ADDR_DIR_MV); -diff --git a/drivers/staging/media/hantro/hantro_h264.c b/drivers/staging/media/hantro/hantro_h264.c -index 6dcd47bd9ed3..7578a4fc1b16 100644 ---- a/drivers/staging/media/hantro/hantro_h264.c -+++ b/drivers/staging/media/hantro/hantro_h264.c -@@ -372,8 +372,7 @@ int hantro_h264_dec_prepare_run(struct hantro_ctx *ctx) - - /* Build the P/B{0,1} ref lists. */ - v4l2_h264_init_reflist_builder(&reflist_builder, ctrls->decode, -- &ctrls->slices[0], ctrls->sps, -- ctx->h264_dec.dpb); -+ 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); -diff --git a/drivers/staging/media/rkvdec/rkvdec-h264.c b/drivers/staging/media/rkvdec/rkvdec-h264.c -index d1f2715f30ae..90f211839be2 100644 ---- a/drivers/staging/media/rkvdec/rkvdec-h264.c -+++ b/drivers/staging/media/rkvdec/rkvdec-h264.c -@@ -730,7 +730,6 @@ 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; -@@ -754,7 +753,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 < dec_params->frame_num) { - p[i] = dpb[i].frame_num; - continue; - } -@@ -1094,8 +1093,7 @@ static int rkvdec_h264_run(struct rkvdec_ctx *ctx) - - /* 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); -+ 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, -diff --git a/drivers/staging/media/sunxi/cedrus/cedrus_h264.c b/drivers/staging/media/sunxi/cedrus/cedrus_h264.c -index 7d9bd5860a1b..c8f626fdd3dd 100644 ---- a/drivers/staging/media/sunxi/cedrus/cedrus_h264.c -+++ b/drivers/staging/media/sunxi/cedrus/cedrus_h264.c -@@ -95,7 +95,6 @@ static void cedrus_write_frame_list(struct cedrus_ctx *ctx, - { - struct cedrus_h264_sram_ref_pic pic_list[CEDRUS_H264_FRAME_NUM]; - const struct v4l2_ctrl_h264_decode_params *decode = run->h264.decode_params; -- const struct v4l2_ctrl_h264_slice_params *slice = run->h264.slice_params; - const struct v4l2_ctrl_h264_sps *sps = run->h264.sps; - struct vb2_queue *cap_q; - struct cedrus_buffer *output_buf; -@@ -144,7 +143,7 @@ static void cedrus_write_frame_list(struct cedrus_ctx *ctx, - output_buf = vb2_to_cedrus_buffer(&run->dst->vb2_buf); - output_buf->codec.h264.position = position; - -- if (slice->flags & V4L2_H264_SLICE_FLAG_FIELD_PIC) -+ if (decode->flags & V4L2_H264_DECODE_PARAM_FLAG_FIELD_PIC) - output_buf->codec.h264.pic_type = CEDRUS_H264_PIC_TYPE_FIELD; - else if (sps->flags & V4L2_H264_SPS_FLAG_MB_ADAPTIVE_FRAME_FIELD) - output_buf->codec.h264.pic_type = CEDRUS_H264_PIC_TYPE_MBAFF; -@@ -407,7 +406,7 @@ static void cedrus_set_params(struct cedrus_ctx *ctx, - reg |= VE_H264_SPS_DIRECT_8X8_INFERENCE; - cedrus_write(dev, VE_H264_SPS, reg); - -- mbaff_pic = !(slice->flags & V4L2_H264_SLICE_FLAG_FIELD_PIC) && -+ mbaff_pic = !(decode->flags & V4L2_H264_DECODE_PARAM_FLAG_FIELD_PIC) && - (sps->flags & V4L2_H264_SPS_FLAG_MB_ADAPTIVE_FRAME_FIELD); - pic_width_in_mbs = sps->pic_width_in_mbs_minus1 + 1; - -@@ -421,9 +420,9 @@ static void cedrus_set_params(struct cedrus_ctx *ctx, - reg |= slice->cabac_init_idc & 0x3; - if (ctx->fh.m2m_ctx->new_frame) - reg |= VE_H264_SHS_FIRST_SLICE_IN_PIC; -- if (slice->flags & V4L2_H264_SLICE_FLAG_FIELD_PIC) -+ if (decode->flags & V4L2_H264_DECODE_PARAM_FLAG_FIELD_PIC) - reg |= VE_H264_SHS_FIELD_PIC; -- if (slice->flags & V4L2_H264_SLICE_FLAG_BOTTOM_FIELD) -+ if (decode->flags & V4L2_H264_DECODE_PARAM_FLAG_BOTTOM_FIELD) - reg |= VE_H264_SHS_BOTTOM_FIELD; - if (slice->flags & V4L2_H264_SLICE_FLAG_DIRECT_SPATIAL_MV_PRED) - reg |= VE_H264_SHS_DIRECT_SPATIAL_MV_PRED; -diff --git a/include/media/h264-ctrls.h b/include/media/h264-ctrls.h -index e4cae02a765f..0c15ff938873 100644 ---- a/include/media/h264-ctrls.h -+++ b/include/media/h264-ctrls.h -@@ -146,10 +146,8 @@ struct v4l2_ctrl_h264_pred_weights { - #define V4L2_H264_SLICE_TYPE_SP 3 - #define V4L2_H264_SLICE_TYPE_SI 4 - --#define V4L2_H264_SLICE_FLAG_FIELD_PIC 0x01 --#define V4L2_H264_SLICE_FLAG_BOTTOM_FIELD 0x02 --#define V4L2_H264_SLICE_FLAG_DIRECT_SPATIAL_MV_PRED 0x04 --#define V4L2_H264_SLICE_FLAG_SP_FOR_SWITCH 0x08 -+#define V4L2_H264_SLICE_FLAG_DIRECT_SPATIAL_MV_PRED 0x01 -+#define V4L2_H264_SLICE_FLAG_SP_FOR_SWITCH 0x02 - - #define V4L2_H264_TOP_FIELD_REF 0x1 - #define V4L2_H264_BOTTOM_FIELD_REF 0x2 -@@ -169,21 +167,8 @@ struct v4l2_ctrl_h264_slice_params { - __u32 first_mb_in_slice; - - __u8 slice_type; -- __u8 pic_parameter_set_id; - __u8 colour_plane_id; - __u8 redundant_pic_cnt; -- __u16 frame_num; -- __u16 idr_pic_id; -- __u16 pic_order_cnt_lsb; -- __s32 delta_pic_order_cnt_bottom; -- __s32 delta_pic_order_cnt0; -- __s32 delta_pic_order_cnt1; -- -- /* Size in bits of dec_ref_pic_marking() syntax element. */ -- __u32 dec_ref_pic_marking_bit_size; -- /* Size in bits of pic order count syntax. */ -- __u32 pic_order_cnt_bit_size; -- - __u8 cabac_init_idc; - __s8 slice_qp_delta; - __s8 slice_qs_delta; -@@ -192,7 +177,8 @@ struct v4l2_ctrl_h264_slice_params { - __s8 slice_beta_offset_div2; - __u8 num_ref_idx_l0_active_minus1; - __u8 num_ref_idx_l1_active_minus1; -- __u32 slice_group_change_cycle; -+ -+ __u8 reserved; - - struct v4l2_h264_reference ref_pic_list0[V4L2_H264_REF_LIST_LEN]; - struct v4l2_h264_reference ref_pic_list1[V4L2_H264_REF_LIST_LEN]; -@@ -217,13 +203,28 @@ struct v4l2_h264_dpb_entry { - __u32 flags; /* V4L2_H264_DPB_ENTRY_FLAG_* */ - }; - --#define V4L2_H264_DECODE_PARAM_FLAG_IDR_PIC 0x01 -+#define V4L2_H264_DECODE_PARAM_FLAG_IDR_PIC 0x01 -+#define V4L2_H264_DECODE_PARAM_FLAG_FIELD_PIC 0x02 -+#define V4L2_H264_DECODE_PARAM_FLAG_BOTTOM_FIELD 0x04 - - struct v4l2_ctrl_h264_decode_params { - struct v4l2_h264_dpb_entry dpb[V4L2_H264_NUM_DPB_ENTRIES]; - __u16 nal_ref_idc; -+ __u16 frame_num; - __s32 top_field_order_cnt; - __s32 bottom_field_order_cnt; -+ __u16 idr_pic_id; -+ __u16 pic_order_cnt_lsb; -+ __s32 delta_pic_order_cnt_bottom; -+ __s32 delta_pic_order_cnt0; -+ __s32 delta_pic_order_cnt1; -+ /* Size in bits of dec_ref_pic_marking() syntax element. */ -+ __u32 dec_ref_pic_marking_bit_size; -+ /* Size in bits of pic order count syntax. */ -+ __u32 pic_order_cnt_bit_size; -+ __u32 slice_group_change_cycle; -+ -+ __u32 reserved; - __u32 flags; /* V4L2_H264_DECODE_PARAM_FLAG_* */ - }; - -diff --git a/include/media/v4l2-h264.h b/include/media/v4l2-h264.h -index 1a5f26fc2a9a..f08ba181263d 100644 ---- a/include/media/v4l2-h264.h -+++ b/include/media/v4l2-h264.h -@@ -44,7 +44,6 @@ struct v4l2_h264_reflist_builder { - 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]); - - -From ca371b762ca1278521c8032a478a3ad3f9e03a18 Mon Sep 17 00:00:00 2001 -From: Ezequiel Garcia -Date: Tue, 25 Aug 2020 05:52:37 +0200 -Subject: [PATCH] media: uapi: h264: Rename and clarify - PPS_FLAG_SCALING_MATRIX_PRESENT - -Applications are expected to fill V4L2_CID_MPEG_VIDEO_H264_SCALING_MATRIX -if a non-flat scaling matrix applies to the picture. This is the case if -SPS scaling_matrix_present_flag or PPS pic_scaling_matrix_present_flag -are set, and should be handled by applications. - -On one hand, the PPS bitstream syntax element signals the presence of a -Picture scaling matrix modifying the Sequence (SPS) scaling matrix. -On the other hand, our flag should indicate if the scaling matrix -V4L2 control is applicable to this request. - -Rename the flag from PPS_FLAG_PIC_SCALING_MATRIX_PRESENT to -PPS_FLAG_SCALING_MATRIX_PRESENT, to avoid mixing this flag with -bitstream syntax element pic_scaling_matrix_present_flag, -and clarify the meaning of our flag. - -Signed-off-by: Ezequiel Garcia -Tested-by: Jonas Karlman -Signed-off-by: Hans Verkuil -Signed-off-by: Mauro Carvalho Chehab -(cherry picked from commit 54889c51b833d236228f983be16212fbe806bb89) ---- - Documentation/userspace-api/media/v4l/ext-ctrls-codec.rst | 5 +++-- - include/media/h264-ctrls.h | 2 +- - 2 files changed, 4 insertions(+), 3 deletions(-) - -diff --git a/Documentation/userspace-api/media/v4l/ext-ctrls-codec.rst b/Documentation/userspace-api/media/v4l/ext-ctrls-codec.rst -index 4cd9fd9c5a89..e2b94b1d0ab0 100644 ---- a/Documentation/userspace-api/media/v4l/ext-ctrls-codec.rst -+++ b/Documentation/userspace-api/media/v4l/ext-ctrls-codec.rst -@@ -1695,9 +1695,10 @@ enum v4l2_mpeg_video_h264_hierarchical_coding_type - - * - ``V4L2_H264_PPS_FLAG_TRANSFORM_8X8_MODE`` - - 0x00000040 - - -- * - ``V4L2_H264_PPS_FLAG_PIC_SCALING_MATRIX_PRESENT`` -+ * - ``V4L2_H264_PPS_FLAG_SCALING_MATRIX_PRESENT`` - - 0x00000080 -- - -+ - Indicates that ``V4L2_CID_MPEG_VIDEO_H264_SCALING_MATRIX`` -+ must be used for this picture. - - ``V4L2_CID_MPEG_VIDEO_H264_SCALING_MATRIX (struct)`` - Specifies the scaling matrix (as extracted from the bitstream) for -diff --git a/include/media/h264-ctrls.h b/include/media/h264-ctrls.h -index 0c15ff938873..ec4799154438 100644 ---- a/include/media/h264-ctrls.h -+++ b/include/media/h264-ctrls.h -@@ -99,7 +99,7 @@ struct v4l2_ctrl_h264_sps { - #define V4L2_H264_PPS_FLAG_CONSTRAINED_INTRA_PRED 0x0010 - #define V4L2_H264_PPS_FLAG_REDUNDANT_PIC_CNT_PRESENT 0x0020 - #define V4L2_H264_PPS_FLAG_TRANSFORM_8X8_MODE 0x0040 --#define V4L2_H264_PPS_FLAG_PIC_SCALING_MATRIX_PRESENT 0x0080 -+#define V4L2_H264_PPS_FLAG_SCALING_MATRIX_PRESENT 0x0080 - - struct v4l2_ctrl_h264_pps { - __u8 pic_parameter_set_id; - -From d8858326adbebde9fa273528c6d03970b6b50168 Mon Sep 17 00:00:00 2001 -From: Ezequiel Garcia -Date: Tue, 25 Aug 2020 05:52:38 +0200 -Subject: [PATCH] media: hantro: Don't require unneeded H264_SLICE_PARAMS - -Now that slice invariant parameters have been moved, -the driver no longer needs this control, so drop it. - -Signed-off-by: Ezequiel Garcia -Tested-by: Jonas Karlman -Signed-off-by: Hans Verkuil -Signed-off-by: Mauro Carvalho Chehab -(cherry picked from commit 057c4452894a38e4cc256858425b2c756003a92f) ---- - drivers/staging/media/hantro/hantro_drv.c | 5 ----- - drivers/staging/media/hantro/hantro_h264.c | 5 ----- - drivers/staging/media/hantro/hantro_hw.h | 2 -- - 3 files changed, 12 deletions(-) - -diff --git a/drivers/staging/media/hantro/hantro_drv.c b/drivers/staging/media/hantro/hantro_drv.c -index 34797507f214..3cd00cc0a364 100644 ---- a/drivers/staging/media/hantro/hantro_drv.c -+++ b/drivers/staging/media/hantro/hantro_drv.c -@@ -306,11 +306,6 @@ static const struct hantro_ctrl controls[] = { - .cfg = { - .id = V4L2_CID_MPEG_VIDEO_H264_DECODE_PARAMS, - }, -- }, { -- .codec = HANTRO_H264_DECODER, -- .cfg = { -- .id = V4L2_CID_MPEG_VIDEO_H264_SLICE_PARAMS, -- }, - }, { - .codec = HANTRO_H264_DECODER, - .cfg = { -diff --git a/drivers/staging/media/hantro/hantro_h264.c b/drivers/staging/media/hantro/hantro_h264.c -index 7578a4fc1b16..089bfa9c625b 100644 ---- a/drivers/staging/media/hantro/hantro_h264.c -+++ b/drivers/staging/media/hantro/hantro_h264.c -@@ -349,11 +349,6 @@ int hantro_h264_dec_prepare_run(struct hantro_ctx *ctx) - if (WARN_ON(!ctrls->decode)) - return -EINVAL; - -- ctrls->slices = -- hantro_get_ctrl(ctx, V4L2_CID_MPEG_VIDEO_H264_SLICE_PARAMS); -- if (WARN_ON(!ctrls->slices)) -- return -EINVAL; -- - ctrls->sps = - hantro_get_ctrl(ctx, V4L2_CID_MPEG_VIDEO_H264_SPS); - if (WARN_ON(!ctrls->sps)) -diff --git a/drivers/staging/media/hantro/hantro_hw.h b/drivers/staging/media/hantro/hantro_hw.h -index f066de6b592d..219283a06f52 100644 ---- a/drivers/staging/media/hantro/hantro_hw.h -+++ b/drivers/staging/media/hantro/hantro_hw.h -@@ -56,14 +56,12 @@ struct hantro_jpeg_enc_hw_ctx { - * struct hantro_h264_dec_ctrls - * @decode: Decode params - * @scaling: Scaling info -- * @slice: Slice params - * @sps: SPS info - * @pps: PPS info - */ - struct hantro_h264_dec_ctrls { - const struct v4l2_ctrl_h264_decode_params *decode; - const struct v4l2_ctrl_h264_scaling_matrix *scaling; -- const struct v4l2_ctrl_h264_slice_params *slices; - const struct v4l2_ctrl_h264_sps *sps; - const struct v4l2_ctrl_h264_pps *pps; - }; - -From a41936be0e44cd4317a6cce088eb6625aef96ac5 Mon Sep 17 00:00:00 2001 -From: Ezequiel Garcia -Date: Tue, 25 Aug 2020 05:52:39 +0200 -Subject: [PATCH] media: rkvdec: Don't require unneeded H264_SLICE_PARAMS - -Now that slice invariant parameters have been moved, -the driver no longer needs this control, so drop it. - -Signed-off-by: Ezequiel Garcia -Reviewed-by: Jonas Karlman -Tested-by: Jonas Karlman -Signed-off-by: Hans Verkuil -Signed-off-by: Mauro Carvalho Chehab -(cherry picked from commit a52b29e8d21d6c6463ff40e862107da0717a0840) ---- - drivers/staging/media/rkvdec/rkvdec-h264.c | 4 ---- - drivers/staging/media/rkvdec/rkvdec.c | 5 ----- - 2 files changed, 9 deletions(-) - -diff --git a/drivers/staging/media/rkvdec/rkvdec-h264.c b/drivers/staging/media/rkvdec/rkvdec-h264.c -index 90f211839be2..c45cd1617b3b 100644 ---- a/drivers/staging/media/rkvdec/rkvdec-h264.c -+++ b/drivers/staging/media/rkvdec/rkvdec-h264.c -@@ -109,7 +109,6 @@ struct rkvdec_h264_reflists { - 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; -@@ -1066,9 +1065,6 @@ static void rkvdec_h264_run_preamble(struct rkvdec_ctx *ctx, - 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; -diff --git a/drivers/staging/media/rkvdec/rkvdec.c b/drivers/staging/media/rkvdec/rkvdec.c -index c8151328fb70..7c5129593921 100644 ---- a/drivers/staging/media/rkvdec/rkvdec.c -+++ b/drivers/staging/media/rkvdec/rkvdec.c -@@ -59,11 +59,6 @@ static const struct rkvdec_ctrl_desc rkvdec_h264_ctrl_descs[] = { - .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, - -From 46d93c497a135bbebf8a46e457cbb1ccbc65187e Mon Sep 17 00:00:00 2001 -From: Jernej Skrabec -Date: Tue, 25 Aug 2020 05:52:40 +0200 -Subject: [PATCH] media: cedrus: h264: Properly configure reference field - -When interlaced H264 content is being decoded, references must indicate -which field is being referenced. Currently this was done by checking -capture buffer flags. However, that is not correct because capture -buffer may hold both fields. - -Fix this by checking newly introduced flags in reference lists. - -Signed-off-by: Jernej Skrabec -Reviewed-by: Nicolas Dufresne -Signed-off-by: Hans Verkuil -Signed-off-by: Mauro Carvalho Chehab -(cherry picked from commit cfc8c3ed533e650270152f293a3536f3ca0e7053) ---- - drivers/staging/media/sunxi/cedrus/cedrus_h264.c | 6 ++---- - 1 file changed, 2 insertions(+), 4 deletions(-) - -diff --git a/drivers/staging/media/sunxi/cedrus/cedrus_h264.c b/drivers/staging/media/sunxi/cedrus/cedrus_h264.c -index c8f626fdd3dd..1e89a8438f36 100644 ---- a/drivers/staging/media/sunxi/cedrus/cedrus_h264.c -+++ b/drivers/staging/media/sunxi/cedrus/cedrus_h264.c -@@ -182,7 +182,6 @@ static void _cedrus_write_ref_list(struct cedrus_ctx *ctx, - for (i = 0; i < num_ref; i++) { - const struct v4l2_h264_dpb_entry *dpb; - const struct cedrus_buffer *cedrus_buf; -- const struct vb2_v4l2_buffer *ref_buf; - unsigned int position; - int buf_idx; - u8 dpb_idx; -@@ -197,12 +196,11 @@ static void _cedrus_write_ref_list(struct cedrus_ctx *ctx, - if (buf_idx < 0) - continue; - -- ref_buf = to_vb2_v4l2_buffer(cap_q->bufs[buf_idx]); -- cedrus_buf = vb2_v4l2_to_cedrus_buffer(ref_buf); -+ cedrus_buf = vb2_to_cedrus_buffer(cap_q->bufs[buf_idx]); - position = cedrus_buf->codec.h264.position; - - sram_array[i] |= position << 1; -- if (ref_buf->field == V4L2_FIELD_BOTTOM) -+ if (ref_list[i].fields & V4L2_H264_BOTTOM_FIELD_REF) - sram_array[i] |= BIT(0); - } - - -From 639f50ba7ef39ae5c7e3d954c4eb45e798d807e1 Mon Sep 17 00:00:00 2001 -From: Jernej Skrabec -Date: Tue, 25 Aug 2020 05:52:41 +0200 -Subject: [PATCH] media: cedrus: h264: Fix frame list construction - -Current frame list construction algorithm assumes that decoded image -will be output into its own buffer. That is true for progressive content -but not for interlaced where each field is decoded separately into same -buffer. - -Fix that by checking if capture buffer is listed in DPB. If it is, reuse -it. - -Signed-off-by: Jernej Skrabec -Signed-off-by: Hans Verkuil -Signed-off-by: Mauro Carvalho Chehab -(cherry picked from commit 46e8893e72b43d10f5cad92355b36a7babe83724) ---- - drivers/staging/media/sunxi/cedrus/cedrus_h264.c | 15 +++++++++------ - 1 file changed, 9 insertions(+), 6 deletions(-) - -diff --git a/drivers/staging/media/sunxi/cedrus/cedrus_h264.c b/drivers/staging/media/sunxi/cedrus/cedrus_h264.c -index 1e89a8438f36..fe041b444385 100644 ---- a/drivers/staging/media/sunxi/cedrus/cedrus_h264.c -+++ b/drivers/staging/media/sunxi/cedrus/cedrus_h264.c -@@ -101,7 +101,7 @@ static void cedrus_write_frame_list(struct cedrus_ctx *ctx, - struct cedrus_dev *dev = ctx->dev; - unsigned long used_dpbs = 0; - unsigned int position; -- unsigned int output = 0; -+ int output = -1; - unsigned int i; - - cap_q = v4l2_m2m_get_vq(ctx->fh.m2m_ctx, V4L2_BUF_TYPE_VIDEO_CAPTURE); -@@ -124,6 +124,11 @@ static void cedrus_write_frame_list(struct cedrus_ctx *ctx, - position = cedrus_buf->codec.h264.position; - used_dpbs |= BIT(position); - -+ if (run->dst->vb2_buf.timestamp == dpb->reference_ts) { -+ output = position; -+ continue; -+ } -+ - if (!(dpb->flags & V4L2_H264_DPB_ENTRY_FLAG_ACTIVE)) - continue; - -@@ -131,13 +136,11 @@ static void cedrus_write_frame_list(struct cedrus_ctx *ctx, - dpb->top_field_order_cnt, - dpb->bottom_field_order_cnt, - &pic_list[position]); -- -- output = max(position, output); - } - -- position = find_next_zero_bit(&used_dpbs, CEDRUS_H264_FRAME_NUM, -- output); -- if (position >= CEDRUS_H264_FRAME_NUM) -+ if (output >= 0) -+ position = output; -+ else - position = find_first_zero_bit(&used_dpbs, CEDRUS_H264_FRAME_NUM); - - output_buf = vb2_to_cedrus_buffer(&run->dst->vb2_buf); - -From 8fcba25193bcdb227cd399ef8f4fff04bd296aa6 Mon Sep 17 00:00:00 2001 -From: Ezequiel Garcia -Date: Tue, 25 Aug 2020 05:52:42 +0200 -Subject: [PATCH] media: rkvdec: Drop unneeded per_request driver-specific - control flag - -Currently, the drivers makes no distinction between per_request -and mandatory, as both are used in the same request validate check. - -The driver only cares to know if a given control is -required to be part of a request, so only one flag is needed. - -Signed-off-by: Ezequiel Garcia -Tested-by: Jonas Karlman -Signed-off-by: Hans Verkuil -Signed-off-by: Mauro Carvalho Chehab -(cherry picked from commit d3951cfc9bee5b1d4282c2f6b9458b4a94929eee) ---- - drivers/staging/media/rkvdec/rkvdec.c | 8 +------- - drivers/staging/media/rkvdec/rkvdec.h | 1 - - 2 files changed, 1 insertion(+), 8 deletions(-) - -diff --git a/drivers/staging/media/rkvdec/rkvdec.c b/drivers/staging/media/rkvdec/rkvdec.c -index 7c5129593921..9f59dfb62d3f 100644 ---- a/drivers/staging/media/rkvdec/rkvdec.c -+++ b/drivers/staging/media/rkvdec/rkvdec.c -@@ -55,35 +55,29 @@ static const struct v4l2_ctrl_ops rkvdec_ctrl_ops = { - - 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_SPS, - .cfg.ops = &rkvdec_ctrl_ops, - }, - { -- .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, -@@ -615,7 +609,7 @@ static int rkvdec_request_validate(struct media_request *req) - u32 id = ctrls->ctrls[i].cfg.id; - struct v4l2_ctrl *ctrl; - -- if (!ctrls->ctrls[i].per_request || !ctrls->ctrls[i].mandatory) -+ if (!ctrls->ctrls[i].mandatory) - continue; - - ctrl = v4l2_ctrl_request_hdl_ctrl_find(hdl, id); -diff --git a/drivers/staging/media/rkvdec/rkvdec.h b/drivers/staging/media/rkvdec/rkvdec.h -index 2fc9f46b6910..77a137cca88e 100644 ---- a/drivers/staging/media/rkvdec/rkvdec.h -+++ b/drivers/staging/media/rkvdec/rkvdec.h -@@ -25,7 +25,6 @@ - struct rkvdec_ctx; - - struct rkvdec_ctrl_desc { -- u32 per_request : 1; - u32 mandatory : 1; - struct v4l2_ctrl_config cfg; - }; - -From 6b4ad3335d579f5a867a7a320dad4e47f0a82e53 Mon Sep 17 00:00:00 2001 -From: Ezequiel Garcia -Date: Tue, 25 Aug 2020 05:52:43 +0200 -Subject: [PATCH] media: rkvdec: Use H264_SCALING_MATRIX only when required - -Baseline, Main and Extended profiles are specified to -not support a scaling matrix. Also, High profiles -can optionally specify a scaling matrix, using -SPS and PPS NAL units. - -To meet this expectation, applications are required to -set the V4L2_CID_MPEG_VIDEO_H264_SCALING_MATRIX control -and set the V4L2_H264_PPS_FLAG_SCALING_MATRIX_PRESENT -flag only when a scaling matrix is specified for a picture. - -Implement this on rkvdec, which has hardware support for this -case. - -Signed-off-by: Ezequiel Garcia -Tested-by: Jonas Karlman -Signed-off-by: Hans Verkuil -Signed-off-by: Mauro Carvalho Chehab -(cherry picked from commit fd902918e3e6c70e771e14e611950f361a78cfc5) ---- - drivers/staging/media/rkvdec/rkvdec-h264.c | 10 +++++++--- - drivers/staging/media/rkvdec/rkvdec.c | 1 - - 2 files changed, 7 insertions(+), 4 deletions(-) - -diff --git a/drivers/staging/media/rkvdec/rkvdec-h264.c b/drivers/staging/media/rkvdec/rkvdec-h264.c -index c45cd1617b3b..7cc3b478a5f4 100644 ---- a/drivers/staging/media/rkvdec/rkvdec-h264.c -+++ b/drivers/staging/media/rkvdec/rkvdec-h264.c -@@ -708,9 +708,9 @@ static void assemble_hw_pps(struct rkvdec_ctx *ctx, - 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); -- -+ WRITE_PPS(!!(pps->flags & V4L2_H264_PPS_FLAG_SCALING_MATRIX_PRESENT), -+ SCALING_LIST_ENABLE_FLAG); -+ /* To be on the safe side, program the scaling matrix address */ - 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); -@@ -792,9 +792,13 @@ static void assemble_hw_scaling_list(struct rkvdec_ctx *ctx, - struct rkvdec_h264_run *run) - { - const struct v4l2_ctrl_h264_scaling_matrix *scaling = run->scaling_matrix; -+ const struct v4l2_ctrl_h264_pps *pps = run->pps; - struct rkvdec_h264_ctx *h264_ctx = ctx->priv; - struct rkvdec_h264_priv_tbl *tbl = h264_ctx->priv_tbl.cpu; - -+ if (!(pps->flags & V4L2_H264_PPS_FLAG_SCALING_MATRIX_PRESENT)) -+ return; -+ - BUILD_BUG_ON(sizeof(tbl->scaling_list.scaling_list_4x4) != - sizeof(scaling->scaling_list_4x4)); - BUILD_BUG_ON(sizeof(tbl->scaling_list.scaling_list_8x8) != -diff --git a/drivers/staging/media/rkvdec/rkvdec.c b/drivers/staging/media/rkvdec/rkvdec.c -index 9f59dfb62d3f..d25c4a37e2af 100644 ---- a/drivers/staging/media/rkvdec/rkvdec.c -+++ b/drivers/staging/media/rkvdec/rkvdec.c -@@ -68,7 +68,6 @@ static const struct rkvdec_ctrl_desc rkvdec_h264_ctrl_descs[] = { - .cfg.id = V4L2_CID_MPEG_VIDEO_H264_PPS, - }, - { -- .mandatory = true, - .cfg.id = V4L2_CID_MPEG_VIDEO_H264_SCALING_MATRIX, - }, - { - -From 2d1e9d1ee8c70cc956e5d4356fa4b0db16475639 Mon Sep 17 00:00:00 2001 -From: Ezequiel Garcia -Date: Tue, 25 Aug 2020 05:52:44 +0200 -Subject: [PATCH] media: hantro: Use H264_SCALING_MATRIX only when required - -Baseline, Main and Extended profiles are specified to -not support a scaling matrix. Also, High profiles -can optionally specify a scaling matrix, using -SPS and PPS NAL units. - -To meet this expectation, applications are required to -set the V4L2_CID_MPEG_VIDEO_H264_SCALING_MATRIX control -and set the V4L2_H264_PPS_FLAG_SCALING_MATRIX_PRESENT -flag only when a scaling matrix is specified for a picture. - -Implement this on hantro, which has hardware support for this -case. - -Signed-off-by: Ezequiel Garcia -Tested-by: Jonas Karlman -Signed-off-by: Hans Verkuil -Signed-off-by: Mauro Carvalho Chehab -(cherry picked from commit e6de6b3fac5f70cbf37eaa671d1bfeb2478469d9) ---- - drivers/staging/media/hantro/hantro_g1_h264_dec.c | 5 ++--- - drivers/staging/media/hantro/hantro_h264.c | 4 ++++ - 2 files changed, 6 insertions(+), 3 deletions(-) - -diff --git a/drivers/staging/media/hantro/hantro_g1_h264_dec.c b/drivers/staging/media/hantro/hantro_g1_h264_dec.c -index f9839e9c6da5..845bef73d218 100644 ---- a/drivers/staging/media/hantro/hantro_g1_h264_dec.c -+++ b/drivers/staging/media/hantro/hantro_g1_h264_dec.c -@@ -59,9 +59,8 @@ static void set_params(struct hantro_ctx *ctx) - reg = G1_REG_DEC_CTRL2_CH_QP_OFFSET(pps->chroma_qp_index_offset) | - G1_REG_DEC_CTRL2_CH_QP_OFFSET2(pps->second_chroma_qp_index_offset); - -- /* always use the matrix sent from userspace */ -- reg |= G1_REG_DEC_CTRL2_TYPE1_QUANT_E; -- -+ if (pps->flags & V4L2_H264_PPS_FLAG_SCALING_MATRIX_PRESENT) -+ reg |= G1_REG_DEC_CTRL2_TYPE1_QUANT_E; - if (!(sps->flags & V4L2_H264_SPS_FLAG_FRAME_MBS_ONLY)) - reg |= G1_REG_DEC_CTRL2_FIELDPIC_FLAG_E; - vdpu_write_relaxed(vpu, reg, G1_REG_DEC_CTRL2); -diff --git a/drivers/staging/media/hantro/hantro_h264.c b/drivers/staging/media/hantro/hantro_h264.c -index 089bfa9c625b..b1bdc00ac262 100644 ---- a/drivers/staging/media/hantro/hantro_h264.c -+++ b/drivers/staging/media/hantro/hantro_h264.c -@@ -197,6 +197,7 @@ assemble_scaling_list(struct hantro_ctx *ctx) - { - const struct hantro_h264_dec_ctrls *ctrls = &ctx->h264_dec.ctrls; - const struct v4l2_ctrl_h264_scaling_matrix *scaling = ctrls->scaling; -+ const struct v4l2_ctrl_h264_pps *pps = ctrls->pps; - 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 list_len_8x8 = ARRAY_SIZE(scaling->scaling_list_8x8[0]); -@@ -205,6 +206,9 @@ assemble_scaling_list(struct hantro_ctx *ctx) - const u32 *src; - int i, j; - -+ if (!(pps->flags & V4L2_H264_PPS_FLAG_SCALING_MATRIX_PRESENT)) -+ return; -+ - for (i = 0; i < num_list_4x4; i++) { - src = (u32 *)&scaling->scaling_list_4x4[i]; - for (j = 0; j < list_len_4x4 / 4; j++) - -From 4c2a7a45d1223e8b736fd2badd8e665cf06e3298 Mon Sep 17 00:00:00 2001 -From: Ezequiel Garcia -Date: Tue, 25 Aug 2020 05:52:45 +0200 -Subject: [PATCH] media: cedrus: Use H264_SCALING_MATRIX only when required - -Baseline, Main and Extended profiles are specified to -not support a scaling matrix. Also, High profiles -can optionally specify a scaling matrix, using -SPS and PPS NAL units. - -To meet this expectation, applications are required to -set the V4L2_CID_MPEG_VIDEO_H264_SCALING_MATRIX control -and set the V4L2_H264_PPS_FLAG_SCALING_MATRIX_PRESENT -flag only when a scaling matrix is specified for a picture. - -Implement this on cedrus, which has hardware support for this -case. - -Signed-off-by: Ezequiel Garcia -Signed-off-by: Hans Verkuil -Signed-off-by: Mauro Carvalho Chehab -(cherry picked from commit b3a23db0e2f89b309c40e32421c423875b5c1e65) ---- - drivers/staging/media/sunxi/cedrus/cedrus.c | 2 +- - drivers/staging/media/sunxi/cedrus/cedrus_h264.c | 6 ++++++ - 2 files changed, 7 insertions(+), 1 deletion(-) - -diff --git a/drivers/staging/media/sunxi/cedrus/cedrus.c b/drivers/staging/media/sunxi/cedrus/cedrus.c -index 5d41d3357663..e0e35502e34a 100644 ---- a/drivers/staging/media/sunxi/cedrus/cedrus.c -+++ b/drivers/staging/media/sunxi/cedrus/cedrus.c -@@ -76,7 +76,7 @@ static const struct cedrus_control cedrus_controls[] = { - .id = V4L2_CID_MPEG_VIDEO_H264_SCALING_MATRIX, - }, - .codec = CEDRUS_CODEC_H264, -- .required = true, -+ .required = false, - }, - { - .cfg = { -diff --git a/drivers/staging/media/sunxi/cedrus/cedrus_h264.c b/drivers/staging/media/sunxi/cedrus/cedrus_h264.c -index fe041b444385..28319351e909 100644 ---- a/drivers/staging/media/sunxi/cedrus/cedrus_h264.c -+++ b/drivers/staging/media/sunxi/cedrus/cedrus_h264.c -@@ -238,8 +238,12 @@ static void cedrus_write_scaling_lists(struct cedrus_ctx *ctx, - { - const struct v4l2_ctrl_h264_scaling_matrix *scaling = - run->h264.scaling_matrix; -+ const struct v4l2_ctrl_h264_pps *pps = run->h264.pps; - struct cedrus_dev *dev = ctx->dev; - -+ if (!(pps->flags & V4L2_H264_PPS_FLAG_SCALING_MATRIX_PRESENT)) -+ return; -+ - cedrus_h264_write_sram(dev, CEDRUS_SRAM_H264_SCALING_LIST_8x8_0, - scaling->scaling_list_8x8[0], - sizeof(scaling->scaling_list_8x8[0])); -@@ -442,6 +446,8 @@ static void cedrus_set_params(struct cedrus_ctx *ctx, - reg |= (pps->second_chroma_qp_index_offset & 0x3f) << 16; - reg |= (pps->chroma_qp_index_offset & 0x3f) << 8; - reg |= (pps->pic_init_qp_minus26 + 26 + slice->slice_qp_delta) & 0x3f; -+ if (pps->flags & V4L2_H264_PPS_FLAG_SCALING_MATRIX_PRESENT) -+ reg |= VE_H264_SHS_QP_SCALING_MATRIX_DEFAULT; - cedrus_write(dev, VE_H264_SHS_QP, reg); - - // clear status flags - -From f63d65cb5f9554f96a9dfd785f775da98bf7cb69 Mon Sep 17 00:00:00 2001 -From: Mauro Carvalho Chehab -Date: Tue, 1 Sep 2020 11:09:26 +0200 -Subject: [PATCH] media: videobuf-dma-sg: number of pages should be unsigned - long - -As reported by smatch: - - drivers/media/v4l2-core/videobuf-dma-sg.c:245 videobuf_dma_init_kernel() warn: should 'nr_pages << 12' be a 64 bit type? - -The printk should not be using %d for the number of pages. - -After looking better, the real problem here is that the -number of pages should be long int. - -Signed-off-by: Mauro Carvalho Chehab -(cherry picked from commit 1faa39e0f3bcfe47dc7a61a72c234b24005c3a1a) ---- - drivers/media/v4l2-core/videobuf-dma-sg.c | 22 ++++++++++++---------- - include/media/videobuf-dma-sg.h | 2 +- - 2 files changed, 13 insertions(+), 11 deletions(-) - -diff --git a/drivers/media/v4l2-core/videobuf-dma-sg.c b/drivers/media/v4l2-core/videobuf-dma-sg.c -index 46ff19df9f53..8dd0562de287 100644 ---- a/drivers/media/v4l2-core/videobuf-dma-sg.c -+++ b/drivers/media/v4l2-core/videobuf-dma-sg.c -@@ -180,7 +180,7 @@ static int videobuf_dma_init_user_locked(struct videobuf_dmabuf *dma, - if (rw == READ) - flags |= FOLL_WRITE; - -- dprintk(1, "init user [0x%lx+0x%lx => %d pages]\n", -+ dprintk(1, "init user [0x%lx+0x%lx => %lu pages]\n", - data, size, dma->nr_pages); - - err = pin_user_pages(data & PAGE_MASK, dma->nr_pages, -@@ -188,7 +188,7 @@ static int videobuf_dma_init_user_locked(struct videobuf_dmabuf *dma, - - if (err != dma->nr_pages) { - dma->nr_pages = (err >= 0) ? err : 0; -- dprintk(1, "pin_user_pages: err=%d [%d]\n", err, -+ dprintk(1, "pin_user_pages: err=%d [%lu]\n", err, - dma->nr_pages); - return err < 0 ? err : -EINVAL; - } -@@ -208,11 +208,11 @@ static int videobuf_dma_init_user(struct videobuf_dmabuf *dma, int direction, - } - - static int videobuf_dma_init_kernel(struct videobuf_dmabuf *dma, int direction, -- int nr_pages) -+ unsigned long nr_pages) - { - int i; - -- dprintk(1, "init kernel [%d pages]\n", nr_pages); -+ dprintk(1, "init kernel [%lu pages]\n", nr_pages); - - dma->direction = direction; - dma->vaddr_pages = kcalloc(nr_pages, sizeof(*dma->vaddr_pages), -@@ -238,11 +238,11 @@ static int videobuf_dma_init_kernel(struct videobuf_dmabuf *dma, int direction, - dma->vaddr = vmap(dma->vaddr_pages, nr_pages, VM_MAP | VM_IOREMAP, - PAGE_KERNEL); - if (NULL == dma->vaddr) { -- dprintk(1, "vmalloc_32(%d pages) failed\n", nr_pages); -+ dprintk(1, "vmalloc_32(%lu pages) failed\n", nr_pages); - goto out_free_pages; - } - -- dprintk(1, "vmalloc is at addr %p, size=%d\n", -+ dprintk(1, "vmalloc is at addr %p, size=%lu\n", - dma->vaddr, nr_pages << PAGE_SHIFT); - - memset(dma->vaddr, 0, nr_pages << PAGE_SHIFT); -@@ -267,9 +267,9 @@ static int videobuf_dma_init_kernel(struct videobuf_dmabuf *dma, int direction, - } - - static int videobuf_dma_init_overlay(struct videobuf_dmabuf *dma, int direction, -- dma_addr_t addr, int nr_pages) -+ dma_addr_t addr, unsigned long nr_pages) - { -- dprintk(1, "init overlay [%d pages @ bus 0x%lx]\n", -+ dprintk(1, "init overlay [%lu pages @ bus 0x%lx]\n", - nr_pages, (unsigned long)addr); - dma->direction = direction; - -@@ -500,9 +500,11 @@ static int __videobuf_iolock(struct videobuf_queue *q, - struct videobuf_buffer *vb, - struct v4l2_framebuffer *fbuf) - { -- int err, pages; -- dma_addr_t bus; - struct videobuf_dma_sg_memory *mem = vb->priv; -+ unsigned long pages; -+ dma_addr_t bus; -+ int err; -+ - BUG_ON(!mem); - - MAGIC_CHECK(mem->magic, MAGIC_SG_MEM); -diff --git a/include/media/videobuf-dma-sg.h b/include/media/videobuf-dma-sg.h -index 34450f7ad510..930ff8d454fc 100644 ---- a/include/media/videobuf-dma-sg.h -+++ b/include/media/videobuf-dma-sg.h -@@ -60,7 +60,7 @@ struct videobuf_dmabuf { - /* common */ - struct scatterlist *sglist; - int sglen; -- int nr_pages; -+ unsigned long nr_pages; - int direction; - }; - - -From 613f4cb124631154bfa17e944e6809031e32fc74 Mon Sep 17 00:00:00 2001 -From: Alexandre Courbot -Date: Thu, 27 Aug 2020 14:49:45 +0200 -Subject: [PATCH] media: v4l2-mem2mem: always consider OUTPUT queue during poll - -If poll() is called on a m2m device with the EPOLLOUT event after the -last buffer of the CAPTURE queue is dequeued, any buffer available on -OUTPUT queue will never be signaled because v4l2_m2m_poll_for_data() -starts by checking whether dst_q->last_buffer_dequeued is set and -returns EPOLLIN in this case, without looking at the state of the OUTPUT -queue. - -Fix this by not early returning so we keep checking the state of the -OUTPUT queue afterwards. - -Signed-off-by: Alexandre Courbot -Reviewed-by: Ezequiel Garcia -Signed-off-by: Hans Verkuil -Signed-off-by: Mauro Carvalho Chehab -(cherry picked from commit 566463afdbc43c7744c5a1b89250fc808df03833) ---- - drivers/media/v4l2-core/v4l2-mem2mem.c | 6 ++---- - 1 file changed, 2 insertions(+), 4 deletions(-) - -diff --git a/drivers/media/v4l2-core/v4l2-mem2mem.c b/drivers/media/v4l2-core/v4l2-mem2mem.c -index 6a80240e9228..121243e5bece 100644 ---- a/drivers/media/v4l2-core/v4l2-mem2mem.c -+++ b/drivers/media/v4l2-core/v4l2-mem2mem.c -@@ -909,10 +909,8 @@ static __poll_t v4l2_m2m_poll_for_data(struct file *file, - * If the last buffer was dequeued from the capture queue, - * return immediately. DQBUF will return -EPIPE. - */ -- if (dst_q->last_buffer_dequeued) { -- spin_unlock_irqrestore(&dst_q->done_lock, flags); -- return EPOLLIN | EPOLLRDNORM; -- } -+ if (dst_q->last_buffer_dequeued) -+ rc |= EPOLLIN | EPOLLRDNORM; - } - spin_unlock_irqrestore(&dst_q->done_lock, flags); - - -From 72d1b85060473b809d9450b54100a3e65331dea3 Mon Sep 17 00:00:00 2001 -From: Alexandre Courbot -Date: Thu, 27 Aug 2020 14:49:46 +0200 -Subject: [PATCH] media: v4l2-mem2mem: simplify poll logic - -Factorize redundant checks into a single code block, remove unneeded -checks (a buffer in done_list is necessarily in the DONE or ERROR -state), and we end up with a much simpler version of this function. - -Signed-off-by: Alexandre Courbot -Reviewed-by: Ezequiel Garcia -Signed-off-by: Hans Verkuil -Signed-off-by: Mauro Carvalho Chehab -(cherry picked from commit 1698a7f1511267a0d07a783dd467eab19bf498f3) ---- - drivers/media/v4l2-core/v4l2-mem2mem.c | 26 +++++--------------------- - 1 file changed, 5 insertions(+), 21 deletions(-) - -diff --git a/drivers/media/v4l2-core/v4l2-mem2mem.c b/drivers/media/v4l2-core/v4l2-mem2mem.c -index 121243e5bece..f626ba5ee3d9 100644 ---- a/drivers/media/v4l2-core/v4l2-mem2mem.c -+++ b/drivers/media/v4l2-core/v4l2-mem2mem.c -@@ -882,7 +882,6 @@ static __poll_t v4l2_m2m_poll_for_data(struct file *file, - struct poll_table_struct *wait) - { - struct vb2_queue *src_q, *dst_q; -- struct vb2_buffer *src_vb = NULL, *dst_vb = NULL; - __poll_t rc = 0; - unsigned long flags; - -@@ -903,32 +902,17 @@ static __poll_t v4l2_m2m_poll_for_data(struct file *file, - list_empty(&dst_q->queued_list))) - return EPOLLERR; - -- spin_lock_irqsave(&dst_q->done_lock, flags); -- if (list_empty(&dst_q->done_list)) { -- /* -- * If the last buffer was dequeued from the capture queue, -- * return immediately. DQBUF will return -EPIPE. -- */ -- if (dst_q->last_buffer_dequeued) -- rc |= EPOLLIN | EPOLLRDNORM; -- } -- spin_unlock_irqrestore(&dst_q->done_lock, flags); -- - spin_lock_irqsave(&src_q->done_lock, flags); - if (!list_empty(&src_q->done_list)) -- src_vb = list_first_entry(&src_q->done_list, struct vb2_buffer, -- done_entry); -- if (src_vb && (src_vb->state == VB2_BUF_STATE_DONE -- || src_vb->state == VB2_BUF_STATE_ERROR)) - rc |= EPOLLOUT | EPOLLWRNORM; - spin_unlock_irqrestore(&src_q->done_lock, flags); - - spin_lock_irqsave(&dst_q->done_lock, flags); -- if (!list_empty(&dst_q->done_list)) -- dst_vb = list_first_entry(&dst_q->done_list, struct vb2_buffer, -- done_entry); -- if (dst_vb && (dst_vb->state == VB2_BUF_STATE_DONE -- || dst_vb->state == VB2_BUF_STATE_ERROR)) -+ /* -+ * If the last buffer was dequeued from the capture queue, signal -+ * userspace. DQBUF(CAPTURE) will return -EPIPE. -+ */ -+ if (!list_empty(&dst_q->done_list) || dst_q->last_buffer_dequeued) - rc |= EPOLLIN | EPOLLRDNORM; - spin_unlock_irqrestore(&dst_q->done_lock, flags); - - -From e12ddb183c1503d7f94320fd20e4e7f2828a0976 Mon Sep 17 00:00:00 2001 -From: Nicolas Dufresne -Date: Fri, 18 Sep 2020 02:27:51 +0200 -Subject: [PATCH] media: cedrus: Propagate OUTPUT resolution to CAPTURE - -As per spec, the CAPTURE resolution should be automatically set based on -the OUTPUT resolution. This patch properly propagate width/height to the -capture when the OUTPUT format is set and override the user provided -width/height with configured OUTPUT resolution when the CAPTURE fmt is -updated. - -This also prevents userspace from selecting a CAPTURE resolution that is -too small, avoiding kernel oops. - -Signed-off-by: Nicolas Dufresne -Reviewed-by: Ezequiel Garcia -Acked-by: Paul Kocialkowski -Tested-by: Ondrej Jirman -Signed-off-by: Hans Verkuil -Signed-off-by: Mauro Carvalho Chehab -(cherry picked from commit 8c608272ec3e6926ae2e258e74e84777d932ddd6) ---- - drivers/staging/media/sunxi/cedrus/cedrus_video.c | 29 +++++++++++++++++++++-- - 1 file changed, 27 insertions(+), 2 deletions(-) - -diff --git a/drivers/staging/media/sunxi/cedrus/cedrus_video.c b/drivers/staging/media/sunxi/cedrus/cedrus_video.c -index 16d82309e7b6..667b86dde1ee 100644 ---- a/drivers/staging/media/sunxi/cedrus/cedrus_video.c -+++ b/drivers/staging/media/sunxi/cedrus/cedrus_video.c -@@ -247,6 +247,8 @@ static int cedrus_try_fmt_vid_cap(struct file *file, void *priv, - return -EINVAL; - - pix_fmt->pixelformat = fmt->pixelformat; -+ pix_fmt->width = ctx->src_fmt.width; -+ pix_fmt->height = ctx->src_fmt.height; - cedrus_prepare_format(pix_fmt); - - return 0; -@@ -296,10 +298,30 @@ static int cedrus_s_fmt_vid_out(struct file *file, void *priv, - { - struct cedrus_ctx *ctx = cedrus_file2ctx(file); - struct vb2_queue *vq; -+ struct vb2_queue *peer_vq; - int ret; - -+ ret = cedrus_try_fmt_vid_out(file, priv, f); -+ if (ret) -+ return ret; -+ - vq = v4l2_m2m_get_vq(ctx->fh.m2m_ctx, f->type); -- if (vb2_is_busy(vq)) -+ /* -+ * In order to support dynamic resolution change, -+ * the decoder admits a resolution change, as long -+ * as the pixelformat remains. Can't be done if streaming. -+ */ -+ if (vb2_is_streaming(vq) || (vb2_is_busy(vq) && -+ f->fmt.pix.pixelformat != ctx->src_fmt.pixelformat)) -+ return -EBUSY; -+ /* -+ * 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(ctx->fh.m2m_ctx, -+ V4L2_BUF_TYPE_VIDEO_CAPTURE); -+ if (vb2_is_busy(peer_vq)) - return -EBUSY; - - ret = cedrus_try_fmt_vid_out(file, priv, f); -@@ -319,11 +341,14 @@ static int cedrus_s_fmt_vid_out(struct file *file, void *priv, - break; - } - -- /* Propagate colorspace information to capture. */ -+ /* Propagate format information to capture. */ - ctx->dst_fmt.colorspace = f->fmt.pix.colorspace; - ctx->dst_fmt.xfer_func = f->fmt.pix.xfer_func; - ctx->dst_fmt.ycbcr_enc = f->fmt.pix.ycbcr_enc; - ctx->dst_fmt.quantization = f->fmt.pix.quantization; -+ ctx->dst_fmt.width = ctx->src_fmt.width; -+ ctx->dst_fmt.height = ctx->src_fmt.height; -+ cedrus_prepare_format(&ctx->dst_fmt); - - return 0; - } - -From 58605ff417174bf3310b01bcc7372a29425d1bdf Mon Sep 17 00:00:00 2001 -From: Ezequiel Garcia -Date: Mon, 28 Sep 2020 16:03:34 +0200 -Subject: [PATCH] media: v4l2-mem2mem: Fix spurious v4l2_m2m_buf_done - -A seemingly bad rebase introduced a spurious v4l2_m2m_buf_done, -which releases a buffer twice and therefore triggers a -noisy warning on each job: - -WARNING: CPU: 0 PID: 0 at drivers/media/common/videobuf2/videobuf2-core.c:986 vb2_buffer_done+0x208/0x2a0 - -Fix it by removing the spurious v4l2_m2m_buf_done. - -Reported-by: Adrian Ratiu -Fixes: 911ea8ec42dea ("media: v4l2-mem2mem: add v4l2_m2m_suspend, v4l2_m2m_resume") -Signed-off-by: Ezequiel Garcia -Tested-by: Adrian Ratiu -Signed-off-by: Hans Verkuil -Signed-off-by: Mauro Carvalho Chehab -(cherry picked from commit 1efe3c28eba1306b007f4cb9303a5646b47cb11b) ---- - drivers/media/v4l2-core/v4l2-mem2mem.c | 1 - - 1 file changed, 1 deletion(-) - -diff --git a/drivers/media/v4l2-core/v4l2-mem2mem.c b/drivers/media/v4l2-core/v4l2-mem2mem.c -index f626ba5ee3d9..b221b4e438a1 100644 ---- a/drivers/media/v4l2-core/v4l2-mem2mem.c -+++ b/drivers/media/v4l2-core/v4l2-mem2mem.c -@@ -516,7 +516,6 @@ void v4l2_m2m_buf_done_and_job_finish(struct v4l2_m2m_dev *m2m_dev, - - if (WARN_ON(!src_buf || !dst_buf)) - goto unlock; -- v4l2_m2m_buf_done(src_buf, state); - dst_buf->is_held = src_buf->flags & V4L2_BUF_FLAG_M2M_HOLD_CAPTURE_BUF; - if (!dst_buf->is_held) { - v4l2_m2m_dst_buf_remove(m2m_ctx); diff --git a/projects/Rockchip/patches/linux/default/linux-0020-drm-from-5.11.patch b/projects/Rockchip/patches/linux/default/linux-0020-drm-from-5.11.patch new file mode 100644 index 0000000000..a438af17e7 --- /dev/null +++ b/projects/Rockchip/patches/linux/default/linux-0020-drm-from-5.11.patch @@ -0,0 +1,647 @@ +From 553d877fd05921abc0860a3119ab154bd8ca7008 Mon Sep 17 00:00:00 2001 +From: Thomas Zimmermann +Date: Wed, 23 Sep 2020 12:21:51 +0200 +Subject: [PATCH] drm/rockchip: Convert to drm_gem_object_funcs +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +GEM object functions deprecate several similar callback interfaces in +struct drm_driver. This patch replaces the per-driver callbacks with +per-instance callbacks in rockchip. The only exception is gem_prime_mmap, +which is non-trivial to convert. + +v3: + * update documentation + +Signed-off-by: Thomas Zimmermann +Reviewed-by: Daniel Vetter +Acked-by: Christian König +Link: https://patchwork.freedesktop.org/patch/msgid/20200923102159.24084-15-tzimmermann@suse.de +(cherry picked from commit 0d590af3140d0f84c537a9ad252aecc780ed7aa5) +--- + drivers/gpu/drm/rockchip/rockchip_drm_drv.c | 5 ----- + drivers/gpu/drm/rockchip/rockchip_drm_gem.c | 12 +++++++++++- + 2 files changed, 11 insertions(+), 6 deletions(-) + +diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_drv.c b/drivers/gpu/drm/rockchip/rockchip_drm_drv.c +index 0f3eb392fe39..b7654f5e4225 100644 +--- a/drivers/gpu/drm/rockchip/rockchip_drm_drv.c ++++ b/drivers/gpu/drm/rockchip/rockchip_drm_drv.c +@@ -212,15 +212,10 @@ static const struct file_operations rockchip_drm_driver_fops = { + static struct drm_driver rockchip_drm_driver = { + .driver_features = DRIVER_MODESET | DRIVER_GEM | DRIVER_ATOMIC, + .lastclose = drm_fb_helper_lastclose, +- .gem_vm_ops = &drm_gem_cma_vm_ops, +- .gem_free_object_unlocked = rockchip_gem_free_object, + .dumb_create = rockchip_gem_dumb_create, + .prime_handle_to_fd = drm_gem_prime_handle_to_fd, + .prime_fd_to_handle = drm_gem_prime_fd_to_handle, +- .gem_prime_get_sg_table = rockchip_gem_prime_get_sg_table, + .gem_prime_import_sg_table = rockchip_gem_prime_import_sg_table, +- .gem_prime_vmap = rockchip_gem_prime_vmap, +- .gem_prime_vunmap = rockchip_gem_prime_vunmap, + .gem_prime_mmap = rockchip_gem_mmap_buf, + .fops = &rockchip_drm_driver_fops, + .name = DRIVER_NAME, +diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_gem.c b/drivers/gpu/drm/rockchip/rockchip_drm_gem.c +index 62e5d0970525..1cf4631461c9 100644 +--- a/drivers/gpu/drm/rockchip/rockchip_drm_gem.c ++++ b/drivers/gpu/drm/rockchip/rockchip_drm_gem.c +@@ -295,6 +295,14 @@ static void rockchip_gem_release_object(struct rockchip_gem_object *rk_obj) + kfree(rk_obj); + } + ++static const struct drm_gem_object_funcs rockchip_gem_object_funcs = { ++ .free = rockchip_gem_free_object, ++ .get_sg_table = rockchip_gem_prime_get_sg_table, ++ .vmap = rockchip_gem_prime_vmap, ++ .vunmap = rockchip_gem_prime_vunmap, ++ .vm_ops = &drm_gem_cma_vm_ops, ++}; ++ + static struct rockchip_gem_object * + rockchip_gem_alloc_object(struct drm_device *drm, unsigned int size) + { +@@ -309,6 +317,8 @@ static struct rockchip_gem_object * + + obj = &rk_obj->base; + ++ obj->funcs = &rockchip_gem_object_funcs; ++ + drm_gem_object_init(drm, obj, size); + + return rk_obj; +@@ -337,7 +347,7 @@ rockchip_gem_create_object(struct drm_device *drm, unsigned int size, + } + + /* +- * rockchip_gem_free_object - (struct drm_driver)->gem_free_object_unlocked ++ * rockchip_gem_free_object - (struct drm_gem_object_funcs)->free + * callback function + */ + void rockchip_gem_free_object(struct drm_gem_object *obj) + +From c270a590320dd7a33e9ece80144d70e5821f7454 Mon Sep 17 00:00:00 2001 +From: Thomas Zimmermann +Date: Mon, 28 Sep 2020 10:16:43 +0200 +Subject: [PATCH] drm/rockchip: Include for + drm_gem_cm_vm_ops +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Include to get drm_gem_cma_vm_ops. Fallout +from the recent conversion to GEM object functions. + +Signed-off-by: Thomas Zimmermann +Reviewed-by: Sam Ravnborg +Reported-by: kernel test robot +Fixes: 0d590af3140d ("drm/rockchip: Convert to drm_gem_object_funcs") +Cc: Thomas Zimmermann +Cc: Daniel Vetter +Cc: Christian König +Cc: Sandy Huang +Cc: "Heiko Stübner" +Cc: dri-devel@lists.freedesktop.org +Cc: linux-arm-kernel@lists.infradead.org +Cc: linux-rockchip@lists.infradead.org +Link: https://patchwork.freedesktop.org/patch/msgid/20200928081643.8575-1-tzimmermann@suse.de +(cherry picked from commit 8f7db83e6abf863c6a2cfddbe7086f1e3251fdbf) +--- + drivers/gpu/drm/rockchip/rockchip_drm_gem.c | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_gem.c b/drivers/gpu/drm/rockchip/rockchip_drm_gem.c +index 1cf4631461c9..7d5ebb10323b 100644 +--- a/drivers/gpu/drm/rockchip/rockchip_drm_gem.c ++++ b/drivers/gpu/drm/rockchip/rockchip_drm_gem.c +@@ -10,6 +10,7 @@ + + #include + #include ++#include + #include + #include + + +From 28bc61a7143738a3f9a7d60b9ddc959720bbf2d3 Mon Sep 17 00:00:00 2001 +From: Qinglang Miao +Date: Mon, 21 Sep 2020 21:10:19 +0800 +Subject: [PATCH] drm/panfrost: simplify the return expression of + cz_ih_hw_init() + +Simplify the return expression. + +Signed-off-by: Qinglang Miao +Reviewed-by: Philipp Zabel +Reviewed-by: Steven Price +Signed-off-by: Steven Price +Link: https://patchwork.freedesktop.org/patch/msgid/20200921131019.91558-1-miaoqinglang@huawei.com +(cherry picked from commit 3c4641d4e75618fa1b5501b9ae9c19f765d75725) +--- + drivers/gpu/drm/panfrost/panfrost_device.c | 8 +------- + 1 file changed, 1 insertion(+), 7 deletions(-) + +diff --git a/drivers/gpu/drm/panfrost/panfrost_device.c b/drivers/gpu/drm/panfrost/panfrost_device.c +index bf7c34cfb84c..a83b2ff5837a 100644 +--- a/drivers/gpu/drm/panfrost/panfrost_device.c ++++ b/drivers/gpu/drm/panfrost/panfrost_device.c +@@ -18,19 +18,13 @@ + + static int panfrost_reset_init(struct panfrost_device *pfdev) + { +- int err; +- + pfdev->rstc = devm_reset_control_array_get(pfdev->dev, false, true); + if (IS_ERR(pfdev->rstc)) { + dev_err(pfdev->dev, "get reset failed %ld\n", PTR_ERR(pfdev->rstc)); + return PTR_ERR(pfdev->rstc); + } + +- err = reset_control_deassert(pfdev->rstc); +- if (err) +- return err; +- +- return 0; ++ return reset_control_deassert(pfdev->rstc); + } + + static void panfrost_reset_fini(struct panfrost_device *pfdev) + +From 71c6db9e7728371aa3f06eec239037d0bf6d43ba Mon Sep 17 00:00:00 2001 +From: Qinglang Miao +Date: Mon, 21 Sep 2020 21:10:21 +0800 +Subject: [PATCH] drm/panfrost: simplify the return expression of + panfrost_devfreq_target() + +Simplify the return expression. + +Signed-off-by: Qinglang Miao +Reviewed-by: Steven Price +Signed-off-by: Steven Price +Link: https://patchwork.freedesktop.org/patch/msgid/20200921131021.91604-1-miaoqinglang@huawei.com +(cherry picked from commit 0c5036590bde1407a6250ea027e836815353820f) +--- + drivers/gpu/drm/panfrost/panfrost_devfreq.c | 7 +------ + 1 file changed, 1 insertion(+), 6 deletions(-) + +diff --git a/drivers/gpu/drm/panfrost/panfrost_devfreq.c b/drivers/gpu/drm/panfrost/panfrost_devfreq.c +index 8ab025d0035f..913eaa6d0bc6 100644 +--- a/drivers/gpu/drm/panfrost/panfrost_devfreq.c ++++ b/drivers/gpu/drm/panfrost/panfrost_devfreq.c +@@ -29,18 +29,13 @@ static int panfrost_devfreq_target(struct device *dev, unsigned long *freq, + u32 flags) + { + struct dev_pm_opp *opp; +- int err; + + opp = devfreq_recommended_opp(dev, freq, flags); + if (IS_ERR(opp)) + return PTR_ERR(opp); + dev_pm_opp_put(opp); + +- err = dev_pm_opp_set_rate(dev, *freq); +- if (err) +- return err; +- +- return 0; ++ return dev_pm_opp_set_rate(dev, *freq); + } + + static void panfrost_devfreq_reset(struct panfrost_devfreq *pfdevfreq) + +From e3e33f48d0881c9e2cb65733583c42422e14ee67 Mon Sep 17 00:00:00 2001 +From: Rikard Falkeborn +Date: Sun, 4 Oct 2020 22:06:53 +0200 +Subject: [PATCH] drm: bridge: dw-hdmi: Constify dw_hdmi_i2s_ops + +The only usage of dw_hdmi_i2s_ops is to assign its address to the ops +field in the hdmi_codec_pdata struct, which is a const pointer. Make it +const to allow the compiler to put it in read-only memory. + +Signed-off-by: Rikard Falkeborn +Signed-off-by: Daniel Vetter +Link: https://patchwork.freedesktop.org/patch/msgid/20201004200653.14702-1-rikard.falkeborn@gmail.com +(cherry picked from commit f3d52908f6baffc21ba45058103d0226ca5cb073) +--- + drivers/gpu/drm/bridge/synopsys/dw-hdmi-i2s-audio.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/drivers/gpu/drm/bridge/synopsys/dw-hdmi-i2s-audio.c b/drivers/gpu/drm/bridge/synopsys/dw-hdmi-i2s-audio.c +index 9fef6413741d..feb04f127b55 100644 +--- a/drivers/gpu/drm/bridge/synopsys/dw-hdmi-i2s-audio.c ++++ b/drivers/gpu/drm/bridge/synopsys/dw-hdmi-i2s-audio.c +@@ -170,7 +170,7 @@ static int dw_hdmi_i2s_hook_plugged_cb(struct device *dev, void *data, + return dw_hdmi_set_plugged_cb(hdmi, fn, codec_dev); + } + +-static struct hdmi_codec_ops dw_hdmi_i2s_ops = { ++static const struct hdmi_codec_ops dw_hdmi_i2s_ops = { + .hw_params = dw_hdmi_i2s_hw_params, + .audio_startup = dw_hdmi_i2s_audio_startup, + .audio_shutdown = dw_hdmi_i2s_audio_shutdown, + +From 221b37c6a6f86adbfa3714b345124c0495e95d48 Mon Sep 17 00:00:00 2001 +From: Liu Shixin +Date: Sat, 19 Sep 2020 18:08:50 +0800 +Subject: [PATCH] drm/lima: simplify the return expression of + lima_devfreq_target + +Simplify the return expression. + +Signed-off-by: Liu Shixin +Signed-off-by: Qiang Yu +Link: https://patchwork.freedesktop.org/patch/msgid/20200919100850.1639111-1-liushixin2@huawei.com +--- + drivers/gpu/drm/lima/lima_devfreq.c | 7 +------ + 1 file changed, 1 insertion(+), 6 deletions(-) + +diff --git a/drivers/gpu/drm/lima/lima_devfreq.c b/drivers/gpu/drm/lima/lima_devfreq.c +index bbe02817721b..5914442936ed 100644 +--- a/drivers/gpu/drm/lima/lima_devfreq.c ++++ b/drivers/gpu/drm/lima/lima_devfreq.c +@@ -35,18 +35,13 @@ static int lima_devfreq_target(struct device *dev, unsigned long *freq, + u32 flags) + { + struct dev_pm_opp *opp; +- int err; + + opp = devfreq_recommended_opp(dev, freq, flags); + if (IS_ERR(opp)) + return PTR_ERR(opp); + dev_pm_opp_put(opp); + +- err = dev_pm_opp_set_rate(dev, *freq); +- if (err) +- return err; +- +- return 0; ++ return dev_pm_opp_set_rate(dev, *freq); + } + + static void lima_devfreq_reset(struct lima_devfreq *devfreq) + +From 0bf1a356f4c76fc74c4bdebd85b83ae995abe5da Mon Sep 17 00:00:00 2001 +From: Lee Jones +Date: Fri, 13 Nov 2020 13:49:13 +0000 +Subject: [PATCH] drm/lima/lima_drv: Demote kernel-doc formatting abuse + +Fixes the following W=1 kernel build warning(s): + + drivers/gpu/drm/lima/lima_drv.c:264: warning: cannot understand function prototype: 'const struct drm_driver lima_drm_driver = ' + +Cc: Qiang Yu +Cc: David Airlie +Cc: Daniel Vetter +Cc: dri-devel@lists.freedesktop.org +Cc: lima@lists.freedesktop.org +Signed-off-by: Lee Jones +Signed-off-by: Qiang Yu +Link: https://patchwork.freedesktop.org/patch/msgid/20201113134938.4004947-16-lee.jones@linaro.org +--- + drivers/gpu/drm/lima/lima_drv.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/drivers/gpu/drm/lima/lima_drv.c b/drivers/gpu/drm/lima/lima_drv.c +index ab460121fd52..065c80c14d10 100644 +--- a/drivers/gpu/drm/lima/lima_drv.c ++++ b/drivers/gpu/drm/lima/lima_drv.c +@@ -255,7 +255,7 @@ static const struct drm_ioctl_desc lima_drm_driver_ioctls[] = { + + DEFINE_DRM_GEM_FOPS(lima_drm_driver_fops); + +-/** ++/* + * Changelog: + * + * - 1.1.0 - add heap buffer support + +From abbee7f2aef747690b1ca8bc7a5811f06f60f4b2 Mon Sep 17 00:00:00 2001 +From: Lee Jones +Date: Fri, 13 Nov 2020 13:49:21 +0000 +Subject: [PATCH] drm/lima/lima_sched: Remove unused and unnecessary variable + 'ret' +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Fixes the following W=1 kernel build warning(s): + + drivers/gpu/drm/lima/lima_sched.c: In function ‘lima_sched_run_job’: + drivers/gpu/drm/lima/lima_sched.c:227:20: warning: variable ‘ret’ set but not used [-Wunused-but-set-variable] + +Cc: Qiang Yu +Cc: David Airlie +Cc: Daniel Vetter +Cc: Sumit Semwal +Cc: "Christian König" +Cc: dri-devel@lists.freedesktop.org +Cc: lima@lists.freedesktop.org +Cc: linux-media@vger.kernel.org +Cc: linaro-mm-sig@lists.linaro.org +Signed-off-by: Lee Jones +Signed-off-by: Qiang Yu +Link: https://patchwork.freedesktop.org/patch/msgid/20201113134938.4004947-24-lee.jones@linaro.org +--- + drivers/gpu/drm/lima/lima_sched.c | 3 +-- + 1 file changed, 1 insertion(+), 2 deletions(-) + +diff --git a/drivers/gpu/drm/lima/lima_sched.c b/drivers/gpu/drm/lima/lima_sched.c +index dc6df9e9a40d..3f5075bd158f 100644 +--- a/drivers/gpu/drm/lima/lima_sched.c ++++ b/drivers/gpu/drm/lima/lima_sched.c +@@ -223,7 +223,6 @@ static struct dma_fence *lima_sched_run_job(struct drm_sched_job *job) + struct lima_sched_pipe *pipe = to_lima_pipe(job->sched); + struct lima_device *ldev = pipe->ldev; + struct lima_fence *fence; +- struct dma_fence *ret; + int i, err; + + /* after GPU reset */ +@@ -245,7 +244,7 @@ static struct dma_fence *lima_sched_run_job(struct drm_sched_job *job) + /* for caller usage of the fence, otherwise irq handler + * may consume the fence before caller use it + */ +- ret = dma_fence_get(task->fence); ++ dma_fence_get(task->fence); + + pipe->current_task = task; + + +From 6c3aa06f1c88d508abbc0ce48ceefc8f6f44dcb5 Mon Sep 17 00:00:00 2001 +From: Viresh Kumar +Date: Wed, 28 Oct 2020 12:14:21 +0530 +Subject: [PATCH] drm/lima: Unconditionally call dev_pm_opp_of_remove_table() + +dev_pm_opp_of_remove_table() doesn't report any errors when it fails to +find the OPP table with error -ENODEV (i.e. OPP table not present for +the device). And we can call dev_pm_opp_of_remove_table() +unconditionally here. + +Reviewed-by: Qiang Yu +Signed-off-by: Viresh Kumar +Signed-off-by: Qiang Yu +Link: https://patchwork.freedesktop.org/patch/msgid/c995335d16d8b4b4ff47b1273869c33e14782b32.1603867405.git.viresh.kumar@linaro.org +--- + drivers/gpu/drm/lima/lima_devfreq.c | 6 +----- + drivers/gpu/drm/lima/lima_devfreq.h | 1 - + 2 files changed, 1 insertion(+), 6 deletions(-) + +diff --git a/drivers/gpu/drm/lima/lima_devfreq.c b/drivers/gpu/drm/lima/lima_devfreq.c +index 5914442936ed..da7099d20bd5 100644 +--- a/drivers/gpu/drm/lima/lima_devfreq.c ++++ b/drivers/gpu/drm/lima/lima_devfreq.c +@@ -100,10 +100,7 @@ void lima_devfreq_fini(struct lima_device *ldev) + devfreq->devfreq = NULL; + } + +- if (devfreq->opp_of_table_added) { +- dev_pm_opp_of_remove_table(ldev->dev); +- devfreq->opp_of_table_added = false; +- } ++ dev_pm_opp_of_remove_table(ldev->dev); + + if (devfreq->regulators_opp_table) { + dev_pm_opp_put_regulators(devfreq->regulators_opp_table); +@@ -157,7 +154,6 @@ int lima_devfreq_init(struct lima_device *ldev) + ret = dev_pm_opp_of_add_table(dev); + if (ret) + goto err_fini; +- ldevfreq->opp_of_table_added = true; + + lima_devfreq_reset(ldevfreq); + +diff --git a/drivers/gpu/drm/lima/lima_devfreq.h b/drivers/gpu/drm/lima/lima_devfreq.h +index 5eed2975a375..2d9b3008ce77 100644 +--- a/drivers/gpu/drm/lima/lima_devfreq.h ++++ b/drivers/gpu/drm/lima/lima_devfreq.h +@@ -18,7 +18,6 @@ struct lima_devfreq { + struct opp_table *clkname_opp_table; + struct opp_table *regulators_opp_table; + struct thermal_cooling_device *cooling; +- bool opp_of_table_added; + + ktime_t busy_time; + ktime_t idle_time; + +From 9436bee60f920685c779029c39a8f79bbb9c633a Mon Sep 17 00:00:00 2001 +From: Viresh Kumar +Date: Fri, 6 Nov 2020 12:18:39 +0530 +Subject: [PATCH] drm/lima: dev_pm_opp_put_*() accepts NULL argument + +The dev_pm_opp_put_*() APIs now accepts a NULL opp_table pointer and so +there is no need for us to carry the extra check. Drop them. + +Reviewed-by: Qiang Yu +Signed-off-by: Viresh Kumar +--- + drivers/gpu/drm/lima/lima_devfreq.c | 13 ++++--------- + 1 file changed, 4 insertions(+), 9 deletions(-) + +diff --git a/drivers/gpu/drm/lima/lima_devfreq.c b/drivers/gpu/drm/lima/lima_devfreq.c +index da7099d20bd5..5686ad4aaf7c 100644 +--- a/drivers/gpu/drm/lima/lima_devfreq.c ++++ b/drivers/gpu/drm/lima/lima_devfreq.c +@@ -102,15 +102,10 @@ void lima_devfreq_fini(struct lima_device *ldev) + + dev_pm_opp_of_remove_table(ldev->dev); + +- if (devfreq->regulators_opp_table) { +- dev_pm_opp_put_regulators(devfreq->regulators_opp_table); +- devfreq->regulators_opp_table = NULL; +- } +- +- if (devfreq->clkname_opp_table) { +- dev_pm_opp_put_clkname(devfreq->clkname_opp_table); +- devfreq->clkname_opp_table = NULL; +- } ++ dev_pm_opp_put_regulators(devfreq->regulators_opp_table); ++ dev_pm_opp_put_clkname(devfreq->clkname_opp_table); ++ devfreq->regulators_opp_table = NULL; ++ devfreq->clkname_opp_table = NULL; + } + + int lima_devfreq_init(struct lima_device *ldev) + +From 622fc4f4e82d4670153fc4dc35825769f8b429b4 Mon Sep 17 00:00:00 2001 +From: Robin Murphy +Date: Tue, 22 Sep 2020 15:16:49 +0100 +Subject: [PATCH] drm/panfrost: Support cache-coherent integrations + +When the GPU's ACE-Lite interface is fully wired up and capable of +snooping CPU caches, it may be described as "dma-coherent" in +devicetree, which will already inform the DMA layer not to perform +unnecessary cache maintenance. However, we still need to ensure that +the GPU uses the appropriate cacheable outer-shareable attributes in +order to generate the requisite snoop signals, and that CPU mappings +don't create a mismatch by using a non-cacheable type either. + +Signed-off-by: Robin Murphy +Tested-by: Neil Armstrong +Reviewed-by: Steven Price +Signed-off-by: Neil Armstrong +Link: https://patchwork.freedesktop.org/patch/msgid/7024ce18c1cb1a226e918037d49175571db0b436.1600780574.git.robin.murphy@arm.com +--- + drivers/gpu/drm/panfrost/panfrost_device.h | 1 + + drivers/gpu/drm/panfrost/panfrost_drv.c | 2 ++ + drivers/gpu/drm/panfrost/panfrost_gem.c | 2 ++ + drivers/gpu/drm/panfrost/panfrost_mmu.c | 1 + + 4 files changed, 6 insertions(+) + +diff --git a/drivers/gpu/drm/panfrost/panfrost_device.h b/drivers/gpu/drm/panfrost/panfrost_device.h +index 67f9f66904be..597cf1459b0a 100644 +--- a/drivers/gpu/drm/panfrost/panfrost_device.h ++++ b/drivers/gpu/drm/panfrost/panfrost_device.h +@@ -88,6 +88,7 @@ struct panfrost_device { + /* pm_domains for devices with more than one. */ + struct device *pm_domain_devs[MAX_PM_DOMAINS]; + struct device_link *pm_domain_links[MAX_PM_DOMAINS]; ++ bool coherent; + + struct panfrost_features features; + const struct panfrost_compatible *comp; +diff --git a/drivers/gpu/drm/panfrost/panfrost_drv.c b/drivers/gpu/drm/panfrost/panfrost_drv.c +index 0fc084110e5b..689be734ed20 100644 +--- a/drivers/gpu/drm/panfrost/panfrost_drv.c ++++ b/drivers/gpu/drm/panfrost/panfrost_drv.c +@@ -587,6 +587,8 @@ static int panfrost_probe(struct platform_device *pdev) + if (!pfdev->comp) + return -ENODEV; + ++ pfdev->coherent = device_get_dma_attr(&pdev->dev) == DEV_DMA_COHERENT; ++ + /* Allocate and initialze the DRM device. */ + ddev = drm_dev_alloc(&panfrost_drm_driver, &pdev->dev); + if (IS_ERR(ddev)) +diff --git a/drivers/gpu/drm/panfrost/panfrost_gem.c b/drivers/gpu/drm/panfrost/panfrost_gem.c +index 62d4d710a571..57a31dd0ffed 100644 +--- a/drivers/gpu/drm/panfrost/panfrost_gem.c ++++ b/drivers/gpu/drm/panfrost/panfrost_gem.c +@@ -218,6 +218,7 @@ static const struct drm_gem_object_funcs panfrost_gem_funcs = { + */ + struct drm_gem_object *panfrost_gem_create_object(struct drm_device *dev, size_t size) + { ++ struct panfrost_device *pfdev = dev->dev_private; + struct panfrost_gem_object *obj; + + obj = kzalloc(sizeof(*obj), GFP_KERNEL); +@@ -227,6 +228,7 @@ struct drm_gem_object *panfrost_gem_create_object(struct drm_device *dev, size_t + INIT_LIST_HEAD(&obj->mappings.list); + mutex_init(&obj->mappings.lock); + obj->base.base.funcs = &panfrost_gem_funcs; ++ obj->base.map_cached = pfdev->coherent; + + return &obj->base.base; + } +diff --git a/drivers/gpu/drm/panfrost/panfrost_mmu.c b/drivers/gpu/drm/panfrost/panfrost_mmu.c +index 776448c527ea..be8d68fb0e11 100644 +--- a/drivers/gpu/drm/panfrost/panfrost_mmu.c ++++ b/drivers/gpu/drm/panfrost/panfrost_mmu.c +@@ -371,6 +371,7 @@ int panfrost_mmu_pgtable_alloc(struct panfrost_file_priv *priv) + .pgsize_bitmap = SZ_4K | SZ_2M, + .ias = FIELD_GET(0xff, pfdev->features.mmu_features), + .oas = FIELD_GET(0xff00, pfdev->features.mmu_features), ++ .coherent_walk = pfdev->coherent, + .tlb = &mmu_tlb_ops, + .iommu_dev = pfdev->dev, + }; + +From db5daacf2829ff99d89c949b1e116210e5c8f2be Mon Sep 17 00:00:00 2001 +From: Steven Price +Date: Thu, 29 Oct 2020 17:00:47 +0000 +Subject: [PATCH] drm/panfrost: Don't corrupt the queue mutex on open/close + +The mutex within the panfrost_queue_state should have the lifetime of +the queue, however it was erroneously initialised/destroyed during +panfrost_job_{open,close} which is called every time a client +opens/closes the drm node. + +Move the initialisation/destruction to panfrost_job_{init,fini} where it +belongs. + +Fixes: 1a11a88cfd9a ("drm/panfrost: Fix job timeout handling") +Signed-off-by: Steven Price +Reviewed-by: Boris Brezillon +Signed-off-by: Boris Brezillon +Link: https://patchwork.freedesktop.org/patch/msgid/20201029170047.30564-1-steven.price@arm.com +--- + drivers/gpu/drm/panfrost/panfrost_job.c | 11 ++++++----- + 1 file changed, 6 insertions(+), 5 deletions(-) + +diff --git a/drivers/gpu/drm/panfrost/panfrost_job.c b/drivers/gpu/drm/panfrost/panfrost_job.c +index 1ce2001106e5..517dfb247a80 100644 +--- a/drivers/gpu/drm/panfrost/panfrost_job.c ++++ b/drivers/gpu/drm/panfrost/panfrost_job.c +@@ -617,6 +617,8 @@ int panfrost_job_init(struct panfrost_device *pfdev) + } + + for (j = 0; j < NUM_JOB_SLOTS; j++) { ++ mutex_init(&js->queue[j].lock); ++ + js->queue[j].fence_context = dma_fence_context_alloc(1); + + ret = drm_sched_init(&js->queue[j].sched, +@@ -647,8 +649,10 @@ void panfrost_job_fini(struct panfrost_device *pfdev) + + job_write(pfdev, JOB_INT_MASK, 0); + +- for (j = 0; j < NUM_JOB_SLOTS; j++) ++ for (j = 0; j < NUM_JOB_SLOTS; j++) { + drm_sched_fini(&js->queue[j].sched); ++ mutex_destroy(&js->queue[j].lock); ++ } + + } + +@@ -660,7 +664,6 @@ int panfrost_job_open(struct panfrost_file_priv *panfrost_priv) + int ret, i; + + for (i = 0; i < NUM_JOB_SLOTS; i++) { +- mutex_init(&js->queue[i].lock); + sched = &js->queue[i].sched; + ret = drm_sched_entity_init(&panfrost_priv->sched_entity[i], + DRM_SCHED_PRIORITY_NORMAL, &sched, +@@ -677,10 +680,8 @@ void panfrost_job_close(struct panfrost_file_priv *panfrost_priv) + struct panfrost_job_slot *js = pfdev->js; + int i; + +- for (i = 0; i < NUM_JOB_SLOTS; i++) { ++ for (i = 0; i < NUM_JOB_SLOTS; i++) + drm_sched_entity_destroy(&panfrost_priv->sched_entity[i]); +- mutex_destroy(&js->queue[i].lock); +- } + } + + int panfrost_job_is_idle(struct panfrost_device *pfdev) + +From 44850d0b1a20313d1a22964ccf4fcb9d611c3f9b Mon Sep 17 00:00:00 2001 +From: Boris Brezillon +Date: Sun, 1 Nov 2020 18:38:17 +0100 +Subject: [PATCH] drm/panfrost: Remove unused variables in panfrost_job_close() + +Commit a17d609e3e21 ("drm/panfrost: Don't corrupt the queue mutex on +open/close") left unused variables behind, thus generating a warning +at compilation time. Remove those variables. + +Fixes: a17d609e3e21 ("drm/panfrost: Don't corrupt the queue mutex on open/close") +Signed-off-by: Boris Brezillon +Reviewed-by: Steven Price +Link: https://patchwork.freedesktop.org/patch/msgid/20201101173817.831769-1-boris.brezillon@collabora.com +--- + drivers/gpu/drm/panfrost/panfrost_job.c | 2 -- + 1 file changed, 2 deletions(-) + +diff --git a/drivers/gpu/drm/panfrost/panfrost_job.c b/drivers/gpu/drm/panfrost/panfrost_job.c +index 517dfb247a80..04e6f6f9b742 100644 +--- a/drivers/gpu/drm/panfrost/panfrost_job.c ++++ b/drivers/gpu/drm/panfrost/panfrost_job.c +@@ -676,8 +676,6 @@ int panfrost_job_open(struct panfrost_file_priv *panfrost_priv) + + void panfrost_job_close(struct panfrost_file_priv *panfrost_priv) + { +- struct panfrost_device *pfdev = panfrost_priv->pfdev; +- struct panfrost_job_slot *js = pfdev->js; + int i; + + for (i = 0; i < NUM_JOB_SLOTS; i++) diff --git a/projects/Rockchip/patches/linux/default/linux-0021-drm-from-5.10.patch b/projects/Rockchip/patches/linux/default/linux-0021-drm-from-5.10.patch deleted file mode 100644 index c87b42921d..0000000000 --- a/projects/Rockchip/patches/linux/default/linux-0021-drm-from-5.10.patch +++ /dev/null @@ -1,2194 +0,0 @@ -From b162fb6ee80dd2a986dc4d0d4eaefd29f9152f9c Mon Sep 17 00:00:00 2001 -From: Tomeu Vizoso -Date: Thu, 11 Jun 2020 10:58:43 +0200 -Subject: [PATCH] drm/panfrost: Make sure GPU is powered on when reading - GPU_LATEST_FLUSH_ID - -Bifrost devices do support the flush reduction feature, so on first job -submit we were trying to read the register while still powered off. - -If the GPU is powered off, the feature doesn't bring any benefit, so -don't try to read. - -Tested-by: Heiko Stuebner -Reviewed-by: Steven Price -Signed-off-by: Tomeu Vizoso -Signed-off-by: Rob Herring -Link: https://patchwork.freedesktop.org/patch/msgid/20200611085900.49740-1-tomeu.vizoso@collabora.com -(cherry picked from commit 3a74265c54f883c847ed8554129baefb3e04f135) ---- - drivers/gpu/drm/panfrost/panfrost_gpu.c | 14 ++++++++++++-- - 1 file changed, 12 insertions(+), 2 deletions(-) - -diff --git a/drivers/gpu/drm/panfrost/panfrost_gpu.c b/drivers/gpu/drm/panfrost/panfrost_gpu.c -index f2c1ddc41a9b..e0f190e43813 100644 ---- a/drivers/gpu/drm/panfrost/panfrost_gpu.c -+++ b/drivers/gpu/drm/panfrost/panfrost_gpu.c -@@ -10,6 +10,7 @@ - #include - #include - #include -+#include - - #include "panfrost_device.h" - #include "panfrost_features.h" -@@ -368,7 +369,16 @@ void panfrost_gpu_fini(struct panfrost_device *pfdev) - - u32 panfrost_gpu_get_latest_flush_id(struct panfrost_device *pfdev) - { -- if (panfrost_has_hw_feature(pfdev, HW_FEATURE_FLUSH_REDUCTION)) -- return gpu_read(pfdev, GPU_LATEST_FLUSH_ID); -+ u32 flush_id; -+ -+ if (panfrost_has_hw_feature(pfdev, HW_FEATURE_FLUSH_REDUCTION)) { -+ /* Flush reduction only makes sense when the GPU is kept powered on between jobs */ -+ if (pm_runtime_get_if_in_use(pfdev->dev)) { -+ flush_id = gpu_read(pfdev, GPU_LATEST_FLUSH_ID); -+ pm_runtime_put(pfdev->dev); -+ return flush_id; -+ } -+ } -+ - return 0; - } - -From 2aacfa5ced256a281c36ea2577fc5fb7a4974e9b Mon Sep 17 00:00:00 2001 -From: Tomeu Vizoso -Date: Thu, 11 Jun 2020 10:58:44 +0200 -Subject: [PATCH] drm/panfrost: Add compatible string for bifrost - -Mesa now supports some Bifrost devices, so enable it. - -Tested-by: Heiko Stuebner -Reviewed-by: Steven Price -Reviewed-by: Heiko Stuebner -Signed-off-by: Tomeu Vizoso -Signed-off-by: Rob Herring -Link: https://patchwork.freedesktop.org/patch/msgid/20200611085900.49740-2-tomeu.vizoso@collabora.com -(cherry picked from commit 72ef7fe96fd20d3d0e538e165b393819f99870ad) ---- - drivers/gpu/drm/panfrost/panfrost_drv.c | 1 + - 1 file changed, 1 insertion(+) - -diff --git a/drivers/gpu/drm/panfrost/panfrost_drv.c b/drivers/gpu/drm/panfrost/panfrost_drv.c -index ada51df9a7a3..f79f98534ab6 100644 ---- a/drivers/gpu/drm/panfrost/panfrost_drv.c -+++ b/drivers/gpu/drm/panfrost/panfrost_drv.c -@@ -677,6 +677,7 @@ static const struct of_device_id dt_match[] = { - { .compatible = "arm,mali-t830", .data = &default_data, }, - { .compatible = "arm,mali-t860", .data = &default_data, }, - { .compatible = "arm,mali-t880", .data = &default_data, }, -+ { .compatible = "arm,mali-bifrost", .data = &default_data, }, - {} - }; - MODULE_DEVICE_TABLE(of, dt_match); - -From ef833747ee892a26711ee7765ff81166cd5f1d52 Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Cl=C3=A9ment=20P=C3=A9ron?= -Date: Fri, 10 Jul 2020 11:53:56 +0200 -Subject: [PATCH] drm/panfrost: avoid static declaration -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -This declaration can be avoided so change it. - -Reviewed-by: Steven Price -Reviewed-by: Alyssa Rosenzweig -Signed-off-by: Clément Péron -Signed-off-by: Rob Herring -Link: https://patchwork.freedesktop.org/patch/msgid/20200710095409.407087-2-peron.clem@gmail.com -(cherry picked from commit 862cc626210e34501b4d7a7795c41a67785987e5) ---- - drivers/gpu/drm/panfrost/panfrost_devfreq.c | 38 ++++++++++++++--------------- - 1 file changed, 18 insertions(+), 20 deletions(-) - -diff --git a/drivers/gpu/drm/panfrost/panfrost_devfreq.c b/drivers/gpu/drm/panfrost/panfrost_devfreq.c -index 413987038fbf..1b560b903ea6 100644 ---- a/drivers/gpu/drm/panfrost/panfrost_devfreq.c -+++ b/drivers/gpu/drm/panfrost/panfrost_devfreq.c -@@ -14,7 +14,24 @@ - #include "panfrost_gpu.h" - #include "panfrost_regs.h" - --static void panfrost_devfreq_update_utilization(struct panfrost_device *pfdev); -+static void panfrost_devfreq_update_utilization(struct panfrost_device *pfdev) -+{ -+ ktime_t now; -+ ktime_t last; -+ -+ if (!pfdev->devfreq.devfreq) -+ return; -+ -+ now = ktime_get(); -+ last = pfdev->devfreq.time_last_update; -+ -+ if (atomic_read(&pfdev->devfreq.busy_count) > 0) -+ pfdev->devfreq.busy_time += ktime_sub(now, last); -+ else -+ pfdev->devfreq.idle_time += ktime_sub(now, last); -+ -+ pfdev->devfreq.time_last_update = now; -+} - - static int panfrost_devfreq_target(struct device *dev, unsigned long *freq, - u32 flags) -@@ -139,25 +156,6 @@ void panfrost_devfreq_suspend(struct panfrost_device *pfdev) - devfreq_suspend_device(pfdev->devfreq.devfreq); - } - --static void panfrost_devfreq_update_utilization(struct panfrost_device *pfdev) --{ -- ktime_t now; -- ktime_t last; -- -- if (!pfdev->devfreq.devfreq) -- return; -- -- now = ktime_get(); -- last = pfdev->devfreq.time_last_update; -- -- if (atomic_read(&pfdev->devfreq.busy_count) > 0) -- pfdev->devfreq.busy_time += ktime_sub(now, last); -- else -- pfdev->devfreq.idle_time += ktime_sub(now, last); -- -- pfdev->devfreq.time_last_update = now; --} -- - void panfrost_devfreq_record_busy(struct panfrost_device *pfdev) - { - panfrost_devfreq_update_utilization(pfdev); - -From e79051392b32df8ba3dcb9cd160f1dfe5631ca1a Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Cl=C3=A9ment=20P=C3=A9ron?= -Date: Fri, 10 Jul 2020 11:53:57 +0200 -Subject: [PATCH] drm/panfrost: clean headers in devfreq -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -Don't include not required headers and sort them. - -Reviewed-by: Steven Price -Reviewed-by: Alyssa Rosenzweig -Signed-off-by: Clément Péron -Signed-off-by: Rob Herring -Link: https://patchwork.freedesktop.org/patch/msgid/20200710095409.407087-3-peron.clem@gmail.com -(cherry picked from commit 9713e942a539c55b5e0bc64ba83b736bda1087fe) ---- - drivers/gpu/drm/panfrost/panfrost_devfreq.c | 8 ++------ - 1 file changed, 2 insertions(+), 6 deletions(-) - -diff --git a/drivers/gpu/drm/panfrost/panfrost_devfreq.c b/drivers/gpu/drm/panfrost/panfrost_devfreq.c -index 1b560b903ea6..df7b71da9a84 100644 ---- a/drivers/gpu/drm/panfrost/panfrost_devfreq.c -+++ b/drivers/gpu/drm/panfrost/panfrost_devfreq.c -@@ -1,18 +1,14 @@ - // SPDX-License-Identifier: GPL-2.0 - /* Copyright 2019 Collabora ltd. */ -+ -+#include - #include - #include - #include - #include --#include --#include - - #include "panfrost_device.h" - #include "panfrost_devfreq.h" --#include "panfrost_features.h" --#include "panfrost_issues.h" --#include "panfrost_gpu.h" --#include "panfrost_regs.h" - - static void panfrost_devfreq_update_utilization(struct panfrost_device *pfdev) - { - -From b644d4b83e0c6b86565dc6e7eda0e368e855c56d Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Cl=C3=A9ment=20P=C3=A9ron?= -Date: Fri, 10 Jul 2020 11:53:58 +0200 -Subject: [PATCH] drm/panfrost: don't use pfdevfreq.busy_count to know if hw is - idle -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -This use devfreq variable that will be lock with spinlock in future -patches. We should either introduce a function to access this one -but as devfreq is optional let's just remove it. - -Reviewed-by: Steven Price -Reviewed-by: Alyssa Rosenzweig -Signed-off-by: Clément Péron -Signed-off-by: Rob Herring -Link: https://patchwork.freedesktop.org/patch/msgid/20200710095409.407087-4-peron.clem@gmail.com -(cherry picked from commit eb9dd67249b55fd1fa3d7359be387ea2079247a6) ---- - drivers/gpu/drm/panfrost/panfrost_job.c | 4 ---- - 1 file changed, 4 deletions(-) - -diff --git a/drivers/gpu/drm/panfrost/panfrost_job.c b/drivers/gpu/drm/panfrost/panfrost_job.c -index 360146f6f3d9..4c13dbae68fb 100644 ---- a/drivers/gpu/drm/panfrost/panfrost_job.c -+++ b/drivers/gpu/drm/panfrost/panfrost_job.c -@@ -581,10 +581,6 @@ int panfrost_job_is_idle(struct panfrost_device *pfdev) - struct panfrost_job_slot *js = pfdev->js; - int i; - -- /* Check whether the hardware is idle */ -- if (atomic_read(&pfdev->devfreq.busy_count)) -- return false; -- - for (i = 0; i < NUM_JOB_SLOTS; i++) { - /* If there are any jobs in the HW queue, we're not idle */ - if (atomic_read(&js->queue[i].sched.hw_rq_count)) - -From 1a29b20297e3cfb87ccd6c2a05b385b1a3adf099 Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Cl=C3=A9ment=20P=C3=A9ron?= -Date: Fri, 10 Jul 2020 11:53:59 +0200 -Subject: [PATCH] drm/panfrost: introduce panfrost_devfreq struct -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -Introduce a proper panfrost_devfreq to deal with devfreq variables. - -Reviewed-by: Steven Price -Reviewed-by: Alyssa Rosenzweig -Signed-off-by: Clément Péron -Signed-off-by: Rob Herring -Link: https://patchwork.freedesktop.org/patch/msgid/20200710095409.407087-5-peron.clem@gmail.com -(cherry picked from commit 9bfacfc82f903b066b0b63460d5b7943705048a4) ---- - drivers/gpu/drm/panfrost/panfrost_devfreq.c | 76 ++++++++++++++++------------- - drivers/gpu/drm/panfrost/panfrost_devfreq.h | 20 +++++++- - drivers/gpu/drm/panfrost/panfrost_device.h | 11 ++--- - drivers/gpu/drm/panfrost/panfrost_job.c | 6 +-- - 4 files changed, 66 insertions(+), 47 deletions(-) - -diff --git a/drivers/gpu/drm/panfrost/panfrost_devfreq.c b/drivers/gpu/drm/panfrost/panfrost_devfreq.c -index df7b71da9a84..962550363391 100644 ---- a/drivers/gpu/drm/panfrost/panfrost_devfreq.c -+++ b/drivers/gpu/drm/panfrost/panfrost_devfreq.c -@@ -10,23 +10,23 @@ - #include "panfrost_device.h" - #include "panfrost_devfreq.h" - --static void panfrost_devfreq_update_utilization(struct panfrost_device *pfdev) -+static void panfrost_devfreq_update_utilization(struct panfrost_devfreq *pfdevfreq) - { - ktime_t now; - ktime_t last; - -- if (!pfdev->devfreq.devfreq) -+ if (!pfdevfreq->devfreq) - return; - - now = ktime_get(); -- last = pfdev->devfreq.time_last_update; -+ last = pfdevfreq->time_last_update; - -- if (atomic_read(&pfdev->devfreq.busy_count) > 0) -- pfdev->devfreq.busy_time += ktime_sub(now, last); -+ if (atomic_read(&pfdevfreq->busy_count) > 0) -+ pfdevfreq->busy_time += ktime_sub(now, last); - else -- pfdev->devfreq.idle_time += ktime_sub(now, last); -+ pfdevfreq->idle_time += ktime_sub(now, last); - -- pfdev->devfreq.time_last_update = now; -+ pfdevfreq->time_last_update = now; - } - - static int panfrost_devfreq_target(struct device *dev, unsigned long *freq, -@@ -47,30 +47,31 @@ static int panfrost_devfreq_target(struct device *dev, unsigned long *freq, - return 0; - } - --static void panfrost_devfreq_reset(struct panfrost_device *pfdev) -+static void panfrost_devfreq_reset(struct panfrost_devfreq *pfdevfreq) - { -- pfdev->devfreq.busy_time = 0; -- pfdev->devfreq.idle_time = 0; -- pfdev->devfreq.time_last_update = ktime_get(); -+ pfdevfreq->busy_time = 0; -+ pfdevfreq->idle_time = 0; -+ pfdevfreq->time_last_update = ktime_get(); - } - - static int panfrost_devfreq_get_dev_status(struct device *dev, - struct devfreq_dev_status *status) - { - struct panfrost_device *pfdev = dev_get_drvdata(dev); -+ struct panfrost_devfreq *pfdevfreq = &pfdev->pfdevfreq; - -- panfrost_devfreq_update_utilization(pfdev); -+ panfrost_devfreq_update_utilization(pfdevfreq); - - status->current_frequency = clk_get_rate(pfdev->clock); -- status->total_time = ktime_to_ns(ktime_add(pfdev->devfreq.busy_time, -- pfdev->devfreq.idle_time)); -+ status->total_time = ktime_to_ns(ktime_add(pfdevfreq->busy_time, -+ pfdevfreq->idle_time)); - -- status->busy_time = ktime_to_ns(pfdev->devfreq.busy_time); -+ status->busy_time = ktime_to_ns(pfdevfreq->busy_time); - -- panfrost_devfreq_reset(pfdev); -+ panfrost_devfreq_reset(pfdevfreq); - -- dev_dbg(pfdev->dev, "busy %lu total %lu %lu %% freq %lu MHz\n", status->busy_time, -- status->total_time, -+ dev_dbg(pfdev->dev, "busy %lu total %lu %lu %% freq %lu MHz\n", -+ status->busy_time, status->total_time, - status->busy_time / (status->total_time / 100), - status->current_frequency / 1000 / 1000); - -@@ -91,6 +92,7 @@ int panfrost_devfreq_init(struct panfrost_device *pfdev) - struct device *dev = &pfdev->pdev->dev; - struct devfreq *devfreq; - struct thermal_cooling_device *cooling; -+ struct panfrost_devfreq *pfdevfreq = &pfdev->pfdevfreq; - - ret = dev_pm_opp_of_add_table(dev); - if (ret == -ENODEV) /* Optional, continue without devfreq */ -@@ -98,7 +100,7 @@ int panfrost_devfreq_init(struct panfrost_device *pfdev) - else if (ret) - return ret; - -- panfrost_devfreq_reset(pfdev); -+ panfrost_devfreq_reset(pfdevfreq); - - cur_freq = clk_get_rate(pfdev->clock); - -@@ -116,53 +118,59 @@ int panfrost_devfreq_init(struct panfrost_device *pfdev) - dev_pm_opp_of_remove_table(dev); - return PTR_ERR(devfreq); - } -- pfdev->devfreq.devfreq = devfreq; -+ pfdevfreq->devfreq = devfreq; - - cooling = of_devfreq_cooling_register(dev->of_node, devfreq); - if (IS_ERR(cooling)) - DRM_DEV_INFO(dev, "Failed to register cooling device\n"); - else -- pfdev->devfreq.cooling = cooling; -+ pfdevfreq->cooling = cooling; - - return 0; - } - - void panfrost_devfreq_fini(struct panfrost_device *pfdev) - { -- if (pfdev->devfreq.cooling) -- devfreq_cooling_unregister(pfdev->devfreq.cooling); -+ struct panfrost_devfreq *pfdevfreq = &pfdev->pfdevfreq; -+ -+ if (pfdevfreq->cooling) -+ devfreq_cooling_unregister(pfdevfreq->cooling); - dev_pm_opp_of_remove_table(&pfdev->pdev->dev); - } - - void panfrost_devfreq_resume(struct panfrost_device *pfdev) - { -- if (!pfdev->devfreq.devfreq) -+ struct panfrost_devfreq *pfdevfreq = &pfdev->pfdevfreq; -+ -+ if (!pfdevfreq->devfreq) - return; - -- panfrost_devfreq_reset(pfdev); -+ panfrost_devfreq_reset(pfdevfreq); - -- devfreq_resume_device(pfdev->devfreq.devfreq); -+ devfreq_resume_device(pfdevfreq->devfreq); - } - - void panfrost_devfreq_suspend(struct panfrost_device *pfdev) - { -- if (!pfdev->devfreq.devfreq) -+ struct panfrost_devfreq *pfdevfreq = &pfdev->pfdevfreq; -+ -+ if (!pfdevfreq->devfreq) - return; - -- devfreq_suspend_device(pfdev->devfreq.devfreq); -+ devfreq_suspend_device(pfdevfreq->devfreq); - } - --void panfrost_devfreq_record_busy(struct panfrost_device *pfdev) -+void panfrost_devfreq_record_busy(struct panfrost_devfreq *pfdevfreq) - { -- panfrost_devfreq_update_utilization(pfdev); -- atomic_inc(&pfdev->devfreq.busy_count); -+ panfrost_devfreq_update_utilization(pfdevfreq); -+ atomic_inc(&pfdevfreq->busy_count); - } - --void panfrost_devfreq_record_idle(struct panfrost_device *pfdev) -+void panfrost_devfreq_record_idle(struct panfrost_devfreq *pfdevfreq) - { - int count; - -- panfrost_devfreq_update_utilization(pfdev); -- count = atomic_dec_if_positive(&pfdev->devfreq.busy_count); -+ panfrost_devfreq_update_utilization(pfdevfreq); -+ count = atomic_dec_if_positive(&pfdevfreq->busy_count); - WARN_ON(count < 0); - } -diff --git a/drivers/gpu/drm/panfrost/panfrost_devfreq.h b/drivers/gpu/drm/panfrost/panfrost_devfreq.h -index 0611beffc8d0..0697f8d5aa34 100644 ---- a/drivers/gpu/drm/panfrost/panfrost_devfreq.h -+++ b/drivers/gpu/drm/panfrost/panfrost_devfreq.h -@@ -4,13 +4,29 @@ - #ifndef __PANFROST_DEVFREQ_H__ - #define __PANFROST_DEVFREQ_H__ - -+#include -+ -+struct devfreq; -+struct thermal_cooling_device; -+ -+struct panfrost_device; -+ -+struct panfrost_devfreq { -+ struct devfreq *devfreq; -+ struct thermal_cooling_device *cooling; -+ ktime_t busy_time; -+ ktime_t idle_time; -+ ktime_t time_last_update; -+ atomic_t busy_count; -+}; -+ - int panfrost_devfreq_init(struct panfrost_device *pfdev); - void panfrost_devfreq_fini(struct panfrost_device *pfdev); - - void panfrost_devfreq_resume(struct panfrost_device *pfdev); - void panfrost_devfreq_suspend(struct panfrost_device *pfdev); - --void panfrost_devfreq_record_busy(struct panfrost_device *pfdev); --void panfrost_devfreq_record_idle(struct panfrost_device *pfdev); -+void panfrost_devfreq_record_busy(struct panfrost_devfreq *devfreq); -+void panfrost_devfreq_record_idle(struct panfrost_devfreq *devfreq); - - #endif /* __PANFROST_DEVFREQ_H__ */ -diff --git a/drivers/gpu/drm/panfrost/panfrost_device.h b/drivers/gpu/drm/panfrost/panfrost_device.h -index c30c719a8059..2efa59c9d1c5 100644 ---- a/drivers/gpu/drm/panfrost/panfrost_device.h -+++ b/drivers/gpu/drm/panfrost/panfrost_device.h -@@ -13,6 +13,8 @@ - #include - #include - -+#include "panfrost_devfreq.h" -+ - struct panfrost_device; - struct panfrost_mmu; - struct panfrost_job_slot; -@@ -107,14 +109,7 @@ struct panfrost_device { - struct list_head shrinker_list; - struct shrinker shrinker; - -- struct { -- struct devfreq *devfreq; -- struct thermal_cooling_device *cooling; -- ktime_t busy_time; -- ktime_t idle_time; -- ktime_t time_last_update; -- atomic_t busy_count; -- } devfreq; -+ struct panfrost_devfreq pfdevfreq; - }; - - struct panfrost_mmu { -diff --git a/drivers/gpu/drm/panfrost/panfrost_job.c b/drivers/gpu/drm/panfrost/panfrost_job.c -index 4c13dbae68fb..30e7b7196dab 100644 ---- a/drivers/gpu/drm/panfrost/panfrost_job.c -+++ b/drivers/gpu/drm/panfrost/panfrost_job.c -@@ -145,7 +145,7 @@ static void panfrost_job_hw_submit(struct panfrost_job *job, int js) - u64 jc_head = job->jc; - int ret; - -- panfrost_devfreq_record_busy(pfdev); -+ panfrost_devfreq_record_busy(&pfdev->pfdevfreq); - - ret = pm_runtime_get_sync(pfdev->dev); - if (ret < 0) -@@ -410,7 +410,7 @@ static void panfrost_job_timedout(struct drm_sched_job *sched_job) - for (i = 0; i < NUM_JOB_SLOTS; i++) { - if (pfdev->jobs[i]) { - pm_runtime_put_noidle(pfdev->dev); -- panfrost_devfreq_record_idle(pfdev); -+ panfrost_devfreq_record_idle(&pfdev->pfdevfreq); - pfdev->jobs[i] = NULL; - } - } -@@ -478,7 +478,7 @@ static irqreturn_t panfrost_job_irq_handler(int irq, void *data) - pfdev->jobs[j] = NULL; - - panfrost_mmu_as_put(pfdev, &job->file_priv->mmu); -- panfrost_devfreq_record_idle(pfdev); -+ panfrost_devfreq_record_idle(&pfdev->pfdevfreq); - - dma_fence_signal_locked(job->done_fence); - pm_runtime_put_autosuspend(pfdev->dev); - -From c0bae02328a32aabc9cd41f37ab93623ea2ea3e3 Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Cl=C3=A9ment=20P=C3=A9ron?= -Date: Fri, 10 Jul 2020 11:54:00 +0200 -Subject: [PATCH] drm/panfrost: use spinlock instead of atomic -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -Convert busy_count to a simple int protected by spinlock. - -Reviewed-by: Steven Price -Reviewed-by: Alyssa Rosenzweig -Signed-off-by: Clément Péron -Signed-off-by: Rob Herring -Link: https://patchwork.freedesktop.org/patch/msgid/20200710095409.407087-6-peron.clem@gmail.com -(cherry picked from commit ed85df3f60740bb4be23fbc2db283d59b361a834) ---- - drivers/gpu/drm/panfrost/panfrost_devfreq.c | 43 +++++++++++++++++++++-------- - drivers/gpu/drm/panfrost/panfrost_devfreq.h | 9 +++++- - 2 files changed, 40 insertions(+), 12 deletions(-) - -diff --git a/drivers/gpu/drm/panfrost/panfrost_devfreq.c b/drivers/gpu/drm/panfrost/panfrost_devfreq.c -index 962550363391..78753cfb59fb 100644 ---- a/drivers/gpu/drm/panfrost/panfrost_devfreq.c -+++ b/drivers/gpu/drm/panfrost/panfrost_devfreq.c -@@ -12,16 +12,12 @@ - - static void panfrost_devfreq_update_utilization(struct panfrost_devfreq *pfdevfreq) - { -- ktime_t now; -- ktime_t last; -- -- if (!pfdevfreq->devfreq) -- return; -+ ktime_t now, last; - - now = ktime_get(); - last = pfdevfreq->time_last_update; - -- if (atomic_read(&pfdevfreq->busy_count) > 0) -+ if (pfdevfreq->busy_count > 0) - pfdevfreq->busy_time += ktime_sub(now, last); - else - pfdevfreq->idle_time += ktime_sub(now, last); -@@ -59,10 +55,14 @@ static int panfrost_devfreq_get_dev_status(struct device *dev, - { - struct panfrost_device *pfdev = dev_get_drvdata(dev); - struct panfrost_devfreq *pfdevfreq = &pfdev->pfdevfreq; -+ unsigned long irqflags; -+ -+ status->current_frequency = clk_get_rate(pfdev->clock); -+ -+ spin_lock_irqsave(&pfdevfreq->lock, irqflags); - - panfrost_devfreq_update_utilization(pfdevfreq); - -- status->current_frequency = clk_get_rate(pfdev->clock); - status->total_time = ktime_to_ns(ktime_add(pfdevfreq->busy_time, - pfdevfreq->idle_time)); - -@@ -70,6 +70,8 @@ static int panfrost_devfreq_get_dev_status(struct device *dev, - - panfrost_devfreq_reset(pfdevfreq); - -+ spin_unlock_irqrestore(&pfdevfreq->lock, irqflags); -+ - dev_dbg(pfdev->dev, "busy %lu total %lu %lu %% freq %lu MHz\n", - status->busy_time, status->total_time, - status->busy_time / (status->total_time / 100), -@@ -100,6 +102,8 @@ int panfrost_devfreq_init(struct panfrost_device *pfdev) - else if (ret) - return ret; - -+ spin_lock_init(&pfdevfreq->lock); -+ - panfrost_devfreq_reset(pfdevfreq); - - cur_freq = clk_get_rate(pfdev->clock); -@@ -162,15 +166,32 @@ void panfrost_devfreq_suspend(struct panfrost_device *pfdev) - - void panfrost_devfreq_record_busy(struct panfrost_devfreq *pfdevfreq) - { -+ unsigned long irqflags; -+ -+ if (!pfdevfreq->devfreq) -+ return; -+ -+ spin_lock_irqsave(&pfdevfreq->lock, irqflags); -+ - panfrost_devfreq_update_utilization(pfdevfreq); -- atomic_inc(&pfdevfreq->busy_count); -+ -+ pfdevfreq->busy_count++; -+ -+ spin_unlock_irqrestore(&pfdevfreq->lock, irqflags); - } - - void panfrost_devfreq_record_idle(struct panfrost_devfreq *pfdevfreq) - { -- int count; -+ unsigned long irqflags; -+ -+ if (!pfdevfreq->devfreq) -+ return; -+ -+ spin_lock_irqsave(&pfdevfreq->lock, irqflags); - - panfrost_devfreq_update_utilization(pfdevfreq); -- count = atomic_dec_if_positive(&pfdevfreq->busy_count); -- WARN_ON(count < 0); -+ -+ WARN_ON(--pfdevfreq->busy_count < 0); -+ -+ spin_unlock_irqrestore(&pfdevfreq->lock, irqflags); - } -diff --git a/drivers/gpu/drm/panfrost/panfrost_devfreq.h b/drivers/gpu/drm/panfrost/panfrost_devfreq.h -index 0697f8d5aa34..3392df1020be 100644 ---- a/drivers/gpu/drm/panfrost/panfrost_devfreq.h -+++ b/drivers/gpu/drm/panfrost/panfrost_devfreq.h -@@ -4,6 +4,7 @@ - #ifndef __PANFROST_DEVFREQ_H__ - #define __PANFROST_DEVFREQ_H__ - -+#include - #include - - struct devfreq; -@@ -14,10 +15,16 @@ struct panfrost_device; - struct panfrost_devfreq { - struct devfreq *devfreq; - struct thermal_cooling_device *cooling; -+ - ktime_t busy_time; - ktime_t idle_time; - ktime_t time_last_update; -- atomic_t busy_count; -+ int busy_count; -+ /* -+ * Protect busy_time, idle_time, time_last_update and busy_count -+ * because these can be updated concurrently between multiple jobs. -+ */ -+ spinlock_t lock; - }; - - int panfrost_devfreq_init(struct panfrost_device *pfdev); - -From f2c14c5a166e0d30ef41f6b4e4b8e7904dc931da Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Cl=C3=A9ment=20P=C3=A9ron?= -Date: Fri, 10 Jul 2020 11:54:01 +0200 -Subject: [PATCH] drm/panfrost: properly handle error in probe -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -Introduce a boolean to know if opp table has been added. - -With this, we can call panfrost_devfreq_fini() in case of error -and release what has been initialised. - -Reviewed-by: Steven Price -Reviewed-by: Alyssa Rosenzweig -Signed-off-by: Clément Péron -Signed-off-by: Rob Herring -Link: https://patchwork.freedesktop.org/patch/msgid/20200710095409.407087-7-peron.clem@gmail.com -(cherry picked from commit 81f2fbe62cb54b6cf3d91078c4d49451ba7b9877) ---- - drivers/gpu/drm/panfrost/panfrost_devfreq.c | 25 +++++++++++++++++++------ - drivers/gpu/drm/panfrost/panfrost_devfreq.h | 1 + - 2 files changed, 20 insertions(+), 6 deletions(-) - -diff --git a/drivers/gpu/drm/panfrost/panfrost_devfreq.c b/drivers/gpu/drm/panfrost/panfrost_devfreq.c -index 78753cfb59fb..d9007f44b772 100644 ---- a/drivers/gpu/drm/panfrost/panfrost_devfreq.c -+++ b/drivers/gpu/drm/panfrost/panfrost_devfreq.c -@@ -101,6 +101,7 @@ int panfrost_devfreq_init(struct panfrost_device *pfdev) - return 0; - else if (ret) - return ret; -+ pfdevfreq->opp_of_table_added = true; - - spin_lock_init(&pfdevfreq->lock); - -@@ -109,8 +110,10 @@ int panfrost_devfreq_init(struct panfrost_device *pfdev) - cur_freq = clk_get_rate(pfdev->clock); - - opp = devfreq_recommended_opp(dev, &cur_freq, 0); -- if (IS_ERR(opp)) -- return PTR_ERR(opp); -+ if (IS_ERR(opp)) { -+ ret = PTR_ERR(opp); -+ goto err_fini; -+ } - - panfrost_devfreq_profile.initial_freq = cur_freq; - dev_pm_opp_put(opp); -@@ -119,8 +122,8 @@ int panfrost_devfreq_init(struct panfrost_device *pfdev) - DEVFREQ_GOV_SIMPLE_ONDEMAND, NULL); - if (IS_ERR(devfreq)) { - DRM_DEV_ERROR(dev, "Couldn't initialize GPU devfreq\n"); -- dev_pm_opp_of_remove_table(dev); -- return PTR_ERR(devfreq); -+ ret = PTR_ERR(devfreq); -+ goto err_fini; - } - pfdevfreq->devfreq = devfreq; - -@@ -131,15 +134,25 @@ int panfrost_devfreq_init(struct panfrost_device *pfdev) - pfdevfreq->cooling = cooling; - - return 0; -+ -+err_fini: -+ panfrost_devfreq_fini(pfdev); -+ return ret; - } - - void panfrost_devfreq_fini(struct panfrost_device *pfdev) - { - struct panfrost_devfreq *pfdevfreq = &pfdev->pfdevfreq; - -- if (pfdevfreq->cooling) -+ if (pfdevfreq->cooling) { - devfreq_cooling_unregister(pfdevfreq->cooling); -- dev_pm_opp_of_remove_table(&pfdev->pdev->dev); -+ pfdevfreq->cooling = NULL; -+ } -+ -+ if (pfdevfreq->opp_of_table_added) { -+ dev_pm_opp_of_remove_table(&pfdev->pdev->dev); -+ pfdevfreq->opp_of_table_added = false; -+ } - } - - void panfrost_devfreq_resume(struct panfrost_device *pfdev) -diff --git a/drivers/gpu/drm/panfrost/panfrost_devfreq.h b/drivers/gpu/drm/panfrost/panfrost_devfreq.h -index 3392df1020be..210269944687 100644 ---- a/drivers/gpu/drm/panfrost/panfrost_devfreq.h -+++ b/drivers/gpu/drm/panfrost/panfrost_devfreq.h -@@ -15,6 +15,7 @@ struct panfrost_device; - struct panfrost_devfreq { - struct devfreq *devfreq; - struct thermal_cooling_device *cooling; -+ bool opp_of_table_added; - - ktime_t busy_time; - ktime_t idle_time; - -From 6d5816fcaa6621b0f7bb9c07bdc4a74696b0d4f6 Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Cl=C3=A9ment=20P=C3=A9ron?= -Date: Fri, 10 Jul 2020 11:54:04 +0200 -Subject: [PATCH] drm/panfrost: dynamically alloc regulators -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -We will later introduce regulators managed by OPP. - -Only alloc regulators when it's needed. This also help use -to release the regulators only when they are allocated. - -Reviewed-by: Steven Price -Reviewed-by: Alyssa Rosenzweig -Signed-off-by: Clément Péron -Signed-off-by: Rob Herring -Link: https://patchwork.freedesktop.org/patch/msgid/20200710095409.407087-10-peron.clem@gmail.com -(cherry picked from commit 512f21227fd3d2dbe7aad57a995b9732229c9b56) ---- - drivers/gpu/drm/panfrost/panfrost_device.c | 14 +++++++++----- - drivers/gpu/drm/panfrost/panfrost_device.h | 3 +-- - 2 files changed, 10 insertions(+), 7 deletions(-) - -diff --git a/drivers/gpu/drm/panfrost/panfrost_device.c b/drivers/gpu/drm/panfrost/panfrost_device.c -index 36b5c8fea3eb..f1474b961def 100644 ---- a/drivers/gpu/drm/panfrost/panfrost_device.c -+++ b/drivers/gpu/drm/panfrost/panfrost_device.c -@@ -90,9 +90,11 @@ static int panfrost_regulator_init(struct panfrost_device *pfdev) - { - int ret, i; - -- if (WARN(pfdev->comp->num_supplies > ARRAY_SIZE(pfdev->regulators), -- "Too many supplies in compatible structure.\n")) -- return -EINVAL; -+ pfdev->regulators = devm_kcalloc(pfdev->dev, pfdev->comp->num_supplies, -+ sizeof(*pfdev->regulators), -+ GFP_KERNEL); -+ if (!pfdev->regulators) -+ return -ENOMEM; - - for (i = 0; i < pfdev->comp->num_supplies; i++) - pfdev->regulators[i].supply = pfdev->comp->supply_names[i]; -@@ -119,8 +121,10 @@ static int panfrost_regulator_init(struct panfrost_device *pfdev) - - static void panfrost_regulator_fini(struct panfrost_device *pfdev) - { -- regulator_bulk_disable(pfdev->comp->num_supplies, -- pfdev->regulators); -+ if (!pfdev->regulators) -+ return; -+ -+ regulator_bulk_disable(pfdev->comp->num_supplies, pfdev->regulators); - } - - static void panfrost_pm_domain_fini(struct panfrost_device *pfdev) -diff --git a/drivers/gpu/drm/panfrost/panfrost_device.h b/drivers/gpu/drm/panfrost/panfrost_device.h -index 2efa59c9d1c5..953f7536a773 100644 ---- a/drivers/gpu/drm/panfrost/panfrost_device.h -+++ b/drivers/gpu/drm/panfrost/panfrost_device.h -@@ -22,7 +22,6 @@ struct panfrost_job; - struct panfrost_perfcnt; - - #define NUM_JOB_SLOTS 3 --#define MAX_REGULATORS 2 - #define MAX_PM_DOMAINS 3 - - struct panfrost_features { -@@ -81,7 +80,7 @@ struct panfrost_device { - void __iomem *iomem; - struct clk *clock; - struct clk *bus_clock; -- struct regulator_bulk_data regulators[MAX_REGULATORS]; -+ struct regulator_bulk_data *regulators; - struct reset_control *rstc; - /* pm_domains for devices with more than one. */ - struct device *pm_domain_devs[MAX_PM_DOMAINS]; - -From 132fdf3d6a3bb089fa4e7aab7306d98dfeff3273 Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Cl=C3=A9ment=20P=C3=A9ron?= -Date: Fri, 10 Jul 2020 11:54:05 +0200 -Subject: [PATCH] drm/panfrost: add regulators to devfreq -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -Some OPP tables specify voltage for each frequency. Devfreq can -handle these regulators but they should be get only 1 time to avoid -issue and know who is in charge. - -If OPP table is probe don't init regulator. - -Reviewed-by: Steven Price -Reviewed-by: Alyssa Rosenzweig -Signed-off-by: Clément Péron -Signed-off-by: Rob Herring -Link: https://patchwork.freedesktop.org/patch/msgid/20200710095409.407087-11-peron.clem@gmail.com -(cherry picked from commit fd587ff01d59554144e2fd20f4113638a45c7c4e) ---- - drivers/gpu/drm/panfrost/panfrost_devfreq.c | 29 +++++++++++++++++++++++++---- - drivers/gpu/drm/panfrost/panfrost_devfreq.h | 2 ++ - drivers/gpu/drm/panfrost/panfrost_device.c | 9 ++++++--- - 3 files changed, 33 insertions(+), 7 deletions(-) - -diff --git a/drivers/gpu/drm/panfrost/panfrost_devfreq.c b/drivers/gpu/drm/panfrost/panfrost_devfreq.c -index d9007f44b772..8ab025d0035f 100644 ---- a/drivers/gpu/drm/panfrost/panfrost_devfreq.c -+++ b/drivers/gpu/drm/panfrost/panfrost_devfreq.c -@@ -93,14 +93,30 @@ int panfrost_devfreq_init(struct panfrost_device *pfdev) - unsigned long cur_freq; - struct device *dev = &pfdev->pdev->dev; - struct devfreq *devfreq; -+ struct opp_table *opp_table; - struct thermal_cooling_device *cooling; - struct panfrost_devfreq *pfdevfreq = &pfdev->pfdevfreq; - -+ opp_table = dev_pm_opp_set_regulators(dev, pfdev->comp->supply_names, -+ pfdev->comp->num_supplies); -+ if (IS_ERR(opp_table)) { -+ ret = PTR_ERR(opp_table); -+ /* Continue if the optional regulator is missing */ -+ if (ret != -ENODEV) { -+ DRM_DEV_ERROR(dev, "Couldn't set OPP regulators\n"); -+ goto err_fini; -+ } -+ } else { -+ pfdevfreq->regulators_opp_table = opp_table; -+ } -+ - ret = dev_pm_opp_of_add_table(dev); -- if (ret == -ENODEV) /* Optional, continue without devfreq */ -- return 0; -- else if (ret) -- return ret; -+ if (ret) { -+ /* Optional, continue without devfreq */ -+ if (ret == -ENODEV) -+ ret = 0; -+ goto err_fini; -+ } - pfdevfreq->opp_of_table_added = true; - - spin_lock_init(&pfdevfreq->lock); -@@ -153,6 +169,11 @@ void panfrost_devfreq_fini(struct panfrost_device *pfdev) - dev_pm_opp_of_remove_table(&pfdev->pdev->dev); - pfdevfreq->opp_of_table_added = false; - } -+ -+ if (pfdevfreq->regulators_opp_table) { -+ dev_pm_opp_put_regulators(pfdevfreq->regulators_opp_table); -+ pfdevfreq->regulators_opp_table = NULL; -+ } - } - - void panfrost_devfreq_resume(struct panfrost_device *pfdev) -diff --git a/drivers/gpu/drm/panfrost/panfrost_devfreq.h b/drivers/gpu/drm/panfrost/panfrost_devfreq.h -index 210269944687..db6ea48e21f9 100644 ---- a/drivers/gpu/drm/panfrost/panfrost_devfreq.h -+++ b/drivers/gpu/drm/panfrost/panfrost_devfreq.h -@@ -8,12 +8,14 @@ - #include - - struct devfreq; -+struct opp_table; - struct thermal_cooling_device; - - struct panfrost_device; - - struct panfrost_devfreq { - struct devfreq *devfreq; -+ struct opp_table *regulators_opp_table; - struct thermal_cooling_device *cooling; - bool opp_of_table_added; - -diff --git a/drivers/gpu/drm/panfrost/panfrost_device.c b/drivers/gpu/drm/panfrost/panfrost_device.c -index f1474b961def..e6896733838a 100644 ---- a/drivers/gpu/drm/panfrost/panfrost_device.c -+++ b/drivers/gpu/drm/panfrost/panfrost_device.c -@@ -225,9 +225,12 @@ int panfrost_device_init(struct panfrost_device *pfdev) - goto out_clk; - } - -- err = panfrost_regulator_init(pfdev); -- if (err) -- goto out_devfreq; -+ /* OPP will handle regulators */ -+ if (!pfdev->pfdevfreq.opp_of_table_added) { -+ err = panfrost_regulator_init(pfdev); -+ if (err) -+ goto out_devfreq; -+ } - - err = panfrost_reset_init(pfdev); - if (err) { - -From d54c64a7033c7d9a55ec3a455a93ccfa09ba9549 Mon Sep 17 00:00:00 2001 -From: Antonio Borneo -Date: Wed, 8 Jul 2020 16:08:36 +0200 -Subject: [PATCH] drm/bridge/synopsys: dsi: allow LP commands in video mode - -Current code only sends LP commands in command mode. - -Allows sending LP commands also in video mode by setting the -proper flag in DSI_VID_MODE_CFG. - -Signed-off-by: Antonio Borneo -Tested-by: Philippe Cornu -Reviewed-by: Philippe Cornu -Acked-by: Neil Armstrong -Signed-off-by: Neil Armstrong -Link: https://patchwork.freedesktop.org/patch/msgid/20200708140836.32418-1-yannick.fertre@st.com -(cherry picked from commit 6188b06e0357b3bc3b91d0b67783681d34ff2b64) ---- - drivers/gpu/drm/bridge/synopsys/dw-mipi-dsi.c | 8 ++++++++ - 1 file changed, 8 insertions(+) - -diff --git a/drivers/gpu/drm/bridge/synopsys/dw-mipi-dsi.c b/drivers/gpu/drm/bridge/synopsys/dw-mipi-dsi.c -index d580b2aa4ce9..d41ce1de1067 100644 ---- a/drivers/gpu/drm/bridge/synopsys/dw-mipi-dsi.c -+++ b/drivers/gpu/drm/bridge/synopsys/dw-mipi-dsi.c -@@ -89,6 +89,7 @@ - #define VID_MODE_TYPE_NON_BURST_SYNC_EVENTS 0x1 - #define VID_MODE_TYPE_BURST 0x2 - #define VID_MODE_TYPE_MASK 0x3 -+#define ENABLE_LOW_POWER_CMD BIT(15) - #define VID_MODE_VPG_ENABLE BIT(16) - #define VID_MODE_VPG_HORIZONTAL BIT(24) - -@@ -367,6 +368,13 @@ static void dw_mipi_message_config(struct dw_mipi_dsi *dsi, - - dsi_write(dsi, DSI_LPCLK_CTRL, lpm ? 0 : PHY_TXREQUESTCLKHS); - dsi_write(dsi, DSI_CMD_MODE_CFG, val); -+ -+ val = dsi_read(dsi, DSI_VID_MODE_CFG); -+ if (lpm) -+ val |= ENABLE_LOW_POWER_CMD; -+ else -+ val &= ~ENABLE_LOW_POWER_CMD; -+ dsi_write(dsi, DSI_VID_MODE_CFG, val); - } - - static int dw_mipi_dsi_gen_pkt_hdr_write(struct dw_mipi_dsi *dsi, u32 hdr_val) - -From 071e4591b5ddac631fe65bd2e527d7ca28105c5b Mon Sep 17 00:00:00 2001 -From: Antonio Borneo -Date: Wed, 1 Jul 2020 16:31:31 +0200 -Subject: [PATCH] drm/bridge/synopsys: dsi: allow sending longer LP commands - -Current code does not properly computes the max length of LP -commands that can be send during H or V sync, and rely on static -values. -Limiting the max LP length to 4 byte during the V-sync is overly -conservative. - -Relax the limit and allows longer LP commands (16 bytes) to be -sent during V-sync. - -Signed-off-by: Antonio Borneo -Tested-by: Philippe Cornu -Reviewed-by: Philippe Cornu -Acked-by: Neil Armstrong -Signed-off-by: Neil Armstrong -Link: https://patchwork.freedesktop.org/patch/msgid/20200701143131.841-1-yannick.fertre@st.com -(cherry picked from commit 9e025e80660fe35432c81e67d401109d8e7b0ff4) ---- - drivers/gpu/drm/bridge/synopsys/dw-mipi-dsi.c | 17 +++++++++-------- - 1 file changed, 9 insertions(+), 8 deletions(-) - -diff --git a/drivers/gpu/drm/bridge/synopsys/dw-mipi-dsi.c b/drivers/gpu/drm/bridge/synopsys/dw-mipi-dsi.c -index d41ce1de1067..e9a0f42ff99f 100644 ---- a/drivers/gpu/drm/bridge/synopsys/dw-mipi-dsi.c -+++ b/drivers/gpu/drm/bridge/synopsys/dw-mipi-dsi.c -@@ -361,6 +361,15 @@ static void dw_mipi_message_config(struct dw_mipi_dsi *dsi, - bool lpm = msg->flags & MIPI_DSI_MSG_USE_LPM; - u32 val = 0; - -+ /* -+ * TODO dw drv improvements -+ * largest packet sizes during hfp or during vsa/vpb/vfp -+ * should be computed according to byte lane, lane number and only -+ * if sending lp cmds in high speed is enable (PHY_TXREQUESTCLKHS) -+ */ -+ dsi_write(dsi, DSI_DPI_LP_CMD_TIM, OUTVACT_LPCMD_TIME(16) -+ | INVACT_LPCMD_TIME(4)); -+ - if (msg->flags & MIPI_DSI_MSG_REQ_ACK) - val |= ACK_RQST_EN; - if (lpm) -@@ -619,14 +628,6 @@ static void dw_mipi_dsi_dpi_config(struct dw_mipi_dsi *dsi, - dsi_write(dsi, DSI_DPI_VCID, DPI_VCID(dsi->channel)); - dsi_write(dsi, DSI_DPI_COLOR_CODING, color); - dsi_write(dsi, DSI_DPI_CFG_POL, val); -- /* -- * TODO dw drv improvements -- * largest packet sizes during hfp or during vsa/vpb/vfp -- * should be computed according to byte lane, lane number and only -- * if sending lp cmds in high speed is enable (PHY_TXREQUESTCLKHS) -- */ -- dsi_write(dsi, DSI_DPI_LP_CMD_TIM, OUTVACT_LPCMD_TIME(4) -- | INVACT_LPCMD_TIME(4)); - } - - static void dw_mipi_dsi_packet_handler_config(struct dw_mipi_dsi *dsi) - -From b3ba2bd08c57aedc749e4f3e646b4b773147866b Mon Sep 17 00:00:00 2001 -From: Angelo Ribeiro -Date: Mon, 6 Apr 2020 15:49:03 +0200 -Subject: [PATCH] drm/bridge: dw-mipi-dsi.c: Add VPG runtime config through - debugfs - -Add support for the video pattern generator (VPG) BER pattern mode and -configuration in runtime. - -This enables using the debugfs interface to manipulate the VPG after -the pipeline is set. -Also, enables the usage of the VPG BER pattern. - -Changes in v2: - - Added VID_MODE_VPG_MODE - - Solved incompatible return type on __get and __set - -Reported-by: kbuild test robot -Reported-by: Adrian Pop -Signed-off-by: Angelo Ribeiro -Tested-by: Yannick Fertre -Tested-by: Adrian Pop -Acked-by: Neil Armstrong -Cc: Gustavo Pimentel -Cc: Joao Pinto -Cc: Jose Abreu -Signed-off-by: Neil Armstrong -Link: https://patchwork.freedesktop.org/patch/msgid/a809feb7d7153a92e323416f744f1565e995da01.1586180592.git.angelo.ribeiro@synopsys.com -(cherry picked from commit e2435d69204c1f041e5742cac9af301021afa46f) ---- - drivers/gpu/drm/bridge/synopsys/dw-mipi-dsi.c | 98 ++++++++++++++++++++++++--- - 1 file changed, 90 insertions(+), 8 deletions(-) - -diff --git a/drivers/gpu/drm/bridge/synopsys/dw-mipi-dsi.c b/drivers/gpu/drm/bridge/synopsys/dw-mipi-dsi.c -index 8510a84c4c63..0b3825a4fbdb 100644 ---- a/drivers/gpu/drm/bridge/synopsys/dw-mipi-dsi.c -+++ b/drivers/gpu/drm/bridge/synopsys/dw-mipi-dsi.c -@@ -91,6 +91,7 @@ - #define VID_MODE_TYPE_MASK 0x3 - #define ENABLE_LOW_POWER_CMD BIT(15) - #define VID_MODE_VPG_ENABLE BIT(16) -+#define VID_MODE_VPG_MODE BIT(20) - #define VID_MODE_VPG_HORIZONTAL BIT(24) - - #define DSI_VID_PKT_SIZE 0x3c -@@ -221,6 +222,21 @@ - #define PHY_STATUS_TIMEOUT_US 10000 - #define CMD_PKT_STATUS_TIMEOUT_US 20000 - -+#ifdef CONFIG_DEBUG_FS -+#define VPG_DEFS(name, dsi) \ -+ ((void __force *)&((*dsi).vpg_defs.name)) -+ -+#define REGISTER(name, mask, dsi) \ -+ { #name, VPG_DEFS(name, dsi), mask, dsi } -+ -+struct debugfs_entries { -+ const char *name; -+ bool *reg; -+ u32 mask; -+ struct dw_mipi_dsi *dsi; -+}; -+#endif /* CONFIG_DEBUG_FS */ -+ - struct dw_mipi_dsi { - struct drm_bridge bridge; - struct mipi_dsi_host dsi_host; -@@ -238,9 +254,12 @@ struct dw_mipi_dsi { - - #ifdef CONFIG_DEBUG_FS - struct dentry *debugfs; -- -- bool vpg; -- bool vpg_horizontal; -+ struct debugfs_entries *debugfs_vpg; -+ struct { -+ bool vpg; -+ bool vpg_horizontal; -+ bool vpg_ber_pattern; -+ } vpg_defs; - #endif /* CONFIG_DEBUG_FS */ - - struct dw_mipi_dsi *master; /* dual-dsi master ptr */ -@@ -545,9 +564,11 @@ static void dw_mipi_dsi_video_mode_config(struct dw_mipi_dsi *dsi) - val |= VID_MODE_TYPE_NON_BURST_SYNC_EVENTS; - - #ifdef CONFIG_DEBUG_FS -- if (dsi->vpg) { -+ if (dsi->vpg_defs.vpg) { - val |= VID_MODE_VPG_ENABLE; -- val |= dsi->vpg_horizontal ? VID_MODE_VPG_HORIZONTAL : 0; -+ val |= dsi->vpg_defs.vpg_horizontal ? -+ VID_MODE_VPG_HORIZONTAL : 0; -+ val |= dsi->vpg_defs.vpg_ber_pattern ? VID_MODE_VPG_MODE : 0; - } - #endif /* CONFIG_DEBUG_FS */ - -@@ -978,6 +999,68 @@ static const struct drm_bridge_funcs dw_mipi_dsi_bridge_funcs = { - - #ifdef CONFIG_DEBUG_FS - -+int dw_mipi_dsi_debugfs_write(void *data, u64 val) -+{ -+ struct debugfs_entries *vpg = data; -+ struct dw_mipi_dsi *dsi; -+ u32 mode_cfg; -+ -+ if (!vpg) -+ return -ENODEV; -+ -+ dsi = vpg->dsi; -+ -+ *vpg->reg = (bool)val; -+ -+ mode_cfg = dsi_read(dsi, DSI_VID_MODE_CFG); -+ -+ if (*vpg->reg) -+ mode_cfg |= vpg->mask; -+ else -+ mode_cfg &= ~vpg->mask; -+ -+ dsi_write(dsi, DSI_VID_MODE_CFG, mode_cfg); -+ -+ return 0; -+} -+ -+int dw_mipi_dsi_debugfs_show(void *data, u64 *val) -+{ -+ struct debugfs_entries *vpg = data; -+ -+ if (!vpg) -+ return -ENODEV; -+ -+ *val = *vpg->reg; -+ -+ return 0; -+} -+ -+DEFINE_DEBUGFS_ATTRIBUTE(fops_x32, dw_mipi_dsi_debugfs_show, -+ dw_mipi_dsi_debugfs_write, "%llu\n"); -+ -+static void debugfs_create_files(void *data) -+{ -+ struct dw_mipi_dsi *dsi = data; -+ struct debugfs_entries debugfs[] = { -+ REGISTER(vpg, VID_MODE_VPG_ENABLE, dsi), -+ REGISTER(vpg_horizontal, VID_MODE_VPG_HORIZONTAL, dsi), -+ REGISTER(vpg_ber_pattern, VID_MODE_VPG_MODE, dsi), -+ }; -+ int i; -+ -+ dsi->debugfs_vpg = kmalloc(sizeof(debugfs), GFP_KERNEL); -+ if (!dsi->debugfs_vpg) -+ return; -+ -+ memcpy(dsi->debugfs_vpg, debugfs, sizeof(debugfs)); -+ -+ for (i = 0; i < ARRAY_SIZE(debugfs); i++) -+ debugfs_create_file(dsi->debugfs_vpg[i].name, 0644, -+ dsi->debugfs, &dsi->debugfs_vpg[i], -+ &fops_x32); -+} -+ - static void dw_mipi_dsi_debugfs_init(struct dw_mipi_dsi *dsi) - { - dsi->debugfs = debugfs_create_dir(dev_name(dsi->dev), NULL); -@@ -986,14 +1069,13 @@ static void dw_mipi_dsi_debugfs_init(struct dw_mipi_dsi *dsi) - return; - } - -- debugfs_create_bool("vpg", 0660, dsi->debugfs, &dsi->vpg); -- debugfs_create_bool("vpg_horizontal", 0660, dsi->debugfs, -- &dsi->vpg_horizontal); -+ debugfs_create_files(dsi); - } - - static void dw_mipi_dsi_debugfs_remove(struct dw_mipi_dsi *dsi) - { - debugfs_remove_recursive(dsi->debugfs); -+ kfree(dsi->debugfs_vpg); - } - - #else - -From b48c8b2c43459f3c3bf28ffdec42553844412a83 Mon Sep 17 00:00:00 2001 -From: Neil Armstrong -Date: Mon, 7 Sep 2020 12:27:11 +0200 -Subject: [PATCH] drm/bridge: dw-mipi-dsi: fix dw_mipi_dsi_debugfs_show/write - warnings - -This fixes the following warnings while building in W=1 : -dw-mipi-dsi.c:1002:5: warning: no previous prototype for 'dw_mipi_dsi_debugfs_write' [-Wmissing-prototypes] -dw-mipi-dsi.c:1027:5: warning: no previous prototype for 'dw_mipi_dsi_debugfs_show' [-Wmissing-prototypes] - -Fixes: e2435d69204c ("drm/bridge: dw-mipi-dsi.c: Add VPG runtime config through debugfs") -Reported-by: kernel test robot -Signed-off-by: Neil Armstrong -Reviewed-by: Daniel Vetter -Cc: Angelo Ribeiro -Cc: Maxime Ripard -Cc: Maarten Lankhorst -Cc: Thomas Zimmermann -Link: https://patchwork.freedesktop.org/patch/msgid/20200907102711.23748-1-narmstrong@baylibre.com -(cherry picked from commit 25c4bcf9858e3e8752985fa0cda64a212ea328b7) ---- - drivers/gpu/drm/bridge/synopsys/dw-mipi-dsi.c | 4 ++-- - 1 file changed, 2 insertions(+), 2 deletions(-) - -diff --git a/drivers/gpu/drm/bridge/synopsys/dw-mipi-dsi.c b/drivers/gpu/drm/bridge/synopsys/dw-mipi-dsi.c -index 0b3825a4fbdb..52f5c5a2ed64 100644 ---- a/drivers/gpu/drm/bridge/synopsys/dw-mipi-dsi.c -+++ b/drivers/gpu/drm/bridge/synopsys/dw-mipi-dsi.c -@@ -999,7 +999,7 @@ static const struct drm_bridge_funcs dw_mipi_dsi_bridge_funcs = { - - #ifdef CONFIG_DEBUG_FS - --int dw_mipi_dsi_debugfs_write(void *data, u64 val) -+static int dw_mipi_dsi_debugfs_write(void *data, u64 val) - { - struct debugfs_entries *vpg = data; - struct dw_mipi_dsi *dsi; -@@ -1024,7 +1024,7 @@ int dw_mipi_dsi_debugfs_write(void *data, u64 val) - return 0; - } - --int dw_mipi_dsi_debugfs_show(void *data, u64 *val) -+static int dw_mipi_dsi_debugfs_show(void *data, u64 *val) - { - struct debugfs_entries *vpg = data; - - -From 0765583a5df3824d6347f89088656d52f70d9de0 Mon Sep 17 00:00:00 2001 -From: Gerd Hoffmann -Date: Mon, 7 Sep 2020 13:24:25 +0200 -Subject: [PATCH] drm: allow limiting the scatter list size. - -Add drm_device argument to drm_prime_pages_to_sg(), so we can -call dma_max_mapping_size() to figure the segment size limit -and call into __sg_alloc_table_from_pages() with the correct -limit. - -This fixes virtio-gpu with sev. Possibly it'll fix other bugs -too given that drm seems to totaly ignore segment size limits -so far ... - -v2: place max_segment in drm driver not gem object. -v3: move max_segment next to the other gem fields. -v4: just use dma_max_mapping_size(). - -Signed-off-by: Gerd Hoffmann -Reviewed-by: Daniel Vetter -Link: http://patchwork.freedesktop.org/patch/msgid/20200907112425.15610-2-kraxel@redhat.com -(cherry picked from commit 707d561f77b5e2a6f90c9786bee44ee7a8dedc7e) ---- - drivers/gpu/drm/amd/amdgpu/amdgpu_dma_buf.c | 3 ++- - drivers/gpu/drm/drm_gem_shmem_helper.c | 2 +- - drivers/gpu/drm/drm_prime.c | 13 ++++++++++--- - drivers/gpu/drm/etnaviv/etnaviv_gem.c | 3 ++- - drivers/gpu/drm/etnaviv/etnaviv_gem_prime.c | 2 +- - drivers/gpu/drm/msm/msm_gem.c | 2 +- - drivers/gpu/drm/msm/msm_gem_prime.c | 2 +- - drivers/gpu/drm/nouveau/nouveau_prime.c | 2 +- - drivers/gpu/drm/radeon/radeon_prime.c | 2 +- - drivers/gpu/drm/rockchip/rockchip_drm_gem.c | 5 +++-- - drivers/gpu/drm/tegra/gem.c | 2 +- - drivers/gpu/drm/vgem/vgem_drv.c | 2 +- - drivers/gpu/drm/xen/xen_drm_front_gem.c | 3 ++- - include/drm/drm_prime.h | 3 ++- - 14 files changed, 29 insertions(+), 17 deletions(-) - -diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_dma_buf.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_dma_buf.c -index 519ce4427fce..d7050ab95946 100644 ---- a/drivers/gpu/drm/amd/amdgpu/amdgpu_dma_buf.c -+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_dma_buf.c -@@ -302,7 +302,8 @@ static struct sg_table *amdgpu_dma_buf_map(struct dma_buf_attachment *attach, - - switch (bo->tbo.mem.mem_type) { - case TTM_PL_TT: -- sgt = drm_prime_pages_to_sg(bo->tbo.ttm->pages, -+ sgt = drm_prime_pages_to_sg(obj->dev, -+ bo->tbo.ttm->pages, - bo->tbo.num_pages); - if (IS_ERR(sgt)) - return sgt; -diff --git a/drivers/gpu/drm/drm_gem_shmem_helper.c b/drivers/gpu/drm/drm_gem_shmem_helper.c -index 4b7cfbac4daa..0a952f27c184 100644 ---- a/drivers/gpu/drm/drm_gem_shmem_helper.c -+++ b/drivers/gpu/drm/drm_gem_shmem_helper.c -@@ -656,7 +656,7 @@ struct sg_table *drm_gem_shmem_get_sg_table(struct drm_gem_object *obj) - - WARN_ON(shmem->base.import_attach); - -- return drm_prime_pages_to_sg(shmem->pages, obj->size >> PAGE_SHIFT); -+ return drm_prime_pages_to_sg(obj->dev, shmem->pages, obj->size >> PAGE_SHIFT); - } - EXPORT_SYMBOL_GPL(drm_gem_shmem_get_sg_table); - -diff --git a/drivers/gpu/drm/drm_prime.c b/drivers/gpu/drm/drm_prime.c -index 1693aa7c14b5..8a6a3c99b7d8 100644 ---- a/drivers/gpu/drm/drm_prime.c -+++ b/drivers/gpu/drm/drm_prime.c -@@ -802,9 +802,11 @@ static const struct dma_buf_ops drm_gem_prime_dmabuf_ops = { - * - * This is useful for implementing &drm_gem_object_funcs.get_sg_table. - */ --struct sg_table *drm_prime_pages_to_sg(struct page **pages, unsigned int nr_pages) -+struct sg_table *drm_prime_pages_to_sg(struct drm_device *dev, -+ struct page **pages, unsigned int nr_pages) - { - struct sg_table *sg = NULL; -+ size_t max_segment = 0; - int ret; - - sg = kmalloc(sizeof(struct sg_table), GFP_KERNEL); -@@ -813,8 +815,13 @@ struct sg_table *drm_prime_pages_to_sg(struct page **pages, unsigned int nr_page - goto out; - } - -- ret = sg_alloc_table_from_pages(sg, pages, nr_pages, 0, -- nr_pages << PAGE_SHIFT, GFP_KERNEL); -+ if (dev) -+ max_segment = dma_max_mapping_size(dev->dev); -+ if (max_segment == 0 || max_segment > SCATTERLIST_MAX_SEGMENT) -+ max_segment = SCATTERLIST_MAX_SEGMENT; -+ ret = __sg_alloc_table_from_pages(sg, pages, nr_pages, 0, -+ nr_pages << PAGE_SHIFT, -+ max_segment, GFP_KERNEL); - if (ret) - goto out; - -diff --git a/drivers/gpu/drm/etnaviv/etnaviv_gem.c b/drivers/gpu/drm/etnaviv/etnaviv_gem.c -index f06e19e7be04..ea19f1d27275 100644 ---- a/drivers/gpu/drm/etnaviv/etnaviv_gem.c -+++ b/drivers/gpu/drm/etnaviv/etnaviv_gem.c -@@ -103,7 +103,8 @@ struct page **etnaviv_gem_get_pages(struct etnaviv_gem_object *etnaviv_obj) - int npages = etnaviv_obj->base.size >> PAGE_SHIFT; - struct sg_table *sgt; - -- sgt = drm_prime_pages_to_sg(etnaviv_obj->pages, npages); -+ sgt = drm_prime_pages_to_sg(etnaviv_obj->base.dev, -+ etnaviv_obj->pages, npages); - if (IS_ERR(sgt)) { - dev_err(dev->dev, "failed to allocate sgt: %ld\n", - PTR_ERR(sgt)); -diff --git a/drivers/gpu/drm/etnaviv/etnaviv_gem_prime.c b/drivers/gpu/drm/etnaviv/etnaviv_gem_prime.c -index 6d9e5c3c4dd5..4aa3426a9ba4 100644 ---- a/drivers/gpu/drm/etnaviv/etnaviv_gem_prime.c -+++ b/drivers/gpu/drm/etnaviv/etnaviv_gem_prime.c -@@ -19,7 +19,7 @@ struct sg_table *etnaviv_gem_prime_get_sg_table(struct drm_gem_object *obj) - if (WARN_ON(!etnaviv_obj->pages)) /* should have already pinned! */ - return ERR_PTR(-EINVAL); - -- return drm_prime_pages_to_sg(etnaviv_obj->pages, npages); -+ return drm_prime_pages_to_sg(obj->dev, etnaviv_obj->pages, npages); - } - - void *etnaviv_gem_prime_vmap(struct drm_gem_object *obj) -diff --git a/drivers/gpu/drm/msm/msm_gem.c b/drivers/gpu/drm/msm/msm_gem.c -index b2f49152b4d4..b4553caaa196 100644 ---- a/drivers/gpu/drm/msm/msm_gem.c -+++ b/drivers/gpu/drm/msm/msm_gem.c -@@ -126,7 +126,7 @@ static struct page **get_pages(struct drm_gem_object *obj) - - msm_obj->pages = p; - -- msm_obj->sgt = drm_prime_pages_to_sg(p, npages); -+ msm_obj->sgt = drm_prime_pages_to_sg(obj->dev, p, npages); - if (IS_ERR(msm_obj->sgt)) { - void *ptr = ERR_CAST(msm_obj->sgt); - -diff --git a/drivers/gpu/drm/msm/msm_gem_prime.c b/drivers/gpu/drm/msm/msm_gem_prime.c -index d7c8948427fe..515ef80816a0 100644 ---- a/drivers/gpu/drm/msm/msm_gem_prime.c -+++ b/drivers/gpu/drm/msm/msm_gem_prime.c -@@ -19,7 +19,7 @@ struct sg_table *msm_gem_prime_get_sg_table(struct drm_gem_object *obj) - if (WARN_ON(!msm_obj->pages)) /* should have already pinned! */ - return NULL; - -- return drm_prime_pages_to_sg(msm_obj->pages, npages); -+ return drm_prime_pages_to_sg(obj->dev, msm_obj->pages, npages); - } - - void *msm_gem_prime_vmap(struct drm_gem_object *obj) -diff --git a/drivers/gpu/drm/nouveau/nouveau_prime.c b/drivers/gpu/drm/nouveau/nouveau_prime.c -index bae6a3eccee0..7766b810653f 100644 ---- a/drivers/gpu/drm/nouveau/nouveau_prime.c -+++ b/drivers/gpu/drm/nouveau/nouveau_prime.c -@@ -32,7 +32,7 @@ struct sg_table *nouveau_gem_prime_get_sg_table(struct drm_gem_object *obj) - struct nouveau_bo *nvbo = nouveau_gem_object(obj); - int npages = nvbo->bo.num_pages; - -- return drm_prime_pages_to_sg(nvbo->bo.ttm->pages, npages); -+ return drm_prime_pages_to_sg(obj->dev, nvbo->bo.ttm->pages, npages); - } - - void *nouveau_gem_prime_vmap(struct drm_gem_object *obj) -diff --git a/drivers/gpu/drm/radeon/radeon_prime.c b/drivers/gpu/drm/radeon/radeon_prime.c -index b906e8fbd5f3..ea4c900e7c41 100644 ---- a/drivers/gpu/drm/radeon/radeon_prime.c -+++ b/drivers/gpu/drm/radeon/radeon_prime.c -@@ -36,7 +36,7 @@ struct sg_table *radeon_gem_prime_get_sg_table(struct drm_gem_object *obj) - struct radeon_bo *bo = gem_to_radeon_bo(obj); - int npages = bo->tbo.num_pages; - -- return drm_prime_pages_to_sg(bo->tbo.ttm->pages, npages); -+ return drm_prime_pages_to_sg(obj->dev, bo->tbo.ttm->pages, npages); - } - - void *radeon_gem_prime_vmap(struct drm_gem_object *obj) -diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_gem.c b/drivers/gpu/drm/rockchip/rockchip_drm_gem.c -index b9275ba7c5a5..0055d86576f7 100644 ---- a/drivers/gpu/drm/rockchip/rockchip_drm_gem.c -+++ b/drivers/gpu/drm/rockchip/rockchip_drm_gem.c -@@ -85,7 +85,8 @@ static int rockchip_gem_get_pages(struct rockchip_gem_object *rk_obj) - - rk_obj->num_pages = rk_obj->base.size >> PAGE_SHIFT; - -- rk_obj->sgt = drm_prime_pages_to_sg(rk_obj->pages, rk_obj->num_pages); -+ rk_obj->sgt = drm_prime_pages_to_sg(rk_obj->base.dev, -+ rk_obj->pages, rk_obj->num_pages); - if (IS_ERR(rk_obj->sgt)) { - ret = PTR_ERR(rk_obj->sgt); - goto err_put_pages; -@@ -442,7 +443,7 @@ struct sg_table *rockchip_gem_prime_get_sg_table(struct drm_gem_object *obj) - int ret; - - if (rk_obj->pages) -- return drm_prime_pages_to_sg(rk_obj->pages, rk_obj->num_pages); -+ return drm_prime_pages_to_sg(obj->dev, rk_obj->pages, rk_obj->num_pages); - - sgt = kzalloc(sizeof(*sgt), GFP_KERNEL); - if (!sgt) -diff --git a/drivers/gpu/drm/tegra/gem.c b/drivers/gpu/drm/tegra/gem.c -index 723df142a981..47e2935b8c68 100644 ---- a/drivers/gpu/drm/tegra/gem.c -+++ b/drivers/gpu/drm/tegra/gem.c -@@ -284,7 +284,7 @@ static int tegra_bo_get_pages(struct drm_device *drm, struct tegra_bo *bo) - - bo->num_pages = bo->gem.size >> PAGE_SHIFT; - -- bo->sgt = drm_prime_pages_to_sg(bo->pages, bo->num_pages); -+ bo->sgt = drm_prime_pages_to_sg(bo->gem.dev, bo->pages, bo->num_pages); - if (IS_ERR(bo->sgt)) { - err = PTR_ERR(bo->sgt); - goto put_pages; -diff --git a/drivers/gpu/drm/vgem/vgem_drv.c b/drivers/gpu/drm/vgem/vgem_drv.c -index a775feda1cc7..4f0fd71d2da1 100644 ---- a/drivers/gpu/drm/vgem/vgem_drv.c -+++ b/drivers/gpu/drm/vgem/vgem_drv.c -@@ -321,7 +321,7 @@ static struct sg_table *vgem_prime_get_sg_table(struct drm_gem_object *obj) - { - struct drm_vgem_gem_object *bo = to_vgem_bo(obj); - -- return drm_prime_pages_to_sg(bo->pages, bo->base.size >> PAGE_SHIFT); -+ return drm_prime_pages_to_sg(obj->dev, bo->pages, bo->base.size >> PAGE_SHIFT); - } - - static struct drm_gem_object* vgem_prime_import(struct drm_device *dev, -diff --git a/drivers/gpu/drm/xen/xen_drm_front_gem.c b/drivers/gpu/drm/xen/xen_drm_front_gem.c -index 534daf37c97e..a8aefaa38bd3 100644 ---- a/drivers/gpu/drm/xen/xen_drm_front_gem.c -+++ b/drivers/gpu/drm/xen/xen_drm_front_gem.c -@@ -180,7 +180,8 @@ struct sg_table *xen_drm_front_gem_get_sg_table(struct drm_gem_object *gem_obj) - if (!xen_obj->pages) - return ERR_PTR(-ENOMEM); - -- return drm_prime_pages_to_sg(xen_obj->pages, xen_obj->num_pages); -+ return drm_prime_pages_to_sg(gem_obj->dev, -+ xen_obj->pages, xen_obj->num_pages); - } - - struct drm_gem_object * -diff --git a/include/drm/drm_prime.h b/include/drm/drm_prime.h -index 9af7422b44cf..bf141e74a1c2 100644 ---- a/include/drm/drm_prime.h -+++ b/include/drm/drm_prime.h -@@ -88,7 +88,8 @@ void drm_gem_dmabuf_vunmap(struct dma_buf *dma_buf, void *vaddr); - int drm_gem_prime_mmap(struct drm_gem_object *obj, struct vm_area_struct *vma); - int drm_gem_dmabuf_mmap(struct dma_buf *dma_buf, struct vm_area_struct *vma); - --struct sg_table *drm_prime_pages_to_sg(struct page **pages, unsigned int nr_pages); -+struct sg_table *drm_prime_pages_to_sg(struct drm_device *dev, -+ struct page **pages, unsigned int nr_pages); - struct dma_buf *drm_gem_prime_export(struct drm_gem_object *obj, - int flags); - - -From 0839a46485ed6cca60e13a706b8501267bd23bfa Mon Sep 17 00:00:00 2001 -From: Marek Szyprowski -Date: Fri, 8 May 2020 16:04:44 +0200 -Subject: [PATCH] drm: prime: add common helper to check scatterlist contiguity - -It is a common operation done by DRM drivers to check the contiguity -of the DMA-mapped buffer described by a scatterlist in the -sg_table object. Let's add a common helper for this operation. - -Signed-off-by: Marek Szyprowski -Reviewed-by: Andrzej Hajda -Reviewed-by: Robin Murphy -(cherry picked from commit d46e7ae24b81533d21edfa90914d27efa0c5f85d) ---- - drivers/gpu/drm/drm_gem_cma_helper.c | 23 +++-------------------- - drivers/gpu/drm/drm_prime.c | 31 +++++++++++++++++++++++++++++++ - include/drm/drm_prime.h | 2 ++ - 3 files changed, 36 insertions(+), 20 deletions(-) - -diff --git a/drivers/gpu/drm/drm_gem_cma_helper.c b/drivers/gpu/drm/drm_gem_cma_helper.c -index 822edeadbab3..59b9ca207b42 100644 ---- a/drivers/gpu/drm/drm_gem_cma_helper.c -+++ b/drivers/gpu/drm/drm_gem_cma_helper.c -@@ -471,26 +471,9 @@ drm_gem_cma_prime_import_sg_table(struct drm_device *dev, - { - struct drm_gem_cma_object *cma_obj; - -- if (sgt->nents != 1) { -- /* check if the entries in the sg_table are contiguous */ -- dma_addr_t next_addr = sg_dma_address(sgt->sgl); -- struct scatterlist *s; -- unsigned int i; -- -- for_each_sg(sgt->sgl, s, sgt->nents, i) { -- /* -- * sg_dma_address(s) is only valid for entries -- * that have sg_dma_len(s) != 0 -- */ -- if (!sg_dma_len(s)) -- continue; -- -- if (sg_dma_address(s) != next_addr) -- return ERR_PTR(-EINVAL); -- -- next_addr = sg_dma_address(s) + sg_dma_len(s); -- } -- } -+ /* check if the entries in the sg_table are contiguous */ -+ if (drm_prime_get_contiguous_size(sgt) < attach->dmabuf->size) -+ return ERR_PTR(-EINVAL); - - /* Create a CMA GEM buffer. */ - cma_obj = __drm_gem_cma_create(dev, attach->dmabuf->size); -diff --git a/drivers/gpu/drm/drm_prime.c b/drivers/gpu/drm/drm_prime.c -index 8a6a3c99b7d8..5a134c63856f 100644 ---- a/drivers/gpu/drm/drm_prime.c -+++ b/drivers/gpu/drm/drm_prime.c -@@ -832,6 +832,37 @@ struct sg_table *drm_prime_pages_to_sg(struct drm_device *dev, - } - EXPORT_SYMBOL(drm_prime_pages_to_sg); - -+/** -+ * drm_prime_get_contiguous_size - returns the contiguous size of the buffer -+ * @sgt: sg_table describing the buffer to check -+ * -+ * This helper calculates the contiguous size in the DMA address space -+ * of the the buffer described by the provided sg_table. -+ * -+ * This is useful for implementing -+ * &drm_gem_object_funcs.gem_prime_import_sg_table. -+ */ -+unsigned long drm_prime_get_contiguous_size(struct sg_table *sgt) -+{ -+ dma_addr_t expected = sg_dma_address(sgt->sgl); -+ struct scatterlist *sg; -+ unsigned long size = 0; -+ int i; -+ -+ for_each_sgtable_dma_sg(sgt, sg, i) { -+ unsigned int len = sg_dma_len(sg); -+ -+ if (!len) -+ break; -+ if (sg_dma_address(sg) != expected) -+ break; -+ expected += len; -+ size += len; -+ } -+ return size; -+} -+EXPORT_SYMBOL(drm_prime_get_contiguous_size); -+ - /** - * drm_gem_prime_export - helper library implementation of the export callback - * @obj: GEM object to export -diff --git a/include/drm/drm_prime.h b/include/drm/drm_prime.h -index bf141e74a1c2..0f69f9fbf12c 100644 ---- a/include/drm/drm_prime.h -+++ b/include/drm/drm_prime.h -@@ -93,6 +93,8 @@ struct sg_table *drm_prime_pages_to_sg(struct drm_device *dev, - struct dma_buf *drm_gem_prime_export(struct drm_gem_object *obj, - int flags); - -+unsigned long drm_prime_get_contiguous_size(struct sg_table *sgt); -+ - /* helper functions for importing */ - struct drm_gem_object *drm_gem_prime_import_dev(struct drm_device *dev, - struct dma_buf *dma_buf, - -From 4e60d2c4b502537362bae39f3d15b56c41a20648 Mon Sep 17 00:00:00 2001 -From: Marek Szyprowski -Date: Fri, 8 May 2020 16:05:14 +0200 -Subject: [PATCH] drm: prime: use sgtable iterators in - drm_prime_sg_to_page_addr_arrays() - -Replace the current hand-crafted code for extracting pages and DMA -addresses from the given scatterlist by the much more robust -code based on the generic scatterlist iterators and recently -introduced sg_table-based wrappers. The resulting code is simple and -easy to understand, so the comment describing the old code is no -longer needed. - -Signed-off-by: Marek Szyprowski -Reviewed-by: Andrzej Hajda -Reviewed-by: Robin Murphy -(cherry picked from commit 0552daac2d18fc92c71c94492476b8eb521227e9) ---- - drivers/gpu/drm/drm_prime.c | 49 ++++++++++++++------------------------------- - 1 file changed, 15 insertions(+), 34 deletions(-) - -diff --git a/drivers/gpu/drm/drm_prime.c b/drivers/gpu/drm/drm_prime.c -index 5a134c63856f..9d2643f2d9e7 100644 ---- a/drivers/gpu/drm/drm_prime.c -+++ b/drivers/gpu/drm/drm_prime.c -@@ -997,45 +997,26 @@ EXPORT_SYMBOL(drm_gem_prime_import); - int drm_prime_sg_to_page_addr_arrays(struct sg_table *sgt, struct page **pages, - dma_addr_t *addrs, int max_entries) - { -- unsigned count; -- struct scatterlist *sg; -- struct page *page; -- u32 page_len, page_index; -- dma_addr_t addr; -- u32 dma_len, dma_index; -- -- /* -- * Scatterlist elements contains both pages and DMA addresses, but -- * one shoud not assume 1:1 relation between them. The sg->length is -- * the size of the physical memory chunk described by the sg->page, -- * while sg_dma_len(sg) is the size of the DMA (IO virtual) chunk -- * described by the sg_dma_address(sg). -- */ -- page_index = 0; -- dma_index = 0; -- for_each_sg(sgt->sgl, sg, sgt->nents, count) { -- page_len = sg->length; -- page = sg_page(sg); -- dma_len = sg_dma_len(sg); -- addr = sg_dma_address(sg); -- -- while (pages && page_len > 0) { -- if (WARN_ON(page_index >= max_entries)) -+ struct sg_dma_page_iter dma_iter; -+ struct sg_page_iter page_iter; -+ struct page **p = pages; -+ dma_addr_t *a = addrs; -+ -+ if (pages) { -+ for_each_sgtable_page(sgt, &page_iter, 0) { -+ if (WARN_ON(p - pages >= max_entries)) - return -1; -- pages[page_index] = page; -- page++; -- page_len -= PAGE_SIZE; -- page_index++; -+ *p++ = sg_page_iter_page(&page_iter); - } -- while (addrs && dma_len > 0) { -- if (WARN_ON(dma_index >= max_entries)) -+ } -+ if (addrs) { -+ for_each_sgtable_dma_page(sgt, &dma_iter, 0) { -+ if (WARN_ON(a - addrs >= max_entries)) - return -1; -- addrs[dma_index] = addr; -- addr += PAGE_SIZE; -- dma_len -= PAGE_SIZE; -- dma_index++; -+ *a++ = sg_page_iter_dma_address(&dma_iter); - } - } -+ - return 0; - } - EXPORT_SYMBOL(drm_prime_sg_to_page_addr_arrays); - -From ec3929e32f4ca8176edcb0d5ba72ea2051ccfd11 Mon Sep 17 00:00:00 2001 -From: Marek Szyprowski -Date: Mon, 11 May 2020 12:27:54 +0200 -Subject: [PATCH] drm: core: fix common struct sg_table related issues - -The Documentation/DMA-API-HOWTO.txt states that the dma_map_sg() function -returns the number of the created entries in the DMA address space. -However the subsequent calls to the dma_sync_sg_for_{device,cpu}() and -dma_unmap_sg must be called with the original number of the entries -passed to the dma_map_sg(). - -struct sg_table is a common structure used for describing a non-contiguous -memory buffer, used commonly in the DRM and graphics subsystems. It -consists of a scatterlist with memory pages and DMA addresses (sgl entry), -as well as the number of scatterlist entries: CPU pages (orig_nents entry) -and DMA mapped pages (nents entry). - -It turned out that it was a common mistake to misuse nents and orig_nents -entries, calling DMA-mapping functions with a wrong number of entries or -ignoring the number of mapped entries returned by the dma_map_sg() -function. - -To avoid such issues, lets use a common dma-mapping wrappers operating -directly on the struct sg_table objects and use scatterlist page -iterators where possible. This, almost always, hides references to the -nents and orig_nents entries, making the code robust, easier to follow -and copy/paste safe. - -Signed-off-by: Marek Szyprowski -Reviewed-by: Andrzej Hajda -Reviewed-by: Robin Murphy -(cherry picked from commit 6c6fa39ca958d5313ff90d3e6c3064e0043c1da3) ---- - drivers/gpu/drm/drm_cache.c | 2 +- - drivers/gpu/drm/drm_gem_shmem_helper.c | 14 +++++++++----- - drivers/gpu/drm/drm_prime.c | 11 ++++++----- - 3 files changed, 16 insertions(+), 11 deletions(-) - -diff --git a/drivers/gpu/drm/drm_cache.c b/drivers/gpu/drm/drm_cache.c -index 03e01b000f7a..0fe3c496002a 100644 ---- a/drivers/gpu/drm/drm_cache.c -+++ b/drivers/gpu/drm/drm_cache.c -@@ -127,7 +127,7 @@ drm_clflush_sg(struct sg_table *st) - struct sg_page_iter sg_iter; - - mb(); /*CLFLUSH is ordered only by using memory barriers*/ -- for_each_sg_page(st->sgl, &sg_iter, st->nents, 0) -+ for_each_sgtable_page(st, &sg_iter, 0) - drm_clflush_page(sg_page_iter_page(&sg_iter)); - mb(); /*Make sure that all cache line entry is flushed*/ - -diff --git a/drivers/gpu/drm/drm_gem_shmem_helper.c b/drivers/gpu/drm/drm_gem_shmem_helper.c -index 0a952f27c184..d77c9f8ff26c 100644 ---- a/drivers/gpu/drm/drm_gem_shmem_helper.c -+++ b/drivers/gpu/drm/drm_gem_shmem_helper.c -@@ -126,8 +126,8 @@ void drm_gem_shmem_free_object(struct drm_gem_object *obj) - drm_prime_gem_destroy(obj, shmem->sgt); - } else { - if (shmem->sgt) { -- dma_unmap_sg(obj->dev->dev, shmem->sgt->sgl, -- shmem->sgt->nents, DMA_BIDIRECTIONAL); -+ dma_unmap_sgtable(obj->dev->dev, shmem->sgt, -+ DMA_BIDIRECTIONAL, 0); - sg_free_table(shmem->sgt); - kfree(shmem->sgt); - } -@@ -424,8 +424,7 @@ void drm_gem_shmem_purge_locked(struct drm_gem_object *obj) - - WARN_ON(!drm_gem_shmem_is_purgeable(shmem)); - -- dma_unmap_sg(obj->dev->dev, shmem->sgt->sgl, -- shmem->sgt->nents, DMA_BIDIRECTIONAL); -+ dma_unmap_sgtable(obj->dev->dev, shmem->sgt, DMA_BIDIRECTIONAL, 0); - sg_free_table(shmem->sgt); - kfree(shmem->sgt); - shmem->sgt = NULL; -@@ -697,12 +696,17 @@ struct sg_table *drm_gem_shmem_get_pages_sgt(struct drm_gem_object *obj) - goto err_put_pages; - } - /* Map the pages for use by the h/w. */ -- dma_map_sg(obj->dev->dev, sgt->sgl, sgt->nents, DMA_BIDIRECTIONAL); -+ ret = dma_map_sgtable(obj->dev->dev, sgt, DMA_BIDIRECTIONAL, 0); -+ if (ret) -+ goto err_free_sgt; - - shmem->sgt = sgt; - - return sgt; - -+err_free_sgt: -+ sg_free_table(sgt); -+ kfree(sgt); - err_put_pages: - drm_gem_shmem_put_pages(shmem); - return ERR_PTR(ret); -diff --git a/drivers/gpu/drm/drm_prime.c b/drivers/gpu/drm/drm_prime.c -index 9d2643f2d9e7..11fe9ff76fd5 100644 ---- a/drivers/gpu/drm/drm_prime.c -+++ b/drivers/gpu/drm/drm_prime.c -@@ -617,6 +617,7 @@ struct sg_table *drm_gem_map_dma_buf(struct dma_buf_attachment *attach, - { - struct drm_gem_object *obj = attach->dmabuf->priv; - struct sg_table *sgt; -+ int ret; - - if (WARN_ON(dir == DMA_NONE)) - return ERR_PTR(-EINVAL); -@@ -626,11 +627,12 @@ struct sg_table *drm_gem_map_dma_buf(struct dma_buf_attachment *attach, - else - sgt = obj->dev->driver->gem_prime_get_sg_table(obj); - -- if (!dma_map_sg_attrs(attach->dev, sgt->sgl, sgt->nents, dir, -- DMA_ATTR_SKIP_CPU_SYNC)) { -+ ret = dma_map_sgtable(attach->dev, sgt, dir, -+ DMA_ATTR_SKIP_CPU_SYNC); -+ if (ret) { - sg_free_table(sgt); - kfree(sgt); -- sgt = ERR_PTR(-ENOMEM); -+ sgt = ERR_PTR(ret); - } - - return sgt; -@@ -652,8 +654,7 @@ void drm_gem_unmap_dma_buf(struct dma_buf_attachment *attach, - if (!sgt) - return; - -- dma_unmap_sg_attrs(attach->dev, sgt->sgl, sgt->nents, dir, -- DMA_ATTR_SKIP_CPU_SYNC); -+ dma_unmap_sgtable(attach->dev, sgt, dir, DMA_ATTR_SKIP_CPU_SYNC); - sg_free_table(sgt); - kfree(sgt); - } - -From 03fcee5f1d9c78e00f2000cf87843020c5fb1634 Mon Sep 17 00:00:00 2001 -From: Marek Szyprowski -Date: Thu, 30 Apr 2020 14:02:47 +0200 -Subject: [PATCH] drm: rockchip: use common helper for a scatterlist contiguity - check - -Use common helper for checking the contiguity of the imported dma-buf. - -Signed-off-by: Marek Szyprowski -Reviewed-by: Robin Murphy -(cherry picked from commit 6a8f15c62cd9235a3a4eb1c96e79131061310d57) ---- - drivers/gpu/drm/rockchip/rockchip_drm_gem.c | 19 +------------------ - 1 file changed, 1 insertion(+), 18 deletions(-) - -diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_gem.c b/drivers/gpu/drm/rockchip/rockchip_drm_gem.c -index 0055d86576f7..d1559146dcce 100644 ---- a/drivers/gpu/drm/rockchip/rockchip_drm_gem.c -+++ b/drivers/gpu/drm/rockchip/rockchip_drm_gem.c -@@ -461,23 +461,6 @@ struct sg_table *rockchip_gem_prime_get_sg_table(struct drm_gem_object *obj) - return sgt; - } - --static unsigned long rockchip_sg_get_contiguous_size(struct sg_table *sgt, -- int count) --{ -- struct scatterlist *s; -- dma_addr_t expected = sg_dma_address(sgt->sgl); -- unsigned int i; -- unsigned long size = 0; -- -- for_each_sg(sgt->sgl, s, count, i) { -- if (sg_dma_address(s) != expected) -- break; -- expected = sg_dma_address(s) + sg_dma_len(s); -- size += sg_dma_len(s); -- } -- return size; --} -- - static int - rockchip_gem_iommu_map_sg(struct drm_device *drm, - struct dma_buf_attachment *attach, -@@ -499,7 +482,7 @@ rockchip_gem_dma_map_sg(struct drm_device *drm, - if (!count) - return -EINVAL; - -- if (rockchip_sg_get_contiguous_size(sg, count) < attach->dmabuf->size) { -+ if (drm_prime_get_contiguous_size(sg) < attach->dmabuf->size) { - DRM_ERROR("failed to map sg_table to contiguous linear address.\n"); - dma_unmap_sg(drm->dev, sg->sgl, sg->nents, - DMA_BIDIRECTIONAL); - -From 11f9a73528dc2bd14e6d7e54cb8df803478eef68 Mon Sep 17 00:00:00 2001 -From: Marek Szyprowski -Date: Tue, 28 Apr 2020 13:10:01 +0200 -Subject: [PATCH] drm: rockchip: fix common struct sg_table related issues - -The Documentation/DMA-API-HOWTO.txt states that the dma_map_sg() function -returns the number of the created entries in the DMA address space. -However the subsequent calls to the dma_sync_sg_for_{device,cpu}() and -dma_unmap_sg must be called with the original number of the entries -passed to the dma_map_sg(). - -struct sg_table is a common structure used for describing a non-contiguous -memory buffer, used commonly in the DRM and graphics subsystems. It -consists of a scatterlist with memory pages and DMA addresses (sgl entry), -as well as the number of scatterlist entries: CPU pages (orig_nents entry) -and DMA mapped pages (nents entry). - -It turned out that it was a common mistake to misuse nents and orig_nents -entries, calling DMA-mapping functions with a wrong number of entries or -ignoring the number of mapped entries returned by the dma_map_sg() -function. - -To avoid such issues, lets use a common dma-mapping wrappers operating -directly on the struct sg_table objects and use scatterlist page -iterators where possible. This, almost always, hides references to the -nents and orig_nents entries, making the code robust, easier to follow -and copy/paste safe. - -Signed-off-by: Marek Szyprowski -Reviewed-by: Robin Murphy -(cherry picked from commit 82c245b592da791c63316e7a82d9b9d01552c0c5) ---- - drivers/gpu/drm/rockchip/rockchip_drm_gem.c | 23 ++++++++++------------- - 1 file changed, 10 insertions(+), 13 deletions(-) - -diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_gem.c b/drivers/gpu/drm/rockchip/rockchip_drm_gem.c -index d1559146dcce..62e5d0970525 100644 ---- a/drivers/gpu/drm/rockchip/rockchip_drm_gem.c -+++ b/drivers/gpu/drm/rockchip/rockchip_drm_gem.c -@@ -36,8 +36,8 @@ static int rockchip_gem_iommu_map(struct rockchip_gem_object *rk_obj) - - rk_obj->dma_addr = rk_obj->mm.start; - -- ret = iommu_map_sg(private->domain, rk_obj->dma_addr, rk_obj->sgt->sgl, -- rk_obj->sgt->nents, prot); -+ ret = iommu_map_sgtable(private->domain, rk_obj->dma_addr, rk_obj->sgt, -+ prot); - if (ret < rk_obj->base.size) { - DRM_ERROR("failed to map buffer: size=%zd request_size=%zd\n", - ret, rk_obj->base.size); -@@ -99,11 +99,10 @@ static int rockchip_gem_get_pages(struct rockchip_gem_object *rk_obj) - * TODO: Replace this by drm_clflush_sg() once it can be implemented - * without relying on symbols that are not exported. - */ -- for_each_sg(rk_obj->sgt->sgl, s, rk_obj->sgt->nents, i) -+ for_each_sgtable_sg(rk_obj->sgt, s, i) - sg_dma_address(s) = sg_phys(s); - -- dma_sync_sg_for_device(drm->dev, rk_obj->sgt->sgl, rk_obj->sgt->nents, -- DMA_TO_DEVICE); -+ dma_sync_sgtable_for_device(drm->dev, rk_obj->sgt, DMA_TO_DEVICE); - - return 0; - -@@ -351,8 +350,8 @@ void rockchip_gem_free_object(struct drm_gem_object *obj) - if (private->domain) { - rockchip_gem_iommu_unmap(rk_obj); - } else { -- dma_unmap_sg(drm->dev, rk_obj->sgt->sgl, -- rk_obj->sgt->nents, DMA_BIDIRECTIONAL); -+ dma_unmap_sgtable(drm->dev, rk_obj->sgt, -+ DMA_BIDIRECTIONAL, 0); - } - drm_prime_gem_destroy(obj, rk_obj->sgt); - } else { -@@ -477,15 +476,13 @@ rockchip_gem_dma_map_sg(struct drm_device *drm, - struct sg_table *sg, - struct rockchip_gem_object *rk_obj) - { -- int count = dma_map_sg(drm->dev, sg->sgl, sg->nents, -- DMA_BIDIRECTIONAL); -- if (!count) -- return -EINVAL; -+ int err = dma_map_sgtable(drm->dev, sg, DMA_BIDIRECTIONAL, 0); -+ if (err) -+ return err; - - if (drm_prime_get_contiguous_size(sg) < attach->dmabuf->size) { - DRM_ERROR("failed to map sg_table to contiguous linear address.\n"); -- dma_unmap_sg(drm->dev, sg->sgl, sg->nents, -- DMA_BIDIRECTIONAL); -+ dma_unmap_sgtable(drm->dev, sg, DMA_BIDIRECTIONAL, 0); - return -EINVAL; - } - - -From 314b770980da1e7d968e8178194de70cbb44fd6c Mon Sep 17 00:00:00 2001 -From: Robin Murphy -Date: Thu, 3 Sep 2020 14:59:23 +0100 -Subject: [PATCH] drm/panfrost: Set DMA max segment size - -Since all we do with scatterlists is map them in the MMU, we don't have -any hardware constraints on how they're laid out. Let the DMA layer know -so it won't warn when DMA API debugging is enabled. - -Signed-off-by: Robin Murphy -Reviewed-by: Steven Price -Signed-off-by: Steven Price -Link: https://patchwork.freedesktop.org/patch/msgid/04371bc36512076b7feee07f854e56b80675d953.1599141563.git.robin.murphy@arm.com -(cherry picked from commit ac5037afefd33fea9a9c1a4a5ac46ece396e7465) ---- - drivers/gpu/drm/panfrost/panfrost_gpu.c | 1 + - 1 file changed, 1 insertion(+) - -diff --git a/drivers/gpu/drm/panfrost/panfrost_gpu.c b/drivers/gpu/drm/panfrost/panfrost_gpu.c -index e0f190e43813..eea049c640a6 100644 ---- a/drivers/gpu/drm/panfrost/panfrost_gpu.c -+++ b/drivers/gpu/drm/panfrost/panfrost_gpu.c -@@ -344,6 +344,7 @@ int panfrost_gpu_init(struct panfrost_device *pfdev) - - dma_set_mask_and_coherent(pfdev->dev, - DMA_BIT_MASK(FIELD_GET(0xff00, pfdev->features.mmu_features))); -+ dma_set_max_seg_size(pfdev->dev, UINT_MAX); - - irq = platform_get_irq_byname(to_platform_device(pfdev->dev), "gpu"); - if (irq <= 0) - -From 99d273baa069a7838597fdd601e01248d12c2fd1 Mon Sep 17 00:00:00 2001 -From: Alex Dewar -Date: Wed, 9 Sep 2020 20:02:08 +0100 -Subject: [PATCH] drm/bridge: dw-mipi-dsi: Use kmemdup cf. kmalloc+memcpy - -kmemdup can be used instead of kmalloc+memcpy. Replace an occurrence of -this pattern. - -Issue identified with Coccinelle. - -Signed-off-by: Alex Dewar -Acked-by: Neil Armstrong -Signed-off-by: Neil Armstrong -Link: https://patchwork.freedesktop.org/patch/msgid/20200909190213.156302-1-alex.dewar90@gmail.com -(cherry picked from commit 33f290811d4c1a09c4e92f5bf0458525835dbcba) ---- - drivers/gpu/drm/bridge/synopsys/dw-mipi-dsi.c | 4 +--- - 1 file changed, 1 insertion(+), 3 deletions(-) - -diff --git a/drivers/gpu/drm/bridge/synopsys/dw-mipi-dsi.c b/drivers/gpu/drm/bridge/synopsys/dw-mipi-dsi.c -index 52f5c5a2ed64..7e9a62ad56e8 100644 ---- a/drivers/gpu/drm/bridge/synopsys/dw-mipi-dsi.c -+++ b/drivers/gpu/drm/bridge/synopsys/dw-mipi-dsi.c -@@ -1049,12 +1049,10 @@ static void debugfs_create_files(void *data) - }; - int i; - -- dsi->debugfs_vpg = kmalloc(sizeof(debugfs), GFP_KERNEL); -+ dsi->debugfs_vpg = kmemdup(debugfs, sizeof(debugfs), GFP_KERNEL); - if (!dsi->debugfs_vpg) - return; - -- memcpy(dsi->debugfs_vpg, debugfs, sizeof(debugfs)); -- - for (i = 0; i < ARRAY_SIZE(debugfs); i++) - debugfs_create_file(dsi->debugfs_vpg[i].name, 0644, - dsi->debugfs, &dsi->debugfs_vpg[i], - -From 0d1797eb5960177619add1f2ad6f2e57341a628b Mon Sep 17 00:00:00 2001 -From: Neil Armstrong -Date: Fri, 4 Sep 2020 14:55:31 +0200 -Subject: [PATCH] drm/bridge: dw-mipi-dsi: permit configuring the escape clock - rate - -The Amlogic D-PHY in the Amlogic AXG SoC Family does support a frequency -higher than 10MHz for the TX Escape Clock, thus make the target rate -configurable. - -Signed-off-by: Neil Armstrong -Reviewed-by: Philippe Cornu -Link: https://patchwork.freedesktop.org/patch/msgid/20200904125531.15248-1-narmstrong@baylibre.com -(cherry picked from commit a328ca7e4af347e47742f36933df0fdac1c24ea5) ---- - drivers/gpu/drm/bridge/synopsys/dw-mipi-dsi.c | 25 ++++++++++++++++++++----- - include/drm/bridge/dw_mipi_dsi.h | 1 + - 2 files changed, 21 insertions(+), 5 deletions(-) - -diff --git a/drivers/gpu/drm/bridge/synopsys/dw-mipi-dsi.c b/drivers/gpu/drm/bridge/synopsys/dw-mipi-dsi.c -index 7e9a62ad56e8..6b268f9445b3 100644 ---- a/drivers/gpu/drm/bridge/synopsys/dw-mipi-dsi.c -+++ b/drivers/gpu/drm/bridge/synopsys/dw-mipi-dsi.c -@@ -605,15 +605,30 @@ static void dw_mipi_dsi_disable(struct dw_mipi_dsi *dsi) - - static void dw_mipi_dsi_init(struct dw_mipi_dsi *dsi) - { -+ const struct dw_mipi_dsi_phy_ops *phy_ops = dsi->plat_data->phy_ops; -+ unsigned int esc_rate; /* in MHz */ -+ u32 esc_clk_division; -+ int ret; -+ - /* - * The maximum permitted escape clock is 20MHz and it is derived from -- * lanebyteclk, which is running at "lane_mbps / 8". Thus we want: -- * -- * (lane_mbps >> 3) / esc_clk_division < 20 -+ * lanebyteclk, which is running at "lane_mbps / 8". -+ */ -+ if (phy_ops->get_esc_clk_rate) { -+ ret = phy_ops->get_esc_clk_rate(dsi->plat_data->priv_data, -+ &esc_rate); -+ if (ret) -+ DRM_DEBUG_DRIVER("Phy get_esc_clk_rate() failed\n"); -+ } else -+ esc_rate = 20; /* Default to 20MHz */ -+ -+ /* -+ * We want : -+ * (lane_mbps >> 3) / esc_clk_division < X - * which is: -- * (lane_mbps >> 3) / 20 > esc_clk_division -+ * (lane_mbps >> 3) / X > esc_clk_division - */ -- u32 esc_clk_division = (dsi->lane_mbps >> 3) / 20 + 1; -+ esc_clk_division = (dsi->lane_mbps >> 3) / esc_rate + 1; - - dsi_write(dsi, DSI_PWR_UP, RESET); - -diff --git a/include/drm/bridge/dw_mipi_dsi.h b/include/drm/bridge/dw_mipi_dsi.h -index b0e390b3288e..bda8aa7c2280 100644 ---- a/include/drm/bridge/dw_mipi_dsi.h -+++ b/include/drm/bridge/dw_mipi_dsi.h -@@ -36,6 +36,7 @@ struct dw_mipi_dsi_phy_ops { - unsigned int *lane_mbps); - int (*get_timing)(void *priv_data, unsigned int lane_mbps, - struct dw_mipi_dsi_dphy_timing *timing); -+ int (*get_esc_clk_rate)(void *priv_data, unsigned int *esc_clk_rate); - }; - - struct dw_mipi_dsi_host_ops { diff --git a/projects/Rockchip/patches/linux/default/linux-0021-drm-from-list.patch b/projects/Rockchip/patches/linux/default/linux-0021-drm-from-list.patch new file mode 100644 index 0000000000..b89b35c8a0 --- /dev/null +++ b/projects/Rockchip/patches/linux/default/linux-0021-drm-from-list.patch @@ -0,0 +1,234 @@ +From 7f65dfa79e600df193a274157794705d61302ffe Mon Sep 17 00:00:00 2001 +From: Jonas Karlman +Date: Mon, 6 Jul 2020 22:30:13 +0000 +Subject: [PATCH] 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 82f327801267..d8e6159213dc 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 + +From 5c761a6923ab956a6c1a7c570628c344055e3e85 Mon Sep 17 00:00:00 2001 +From: Jonas Karlman +Date: Mon, 6 Jul 2020 22:30:13 +0000 +Subject: [PATCH] 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 c80f7d9fd13f..eb663e25ad9e 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 4a2099cb582e..eab055d9b56d 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 80053d91a301..2c55e1852c3d 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, +@@ -579,11 +596,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), +@@ -713,11 +731,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), +@@ -862,11 +881,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), diff --git a/projects/Rockchip/patches/linux/default/linux-0022-drm-from-next.patch b/projects/Rockchip/patches/linux/default/linux-0022-drm-from-next.patch deleted file mode 100644 index 86615ef337..0000000000 --- a/projects/Rockchip/patches/linux/default/linux-0022-drm-from-next.patch +++ /dev/null @@ -1,403 +0,0 @@ -From 0898302e2ab75165acf8ad43726e67f3f0f6ab32 Mon Sep 17 00:00:00 2001 -From: Thomas Zimmermann -Date: Wed, 23 Sep 2020 12:21:51 +0200 -Subject: [PATCH] drm/rockchip: Convert to drm_gem_object_funcs -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -GEM object functions deprecate several similar callback interfaces in -struct drm_driver. This patch replaces the per-driver callbacks with -per-instance callbacks in rockchip. The only exception is gem_prime_mmap, -which is non-trivial to convert. - -v3: - * update documentation - -Signed-off-by: Thomas Zimmermann -Reviewed-by: Daniel Vetter -Acked-by: Christian König -Link: https://patchwork.freedesktop.org/patch/msgid/20200923102159.24084-15-tzimmermann@suse.de -(cherry picked from commit 0d590af3140d0f84c537a9ad252aecc780ed7aa5) ---- - drivers/gpu/drm/rockchip/rockchip_drm_drv.c | 5 ----- - drivers/gpu/drm/rockchip/rockchip_drm_gem.c | 12 +++++++++++- - 2 files changed, 11 insertions(+), 6 deletions(-) - -diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_drv.c b/drivers/gpu/drm/rockchip/rockchip_drm_drv.c -index 0f3eb392fe39..b7654f5e4225 100644 ---- a/drivers/gpu/drm/rockchip/rockchip_drm_drv.c -+++ b/drivers/gpu/drm/rockchip/rockchip_drm_drv.c -@@ -212,15 +212,10 @@ static const struct file_operations rockchip_drm_driver_fops = { - static struct drm_driver rockchip_drm_driver = { - .driver_features = DRIVER_MODESET | DRIVER_GEM | DRIVER_ATOMIC, - .lastclose = drm_fb_helper_lastclose, -- .gem_vm_ops = &drm_gem_cma_vm_ops, -- .gem_free_object_unlocked = rockchip_gem_free_object, - .dumb_create = rockchip_gem_dumb_create, - .prime_handle_to_fd = drm_gem_prime_handle_to_fd, - .prime_fd_to_handle = drm_gem_prime_fd_to_handle, -- .gem_prime_get_sg_table = rockchip_gem_prime_get_sg_table, - .gem_prime_import_sg_table = rockchip_gem_prime_import_sg_table, -- .gem_prime_vmap = rockchip_gem_prime_vmap, -- .gem_prime_vunmap = rockchip_gem_prime_vunmap, - .gem_prime_mmap = rockchip_gem_mmap_buf, - .fops = &rockchip_drm_driver_fops, - .name = DRIVER_NAME, -diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_gem.c b/drivers/gpu/drm/rockchip/rockchip_drm_gem.c -index 62e5d0970525..1cf4631461c9 100644 ---- a/drivers/gpu/drm/rockchip/rockchip_drm_gem.c -+++ b/drivers/gpu/drm/rockchip/rockchip_drm_gem.c -@@ -295,6 +295,14 @@ static void rockchip_gem_release_object(struct rockchip_gem_object *rk_obj) - kfree(rk_obj); - } - -+static const struct drm_gem_object_funcs rockchip_gem_object_funcs = { -+ .free = rockchip_gem_free_object, -+ .get_sg_table = rockchip_gem_prime_get_sg_table, -+ .vmap = rockchip_gem_prime_vmap, -+ .vunmap = rockchip_gem_prime_vunmap, -+ .vm_ops = &drm_gem_cma_vm_ops, -+}; -+ - static struct rockchip_gem_object * - rockchip_gem_alloc_object(struct drm_device *drm, unsigned int size) - { -@@ -309,6 +317,8 @@ static struct rockchip_gem_object * - - obj = &rk_obj->base; - -+ obj->funcs = &rockchip_gem_object_funcs; -+ - drm_gem_object_init(drm, obj, size); - - return rk_obj; -@@ -337,7 +347,7 @@ rockchip_gem_create_object(struct drm_device *drm, unsigned int size, - } - - /* -- * rockchip_gem_free_object - (struct drm_driver)->gem_free_object_unlocked -+ * rockchip_gem_free_object - (struct drm_gem_object_funcs)->free - * callback function - */ - void rockchip_gem_free_object(struct drm_gem_object *obj) - -From 411c1e880514d8903890c1fe67c4b532d8f0c21c Mon Sep 17 00:00:00 2001 -From: Thomas Zimmermann -Date: Mon, 28 Sep 2020 10:16:43 +0200 -Subject: [PATCH] drm/rockchip: Include for - drm_gem_cm_vm_ops -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -Include to get drm_gem_cma_vm_ops. Fallout -from the recent conversion to GEM object functions. - -Signed-off-by: Thomas Zimmermann -Reviewed-by: Sam Ravnborg -Reported-by: kernel test robot -Fixes: 0d590af3140d ("drm/rockchip: Convert to drm_gem_object_funcs") -Cc: Thomas Zimmermann -Cc: Daniel Vetter -Cc: Christian König -Cc: Sandy Huang -Cc: "Heiko Stübner" -Cc: dri-devel@lists.freedesktop.org -Cc: linux-arm-kernel@lists.infradead.org -Cc: linux-rockchip@lists.infradead.org -Link: https://patchwork.freedesktop.org/patch/msgid/20200928081643.8575-1-tzimmermann@suse.de -(cherry picked from commit 8f7db83e6abf863c6a2cfddbe7086f1e3251fdbf) ---- - drivers/gpu/drm/rockchip/rockchip_drm_gem.c | 1 + - 1 file changed, 1 insertion(+) - -diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_gem.c b/drivers/gpu/drm/rockchip/rockchip_drm_gem.c -index 1cf4631461c9..7d5ebb10323b 100644 ---- a/drivers/gpu/drm/rockchip/rockchip_drm_gem.c -+++ b/drivers/gpu/drm/rockchip/rockchip_drm_gem.c -@@ -10,6 +10,7 @@ - - #include - #include -+#include - #include - #include - - -From 4ddb01c2866cd57b134d739e9e88e00dc88453ae Mon Sep 17 00:00:00 2001 -From: Qinglang Miao -Date: Mon, 21 Sep 2020 21:10:19 +0800 -Subject: [PATCH] drm/panfrost: simplify the return expression of - cz_ih_hw_init() - -Simplify the return expression. - -Signed-off-by: Qinglang Miao -Reviewed-by: Philipp Zabel -Reviewed-by: Steven Price -Signed-off-by: Steven Price -Link: https://patchwork.freedesktop.org/patch/msgid/20200921131019.91558-1-miaoqinglang@huawei.com -(cherry picked from commit 3c4641d4e75618fa1b5501b9ae9c19f765d75725) ---- - drivers/gpu/drm/panfrost/panfrost_device.c | 8 +------- - 1 file changed, 1 insertion(+), 7 deletions(-) - -diff --git a/drivers/gpu/drm/panfrost/panfrost_device.c b/drivers/gpu/drm/panfrost/panfrost_device.c -index e6896733838a..ea8d31863c50 100644 ---- a/drivers/gpu/drm/panfrost/panfrost_device.c -+++ b/drivers/gpu/drm/panfrost/panfrost_device.c -@@ -18,19 +18,13 @@ - - static int panfrost_reset_init(struct panfrost_device *pfdev) - { -- int err; -- - pfdev->rstc = devm_reset_control_array_get(pfdev->dev, false, true); - if (IS_ERR(pfdev->rstc)) { - dev_err(pfdev->dev, "get reset failed %ld\n", PTR_ERR(pfdev->rstc)); - return PTR_ERR(pfdev->rstc); - } - -- err = reset_control_deassert(pfdev->rstc); -- if (err) -- return err; -- -- return 0; -+ return reset_control_deassert(pfdev->rstc); - } - - static void panfrost_reset_fini(struct panfrost_device *pfdev) - -From b75473ce0e84aa528eef4f805c95fc5e2f6f766a Mon Sep 17 00:00:00 2001 -From: Qinglang Miao -Date: Mon, 21 Sep 2020 21:10:21 +0800 -Subject: [PATCH] drm/panfrost: simplify the return expression of - panfrost_devfreq_target() - -Simplify the return expression. - -Signed-off-by: Qinglang Miao -Reviewed-by: Steven Price -Signed-off-by: Steven Price -Link: https://patchwork.freedesktop.org/patch/msgid/20200921131021.91604-1-miaoqinglang@huawei.com -(cherry picked from commit 0c5036590bde1407a6250ea027e836815353820f) ---- - drivers/gpu/drm/panfrost/panfrost_devfreq.c | 7 +------ - 1 file changed, 1 insertion(+), 6 deletions(-) - -diff --git a/drivers/gpu/drm/panfrost/panfrost_devfreq.c b/drivers/gpu/drm/panfrost/panfrost_devfreq.c -index 8ab025d0035f..913eaa6d0bc6 100644 ---- a/drivers/gpu/drm/panfrost/panfrost_devfreq.c -+++ b/drivers/gpu/drm/panfrost/panfrost_devfreq.c -@@ -29,18 +29,13 @@ static int panfrost_devfreq_target(struct device *dev, unsigned long *freq, - u32 flags) - { - struct dev_pm_opp *opp; -- int err; - - opp = devfreq_recommended_opp(dev, freq, flags); - if (IS_ERR(opp)) - return PTR_ERR(opp); - dev_pm_opp_put(opp); - -- err = dev_pm_opp_set_rate(dev, *freq); -- if (err) -- return err; -- -- return 0; -+ return dev_pm_opp_set_rate(dev, *freq); - } - - static void panfrost_devfreq_reset(struct panfrost_devfreq *pfdevfreq) - -From f3f98ffb76cdbf06f0549ce904007a7725b76c6f Mon Sep 17 00:00:00 2001 -From: Rikard Falkeborn -Date: Sun, 4 Oct 2020 22:06:53 +0200 -Subject: [PATCH] drm: bridge: dw-hdmi: Constify dw_hdmi_i2s_ops - -The only usage of dw_hdmi_i2s_ops is to assign its address to the ops -field in the hdmi_codec_pdata struct, which is a const pointer. Make it -const to allow the compiler to put it in read-only memory. - -Signed-off-by: Rikard Falkeborn -Signed-off-by: Daniel Vetter -Link: https://patchwork.freedesktop.org/patch/msgid/20201004200653.14702-1-rikard.falkeborn@gmail.com -(cherry picked from commit f3d52908f6baffc21ba45058103d0226ca5cb073) ---- - drivers/gpu/drm/bridge/synopsys/dw-hdmi-i2s-audio.c | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/drivers/gpu/drm/bridge/synopsys/dw-hdmi-i2s-audio.c b/drivers/gpu/drm/bridge/synopsys/dw-hdmi-i2s-audio.c -index 9fef6413741d..feb04f127b55 100644 ---- a/drivers/gpu/drm/bridge/synopsys/dw-hdmi-i2s-audio.c -+++ b/drivers/gpu/drm/bridge/synopsys/dw-hdmi-i2s-audio.c -@@ -170,7 +170,7 @@ static int dw_hdmi_i2s_hook_plugged_cb(struct device *dev, void *data, - return dw_hdmi_set_plugged_cb(hdmi, fn, codec_dev); - } - --static struct hdmi_codec_ops dw_hdmi_i2s_ops = { -+static const struct hdmi_codec_ops dw_hdmi_i2s_ops = { - .hw_params = dw_hdmi_i2s_hw_params, - .audio_startup = dw_hdmi_i2s_audio_startup, - .audio_shutdown = dw_hdmi_i2s_audio_shutdown, - -From 5855d31b6f0e36aea731afe3b8dff3c470efa46b Mon Sep 17 00:00:00 2001 -From: Boris Brezillon -Date: Fri, 2 Oct 2020 14:25:06 +0200 -Subject: [PATCH] drm/panfrost: Fix job timeout handling - -If more than two jobs end up timeout-ing concurrently, only one of them -(the one attached to the scheduler acquiring the lock) is fully handled. -The other one remains in a dangling state where it's no longer part of -the scheduling queue, but still blocks something in scheduler, leading -to repetitive timeouts when new jobs are queued. - -Let's make sure all bad jobs are properly handled by the thread -acquiring the lock. - -v3: -- Add Steven's R-b -- Don't take the sched_lock when stopping the schedulers - -v2: -- Fix the subject prefix -- Stop the scheduler before returning from panfrost_job_timedout() -- Call cancel_delayed_work_sync() after drm_sched_stop() to make sure - no timeout handlers are in flight when we reset the GPU (Steven Price) -- Make sure we release the reset lock before restarting the - schedulers (Steven Price) - -Fixes: f3ba91228e8e ("drm/panfrost: Add initial panfrost driver") -Cc: -Signed-off-by: Boris Brezillon -Reviewed-by: Steven Price -Signed-off-by: Steven Price -Link: https://patchwork.freedesktop.org/patch/msgid/20201002122506.1374183-1-boris.brezillon@collabora.com -(cherry picked from commit 1a11a88cfd9a97e13be8bc880c4795f9844fbbec) ---- - drivers/gpu/drm/panfrost/panfrost_job.c | 62 ++++++++++++++++++++++++++++----- - 1 file changed, 53 insertions(+), 9 deletions(-) - -diff --git a/drivers/gpu/drm/panfrost/panfrost_job.c b/drivers/gpu/drm/panfrost/panfrost_job.c -index 30e7b7196dab..d0469e944143 100644 ---- a/drivers/gpu/drm/panfrost/panfrost_job.c -+++ b/drivers/gpu/drm/panfrost/panfrost_job.c -@@ -25,7 +25,8 @@ - - struct panfrost_queue_state { - struct drm_gpu_scheduler sched; -- -+ bool stopped; -+ struct mutex lock; - u64 fence_context; - u64 emit_seqno; - }; -@@ -369,6 +370,24 @@ void panfrost_job_enable_interrupts(struct panfrost_device *pfdev) - job_write(pfdev, JOB_INT_MASK, irq_mask); - } - -+static bool panfrost_scheduler_stop(struct panfrost_queue_state *queue, -+ struct drm_sched_job *bad) -+{ -+ bool stopped = false; -+ -+ mutex_lock(&queue->lock); -+ if (!queue->stopped) { -+ drm_sched_stop(&queue->sched, bad); -+ if (bad) -+ drm_sched_increase_karma(bad); -+ queue->stopped = true; -+ stopped = true; -+ } -+ mutex_unlock(&queue->lock); -+ -+ return stopped; -+} -+ - static void panfrost_job_timedout(struct drm_sched_job *sched_job) - { - struct panfrost_job *job = to_panfrost_job(sched_job); -@@ -392,19 +411,39 @@ static void panfrost_job_timedout(struct drm_sched_job *sched_job) - job_read(pfdev, JS_TAIL_LO(js)), - sched_job); - -+ /* Scheduler is already stopped, nothing to do. */ -+ if (!panfrost_scheduler_stop(&pfdev->js->queue[js], sched_job)) -+ return; -+ - if (!mutex_trylock(&pfdev->reset_lock)) - return; - - for (i = 0; i < NUM_JOB_SLOTS; i++) { - struct drm_gpu_scheduler *sched = &pfdev->js->queue[i].sched; - -- drm_sched_stop(sched, sched_job); -- if (js != i) -- /* Ensure any timeouts on other slots have finished */ -+ /* -+ * If the queue is still active, make sure we wait for any -+ * pending timeouts. -+ */ -+ if (!pfdev->js->queue[i].stopped) - cancel_delayed_work_sync(&sched->work_tdr); -- } - -- drm_sched_increase_karma(sched_job); -+ /* -+ * If the scheduler was not already stopped, there's a tiny -+ * chance a timeout has expired just before we stopped it, and -+ * drm_sched_stop() does not flush pending works. Let's flush -+ * them now so the timeout handler doesn't get called in the -+ * middle of a reset. -+ */ -+ if (panfrost_scheduler_stop(&pfdev->js->queue[i], NULL)) -+ cancel_delayed_work_sync(&sched->work_tdr); -+ -+ /* -+ * Now that we cancelled the pending timeouts, we can safely -+ * reset the stopped state. -+ */ -+ pfdev->js->queue[i].stopped = false; -+ } - - spin_lock_irqsave(&pfdev->js->job_lock, flags); - for (i = 0; i < NUM_JOB_SLOTS; i++) { -@@ -421,11 +460,11 @@ static void panfrost_job_timedout(struct drm_sched_job *sched_job) - for (i = 0; i < NUM_JOB_SLOTS; i++) - drm_sched_resubmit_jobs(&pfdev->js->queue[i].sched); - -+ mutex_unlock(&pfdev->reset_lock); -+ - /* restart scheduler after GPU is usable again */ - for (i = 0; i < NUM_JOB_SLOTS; i++) - drm_sched_start(&pfdev->js->queue[i].sched, true); -- -- mutex_unlock(&pfdev->reset_lock); - } - - static const struct drm_sched_backend_ops panfrost_sched_ops = { -@@ -558,6 +597,7 @@ int panfrost_job_open(struct panfrost_file_priv *panfrost_priv) - int ret, i; - - for (i = 0; i < NUM_JOB_SLOTS; i++) { -+ mutex_init(&js->queue[i].lock); - sched = &js->queue[i].sched; - ret = drm_sched_entity_init(&panfrost_priv->sched_entity[i], - DRM_SCHED_PRIORITY_NORMAL, &sched, -@@ -570,10 +610,14 @@ int panfrost_job_open(struct panfrost_file_priv *panfrost_priv) - - void panfrost_job_close(struct panfrost_file_priv *panfrost_priv) - { -+ struct panfrost_device *pfdev = panfrost_priv->pfdev; -+ struct panfrost_job_slot *js = pfdev->js; - int i; - -- for (i = 0; i < NUM_JOB_SLOTS; i++) -+ for (i = 0; i < NUM_JOB_SLOTS; i++) { - drm_sched_entity_destroy(&panfrost_priv->sched_entity[i]); -+ mutex_destroy(&js->queue[i].lock); -+ } - } - - int panfrost_job_is_idle(struct panfrost_device *pfdev) diff --git a/projects/Rockchip/patches/linux/default/linux-1001-drm-rockchip.patch b/projects/Rockchip/patches/linux/default/linux-1001-drm-rockchip.patch new file mode 100644 index 0000000000..4027e248d3 --- /dev/null +++ b/projects/Rockchip/patches/linux/default/linux-1001-drm-rockchip.patch @@ -0,0 +1,3030 @@ +From c86baca2adad389d6601855070336bfccd6644bf Mon Sep 17 00:00:00 2001 +From: Jonas Karlman +Date: Wed, 15 Jul 2020 15:24:47 +0000 +Subject: [PATCH] drm/rockchip: vop: fix crtc duplicate state + +struct rockchip_crtc_state owned members is always reset to zero in +the atomic_duplicate_state callback. +Fix this by using kmemdup on the subclass state structure. + +Signed-off-by: Jonas Karlman +--- + drivers/gpu/drm/rockchip/rockchip_drm_vop.c | 6 +++++- + 1 file changed, 5 insertions(+), 1 deletion(-) + +diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_vop.c b/drivers/gpu/drm/rockchip/rockchip_drm_vop.c +index eb663e25ad9e..818195594705 100644 +--- a/drivers/gpu/drm/rockchip/rockchip_drm_vop.c ++++ b/drivers/gpu/drm/rockchip/rockchip_drm_vop.c +@@ -1554,7 +1554,11 @@ static struct drm_crtc_state *vop_crtc_duplicate_state(struct drm_crtc *crtc) + { + struct rockchip_crtc_state *rockchip_state; + +- rockchip_state = kzalloc(sizeof(*rockchip_state), GFP_KERNEL); ++ if (WARN_ON(!crtc->state)) ++ return NULL; ++ ++ rockchip_state = kmemdup(to_rockchip_crtc_state(crtc->state), ++ sizeof(*rockchip_state), GFP_KERNEL); + if (!rockchip_state) + return NULL; + + +From af26aac9883dc8f9e93d48f8dd97974c19b55c8a Mon Sep 17 00:00:00 2001 +From: Jonas Karlman +Date: Sun, 3 May 2020 16:51:31 +0000 +Subject: [PATCH] drm/rockchip: vop: filter modes outside 0.5% pixel clock + tolerance + +Filter modes that require a pixel clock that differ more then 0.5% +from the requested pixel clock. + +This filter is only applied to tmds only connector and/or encoders. + +Signed-off-by: Jonas Karlman +--- + drivers/gpu/drm/rockchip/rockchip_drm_vop.c | 54 +++++++++++++++++++++ + 1 file changed, 54 insertions(+) + +diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_vop.c b/drivers/gpu/drm/rockchip/rockchip_drm_vop.c +index 818195594705..77ae88a94c55 100644 +--- a/drivers/gpu/drm/rockchip/rockchip_drm_vop.c ++++ b/drivers/gpu/drm/rockchip/rockchip_drm_vop.c +@@ -1167,6 +1167,59 @@ static void vop_crtc_disable_vblank(struct drm_crtc *crtc) + spin_unlock_irqrestore(&vop->irq_lock, flags); + } + ++static bool vop_crtc_is_tmds(struct drm_crtc *crtc) ++{ ++ struct rockchip_crtc_state *s = to_rockchip_crtc_state(crtc->state); ++ struct drm_encoder *encoder; ++ ++ switch (s->output_type) { ++ case DRM_MODE_CONNECTOR_LVDS: ++ case DRM_MODE_CONNECTOR_DSI: ++ return false; ++ case DRM_MODE_CONNECTOR_eDP: ++ case DRM_MODE_CONNECTOR_HDMIA: ++ case DRM_MODE_CONNECTOR_DisplayPort: ++ return true; ++ } ++ ++ drm_for_each_encoder_mask(encoder, crtc->dev, crtc->state->encoder_mask) ++ if (encoder->encoder_type != DRM_MODE_ENCODER_TMDS) ++ return false; ++ ++ return true; ++} ++ ++/* ++ * The VESA DMT standard specifies a 0.5% pixel clock frequency tolerance. ++ * The CVT spec reuses that tolerance in its examples. ++ */ ++#define CLOCK_TOLERANCE_PER_MILLE 5 ++ ++static enum drm_mode_status vop_crtc_mode_valid(struct drm_crtc *crtc, ++ const struct drm_display_mode *mode) ++{ ++ struct vop *vop = to_vop(crtc); ++ long rounded_rate; ++ long lowest, highest; ++ ++ if (!vop_crtc_is_tmds(crtc)) ++ return MODE_OK; ++ ++ rounded_rate = clk_round_rate(vop->dclk, mode->clock * 1000 + 999); ++ if (rounded_rate < 0) ++ return MODE_NOCLOCK; ++ ++ lowest = mode->clock * (1000 - CLOCK_TOLERANCE_PER_MILLE); ++ if (rounded_rate < lowest) ++ return MODE_CLOCK_LOW; ++ ++ highest = mode->clock * (1000 + CLOCK_TOLERANCE_PER_MILLE); ++ if (rounded_rate > highest) ++ return MODE_CLOCK_HIGH; ++ ++ return MODE_OK; ++} ++ + static bool vop_crtc_mode_fixup(struct drm_crtc *crtc, + const struct drm_display_mode *mode, + struct drm_display_mode *adjusted_mode) +@@ -1537,6 +1590,7 @@ static void vop_crtc_atomic_flush(struct drm_crtc *crtc, + } + + static const struct drm_crtc_helper_funcs vop_crtc_helper_funcs = { ++ .mode_valid = vop_crtc_mode_valid, + .mode_fixup = vop_crtc_mode_fixup, + .atomic_check = vop_crtc_atomic_check, + .atomic_begin = vop_crtc_atomic_begin, + +From f66de7db8568a06bf3251837bc89fb3b73f4b2c9 Mon Sep 17 00:00:00 2001 +From: Jonas Karlman +Date: Mon, 20 Jul 2020 15:15:50 +0000 +Subject: [PATCH] drm/rockchip: vop: filter interlaced modes + +The current version of the driver does not support interlaced modes, +lets filter any interlaced mode. + +Signed-off-by: Jonas Karlman +--- + drivers/gpu/drm/rockchip/rockchip_drm_vop.c | 3 +++ + 1 file changed, 3 insertions(+) + +diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_vop.c b/drivers/gpu/drm/rockchip/rockchip_drm_vop.c +index 77ae88a94c55..e27314249691 100644 +--- a/drivers/gpu/drm/rockchip/rockchip_drm_vop.c ++++ b/drivers/gpu/drm/rockchip/rockchip_drm_vop.c +@@ -1205,6 +1205,9 @@ static enum drm_mode_status vop_crtc_mode_valid(struct drm_crtc *crtc, + if (!vop_crtc_is_tmds(crtc)) + return MODE_OK; + ++ if (mode->flags & DRM_MODE_FLAG_INTERLACE) ++ return MODE_NO_INTERLACE; ++ + rounded_rate = clk_round_rate(vop->dclk, mode->clock * 1000 + 999); + if (rounded_rate < 0) + return MODE_NOCLOCK; + +From 0ecaa96190a23bebd74d3a33eca79de3c50a8f56 Mon Sep 17 00:00:00 2001 +From: Jonas Karlman +Date: Sat, 10 Oct 2020 14:57:30 +0000 +Subject: [PATCH] drm/rockchip: vop: define max output resolution supported + +Signed-off-by: Jonas Karlman +--- + drivers/gpu/drm/rockchip/rockchip_drm_vop.h | 6 ++++++ + drivers/gpu/drm/rockchip/rockchip_vop_reg.c | 7 +++++++ + 2 files changed, 13 insertions(+) + +diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_vop.h b/drivers/gpu/drm/rockchip/rockchip_drm_vop.h +index eab055d9b56d..1b0618147a0e 100644 +--- a/drivers/gpu/drm/rockchip/rockchip_drm_vop.h ++++ b/drivers/gpu/drm/rockchip/rockchip_drm_vop.h +@@ -186,6 +186,11 @@ struct vop_win_data { + enum drm_plane_type type; + }; + ++struct vop_rect { ++ int width; ++ int height; ++}; ++ + struct vop_data { + uint32_t version; + const struct vop_intr *intr; +@@ -198,6 +203,7 @@ struct vop_data { + const struct vop_win_data *win; + unsigned int win_size; + unsigned int lut_size; ++ struct vop_rect max_output; + + #define VOP_FEATURE_OUTPUT_RGB10 BIT(0) + #define VOP_FEATURE_INTERNAL_RGB BIT(1) +diff --git a/drivers/gpu/drm/rockchip/rockchip_vop_reg.c b/drivers/gpu/drm/rockchip/rockchip_vop_reg.c +index 2c55e1852c3d..cf87361108a0 100644 +--- a/drivers/gpu/drm/rockchip/rockchip_vop_reg.c ++++ b/drivers/gpu/drm/rockchip/rockchip_vop_reg.c +@@ -700,6 +700,7 @@ static const struct vop_intr rk3288_vop_intr = { + static const struct vop_data rk3288_vop = { + .version = VOP_VERSION(3, 1), + .feature = VOP_FEATURE_OUTPUT_RGB10, ++ .max_output = { 3840, 2160 }, + .intr = &rk3288_vop_intr, + .common = &rk3288_common, + .modeset = &rk3288_modeset, +@@ -801,6 +802,7 @@ static const struct vop_misc rk3368_misc = { + + static const struct vop_data rk3368_vop = { + .version = VOP_VERSION(3, 2), ++ .max_output = { 4096, 2160 }, + .intr = &rk3368_vop_intr, + .common = &rk3288_common, + .modeset = &rk3288_modeset, +@@ -822,6 +824,7 @@ static const struct vop_intr rk3366_vop_intr = { + + static const struct vop_data rk3366_vop = { + .version = VOP_VERSION(3, 4), ++ .max_output = { 4096, 2160 }, + .intr = &rk3366_vop_intr, + .common = &rk3288_common, + .modeset = &rk3288_modeset, +@@ -929,6 +932,7 @@ static const struct vop_afbc rk3399_vop_afbc = { + static const struct vop_data rk3399_vop_big = { + .version = VOP_VERSION(3, 5), + .feature = VOP_FEATURE_OUTPUT_RGB10, ++ .max_output = { 4096, 2160 }, + .intr = &rk3366_vop_intr, + .common = &rk3288_common, + .modeset = &rk3288_modeset, +@@ -955,6 +959,7 @@ static const struct vop_win_yuv2yuv_data rk3399_vop_lit_win_yuv2yuv_data[] = { + + static const struct vop_data rk3399_vop_lit = { + .version = VOP_VERSION(3, 6), ++ .max_output = { 2560, 1600 }, + .intr = &rk3366_vop_intr, + .common = &rk3288_common, + .modeset = &rk3288_modeset, +@@ -975,6 +980,7 @@ static const struct vop_win_data rk3228_vop_win_data[] = { + static const struct vop_data rk3228_vop = { + .version = VOP_VERSION(3, 7), + .feature = VOP_FEATURE_OUTPUT_RGB10, ++ .max_output = { 4096, 2160 }, + .intr = &rk3366_vop_intr, + .common = &rk3288_common, + .modeset = &rk3288_modeset, +@@ -1046,6 +1052,7 @@ static const struct vop_win_data rk3328_vop_win_data[] = { + static const struct vop_data rk3328_vop = { + .version = VOP_VERSION(3, 8), + .feature = VOP_FEATURE_OUTPUT_RGB10, ++ .max_output = { 4096, 2160 }, + .intr = &rk3328_vop_intr, + .common = &rk3328_common, + .modeset = &rk3328_modeset, + +From 6177761486226484a9ea82c205844a3addcdeb07 Mon Sep 17 00:00:00 2001 +From: Jonas Karlman +Date: Mon, 20 Jul 2020 11:46:16 +0000 +Subject: [PATCH] drm/rockchip: vop: filter modes above max output supported + +Filter any mode with a resolution not supported by the VOP. + +Signed-off-by: Jonas Karlman +--- + drivers/gpu/drm/rockchip/rockchip_drm_vop.c | 16 ++++++++++++++++ + 1 file changed, 16 insertions(+) + +diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_vop.c b/drivers/gpu/drm/rockchip/rockchip_drm_vop.c +index e27314249691..b15ee823039e 100644 +--- a/drivers/gpu/drm/rockchip/rockchip_drm_vop.c ++++ b/drivers/gpu/drm/rockchip/rockchip_drm_vop.c +@@ -1199,6 +1199,7 @@ static enum drm_mode_status vop_crtc_mode_valid(struct drm_crtc *crtc, + const struct drm_display_mode *mode) + { + struct vop *vop = to_vop(crtc); ++ const struct vop_rect *max_output = &vop->data->max_output; + long rounded_rate; + long lowest, highest; + +@@ -1220,6 +1221,10 @@ static enum drm_mode_status vop_crtc_mode_valid(struct drm_crtc *crtc, + if (rounded_rate > highest) + return MODE_CLOCK_HIGH; + ++ if (max_output->width && max_output->height) ++ return drm_mode_validate_size(mode, max_output->width, ++ max_output->height); ++ + return MODE_OK; + } + +@@ -1228,8 +1233,19 @@ static bool vop_crtc_mode_fixup(struct drm_crtc *crtc, + struct drm_display_mode *adjusted_mode) + { + struct vop *vop = to_vop(crtc); ++ const struct vop_rect *max_output = &vop->data->max_output; + unsigned long rate; + ++ if (max_output->width && max_output->height) { ++ enum drm_mode_status status; ++ ++ status = drm_mode_validate_size(adjusted_mode, ++ max_output->width, ++ max_output->height); ++ if (status != MODE_OK) ++ return false; ++ } ++ + /* + * Clock craziness. + * + +From d6041e485e44ea27ce178238b20c120650ec0750 Mon Sep 17 00:00:00 2001 +From: Yakir Yang +Date: Mon, 11 Jul 2016 19:05:39 +0800 +Subject: [PATCH] drm/rockchip: dw_hdmi: adjust cklvl & txlvl for RF/EMI + +Dut to the high HDMI signal voltage driver, Mickey have meet +a serious RF/EMI problem, so we decided to reduce HDMI signal +voltage to a proper value. + +The default params for phy is cklvl = 20 & txlvl = 13 (RF/EMI failed) + ck: lvl = 13, term=100, vlo = 2.71, vhi=3.14, vswing = 0.43 + tx: lvl = 20, term=100, vlo = 2.81, vhi=3.16, vswing = 0.35 + +1. We decided to reduce voltage value to lower, but VSwing still +keep high, RF/EMI have been improved but still failed. + ck: lvl = 6, term=100, vlo = 2.61, vhi=3.11, vswing = 0.50 + tx: lvl = 6, term=100, vlo = 2.61, vhi=3.11, vswing = 0.50 + +2. We try to keep voltage value and vswing both lower, then RF/EMI +test all passed ;) + ck: lvl = 11, term= 66, vlo = 2.68, vhi=3.09, vswing = 0.40 + tx: lvl = 11, term= 66, vlo = 2.68, vhi=3.09, vswing = 0.40 +When we back to run HDMI different test and single-end test, we see +different test passed, but signle-end test failed. The oscilloscope +show that simgle-end clock's VL value is 1.78v (which remind LowLimit +should not lower then 2.6v). + +3. That's to say there are some different between PHY document and +measure value. And according to experiment 2 results, we need to +higher clock voltage and lower data voltage, then we can keep RF/EMI +satisfied and single-end & differen test passed. + ck: lvl = 9, term=100, vlo = 2.65, vhi=3.12, vswing = 0.47 + tx: lvl = 16, term=100, vlo = 2.75, vhi=3.15, vswing = 0.39 + +Signed-off-by: Yakir Yang +Signed-off-by: Jonas Karlman +--- + drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c b/drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c +index 23de359a1dec..f78851e7ef16 100644 +--- a/drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c ++++ b/drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c +@@ -181,7 +181,7 @@ static const struct dw_hdmi_curr_ctrl rockchip_cur_ctr[] = { + static const struct dw_hdmi_phy_config rockchip_phy_config[] = { + /*pixelclk symbol term vlev*/ + { 74250000, 0x8009, 0x0004, 0x0272}, +- { 148500000, 0x802b, 0x0004, 0x028d}, ++ { 165000000, 0x802b, 0x0004, 0x0209}, + { 297000000, 0x8039, 0x0005, 0x028d}, + { ~0UL, 0x0000, 0x0000, 0x0000} + }; + +From 63652150cc73fc1d7a1d751799619d5b5fc7e722 Mon Sep 17 00:00:00 2001 +From: Nickey Yang +Date: Mon, 13 Feb 2017 15:40:29 +0800 +Subject: [PATCH] drm/rockchip: dw_hdmi: add phy_config for 594Mhz pixel clock + +Add phy_config for 594Mhz pixel clock used for 4K@60hz + +Signed-off-by: Nickey Yang +Signed-off-by: Jonas Karlman +--- + drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c b/drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c +index f78851e7ef16..a308adb56d2f 100644 +--- a/drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c ++++ b/drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c +@@ -183,6 +183,7 @@ static const struct dw_hdmi_phy_config rockchip_phy_config[] = { + { 74250000, 0x8009, 0x0004, 0x0272}, + { 165000000, 0x802b, 0x0004, 0x0209}, + { 297000000, 0x8039, 0x0005, 0x028d}, ++ { 594000000, 0x8039, 0x0000, 0x019d}, + { ~0UL, 0x0000, 0x0000, 0x0000} + }; + + +From 07f933df000843378421c5fa12484227e05bd52b Mon Sep 17 00:00:00 2001 +From: Douglas Anderson +Date: Mon, 11 Jul 2016 19:05:36 +0800 +Subject: [PATCH] drm/rockchip: dw_hdmi: Set cur_ctr to 0 always + +Jitter was improved by lowering the MPLL bandwidth to account for high +frequency noise in the rk3288 PLL. In each case MPLL bandwidth was +lowered only enough to get us a comfortable margin. We believe that +lowering the bandwidth like this is safe given sufficient testing. + +Signed-off-by: Douglas Anderson +Signed-off-by: Yakir Yang +Signed-off-by: Jonas Karlman +--- + drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c | 16 ++-------------- + 1 file changed, 2 insertions(+), 14 deletions(-) + +diff --git a/drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c b/drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c +index a308adb56d2f..5b273f26f177 100644 +--- a/drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c ++++ b/drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c +@@ -160,20 +160,8 @@ static const struct dw_hdmi_mpll_config rockchip_mpll_cfg[] = { + static const struct dw_hdmi_curr_ctrl rockchip_cur_ctr[] = { + /* pixelclk bpp8 bpp10 bpp12 */ + { +- 40000000, { 0x0018, 0x0018, 0x0018 }, +- }, { +- 65000000, { 0x0028, 0x0028, 0x0028 }, +- }, { +- 66000000, { 0x0038, 0x0038, 0x0038 }, +- }, { +- 74250000, { 0x0028, 0x0038, 0x0038 }, +- }, { +- 83500000, { 0x0028, 0x0038, 0x0038 }, +- }, { +- 146250000, { 0x0038, 0x0038, 0x0038 }, +- }, { +- 148500000, { 0x0000, 0x0038, 0x0038 }, +- }, { ++ 600000000, { 0x0000, 0x0000, 0x0000 }, ++ }, { + ~0UL, { 0x0000, 0x0000, 0x0000}, + } + }; + +From de579556c521aa66b60cab22b9e6161a98d172ba Mon Sep 17 00:00:00 2001 +From: Douglas Anderson +Date: Mon, 11 Jul 2016 19:05:42 +0800 +Subject: [PATCH] drm/rockchip: dw_hdmi: Use auto-generated tables + +The previous tables for mpll_cfg and curr_ctrl were created using the +20-pages of example settings provided by the PHY vendor. Those +example settings weren't particularly dense, so there were places +where we were guessing what the settings would be for 10-bit and +12-bit (not that we use those anyway). It was also always a lot of +extra work every time we wanted to add a new clock rate since we had +to cross-reference several tables. + +In I've gone through the work to figure +out how to generate this table automatically. Let's now use the +automatically generated table and then we'll never need to look at it +again. + +We only support 8-bit mode right now and only support a small number +of clock rates and and I've verified that the only 8-bit rate that was +affected was 148.5. That mode appears to have been wrong in the old +table. + +Signed-off-by: Douglas Anderson +Signed-off-by: Yakir Yang +Signed-off-by: Jonas Karlman +--- + drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c | 130 +++++++++++--------- + 1 file changed, 69 insertions(+), 61 deletions(-) + +diff --git a/drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c b/drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c +index 5b273f26f177..b5d2cdaa24fa 100644 +--- a/drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c ++++ b/drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c +@@ -79,80 +79,88 @@ struct rockchip_hdmi { + + static const struct dw_hdmi_mpll_config rockchip_mpll_cfg[] = { + { +- 27000000, { +- { 0x00b3, 0x0000}, +- { 0x2153, 0x0000}, +- { 0x40f3, 0x0000} ++ 30666000, { ++ { 0x00b3, 0x0000 }, ++ { 0x2153, 0x0000 }, ++ { 0x40f3, 0x0000 }, + }, +- }, { +- 36000000, { +- { 0x00b3, 0x0000}, +- { 0x2153, 0x0000}, +- { 0x40f3, 0x0000} ++ }, { ++ 36800000, { ++ { 0x00b3, 0x0000 }, ++ { 0x2153, 0x0000 }, ++ { 0x40a2, 0x0001 }, + }, +- }, { +- 40000000, { +- { 0x00b3, 0x0000}, +- { 0x2153, 0x0000}, +- { 0x40f3, 0x0000} ++ }, { ++ 46000000, { ++ { 0x00b3, 0x0000 }, ++ { 0x2142, 0x0001 }, ++ { 0x40a2, 0x0001 }, + }, +- }, { +- 54000000, { +- { 0x0072, 0x0001}, +- { 0x2142, 0x0001}, +- { 0x40a2, 0x0001}, ++ }, { ++ 61333000, { ++ { 0x0072, 0x0001 }, ++ { 0x2142, 0x0001 }, ++ { 0x40a2, 0x0001 }, + }, +- }, { +- 65000000, { +- { 0x0072, 0x0001}, +- { 0x2142, 0x0001}, +- { 0x40a2, 0x0001}, ++ }, { ++ 73600000, { ++ { 0x0072, 0x0001 }, ++ { 0x2142, 0x0001 }, ++ { 0x4061, 0x0002 }, + }, +- }, { +- 66000000, { +- { 0x013e, 0x0003}, +- { 0x217e, 0x0002}, +- { 0x4061, 0x0002} ++ }, { ++ 92000000, { ++ { 0x0072, 0x0001 }, ++ { 0x2145, 0x0002 }, ++ { 0x4061, 0x0002 }, ++ }, ++ }, { ++ 122666000, { ++ { 0x0051, 0x0002 }, ++ { 0x2145, 0x0002 }, ++ { 0x4061, 0x0002 }, + }, +- }, { +- 74250000, { +- { 0x0072, 0x0001}, +- { 0x2145, 0x0002}, +- { 0x4061, 0x0002} ++ }, { ++ 147200000, { ++ { 0x0051, 0x0002 }, ++ { 0x2145, 0x0002 }, ++ { 0x4064, 0x0003 }, + }, +- }, { +- 83500000, { +- { 0x0072, 0x0001}, ++ }, { ++ 184000000, { ++ { 0x0051, 0x0002 }, ++ { 0x214c, 0x0003 }, ++ { 0x4064, 0x0003 }, + }, +- }, { +- 108000000, { +- { 0x0051, 0x0002}, +- { 0x2145, 0x0002}, +- { 0x4061, 0x0002} ++ }, { ++ 226666000, { ++ { 0x0040, 0x0003 }, ++ { 0x214c, 0x0003 }, ++ { 0x4064, 0x0003 }, + }, +- }, { +- 106500000, { +- { 0x0051, 0x0002}, +- { 0x2145, 0x0002}, +- { 0x4061, 0x0002} ++ }, { ++ 272000000, { ++ { 0x0040, 0x0003 }, ++ { 0x214c, 0x0003 }, ++ { 0x5a64, 0x0003 }, + }, +- }, { +- 146250000, { +- { 0x0051, 0x0002}, +- { 0x2145, 0x0002}, +- { 0x4061, 0x0002} ++ }, { ++ 340000000, { ++ { 0x0040, 0x0003 }, ++ { 0x3b4c, 0x0003 }, ++ { 0x5a64, 0x0003 }, + }, +- }, { +- 148500000, { +- { 0x0051, 0x0003}, +- { 0x214c, 0x0003}, +- { 0x4064, 0x0003} ++ }, { ++ 600000000, { ++ { 0x1a40, 0x0003 }, ++ { 0x3b4c, 0x0003 }, ++ { 0x5a64, 0x0003 }, + }, +- }, { ++ }, { + ~0UL, { +- { 0x00a0, 0x000a }, +- { 0x2001, 0x000f }, +- { 0x4002, 0x000f }, ++ { 0x0000, 0x0000 }, ++ { 0x0000, 0x0000 }, ++ { 0x0000, 0x0000 }, + }, + } + }; + +From 2588e01b10b0f41a5245f11a857dd3c0d0d710ea Mon Sep 17 00:00:00 2001 +From: Jonas Karlman +Date: Wed, 8 Jan 2020 21:07:52 +0000 +Subject: [PATCH] drm/rockchip: dw-hdmi: limit tmds to 340mhz + +RK3228/RK3328 does not provide a stable hdmi signal at TMDS rates +above 371.25MHz (340MHz pixel clock). + +Limit the pixel clock rate to 340MHz to provide a stable signal. +Also limit the pixel clock to the display reported max tmds clock. + +This also enables use of pixel clocks up to 340MHz on RK3288/RK3399. + +Signed-off-by: Jonas Karlman +--- + drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c | 16 ++++------------ + 1 file changed, 4 insertions(+), 12 deletions(-) + +diff --git a/drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c b/drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c +index b5d2cdaa24fa..5f7ab8e6bb72 100644 +--- a/drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c ++++ b/drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c +@@ -221,19 +221,11 @@ dw_hdmi_rockchip_mode_valid(struct dw_hdmi *hdmi, void *data, + const struct drm_display_info *info, + const struct drm_display_mode *mode) + { +- const struct dw_hdmi_mpll_config *mpll_cfg = rockchip_mpll_cfg; +- int pclk = mode->clock * 1000; +- bool valid = false; +- int i; +- +- for (i = 0; mpll_cfg[i].mpixelclock != (~0UL); i++) { +- if (pclk == mpll_cfg[i].mpixelclock) { +- valid = true; +- break; +- } +- } ++ if (mode->clock > 340000 || ++ (info->max_tmds_clock && mode->clock > info->max_tmds_clock)) ++ return MODE_CLOCK_HIGH; + +- return (valid) ? MODE_OK : MODE_BAD; ++ return MODE_OK; + } + + static void dw_hdmi_rockchip_encoder_disable(struct drm_encoder *encoder) + +From f675144085ff4d8a542b2af0b64bb40adeeea223 Mon Sep 17 00:00:00 2001 +From: Jonas Karlman +Date: Sun, 3 May 2020 22:36:23 +0000 +Subject: [PATCH] drm/rockchip: dw-hdmi: limit resolution to 3840x2160 + +Signed-off-by: Jonas Karlman +--- + drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c b/drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c +index 5f7ab8e6bb72..0e7ca368314d 100644 +--- a/drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c ++++ b/drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c +@@ -225,7 +225,7 @@ dw_hdmi_rockchip_mode_valid(struct dw_hdmi *hdmi, void *data, + (info->max_tmds_clock && mode->clock > info->max_tmds_clock)) + return MODE_CLOCK_HIGH; + +- return MODE_OK; ++ return drm_mode_validate_size(mode, 3840, 2160); + } + + static void dw_hdmi_rockchip_encoder_disable(struct drm_encoder *encoder) + +From 91c9009079bb18c957de8e5b0734ea72e06bf584 Mon Sep 17 00:00:00 2001 +From: Jonas Karlman +Date: Wed, 8 Jan 2020 21:07:49 +0000 +Subject: [PATCH] drm/rockchip: dw-hdmi: allow high tmds bit rates + +Prepare support for High TMDS Bit Rates used by HDMI2.0 display modes. + +Signed-off-by: Jonas Karlman +--- + drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c | 2 ++ + 1 file changed, 2 insertions(+) + +diff --git a/drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c b/drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c +index 0e7ca368314d..6f7641fbe6cc 100644 +--- a/drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c ++++ b/drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c +@@ -306,6 +306,8 @@ static int dw_hdmi_rockchip_genphy_init(struct dw_hdmi *dw_hdmi, void *data, + { + struct rockchip_hdmi *hdmi = (struct rockchip_hdmi *)data; + ++ dw_hdmi_set_high_tmds_clock_ratio(dw_hdmi, display); ++ + return phy_power_on(hdmi->phy); + } + + +From e088ac1e106ca08f19ed7e121ec4338651a80f50 Mon Sep 17 00:00:00 2001 +From: Jonas Karlman +Date: Wed, 8 Jan 2020 21:07:52 +0000 +Subject: [PATCH] drm/rockchip: dw-hdmi: remove unused plat_data on + rk3228/rk3328 + +mpll_cfg/cur_ctr/phy_config is not used when phy_force_vendor is true, +lets remove them. + +Signed-off-by: Jonas Karlman +--- + drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c | 6 ------ + 1 file changed, 6 deletions(-) + +diff --git a/drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c b/drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c +index 6f7641fbe6cc..cc20a83fa9b8 100644 +--- a/drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c ++++ b/drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c +@@ -396,9 +396,6 @@ static struct rockchip_hdmi_chip_data rk3228_chip_data = { + + static const struct dw_hdmi_plat_data rk3228_hdmi_drv_data = { + .mode_valid = dw_hdmi_rockchip_mode_valid, +- .mpll_cfg = rockchip_mpll_cfg, +- .cur_ctr = rockchip_cur_ctr, +- .phy_config = rockchip_phy_config, + .phy_data = &rk3228_chip_data, + .phy_ops = &rk3228_hdmi_phy_ops, + .phy_name = "inno_dw_hdmi_phy2", +@@ -433,9 +430,6 @@ static struct rockchip_hdmi_chip_data rk3328_chip_data = { + + static const struct dw_hdmi_plat_data rk3328_hdmi_drv_data = { + .mode_valid = dw_hdmi_rockchip_mode_valid, +- .mpll_cfg = rockchip_mpll_cfg, +- .cur_ctr = rockchip_cur_ctr, +- .phy_config = rockchip_phy_config, + .phy_data = &rk3328_chip_data, + .phy_ops = &rk3328_hdmi_phy_ops, + .phy_name = "inno_dw_hdmi_phy2", + +From 32b6d7962f1df9b3bc2af2485dc32a54772c27ec Mon Sep 17 00:00:00 2001 +From: Jonas Karlman +Date: Sat, 10 Oct 2020 10:16:32 +0000 +Subject: [PATCH] drm/rockchip: dw-hdmi: encoder error handling + +Signed-off-by: Jonas Karlman +--- + drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c | 25 +++++++++++++++------ + 1 file changed, 18 insertions(+), 7 deletions(-) + +diff --git a/drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c b/drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c +index cc20a83fa9b8..fd614c8a3486 100644 +--- a/drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c ++++ b/drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c +@@ -516,8 +516,7 @@ static int dw_hdmi_rockchip_bind(struct device *dev, struct device *master, + + ret = clk_prepare_enable(hdmi->vpll_clk); + if (ret) { +- DRM_DEV_ERROR(hdmi->dev, "Failed to enable HDMI vpll: %d\n", +- ret); ++ DRM_DEV_ERROR(hdmi->dev, "Failed to enable vpll: %d\n", ret); + return ret; + } + +@@ -525,12 +524,16 @@ static int dw_hdmi_rockchip_bind(struct device *dev, struct device *master, + if (IS_ERR(hdmi->phy)) { + ret = PTR_ERR(hdmi->phy); + if (ret != -EPROBE_DEFER) +- DRM_DEV_ERROR(hdmi->dev, "failed to get phy\n"); +- return ret; ++ DRM_DEV_ERROR(hdmi->dev, "Failed to get phy: %d\n", ret); ++ goto err_disable_clk; + } + + drm_encoder_helper_add(encoder, &dw_hdmi_rockchip_encoder_helper_funcs); +- drm_simple_encoder_init(drm, encoder, DRM_MODE_ENCODER_TMDS); ++ ret = drm_simple_encoder_init(drm, encoder, DRM_MODE_ENCODER_TMDS); ++ if (ret) { ++ DRM_DEV_ERROR(hdmi->dev, "Failed to init encoder: %d\n", ret); ++ goto err_disable_clk; ++ } + + platform_set_drvdata(pdev, hdmi); + +@@ -542,10 +545,18 @@ static int dw_hdmi_rockchip_bind(struct device *dev, struct device *master, + */ + if (IS_ERR(hdmi->hdmi)) { + ret = PTR_ERR(hdmi->hdmi); +- drm_encoder_cleanup(encoder); +- clk_disable_unprepare(hdmi->vpll_clk); ++ if (ret != -EPROBE_DEFER) ++ DRM_DEV_ERROR(hdmi->dev, "Failed to init dw-hdmi bridge: %d\n", ret); ++ goto err_encoder_cleanup; + } + ++ return 0; ++ ++err_encoder_cleanup: ++ drm_encoder_cleanup(encoder); ++err_disable_clk: ++ clk_disable_unprepare(hdmi->vpll_clk); ++ + return ret; + } + + +From 8d7180b3ff4733269c4465dd2bb2433f762cdf75 Mon Sep 17 00:00:00 2001 +From: Jonas Karlman +Date: Wed, 8 Jan 2020 21:07:50 +0000 +Subject: [PATCH] clk: rockchip: set parent rate for DCLK_VOP clock on rk3228 + +Signed-off-by: Jonas Karlman +--- + drivers/clk/rockchip/clk-rk3228.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/drivers/clk/rockchip/clk-rk3228.c b/drivers/clk/rockchip/clk-rk3228.c +index 47d6482dda9d..a2b4d5487514 100644 +--- a/drivers/clk/rockchip/clk-rk3228.c ++++ b/drivers/clk/rockchip/clk-rk3228.c +@@ -408,7 +408,7 @@ static struct rockchip_clk_branch rk3228_clk_branches[] __initdata = { + RK2928_CLKSEL_CON(29), 0, 3, DFLAGS), + DIV(0, "sclk_vop_pre", "sclk_vop_src", 0, + RK2928_CLKSEL_CON(27), 8, 8, DFLAGS), +- MUX(DCLK_VOP, "dclk_vop", mux_dclk_vop_p, 0, ++ MUX(DCLK_VOP, "dclk_vop", mux_dclk_vop_p, CLK_SET_RATE_PARENT | CLK_SET_RATE_NO_REPARENT, + RK2928_CLKSEL_CON(27), 1, 1, MFLAGS), + + FACTOR(0, "xin12m", "xin24m", 0, 1, 2), + +From 3fa9c4af2ba74a77b9e1a63a587e61b189f7860e Mon Sep 17 00:00:00 2001 +From: Jonas Karlman +Date: Sat, 10 Oct 2020 14:32:21 +0000 +Subject: [PATCH] drm/rockchip: vop: split rk3288 vop + +Signed-off-by: Jonas Karlman +--- + drivers/gpu/drm/rockchip/rockchip_vop_reg.c | 21 ++++++++++++++++++--- + 1 file changed, 18 insertions(+), 3 deletions(-) + +diff --git a/drivers/gpu/drm/rockchip/rockchip_vop_reg.c b/drivers/gpu/drm/rockchip/rockchip_vop_reg.c +index cf87361108a0..05ade8ea962f 100644 +--- a/drivers/gpu/drm/rockchip/rockchip_vop_reg.c ++++ b/drivers/gpu/drm/rockchip/rockchip_vop_reg.c +@@ -697,7 +697,7 @@ static const struct vop_intr rk3288_vop_intr = { + .clear = VOP_REG(RK3288_INTR_CTRL0, 0xf, 8), + }; + +-static const struct vop_data rk3288_vop = { ++static const struct vop_data rk3288_vop_big = { + .version = VOP_VERSION(3, 1), + .feature = VOP_FEATURE_OUTPUT_RGB10, + .max_output = { 3840, 2160 }, +@@ -710,6 +710,19 @@ static const struct vop_data rk3288_vop = { + .lut_size = 1024, + }; + ++static const struct vop_data rk3288_vop_lit = { ++ .version = VOP_VERSION(3, 1), ++ .feature = VOP_FEATURE_OUTPUT_RGB10, ++ .max_output = { 2560, 1600 }, ++ .intr = &rk3288_vop_intr, ++ .common = &rk3288_common, ++ .modeset = &rk3288_modeset, ++ .output = &rk3288_output, ++ .win = rk3288_vop_win_data, ++ .win_size = ARRAY_SIZE(rk3288_vop_win_data), ++ .lut_size = 1024, ++}; ++ + static const int rk3368_vop_intrs[] = { + FS_INTR, + 0, 0, +@@ -1075,8 +1088,10 @@ static const struct of_device_id vop_driver_dt_match[] = { + .data = &rk3066_vop }, + { .compatible = "rockchip,rk3188-vop", + .data = &rk3188_vop }, +- { .compatible = "rockchip,rk3288-vop", +- .data = &rk3288_vop }, ++ { .compatible = "rockchip,rk3288-vop-big", ++ .data = &rk3288_vop_big }, ++ { .compatible = "rockchip,rk3288-vop-lit", ++ .data = &rk3288_vop_lit }, + { .compatible = "rockchip,rk3368-vop", + .data = &rk3368_vop }, + { .compatible = "rockchip,rk3366-vop", + +From 49ea3a266d0867e760bae9bc1310b6eff1f31c43 Mon Sep 17 00:00:00 2001 +From: Jonas Karlman +Date: Sat, 10 Oct 2020 14:33:30 +0000 +Subject: [PATCH] ARM: dts: rockchip: split rk3288 vop + +Signed-off-by: Jonas Karlman +--- + arch/arm/boot/dts/rk3288.dtsi | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +diff --git a/arch/arm/boot/dts/rk3288.dtsi b/arch/arm/boot/dts/rk3288.dtsi +index 01ea1f170f77..3575dea1ee29 100644 +--- a/arch/arm/boot/dts/rk3288.dtsi ++++ b/arch/arm/boot/dts/rk3288.dtsi +@@ -1037,7 +1037,7 @@ rga: rga@ff920000 { + }; + + vopb: vop@ff930000 { +- compatible = "rockchip,rk3288-vop"; ++ compatible = "rockchip,rk3288-vop-big"; + reg = <0x0 0xff930000 0x0 0x19c>, <0x0 0xff931000 0x0 0x1000>; + interrupts = ; + clocks = <&cru ACLK_VOP0>, <&cru DCLK_VOP0>, <&cru HCLK_VOP0>; +@@ -1087,7 +1087,7 @@ vopb_mmu: iommu@ff930300 { + }; + + vopl: vop@ff940000 { +- compatible = "rockchip,rk3288-vop"; ++ compatible = "rockchip,rk3288-vop-lit"; + reg = <0x0 0xff940000 0x0 0x19c>, <0x0 0xff941000 0x0 0x1000>; + interrupts = ; + clocks = <&cru ACLK_VOP1>, <&cru DCLK_VOP1>, <&cru HCLK_VOP1>; + +From 99960094869486ec89fb1aae483db0bf9629228a Mon Sep 17 00:00:00 2001 +From: Jonas Karlman +Date: Mon, 20 Jul 2020 18:00:44 +0000 +Subject: [PATCH] drm/bridge: dw-hdmi: add mtmdsclock parameter to phy + configure ops + +Signed-off-by: Jonas Karlman +--- + drivers/gpu/drm/bridge/synopsys/dw-hdmi.c | 10 ++++++---- + drivers/gpu/drm/rcar-du/rcar_dw_hdmi.c | 3 ++- + include/drm/bridge/dw_hdmi.h | 3 ++- + 3 files changed, 10 insertions(+), 6 deletions(-) + +diff --git a/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c b/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c +index 0c79a9ba48bb..50199329ad6f 100644 +--- a/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c ++++ b/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c +@@ -137,7 +137,8 @@ struct dw_hdmi_phy_data { + bool has_svsret; + int (*configure)(struct dw_hdmi *hdmi, + const struct dw_hdmi_plat_data *pdata, +- unsigned long mpixelclock); ++ unsigned long mpixelclock, ++ unsigned long mtmdsclock); + }; + + struct dw_hdmi { +@@ -1441,7 +1442,8 @@ static int dw_hdmi_phy_power_on(struct dw_hdmi *hdmi) + */ + static int hdmi_phy_configure_dwc_hdmi_3d_tx(struct dw_hdmi *hdmi, + const struct dw_hdmi_plat_data *pdata, +- unsigned long mpixelclock) ++ unsigned long mpixelclock, ++ unsigned long mtmdsclock) + { + const struct dw_hdmi_mpll_config *mpll_config = pdata->mpll_cfg; + const struct dw_hdmi_curr_ctrl *curr_ctrl = pdata->cur_ctr; +@@ -1516,9 +1518,9 @@ static int hdmi_phy_configure(struct dw_hdmi *hdmi, + + /* Write to the PHY as configured by the platform */ + if (pdata->configure_phy) +- ret = pdata->configure_phy(hdmi, pdata->priv_data, mpixelclock); ++ ret = pdata->configure_phy(hdmi, pdata->priv_data, mpixelclock, mtmdsclock); + else +- ret = phy->configure(hdmi, pdata, mpixelclock); ++ ret = phy->configure(hdmi, pdata, mpixelclock, mtmdsclock); + if (ret) { + dev_err(hdmi->dev, "PHY configuration failed (clock %lu)\n", + mpixelclock); +diff --git a/drivers/gpu/drm/rcar-du/rcar_dw_hdmi.c b/drivers/gpu/drm/rcar-du/rcar_dw_hdmi.c +index 7b8ec8310699..539d86131fd4 100644 +--- a/drivers/gpu/drm/rcar-du/rcar_dw_hdmi.c ++++ b/drivers/gpu/drm/rcar-du/rcar_dw_hdmi.c +@@ -53,7 +53,8 @@ rcar_hdmi_mode_valid(struct dw_hdmi *hdmi, void *data, + } + + static int rcar_hdmi_phy_configure(struct dw_hdmi *hdmi, void *data, +- unsigned long mpixelclock) ++ unsigned long mpixelclock, ++ unsigned long mtmdsclock) + { + const struct rcar_hdmi_phy_params *params = rcar_hdmi_phy_params; + +diff --git a/include/drm/bridge/dw_hdmi.h b/include/drm/bridge/dw_hdmi.h +index ea34ca146b82..4f61ede6486d 100644 +--- a/include/drm/bridge/dw_hdmi.h ++++ b/include/drm/bridge/dw_hdmi.h +@@ -152,7 +152,8 @@ struct dw_hdmi_plat_data { + const struct dw_hdmi_curr_ctrl *cur_ctr; + const struct dw_hdmi_phy_config *phy_config; + int (*configure_phy)(struct dw_hdmi *hdmi, void *data, +- unsigned long mpixelclock); ++ unsigned long mpixelclock, ++ unsigned long mtmdsclock); + }; + + struct dw_hdmi *dw_hdmi_probe(struct platform_device *pdev, + +From a3824d58ac9d6ab774b096a9cc78c5e386f27703 Mon Sep 17 00:00:00 2001 +From: Jonas Karlman +Date: Mon, 20 Jul 2020 21:34:48 +0000 +Subject: [PATCH] drm/bridge: dw-hdmi: support configuring phy for deep color + +Q: Should we rename dw_hdmi_curr_ctrl and dw_hdmi_phy_config mpixelclock to mtmdsclock ? + +Signed-off-by: Jonas Karlman +--- + drivers/gpu/drm/bridge/synopsys/dw-hdmi.c | 17 ++++++++++++----- + 1 file changed, 12 insertions(+), 5 deletions(-) + +diff --git a/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c b/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c +index 50199329ad6f..2581789178c7 100644 +--- a/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c ++++ b/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c +@@ -1448,6 +1448,7 @@ static int hdmi_phy_configure_dwc_hdmi_3d_tx(struct dw_hdmi *hdmi, + const struct dw_hdmi_mpll_config *mpll_config = pdata->mpll_cfg; + const struct dw_hdmi_curr_ctrl *curr_ctrl = pdata->cur_ctr; + const struct dw_hdmi_phy_config *phy_config = pdata->phy_config; ++ int depth; + + /* TOFIX Will need 420 specific PHY configuration tables */ + +@@ -1457,11 +1458,11 @@ static int hdmi_phy_configure_dwc_hdmi_3d_tx(struct dw_hdmi *hdmi, + break; + + for (; curr_ctrl->mpixelclock != ~0UL; curr_ctrl++) +- if (mpixelclock <= curr_ctrl->mpixelclock) ++ if (mtmdsclock <= curr_ctrl->mpixelclock) + break; + + for (; phy_config->mpixelclock != ~0UL; phy_config++) +- if (mpixelclock <= phy_config->mpixelclock) ++ if (mtmdsclock <= phy_config->mpixelclock) + break; + + if (mpll_config->mpixelclock == ~0UL || +@@ -1469,11 +1470,17 @@ static int hdmi_phy_configure_dwc_hdmi_3d_tx(struct dw_hdmi *hdmi, + phy_config->mpixelclock == ~0UL) + return -EINVAL; + +- dw_hdmi_phy_i2c_write(hdmi, mpll_config->res[0].cpce, ++ depth = hdmi_bus_fmt_color_depth(hdmi->hdmi_data.enc_out_bus_format); ++ if (depth > 8 && mpixelclock != mtmdsclock) ++ depth = fls(depth - 8) - 1; ++ else ++ depth = 0; ++ ++ dw_hdmi_phy_i2c_write(hdmi, mpll_config->res[depth].cpce, + HDMI_3D_TX_PHY_CPCE_CTRL); +- dw_hdmi_phy_i2c_write(hdmi, mpll_config->res[0].gmp, ++ dw_hdmi_phy_i2c_write(hdmi, mpll_config->res[depth].gmp, + HDMI_3D_TX_PHY_GMPCTRL); +- dw_hdmi_phy_i2c_write(hdmi, curr_ctrl->curr[0], ++ dw_hdmi_phy_i2c_write(hdmi, curr_ctrl->curr[depth], + HDMI_3D_TX_PHY_CURRCTRL); + + dw_hdmi_phy_i2c_write(hdmi, 0, HDMI_3D_TX_PHY_PLLPHBYCTRL); + +From 3ea359254a9fd83d4bb88febfeff4ec053ca2251 Mon Sep 17 00:00:00 2001 +From: Jonas Karlman +Date: Mon, 20 Jul 2020 22:25:15 +0000 +Subject: [PATCH] drm/bridge: dw-hdmi: add mpll_cfg_420 for ycbcr420 mode + +Signed-off-by: Jonas Karlman +--- + drivers/gpu/drm/bridge/synopsys/dw-hdmi.c | 4 +++- + include/drm/bridge/dw_hdmi.h | 1 + + 2 files changed, 4 insertions(+), 1 deletion(-) + +diff --git a/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c b/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c +index 2581789178c7..6d319b95b992 100644 +--- a/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c ++++ b/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c +@@ -1450,7 +1450,9 @@ static int hdmi_phy_configure_dwc_hdmi_3d_tx(struct dw_hdmi *hdmi, + const struct dw_hdmi_phy_config *phy_config = pdata->phy_config; + int depth; + +- /* TOFIX Will need 420 specific PHY configuration tables */ ++ if (hdmi_bus_fmt_is_yuv420(hdmi->hdmi_data.enc_out_bus_format) && ++ pdata->mpll_cfg_420) ++ mpll_config = pdata->mpll_cfg_420; + + /* PLL/MPLL Cfg - always match on final entry */ + for (; mpll_config->mpixelclock != ~0UL; mpll_config++) +diff --git a/include/drm/bridge/dw_hdmi.h b/include/drm/bridge/dw_hdmi.h +index 4f61ede6486d..0ebe01835d2a 100644 +--- a/include/drm/bridge/dw_hdmi.h ++++ b/include/drm/bridge/dw_hdmi.h +@@ -149,6 +149,7 @@ struct dw_hdmi_plat_data { + + /* Synopsys PHY support */ + const struct dw_hdmi_mpll_config *mpll_cfg; ++ const struct dw_hdmi_mpll_config *mpll_cfg_420; + const struct dw_hdmi_curr_ctrl *cur_ctr; + const struct dw_hdmi_phy_config *phy_config; + int (*configure_phy)(struct dw_hdmi *hdmi, void *data, + +From bf5ae7b3aa6b108f5346ead89ae2f0b7c0be8ada Mon Sep 17 00:00:00 2001 +From: Jonas Karlman +Date: Wed, 15 Jul 2020 09:49:21 +0000 +Subject: [PATCH] drm/rockchip: dw-hdmi: mode_valid: allow 420 clock rate + +Signed-off-by: Jonas Karlman +--- + drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c | 12 ++++++++++-- + 1 file changed, 10 insertions(+), 2 deletions(-) + +diff --git a/drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c b/drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c +index fd614c8a3486..c22add144cf4 100644 +--- a/drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c ++++ b/drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c +@@ -221,8 +221,15 @@ dw_hdmi_rockchip_mode_valid(struct dw_hdmi *hdmi, void *data, + const struct drm_display_info *info, + const struct drm_display_mode *mode) + { +- if (mode->clock > 340000 || +- (info->max_tmds_clock && mode->clock > info->max_tmds_clock)) ++ struct dw_hdmi_plat_data *pdata = (struct dw_hdmi_plat_data *)data; ++ int clock = mode->clock; ++ ++ if (pdata->ycbcr_420_allowed && drm_mode_is_420(info, mode) && ++ (info->color_formats & DRM_COLOR_FORMAT_YCRCB420)) ++ clock /= 2; ++ ++ if (clock > 340000 || ++ (info->max_tmds_clock && clock > info->max_tmds_clock)) + return MODE_CLOCK_HIGH; + + return drm_mode_validate_size(mode, 3840, 2160); +@@ -495,6 +502,7 @@ static int dw_hdmi_rockchip_bind(struct device *dev, struct device *master, + + hdmi->dev = &pdev->dev; + hdmi->chip_data = plat_data->phy_data; ++ plat_data->priv_data = plat_data; + plat_data->phy_data = hdmi; + encoder = &hdmi->encoder; + + +From 50c0ad01ff4dcff17fa87fb378f5214e37df572c Mon Sep 17 00:00:00 2001 +From: Jonas Karlman +Date: Mon, 20 Jul 2020 22:26:19 +0000 +Subject: [PATCH] drm/rockchip: dw-hdmi: add YCbCr420 mpll cfg for rk3399 + +Signed-off-by: Jonas Karlman +--- + drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c | 41 +++++++++++++++++++++ + 1 file changed, 41 insertions(+) + +diff --git a/drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c b/drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c +index c22add144cf4..1e558af2c9b2 100644 +--- a/drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c ++++ b/drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c +@@ -165,6 +165,46 @@ static const struct dw_hdmi_mpll_config rockchip_mpll_cfg[] = { + } + }; + ++static const struct dw_hdmi_mpll_config rockchip_mpll_cfg_420[] = { ++ { ++ 30666000, { ++ { 0x00b7, 0x0000 }, ++ { 0x2157, 0x0000 }, ++ { 0x40f7, 0x0000 }, ++ }, ++ }, { ++ 92000000, { ++ { 0x00b7, 0x0000 }, ++ { 0x2143, 0x0001 }, ++ { 0x40a3, 0x0001 }, ++ }, ++ }, { ++ 184000000, { ++ { 0x0073, 0x0001 }, ++ { 0x2146, 0x0002 }, ++ { 0x4062, 0x0002 }, ++ }, ++ }, { ++ 340000000, { ++ { 0x0052, 0x0003 }, ++ { 0x214d, 0x0003 }, ++ { 0x4065, 0x0003 }, ++ }, ++ }, { ++ 600000000, { ++ { 0x0041, 0x0003 }, ++ { 0x3b4d, 0x0003 }, ++ { 0x5a65, 0x0003 }, ++ }, ++ }, { ++ ~0UL, { ++ { 0x0000, 0x0000 }, ++ { 0x0000, 0x0000 }, ++ { 0x0000, 0x0000 }, ++ }, ++ } ++}; ++ + static const struct dw_hdmi_curr_ctrl rockchip_cur_ctr[] = { + /* pixelclk bpp8 bpp10 bpp12 */ + { +@@ -453,6 +493,7 @@ static struct rockchip_hdmi_chip_data rk3399_chip_data = { + static const struct dw_hdmi_plat_data rk3399_hdmi_drv_data = { + .mode_valid = dw_hdmi_rockchip_mode_valid, + .mpll_cfg = rockchip_mpll_cfg, ++ .mpll_cfg_420 = rockchip_mpll_cfg_420, + .cur_ctr = rockchip_cur_ctr, + .phy_config = rockchip_phy_config, + .phy_data = &rk3399_chip_data, + +From 22eeecd451b46dba081deea74c2613a339619f1c Mon Sep 17 00:00:00 2001 +From: Shunqing Chen +Date: Wed, 15 Jul 2020 15:19:11 +0800 +Subject: [PATCH] drm/rockchip: dw-hdmi: add YCbCr420 mpll cfg for rk3288w + +Signed-off-by: Shunqing Chen +Signed-off-by: Jonas Karlman +--- + drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c | 41 +++++++++++++++++++++ + 1 file changed, 41 insertions(+) + +diff --git a/drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c b/drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c +index 1e558af2c9b2..6dbd0e422ca1 100644 +--- a/drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c ++++ b/drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c +@@ -205,6 +205,46 @@ static const struct dw_hdmi_mpll_config rockchip_mpll_cfg_420[] = { + } + }; + ++static const struct dw_hdmi_mpll_config rockchip_rk3288w_mpll_cfg_420[] = { ++ { ++ 30666000, { ++ { 0x00b7, 0x0000 }, ++ { 0x2157, 0x0000 }, ++ { 0x40f7, 0x0000 }, ++ }, ++ }, { ++ 92000000, { ++ { 0x00b7, 0x0000 }, ++ { 0x2143, 0x0001 }, ++ { 0x40a3, 0x0001 }, ++ }, ++ }, { ++ 184000000, { ++ { 0x0073, 0x0001 }, ++ { 0x2146, 0x0002 }, ++ { 0x4062, 0x0002 }, ++ }, ++ }, { ++ 340000000, { ++ { 0x0052, 0x0003 }, ++ { 0x214d, 0x0003 }, ++ { 0x4065, 0x0003 }, ++ }, ++ }, { ++ 600000000, { ++ { 0x0040, 0x0003 }, ++ { 0x3b4c, 0x0003 }, ++ { 0x5a65, 0x0003 }, ++ }, ++ }, { ++ ~0UL, { ++ { 0x0000, 0x0000 }, ++ { 0x0000, 0x0000 }, ++ { 0x0000, 0x0000 }, ++ }, ++ } ++}; ++ + static const struct dw_hdmi_curr_ctrl rockchip_cur_ctr[] = { + /* pixelclk bpp8 bpp10 bpp12 */ + { +@@ -458,6 +498,7 @@ static struct rockchip_hdmi_chip_data rk3288_chip_data = { + static const struct dw_hdmi_plat_data rk3288_hdmi_drv_data = { + .mode_valid = dw_hdmi_rockchip_mode_valid, + .mpll_cfg = rockchip_mpll_cfg, ++ .mpll_cfg_420 = rockchip_rk3288w_mpll_cfg_420, + .cur_ctr = rockchip_cur_ctr, + .phy_config = rockchip_phy_config, + .phy_data = &rk3288_chip_data, + +From 9da14af9655198b1f10d8f06a5b1f0995e578a48 Mon Sep 17 00:00:00 2001 +From: Jonas Karlman +Date: Fri, 20 Dec 2019 08:12:42 +0000 +Subject: [PATCH] drm/rockchip: dw-hdmi: add bridge and switch to + drm_bridge_funcs + +Switch the dw-hdmi driver to drm_bridge_funcs by implementing +a new local bridge, connecting it to the dw-hdmi bridge. + +Also enable bridge format negotiation by implementing +atomic_get_input_bus_fmts and support for 8-bit RGB 4:4:4. + +Signed-off-by: Jonas Karlman +--- + drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c | 110 ++++++++++++++------ + 1 file changed, 78 insertions(+), 32 deletions(-) + +diff --git a/drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c b/drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c +index 6dbd0e422ca1..510ae5d5f133 100644 +--- a/drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c ++++ b/drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c +@@ -68,6 +68,7 @@ struct rockchip_hdmi { + struct device *dev; + struct regmap *regmap; + struct drm_encoder encoder; ++ struct drm_bridge bridge; + const struct rockchip_hdmi_chip_data *chip_data; + struct clk *vpll_clk; + struct clk *grf_clk; +@@ -315,30 +316,20 @@ dw_hdmi_rockchip_mode_valid(struct dw_hdmi *hdmi, void *data, + return drm_mode_validate_size(mode, 3840, 2160); + } + +-static void dw_hdmi_rockchip_encoder_disable(struct drm_encoder *encoder) ++static void ++dw_hdmi_rockchip_bridge_mode_set(struct drm_bridge *bridge, ++ const struct drm_display_mode *mode, ++ const struct drm_display_mode *adjusted_mode) + { +-} ++ struct rockchip_hdmi *hdmi = to_rockchip_hdmi(bridge); + +-static bool +-dw_hdmi_rockchip_encoder_mode_fixup(struct drm_encoder *encoder, +- const struct drm_display_mode *mode, +- struct drm_display_mode *adj_mode) +-{ +- return true; ++ clk_set_rate(hdmi->vpll_clk, adjusted_mode->clock * 1000); + } + +-static void dw_hdmi_rockchip_encoder_mode_set(struct drm_encoder *encoder, +- struct drm_display_mode *mode, +- struct drm_display_mode *adj_mode) ++static void dw_hdmi_rockchip_bridge_enable(struct drm_bridge *bridge) + { +- struct rockchip_hdmi *hdmi = to_rockchip_hdmi(encoder); +- +- clk_set_rate(hdmi->vpll_clk, adj_mode->clock * 1000); +-} +- +-static void dw_hdmi_rockchip_encoder_enable(struct drm_encoder *encoder) +-{ +- struct rockchip_hdmi *hdmi = to_rockchip_hdmi(encoder); ++ struct rockchip_hdmi *hdmi = to_rockchip_hdmi(bridge); ++ struct drm_encoder *encoder = bridge->encoder; + u32 val; + int ret; + +@@ -366,10 +357,21 @@ static void dw_hdmi_rockchip_encoder_enable(struct drm_encoder *encoder) + ret ? "LIT" : "BIG"); + } + ++static bool is_rgb(u32 format) ++{ ++ switch (format) { ++ case MEDIA_BUS_FMT_RGB888_1X24: ++ return true; ++ default: ++ return false; ++ } ++} ++ + static int +-dw_hdmi_rockchip_encoder_atomic_check(struct drm_encoder *encoder, +- struct drm_crtc_state *crtc_state, +- struct drm_connector_state *conn_state) ++dw_hdmi_rockchip_bridge_atomic_check(struct drm_bridge *bridge, ++ struct drm_bridge_state *bridge_state, ++ struct drm_crtc_state *crtc_state, ++ struct drm_connector_state *conn_state) + { + struct rockchip_crtc_state *s = to_rockchip_crtc_state(crtc_state); + +@@ -379,12 +381,38 @@ dw_hdmi_rockchip_encoder_atomic_check(struct drm_encoder *encoder, + return 0; + } + +-static const struct drm_encoder_helper_funcs dw_hdmi_rockchip_encoder_helper_funcs = { +- .mode_fixup = dw_hdmi_rockchip_encoder_mode_fixup, +- .mode_set = dw_hdmi_rockchip_encoder_mode_set, +- .enable = dw_hdmi_rockchip_encoder_enable, +- .disable = dw_hdmi_rockchip_encoder_disable, +- .atomic_check = dw_hdmi_rockchip_encoder_atomic_check, ++static u32 *dw_hdmi_rockchip_get_input_bus_fmts(struct drm_bridge *bridge, ++ struct drm_bridge_state *bridge_state, ++ struct drm_crtc_state *crtc_state, ++ struct drm_connector_state *conn_state, ++ u32 output_fmt, ++ unsigned int *num_input_fmts) ++{ ++ u32 *input_fmt; ++ ++ *num_input_fmts = 0; ++ ++ if (!is_rgb(output_fmt)) ++ return NULL; ++ ++ input_fmt = kzalloc(sizeof(*input_fmt), GFP_KERNEL); ++ if (!input_fmt) ++ return NULL; ++ ++ *num_input_fmts = 1; ++ *input_fmt = output_fmt; ++ ++ return input_fmt; ++} ++ ++static const struct drm_bridge_funcs dw_hdmi_rockchip_bridge_funcs = { ++ .mode_set = dw_hdmi_rockchip_bridge_mode_set, ++ .enable = dw_hdmi_rockchip_bridge_enable, ++ .atomic_duplicate_state = drm_atomic_helper_bridge_duplicate_state, ++ .atomic_destroy_state = drm_atomic_helper_bridge_destroy_state, ++ .atomic_get_input_bus_fmts = dw_hdmi_rockchip_get_input_bus_fmts, ++ .atomic_check = dw_hdmi_rockchip_bridge_atomic_check, ++ .atomic_reset = drm_atomic_helper_bridge_reset, + }; + + static int dw_hdmi_rockchip_genphy_init(struct dw_hdmi *dw_hdmi, void *data, +@@ -565,6 +593,7 @@ static int dw_hdmi_rockchip_bind(struct device *dev, struct device *master, + struct dw_hdmi_plat_data *plat_data; + const struct of_device_id *match; + struct drm_device *drm = data; ++ struct drm_bridge *next_bridge; + struct drm_encoder *encoder; + struct rockchip_hdmi *hdmi; + int ret; +@@ -618,19 +647,21 @@ static int dw_hdmi_rockchip_bind(struct device *dev, struct device *master, + goto err_disable_clk; + } + +- drm_encoder_helper_add(encoder, &dw_hdmi_rockchip_encoder_helper_funcs); + ret = drm_simple_encoder_init(drm, encoder, DRM_MODE_ENCODER_TMDS); + if (ret) { + DRM_DEV_ERROR(hdmi->dev, "Failed to init encoder: %d\n", ret); + goto err_disable_clk; + } + ++ hdmi->bridge.funcs = &dw_hdmi_rockchip_bridge_funcs; ++ drm_bridge_attach(encoder, &hdmi->bridge, NULL, 0); ++ + platform_set_drvdata(pdev, hdmi); + +- hdmi->hdmi = dw_hdmi_bind(pdev, encoder, plat_data); ++ hdmi->hdmi = dw_hdmi_probe(pdev, plat_data); + + /* +- * If dw_hdmi_bind() fails we'll never call dw_hdmi_unbind(), ++ * If dw_hdmi_probe() fails we'll never call dw_hdmi_remove(), + * which would have called the encoder cleanup. Do it manually. + */ + if (IS_ERR(hdmi->hdmi)) { +@@ -640,8 +671,23 @@ static int dw_hdmi_rockchip_bind(struct device *dev, struct device *master, + goto err_encoder_cleanup; + } + ++ next_bridge = of_drm_find_bridge(pdev->dev.of_node); ++ if (!next_bridge) { ++ ret = -EPROBE_DEFER; ++ goto err_dw_hdmi_remove; ++ } ++ ++ ret = drm_bridge_attach(encoder, next_bridge, &hdmi->bridge, 0); ++ if (ret) { ++ if (ret != -EPROBE_DEFER) ++ DRM_DEV_ERROR(hdmi->dev, "Failed to attach dw-hdmi bridge: %d\n", ret); ++ goto err_dw_hdmi_remove; ++ } ++ + return 0; + ++err_dw_hdmi_remove: ++ dw_hdmi_remove(hdmi->hdmi); + err_encoder_cleanup: + drm_encoder_cleanup(encoder); + err_disable_clk: +@@ -655,7 +701,7 @@ static void dw_hdmi_rockchip_unbind(struct device *dev, struct device *master, + { + struct rockchip_hdmi *hdmi = dev_get_drvdata(dev); + +- dw_hdmi_unbind(hdmi->hdmi); ++ dw_hdmi_remove(hdmi->hdmi); + clk_disable_unprepare(hdmi->vpll_clk); + } + + +From 8efac3d1616d43baa58ea7e1e06a93d31abb014d Mon Sep 17 00:00:00 2001 +From: Jonas Karlman +Date: Fri, 9 Oct 2020 15:24:53 +0000 +Subject: [PATCH] drm/rockchip: vop: create planes in window order + +Signed-off-by: Jonas Karlman +--- + drivers/gpu/drm/rockchip/rockchip_drm_vop.c | 36 +++------------------ + 1 file changed, 4 insertions(+), 32 deletions(-) + +diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_vop.c b/drivers/gpu/drm/rockchip/rockchip_drm_vop.c +index b15ee823039e..def4c592b75f 100644 +--- a/drivers/gpu/drm/rockchip/rockchip_drm_vop.c ++++ b/drivers/gpu/drm/rockchip/rockchip_drm_vop.c +@@ -1854,19 +1854,10 @@ static int vop_create_crtc(struct vop *vop) + int ret; + int i; + +- /* +- * Create drm_plane for primary and cursor planes first, since we need +- * to pass them to drm_crtc_init_with_planes, which sets the +- * "possible_crtcs" to the newly initialized crtc. +- */ + for (i = 0; i < vop_data->win_size; i++) { + struct vop_win *vop_win = &vop->win[i]; + const struct vop_win_data *win_data = vop_win->data; + +- if (win_data->type != DRM_PLANE_TYPE_PRIMARY && +- win_data->type != DRM_PLANE_TYPE_CURSOR) +- continue; +- + ret = drm_universal_plane_init(vop->drm_dev, &vop_win->base, + 0, &vop_plane_funcs, + win_data->phy->data_formats, +@@ -1899,32 +1890,13 @@ static int vop_create_crtc(struct vop *vop) + drm_crtc_enable_color_mgmt(crtc, 0, false, vop_data->lut_size); + } + +- /* +- * Create drm_planes for overlay windows with possible_crtcs restricted +- * to the newly created crtc. +- */ ++ /* Set possible_crtcs to the newly created crtc for overlay windows */ + for (i = 0; i < vop_data->win_size; i++) { + struct vop_win *vop_win = &vop->win[i]; +- const struct vop_win_data *win_data = vop_win->data; +- unsigned long possible_crtcs = drm_crtc_mask(crtc); +- +- if (win_data->type != DRM_PLANE_TYPE_OVERLAY) +- continue; + +- ret = drm_universal_plane_init(vop->drm_dev, &vop_win->base, +- possible_crtcs, +- &vop_plane_funcs, +- win_data->phy->data_formats, +- win_data->phy->nformats, +- win_data->phy->format_modifiers, +- win_data->type, NULL); +- if (ret) { +- DRM_DEV_ERROR(vop->dev, "failed to init overlay %d\n", +- ret); +- goto err_cleanup_crtc; +- } +- drm_plane_helper_add(&vop_win->base, &plane_helper_funcs); +- vop_plane_add_properties(&vop_win->base, win_data); ++ plane = &vop_win->base; ++ if (plane->type == DRM_PLANE_TYPE_OVERLAY) ++ plane->possible_crtcs = drm_crtc_mask(crtc); + } + + port = of_get_child_by_name(dev->of_node, "port"); + +From a3890216ecafda474fcd3fda529f1177b682dbe9 Mon Sep 17 00:00:00 2001 +From: Jonas Karlman +Date: Fri, 9 Oct 2020 15:29:27 +0000 +Subject: [PATCH] drm/rockchip: vop: add immutable zpos property + +Signed-off-by: Jonas Karlman +--- + drivers/gpu/drm/rockchip/rockchip_drm_fb.c | 2 ++ + drivers/gpu/drm/rockchip/rockchip_drm_vop.c | 6 ++++-- + 2 files changed, 6 insertions(+), 2 deletions(-) + +diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_fb.c b/drivers/gpu/drm/rockchip/rockchip_drm_fb.c +index 3aa37e177667..a2b59faa9184 100644 +--- a/drivers/gpu/drm/rockchip/rockchip_drm_fb.c ++++ b/drivers/gpu/drm/rockchip/rockchip_drm_fb.c +@@ -132,6 +132,8 @@ void rockchip_drm_mode_config_init(struct drm_device *dev) + dev->mode_config.max_width = 4096; + dev->mode_config.max_height = 4096; + ++ dev->mode_config.normalize_zpos = true; ++ + dev->mode_config.funcs = &rockchip_drm_mode_config_funcs; + dev->mode_config.helper_private = &rockchip_mode_config_helpers; + } +diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_vop.c b/drivers/gpu/drm/rockchip/rockchip_drm_vop.c +index def4c592b75f..1dd8bf5ff4be 100644 +--- a/drivers/gpu/drm/rockchip/rockchip_drm_vop.c ++++ b/drivers/gpu/drm/rockchip/rockchip_drm_vop.c +@@ -1831,7 +1831,7 @@ static irqreturn_t vop_isr(int irq, void *data) + return ret; + } + +-static void vop_plane_add_properties(struct drm_plane *plane, ++static void vop_plane_add_properties(struct drm_plane *plane, int zpos, + const struct vop_win_data *win_data) + { + unsigned int flags = 0; +@@ -1841,6 +1841,8 @@ static void vop_plane_add_properties(struct drm_plane *plane, + if (flags) + drm_plane_create_rotation_property(plane, DRM_MODE_ROTATE_0, + DRM_MODE_ROTATE_0 | flags); ++ ++ drm_plane_create_zpos_immutable_property(plane, zpos); + } + + static int vop_create_crtc(struct vop *vop) +@@ -1872,7 +1874,7 @@ static int vop_create_crtc(struct vop *vop) + + plane = &vop_win->base; + drm_plane_helper_add(plane, &plane_helper_funcs); +- vop_plane_add_properties(plane, win_data); ++ vop_plane_add_properties(plane, i, win_data); + if (plane->type == DRM_PLANE_TYPE_PRIMARY) + primary = plane; + else if (plane->type == DRM_PLANE_TYPE_CURSOR) + +From a54a460f95ac032ae621695a27362b9bec3a3d52 Mon Sep 17 00:00:00 2001 +From: Jonas Karlman +Date: Sat, 10 Oct 2020 09:20:44 +0000 +Subject: [PATCH] drm/rockchip: vop: add plane color properties + +Signed-off-by: Jonas Karlman +--- + drivers/gpu/drm/rockchip/rockchip_drm_vop.c | 32 +++++++++++++++++++-- + 1 file changed, 30 insertions(+), 2 deletions(-) + +diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_vop.c b/drivers/gpu/drm/rockchip/rockchip_drm_vop.c +index 1dd8bf5ff4be..5f89b51ce891 100644 +--- a/drivers/gpu/drm/rockchip/rockchip_drm_vop.c ++++ b/drivers/gpu/drm/rockchip/rockchip_drm_vop.c +@@ -1831,8 +1831,23 @@ static irqreturn_t vop_isr(int irq, void *data) + return ret; + } + ++static bool plane_supports_yuv_format(const struct drm_plane *plane) ++{ ++ const struct drm_format_info *info; ++ int i; ++ ++ for (i = 0; i < plane->format_count; i++) { ++ info = drm_format_info(plane->format_types[i]); ++ if (info->is_yuv) ++ return true; ++ } ++ ++ return false; ++} ++ + static void vop_plane_add_properties(struct drm_plane *plane, int zpos, +- const struct vop_win_data *win_data) ++ const struct vop_win_data *win_data, ++ const struct vop_data *vop_data) + { + unsigned int flags = 0; + +@@ -1843,6 +1858,19 @@ static void vop_plane_add_properties(struct drm_plane *plane, int zpos, + DRM_MODE_ROTATE_0 | flags); + + drm_plane_create_zpos_immutable_property(plane, zpos); ++ ++ if (!plane_supports_yuv_format(plane)) ++ return; ++ ++ flags = BIT(DRM_COLOR_YCBCR_BT601) | BIT(DRM_COLOR_YCBCR_BT709); ++ if (vop_data->feature & VOP_FEATURE_OUTPUT_RGB10) ++ flags |= BIT(DRM_COLOR_YCBCR_BT2020); ++ ++ drm_plane_create_color_properties(plane, flags, ++ BIT(DRM_COLOR_YCBCR_LIMITED_RANGE) | ++ BIT(DRM_COLOR_YCBCR_FULL_RANGE), ++ DRM_COLOR_YCBCR_BT601, ++ DRM_COLOR_YCBCR_LIMITED_RANGE); + } + + static int vop_create_crtc(struct vop *vop) +@@ -1874,7 +1902,7 @@ static int vop_create_crtc(struct vop *vop) + + plane = &vop_win->base; + drm_plane_helper_add(plane, &plane_helper_funcs); +- vop_plane_add_properties(plane, i, win_data); ++ vop_plane_add_properties(plane, i, win_data, vop_data); + if (plane->type == DRM_PLANE_TYPE_PRIMARY) + primary = plane; + else if (plane->type == DRM_PLANE_TYPE_CURSOR) + +From be7e186bbe47bf56f11460ea9f9def9bb922df4e Mon Sep 17 00:00:00 2001 +From: Nickey Yang +Date: Mon, 17 Jul 2017 16:35:34 +0800 +Subject: [PATCH] HACK: clk: rockchip: rk3288: dedicate npll for vopb and hdmi + use + +MINIARM: set npll be used for hdmi only + +Signed-off-by: Nickey Yang +Signed-off-by: Jonas Karlman +--- + arch/arm/boot/dts/rk3288.dtsi | 2 ++ + drivers/clk/rockchip/clk-rk3288.c | 4 ++-- + 2 files changed, 4 insertions(+), 2 deletions(-) + +diff --git a/arch/arm/boot/dts/rk3288.dtsi b/arch/arm/boot/dts/rk3288.dtsi +index 3575dea1ee29..03e86d012edd 100644 +--- a/arch/arm/boot/dts/rk3288.dtsi ++++ b/arch/arm/boot/dts/rk3288.dtsi +@@ -1046,6 +1046,8 @@ vopb: vop@ff930000 { + resets = <&cru SRST_LCDC0_AXI>, <&cru SRST_LCDC0_AHB>, <&cru SRST_LCDC0_DCLK>; + reset-names = "axi", "ahb", "dclk"; + iommus = <&vopb_mmu>; ++ assigned-clocks = <&cru DCLK_VOP0>; ++ assigned-clock-parents = <&cru PLL_NPLL>; + status = "disabled"; + + vopb_out: port { +diff --git a/drivers/clk/rockchip/clk-rk3288.c b/drivers/clk/rockchip/clk-rk3288.c +index 93c794695c46..db6c8bbb35f4 100644 +--- a/drivers/clk/rockchip/clk-rk3288.c ++++ b/drivers/clk/rockchip/clk-rk3288.c +@@ -231,7 +231,7 @@ static struct rockchip_pll_clock rk3288_pll_clks[] __initdata = { + [gpll] = PLL(pll_rk3066, PLL_GPLL, "gpll", mux_pll_p, 0, RK3288_PLL_CON(12), + RK3288_MODE_CON, 12, 8, ROCKCHIP_PLL_SYNC_RATE, rk3288_pll_rates), + [npll] = PLL(pll_rk3066, PLL_NPLL, "npll", mux_pll_p, 0, RK3288_PLL_CON(16), +- RK3288_MODE_CON, 14, 9, ROCKCHIP_PLL_SYNC_RATE, rk3288_pll_rates), ++ RK3288_MODE_CON, 14, 9, 0, rk3288_pll_rates), + }; + + static struct clk_div_table div_hclk_cpu_t[] = { +@@ -441,7 +441,7 @@ static struct rockchip_clk_branch rk3288_clk_branches[] __initdata = { + RK3288_CLKSEL_CON(30), 14, 2, MFLAGS, 8, 5, DFLAGS, + RK3288_CLKGATE_CON(3), 4, GFLAGS), + +- COMPOSITE(DCLK_VOP0, "dclk_vop0", mux_pll_src_cpll_gpll_npll_p, 0, ++ COMPOSITE(DCLK_VOP0, "dclk_vop0", mux_pll_src_cpll_gpll_npll_p, CLK_SET_RATE_NO_REPARENT | CLK_SET_RATE_PARENT, + RK3288_CLKSEL_CON(27), 0, 2, MFLAGS, 8, 8, DFLAGS, + RK3288_CLKGATE_CON(3), 1, GFLAGS), + COMPOSITE(DCLK_VOP1, "dclk_vop1", mux_pll_src_cpll_gpll_npll_p, 0, + +From 0022fe5e0074a3bb71baf175af08ae54a33824a1 Mon Sep 17 00:00:00 2001 +From: Jonas Karlman +Date: Sat, 4 Aug 2018 14:51:14 +0200 +Subject: [PATCH] HACK: clk: rockchip: rk3288: use npll table to to improve + HDMI compatibility + +Based on https://github.com/TinkerBoard/debian_kernel/commit/3d90870530b8a2901681f7b7fa598ee7381e49f3 + +Signed-off-by: Jonas Karlman +--- + drivers/clk/rockchip/clk-rk3288.c | 23 ++++++++++++++++++++++- + 1 file changed, 22 insertions(+), 1 deletion(-) + +diff --git a/drivers/clk/rockchip/clk-rk3288.c b/drivers/clk/rockchip/clk-rk3288.c +index db6c8bbb35f4..426309f5dd44 100644 +--- a/drivers/clk/rockchip/clk-rk3288.c ++++ b/drivers/clk/rockchip/clk-rk3288.c +@@ -121,6 +121,27 @@ static struct rockchip_pll_rate_table rk3288_pll_rates[] = { + { /* sentinel */ }, + }; + ++static struct rockchip_pll_rate_table rk3288_npll_rates[] = { ++ RK3066_PLL_RATE_NB(594000000, 1, 99, 4, 32), ++ RK3066_PLL_RATE_NB(585000000, 6, 585, 4, 32), ++ RK3066_PLL_RATE_NB(432000000, 3, 216, 4, 32), ++ RK3066_PLL_RATE_NB(426000000, 3, 213, 4, 32), ++ RK3066_PLL_RATE_NB(400000000, 1, 100, 6, 32), ++ RK3066_PLL_RATE_NB(342000000, 3, 171, 4, 32), ++ RK3066_PLL_RATE_NB(297000000, 2, 198, 8, 16), ++ RK3066_PLL_RATE_NB(270000000, 1, 135, 12, 32), ++ RK3066_PLL_RATE_NB(260000000, 1, 130, 12, 32), ++ RK3066_PLL_RATE_NB(148500000, 1, 99, 16, 32), ++ RK3066_PLL_RATE(148352000, 13, 1125, 14), ++ RK3066_PLL_RATE_NB(146250000, 6, 585, 16, 32), ++ RK3066_PLL_RATE_NB(108000000, 1, 54, 12, 32), ++ RK3066_PLL_RATE_NB(106500000, 4, 213, 12, 32), ++ RK3066_PLL_RATE_NB(85500000, 4, 171, 12, 32), ++ RK3066_PLL_RATE_NB(74250000, 4, 198, 16, 32), ++ RK3066_PLL_RATE(74176000, 26, 1125, 14), ++ { /* sentinel */ }, ++}; ++ + #define RK3288_DIV_ACLK_CORE_M0_MASK 0xf + #define RK3288_DIV_ACLK_CORE_M0_SHIFT 0 + #define RK3288_DIV_ACLK_CORE_MP_MASK 0xf +@@ -231,7 +252,7 @@ static struct rockchip_pll_clock rk3288_pll_clks[] __initdata = { + [gpll] = PLL(pll_rk3066, PLL_GPLL, "gpll", mux_pll_p, 0, RK3288_PLL_CON(12), + RK3288_MODE_CON, 12, 8, ROCKCHIP_PLL_SYNC_RATE, rk3288_pll_rates), + [npll] = PLL(pll_rk3066, PLL_NPLL, "npll", mux_pll_p, 0, RK3288_PLL_CON(16), +- RK3288_MODE_CON, 14, 9, 0, rk3288_pll_rates), ++ RK3288_MODE_CON, 14, 9, 0, rk3288_npll_rates), + }; + + static struct clk_div_table div_hclk_cpu_t[] = { + +From c2932a004f3bfe0db020bd9e2a6e4967eab48313 Mon Sep 17 00:00:00 2001 +From: Jonas Karlman +Date: Sun, 28 Oct 2018 21:43:01 +0100 +Subject: [PATCH] HACK: clk: rockchip: rk3288: add more npll clocks + +Fixes 2560x1440@60Hz, 1600x1200@60Hz, 1920x1200@60Hz, 1680x1050@60Hz and 1440x900@60Hz modes on my monitor + +Signed-off-by: Jonas Karlman +--- + drivers/clk/rockchip/clk-rk3288.c | 16 ++++++++++++++++ + 1 file changed, 16 insertions(+) + +diff --git a/drivers/clk/rockchip/clk-rk3288.c b/drivers/clk/rockchip/clk-rk3288.c +index 426309f5dd44..b3247a3a7290 100644 +--- a/drivers/clk/rockchip/clk-rk3288.c ++++ b/drivers/clk/rockchip/clk-rk3288.c +@@ -127,18 +127,34 @@ static struct rockchip_pll_rate_table rk3288_npll_rates[] = { + RK3066_PLL_RATE_NB(432000000, 3, 216, 4, 32), + RK3066_PLL_RATE_NB(426000000, 3, 213, 4, 32), + RK3066_PLL_RATE_NB(400000000, 1, 100, 6, 32), ++ RK3066_PLL_RATE(348500000, 8, 697, 6), + RK3066_PLL_RATE_NB(342000000, 3, 171, 4, 32), + RK3066_PLL_RATE_NB(297000000, 2, 198, 8, 16), + RK3066_PLL_RATE_NB(270000000, 1, 135, 12, 32), + RK3066_PLL_RATE_NB(260000000, 1, 130, 12, 32), ++ RK3066_PLL_RATE(241500000, 2, 161, 8), ++ RK3066_PLL_RATE(162000000, 1, 81, 12), ++ RK3066_PLL_RATE(154000000, 6, 539, 14), + RK3066_PLL_RATE_NB(148500000, 1, 99, 16, 32), + RK3066_PLL_RATE(148352000, 13, 1125, 14), + RK3066_PLL_RATE_NB(146250000, 6, 585, 16, 32), ++ RK3066_PLL_RATE(121750000, 6, 487, 16), ++ RK3066_PLL_RATE(119000000, 3, 238, 16), + RK3066_PLL_RATE_NB(108000000, 1, 54, 12, 32), + RK3066_PLL_RATE_NB(106500000, 4, 213, 12, 32), ++ RK3066_PLL_RATE(101000000, 3, 202, 16), ++ RK3066_PLL_RATE(88750000, 6, 355, 16), + RK3066_PLL_RATE_NB(85500000, 4, 171, 12, 32), ++ RK3066_PLL_RATE(83500000, 3, 167, 16), ++ RK3066_PLL_RATE(79500000, 1, 53, 16), + RK3066_PLL_RATE_NB(74250000, 4, 198, 16, 32), + RK3066_PLL_RATE(74176000, 26, 1125, 14), ++ RK3066_PLL_RATE(72000000, 1, 48, 16), ++ RK3066_PLL_RATE(71000000, 3, 142, 16), ++ RK3066_PLL_RATE(68250000, 2, 91, 16), ++ RK3066_PLL_RATE(65000000, 3, 130, 16), ++ RK3066_PLL_RATE(40000000, 3, 80, 16), ++ RK3066_PLL_RATE(33750000, 2, 45, 16), + { /* sentinel */ }, + }; + + +From 53449cc453ac4eebebea84efd6d8694eed1d0365 Mon Sep 17 00:00:00 2001 +From: Jonas Karlman +Date: Mon, 25 May 2020 20:36:45 +0000 +Subject: [PATCH] HACK: clk: rockchip: rk3399: dedicate vpll for vopb and hdmi + use + +Signed-off-by: Jonas Karlman +--- + drivers/clk/rockchip/clk-rk3399.c | 32 +++++++++++++++++++++++++------ + 1 file changed, 26 insertions(+), 6 deletions(-) + +diff --git a/drivers/clk/rockchip/clk-rk3399.c b/drivers/clk/rockchip/clk-rk3399.c +index 7df2f1e00347..d39d9ea39aca 100644 +--- a/drivers/clk/rockchip/clk-rk3399.c ++++ b/drivers/clk/rockchip/clk-rk3399.c +@@ -105,6 +105,25 @@ static struct rockchip_pll_rate_table rk3399_pll_rates[] = { + { /* sentinel */ }, + }; + ++static struct rockchip_pll_rate_table rk3399_vpll_rates[] = { ++ /* _mhz, _refdiv, _fbdiv, _postdiv1, _postdiv2, _dsmpd, _frac */ ++ RK3036_PLL_RATE( 594000000, 1, 123, 5, 1, 0, 12582912), /* vco = 2970000000 */ ++ RK3036_PLL_RATE( 593406592, 1, 123, 5, 1, 0, 10508804), /* vco = 2967032965 */ ++ RK3036_PLL_RATE( 297000000, 1, 123, 5, 2, 0, 12582912), /* vco = 2970000000 */ ++ RK3036_PLL_RATE( 296703296, 1, 123, 5, 2, 0, 10508807), /* vco = 2967032970 */ ++ RK3036_PLL_RATE( 148500000, 1, 129, 7, 3, 0, 15728640), /* vco = 3118500000 */ ++ RK3036_PLL_RATE( 148351648, 1, 123, 5, 4, 0, 10508800), /* vco = 2967032960 */ ++ RK3036_PLL_RATE( 106500000, 1, 124, 7, 4, 0, 4194304), /* vco = 2982000000 */ ++ RK3036_PLL_RATE( 74250000, 1, 129, 7, 6, 0, 15728640), /* vco = 3118500000 */ ++ RK3036_PLL_RATE( 74175824, 1, 129, 7, 6, 0, 13550823), /* vco = 3115384608 */ ++ RK3036_PLL_RATE( 65000000, 1, 113, 7, 6, 0, 12582912), /* vco = 2730000000 */ ++ RK3036_PLL_RATE( 59340659, 1, 121, 7, 7, 0, 2581098), /* vco = 2907692291 */ ++ RK3036_PLL_RATE( 54000000, 1, 110, 7, 7, 0, 4194304), /* vco = 2646000000 */ ++ RK3036_PLL_RATE( 27000000, 1, 55, 7, 7, 0, 2097152), /* vco = 1323000000 */ ++ RK3036_PLL_RATE( 26973026, 1, 55, 7, 7, 0, 1173232), /* vco = 1321678323 */ ++ { /* sentinel */ }, ++}; ++ + /* CRU parents */ + PNAME(mux_pll_p) = { "xin24m", "xin32k" }; + +@@ -123,7 +142,7 @@ PNAME(mux_ddrclk_p) = { "clk_ddrc_lpll_src", + PNAME(mux_aclk_cci_p) = { "cpll_aclk_cci_src", + "gpll_aclk_cci_src", + "npll_aclk_cci_src", +- "vpll_aclk_cci_src" }; ++ "prevent:vpll" }; + PNAME(mux_cci_trace_p) = { "cpll_cci_trace", + "gpll_cci_trace" }; + PNAME(mux_cs_p) = { "cpll_cs", "gpll_cs", +@@ -150,9 +169,10 @@ PNAME(mux_pll_src_cpll_gpll_npll_ppll_upll_24m_p) = { "cpll", "gpll", "npll", + "ppll", "upll", "xin24m" }; + + PNAME(mux_pll_src_vpll_cpll_gpll_p) = { "vpll", "cpll", "gpll" }; +-PNAME(mux_pll_src_vpll_cpll_gpll_npll_p) = { "vpll", "cpll", "gpll", ++ ++PNAME(mux_pll_src_vpll_cpll_gpll_npll_p) = { "prevent:vpll", "cpll", "gpll", + "npll" }; +-PNAME(mux_pll_src_vpll_cpll_gpll_24m_p) = { "vpll", "cpll", "gpll", ++PNAME(mux_pll_src_vpll_cpll_gpll_24m_p) = { "prevent:vpll", "cpll", "gpll", + "xin24m" }; + + PNAME(mux_dclk_vop0_p) = { "dclk_vop0_div", +@@ -229,7 +249,7 @@ static struct rockchip_pll_clock rk3399_pll_clks[] __initdata = { + [npll] = PLL(pll_rk3399, PLL_NPLL, "npll", mux_pll_p, 0, RK3399_PLL_CON(40), + RK3399_PLL_CON(43), 8, 31, ROCKCHIP_PLL_SYNC_RATE, rk3399_pll_rates), + [vpll] = PLL(pll_rk3399, PLL_VPLL, "vpll", mux_pll_p, 0, RK3399_PLL_CON(48), +- RK3399_PLL_CON(51), 8, 31, ROCKCHIP_PLL_SYNC_RATE, rk3399_pll_rates), ++ RK3399_PLL_CON(51), 8, 31, ROCKCHIP_PLL_SYNC_RATE, rk3399_vpll_rates), + }; + + static struct rockchip_pll_clock rk3399_pmu_pll_clks[] __initdata = { +@@ -279,7 +299,7 @@ static struct rockchip_clk_branch rk3399_uart4_pmu_fracmux __initdata = + RK3399_PMU_CLKSEL_CON(5), 8, 2, MFLAGS); + + static struct rockchip_clk_branch rk3399_dclk_vop0_fracmux __initdata = +- MUX(DCLK_VOP0, "dclk_vop0", mux_dclk_vop0_p, CLK_SET_RATE_PARENT, ++ MUX(DCLK_VOP0, "dclk_vop0", mux_dclk_vop0_p, CLK_SET_RATE_PARENT | CLK_SET_RATE_NO_REPARENT, + RK3399_CLKSEL_CON(49), 11, 1, MFLAGS); + + static struct rockchip_clk_branch rk3399_dclk_vop1_fracmux __initdata = +@@ -1160,7 +1180,7 @@ static struct rockchip_clk_branch rk3399_clk_branches[] __initdata = { + GATE(HCLK_VOP0_NOC, "hclk_vop0_noc", "hclk_vop0_pre", CLK_IGNORE_UNUSED, + RK3399_CLKGATE_CON(28), 0, GFLAGS), + +- COMPOSITE(DCLK_VOP0_DIV, "dclk_vop0_div", mux_pll_src_vpll_cpll_gpll_p, 0, ++ COMPOSITE(DCLK_VOP0_DIV, "dclk_vop0_div", mux_pll_src_vpll_cpll_gpll_p, CLK_SET_RATE_PARENT | CLK_SET_RATE_NO_REPARENT, + RK3399_CLKSEL_CON(49), 8, 2, MFLAGS, 0, 8, DFLAGS, + RK3399_CLKGATE_CON(10), 12, GFLAGS), + + +From 93cfe23ab3faabc6905900be57ffecf0644711c3 Mon Sep 17 00:00:00 2001 +From: Jonas Karlman +Date: Sun, 19 Jul 2020 16:35:11 +0000 +Subject: [PATCH] HACK: dts: rockchip: do not use vopl for hdmi + +--- + arch/arm/boot/dts/rk3288.dtsi | 9 --------- + arch/arm64/boot/dts/rockchip/rk3399.dtsi | 9 --------- + 2 files changed, 18 deletions(-) + +diff --git a/arch/arm/boot/dts/rk3288.dtsi b/arch/arm/boot/dts/rk3288.dtsi +index 03e86d012edd..746acfac1e92 100644 +--- a/arch/arm/boot/dts/rk3288.dtsi ++++ b/arch/arm/boot/dts/rk3288.dtsi +@@ -1104,11 +1104,6 @@ vopl_out: port { + #address-cells = <1>; + #size-cells = <0>; + +- vopl_out_hdmi: endpoint@0 { +- reg = <0>; +- remote-endpoint = <&hdmi_in_vopl>; +- }; +- + vopl_out_edp: endpoint@1 { + reg = <1>; + remote-endpoint = <&edp_in_vopl>; +@@ -1249,10 +1244,6 @@ hdmi_in_vopb: endpoint@0 { + reg = <0>; + remote-endpoint = <&vopb_out_hdmi>; + }; +- hdmi_in_vopl: endpoint@1 { +- reg = <1>; +- remote-endpoint = <&vopl_out_hdmi>; +- }; + }; + }; + }; +diff --git a/arch/arm64/boot/dts/rockchip/rk3399.dtsi b/arch/arm64/boot/dts/rockchip/rk3399.dtsi +index a855805649ef..418d16b0b648 100644 +--- a/arch/arm64/boot/dts/rockchip/rk3399.dtsi ++++ b/arch/arm64/boot/dts/rockchip/rk3399.dtsi +@@ -1640,11 +1640,6 @@ vopl_out_edp: endpoint@1 { + remote-endpoint = <&edp_in_vopl>; + }; + +- vopl_out_hdmi: endpoint@2 { +- reg = <2>; +- remote-endpoint = <&hdmi_in_vopl>; +- }; +- + vopl_out_mipi1: endpoint@3 { + reg = <3>; + remote-endpoint = <&mipi1_in_vopl>; +@@ -1816,10 +1811,6 @@ hdmi_in_vopb: endpoint@0 { + reg = <0>; + remote-endpoint = <&vopb_out_hdmi>; + }; +- hdmi_in_vopl: endpoint@1 { +- reg = <1>; +- remote-endpoint = <&vopl_out_hdmi>; +- }; + }; + }; + }; + +From 7f4418d9c9b277966153bd88bf8543cc750ba5e2 Mon Sep 17 00:00:00 2001 +From: Jonas Karlman +Date: Fri, 20 Dec 2019 08:12:43 +0000 +Subject: [PATCH] WIP: drm/bridge: dw-hdmi: limit mode and bus format to + max_tmds_clock + +--- + drivers/gpu/drm/bridge/synopsys/dw-hdmi.c | 120 ++++++++++++++-------- + 1 file changed, 76 insertions(+), 44 deletions(-) + +diff --git a/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c b/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c +index 6d319b95b992..c2425d7fc465 100644 +--- a/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c ++++ b/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c +@@ -1859,6 +1859,21 @@ static void hdmi_config_drm_infoframe(struct dw_hdmi *hdmi, + HDMI_FC_PACKET_TX_EN_DRM_MASK, HDMI_FC_PACKET_TX_EN); + } + ++static unsigned int ++hdmi_get_tmdsclock(unsigned int bus_format, unsigned int pixelclock) ++{ ++ int color_depth = hdmi_bus_fmt_color_depth(bus_format); ++ unsigned int tmdsclock = pixelclock; ++ ++ if (!hdmi_bus_fmt_is_yuv422(bus_format) && color_depth > 8) ++ tmdsclock = (u64)pixelclock * color_depth / 8; ++ ++ if (hdmi_bus_fmt_is_yuv420(bus_format)) ++ tmdsclock /= 2; ++ ++ return tmdsclock; ++} ++ + static void hdmi_av_composer(struct dw_hdmi *hdmi, + const struct drm_display_info *display, + const struct drm_display_mode *mode) +@@ -1870,29 +1885,11 @@ static void hdmi_av_composer(struct dw_hdmi *hdmi, + unsigned int vdisplay, hdisplay; + + vmode->mpixelclock = mode->clock * 1000; ++ vmode->mtmdsclock = ++ hdmi_get_tmdsclock(hdmi->hdmi_data.enc_out_bus_format, ++ vmode->mpixelclock); + + dev_dbg(hdmi->dev, "final pixclk = %d\n", vmode->mpixelclock); +- +- vmode->mtmdsclock = vmode->mpixelclock; +- +- if (!hdmi_bus_fmt_is_yuv422(hdmi->hdmi_data.enc_out_bus_format)) { +- switch (hdmi_bus_fmt_color_depth( +- hdmi->hdmi_data.enc_out_bus_format)) { +- case 16: +- vmode->mtmdsclock = vmode->mpixelclock * 2; +- break; +- case 12: +- vmode->mtmdsclock = vmode->mpixelclock * 3 / 2; +- break; +- case 10: +- vmode->mtmdsclock = vmode->mpixelclock * 5 / 4; +- break; +- } +- } +- +- if (hdmi_bus_fmt_is_yuv420(hdmi->hdmi_data.enc_out_bus_format)) +- vmode->mtmdsclock /= 2; +- + dev_dbg(hdmi->dev, "final tmdsclock = %d\n", vmode->mtmdsclock); + + /* Set up HDMI_FC_INVIDCONF */ +@@ -2544,8 +2541,21 @@ static int dw_hdmi_connector_create(struct dw_hdmi *hdmi) + * - MEDIA_BUS_FMT_RGB888_1X24, + */ + +-/* Can return a maximum of 11 possible output formats for a mode/connector */ +-#define MAX_OUTPUT_SEL_FORMATS 11 ++/* Can return a maximum of 15 possible output formats for a mode/connector */ ++#define MAX_OUTPUT_SEL_FORMATS 15 ++ ++static bool is_tmds_allowed(struct drm_display_info *info, ++ struct drm_display_mode *mode, ++ u32 bus_format) ++{ ++ unsigned long tmdsclock = hdmi_get_tmdsclock(bus_format, mode->clock); ++ int max_tmds_clock = info->max_tmds_clock ? info->max_tmds_clock : 340000; ++ ++ if (max_tmds_clock >= tmdsclock) ++ return true; ++ ++ return false; ++} + + static u32 *dw_hdmi_bridge_atomic_get_output_bus_fmts(struct drm_bridge *bridge, + struct drm_bridge_state *bridge_state, +@@ -2557,8 +2567,6 @@ static u32 *dw_hdmi_bridge_atomic_get_output_bus_fmts(struct drm_bridge *bridge, + struct drm_display_info *info = &conn->display_info; + struct drm_display_mode *mode = &crtc_state->mode; + u8 max_bpc = conn_state->max_requested_bpc; +- bool is_hdmi2_sink = info->hdmi.scdc.supported || +- (info->color_formats & DRM_COLOR_FORMAT_YCRCB420); + u32 *output_fmts; + unsigned int i = 0; + +@@ -2581,29 +2589,33 @@ static u32 *dw_hdmi_bridge_atomic_get_output_bus_fmts(struct drm_bridge *bridge, + * If the current mode enforces 4:2:0, force the output but format + * to 4:2:0 and do not add the YUV422/444/RGB formats + */ +- if (conn->ycbcr_420_allowed && +- (drm_mode_is_420_only(info, mode) || +- (is_hdmi2_sink && drm_mode_is_420_also(info, mode)))) { ++ if (conn->ycbcr_420_allowed && drm_mode_is_420(info, mode) && ++ (info->color_formats & DRM_COLOR_FORMAT_YCRCB420)) { + + /* Order bus formats from 16bit to 8bit if supported */ + if (max_bpc >= 16 && info->bpc == 16 && +- (info->hdmi.y420_dc_modes & DRM_EDID_YCBCR420_DC_48)) ++ (info->hdmi.y420_dc_modes & DRM_EDID_YCBCR420_DC_48) && ++ is_tmds_allowed(info, mode, MEDIA_BUS_FMT_UYYVYY16_0_5X48)) + output_fmts[i++] = MEDIA_BUS_FMT_UYYVYY16_0_5X48; + + if (max_bpc >= 12 && info->bpc >= 12 && +- (info->hdmi.y420_dc_modes & DRM_EDID_YCBCR420_DC_36)) ++ (info->hdmi.y420_dc_modes & DRM_EDID_YCBCR420_DC_36) && ++ is_tmds_allowed(info, mode, MEDIA_BUS_FMT_UYYVYY12_0_5X36)) + output_fmts[i++] = MEDIA_BUS_FMT_UYYVYY12_0_5X36; + + if (max_bpc >= 10 && info->bpc >= 10 && +- (info->hdmi.y420_dc_modes & DRM_EDID_YCBCR420_DC_30)) ++ (info->hdmi.y420_dc_modes & DRM_EDID_YCBCR420_DC_30) && ++ is_tmds_allowed(info, mode, MEDIA_BUS_FMT_UYYVYY10_0_5X30)) + output_fmts[i++] = MEDIA_BUS_FMT_UYYVYY10_0_5X30; + + /* Default 8bit fallback */ +- output_fmts[i++] = MEDIA_BUS_FMT_UYYVYY8_0_5X24; ++ if (is_tmds_allowed(info, mode, MEDIA_BUS_FMT_UYYVYY8_0_5X24)) ++ output_fmts[i++] = MEDIA_BUS_FMT_UYYVYY8_0_5X24; + + *num_output_fmts = i; + +- return output_fmts; ++ if (drm_mode_is_420_only(info, mode)) ++ return output_fmts; + } + + /* +@@ -2612,40 +2624,51 @@ static u32 *dw_hdmi_bridge_atomic_get_output_bus_fmts(struct drm_bridge *bridge, + */ + + if (max_bpc >= 16 && info->bpc == 16) { +- if (info->color_formats & DRM_COLOR_FORMAT_YCRCB444) ++ if ((info->color_formats & DRM_COLOR_FORMAT_YCRCB444) && ++ is_tmds_allowed(info, mode, MEDIA_BUS_FMT_YUV16_1X48)) + output_fmts[i++] = MEDIA_BUS_FMT_YUV16_1X48; + +- output_fmts[i++] = MEDIA_BUS_FMT_RGB161616_1X48; ++ if (is_tmds_allowed(info, mode, MEDIA_BUS_FMT_RGB161616_1X48)) ++ output_fmts[i++] = MEDIA_BUS_FMT_RGB161616_1X48; + } + + if (max_bpc >= 12 && info->bpc >= 12) { +- if (info->color_formats & DRM_COLOR_FORMAT_YCRCB422) ++ if ((info->color_formats & DRM_COLOR_FORMAT_YCRCB422) && ++ is_tmds_allowed(info, mode, MEDIA_BUS_FMT_UYVY12_1X24)) + output_fmts[i++] = MEDIA_BUS_FMT_UYVY12_1X24; + +- if (info->color_formats & DRM_COLOR_FORMAT_YCRCB444) ++ if ((info->color_formats & DRM_COLOR_FORMAT_YCRCB444) && ++ is_tmds_allowed(info, mode, MEDIA_BUS_FMT_YUV12_1X36)) + output_fmts[i++] = MEDIA_BUS_FMT_YUV12_1X36; + +- output_fmts[i++] = MEDIA_BUS_FMT_RGB121212_1X36; ++ if (is_tmds_allowed(info, mode, MEDIA_BUS_FMT_RGB121212_1X36)) ++ output_fmts[i++] = MEDIA_BUS_FMT_RGB121212_1X36; + } + + if (max_bpc >= 10 && info->bpc >= 10) { +- if (info->color_formats & DRM_COLOR_FORMAT_YCRCB422) ++ if ((info->color_formats & DRM_COLOR_FORMAT_YCRCB422) && ++ is_tmds_allowed(info, mode, MEDIA_BUS_FMT_UYVY10_1X20)) + output_fmts[i++] = MEDIA_BUS_FMT_UYVY10_1X20; + +- if (info->color_formats & DRM_COLOR_FORMAT_YCRCB444) ++ if ((info->color_formats & DRM_COLOR_FORMAT_YCRCB444) && ++ is_tmds_allowed(info, mode, MEDIA_BUS_FMT_YUV10_1X30)) + output_fmts[i++] = MEDIA_BUS_FMT_YUV10_1X30; + +- output_fmts[i++] = MEDIA_BUS_FMT_RGB101010_1X30; ++ if (is_tmds_allowed(info, mode, MEDIA_BUS_FMT_RGB101010_1X30)) ++ output_fmts[i++] = MEDIA_BUS_FMT_RGB101010_1X30; + } + +- if (info->color_formats & DRM_COLOR_FORMAT_YCRCB422) ++ if ((info->color_formats & DRM_COLOR_FORMAT_YCRCB422) && ++ is_tmds_allowed(info, mode, MEDIA_BUS_FMT_UYVY8_1X16)) + output_fmts[i++] = MEDIA_BUS_FMT_UYVY8_1X16; + +- if (info->color_formats & DRM_COLOR_FORMAT_YCRCB444) ++ if ((info->color_formats & DRM_COLOR_FORMAT_YCRCB444) && ++ is_tmds_allowed(info, mode, MEDIA_BUS_FMT_YUV8_1X24)) + output_fmts[i++] = MEDIA_BUS_FMT_YUV8_1X24; + + /* Default 8bit RGB fallback */ +- output_fmts[i++] = MEDIA_BUS_FMT_RGB888_1X24; ++ if (is_tmds_allowed(info, mode, MEDIA_BUS_FMT_RGB888_1X24)) ++ output_fmts[i++] = MEDIA_BUS_FMT_RGB888_1X24; + + *num_output_fmts = i; + +@@ -2825,11 +2848,20 @@ dw_hdmi_bridge_mode_valid(struct drm_bridge *bridge, + struct dw_hdmi *hdmi = bridge->driver_private; + const struct dw_hdmi_plat_data *pdata = hdmi->plat_data; + enum drm_mode_status mode_status = MODE_OK; ++ int max_tmds_clock = info->max_tmds_clock ? info->max_tmds_clock : 340000; ++ int clock = mode->clock; + + /* We don't support double-clocked modes */ + if (mode->flags & DRM_MODE_FLAG_DBLCLK) + return MODE_BAD; + ++ if (pdata->ycbcr_420_allowed && drm_mode_is_420(info, mode) && ++ (info->color_formats & DRM_COLOR_FORMAT_YCRCB420)) ++ clock /= 2; ++ ++ if (clock > max_tmds_clock) ++ return MODE_CLOCK_HIGH; ++ + if (pdata->mode_valid) + mode_status = pdata->mode_valid(hdmi, pdata->priv_data, info, + mode); + +From 6bd50413f8df7ff8f30dbf94489624ffe8e53fdd Mon Sep 17 00:00:00 2001 +From: Jonas Karlman +Date: Fri, 20 Dec 2019 08:12:42 +0000 +Subject: [PATCH] WIP: drm/rockchip: dw_hdmi: add 10-bit rgb bus format + +--- + drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c | 41 +++++++++++++++++++++ + drivers/gpu/drm/rockchip/rockchip_drm_drv.h | 2 + + 2 files changed, 43 insertions(+) + +diff --git a/drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c b/drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c +index 510ae5d5f133..43ad0278fad1 100644 +--- a/drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c ++++ b/drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c +@@ -77,6 +77,7 @@ struct rockchip_hdmi { + }; + + #define to_rockchip_hdmi(x) container_of(x, struct rockchip_hdmi, x) ++#define to_crtc_state(x) container_of(x, struct drm_crtc_state, x) + + static const struct dw_hdmi_mpll_config rockchip_mpll_cfg[] = { + { +@@ -322,6 +323,11 @@ dw_hdmi_rockchip_bridge_mode_set(struct drm_bridge *bridge, + const struct drm_display_mode *adjusted_mode) + { + struct rockchip_hdmi *hdmi = to_rockchip_hdmi(bridge); ++ struct drm_crtc_state *crtc_state = to_crtc_state(adjusted_mode); ++ struct rockchip_crtc_state *s = to_rockchip_crtc_state(crtc_state); ++ ++ if (hdmi->phy) ++ phy_set_bus_width(hdmi->phy, s->bus_width); + + clk_set_rate(hdmi->vpll_clk, adjusted_mode->clock * 1000); + } +@@ -360,6 +366,7 @@ static void dw_hdmi_rockchip_bridge_enable(struct drm_bridge *bridge) + static bool is_rgb(u32 format) + { + switch (format) { ++ case MEDIA_BUS_FMT_RGB101010_1X30: + case MEDIA_BUS_FMT_RGB888_1X24: + return true; + default: +@@ -367,6 +374,16 @@ static bool is_rgb(u32 format) + } + } + ++static bool is_10bit(u32 format) ++{ ++ switch (format) { ++ case MEDIA_BUS_FMT_RGB101010_1X30: ++ return true; ++ default: ++ return false; ++ } ++} ++ + static int + dw_hdmi_rockchip_bridge_atomic_check(struct drm_bridge *bridge, + struct drm_bridge_state *bridge_state, +@@ -374,9 +391,24 @@ dw_hdmi_rockchip_bridge_atomic_check(struct drm_bridge *bridge, + struct drm_connector_state *conn_state) + { + struct rockchip_crtc_state *s = to_rockchip_crtc_state(crtc_state); ++ struct drm_atomic_state *state = bridge_state->base.state; ++ struct drm_crtc_state *old_crtc_state; ++ struct rockchip_crtc_state *old_state; ++ u32 format = bridge_state->output_bus_cfg.format; + + s->output_mode = ROCKCHIP_OUT_MODE_AAAA; + s->output_type = DRM_MODE_CONNECTOR_HDMIA; ++ s->output_bpc = 10; ++ s->bus_format = format; ++ s->bus_width = is_10bit(format) ? 10 : 8; ++ ++ old_crtc_state = drm_atomic_get_old_crtc_state(state, conn_state->crtc); ++ if (old_crtc_state && !crtc_state->mode_changed) { ++ old_state = to_rockchip_crtc_state(old_crtc_state); ++ if (s->bus_format != old_state->bus_format || ++ s->bus_width != old_state->bus_width) ++ crtc_state->mode_changed = true; ++ } + + return 0; + } +@@ -388,10 +420,19 @@ static u32 *dw_hdmi_rockchip_get_input_bus_fmts(struct drm_bridge *bridge, + u32 output_fmt, + unsigned int *num_input_fmts) + { ++ struct rockchip_hdmi *hdmi = to_rockchip_hdmi(bridge); ++ struct drm_encoder *encoder = bridge->encoder; + u32 *input_fmt; ++ bool has_10bit = true; + + *num_input_fmts = 0; + ++ if (drm_of_encoder_active_endpoint_id(hdmi->dev->of_node, encoder)) ++ has_10bit = false; ++ ++ if (!has_10bit && is_10bit(output_fmt)) ++ return NULL; ++ + if (!is_rgb(output_fmt)) + return NULL; + +diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_drv.h b/drivers/gpu/drm/rockchip/rockchip_drm_drv.h +index e33c2dcd0d4b..03944e08b6c7 100644 +--- a/drivers/gpu/drm/rockchip/rockchip_drm_drv.h ++++ b/drivers/gpu/drm/rockchip/rockchip_drm_drv.h +@@ -31,6 +31,8 @@ struct rockchip_crtc_state { + int output_bpc; + int output_flags; + bool enable_afbc; ++ u32 bus_format; ++ int bus_width; + }; + #define to_rockchip_crtc_state(s) \ + container_of(s, struct rockchip_crtc_state, base) + +From a6b6713b53e019176f2c1c7c4140f0d498066f25 Mon Sep 17 00:00:00 2001 +From: Jonas Karlman +Date: Sun, 8 Dec 2019 23:42:44 +0000 +Subject: [PATCH] WIP: drm: dw-hdmi: add content type connector property + +Signed-off-by: Jonas Karlman +--- + drivers/gpu/drm/bridge/synopsys/dw-hdmi.c | 8 +++++++- + 1 file changed, 7 insertions(+), 1 deletion(-) + +diff --git a/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c b/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c +index c2425d7fc465..f86b8fa40ab6 100644 +--- a/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c ++++ b/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c +@@ -1646,6 +1646,7 @@ static void hdmi_config_AVI(struct dw_hdmi *hdmi, + const struct drm_connector *connector, + const struct drm_display_mode *mode) + { ++ const struct drm_connector_state *conn_state = connector->state; + struct hdmi_avi_infoframe frame; + u8 val; + +@@ -1703,6 +1704,8 @@ static void hdmi_config_AVI(struct dw_hdmi *hdmi, + HDMI_EXTENDED_COLORIMETRY_XV_YCC_601; + } + ++ drm_hdmi_avi_infoframe_content_type(&frame, conn_state); ++ + /* + * The Designware IP uses a different byte format from standard + * AVI info frames, though generally the bits are in the correct +@@ -2431,7 +2434,8 @@ static int dw_hdmi_connector_atomic_check(struct drm_connector *connector, + if (!crtc) + return 0; + +- if (!hdr_metadata_equal(old_state, new_state)) { ++ if (!hdr_metadata_equal(old_state, new_state) || ++ old_state->content_type != new_state->content_type) { + crtc_state = drm_atomic_get_crtc_state(state, crtc); + if (IS_ERR(crtc_state)) + return PTR_ERR(crtc_state); +@@ -2499,6 +2503,8 @@ static int dw_hdmi_connector_create(struct dw_hdmi *hdmi) + + drm_connector_attach_max_bpc_property(connector, 8, 16); + ++ drm_connector_attach_content_type_property(connector); ++ + if (hdmi->version >= 0x200a && hdmi->plat_data->use_drm_infoframe) + drm_object_attach_property(&connector->base, + connector->dev->mode_config.hdr_output_metadata_property, 0); + +From 97e0c955f0b11f528a3369324bdb74c656989784 Mon Sep 17 00:00:00 2001 +From: Jonas Karlman +Date: Fri, 20 Dec 2019 08:12:43 +0000 +Subject: [PATCH] WIP: drm/rockchip: add yuv444 support + +--- + drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c | 29 ++++++++++++++++++++- + drivers/gpu/drm/rockchip/rockchip_drm_vop.c | 29 +++++++++++++++++++++ + drivers/gpu/drm/rockchip/rockchip_drm_vop.h | 6 +++++ + drivers/gpu/drm/rockchip/rockchip_vop_reg.c | 14 ++++++++++ + 4 files changed, 77 insertions(+), 1 deletion(-) + +diff --git a/drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c b/drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c +index 43ad0278fad1..c8eaeb484672 100644 +--- a/drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c ++++ b/drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c +@@ -62,6 +62,7 @@ struct rockchip_hdmi_chip_data { + int lcdsel_grf_reg; + u32 lcdsel_big; + u32 lcdsel_lit; ++ bool ycbcr_444_allowed; + }; + + struct rockchip_hdmi { +@@ -374,10 +375,22 @@ static bool is_rgb(u32 format) + } + } + ++static bool is_yuv444(u32 format) ++{ ++ switch (format) { ++ case MEDIA_BUS_FMT_YUV10_1X30: ++ case MEDIA_BUS_FMT_YUV8_1X24: ++ return true; ++ default: ++ return false; ++ } ++} ++ + static bool is_10bit(u32 format) + { + switch (format) { + case MEDIA_BUS_FMT_RGB101010_1X30: ++ case MEDIA_BUS_FMT_YUV10_1X30: + return true; + default: + return false; +@@ -394,12 +407,22 @@ dw_hdmi_rockchip_bridge_atomic_check(struct drm_bridge *bridge, + struct drm_atomic_state *state = bridge_state->base.state; + struct drm_crtc_state *old_crtc_state; + struct rockchip_crtc_state *old_state; ++ struct drm_bridge *next_bridge; ++ struct drm_bridge_state *next_bridge_state; + u32 format = bridge_state->output_bus_cfg.format; + + s->output_mode = ROCKCHIP_OUT_MODE_AAAA; + s->output_type = DRM_MODE_CONNECTOR_HDMIA; + s->output_bpc = 10; + s->bus_format = format; ++ ++ next_bridge = drm_bridge_get_next_bridge(bridge); ++ if (next_bridge) { ++ next_bridge_state = drm_atomic_get_new_bridge_state(state, ++ next_bridge); ++ format = next_bridge_state->output_bus_cfg.format; ++ } ++ + s->bus_width = is_10bit(format) ? 10 : 8; + + old_crtc_state = drm_atomic_get_old_crtc_state(state, conn_state->crtc); +@@ -433,7 +456,10 @@ static u32 *dw_hdmi_rockchip_get_input_bus_fmts(struct drm_bridge *bridge, + if (!has_10bit && is_10bit(output_fmt)) + return NULL; + +- if (!is_rgb(output_fmt)) ++ if (is_yuv444(output_fmt)) { ++ if (!hdmi->chip_data->ycbcr_444_allowed) ++ return NULL; ++ } else if (!is_rgb(output_fmt)) + return NULL; + + input_fmt = kzalloc(sizeof(*input_fmt), GFP_KERNEL); +@@ -583,6 +609,7 @@ static const struct dw_hdmi_phy_ops rk3328_hdmi_phy_ops = { + + static struct rockchip_hdmi_chip_data rk3328_chip_data = { + .lcdsel_grf_reg = -1, ++ .ycbcr_444_allowed = true, + }; + + static const struct dw_hdmi_plat_data rk3328_hdmi_drv_data = { +diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_vop.c b/drivers/gpu/drm/rockchip/rockchip_drm_vop.c +index 5f89b51ce891..409734c4425b 100644 +--- a/drivers/gpu/drm/rockchip/rockchip_drm_vop.c ++++ b/drivers/gpu/drm/rockchip/rockchip_drm_vop.c +@@ -325,6 +325,17 @@ static int vop_convert_afbc_format(uint32_t format) + return -EINVAL; + } + ++static bool is_yuv_output(uint32_t bus_format) ++{ ++ switch (bus_format) { ++ case MEDIA_BUS_FMT_YUV8_1X24: ++ case MEDIA_BUS_FMT_YUV10_1X30: ++ return true; ++ default: ++ return false; ++ } ++} ++ + static uint16_t scl_vop_cal_scale(enum scale_mode mode, uint32_t src, + uint32_t dst, bool is_horizontal, + int vsu_mode, int *vskiplines) +@@ -1375,6 +1386,7 @@ static void vop_crtc_atomic_enable(struct drm_crtc *crtc, + u16 vact_end = vact_st + vdisplay; + uint32_t pin_pol, val; + int dither_bpc = s->output_bpc ? s->output_bpc : 10; ++ bool yuv_output = is_yuv_output(s->bus_format); + int ret; + + if (old_state && old_state->self_refresh_active) { +@@ -1448,6 +1460,8 @@ static void vop_crtc_atomic_enable(struct drm_crtc *crtc, + !(vop_data->feature & VOP_FEATURE_OUTPUT_RGB10)) + s->output_mode = ROCKCHIP_OUT_MODE_P888; + ++ VOP_REG_SET(vop, common, dsp_data_swap, yuv_output ? 2 : 0); ++ + if (s->output_mode == ROCKCHIP_OUT_MODE_AAAA && dither_bpc <= 8) + VOP_REG_SET(vop, common, pre_dither_down, 1); + else +@@ -1463,6 +1477,21 @@ static void vop_crtc_atomic_enable(struct drm_crtc *crtc, + + VOP_REG_SET(vop, common, out_mode, s->output_mode); + ++ VOP_REG_SET(vop, common, overlay_mode, yuv_output); ++ VOP_REG_SET(vop, common, dsp_out_yuv, yuv_output); ++ ++ /* ++ * Background color is 10bit depth if vop version >= 3.5 ++ */ ++ if (!yuv_output) ++ val = 0; ++ else if (VOP_MAJOR(vop_data->version) == 3 && ++ VOP_MINOR(vop_data->version) >= 5) ++ val = 0x20010200; ++ else ++ val = 0x801080; ++ VOP_REG_SET(vop, common, dsp_background, val); ++ + VOP_REG_SET(vop, modeset, htotal_pw, (htotal << 16) | hsync_len); + val = hact_st << 16; + val |= hact_end; +diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_vop.h b/drivers/gpu/drm/rockchip/rockchip_drm_vop.h +index 1b0618147a0e..896b441e4a63 100644 +--- a/drivers/gpu/drm/rockchip/rockchip_drm_vop.h ++++ b/drivers/gpu/drm/rockchip/rockchip_drm_vop.h +@@ -92,10 +92,16 @@ struct vop_common { + struct vop_reg mmu_en; + struct vop_reg out_mode; + struct vop_reg standby; ++ ++ struct vop_reg overlay_mode; ++ struct vop_reg dsp_data_swap; ++ struct vop_reg dsp_out_yuv; ++ struct vop_reg dsp_background; + }; + + struct vop_misc { + struct vop_reg global_regdone_en; ++ struct vop_reg win_channel[4]; + }; + + struct vop_intr { +diff --git a/drivers/gpu/drm/rockchip/rockchip_vop_reg.c b/drivers/gpu/drm/rockchip/rockchip_vop_reg.c +index 05ade8ea962f..f276ef4b3f64 100644 +--- a/drivers/gpu/drm/rockchip/rockchip_vop_reg.c ++++ b/drivers/gpu/drm/rockchip/rockchip_vop_reg.c +@@ -662,6 +662,11 @@ static const struct vop_common rk3288_common = { + .dsp_blank = VOP_REG(RK3288_DSP_CTRL0, 0x3, 18), + .out_mode = VOP_REG(RK3288_DSP_CTRL0, 0xf, 0), + .cfg_done = VOP_REG_SYNC(RK3288_REG_CFG_DONE, 0x1, 0), ++ ++ .overlay_mode = VOP_REG(RK3288_SYS_CTRL, 0x1, 16), ++ .dsp_data_swap = VOP_REG(RK3288_DSP_CTRL0, 0x1f, 12), ++ .dsp_out_yuv = VOP_REG(RK3288_POST_SCL_CTRL, 0x1, 2), ++ .dsp_background = VOP_REG(RK3288_DSP_BG, 0xffffffff, 0), + }; + + /* +@@ -1029,6 +1034,10 @@ static const struct vop_output rk3328_output = { + + static const struct vop_misc rk3328_misc = { + .global_regdone_en = VOP_REG(RK3328_SYS_CTRL, 0x1, 11), ++ ++ .win_channel[0] = VOP_REG(RK3328_WIN0_CTRL2, 0xff, 0), ++ .win_channel[1] = VOP_REG(RK3328_WIN1_CTRL2, 0xff, 0), ++ .win_channel[2] = VOP_REG(RK3328_WIN2_CTRL2, 0xff, 0), + }; + + static const struct vop_common rk3328_common = { +@@ -1041,6 +1050,11 @@ static const struct vop_common rk3328_common = { + .dsp_blank = VOP_REG(RK3328_DSP_CTRL0, 0x3, 18), + .out_mode = VOP_REG(RK3328_DSP_CTRL0, 0xf, 0), + .cfg_done = VOP_REG_SYNC(RK3328_REG_CFG_DONE, 0x1, 0), ++ ++ .overlay_mode = VOP_REG(RK3328_SYS_CTRL, 0x1, 16), ++ .dsp_data_swap = VOP_REG(RK3328_DSP_CTRL0, 0x1f, 12), ++ .dsp_out_yuv = VOP_REG(RK3328_POST_SCL_CTRL, 0x1, 2), ++ .dsp_background = VOP_REG(RK3328_DSP_BG, 0xffffffff, 0), + }; + + static const struct vop_intr rk3328_vop_intr = { + +From 4c8a9c260b7d5de435bc68f84e4a81e25c5d597e Mon Sep 17 00:00:00 2001 +From: Jonas Karlman +Date: Fri, 20 Dec 2019 08:12:43 +0000 +Subject: [PATCH] WIP: drm/rockchip: add yuv420 support + +--- + drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c | 22 +++++++++++++++++++++ + drivers/gpu/drm/rockchip/rockchip_drm_vop.c | 18 ++++++++++++++++- + drivers/gpu/drm/rockchip/rockchip_drm_vop.h | 10 ++++++---- + drivers/gpu/drm/rockchip/rockchip_vop_reg.c | 2 ++ + 4 files changed, 47 insertions(+), 5 deletions(-) + +diff --git a/drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c b/drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c +index c8eaeb484672..9fe690570e3d 100644 +--- a/drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c ++++ b/drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c +@@ -386,9 +386,21 @@ static bool is_yuv444(u32 format) + } + } + ++static bool is_yuv420(u32 format) ++{ ++ switch (format) { ++ case MEDIA_BUS_FMT_UYYVYY10_0_5X30: ++ case MEDIA_BUS_FMT_UYYVYY8_0_5X24: ++ return true; ++ default: ++ return false; ++ } ++} ++ + static bool is_10bit(u32 format) + { + switch (format) { ++ case MEDIA_BUS_FMT_UYYVYY10_0_5X30: + case MEDIA_BUS_FMT_RGB101010_1X30: + case MEDIA_BUS_FMT_YUV10_1X30: + return true; +@@ -425,6 +437,11 @@ dw_hdmi_rockchip_bridge_atomic_check(struct drm_bridge *bridge, + + s->bus_width = is_10bit(format) ? 10 : 8; + ++ if (is_yuv420(format)) { ++ s->output_mode = ROCKCHIP_OUT_MODE_YUV420; ++ s->bus_width /= 2; ++ } ++ + old_crtc_state = drm_atomic_get_old_crtc_state(state, conn_state->crtc); + if (old_crtc_state && !crtc_state->mode_changed) { + old_state = to_rockchip_crtc_state(old_crtc_state); +@@ -445,6 +462,7 @@ static u32 *dw_hdmi_rockchip_get_input_bus_fmts(struct drm_bridge *bridge, + { + struct rockchip_hdmi *hdmi = to_rockchip_hdmi(bridge); + struct drm_encoder *encoder = bridge->encoder; ++ struct drm_connector *connector = conn_state->connector; + u32 *input_fmt; + bool has_10bit = true; + +@@ -459,6 +477,9 @@ static u32 *dw_hdmi_rockchip_get_input_bus_fmts(struct drm_bridge *bridge, + if (is_yuv444(output_fmt)) { + if (!hdmi->chip_data->ycbcr_444_allowed) + return NULL; ++ } else if (is_yuv420(output_fmt)) { ++ if (!connector->ycbcr_420_allowed) ++ return NULL; + } else if (!is_rgb(output_fmt)) + return NULL; + +@@ -619,6 +640,7 @@ static const struct dw_hdmi_plat_data rk3328_hdmi_drv_data = { + .phy_name = "inno_dw_hdmi_phy2", + .phy_force_vendor = true, + .use_drm_infoframe = true, ++ .ycbcr_420_allowed = true, + }; + + static struct rockchip_hdmi_chip_data rk3399_chip_data = { +diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_vop.c b/drivers/gpu/drm/rockchip/rockchip_drm_vop.c +index 409734c4425b..d5048c111b82 100644 +--- a/drivers/gpu/drm/rockchip/rockchip_drm_vop.c ++++ b/drivers/gpu/drm/rockchip/rockchip_drm_vop.c +@@ -326,6 +326,19 @@ static int vop_convert_afbc_format(uint32_t format) + } + + static bool is_yuv_output(uint32_t bus_format) ++{ ++ switch (bus_format) { ++ case MEDIA_BUS_FMT_YUV8_1X24: ++ case MEDIA_BUS_FMT_YUV10_1X30: ++ case MEDIA_BUS_FMT_UYYVYY8_0_5X24: ++ case MEDIA_BUS_FMT_UYYVYY10_0_5X30: ++ return true; ++ default: ++ return false; ++ } ++} ++ ++static bool has_uv_swapped(uint32_t bus_format) + { + switch (bus_format) { + case MEDIA_BUS_FMT_YUV8_1X24: +@@ -1460,7 +1473,7 @@ static void vop_crtc_atomic_enable(struct drm_crtc *crtc, + !(vop_data->feature & VOP_FEATURE_OUTPUT_RGB10)) + s->output_mode = ROCKCHIP_OUT_MODE_P888; + +- VOP_REG_SET(vop, common, dsp_data_swap, yuv_output ? 2 : 0); ++ VOP_REG_SET(vop, common, dsp_data_swap, has_uv_swapped(s->bus_format) ? 2 : 0); + + if (s->output_mode == ROCKCHIP_OUT_MODE_AAAA && dither_bpc <= 8) + VOP_REG_SET(vop, common, pre_dither_down, 1); +@@ -1477,6 +1490,9 @@ static void vop_crtc_atomic_enable(struct drm_crtc *crtc, + + VOP_REG_SET(vop, common, out_mode, s->output_mode); + ++ VOP_REG_SET(vop, common, dclk_ddr, ++ s->output_mode == ROCKCHIP_OUT_MODE_YUV420 ? 1 : 0); ++ + VOP_REG_SET(vop, common, overlay_mode, yuv_output); + VOP_REG_SET(vop, common, dsp_out_yuv, yuv_output); + +diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_vop.h b/drivers/gpu/drm/rockchip/rockchip_drm_vop.h +index 896b441e4a63..9f50e0e00127 100644 +--- a/drivers/gpu/drm/rockchip/rockchip_drm_vop.h ++++ b/drivers/gpu/drm/rockchip/rockchip_drm_vop.h +@@ -94,6 +94,7 @@ struct vop_common { + struct vop_reg standby; + + struct vop_reg overlay_mode; ++ struct vop_reg dclk_ddr; + struct vop_reg dsp_data_swap; + struct vop_reg dsp_out_yuv; + struct vop_reg dsp_background; +@@ -258,11 +259,12 @@ struct vop_data { + /* + * display output interface supported by rockchip lcdc + */ +-#define ROCKCHIP_OUT_MODE_P888 0 +-#define ROCKCHIP_OUT_MODE_P666 1 +-#define ROCKCHIP_OUT_MODE_P565 2 ++#define ROCKCHIP_OUT_MODE_P888 0 ++#define ROCKCHIP_OUT_MODE_P666 1 ++#define ROCKCHIP_OUT_MODE_P565 2 ++#define ROCKCHIP_OUT_MODE_YUV420 14 + /* for use special outface */ +-#define ROCKCHIP_OUT_MODE_AAAA 15 ++#define ROCKCHIP_OUT_MODE_AAAA 15 + + /* output flags */ + #define ROCKCHIP_OUTPUT_DSI_DUAL BIT(0) +diff --git a/drivers/gpu/drm/rockchip/rockchip_vop_reg.c b/drivers/gpu/drm/rockchip/rockchip_vop_reg.c +index f276ef4b3f64..8c99cc2a7eda 100644 +--- a/drivers/gpu/drm/rockchip/rockchip_vop_reg.c ++++ b/drivers/gpu/drm/rockchip/rockchip_vop_reg.c +@@ -664,6 +664,7 @@ static const struct vop_common rk3288_common = { + .cfg_done = VOP_REG_SYNC(RK3288_REG_CFG_DONE, 0x1, 0), + + .overlay_mode = VOP_REG(RK3288_SYS_CTRL, 0x1, 16), ++ .dclk_ddr = VOP_REG(RK3288_DSP_CTRL0, 0x1, 8), + .dsp_data_swap = VOP_REG(RK3288_DSP_CTRL0, 0x1f, 12), + .dsp_out_yuv = VOP_REG(RK3288_POST_SCL_CTRL, 0x1, 2), + .dsp_background = VOP_REG(RK3288_DSP_BG, 0xffffffff, 0), +@@ -1052,6 +1053,7 @@ static const struct vop_common rk3328_common = { + .cfg_done = VOP_REG_SYNC(RK3328_REG_CFG_DONE, 0x1, 0), + + .overlay_mode = VOP_REG(RK3328_SYS_CTRL, 0x1, 16), ++ .dclk_ddr = VOP_REG(RK3328_DSP_CTRL0, 0x1, 8), + .dsp_data_swap = VOP_REG(RK3328_DSP_CTRL0, 0x1f, 12), + .dsp_out_yuv = VOP_REG(RK3328_POST_SCL_CTRL, 0x1, 2), + .dsp_background = VOP_REG(RK3328_DSP_BG, 0xffffffff, 0), + +From 335e1bd47a2d0db95907753deb80a6f29fbc1d32 Mon Sep 17 00:00:00 2001 +From: Alex Bee +Date: Sat, 15 Aug 2020 23:20:34 +0200 +Subject: [PATCH] drm/rockchip: enable ycbcr_420_allowed and ycbcr_444_allowed + for RK3228 + +--- + drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c | 2 ++ + 1 file changed, 2 insertions(+) + +diff --git a/drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c b/drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c +index 9fe690570e3d..bccdbb3e0a54 100644 +--- a/drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c ++++ b/drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c +@@ -595,6 +595,7 @@ static const struct dw_hdmi_phy_ops rk3228_hdmi_phy_ops = { + + static struct rockchip_hdmi_chip_data rk3228_chip_data = { + .lcdsel_grf_reg = -1, ++ .ycbcr_444_allowed = true, + }; + + static const struct dw_hdmi_plat_data rk3228_hdmi_drv_data = { +@@ -603,6 +604,7 @@ static const struct dw_hdmi_plat_data rk3228_hdmi_drv_data = { + .phy_ops = &rk3228_hdmi_phy_ops, + .phy_name = "inno_dw_hdmi_phy2", + .phy_force_vendor = true, ++ .ycbcr_420_allowed = true, + }; + + static struct rockchip_hdmi_chip_data rk3288_chip_data = { + +From 825906fc0f83ac7d9fe19bd02063f2e1738f1726 Mon Sep 17 00:00:00 2001 +From: Alex Bee +Date: Mon, 4 Jan 2021 22:38:26 +0100 +Subject: [PATCH] drm/rockchip: seperate mode clock validation + +seperate mode clock validation between internal and external +phy types. +this will allow modes >= 2160p@50Hz on RK3288/RK3399 (RGB444) + +Signed-off-by: Alex Bee +--- + drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c | 18 ++++++++++++++++-- + 1 file changed, 16 insertions(+), 2 deletions(-) + +diff --git a/drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c b/drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c +index bccdbb3e0a54..a612bf3da9ee 100644 +--- a/drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c ++++ b/drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c +@@ -305,16 +305,30 @@ dw_hdmi_rockchip_mode_valid(struct dw_hdmi *hdmi, void *data, + const struct drm_display_mode *mode) + { + struct dw_hdmi_plat_data *pdata = (struct dw_hdmi_plat_data *)data; ++ const struct dw_hdmi_mpll_config *mpll_cfg = pdata->mpll_cfg; ++ + int clock = mode->clock; ++ int i = 0; + + if (pdata->ycbcr_420_allowed && drm_mode_is_420(info, mode) && +- (info->color_formats & DRM_COLOR_FORMAT_YCRCB420)) ++ (info->color_formats & DRM_COLOR_FORMAT_YCRCB420)) { + clock /= 2; ++ mpll_cfg = pdata->mpll_cfg_420; ++ } + +- if (clock > 340000 || ++ if ((!mpll_cfg && clock > 340000) || + (info->max_tmds_clock && clock > info->max_tmds_clock)) + return MODE_CLOCK_HIGH; + ++ if (mpll_cfg) { ++ while ((clock * 1000) < mpll_cfg[i].mpixelclock && ++ mpll_cfg[i].mpixelclock != (~0UL)) ++ i++; ++ ++ if (mpll_cfg[i].mpixelclock == (~0UL)) ++ return MODE_CLOCK_HIGH; ++ } ++ + return drm_mode_validate_size(mode, 3840, 2160); + } + + +From c75dca36b0d16f2a3740fcd0d16519a244d3720f Mon Sep 17 00:00:00 2001 +From: Alex Bee +Date: Sat, 15 Aug 2020 21:11:08 +0200 +Subject: [PATCH] !fixup drm/rockchip: rk3368's vop does not support 10-bit + formats + +--- + drivers/gpu/drm/rockchip/rockchip_vop_reg.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +diff --git a/drivers/gpu/drm/rockchip/rockchip_vop_reg.c b/drivers/gpu/drm/rockchip/rockchip_vop_reg.c +index 8c99cc2a7eda..9ca9fff0d359 100644 +--- a/drivers/gpu/drm/rockchip/rockchip_vop_reg.c ++++ b/drivers/gpu/drm/rockchip/rockchip_vop_reg.c +@@ -751,8 +751,8 @@ 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_10, +- .nformats = ARRAY_SIZE(formats_win_full_10), ++ .data_formats = formats_win_full, ++ .nformats = ARRAY_SIZE(formats_win_full), + .format_modifiers = format_modifiers_win_full, + .enable = VOP_REG(RK3368_WIN0_CTRL0, 0x1, 0), + .format = VOP_REG(RK3368_WIN0_CTRL0, 0x7, 1), + +From 5f8d264498ae4f92b7e66fcc0db03fef02c4b529 Mon Sep 17 00:00:00 2001 +From: Alex Bee +Date: Wed, 14 Oct 2020 16:42:05 +0100 +Subject: [PATCH] drm/rockchip: split rk3328 vop for 10-bit support + +Signed-off-by: Alex Bee +--- + drivers/gpu/drm/rockchip/rockchip_vop_reg.c | 30 ++++++++++++++++++--- + 1 file changed, 27 insertions(+), 3 deletions(-) + +diff --git a/drivers/gpu/drm/rockchip/rockchip_vop_reg.c b/drivers/gpu/drm/rockchip/rockchip_vop_reg.c +index 9ca9fff0d359..e34482c3d2be 100644 +--- a/drivers/gpu/drm/rockchip/rockchip_vop_reg.c ++++ b/drivers/gpu/drm/rockchip/rockchip_vop_reg.c +@@ -1069,12 +1069,36 @@ static const struct vop_intr rk3328_vop_intr = { + .clear = VOP_REG_MASK_SYNC(RK3328_INTR_CLEAR0, 0xffff, 0), + }; + ++static const struct vop_win_phy rk3328_win01_data = { ++ .scl = &rk3288_win_full_scl, ++ .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), ++ .act_info = VOP_REG(RK3368_WIN0_ACT_INFO, 0x1fff1fff, 0), ++ .dsp_info = VOP_REG(RK3368_WIN0_DSP_INFO, 0x0fff0fff, 0), ++ .dsp_st = VOP_REG(RK3368_WIN0_DSP_ST, 0x1fff1fff, 0), ++ .yrgb_mst = VOP_REG(RK3368_WIN0_YRGB_MST, 0xffffffff, 0), ++ .uv_mst = VOP_REG(RK3368_WIN0_CBR_MST, 0xffffffff, 0), ++ .yrgb_vir = VOP_REG(RK3368_WIN0_VIR, 0x3fff, 0), ++ .uv_vir = VOP_REG(RK3368_WIN0_VIR, 0x3fff, 16), ++ .src_alpha_ctl = VOP_REG(RK3368_WIN0_SRC_ALPHA_CTRL, 0xff, 0), ++ .dst_alpha_ctl = VOP_REG(RK3368_WIN0_DST_ALPHA_CTRL, 0xff, 0), ++ .channel = VOP_REG(RK3368_WIN0_CTRL2, 0xff, 0), ++}; ++ ++ + static const struct vop_win_data rk3328_vop_win_data[] = { +- { .base = 0xd0, .phy = &rk3368_win01_data, ++ { .base = 0xd0, .phy = &rk3328_win01_data, + .type = DRM_PLANE_TYPE_PRIMARY }, +- { .base = 0x1d0, .phy = &rk3368_win01_data, ++ { .base = 0x1d0, .phy = &rk3328_win01_data, + .type = DRM_PLANE_TYPE_OVERLAY }, +- { .base = 0x2d0, .phy = &rk3368_win01_data, ++ { .base = 0x2d0, .phy = &rk3328_win01_data, + .type = DRM_PLANE_TYPE_CURSOR }, + }; + + +From 3da4ffc999ca999789d1834f45494396cf1dff60 Mon Sep 17 00:00:00 2001 +From: Jonas Karlman +Date: Sat, 18 Nov 2017 11:09:39 +0100 +Subject: [PATCH] rockchip: vop: force skip lines if image too big + +--- + drivers/gpu/drm/rockchip/rockchip_drm_vop.c | 13 ++++++++++--- + 1 file changed, 10 insertions(+), 3 deletions(-) + +diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_vop.c b/drivers/gpu/drm/rockchip/rockchip_drm_vop.c +index d5048c111b82..c0245f5daeb6 100644 +--- a/drivers/gpu/drm/rockchip/rockchip_drm_vop.c ++++ b/drivers/gpu/drm/rockchip/rockchip_drm_vop.c +@@ -932,6 +932,7 @@ static void vop_plane_atomic_update(struct drm_plane *plane, + int format; + int is_yuv = fb->format->is_yuv; + int i; ++ int skiplines = 0; + + /* + * can't update plane when vop is disabled. +@@ -950,8 +951,14 @@ static void vop_plane_atomic_update(struct drm_plane *plane, + obj = fb->obj[0]; + rk_obj = to_rockchip_obj(obj); + ++ /* ++ * Force skip lines when image is yuv and 3840 width, ++ * fixes a "jumping" green lines issue on RK3328. ++ */ + actual_w = drm_rect_width(src) >> 16; +- actual_h = drm_rect_height(src) >> 16; ++ if (actual_w == 3840 && is_yuv) ++ skiplines = 1; ++ actual_h = drm_rect_height(src) >> (16 + skiplines); + act_info = (actual_h - 1) << 16 | ((actual_w - 1) & 0xffff); + + dsp_info = (drm_rect_height(dest) - 1) << 16; +@@ -993,7 +1000,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_vir, DIV_ROUND_UP(fb->pitches[0], 4 >> skiplines)); + VOP_WIN_SET(vop, win, yrgb_mst, dma_addr); + VOP_WIN_YUV2YUV_SET(vop, win_yuv2yuv, y2r_en, is_yuv); + VOP_WIN_SET(vop, win, y_mir_en, +@@ -1017,7 +1024,7 @@ static void vop_plane_atomic_update(struct drm_plane *plane, + offset += (src->y1 >> 16) * fb->pitches[1] / vsub; + + dma_addr = rk_uv_obj->dma_addr + offset + fb->offsets[1]; +- VOP_WIN_SET(vop, win, uv_vir, DIV_ROUND_UP(fb->pitches[1], 4)); ++ VOP_WIN_SET(vop, win, uv_vir, DIV_ROUND_UP(fb->pitches[1], 4 >> skiplines)); + VOP_WIN_SET(vop, win, uv_mst, dma_addr); + + for (i = 0; i < NUM_YUV2YUV_COEFFICIENTS; i++) { + +From cbd53e07eca0e28b8f425fca00ae0b0703ae1aee Mon Sep 17 00:00:00 2001 +From: Jonas Karlman +Date: Wed, 8 Jan 2020 21:07:51 +0000 +Subject: [PATCH] arm64: dts: rockchip: increase vop clock rate on rk3328 + +The VOP on RK3328 needs to run at higher rate in order to +produce a proper 3840x2160 signal. + +Signed-off-by: Jonas Karlman +--- + arch/arm64/boot/dts/rockchip/rk3328.dtsi | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +diff --git a/arch/arm64/boot/dts/rockchip/rk3328.dtsi b/arch/arm64/boot/dts/rockchip/rk3328.dtsi +index 72f34205fd20..9358d302f5e4 100644 +--- a/arch/arm64/boot/dts/rockchip/rk3328.dtsi ++++ b/arch/arm64/boot/dts/rockchip/rk3328.dtsi +@@ -805,8 +805,8 @@ cru: clock-controller@ff440000 { + <0>, <24000000>, + <24000000>, <24000000>, + <15000000>, <15000000>, +- <100000000>, <100000000>, +- <100000000>, <100000000>, ++ <300000000>, <100000000>, ++ <400000000>, <100000000>, + <50000000>, <100000000>, + <100000000>, <100000000>, + <50000000>, <50000000>, diff --git a/projects/Rockchip/patches/linux/default/linux-1002-v4l2-rockchip.patch b/projects/Rockchip/patches/linux/default/linux-1002-v4l2-rockchip.patch new file mode 100644 index 0000000000..6b6703daaf --- /dev/null +++ b/projects/Rockchip/patches/linux/default/linux-1002-v4l2-rockchip.patch @@ -0,0 +1,670 @@ +From 21616471f5cec9044620089999b23c53d2ddeb97 Mon Sep 17 00:00:00 2001 +From: Jonas Karlman +Date: Sat, 23 May 2020 10:18:16 +0000 +Subject: [PATCH] WIP: media: rkvdec: continue to gate clock when decoding + finish + +Signed-off-by: Jonas Karlman +--- + drivers/staging/media/rkvdec/rkvdec.c | 6 ++++-- + 1 file changed, 4 insertions(+), 2 deletions(-) + +diff --git a/drivers/staging/media/rkvdec/rkvdec.c b/drivers/staging/media/rkvdec/rkvdec.c +index 87987a782d75..a1c33905970d 100644 +--- a/drivers/staging/media/rkvdec/rkvdec.c ++++ b/drivers/staging/media/rkvdec/rkvdec.c +@@ -1024,7 +1024,8 @@ static irqreturn_t rkvdec_irq_handler(int irq, void *priv) + state = (status & RKVDEC_RDY_STA) ? + VB2_BUF_STATE_DONE : VB2_BUF_STATE_ERROR; + +- writel(0, rkvdec->regs + RKVDEC_REG_INTERRUPT); ++ writel(RKVDEC_CONFIG_DEC_CLK_GATE_E, ++ rkvdec->regs + RKVDEC_REG_INTERRUPT); + if (cancel_delayed_work(&rkvdec->watchdog_work)) { + struct rkvdec_ctx *ctx; + +@@ -1045,7 +1046,8 @@ static void rkvdec_watchdog_func(struct work_struct *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(RKVDEC_CONFIG_DEC_CLK_GATE_E | RKVDEC_IRQ_DIS, ++ rkvdec->regs + RKVDEC_REG_INTERRUPT); + writel(0, rkvdec->regs + RKVDEC_REG_SYSCTRL); + rkvdec_job_finish(ctx, VB2_BUF_STATE_ERROR); + } + +From a2324e786890f3f2d41df537fb8208dd49fafd69 Mon Sep 17 00:00:00 2001 +From: Jonas Karlman +Date: Sat, 23 May 2020 10:16:01 +0000 +Subject: [PATCH] WIP: media: rkvdec: pm runtime dont use autosuspend before + disable and cleanup + +Signed-off-by: Jonas Karlman +--- + drivers/staging/media/rkvdec/rkvdec.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +diff --git a/drivers/staging/media/rkvdec/rkvdec.c b/drivers/staging/media/rkvdec/rkvdec.c +index a1c33905970d..8c2ff05e01f7 100644 +--- a/drivers/staging/media/rkvdec/rkvdec.c ++++ b/drivers/staging/media/rkvdec/rkvdec.c +@@ -1145,9 +1145,9 @@ 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); ++ pm_runtime_disable(&pdev->dev); ++ rkvdec_v4l2_cleanup(rkvdec); + return 0; + } + + +From 3ef8eba5dee33aaa0d0e2c56c44b4fd211b67d6b Mon Sep 17 00:00:00 2001 +From: Jonas Karlman +Date: Sat, 23 May 2020 11:23:04 +0000 +Subject: [PATCH] WIP: media: rkvdec: h264: return early when no reference + pictures + +NOTE: also change from a switch statement to access reflists from a pointer array, +should simplify once we add support for field reference list + +Signed-off-by: Jonas Karlman +--- + drivers/staging/media/rkvdec/rkvdec-h264.c | 18 +++++------------- + 1 file changed, 5 insertions(+), 13 deletions(-) + +diff --git a/drivers/staging/media/rkvdec/rkvdec-h264.c b/drivers/staging/media/rkvdec/rkvdec-h264.c +index c115cd362a7f..d9a2fd9386e2 100644 +--- a/drivers/staging/media/rkvdec/rkvdec-h264.c ++++ b/drivers/staging/media/rkvdec/rkvdec-h264.c +@@ -734,6 +734,7 @@ static void assemble_hw_rps(struct rkvdec_ctx *ctx, + 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); ++ u8 *reflists[3] = { h264_ctx->reflists.p, h264_ctx->reflists.b0, h264_ctx->reflists.b1 }; + + u32 *hw_rps = priv_tbl->rps; + u32 i, j; +@@ -741,6 +742,9 @@ static void assemble_hw_rps(struct rkvdec_ctx *ctx, + + memset(hw_rps, 0, sizeof(priv_tbl->rps)); + ++ if (!h264_ctx->reflists.num_valid) ++ return; ++ + /* + * 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 +@@ -763,19 +767,7 @@ static void assemble_hw_rps(struct rkvdec_ctx *ctx, + 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; +- } ++ u8 idx = reflists[j][i]; + + if (idx >= ARRAY_SIZE(dec_params->dpb)) + continue; + +From bfa9384246a28120cc30e369b07bab5538a49c5c Mon Sep 17 00:00:00 2001 +From: Jonas Karlman +Date: Sat, 23 May 2020 14:42:27 +0000 +Subject: [PATCH] WIP: media: rkvdec: h264: add field decoding support + +Signed-off-by: Jonas Karlman +--- + drivers/staging/media/rkvdec/rkvdec-h264.c | 79 ++++++++++++++++++---- + 1 file changed, 64 insertions(+), 15 deletions(-) + +diff --git a/drivers/staging/media/rkvdec/rkvdec-h264.c b/drivers/staging/media/rkvdec/rkvdec-h264.c +index d9a2fd9386e2..d4f27ef7addd 100644 +--- a/drivers/staging/media/rkvdec/rkvdec-h264.c ++++ b/drivers/staging/media/rkvdec/rkvdec-h264.c +@@ -737,7 +737,7 @@ static void assemble_hw_rps(struct rkvdec_ctx *ctx, + u8 *reflists[3] = { h264_ctx->reflists.p, h264_ctx->reflists.b0, h264_ctx->reflists.b1 }; + + u32 *hw_rps = priv_tbl->rps; +- u32 i, j; ++ u32 i, j, k; + u16 *p = (u16 *)hw_rps; + + memset(hw_rps, 0, sizeof(priv_tbl->rps)); +@@ -764,18 +764,71 @@ static void assemble_hw_rps(struct rkvdec_ctx *ctx, + 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 = reflists[j][i]; ++ if (!(dec_params->flags & V4L2_H264_DECODE_PARAM_FLAG_FIELD_PIC)) { ++ for (j = 0; j < RKVDEC_NUM_REFLIST; j++) { ++ for (i = 0; i < h264_ctx->reflists.num_valid; i++) { ++ u8 dpb_valid = 0; ++ u8 idx = reflists[j][i]; + +- if (idx >= ARRAY_SIZE(dec_params->dpb)) +- continue; +- dpb_valid = !!(dpb[idx].flags & +- V4L2_H264_DPB_ENTRY_FLAG_ACTIVE); ++ 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); ++ set_ps_field(hw_rps, DPB_INFO(i, j), ++ idx | dpb_valid << 4); ++ } ++ } ++ return; ++ } ++ ++ for (j = 0; j < RKVDEC_NUM_REFLIST; j++) { ++ enum v4l2_h264_field_reference a_parity = ++ (dec_params->flags & V4L2_H264_DECODE_PARAM_FLAG_BOTTOM_FIELD) ++ ? V4L2_H264_BOTTOM_FIELD_REF : V4L2_H264_TOP_FIELD_REF; ++ enum v4l2_h264_field_reference b_parity = ++ (dec_params->flags & V4L2_H264_DECODE_PARAM_FLAG_BOTTOM_FIELD) ++ ? V4L2_H264_TOP_FIELD_REF : V4L2_H264_BOTTOM_FIELD_REF; ++ u32 flags = V4L2_H264_DPB_ENTRY_FLAG_LONG_TERM; ++ i = 0; ++ ++ for (k = 0; k < 2; k++) { ++ u8 a = 0; ++ u8 b = 0; ++ u32 long_term = k ? V4L2_H264_DPB_ENTRY_FLAG_LONG_TERM : 0; ++ ++ while (a < h264_ctx->reflists.num_valid || b < h264_ctx->reflists.num_valid) { ++ for (; a < h264_ctx->reflists.num_valid; a++) { ++ u8 idx = reflists[j][a]; ++ if (idx >= ARRAY_SIZE(dec_params->dpb)) ++ continue; ++ if ((dpb[idx].reference & a_parity) == a_parity && ++ (dpb[idx].flags & flags) == long_term) { ++ set_ps_field(hw_rps, DPB_INFO(i, j), ++ idx | (1 << 4)); ++ set_ps_field(hw_rps, BOTTOM_FLAG(i, j), ++ a_parity == V4L2_H264_BOTTOM_FIELD_REF); ++ i++; ++ a++; ++ break; ++ } ++ } ++ for (; b < h264_ctx->reflists.num_valid; b++) { ++ u8 idx = reflists[j][b]; ++ if (idx >= ARRAY_SIZE(dec_params->dpb)) ++ continue; ++ if ((dpb[idx].reference & b_parity) == b_parity && ++ (dpb[idx].flags & flags) == long_term) { ++ set_ps_field(hw_rps, DPB_INFO(i, j), ++ idx | (1 << 4)); ++ set_ps_field(hw_rps, BOTTOM_FLAG(i, j), ++ b_parity == V4L2_H264_BOTTOM_FIELD_REF); ++ i++; ++ b++; ++ break; ++ } ++ } ++ } + } + } + } +@@ -968,10 +1021,6 @@ static void config_registers(struct rkvdec_ctx *ctx, + 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); + + +From d8c26ae5339462b975d58403d7457283db3f2f82 Mon Sep 17 00:00:00 2001 +From: Jonas Karlman +Date: Tue, 29 Oct 2019 01:26:02 +0000 +Subject: [PATCH] RFC: media: hantro: Fix H264 decoding of field encoded + content + +This still need code cleanup and formatting + +Signed-off-by: Jonas Karlman +--- + .../staging/media/hantro/hantro_g1_h264_dec.c | 17 +--- + drivers/staging/media/hantro/hantro_h264.c | 81 ++++++++++++++++--- + drivers/staging/media/hantro/hantro_hw.h | 2 + + 3 files changed, 74 insertions(+), 26 deletions(-) + +diff --git a/drivers/staging/media/hantro/hantro_g1_h264_dec.c b/drivers/staging/media/hantro/hantro_g1_h264_dec.c +index 845bef73d218..869ee261a5db 100644 +--- a/drivers/staging/media/hantro/hantro_g1_h264_dec.c ++++ b/drivers/staging/media/hantro/hantro_g1_h264_dec.c +@@ -130,25 +130,12 @@ static void set_ref(struct hantro_ctx *ctx) + struct v4l2_h264_dpb_entry *dpb = ctx->h264_dec.dpb; + const u8 *b0_reflist, *b1_reflist, *p_reflist; + struct hantro_dev *vpu = ctx->dev; +- u32 dpb_longterm = 0; +- u32 dpb_valid = 0; + int reg_num; + u32 reg; + int i; + +- /* +- * Set up bit maps of valid and long term DPBs. +- * NOTE: The bits are reversed, i.e. MSb is DPB 0. +- */ +- for (i = 0; i < HANTRO_H264_DPB_SIZE; ++i) { +- if (dpb[i].flags & V4L2_H264_DPB_ENTRY_FLAG_ACTIVE) +- dpb_valid |= BIT(HANTRO_H264_DPB_SIZE - 1 - i); +- +- if (dpb[i].flags & V4L2_H264_DPB_ENTRY_FLAG_LONG_TERM) +- dpb_longterm |= BIT(HANTRO_H264_DPB_SIZE - 1 - i); +- } +- vdpu_write_relaxed(vpu, dpb_valid << 16, G1_REG_VALID_REF); +- vdpu_write_relaxed(vpu, dpb_longterm << 16, G1_REG_LT_REF); ++ vdpu_write_relaxed(vpu, ctx->h264_dec.dpb_valid, G1_REG_VALID_REF); ++ vdpu_write_relaxed(vpu, ctx->h264_dec.dpb_longterm, G1_REG_LT_REF); + + /* + * Set up reference frame picture numbers. +diff --git a/drivers/staging/media/hantro/hantro_h264.c b/drivers/staging/media/hantro/hantro_h264.c +index b1bdc00ac262..bc2af450a94c 100644 +--- a/drivers/staging/media/hantro/hantro_h264.c ++++ b/drivers/staging/media/hantro/hantro_h264.c +@@ -227,17 +227,67 @@ static void prepare_table(struct hantro_ctx *ctx) + { + const struct hantro_h264_dec_ctrls *ctrls = &ctx->h264_dec.ctrls; + const struct v4l2_ctrl_h264_decode_params *dec_param = ctrls->decode; ++ const struct v4l2_ctrl_h264_sps *sps = ctrls->sps; + struct hantro_h264_dec_priv_tbl *tbl = ctx->h264_dec.priv.cpu; + const struct v4l2_h264_dpb_entry *dpb = ctx->h264_dec.dpb; ++ u32 dpb_longterm = 0; ++ u32 dpb_valid = 0; + int i; + ++ /* ++ * Set up bit maps of valid and long term DPBs. ++ * NOTE: The bits are reversed, i.e. MSb is DPB 0. ++ */ ++ if ((dec_param->flags & V4L2_H264_DECODE_PARAM_FLAG_FIELD_PIC) || (sps->flags & V4L2_H264_SPS_FLAG_MB_ADAPTIVE_FRAME_FIELD)) { ++ for (i = 0; i < HANTRO_H264_DPB_SIZE * 2; ++i) { ++ // check for correct reference use ++ enum v4l2_h264_field_reference parity = (i & 0x1) ? ++ V4L2_H264_BOTTOM_FIELD_REF : V4L2_H264_TOP_FIELD_REF; ++ if (dpb[i / 2].flags & V4L2_H264_DPB_ENTRY_FLAG_ACTIVE && ++ dpb[i / 2].reference & parity) ++ dpb_valid |= BIT(HANTRO_H264_DPB_SIZE * 2 - 1 - i); ++ ++ if (dpb[i / 2].flags & V4L2_H264_DPB_ENTRY_FLAG_LONG_TERM) ++ dpb_longterm |= BIT(HANTRO_H264_DPB_SIZE * 2 - 1 - i); ++ } ++ ++ ctx->h264_dec.dpb_valid = dpb_valid; ++ ctx->h264_dec.dpb_longterm = dpb_longterm; ++ } else { ++ for (i = 0; i < HANTRO_H264_DPB_SIZE; ++i) { ++ if (dpb[i].flags & V4L2_H264_DPB_ENTRY_FLAG_ACTIVE) ++ dpb_valid |= BIT(HANTRO_H264_DPB_SIZE - 1 - i); ++ ++ if (dpb[i].flags & V4L2_H264_DPB_ENTRY_FLAG_LONG_TERM) ++ dpb_longterm |= BIT(HANTRO_H264_DPB_SIZE - 1 - i); ++ } ++ ++ ctx->h264_dec.dpb_valid = dpb_valid << 16; ++ ctx->h264_dec.dpb_longterm = dpb_longterm << 16; ++ } ++ + for (i = 0; i < HANTRO_H264_DPB_SIZE; ++i) { +- tbl->poc[i * 2] = dpb[i].top_field_order_cnt; +- tbl->poc[i * 2 + 1] = dpb[i].bottom_field_order_cnt; ++ if (dpb[i].flags & V4L2_H264_DPB_ENTRY_FLAG_ACTIVE) { ++ tbl->poc[i * 2] = dpb[i].top_field_order_cnt; ++ tbl->poc[i * 2 + 1] = dpb[i].bottom_field_order_cnt; ++ } else { ++ tbl->poc[i * 2] = 0; ++ tbl->poc[i * 2 + 1] = 0; ++ } + } + +- tbl->poc[32] = dec_param->top_field_order_cnt; +- tbl->poc[33] = dec_param->bottom_field_order_cnt; ++ if ((dec_param->flags & V4L2_H264_DECODE_PARAM_FLAG_FIELD_PIC) || !(sps->flags & V4L2_H264_SPS_FLAG_MB_ADAPTIVE_FRAME_FIELD)) { ++ if ((dec_param->flags & V4L2_H264_DECODE_PARAM_FLAG_FIELD_PIC)) ++ tbl->poc[32] = (dec_param->flags & V4L2_H264_DECODE_PARAM_FLAG_BOTTOM_FIELD) ? ++ dec_param->bottom_field_order_cnt : ++ dec_param->top_field_order_cnt; ++ else ++ tbl->poc[32] = min(dec_param->top_field_order_cnt, dec_param->bottom_field_order_cnt); ++ tbl->poc[33] = 0; ++ } else { ++ tbl->poc[32] = dec_param->top_field_order_cnt; ++ tbl->poc[33] = dec_param->bottom_field_order_cnt; ++ } + + assemble_scaling_list(ctx); + } +@@ -245,8 +295,7 @@ static void prepare_table(struct hantro_ctx *ctx) + static bool dpb_entry_match(const struct v4l2_h264_dpb_entry *a, + const struct v4l2_h264_dpb_entry *b) + { +- return a->top_field_order_cnt == b->top_field_order_cnt && +- a->bottom_field_order_cnt == b->bottom_field_order_cnt; ++ return a->reference_ts == b->reference_ts; + } + + static void update_dpb(struct hantro_ctx *ctx) +@@ -260,13 +309,13 @@ static void update_dpb(struct hantro_ctx *ctx) + + /* Disable all entries by default. */ + for (i = 0; i < ARRAY_SIZE(ctx->h264_dec.dpb); i++) +- ctx->h264_dec.dpb[i].flags &= ~V4L2_H264_DPB_ENTRY_FLAG_ACTIVE; ++ ctx->h264_dec.dpb[i].flags = 0; + + /* Try to match new DPB entries with existing ones by their POCs. */ + for (i = 0; i < ARRAY_SIZE(dec_param->dpb); i++) { + const struct v4l2_h264_dpb_entry *ndpb = &dec_param->dpb[i]; + +- if (!(ndpb->flags & V4L2_H264_DPB_ENTRY_FLAG_ACTIVE)) ++ if (!(ndpb->flags & V4L2_H264_DPB_ENTRY_FLAG_VALID)) + continue; + + /* +@@ -277,8 +326,7 @@ static void update_dpb(struct hantro_ctx *ctx) + struct v4l2_h264_dpb_entry *cdpb; + + cdpb = &ctx->h264_dec.dpb[j]; +- if (cdpb->flags & V4L2_H264_DPB_ENTRY_FLAG_ACTIVE || +- !dpb_entry_match(cdpb, ndpb)) ++ if (!dpb_entry_match(cdpb, ndpb)) + continue; + + *cdpb = *ndpb; +@@ -314,7 +362,10 @@ dma_addr_t hantro_h264_get_ref_buf(struct hantro_ctx *ctx, + unsigned int dpb_idx) + { + struct v4l2_h264_dpb_entry *dpb = ctx->h264_dec.dpb; ++ const struct v4l2_ctrl_h264_decode_params *dec_param = ctx->h264_dec.ctrls.decode; + dma_addr_t dma_addr = 0; ++ s32 cur_poc; ++ u32 flags; + + if (dpb[dpb_idx].flags & V4L2_H264_DPB_ENTRY_FLAG_ACTIVE) + dma_addr = hantro_get_ref(ctx, dpb[dpb_idx].reference_ts); +@@ -332,7 +383,15 @@ dma_addr_t hantro_h264_get_ref_buf(struct hantro_ctx *ctx, + dma_addr = hantro_get_dec_buf_addr(ctx, buf); + } + +- return dma_addr; ++ cur_poc = dec_param->flags & V4L2_H264_DECODE_PARAM_FLAG_BOTTOM_FIELD ? ++ dec_param->bottom_field_order_cnt : ++ dec_param->top_field_order_cnt; ++ flags = dpb[dpb_idx].flags & V4L2_H264_DPB_ENTRY_FLAG_FIELD ? 0x2 : 0; ++ flags |= abs(dpb[dpb_idx].top_field_order_cnt - cur_poc) < ++ abs(dpb[dpb_idx].bottom_field_order_cnt - cur_poc) ? ++ 0x1 : 0; ++ ++ return dma_addr | flags; + } + + int hantro_h264_dec_prepare_run(struct hantro_ctx *ctx) +diff --git a/drivers/staging/media/hantro/hantro_hw.h b/drivers/staging/media/hantro/hantro_hw.h +index 219283a06f52..7e35140a4f22 100644 +--- a/drivers/staging/media/hantro/hantro_hw.h ++++ b/drivers/staging/media/hantro/hantro_hw.h +@@ -90,6 +90,8 @@ struct hantro_h264_dec_hw_ctx { + struct v4l2_h264_dpb_entry dpb[HANTRO_H264_DPB_SIZE]; + struct hantro_h264_dec_reflists reflists; + struct hantro_h264_dec_ctrls ctrls; ++ u32 dpb_longterm; ++ u32 dpb_valid; + }; + + /** + +From 425502e84ccd26c89822213750e4054c480a96db Mon Sep 17 00:00:00 2001 +From: Alex Bee +Date: Wed, 19 Aug 2020 21:12:54 +0200 +Subject: [PATCH] arm64: dts: rockchip: add rkvdec node for RK3328 + +Signed-off-by: Alex Bee +--- + .../bindings/media/rockchip,vdec.yaml | 5 +++++ + arch/arm64/boot/dts/rockchip/rk3328.dtsi | 21 ++++++++++++++++++- + 2 files changed, 25 insertions(+), 1 deletion(-) + +diff --git a/Documentation/devicetree/bindings/media/rockchip,vdec.yaml b/Documentation/devicetree/bindings/media/rockchip,vdec.yaml +index 8d35c327018b..4e4f07d3050c 100644 +--- a/Documentation/devicetree/bindings/media/rockchip,vdec.yaml ++++ b/Documentation/devicetree/bindings/media/rockchip,vdec.yaml +@@ -16,6 +16,11 @@ description: |- + properties: + compatible: + const: rockchip,rk3399-vdec ++ - items: ++ - enum: ++ - rockchip,rk3328-vdec ++ - const: rockchip,rk3399-vdec ++ + + reg: + maxItems: 1 +diff --git a/arch/arm64/boot/dts/rockchip/rk3328.dtsi b/arch/arm64/boot/dts/rockchip/rk3328.dtsi +index 9358d302f5e4..b54ff9055e5f 100644 +--- a/arch/arm64/boot/dts/rockchip/rk3328.dtsi ++++ b/arch/arm64/boot/dts/rockchip/rk3328.dtsi +@@ -326,6 +326,10 @@ pd_hevc@RK3328_PD_HEVC { + }; + pd_video@RK3328_PD_VIDEO { + reg = ; ++ clocks = <&cru ACLK_RKVDEC>, ++ <&cru HCLK_RKVDEC>, ++ <&cru SCLK_VDEC_CABAC>, ++ <&cru SCLK_VDEC_CORE>; + }; + pd_vpu@RK3328_PD_VPU { + reg = ; +@@ -670,6 +674,21 @@ vpu_mmu: iommu@ff350800 { + power-domains = <&power RK3328_PD_VPU>; + }; + ++ rkvdec: video-codec@ff360000 { ++ compatible = "rockchip,rk3328-vdec", "rockchip,rk3399-vdec"; ++ reg = <0x0 0xff360000 0x0 0x480>; ++ interrupts = ; ++ interrupt-names = "vdpu"; ++ assigned-clocks = <&cru ACLK_RKVDEC>, <&cru SCLK_VDEC_CABAC>, ++ <&cru SCLK_VDEC_CORE>; ++ assigned-clock-rates = <500000000>, <300000000>, <250000000>; ++ clocks = <&cru ACLK_RKVDEC>, <&cru HCLK_RKVDEC>, ++ <&cru SCLK_VDEC_CABAC>, <&cru SCLK_VDEC_CORE>; ++ clock-names = "axi", "ahb", "cabac", "core"; ++ iommus = <&rkvdec_mmu>; ++ power-domains = <&power RK3328_PD_VIDEO>; ++ }; ++ + rkvdec_mmu: iommu@ff360480 { + compatible = "rockchip,iommu"; + reg = <0x0 0xff360480 0x0 0x40>, <0x0 0xff3604c0 0x0 0x40>; +@@ -678,7 +697,7 @@ rkvdec_mmu: iommu@ff360480 { + clocks = <&cru ACLK_RKVDEC>, <&cru HCLK_RKVDEC>; + clock-names = "aclk", "iface"; + #iommu-cells = <0>; +- status = "disabled"; ++ power-domains = <&power RK3328_PD_VIDEO>; + }; + + vop: vop@ff370000 { + +From 9a067bb4800e4a9907c070dcfe68da5d625b8c8a Mon Sep 17 00:00:00 2001 +From: Alex Bee +Date: Wed, 14 Oct 2020 13:27:12 +0200 +Subject: [PATCH] media: hantro: adapt to match 5.11 H.264 uapi changes + +Signed-off-by: Alex Bee +--- + drivers/staging/media/hantro/hantro_h264.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +diff --git a/drivers/staging/media/hantro/hantro_h264.c b/drivers/staging/media/hantro/hantro_h264.c +index bc2af450a94c..7bdefcc2fc77 100644 +--- a/drivers/staging/media/hantro/hantro_h264.c ++++ b/drivers/staging/media/hantro/hantro_h264.c +@@ -241,10 +241,10 @@ static void prepare_table(struct hantro_ctx *ctx) + if ((dec_param->flags & V4L2_H264_DECODE_PARAM_FLAG_FIELD_PIC) || (sps->flags & V4L2_H264_SPS_FLAG_MB_ADAPTIVE_FRAME_FIELD)) { + for (i = 0; i < HANTRO_H264_DPB_SIZE * 2; ++i) { + // check for correct reference use +- enum v4l2_h264_field_reference parity = (i & 0x1) ? ++ u8 parity = (i & 0x1) ? + V4L2_H264_BOTTOM_FIELD_REF : V4L2_H264_TOP_FIELD_REF; + if (dpb[i / 2].flags & V4L2_H264_DPB_ENTRY_FLAG_ACTIVE && +- dpb[i / 2].reference & parity) ++ dpb[i / 2].fields & parity) + dpb_valid |= BIT(HANTRO_H264_DPB_SIZE * 2 - 1 - i); + + if (dpb[i / 2].flags & V4L2_H264_DPB_ENTRY_FLAG_LONG_TERM) + +From fae421aabc3a070aef53715808976d84b9a563e5 Mon Sep 17 00:00:00 2001 +From: Alex Bee +Date: Wed, 14 Oct 2020 13:42:01 +0200 +Subject: [PATCH] media: rkvdec: adapt to match 5.11 H.264 uapi changes + +Signed-off-by: Alex Bee +--- + drivers/staging/media/rkvdec/rkvdec-h264.c | 8 ++++---- + 1 file changed, 4 insertions(+), 4 deletions(-) + +diff --git a/drivers/staging/media/rkvdec/rkvdec-h264.c b/drivers/staging/media/rkvdec/rkvdec-h264.c +index d4f27ef7addd..627cd4efabef 100644 +--- a/drivers/staging/media/rkvdec/rkvdec-h264.c ++++ b/drivers/staging/media/rkvdec/rkvdec-h264.c +@@ -783,10 +783,10 @@ static void assemble_hw_rps(struct rkvdec_ctx *ctx, + } + + for (j = 0; j < RKVDEC_NUM_REFLIST; j++) { +- enum v4l2_h264_field_reference a_parity = ++ u8 a_parity = + (dec_params->flags & V4L2_H264_DECODE_PARAM_FLAG_BOTTOM_FIELD) + ? V4L2_H264_BOTTOM_FIELD_REF : V4L2_H264_TOP_FIELD_REF; +- enum v4l2_h264_field_reference b_parity = ++ u8 b_parity = + (dec_params->flags & V4L2_H264_DECODE_PARAM_FLAG_BOTTOM_FIELD) + ? V4L2_H264_TOP_FIELD_REF : V4L2_H264_BOTTOM_FIELD_REF; + u32 flags = V4L2_H264_DPB_ENTRY_FLAG_LONG_TERM; +@@ -802,7 +802,7 @@ static void assemble_hw_rps(struct rkvdec_ctx *ctx, + u8 idx = reflists[j][a]; + if (idx >= ARRAY_SIZE(dec_params->dpb)) + continue; +- if ((dpb[idx].reference & a_parity) == a_parity && ++ if ((dpb[idx].fields & a_parity) == a_parity && + (dpb[idx].flags & flags) == long_term) { + set_ps_field(hw_rps, DPB_INFO(i, j), + idx | (1 << 4)); +@@ -817,7 +817,7 @@ static void assemble_hw_rps(struct rkvdec_ctx *ctx, + u8 idx = reflists[j][b]; + if (idx >= ARRAY_SIZE(dec_params->dpb)) + continue; +- if ((dpb[idx].reference & b_parity) == b_parity && ++ if ((dpb[idx].fields & b_parity) == b_parity && + (dpb[idx].flags & flags) == long_term) { + set_ps_field(hw_rps, DPB_INFO(i, j), + idx | (1 << 4)); + +From e86afb0d646bd4823849138ac1708a456fff3fcb Mon Sep 17 00:00:00 2001 +From: Alex Bee +Date: Sun, 31 May 2020 18:22:01 +0200 +Subject: [PATCH] media: hantro: rk3288: increase max ACLK + +as per vendor source + +Signed-off-by: Alex Bee +--- + drivers/staging/media/hantro/rk3288_vpu_hw.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/drivers/staging/media/hantro/rk3288_vpu_hw.c b/drivers/staging/media/hantro/rk3288_vpu_hw.c +index 7b299ee3e93d..23f793e73941 100644 +--- a/drivers/staging/media/hantro/rk3288_vpu_hw.c ++++ b/drivers/staging/media/hantro/rk3288_vpu_hw.c +@@ -13,7 +13,7 @@ + #include "hantro_g1_regs.h" + #include "hantro_h1_regs.h" + +-#define RK3288_ACLK_MAX_FREQ (400 * 1000 * 1000) ++#define RK3288_ACLK_MAX_FREQ (600 * 1000 * 1000) + + /* + * Supported formats. +From aa00e71228f42708062cf4003cd51ee40dc32b8b Mon Sep 17 00:00:00 2001 +From: Jonas Karlman +Date: Sat, 23 May 2020 11:42:23 +0000 +Subject: [PATCH] HACK: media: rkvdec: soft reset + +NOTE: rkvdec does not fully self reset, trigger pm runtime suspend to unlock when rkvdec issue soft reset +--- + drivers/staging/media/rkvdec/rkvdec.c | 9 ++++++++- + drivers/staging/media/rkvdec/rkvdec.h | 1 + + 2 files changed, 9 insertions(+), 1 deletion(-) + +diff --git a/drivers/staging/media/rkvdec/rkvdec.c b/drivers/staging/media/rkvdec/rkvdec.c +index 5eec0ed710b2..3108d06ef7e0 100644 +--- a/drivers/staging/media/rkvdec/rkvdec.c ++++ b/drivers/staging/media/rkvdec/rkvdec.c +@@ -882,6 +882,8 @@ static void rkvdec_job_finish(struct rkvdec_ctx *ctx, + + pm_runtime_mark_last_busy(rkvdec->dev); + pm_runtime_put_autosuspend(rkvdec->dev); ++ if (result == VB2_BUF_STATE_ERROR) ++ rkvdec->soft_reset = true; + rkvdec_job_finish_no_pm(ctx, result); + } + +@@ -920,6 +922,11 @@ static void rkvdec_device_run(void *priv) + if (WARN_ON(!desc)) + return; + ++ if (rkvdec->soft_reset) { ++ pm_runtime_suspend(rkvdec->dev); ++ rkvdec->soft_reset = false; ++ } ++ + ret = pm_runtime_get_sync(rkvdec->dev); + if (ret < 0) { + rkvdec_job_finish_no_pm(ctx, VB2_BUF_STATE_ERROR); +@@ -1203,7 +1210,7 @@ static void rkvdec_watchdog_func(struct work_struct *work) + ctx = v4l2_m2m_get_curr_priv(rkvdec->m2m_dev); + if (ctx) { + dev_err(rkvdec->dev, "Frame processing timed out!\n"); +- writel(RKVDEC_CONFIG_DEC_CLK_GATE_E | RKVDEC_IRQ_DIS, ++ writel(RKVDEC_CONFIG_DEC_CLK_GATE_E | RKVDEC_IRQ_DIS | RKVDEC_SOFTRST_EN_P, + rkvdec->regs + RKVDEC_REG_INTERRUPT); + writel(0, rkvdec->regs + RKVDEC_REG_SYSCTRL); + rkvdec_job_finish(ctx, VB2_BUF_STATE_ERROR); +diff --git a/drivers/staging/media/rkvdec/rkvdec.h b/drivers/staging/media/rkvdec/rkvdec.h +index d5600c6a4c17..a801668f5f7b 100644 +--- a/drivers/staging/media/rkvdec/rkvdec.h ++++ b/drivers/staging/media/rkvdec/rkvdec.h +@@ -95,6 +95,7 @@ struct rkvdec_dev { + void __iomem *regs; + struct mutex vdev_lock; /* serializes ioctls */ + struct delayed_work watchdog_work; ++ bool soft_reset; + }; + + struct rkvdec_ctx { diff --git a/projects/Rockchip/patches/linux/default/linux-1003-RK3328-enable-USB3-for-supported-boards.patch b/projects/Rockchip/patches/linux/default/linux-1003-RK3328-enable-USB3-for-supported-boards.patch new file mode 100644 index 0000000000..65a80036ad --- /dev/null +++ b/projects/Rockchip/patches/linux/default/linux-1003-RK3328-enable-USB3-for-supported-boards.patch @@ -0,0 +1,76 @@ +From 3fd56f9d0e8ec407bdce20b6b4af7ee3c5e17f6a Mon Sep 17 00:00:00 2001 +From: Alex Bee +Date: Sat, 16 Jan 2021 12:24:58 +0000 +Subject: [PATCH] ARM64: dts: rockchip: RK3328: enable USB3 for supported + boards + +Signed-off-by: Alex Bee +--- + arch/arm64/boot/dts/rockchip/rk3328-a1.dts | 21 +++++++++++++++++++ + .../arm64/boot/dts/rockchip/rk3328-rock64.dts | 21 +++++++++++++++++++ + 2 files changed, 42 insertions(+) + +diff --git a/arch/arm64/boot/dts/rockchip/rk3328-a1.dts b/arch/arm64/boot/dts/rockchip/rk3328-a1.dts +index 37f307cfa4cc..4013f16bb368 100644 +--- a/arch/arm64/boot/dts/rockchip/rk3328-a1.dts ++++ b/arch/arm64/boot/dts/rockchip/rk3328-a1.dts +@@ -352,6 +352,27 @@ &usb_host0_ehci { + status = "okay"; + }; + ++&usbdrd3 { ++ status = "okay"; ++}; ++ ++&usbdrd_dwc3 { ++ dr_mode = "host"; ++ status = "okay"; ++}; ++ ++&usb3phy { ++ status = "okay"; ++}; ++ ++&usb3phy_utmi { ++ status = "okay"; ++}; ++ ++&usb3phy_pipe { ++ status = "okay"; ++}; ++ + &vop { + status = "okay"; + }; +diff --git a/arch/arm64/boot/dts/rockchip/rk3328-rock64.dts b/arch/arm64/boot/dts/rockchip/rk3328-rock64.dts +index c984662043da..89fde87f7650 100644 +--- a/arch/arm64/boot/dts/rockchip/rk3328-rock64.dts ++++ b/arch/arm64/boot/dts/rockchip/rk3328-rock64.dts +@@ -384,6 +384,27 @@ &usb_host0_ohci { + status = "okay"; + }; + ++&usbdrd3 { ++ status = "okay"; ++}; ++ ++&usbdrd_dwc3 { ++ dr_mode = "host"; ++ status = "okay"; ++}; ++ ++&usb3phy { ++ status = "okay"; ++}; ++ ++&usb3phy_utmi { ++ status = "okay"; ++}; ++ ++&usb3phy_pipe { ++ status = "okay"; ++}; ++ + &vop { + status = "okay"; + }; From fb250136faebf949aeab6d35326c7ec060666b3a Mon Sep 17 00:00:00 2001 From: Alex Bee Date: Sun, 17 Jan 2021 17:02:37 +0100 Subject: [PATCH 2/6] rockchip: align uboot_helper and READMEs for currently supported boards --- projects/Rockchip/devices/RK3328/README.md | 5 +---- projects/Rockchip/devices/RK3399/README.md | 8 ++++++++ scripts/uboot_helper | 16 ---------------- 3 files changed, 9 insertions(+), 20 deletions(-) diff --git a/projects/Rockchip/devices/RK3328/README.md b/projects/Rockchip/devices/RK3328/README.md index 685eca9b81..c06a8ff691 100644 --- a/projects/Rockchip/devices/RK3328/README.md +++ b/projects/Rockchip/devices/RK3328/README.md @@ -4,12 +4,9 @@ This is a SoC device for RK3328 **Build** -* `PROJECT=Rockchip DEVICE=RK3328 ARCH=arm UBOOT_SYSTEM=box make image` -* `PROJECT=Rockchip DEVICE=RK3328 ARCH=arm UBOOT_SYSTEM=box-trn9 make image` -* `PROJECT=Rockchip DEVICE=RK3328 ARCH=arm UBOOT_SYSTEM=box-z28 make image` +* `PROJECT=Rockchip DEVICE=RK3328 ARCH=arm UBOOT_SYSTEM=a1 make image` * `PROJECT=Rockchip DEVICE=RK3328 ARCH=arm UBOOT_SYSTEM=roc-cc make image` * `PROJECT=Rockchip DEVICE=RK3328 ARCH=arm UBOOT_SYSTEM=rock64 make image` -* `PROJECT=Rockchip DEVICE=RK3328 ARCH=arm UBOOT_SYSTEM=rockbox make image` **How to use on an Android device** - Flash image to a sd-card diff --git a/projects/Rockchip/devices/RK3399/README.md b/projects/Rockchip/devices/RK3399/README.md index 9cc3c7bd4d..72923919c1 100644 --- a/projects/Rockchip/devices/RK3399/README.md +++ b/projects/Rockchip/devices/RK3399/README.md @@ -4,10 +4,18 @@ This is a SoC device for RK3399 **Build** +* `PROJECT=Rockchip DEVICE=RK3399 ARCH=arm UBOOT_SYSTEM=firefly make image` +* `PROJECT=Rockchip DEVICE=RK3399 ARCH=arm UBOOT_SYSTEM=hugsun-x99 make image` * `PROJECT=Rockchip DEVICE=RK3399 ARCH=arm UBOOT_SYSTEM=khadas-edge make image` +* `PROJECT=Rockchip DEVICE=RK3399 ARCH=arm UBOOT_SYSTEM=khadas-edge-v make image` +* `PROJECT=Rockchip DEVICE=RK3399 ARCH=arm UBOOT_SYSTEM=nanopc-t4 make image` +* `PROJECT=Rockchip DEVICE=RK3399 ARCH=arm UBOOT_SYSTEM=nanopi-m4 make image` +* `PROJECT=Rockchip DEVICE=RK3399 ARCH=arm UBOOT_SYSTEM=nanopi-neo4 make image` +* `PROJECT=Rockchip DEVICE=RK3399 ARCH=arm UBOOT_SYSTEM=orangepi make image` * `PROJECT=Rockchip DEVICE=RK3399 ARCH=arm UBOOT_SYSTEM=rock960 make image` * `PROJECT=Rockchip DEVICE=RK3399 ARCH=arm UBOOT_SYSTEM=rock-pi-4a make image` * `PROJECT=Rockchip DEVICE=RK3399 ARCH=arm UBOOT_SYSTEM=rock-pi-4b make image` * `PROJECT=Rockchip DEVICE=RK3399 ARCH=arm UBOOT_SYSTEM=rock-pi-4c make image` * `PROJECT=Rockchip DEVICE=RK3399 ARCH=arm UBOOT_SYSTEM=rockpro64 make image` +* `PROJECT=Rockchip DEVICE=RK3399 ARCH=arm UBOOT_SYSTEM=roc-pc make image` * `PROJECT=Rockchip DEVICE=RK3399 ARCH=arm UBOOT_SYSTEM=sapphire make image` diff --git a/scripts/uboot_helper b/scripts/uboot_helper index ed275697c6..c9ba1a9f61 100755 --- a/scripts/uboot_helper +++ b/scripts/uboot_helper @@ -244,18 +244,6 @@ devices = \ 'dtb': 'rk3328-a1.dtb', 'config': 'evb-rk3328_defconfig' }, - 'box': { - 'dtb': 'rk3328-box.dtb', - 'config': 'evb-rk3328_defconfig' - }, - 'box-trn9': { - 'dtb': 'rk3328-box-trn9.dtb', - 'config': 'evb-rk3328_defconfig' - }, - 'box-z28': { - 'dtb': 'rk3328-box-z28.dtb', - 'config': 'evb-rk3328_defconfig' - }, 'roc-cc': { 'dtb': 'rk3328-roc-cc.dtb', 'config': 'evb-rk3328_defconfig' @@ -264,10 +252,6 @@ devices = \ 'dtb': 'rk3328-rock64.dtb', 'config': 'evb-rk3328_defconfig' }, - 'rockbox': { - 'dtb': 'rk3328-rockbox.dtb', - 'config': 'evb-rk3328_defconfig' - }, }, 'RK3399': { 'firefly': { From aa7c55f606b4013706b1a50f76ea7737737928ae Mon Sep 17 00:00:00 2001 From: Alex Bee Date: Sun, 17 Jan 2021 17:06:10 +0100 Subject: [PATCH 3/6] rockchip: kodi: update appliance.xml This aligns rockchip's appliance.xml with https://github.com/xbmc/xbmc/pull/16216 --- projects/Rockchip/kodi/appliance.xml | 24 +----------------------- 1 file changed, 1 insertion(+), 23 deletions(-) diff --git a/projects/Rockchip/kodi/appliance.xml b/projects/Rockchip/kodi/appliance.xml index 8c37b2d46c..31f6e9f58e 100644 --- a/projects/Rockchip/kodi/appliance.xml +++ b/projects/Rockchip/kodi/appliance.xml @@ -3,21 +3,15 @@
- - 0384002160060.00000pstd,0384002160059.94006pstd,0384002160050.00000pstd,0384002160030.00000pstd,0384002160029.97003pstd,0384002160025.00000pstd,0384002160024.00000pstd,0384002160023.97602pstd,0192001080060.00000pstd,0192001080059.94006pstd,0192001080050.00000pstd,0192001080030.00000pstd,0192001080029.97003pstd,0192001080024.00000pstd,0192001080023.97602pstd,0128000720060.00000pstd,0128000720059.94006pstd,0128000720050.00000pstd - false - - false - 3 true - + 2 false @@ -31,21 +25,5 @@ - - - - false - - - -
-
- - - - 2 - - -
From 6528f6683393434c0286dd94377831cdaf0d5586 Mon Sep 17 00:00:00 2001 From: Alex Bee Date: Sun, 17 Jan 2021 17:08:22 +0100 Subject: [PATCH 4/6] rockchip: kodi: add workaround for rendering sw-decoded content on mali4x0 GPUs Current upstream mesa has a shortcoming for YUV12 to XR24 conversion so that DRMPRIMEGLES conversion cannot be used (for details see https://gitlab.freedesktop.org/mesa/mesa/-/issues/4074) This adds a patch to kodi to not use this on lima GPUs and allow proper fallback to LinuxRendererGLES where shaders are used and the conversion is working. --- ...1-allow-sw-decoding-on-mali-4xx-gpus.patch | 44 +++++++++++++++++++ 1 file changed, 44 insertions(+) create mode 100644 projects/Rockchip/patches/kodi/0001-allow-sw-decoding-on-mali-4xx-gpus.patch diff --git a/projects/Rockchip/patches/kodi/0001-allow-sw-decoding-on-mali-4xx-gpus.patch b/projects/Rockchip/patches/kodi/0001-allow-sw-decoding-on-mali-4xx-gpus.patch new file mode 100644 index 0000000000..2bb6b0a8a3 --- /dev/null +++ b/projects/Rockchip/patches/kodi/0001-allow-sw-decoding-on-mali-4xx-gpus.patch @@ -0,0 +1,44 @@ +From 7479f183788ad47dc5ab74666808c29b7c272531 Mon Sep 17 00:00:00 2001 +From: Alex Bee +Date: Thu, 14 Jan 2021 23:51:20 +0100 +Subject: [PATCH] HACKOFF: DRMPRIMEGLES: avoid for lima due to broken + YU12->XR24 conversion + +Signed-off-by: Alex Bee +--- + xbmc/cores/VideoPlayer/VideoRenderers/BaseRenderer.cpp | 2 +- + .../VideoRenderers/HwDecRender/RendererDRMPRIMEGLES.cpp | 5 +++++ + 2 files changed, 6 insertions(+), 1 deletion(-) + +diff --git a/xbmc/cores/VideoPlayer/VideoRenderers/BaseRenderer.cpp b/xbmc/cores/VideoPlayer/VideoRenderers/BaseRenderer.cpp +index 8c78f1beac..241a307351 100644 +--- a/xbmc/cores/VideoPlayer/VideoRenderers/BaseRenderer.cpp ++++ b/xbmc/cores/VideoPlayer/VideoRenderers/BaseRenderer.cpp +@@ -329,7 +329,7 @@ EShaderFormat CBaseRenderer::GetShaderFormat() + { + EShaderFormat ret = SHADER_NONE; + +- if (m_format == AV_PIX_FMT_YUV420P) ++ if (m_format == AV_PIX_FMT_YUV420P || m_format == AV_PIX_FMT_DRM_PRIME) + ret = SHADER_YV12; + else if (m_format == AV_PIX_FMT_YUV420P9) + ret = SHADER_YV12_9; +diff --git a/xbmc/cores/VideoPlayer/VideoRenderers/HwDecRender/RendererDRMPRIMEGLES.cpp b/xbmc/cores/VideoPlayer/VideoRenderers/HwDecRender/RendererDRMPRIMEGLES.cpp +index c1d69bf381..d33b58a321 100644 +--- a/xbmc/cores/VideoPlayer/VideoRenderers/HwDecRender/RendererDRMPRIMEGLES.cpp ++++ b/xbmc/cores/VideoPlayer/VideoRenderers/HwDecRender/RendererDRMPRIMEGLES.cpp +@@ -59,6 +59,11 @@ CBaseRenderer* CRendererDRMPRIMEGLES::Create(CVideoBuffer* buffer) + if (!winSystemEGL) + return nullptr; + ++ if (CServiceBroker::GetRenderSystem()->GetRenderVendor() == "lima") ++ { ++ CLog::LogF(LOGDEBUG, "Not using DRMPRIMEGLES due to broken mesa lima driver."); ++ return nullptr; ++ } + CEGLImage image{winSystemEGL->GetEGLDisplay()}; + if (!image.SupportsFormatAndModifier(format, modifier)) + return nullptr; +-- +2.25.1 + From 07446da50615b1de14f96589ea28eac5de8a7ec0 Mon Sep 17 00:00:00 2001 From: Alex Bee Date: Sun, 17 Jan 2021 17:16:58 +0100 Subject: [PATCH 5/6] rockchip: enable HEVC (8/10 bit) and VP9 (8 bit) decoding on RK3328 and RK3399 This should really be seen as WIP, since not all (HEVC) respectively very few (VP9) samples are decoded / rendered correctly. --- ...ffmpeg-0001-v4l2-request-rkvdec-hevc.patch | 123 + .../linux-2000-v4l-wip-rkvdec-vp9.patch | 3176 +++++++++++++++++ .../linux-2001-v4l-wip-rkvdec-hevc.patch | 3087 ++++++++++++++++ 3 files changed, 6386 insertions(+) create mode 100644 projects/Rockchip/patches/ffmpeg/ffmpeg-0001-v4l2-request-rkvdec-hevc.patch create mode 100644 projects/Rockchip/patches/linux/default/linux-2000-v4l-wip-rkvdec-vp9.patch create mode 100644 projects/Rockchip/patches/linux/default/linux-2001-v4l-wip-rkvdec-hevc.patch diff --git a/projects/Rockchip/patches/ffmpeg/ffmpeg-0001-v4l2-request-rkvdec-hevc.patch b/projects/Rockchip/patches/ffmpeg/ffmpeg-0001-v4l2-request-rkvdec-hevc.patch new file mode 100644 index 0000000000..6853d41ff6 --- /dev/null +++ b/projects/Rockchip/patches/ffmpeg/ffmpeg-0001-v4l2-request-rkvdec-hevc.patch @@ -0,0 +1,123 @@ +From 5e9575a822a94139bdcfe6a7fa78e4ef771ccb39 Mon Sep 17 00:00:00 2001 +From: Jonas Karlman +Date: Wed, 13 May 2020 22:51:21 +0000 +Subject: [PATCH] WIP: hevc rkvdec fields + +Signed-off-by: Jonas Karlman +--- + libavcodec/hevc-ctrls.h | 17 +++++++++++++---- + libavcodec/v4l2_request_hevc.c | 12 ++++++++++++ + 2 files changed, 25 insertions(+), 4 deletions(-) + +diff --git a/libavcodec/hevc-ctrls.h b/libavcodec/hevc-ctrls.h +index d1b094c8aaeb..b33e1a8141e1 100644 +--- a/libavcodec/hevc-ctrls.h ++++ b/libavcodec/hevc-ctrls.h +@@ -56,6 +56,9 @@ enum v4l2_mpeg_video_hevc_start_code { + /* The controls are not stable at the moment and will likely be reworked. */ + struct v4l2_ctrl_hevc_sps { + /* ISO/IEC 23008-2, ITU-T Rec. H.265: Sequence parameter set */ ++ __u8 video_parameter_set_id; ++ __u8 seq_parameter_set_id; ++ __u8 chroma_format_idc; + __u16 pic_width_in_luma_samples; + __u16 pic_height_in_luma_samples; + __u8 bit_depth_luma_minus8; +@@ -76,9 +79,9 @@ struct v4l2_ctrl_hevc_sps { + __u8 log2_diff_max_min_pcm_luma_coding_block_size; + __u8 num_short_term_ref_pic_sets; + __u8 num_long_term_ref_pics_sps; +- __u8 chroma_format_idc; + +- __u8 padding; ++ __u8 num_slices; ++ __u8 padding[6]; + + __u64 flags; + }; +@@ -105,7 +108,10 @@ struct v4l2_ctrl_hevc_sps { + + struct v4l2_ctrl_hevc_pps { + /* ISO/IEC 23008-2, ITU-T Rec. H.265: Picture parameter set */ ++ __u8 pic_parameter_set_id; + __u8 num_extra_slice_header_bits; ++ __u8 num_ref_idx_l0_default_active_minus1; ++ __u8 num_ref_idx_l1_default_active_minus1; + __s8 init_qp_minus26; + __u8 diff_cu_qp_delta_depth; + __s8 pps_cb_qp_offset; +@@ -118,7 +124,7 @@ struct v4l2_ctrl_hevc_pps { + __s8 pps_tc_offset_div2; + __u8 log2_parallel_merge_level_minus2; + +- __u8 padding[4]; ++ __u8 padding; + __u64 flags; + }; + +@@ -204,7 +210,10 @@ struct v4l2_ctrl_hevc_slice_params { + __u8 num_rps_poc_st_curr_after; + __u8 num_rps_poc_lt_curr; + +- __u8 padding; ++ __u16 short_term_ref_pic_set_size; ++ __u16 long_term_ref_pic_set_size; ++ ++ __u8 padding[5]; + + __u32 entry_point_offset_minus1[256]; + +diff --git a/libavcodec/v4l2_request_hevc.c b/libavcodec/v4l2_request_hevc.c +index 7e77c83e4e4b..9c6916bcb453 100644 +--- a/libavcodec/v4l2_request_hevc.c ++++ b/libavcodec/v4l2_request_hevc.c +@@ -169,6 +169,9 @@ static void v4l2_request_hevc_fill_slice_params(const HEVCContext *h, + .num_rps_poc_st_curr_before = h->rps[ST_CURR_BEF].nb_refs, + .num_rps_poc_st_curr_after = h->rps[ST_CURR_AFT].nb_refs, + .num_rps_poc_lt_curr = h->rps[LT_CURR].nb_refs, ++ ++ .short_term_ref_pic_set_size = sh->short_term_ref_pic_set_size, ++ .long_term_ref_pic_set_size = sh->long_term_ref_pic_set_size, + }; + + if (sh->slice_sample_adaptive_offset_flag[0]) +@@ -239,9 +242,12 @@ static void v4l2_request_hevc_fill_slice_params(const HEVCContext *h, + static void fill_sps(struct v4l2_ctrl_hevc_sps *ctrl, const HEVCContext *h) + { + const HEVCSPS *sps = h->ps.sps; ++ const HEVCPPS *pps = h->ps.pps; + + /* ISO/IEC 23008-2, ITU-T Rec. H.265: Sequence parameter set */ + *ctrl = (struct v4l2_ctrl_hevc_sps) { ++ .video_parameter_set_id = sps->vps_id, ++ .seq_parameter_set_id = pps->sps_id, + .chroma_format_idc = sps->chroma_format_idc, + .pic_width_in_luma_samples = sps->width, + .pic_height_in_luma_samples = sps->height, +@@ -300,6 +306,7 @@ static int v4l2_request_hevc_start_frame(AVCodecContext *avctx, + const HEVCContext *h = avctx->priv_data; + const HEVCSPS *sps = h->ps.sps; + const HEVCPPS *pps = h->ps.pps; ++ const SliceHeader *sh = &h->sh; + const ScalingList *sl = pps->scaling_list_data_present_flag ? + &pps->scaling_list : + sps->scaling_list_enable_flag ? +@@ -326,6 +333,9 @@ static int v4l2_request_hevc_start_frame(AVCodecContext *avctx, + + /* ISO/IEC 23008-2, ITU-T Rec. H.265: Picture parameter set */ + controls->pps = (struct v4l2_ctrl_hevc_pps) { ++ .pic_parameter_set_id = sh->pps_id, ++ .num_ref_idx_l0_default_active_minus1 = pps->num_ref_idx_l0_default_active - 1, ++ .num_ref_idx_l1_default_active_minus1 = pps->num_ref_idx_l1_default_active - 1, + .num_extra_slice_header_bits = pps->num_extra_slice_header_bits, + .init_qp_minus26 = pps->pic_init_qp_minus26, + .diff_cu_qp_delta_depth = pps->diff_cu_qp_delta_depth, +@@ -442,6 +452,8 @@ static int v4l2_request_hevc_queue_decode(AVCodecContext *avctx, int last_slice) + if (ctx->decode_mode == V4L2_MPEG_VIDEO_HEVC_DECODE_MODE_SLICE_BASED) + return ff_v4l2_request_decode_slice(avctx, h->ref->frame, control, FF_ARRAY_ELEMS(control), controls->first_slice, last_slice); + ++ controls->sps.num_slices = controls->num_slices; ++ + return ff_v4l2_request_decode_frame(avctx, h->ref->frame, control, FF_ARRAY_ELEMS(control)); + } + diff --git a/projects/Rockchip/patches/linux/default/linux-2000-v4l-wip-rkvdec-vp9.patch b/projects/Rockchip/patches/linux/default/linux-2000-v4l-wip-rkvdec-vp9.patch new file mode 100644 index 0000000000..55506c21fc --- /dev/null +++ b/projects/Rockchip/patches/linux/default/linux-2000-v4l-wip-rkvdec-vp9.patch @@ -0,0 +1,3176 @@ +From 829dd9c66a1664438878402cedc301d547e061fc Mon Sep 17 00:00:00 2001 +From: Ezequiel Garcia +Date: Mon, 2 Nov 2020 21:05:49 +0200 +Subject: [PATCH] media: rkvdec: Fix .buf_prepare + +The driver should only set the payload on .buf_prepare if the +buffer is CAPTURE type. If an OUTPUT buffer has a zero bytesused +set by userspace then v4l2-core will set it to buffer length. + +Fixes: cd33c830448ba ("media: rkvdec: Add the rkvdec driver") +Signed-off-by: Ezequiel Garcia +Signed-off-by: Adrian Ratiu +--- + drivers/staging/media/rkvdec/rkvdec.c | 10 +++++++++- + 1 file changed, 9 insertions(+), 1 deletion(-) + +diff --git a/drivers/staging/media/rkvdec/rkvdec.c b/drivers/staging/media/rkvdec/rkvdec.c +index 8c2ff05e01f7..86975cd4ebd0 100644 +--- a/drivers/staging/media/rkvdec/rkvdec.c ++++ b/drivers/staging/media/rkvdec/rkvdec.c +@@ -543,7 +543,15 @@ static int rkvdec_buf_prepare(struct vb2_buffer *vb) + if (vb2_plane_size(vb, i) < sizeimage) + return -EINVAL; + } +- vb2_set_plane_payload(vb, 0, f->fmt.pix_mp.plane_fmt[0].sizeimage); ++ ++ /* ++ * Buffer bytesused is written by driver for CAPTURE buffers. ++ * (if userspace passes 0 bytesused for OUTPUT buffers, v4l2-core sets ++ * it to buffer length). ++ */ ++ if (!V4L2_TYPE_IS_OUTPUT(vq->type)) ++ vb2_set_plane_payload(vb, 0, f->fmt.pix_mp.plane_fmt[0].sizeimage); ++ + return 0; + } + + +From c7e78a632fbf3da6b677114c46943211ccb77956 Mon Sep 17 00:00:00 2001 +From: Boris Brezillon +Date: Mon, 2 Nov 2020 21:05:50 +0200 +Subject: [PATCH] media: uapi: Add VP9 stateless decoder controls + +Add the VP9 stateless decoder controls plus the documentation that goes +with it. + +Signed-off-by: Boris Brezillon +Signed-off-by: Ezequiel Garcia +Signed-off-by: Adrian Ratiu +--- + .../userspace-api/media/v4l/biblio.rst | 10 + + .../media/v4l/ext-ctrls-codec.rst | 550 ++++++++++++++++++ + drivers/media/v4l2-core/v4l2-ctrls.c | 239 ++++++++ + drivers/media/v4l2-core/v4l2-ioctl.c | 1 + + include/media/v4l2-ctrls.h | 5 + + include/media/vp9-ctrls.h | 486 ++++++++++++++++ + 6 files changed, 1291 insertions(+) + create mode 100644 include/media/vp9-ctrls.h + +diff --git a/Documentation/userspace-api/media/v4l/biblio.rst b/Documentation/userspace-api/media/v4l/biblio.rst +index 7869b6f6ff72..6b4a83b053f5 100644 +--- a/Documentation/userspace-api/media/v4l/biblio.rst ++++ b/Documentation/userspace-api/media/v4l/biblio.rst +@@ -407,3 +407,13 @@ VP8 + :title: RFC 6386: "VP8 Data Format and Decoding Guide" + + :author: J. Bankoski et al. ++ ++.. _vp9: ++ ++VP9 ++=== ++ ++ ++:title: VP9 Bitstream & Decoding Process Specification ++ ++:author: Adrian Grange (Google), Peter de Rivaz (Argon Design), Jonathan Hunt (Argon Design) +diff --git a/Documentation/userspace-api/media/v4l/ext-ctrls-codec.rst b/Documentation/userspace-api/media/v4l/ext-ctrls-codec.rst +index ce728c757eaf..456488f2b5ca 100644 +--- a/Documentation/userspace-api/media/v4l/ext-ctrls-codec.rst ++++ b/Documentation/userspace-api/media/v4l/ext-ctrls-codec.rst +@@ -2730,6 +2730,556 @@ enum v4l2_mpeg_video_h264_hierarchical_coding_type - + - ``padding[3]`` + - Applications and drivers must set this to zero. + ++.. _v4l2-mpeg-vp9: ++ ++``V4L2_CID_MPEG_VIDEO_VP9_FRAME_CONTEXT(0..3) (struct)`` ++ Stores VP9 probabilities attached to a specific frame context. The VP9 ++ specification allows using a maximum of 4 contexts. Each frame being ++ decoded refers to one of those context. See section '7.1.2 Refresh ++ probs semantics' section of :ref:`vp9` for more details about these ++ contexts. ++ ++ This control is bi-directional: ++ ++ * all 4 contexts must be initialized by userspace just after the ++ stream is started and before the first decoding request is submitted. ++ * the referenced context might be read by the kernel when a decoding ++ request is submitted, and will be updated after the decoder is done ++ decoding the frame if the `V4L2_VP9_FRAME_FLAG_REFRESH_FRAME_CTX` flag ++ is set. ++ * contexts will be read back by user space before each decoding request ++ to retrieve the updated probabilities. ++ * userspace will re-initialize the context to their default values when ++ a reset context is required. ++ ++ .. note:: ++ ++ This compound control is not yet part of the public kernel API and ++ it is expected to change. ++ ++.. c:type:: v4l2_ctrl_vp9_frame_ctx ++ ++.. cssclass:: longtable ++ ++.. tabularcolumns:: |p{5.8cm}|p{4.8cm}|p{6.6cm}| ++ ++.. flat-table:: struct v4l2_ctrl_vp9_frame_ctx ++ :header-rows: 0 ++ :stub-columns: 0 ++ :widths: 1 1 2 ++ ++ * - struct :c:type:`v4l2_vp9_probabilities` ++ - ``probs`` ++ - Structure with VP9 probabilities attached to the context. ++ ++.. c:type:: v4l2_vp9_probabilities ++ ++.. cssclass:: longtable ++ ++.. tabularcolumns:: |p{1.5cm}|p{6.3cm}|p{9.4cm}| ++ ++.. flat-table:: struct v4l2_vp9_probabilities ++ :header-rows: 0 ++ :stub-columns: 0 ++ :widths: 1 1 2 ++ ++ * - __u8 ++ - ``tx8[2][1]`` ++ - TX 8x8 probabilities. ++ * - __u8 ++ - ``tx16[2][2]`` ++ - TX 16x16 probabilities. ++ * - __u8 ++ - ``tx32[2][3]`` ++ - TX 32x32 probabilities. ++ * - __u8 ++ - ``coef[4][2][2][6][6][3]`` ++ - Coefficient probabilities. ++ * - __u8 ++ - ``skip[3]`` ++ - Skip probabilities. ++ * - __u8 ++ - ``inter_mode[7][3]`` ++ - Inter prediction mode probabilities. ++ * - __u8 ++ - ``interp_filter[4][2]`` ++ - Interpolation filter probabilities. ++ * - __u8 ++ - ``is_inter[4]`` ++ - Is inter-block probabilities. ++ * - __u8 ++ - ``comp_mode[5]`` ++ - Compound prediction mode probabilities. ++ * - __u8 ++ - ``single_ref[5][2]`` ++ - Single reference probabilities. ++ * - __u8 ++ - ``comp_mode[5]`` ++ - Compound reference probabilities. ++ * - __u8 ++ - ``y_mode[4][9]`` ++ - Y prediction mode probabilities. ++ * - __u8 ++ - ``uv_mode[10][9]`` ++ - UV prediction mode probabilities. ++ * - __u8 ++ - ``partition[16][3]`` ++ - Partition probabilities. ++ * - __u8 ++ - ``mv.joint[3]`` ++ - Motion vector joint probabilities. ++ * - __u8 ++ - ``mv.sign[2]`` ++ - Motion vector sign probabilities. ++ * - __u8 ++ - ``mv.class[2][10]`` ++ - Motion vector class probabilities. ++ * - __u8 ++ - ``mv.class0_bit[2]`` ++ - Motion vector class0 bit probabilities. ++ * - __u8 ++ - ``mv.bits[2][10]`` ++ - Motion vector bits probabilities. ++ * - __u8 ++ - ``mv.class0_fr[2][2][3]`` ++ - Motion vector class0 fractional bit probabilities. ++ * - __u8 ++ - ``mv.fr[2][3]`` ++ - Motion vector fractional bit probabilities. ++ * - __u8 ++ - ``mv.class0_hp[2]`` ++ - Motion vector class0 high precision fractional bit probabilities. ++ * - __u8 ++ - ``mv.hp[2]`` ++ - Motion vector high precision fractional bit probabilities. ++ ++``V4L2_CID_MPEG_VIDEO_VP9_FRAME_DECODE_PARAMS (struct)`` ++ Specifies the frame parameters for the associated VP9 frame decode request. ++ This includes the necessary parameters for configuring a stateless hardware ++ decoding pipeline for VP9. The bitstream parameters are defined according ++ to :ref:`vp9`. ++ ++ .. note:: ++ ++ This compound control is not yet part of the public kernel API and ++ it is expected to change. ++ ++.. c:type:: v4l2_ctrl_vp9_frame_decode_params ++ ++.. cssclass:: longtable ++ ++.. tabularcolumns:: |p{1.5cm}|p{6.3cm}|p{9.4cm}| ++ ++.. flat-table:: struct v4l2_ctrl_vp9_frame_decode_params ++ :header-rows: 0 ++ :stub-columns: 0 ++ :widths: 1 1 2 ++ ++ * - __u32 ++ - ``flags`` ++ - Combination of V4L2_VP9_FRAME_FLAG_* flags. See ++ :c:type:`v4l2_vp9_frame_flags`. ++ * - __u16 ++ - ``compressed_header_size`` ++ - Compressed header size in bytes. ++ * - __u16 ++ - ``uncompressed_header_size`` ++ - Uncompressed header size in bytes. ++ * - __u8 ++ - ``profile`` ++ - VP9 profile. Can be 0, 1, 2 or 3. ++ * - __u8 ++ - ``reset_frame_context`` ++ - Frame context that should be used/updated when decoding the frame. ++ * - __u8 ++ - ``bit_depth`` ++ - Component depth in bits. Must be 8 for profile 0 and 1. Must 10 or 12 ++ for profile 2 and 3. ++ * - __u8 ++ - ``interpolation_filter`` ++ - Specifies the filter selection used for performing inter prediction. See ++ :c:type:`v4l2_vp9_interpolation_filter`. ++ * - __u8 ++ - ``tile_cols_log2`` ++ - Specifies the base 2 logarithm of the width of each tile (where the ++ width is measured in units of 8x8 blocks). Shall be less than or equal ++ to 6. ++ * - __u8 ++ - ``tile_rows_log2`` ++ - Specifies the base 2 logarithm of the height of each tile (where the ++ height is measured in units of 8x8 blocks) ++ * - __u8 ++ - ``tx_mode`` ++ - Specifies the TX mode. See :c:type:`v4l2_vp9_tx_mode`. ++ * - __u8 ++ - ``reference_mode`` ++ - Specifies the type of inter prediction to be used. See ++ :c:type:`v4l2_vp9_reference_mode`. ++ * - __u8 ++ - ``padding[7]`` ++ - Needed to make this struct 64 bit aligned. Shall be filled with zeroes. ++ * - __u16 ++ - ``frame_width_minus_1`` ++ - Add 1 to get the frame width expressed in pixels. ++ * - __u16 ++ - ``frame_height_minus_1`` ++ - Add 1 to get the frame height expressed in pixels. ++ * - __u16 ++ - ``frame_width_minus_1`` ++ - Add 1 to get the expected render width expressed in pixels. This is ++ not used during the decoding process but might be used by HW scalers to ++ prepare a frame that's ready for scanout. ++ * - __u16 ++ - frame_height_minus_1 ++ - Add 1 to get the expected render height expressed in pixels. This is ++ not used during the decoding process but might be used by HW scalers to ++ prepare a frame that's ready for scanout. ++ * - __u64 ++ - ``refs[3]`` ++ - Array of reference frame timestamps. ++ * - struct :c:type:`v4l2_vp9_loop_filter` ++ - ``lf`` ++ - Loop filter parameters. See struct :c:type:`v4l2_vp9_loop_filter`. ++ * - struct :c:type:`v4l2_vp9_quantization` ++ - ``quant`` ++ - Quantization parameters. See :c:type:`v4l2_vp9_quantization`. ++ * - struct :c:type:`v4l2_vp9_segmentation` ++ - ``seg`` ++ - Segmentation parameters. See :c:type:`v4l2_vp9_segmentation`. ++ * - struct :c:type:`v4l2_vp9_probabilities` ++ - ``probs`` ++ - Probabilities. See :c:type:`v4l2_vp9_probabilities`. ++ ++.. c:type:: v4l2_vp9_frame_flags ++ ++.. cssclass:: longtable ++ ++.. tabularcolumns:: |p{1.5cm}|p{6.3cm}|p{9.4cm}| ++ ++.. flat-table:: enum v4l2_vp9_frame_flags ++ :header-rows: 0 ++ :stub-columns: 0 ++ :widths: 1 2 ++ ++ * - ``V4L2_VP9_FRAME_FLAG_KEY_FRAME`` ++ - The frame is a key frame. ++ * - ``V4L2_VP9_FRAME_FLAG_SHOW_FRAME`` ++ - The frame should be displayed. ++ * - ``V4L2_VP9_FRAME_FLAG_ERROR_RESILIENT`` ++ - The decoding should be error resilient. ++ * - ``V4L2_VP9_FRAME_FLAG_INTRA_ONLY`` ++ - The frame does not reference other frames. ++ * - ``V4L2_VP9_FRAME_FLAG_ALLOW_HIGH_PREC_MV`` ++ - the frame might can high precision motion vectors. ++ * - ``V4L2_VP9_FRAME_FLAG_REFRESH_FRAME_CTX`` ++ - Frame context should be updated after decoding. ++ * - ``V4L2_VP9_FRAME_FLAG_PARALLEL_DEC_MODE`` ++ - Parallel decoding is used. ++ * - ``V4L2_VP9_FRAME_FLAG_X_SUBSAMPLING`` ++ - Vertical subsampling is enabled. ++ * - ``V4L2_VP9_FRAME_FLAG_Y_SUBSAMPLING`` ++ - Horizontal subsampling is enabled. ++ * - ``V4L2_VP9_FRAME_FLAG_COLOR_RANGE_FULL_SWING`` ++ - The full UV range is used. ++ ++.. c:type:: v4l2_vp9_ref_id ++ ++.. cssclass:: longtable ++ ++.. tabularcolumns:: |p{1.5cm}|p{6.3cm}|p{9.4cm}| ++ ++.. flat-table:: enum v4l2_vp9_ref_id ++ :header-rows: 0 ++ :stub-columns: 0 ++ :widths: 1 2 ++ ++ * - ``V4L2_REF_ID_LAST`` ++ - Last reference frame. ++ * - ``V4L2_REF_ID_GOLDEN`` ++ - Golden reference frame. ++ * - ``V4L2_REF_ID_ALTREF`` ++ - Alternative reference frame. ++ * - ``V4L2_REF_ID_CNT`` ++ - Number of reference frames. ++ ++.. c:type:: v4l2_vp9_tx_mode ++ ++.. cssclass:: longtable ++ ++.. tabularcolumns:: |p{1.5cm}|p{6.3cm}|p{9.4cm}| ++ ++.. flat-table:: enum v4l2_vp9_tx_mode ++ :header-rows: 0 ++ :stub-columns: 0 ++ :widths: 1 2 ++ ++ * - ``V4L2_VP9_TX_MODE_ONLY_4X4`` ++ - Transform size is 4x4. ++ * - ``V4L2_VP9_TX_MODE_ALLOW_8X8`` ++ - Transform size can be up to 8x8. ++ * - ``V4L2_VP9_TX_MODE_ALLOW_16X16`` ++ - Transform size can be up to 16x16. ++ * - ``V4L2_VP9_TX_MODE_ALLOW_32X32`` ++ - transform size can be up to 32x32. ++ * - ``V4L2_VP9_TX_MODE_SELECT`` ++ - Bitstream contains transform size for each block. ++ ++.. c:type:: v4l2_vp9_reference_mode ++ ++.. cssclass:: longtable ++ ++.. tabularcolumns:: |p{1.5cm}|p{6.3cm}|p{9.4cm}| ++ ++.. flat-table:: enum v4l2_vp9_reference_mode ++ :header-rows: 0 ++ :stub-columns: 0 ++ :widths: 1 2 ++ ++ * - ``V4L2_VP9_REF_MODE_SINGLE`` ++ - Indicates that all the inter blocks use only a single reference frame ++ to generate motion compensated prediction. ++ * - ``V4L2_VP9_REF_MODE_COMPOUND`` ++ - Requires all the inter blocks to use compound mode. Single reference ++ frame prediction is not allowed. ++ * - ``V4L2_VP9_REF_MODE_SELECT`` ++ - Allows each individual inter block to select between single and ++ compound prediction modes. ++ ++.. c:type:: v4l2_vp9_interpolation_filter ++ ++.. cssclass:: longtable ++ ++.. tabularcolumns:: |p{1.5cm}|p{6.3cm}|p{9.4cm}| ++ ++.. flat-table:: enum v4l2_vp9_interpolation_filter ++ :header-rows: 0 ++ :stub-columns: 0 ++ :widths: 1 2 ++ ++ * - ``V4L2_VP9_INTERP_FILTER_8TAP`` ++ - Height tap filter. ++ * - ``V4L2_VP9_INTERP_FILTER_8TAP_SMOOTH`` ++ - Height tap smooth filter. ++ * - ``V4L2_VP9_INTERP_FILTER_8TAP_SHARP`` ++ - Height tap sharp filter. ++ * - ``V4L2_VP9_INTERP_FILTER_BILINEAR`` ++ - Bilinear filter. ++ * - ``V4L2_VP9_INTERP_FILTER_SWITCHABLE`` ++ - Filter selection is signaled at the block level. ++ ++.. c:type:: v4l2_vp9_reset_frame_context ++ ++.. cssclass:: longtable ++ ++.. tabularcolumns:: |p{1.5cm}|p{6.3cm}|p{9.4cm}| ++ ++.. flat-table:: enum v4l2_vp9_reset_frame_context ++ :header-rows: 0 ++ :stub-columns: 0 ++ :widths: 1 2 ++ ++ * - ``V4L2_VP9_RESET_FRAME_CTX_NONE`` ++ - Do not reset any frame context. ++ * - ``V4L2_VP9_RESET_FRAME_CTX_SPEC`` ++ - Reset the frame context pointed by ++ :c:type:`v4l2_ctrl_vp9_frame_decode_params`.frame_context_idx. ++ * - ``V4L2_VP9_RESET_FRAME_CTX_ALL`` ++ - Reset all frame contexts. ++ ++.. c:type:: v4l2_vp9_intra_prediction_mode ++ ++.. cssclass:: longtable ++ ++.. tabularcolumns:: |p{1.5cm}|p{6.3cm}|p{9.4cm}| ++ ++.. flat-table:: enum v4l2_vp9_intra_prediction_mode ++ :header-rows: 0 ++ :stub-columns: 0 ++ :widths: 1 2 ++ ++ * - ``V4L2_VP9_INTRA_PRED_DC`` ++ - DC intra prediction. ++ * - ``V4L2_VP9_INTRA_PRED_MODE_V`` ++ - Vertical intra prediction. ++ * - ``V4L2_VP9_INTRA_PRED_MODE_H`` ++ - Horizontal intra prediction. ++ * - ``V4L2_VP9_INTRA_PRED_MODE_D45`` ++ - D45 intra prediction. ++ * - ``V4L2_VP9_INTRA_PRED_MODE_D135`` ++ - D135 intra prediction. ++ * - ``V4L2_VP9_INTRA_PRED_MODE_D117`` ++ - D117 intra prediction. ++ * - ``V4L2_VP9_INTRA_PRED_MODE_D153`` ++ - D153 intra prediction. ++ * - ``V4L2_VP9_INTRA_PRED_MODE_D207`` ++ - D207 intra prediction. ++ * - ``V4L2_VP9_INTRA_PRED_MODE_D63`` ++ - D63 intra prediction. ++ * - ``V4L2_VP9_INTRA_PRED_MODE_TM`` ++ - True motion intra prediction. ++ ++.. c:type:: v4l2_vp9_segmentation ++ ++.. cssclass:: longtable ++ ++.. tabularcolumns:: |p{1.5cm}|p{6.3cm}|p{9.4cm}| ++ ++.. flat-table:: struct v4l2_vp9_segmentation ++ :header-rows: 0 ++ :stub-columns: 0 ++ :widths: 1 1 2 ++ ++ * - __u8 ++ - ``flags`` ++ - Combination of V4L2_VP9_SEGMENTATION_FLAG_* flags. See ++ :c:type:`v4l2_vp9_segmentation_flags`. ++ * - __u8 ++ - ``tree_probs[7]`` ++ - Specifies the probability values to be used when decoding a Segment-ID. ++ See '5.15. Segmentation map' section of :ref:`vp9` for more details. ++ * - __u8 ++ - ``pred_prob[3]`` ++ - Specifies the probability values to be used when decoding a ++ Predicted-Segment-ID. See '6.4.14. Get segment id syntax' ++ section of :ref:`vp9` for more details. ++ * - __u8 ++ - ``padding[5]`` ++ - Used to align this struct on 64 bit. Shall be filled with zeroes. ++ * - __u8 ++ - ``feature_enabled[8]`` ++ - Bitmask defining which features are enabled in each segment. ++ * - __u8 ++ - ``feature_data[8][4]`` ++ - Data attached to each feature. Data entry is only valid if the feature ++ is enabled. ++ ++.. c:type:: v4l2_vp9_segment_feature ++ ++.. cssclass:: longtable ++ ++.. tabularcolumns:: |p{1.5cm}|p{6.3cm}|p{9.4cm}| ++ ++.. flat-table:: enum v4l2_vp9_segment_feature ++ :header-rows: 0 ++ :stub-columns: 0 ++ :widths: 1 2 ++ ++ * - ``V4L2_VP9_SEGMENT_FEATURE_QP_DELTA`` ++ - QP delta segment feature. ++ * - ``V4L2_VP9_SEGMENT_FEATURE_LF`` ++ - Loop filter segment feature. ++ * - ``V4L2_VP9_SEGMENT_FEATURE_REF_FRAME`` ++ - Reference frame segment feature. ++ * - ``V4L2_VP9_SEGMENT_FEATURE_SKIP`` ++ - Skip segment feature. ++ * - ``V4L2_VP9_SEGMENT_FEATURE_CNT`` ++ - Number of segment features. ++ ++.. c:type:: v4l2_vp9_segmentation_flags ++ ++.. cssclass:: longtable ++ ++.. tabularcolumns:: |p{1.5cm}|p{6.3cm}|p{9.4cm}| ++ ++.. flat-table:: enum v4l2_vp9_segmentation_flags ++ :header-rows: 0 ++ :stub-columns: 0 ++ :widths: 1 2 ++ ++ * - ``V4L2_VP9_SEGMENTATION_FLAG_ENABLED`` ++ - Indicates that this frame makes use of the segmentation tool. ++ * - ``V4L2_VP9_SEGMENTATION_FLAG_UPDATE_MAP`` ++ - Indicates that the segmentation map should be updated during the ++ decoding of this frame. ++ * - ``V4L2_VP9_SEGMENTATION_FLAG_TEMPORAL_UPDATE`` ++ - Indicates that the updates to the segmentation map are coded ++ relative to the existing segmentation map. ++ * - ``V4L2_VP9_SEGMENTATION_FLAG_UPDATE_DATA`` ++ - Indicates that new parameters are about to be specified for each ++ segment. ++ * - ``V4L2_VP9_SEGMENTATION_FLAG_ABS_OR_DELTA_UPDATE`` ++ - Indicates that the segmentation parameters represent the actual values ++ to be used. ++ ++.. c:type:: v4l2_vp9_quantization ++ ++.. cssclass:: longtable ++ ++.. tabularcolumns:: |p{1.5cm}|p{6.3cm}|p{9.4cm}| ++ ++.. flat-table:: struct v4l2_vp9_quantization ++ :header-rows: 0 ++ :stub-columns: 0 ++ :widths: 1 1 2 ++ ++ * - __u8 ++ - ``base_q_idx`` ++ - Indicates the base frame qindex. ++ * - __s8 ++ - ``delta_q_y_dc`` ++ - Indicates the Y DC quantizer relative to base_q_idx. ++ * - __s8 ++ - ``delta_q_uv_dc`` ++ - Indicates the UV DC quantizer relative to base_q_idx. ++ * - __s8 ++ - ``delta_q_uv_ac`` ++ - Indicates the UV AC quantizer relative to base_q_idx. ++ * - __u8 ++ - ``padding[4]`` ++ - Padding bytes used to align this struct on 64 bit. Must be set to 0. ++ ++.. c:type:: v4l2_vp9_loop_filter ++ ++.. cssclass:: longtable ++ ++.. tabularcolumns:: |p{1.5cm}|p{6.3cm}|p{9.4cm}| ++ ++.. flat-table:: struct v4l2_vp9_loop_filter ++ :header-rows: 0 ++ :stub-columns: 0 ++ :widths: 1 1 2 ++ ++ * - __u8 ++ - ``flags`` ++ - Combination of V4L2_VP9_LOOP_FILTER_FLAG_* flags. ++ See :c:type:`v4l2_vp9_loop_filter_flags`. ++ * - __u8 ++ - ``level`` ++ - Indicates the loop filter strength. ++ * - __u8 ++ - ``sharpness`` ++ - Indicates the sharpness level. ++ * - __s8 ++ - ``ref_deltas[4]`` ++ - Contains the adjustment needed for the filter level based on the chosen ++ reference frame. ++ * - __s8 ++ - ``mode_deltas[2]`` ++ - Contains the adjustment needed for the filter level based on the chosen ++ mode ++ * - __u8 ++ - ``level_lookup[8][4][2]`` ++ - Level lookup table. ++ ++ ++.. c:type:: v4l2_vp9_loop_filter_flags ++ ++.. cssclass:: longtable ++ ++.. tabularcolumns:: |p{1.5cm}|p{6.3cm}|p{9.4cm}| ++ ++.. flat-table:: enum v4l2_vp9_loop_filter_flags ++ :header-rows: 0 ++ :stub-columns: 0 ++ :widths: 1 2 ++ ++ * - ``V4L2_VP9_LOOP_FILTER_FLAG_DELTA_ENABLED`` ++ - When set, the filter level depends on the mode and reference frame used ++ to predict a block. ++ * - ``V4L2_VP9_LOOP_FILTER_FLAG_DELTA_UPDATE`` ++ - When set, the bitstream contains additional syntax elements that ++ specify which mode and reference frame deltas are to be updated. ++ + .. raw:: latex + + \normalsize +diff --git a/drivers/media/v4l2-core/v4l2-ctrls.c b/drivers/media/v4l2-core/v4l2-ctrls.c +index bd7f330c941c..a88e962ac8a1 100644 +--- a/drivers/media/v4l2-core/v4l2-ctrls.c ++++ b/drivers/media/v4l2-core/v4l2-ctrls.c +@@ -971,6 +971,11 @@ const char *v4l2_ctrl_get_name(u32 id) + case V4L2_CID_MPEG_VIDEO_VP9_PROFILE: return "VP9 Profile"; + case V4L2_CID_MPEG_VIDEO_VP9_LEVEL: return "VP9 Level"; + case V4L2_CID_MPEG_VIDEO_VP8_FRAME_HEADER: return "VP8 Frame Header"; ++ case V4L2_CID_MPEG_VIDEO_VP9_FRAME_DECODE_PARAMS: return "VP9 Frame Decode Parameters"; ++ case V4L2_CID_MPEG_VIDEO_VP9_FRAME_CONTEXT(0): return "VP9 Frame Context 0"; ++ case V4L2_CID_MPEG_VIDEO_VP9_FRAME_CONTEXT(1): return "VP9 Frame Context 1"; ++ case V4L2_CID_MPEG_VIDEO_VP9_FRAME_CONTEXT(2): return "VP9 Frame Context 2"; ++ case V4L2_CID_MPEG_VIDEO_VP9_FRAME_CONTEXT(3): return "VP9 Frame Context 3"; + + /* HEVC controls */ + case V4L2_CID_MPEG_VIDEO_HEVC_I_FRAME_QP: return "HEVC I-Frame QP Value"; +@@ -1452,6 +1457,15 @@ void v4l2_ctrl_fill(u32 id, const char **name, enum v4l2_ctrl_type *type, + case V4L2_CID_MPEG_VIDEO_VP8_FRAME_HEADER: + *type = V4L2_CTRL_TYPE_VP8_FRAME_HEADER; + break; ++ case V4L2_CID_MPEG_VIDEO_VP9_FRAME_DECODE_PARAMS: ++ *type = V4L2_CTRL_TYPE_VP9_FRAME_DECODE_PARAMS; ++ break; ++ case V4L2_CID_MPEG_VIDEO_VP9_FRAME_CONTEXT(0): ++ case V4L2_CID_MPEG_VIDEO_VP9_FRAME_CONTEXT(1): ++ case V4L2_CID_MPEG_VIDEO_VP9_FRAME_CONTEXT(2): ++ case V4L2_CID_MPEG_VIDEO_VP9_FRAME_CONTEXT(3): ++ *type = V4L2_CTRL_TYPE_VP9_FRAME_CONTEXT; ++ break; + case V4L2_CID_MPEG_VIDEO_HEVC_SPS: + *type = V4L2_CTRL_TYPE_HEVC_SPS; + break; +@@ -1754,6 +1768,219 @@ static void std_log(const struct v4l2_ctrl *ctrl) + 0; \ + }) + ++static int ++validate_vp9_lf_params(struct v4l2_vp9_loop_filter *lf) ++{ ++ unsigned int i, j, k; ++ ++ if (lf->flags & ++ ~(V4L2_VP9_LOOP_FILTER_FLAG_DELTA_ENABLED | ++ V4L2_VP9_LOOP_FILTER_FLAG_DELTA_UPDATE)) ++ return -EINVAL; ++ ++ /* ++ * V4L2_VP9_LOOP_FILTER_FLAG_DELTA_ENABLED implies ++ * V4L2_VP9_LOOP_FILTER_FLAG_DELTA_UPDATE. ++ */ ++ if (lf->flags & V4L2_VP9_LOOP_FILTER_FLAG_DELTA_UPDATE && ++ !(lf->flags & V4L2_VP9_LOOP_FILTER_FLAG_DELTA_ENABLED)) ++ return -EINVAL; ++ ++ /* That all values are in the accepted range. */ ++ if (lf->level > GENMASK(5, 0)) ++ return -EINVAL; ++ ++ if (lf->sharpness > GENMASK(2, 0)) ++ return -EINVAL; ++ ++ for (i = 0; i < ARRAY_SIZE(lf->ref_deltas); i++) { ++ if (lf->ref_deltas[i] < -63 || lf->ref_deltas[i] > 63) ++ return -EINVAL; ++ } ++ ++ for (i = 0; i < ARRAY_SIZE(lf->mode_deltas); i++) { ++ if (lf->mode_deltas[i] < -63 || lf->mode_deltas[i] > 63) ++ return -EINVAL; ++ } ++ ++ for (i = 0; i < ARRAY_SIZE(lf->level_lookup); i++) { ++ for (j = 0; j < ARRAY_SIZE(lf->level_lookup[0]); j++) { ++ for (k = 0; k < ARRAY_SIZE(lf->level_lookup[0][0]); k++) { ++ if (lf->level_lookup[i][j][k] > 63) ++ return -EINVAL; ++ } ++ } ++ } ++ ++ return 0; ++} ++ ++static int ++validate_vp9_quant_params(struct v4l2_vp9_quantization *quant) ++{ ++ if (quant->delta_q_y_dc < -15 || quant->delta_q_y_dc > 15 || ++ quant->delta_q_uv_dc < -15 || quant->delta_q_uv_dc > 15 || ++ quant->delta_q_uv_ac < -15 || quant->delta_q_uv_ac > 15) ++ return -EINVAL; ++ ++ memset(quant->padding, 0, sizeof(quant->padding)); ++ return 0; ++} ++ ++static int ++validate_vp9_seg_params(struct v4l2_vp9_segmentation *seg) ++{ ++ unsigned int i, j; ++ ++ if (seg->flags & ++ ~(V4L2_VP9_SEGMENTATION_FLAG_ENABLED | ++ V4L2_VP9_SEGMENTATION_FLAG_UPDATE_MAP | ++ V4L2_VP9_SEGMENTATION_FLAG_TEMPORAL_UPDATE | ++ V4L2_VP9_SEGMENTATION_FLAG_UPDATE_DATA | ++ V4L2_VP9_SEGMENTATION_FLAG_ABS_OR_DELTA_UPDATE)) ++ return -EINVAL; ++ ++ /* ++ * V4L2_VP9_SEGMENTATION_FLAG_UPDATE_MAP and ++ * V4L2_VP9_SEGMENTATION_FLAG_UPDATE_DATA imply ++ * V4L2_VP9_SEGMENTATION_FLAG_ENABLED. ++ */ ++ if ((seg->flags & ++ (V4L2_VP9_SEGMENTATION_FLAG_UPDATE_MAP | ++ V4L2_VP9_SEGMENTATION_FLAG_UPDATE_DATA)) && ++ !(seg->flags & V4L2_VP9_SEGMENTATION_FLAG_ENABLED)) ++ return -EINVAL; ++ ++ /* ++ * V4L2_VP9_SEGMENTATION_FLAG_TEMPORAL_UPDATE implies ++ * V4L2_VP9_SEGMENTATION_FLAG_UPDATE_MAP. ++ */ ++ if (seg->flags & V4L2_VP9_SEGMENTATION_FLAG_TEMPORAL_UPDATE && ++ !(seg->flags & V4L2_VP9_SEGMENTATION_FLAG_UPDATE_MAP)) ++ return -EINVAL; ++ ++ /* ++ * V4L2_VP9_SEGMENTATION_FLAG_ABS_OR_DELTA_UPDATE implies ++ * V4L2_VP9_SEGMENTATION_FLAG_UPDATE_DATA. ++ */ ++ if (seg->flags & V4L2_VP9_SEGMENTATION_FLAG_ABS_OR_DELTA_UPDATE && ++ !(seg->flags & V4L2_VP9_SEGMENTATION_FLAG_UPDATE_DATA)) ++ return -EINVAL; ++ ++ for (i = 0; i < ARRAY_SIZE(seg->feature_enabled); i++) { ++ if (seg->feature_enabled[i] & ++ ~(V4L2_VP9_SEGMENT_FEATURE_QP_DELTA | ++ V4L2_VP9_SEGMENT_FEATURE_LF | ++ V4L2_VP9_SEGMENT_FEATURE_REF_FRAME | ++ V4L2_VP9_SEGMENT_FEATURE_SKIP)) ++ return -EINVAL; ++ } ++ ++ for (i = 0; i < ARRAY_SIZE(seg->feature_data); i++) { ++ const int range[] = {255, 63, 3, 0}; ++ ++ for (j = 0; j < ARRAY_SIZE(seg->feature_data[j]); j++) { ++ if (seg->feature_data[i][j] < -range[j] || ++ seg->feature_data[i][j] > range[j]) ++ return -EINVAL; ++ } ++ } ++ ++ memset(seg->padding, 0, sizeof(seg->padding)); ++ return 0; ++} ++ ++static int ++validate_vp9_frame_decode_params(struct v4l2_ctrl_vp9_frame_decode_params *dec_params) ++{ ++ int ret; ++ ++ /* Make sure we're not passed invalid flags. */ ++ if (dec_params->flags & ++ ~(V4L2_VP9_FRAME_FLAG_KEY_FRAME | ++ V4L2_VP9_FRAME_FLAG_SHOW_FRAME | ++ V4L2_VP9_FRAME_FLAG_ERROR_RESILIENT | ++ V4L2_VP9_FRAME_FLAG_INTRA_ONLY | ++ V4L2_VP9_FRAME_FLAG_ALLOW_HIGH_PREC_MV | ++ V4L2_VP9_FRAME_FLAG_REFRESH_FRAME_CTX | ++ V4L2_VP9_FRAME_FLAG_PARALLEL_DEC_MODE | ++ V4L2_VP9_FRAME_FLAG_X_SUBSAMPLING | ++ V4L2_VP9_FRAME_FLAG_Y_SUBSAMPLING | ++ V4L2_VP9_FRAME_FLAG_COLOR_RANGE_FULL_SWING)) ++ return -EINVAL; ++ ++ /* ++ * The refresh context and error resilient flags are mutually exclusive. ++ * Same goes for parallel decoding and error resilient modes. ++ */ ++ if (dec_params->flags & V4L2_VP9_FRAME_FLAG_ERROR_RESILIENT && ++ dec_params->flags & ++ (V4L2_VP9_FRAME_FLAG_REFRESH_FRAME_CTX | ++ V4L2_VP9_FRAME_FLAG_PARALLEL_DEC_MODE)) ++ return -EINVAL; ++ ++ if (dec_params->profile > V4L2_VP9_PROFILE_MAX) ++ return -EINVAL; ++ ++ if (dec_params->reset_frame_context > V4L2_VP9_RESET_FRAME_CTX_ALL) ++ return -EINVAL; ++ ++ if (dec_params->frame_context_idx >= V4L2_VP9_NUM_FRAME_CTX) ++ return -EINVAL; ++ ++ /* ++ * Profiles 0 and 1 only support 8-bit depth, profiles 2 and 3 only 10 ++ * and 12 bit depths. ++ */ ++ if ((dec_params->profile < 2 && dec_params->bit_depth != 8) || ++ (dec_params->profile >= 2 && ++ (dec_params->bit_depth != 10 && dec_params->bit_depth != 12))) ++ return -EINVAL; ++ ++ /* Profile 0 and 2 only accept YUV 4:2:0. */ ++ if ((dec_params->profile == 0 || dec_params->profile == 2) && ++ (!(dec_params->flags & V4L2_VP9_FRAME_FLAG_X_SUBSAMPLING) || ++ !(dec_params->flags & V4L2_VP9_FRAME_FLAG_Y_SUBSAMPLING))) ++ return -EINVAL; ++ ++ /* Profile 1 and 3 only accept YUV 4:2:2, 4:4:0 and 4:4:4. */ ++ if ((dec_params->profile == 1 || dec_params->profile == 3) && ++ ((dec_params->flags & V4L2_VP9_FRAME_FLAG_X_SUBSAMPLING) && ++ (dec_params->flags & V4L2_VP9_FRAME_FLAG_Y_SUBSAMPLING))) ++ return -EINVAL; ++ ++ if (dec_params->interpolation_filter > V4L2_VP9_INTERP_FILTER_SWITCHABLE) ++ return -EINVAL; ++ ++ /* ++ * According to the spec, tile_cols_log2 shall be less than or equal ++ * to 6. ++ */ ++ if (dec_params->tile_cols_log2 > 6) ++ return -EINVAL; ++ ++ if (dec_params->tx_mode > V4L2_VP9_TX_MODE_SELECT) ++ return -EINVAL; ++ ++ if (dec_params->reference_mode > V4L2_VP9_REF_MODE_SELECT) ++ return -EINVAL; ++ ++ ret = validate_vp9_lf_params(&dec_params->lf); ++ if (ret) ++ return ret; ++ ++ ret = validate_vp9_quant_params(&dec_params->quant); ++ if (ret) ++ return ret; ++ ++ ret = validate_vp9_seg_params(&dec_params->seg); ++ if (ret) ++ return ret; ++ ++ memset(dec_params->padding, 0, sizeof(dec_params->padding)); ++ return 0; ++} ++ + /* Validate a new control */ + + #define zero_padding(s) \ +@@ -1871,6 +2098,12 @@ static int std_validate_compound(const struct v4l2_ctrl *ctrl, u32 idx, + zero_padding(p_vp8_frame_header->coder_state); + break; + ++ case V4L2_CTRL_TYPE_VP9_FRAME_DECODE_PARAMS: ++ return validate_vp9_frame_decode_params(p); ++ ++ case V4L2_CTRL_TYPE_VP9_FRAME_CONTEXT: ++ break; ++ + case V4L2_CTRL_TYPE_HEVC_SPS: + p_hevc_sps = p; + +@@ -2617,6 +2850,12 @@ static struct v4l2_ctrl *v4l2_ctrl_new(struct v4l2_ctrl_handler *hdl, + case V4L2_CTRL_TYPE_VP8_FRAME_HEADER: + elem_size = sizeof(struct v4l2_ctrl_vp8_frame_header); + break; ++ case V4L2_CTRL_TYPE_VP9_FRAME_CONTEXT: ++ elem_size = sizeof(struct v4l2_ctrl_vp9_frame_ctx); ++ break; ++ case V4L2_CTRL_TYPE_VP9_FRAME_DECODE_PARAMS: ++ elem_size = sizeof(struct v4l2_ctrl_vp9_frame_decode_params); ++ break; + case V4L2_CTRL_TYPE_HEVC_SPS: + elem_size = sizeof(struct v4l2_ctrl_hevc_sps); + break; +diff --git a/drivers/media/v4l2-core/v4l2-ioctl.c b/drivers/media/v4l2-core/v4l2-ioctl.c +index 80cb42450a1b..9351c2635646 100644 +--- a/drivers/media/v4l2-core/v4l2-ioctl.c ++++ b/drivers/media/v4l2-core/v4l2-ioctl.c +@@ -1429,6 +1429,7 @@ static void v4l_fill_fmtdesc(struct v4l2_fmtdesc *fmt) + case V4L2_PIX_FMT_VP8: descr = "VP8"; break; + case V4L2_PIX_FMT_VP8_FRAME: descr = "VP8 Frame"; break; + case V4L2_PIX_FMT_VP9: descr = "VP9"; break; ++ case V4L2_PIX_FMT_VP9_FRAME: descr = "VP9 Frame"; break; + case V4L2_PIX_FMT_HEVC: descr = "HEVC"; break; /* aka H.265 */ + case V4L2_PIX_FMT_HEVC_SLICE: descr = "HEVC Parsed Slice Data"; break; + case V4L2_PIX_FMT_FWHT: descr = "FWHT"; break; /* used in vicodec */ +diff --git a/include/media/v4l2-ctrls.h b/include/media/v4l2-ctrls.h +index cb25f345e9ad..fb299d83df6b 100644 +--- a/include/media/v4l2-ctrls.h ++++ b/include/media/v4l2-ctrls.h +@@ -21,6 +21,7 @@ + #include + #include + #include ++#include + #include + + /* forward references */ +@@ -53,6 +54,8 @@ struct video_device; + * @p_h264_decode_params: Pointer to a struct v4l2_ctrl_h264_decode_params. + * @p_h264_pred_weights: Pointer to a struct v4l2_ctrl_h264_pred_weights. + * @p_vp8_frame_header: Pointer to a VP8 frame header structure. ++ * @p_vp9_frame_ctx: Pointer to a VP9 frame context structure. ++ * @p_vp9_frame_decode_params: Pointer to a VP9 frame params structure. + * @p_hevc_sps: Pointer to an HEVC sequence parameter set structure. + * @p_hevc_pps: Pointer to an HEVC picture parameter set structure. + * @p_hevc_slice_params: Pointer to an HEVC slice parameters structure. +@@ -80,6 +83,8 @@ union v4l2_ctrl_ptr { + struct v4l2_ctrl_hevc_sps *p_hevc_sps; + struct v4l2_ctrl_hevc_pps *p_hevc_pps; + struct v4l2_ctrl_hevc_slice_params *p_hevc_slice_params; ++ struct v4l2_ctrl_vp9_frame_ctx *p_vp9_frame_ctx; ++ struct v4l2_ctrl_vp9_frame_decode_params *p_vp9_frame_decode_params; + struct v4l2_area *p_area; + void *p; + const void *p_const; +diff --git a/include/media/vp9-ctrls.h b/include/media/vp9-ctrls.h +new file mode 100644 +index 000000000000..a14fffb3ad61 +--- /dev/null ++++ b/include/media/vp9-ctrls.h +@@ -0,0 +1,486 @@ ++/* SPDX-License-Identifier: GPL-2.0 */ ++/* ++ * These are the VP9 state controls for use with stateless VP9 ++ * codec drivers. ++ * ++ * It turns out that these structs are not stable yet and will undergo ++ * more changes. So keep them private until they are stable and ready to ++ * become part of the official public API. ++ */ ++ ++#ifndef _VP9_CTRLS_H_ ++#define _VP9_CTRLS_H_ ++ ++#include ++ ++#define V4L2_PIX_FMT_VP9_FRAME v4l2_fourcc('V', 'P', '9', 'F') ++ ++#define V4L2_CID_MPEG_VIDEO_VP9_FRAME_CONTEXT(i) (V4L2_CID_MPEG_BASE + 4000 + (i)) ++#define V4L2_CID_MPEG_VIDEO_VP9_FRAME_DECODE_PARAMS (V4L2_CID_MPEG_BASE + 4004) ++#define V4L2_CTRL_TYPE_VP9_FRAME_CONTEXT 0x400 ++#define V4L2_CTRL_TYPE_VP9_FRAME_DECODE_PARAMS 0x404 ++ ++/** ++ * enum v4l2_vp9_loop_filter_flags - VP9 loop filter flags ++ * ++ * @V4L2_VP9_LOOP_FILTER_FLAG_DELTA_ENABLED: the filter level depends on ++ * the mode and reference frame used ++ * to predict a block ++ * @V4L2_VP9_LOOP_FILTER_FLAG_DELTA_UPDATE: the bitstream contains additional ++ * syntax elements that specify which ++ * mode and reference frame deltas ++ * are to be updated ++ * ++ * Those are the flags you should pass to &v4l2_vp9_loop_filter.flags. See ++ * section '7.2.8 Loop filter semantics' of the VP9 specification for more ++ * details. ++ */ ++enum v4l2_vp9_loop_filter_flags { ++ V4L2_VP9_LOOP_FILTER_FLAG_DELTA_ENABLED = 1 << 0, ++ V4L2_VP9_LOOP_FILTER_FLAG_DELTA_UPDATE = 1 << 1, ++}; ++ ++/** ++ * struct v4l2_vp9_loop_filter - VP9 loop filter parameters ++ * ++ * @flags: combination of V4L2_VP9_LOOP_FILTER_FLAG_* flags ++ * @level: indicates the loop filter strength ++ * @sharpness: indicates the sharpness level ++ * @ref_deltas: contains the adjustment needed for the filter level based on ++ * the chosen reference frame ++ * @mode_deltas: contains the adjustment needed for the filter level based on ++ * the chosen mode ++ * @level_lookup: level lookup table ++ * ++ * This structure contains all loop filter related parameters. See sections ++ * '7.2.8 Loop filter semantics' and '8.8.1 Loop filter frame init process' ++ * of the VP9 specification for more details. ++ */ ++struct v4l2_vp9_loop_filter { ++ __u8 flags; ++ __u8 level; ++ __u8 sharpness; ++ __s8 ref_deltas[4]; ++ __s8 mode_deltas[2]; ++ __u8 level_lookup[8][4][2]; ++ __u8 padding; ++}; ++ ++/** ++ * struct v4l2_vp9_quantization - VP9 quantization parameters ++ * ++ * @base_q_idx: indicates the base frame qindex ++ * @delta_q_y_dc: indicates the Y DC quantizer relative to base_q_idx ++ * @delta_q_uv_dc: indicates the UV DC quantizer relative to base_q_idx ++ * @delta_q_uv_ac indicates the UV AC quantizer relative to base_q_idx ++ * @padding: padding bytes to align things on 64 bits. Must be set to 0 ++ * ++ * Encodes the quantization parameters. See section '7.2.9 Quantization params ++ * syntax' of the VP9 specification for more details. ++ */ ++struct v4l2_vp9_quantization { ++ __u8 base_q_idx; ++ __s8 delta_q_y_dc; ++ __s8 delta_q_uv_dc; ++ __s8 delta_q_uv_ac; ++ __u8 padding[4]; ++}; ++ ++/** ++ * enum v4l2_vp9_segmentation_flags - VP9 segmentation flags ++ * ++ * @V4L2_VP9_SEGMENTATION_FLAG_ENABLED: indicates that this frame makes use of ++ * the segmentation tool ++ * @V4L2_VP9_SEGMENTATION_FLAG_UPDATE_MAP: indicates that the segmentation map ++ * should be updated during the ++ * decoding of this frame ++ * @V4L2_VP9_SEGMENTATION_FLAG_TEMPORAL_UPDATE: indicates that the updates to ++ * the segmentation map are coded ++ * relative to the existing ++ * segmentation map ++ * @V4L2_VP9_SEGMENTATION_FLAG_UPDATE_DATA: indicates that new parameters are ++ * about to be specified for each ++ * segment ++ * @V4L2_VP9_SEGMENTATION_FLAG_ABS_OR_DELTA_UPDATE: indicates that the ++ * segmentation parameters ++ * represent the actual values ++ * to be used ++ * ++ * Those are the flags you should pass to &v4l2_vp9_segmentation.flags. See ++ * section '7.2.10 Segmentation params syntax' of the VP9 specification for ++ * more details. ++ */ ++enum v4l2_vp9_segmentation_flags { ++ V4L2_VP9_SEGMENTATION_FLAG_ENABLED = 1 << 0, ++ V4L2_VP9_SEGMENTATION_FLAG_UPDATE_MAP = 1 << 1, ++ V4L2_VP9_SEGMENTATION_FLAG_TEMPORAL_UPDATE = 1 << 2, ++ V4L2_VP9_SEGMENTATION_FLAG_UPDATE_DATA = 1 << 3, ++ V4L2_VP9_SEGMENTATION_FLAG_ABS_OR_DELTA_UPDATE = 1 << 4, ++}; ++ ++#define V4L2_VP9_SEGMENT_FEATURE_ENABLED(id) (1 << (id)) ++#define V4L2_VP9_SEGMENT_FEATURE_ENABLED_MASK 0xf ++ ++/** ++ * enum v4l2_vp9_segment_feature - VP9 segment feature IDs ++ * ++ * @V4L2_VP9_SEGMENT_FEATURE_QP_DELTA: QP delta segment feature ++ * @V4L2_VP9_SEGMENT_FEATURE_LF: loop filter segment feature ++ * @V4L2_VP9_SEGMENT_FEATURE_REF_FRAME: reference frame segment feature ++ * @V4L2_VP9_SEGMENT_FEATURE_SKIP: skip segment feature ++ * @V4L2_VP9_SEGMENT_FEATURE_CNT: number of segment features ++ * ++ * Segment feature IDs. See section '7.2.10 Segmentation params syntax' of the ++ * VP9 specification for more details. ++ */ ++enum v4l2_vp9_segment_feature { ++ V4L2_VP9_SEGMENT_FEATURE_QP_DELTA, ++ V4L2_VP9_SEGMENT_FEATURE_LF, ++ V4L2_VP9_SEGMENT_FEATURE_REF_FRAME, ++ V4L2_VP9_SEGMENT_FEATURE_SKIP, ++ V4L2_VP9_SEGMENT_FEATURE_CNT, ++}; ++ ++/** ++ * struct v4l2_vp9_segmentation - VP9 segmentation parameters ++ * ++ * @flags: combination of V4L2_VP9_SEGMENTATION_FLAG_* flags ++ * @tree_probs: specifies the probability values to be used when ++ * decoding a Segment-ID. See '5.15. Segmentation map' ++ * section of the VP9 specification for more details. ++ * @pred_prob: specifies the probability values to be used when decoding a ++ * Predicted-Segment-ID. See '6.4.14. Get segment id syntax' ++ * section of :ref:`vp9` for more details.. ++ * @padding: padding used to make things aligned on 64 bits. Shall be zero ++ * filled ++ * @feature_enabled: bitmask defining which features are enabled in each ++ * segment ++ * @feature_data: data attached to each feature. Data entry is only valid if ++ * the feature is enabled ++ * ++ * Encodes the quantization parameters. See section '7.2.10 Segmentation ++ * params syntax' of the VP9 specification for more details. ++ */ ++struct v4l2_vp9_segmentation { ++ __u8 flags; ++ __u8 tree_probs[7]; ++ __u8 pred_probs[3]; ++ __u8 padding[5]; ++ __u8 feature_enabled[8]; ++ __s16 feature_data[8][4]; ++}; ++ ++/** ++ * enum v4l2_vp9_intra_prediction_mode - VP9 Intra prediction modes ++ * ++ * @V4L2_VP9_INTRA_PRED_DC: DC intra prediction ++ * @V4L2_VP9_INTRA_PRED_MODE_V: vertical intra prediction ++ * @V4L2_VP9_INTRA_PRED_MODE_H: horizontal intra prediction ++ * @V4L2_VP9_INTRA_PRED_MODE_D45: D45 intra prediction ++ * @V4L2_VP9_INTRA_PRED_MODE_D135: D135 intra prediction ++ * @V4L2_VP9_INTRA_PRED_MODE_D117: D117 intra prediction ++ * @V4L2_VP9_INTRA_PRED_MODE_D153: D153 intra prediction ++ * @V4L2_VP9_INTRA_PRED_MODE_D207: D207 intra prediction ++ * @V4L2_VP9_INTRA_PRED_MODE_D63: D63 intra prediction ++ * @V4L2_VP9_INTRA_PRED_MODE_TM: True Motion intra prediction ++ * ++ * See section '7.4.5 Intra frame mode info semantics' for more details. ++ */ ++enum v4l2_vp9_intra_prediction_mode { ++ V4L2_VP9_INTRA_PRED_MODE_DC, ++ V4L2_VP9_INTRA_PRED_MODE_V, ++ V4L2_VP9_INTRA_PRED_MODE_H, ++ V4L2_VP9_INTRA_PRED_MODE_D45, ++ V4L2_VP9_INTRA_PRED_MODE_D135, ++ V4L2_VP9_INTRA_PRED_MODE_D117, ++ V4L2_VP9_INTRA_PRED_MODE_D153, ++ V4L2_VP9_INTRA_PRED_MODE_D207, ++ V4L2_VP9_INTRA_PRED_MODE_D63, ++ V4L2_VP9_INTRA_PRED_MODE_TM, ++}; ++ ++/** ++ * struct v4l2_vp9_mv_probabilities - VP9 Motion vector probabilities ++ * @joint: motion vector joint probabilities ++ * @sign: motion vector sign probabilities ++ * @class: motion vector class probabilities ++ * @class0_bit: motion vector class0 bit probabilities ++ * @bits: motion vector bits probabilities ++ * @class0_fr: motion vector class0 fractional bit probabilities ++ * @fr: motion vector fractional bit probabilities ++ * @class0_hp: motion vector class0 high precision fractional bit probabilities ++ * @hp: motion vector high precision fractional bit probabilities ++ */ ++struct v4l2_vp9_mv_probabilities { ++ __u8 joint[3]; ++ __u8 sign[2]; ++ __u8 class[2][10]; ++ __u8 class0_bit[2]; ++ __u8 bits[2][10]; ++ __u8 class0_fr[2][2][3]; ++ __u8 fr[2][3]; ++ __u8 class0_hp[2]; ++ __u8 hp[2]; ++}; ++ ++/** ++ * struct v4l2_vp9_probabilities - VP9 Probabilities ++ * ++ * @tx8: TX 8x8 probabilities ++ * @tx16: TX 16x16 probabilities ++ * @tx32: TX 32x32 probabilities ++ * @coef: coefficient probabilities ++ * @skip: skip probabilities ++ * @inter_mode: inter mode probabilities ++ * @interp_filter: interpolation filter probabilities ++ * @is_inter: is inter-block probabilities ++ * @comp_mode: compound prediction mode probabilities ++ * @single_ref: single ref probabilities ++ * @comp_ref: compound ref probabilities ++ * @y_mode: Y prediction mode probabilities ++ * @uv_mode: UV prediction mode probabilities ++ * @partition: partition probabilities ++ * @mv: motion vector probabilities ++ * ++ * Structure containing most VP9 probabilities. See the VP9 specification ++ * for more details. ++ */ ++struct v4l2_vp9_probabilities { ++ __u8 tx8[2][1]; ++ __u8 tx16[2][2]; ++ __u8 tx32[2][3]; ++ __u8 coef[4][2][2][6][6][3]; ++ __u8 skip[3]; ++ __u8 inter_mode[7][3]; ++ __u8 interp_filter[4][2]; ++ __u8 is_inter[4]; ++ __u8 comp_mode[5]; ++ __u8 single_ref[5][2]; ++ __u8 comp_ref[5]; ++ __u8 y_mode[4][9]; ++ __u8 uv_mode[10][9]; ++ __u8 partition[16][3]; ++ ++ struct v4l2_vp9_mv_probabilities mv; ++}; ++ ++/** ++ * enum v4l2_vp9_reset_frame_context - Valid values for ++ * &v4l2_ctrl_vp9_frame_decode_params->reset_frame_context ++ * ++ * @V4L2_VP9_RESET_FRAME_CTX_NONE: don't reset any frame context ++ * @V4L2_VP9_RESET_FRAME_CTX_SPEC: reset the frame context pointed by ++ * &v4l2_ctrl_vp9_frame_decode_params.frame_context_idx ++ * @V4L2_VP9_RESET_FRAME_CTX_ALL: reset all frame contexts ++ * ++ * See section '7.2 Uncompressed header semantics' of the VP9 specification ++ * for more details. ++ */ ++enum v4l2_vp9_reset_frame_context { ++ V4L2_VP9_RESET_FRAME_CTX_NONE, ++ V4L2_VP9_RESET_FRAME_CTX_SPEC, ++ V4L2_VP9_RESET_FRAME_CTX_ALL, ++}; ++ ++/** ++ * enum v4l2_vp9_interpolation_filter - VP9 interpolation filter types ++ * ++ * @V4L2_VP9_INTERP_FILTER_8TAP: height tap filter ++ * @V4L2_VP9_INTERP_FILTER_8TAP_SMOOTH: height tap smooth filter ++ * @V4L2_VP9_INTERP_FILTER_8TAP_SHARP: height tap sharp filter ++ * @V4L2_VP9_INTERP_FILTER_BILINEAR: bilinear filter ++ * @V4L2_VP9_INTERP_FILTER_SWITCHABLE: filter selection is signaled at the ++ * block level ++ * ++ * See section '7.2.7 Interpolation filter semantics' of the VP9 specification ++ * for more details. ++ */ ++enum v4l2_vp9_interpolation_filter { ++ V4L2_VP9_INTERP_FILTER_8TAP, ++ V4L2_VP9_INTERP_FILTER_8TAP_SMOOTH, ++ V4L2_VP9_INTERP_FILTER_8TAP_SHARP, ++ V4L2_VP9_INTERP_FILTER_BILINEAR, ++ V4L2_VP9_INTERP_FILTER_SWITCHABLE, ++}; ++ ++/** ++ * enum v4l2_vp9_reference_mode - VP9 reference modes ++ * ++ * @V4L2_VP9_REF_MODE_SINGLE: indicates that all the inter blocks use only a ++ * single reference frame to generate motion ++ * compensated prediction ++ * @V4L2_VP9_REF_MODE_COMPOUND: requires all the inter blocks to use compound ++ * mode. Single reference frame prediction is not ++ * allowed ++ * @V4L2_VP9_REF_MODE_SELECT: allows each individual inter block to select ++ * between single and compound prediction modes ++ * ++ * See section '7.3.6 Frame reference mode semantics' of the VP9 specification ++ * for more details. ++ */ ++enum v4l2_vp9_reference_mode { ++ V4L2_VP9_REF_MODE_SINGLE, ++ V4L2_VP9_REF_MODE_COMPOUND, ++ V4L2_VP9_REF_MODE_SELECT, ++}; ++ ++/** ++ * enum v4l2_vp9_tx_mode - VP9 TX modes ++ * ++ * @V4L2_VP9_TX_MODE_ONLY_4X4: transform size is 4x4 ++ * @V4L2_VP9_TX_MODE_ALLOW_8X8: transform size can be up to 8x8 ++ * @V4L2_VP9_TX_MODE_ALLOW_16X16: transform size can be up to 16x16 ++ * @V4L2_VP9_TX_MODE_ALLOW_32X32: transform size can be up to 32x32 ++ * @V4L2_VP9_TX_MODE_SELECT: bitstream contains transform size for each block ++ * ++ * See section '7.3.1 Tx mode semantics' of the VP9 specification for more ++ * details. ++ */ ++enum v4l2_vp9_tx_mode { ++ V4L2_VP9_TX_MODE_ONLY_4X4, ++ V4L2_VP9_TX_MODE_ALLOW_8X8, ++ V4L2_VP9_TX_MODE_ALLOW_16X16, ++ V4L2_VP9_TX_MODE_ALLOW_32X32, ++ V4L2_VP9_TX_MODE_SELECT, ++}; ++ ++/** ++ * enum v4l2_vp9_ref_id - VP9 Reference frame IDs ++ * ++ * @V4L2_REF_ID_LAST: last reference frame ++ * @V4L2_REF_ID_GOLDEN: golden reference frame ++ * @V4L2_REF_ID_ALTREF: alternative reference frame ++ * @V4L2_REF_ID_CNT: number of reference frames ++ * ++ * See section '7.4.12 Ref frames semantics' of the VP9 specification for more ++ * details. ++ */ ++enum v4l2_vp9_ref_id { ++ V4L2_REF_ID_LAST, ++ V4L2_REF_ID_GOLDEN, ++ V4L2_REF_ID_ALTREF, ++ V4L2_REF_ID_CNT, ++}; ++ ++/** ++ * enum v4l2_vp9_frame_flags - VP9 frame flags ++ * @V4L2_VP9_FRAME_FLAG_KEY_FRAME: the frame is a key frame ++ * @V4L2_VP9_FRAME_FLAG_SHOW_FRAME: the frame should be displayed ++ * @V4L2_VP9_FRAME_FLAG_ERROR_RESILIENT: the decoding should be error resilient ++ * @V4L2_VP9_FRAME_FLAG_INTRA_ONLY: the frame does not reference other frames ++ * @V4L2_VP9_FRAME_FLAG_ALLOW_HIGH_PREC_MV: the frame might can high precision ++ * motion vectors ++ * @V4L2_VP9_FRAME_FLAG_REFRESH_FRAME_CTX: frame context should be updated ++ * after decoding ++ * @V4L2_VP9_FRAME_FLAG_PARALLEL_DEC_MODE: parallel decoding is used ++ * @V4L2_VP9_FRAME_FLAG_X_SUBSAMPLING: vertical subsampling is enabled ++ * @V4L2_VP9_FRAME_FLAG_Y_SUBSAMPLING: horizontal subsampling is enabled ++ * @V4L2_VP9_FRAME_FLAG_COLOR_RANGE_FULL_SWING: full UV range is used ++ * ++ * Check the VP9 specification for more details. ++ */ ++enum v4l2_vp9_frame_flags { ++ V4L2_VP9_FRAME_FLAG_KEY_FRAME = 1 << 0, ++ V4L2_VP9_FRAME_FLAG_SHOW_FRAME = 1 << 1, ++ V4L2_VP9_FRAME_FLAG_ERROR_RESILIENT = 1 << 2, ++ V4L2_VP9_FRAME_FLAG_INTRA_ONLY = 1 << 3, ++ V4L2_VP9_FRAME_FLAG_ALLOW_HIGH_PREC_MV = 1 << 4, ++ V4L2_VP9_FRAME_FLAG_REFRESH_FRAME_CTX = 1 << 5, ++ V4L2_VP9_FRAME_FLAG_PARALLEL_DEC_MODE = 1 << 6, ++ V4L2_VP9_FRAME_FLAG_X_SUBSAMPLING = 1 << 7, ++ V4L2_VP9_FRAME_FLAG_Y_SUBSAMPLING = 1 << 8, ++ V4L2_VP9_FRAME_FLAG_COLOR_RANGE_FULL_SWING = 1 << 9, ++}; ++ ++#define V4L2_VP9_PROFILE_MAX 3 ++ ++/** ++ * struct v4l2_ctrl_vp9_frame_decode_params - VP9 frame decoding control ++ * ++ * @flags: combination of V4L2_VP9_FRAME_FLAG_* flags ++ * @compressed_header_size: compressed header size in bytes ++ * @uncompressed_header_size: uncompressed header size in bytes ++ * @profile: VP9 profile. Can be 0, 1, 2 or 3 ++ * @reset_frame_context: specifies whether the frame context should be reset ++ * to default values. See &v4l2_vp9_reset_frame_context ++ * for more details ++ * @frame_context_idx: frame context that should be used/updated ++ * @bit_depth: bits per components. Can be 8, 10 or 12. Note that not all ++ * profiles support 10 and/or 12 bits depths ++ * @interpolation_filter: specifies the filter selection used for performing ++ * inter prediction. See &v4l2_vp9_interpolation_filter ++ * for more details ++ * @tile_cols_log2: specifies the base 2 logarithm of the width of each tile ++ * (where the width is measured in units of 8x8 blocks). ++ * Shall be less than or equal to 6 ++ * @tile_rows_log2: specifies the base 2 logarithm of the height of each tile ++ * (where the height is measured in units of 8x8 blocks) ++ * @tx_mode: specifies the TX mode. See &v4l2_vp9_tx_mode for more details ++ * @reference_mode: specifies the type of inter prediction to be used. See ++ * &v4l2_vp9_reference_mode for more details ++ * @padding: needed to make this struct 64 bit aligned. Shall be filled with ++ * zeros ++ * @frame_width_minus_1: add 1 to it and you'll get the frame width expressed ++ * in pixels ++ * @frame_height_minus_1: add 1 to it and you'll get the frame height expressed ++ * in pixels ++ * @frame_width_minus_1: add 1 to it and you'll get the expected render width ++ * expressed in pixels. This is not used during the ++ * decoding process but might be used by HW scalers to ++ * prepare a frame that's ready for scanout ++ * @frame_height_minus_1: add 1 to it and you'll get the expected render height ++ * expressed in pixels. This is not used during the ++ * decoding process but might be used by HW scalers to ++ * prepare a frame that's ready for scanout ++ * @refs: array of ref frames timestamps. See &v4l2_vp9_ref_id for more details ++ * @lf: loop filter parameters. See &v4l2_vp9_loop_filter for more details ++ * @quant: quantization parameters. See &v4l2_vp9_quantization for more details ++ * @seg: segmentation parameters. See &v4l2_vp9_segmentation for more details ++ * @probs: probabilities. See &v4l2_vp9_probabilities for more details ++ */ ++struct v4l2_ctrl_vp9_frame_decode_params { ++ __u32 flags; ++ __u16 compressed_header_size; ++ __u16 uncompressed_header_size; ++ __u8 profile; ++ __u8 reset_frame_context; ++ __u8 frame_context_idx; ++ __u8 bit_depth; ++ __u8 interpolation_filter; ++ __u8 tile_cols_log2; ++ __u8 tile_rows_log2; ++ __u8 tx_mode; ++ __u8 reference_mode; ++ __u8 padding[7]; ++ __u16 frame_width_minus_1; ++ __u16 frame_height_minus_1; ++ __u16 render_width_minus_1; ++ __u16 render_height_minus_1; ++ __u64 refs[V4L2_REF_ID_CNT]; ++ struct v4l2_vp9_loop_filter lf; ++ struct v4l2_vp9_quantization quant; ++ struct v4l2_vp9_segmentation seg; ++ struct v4l2_vp9_probabilities probs; ++}; ++ ++#define V4L2_VP9_NUM_FRAME_CTX 4 ++ ++/** ++ * struct v4l2_ctrl_vp9_frame_ctx - VP9 frame context control ++ * ++ * @probs: VP9 probabilities ++ * ++ * This control is accessed in both direction. The user should initialize the ++ * 4 contexts with default values just after starting the stream. Then before ++ * decoding a frame it should query the current frame context (the one passed ++ * through &v4l2_ctrl_vp9_frame_decode_params.frame_context_idx) to initialize ++ * &v4l2_ctrl_vp9_frame_decode_params.probs. The probs are then adjusted based ++ * on the bitstream info and passed to the kernel. The codec should update ++ * the frame context after the frame has been decoded, so that next time ++ * userspace query this context it contains the updated probabilities. ++ */ ++struct v4l2_ctrl_vp9_frame_ctx { ++ struct v4l2_vp9_probabilities probs; ++}; ++ ++#endif /* _VP9_CTRLS_H_ */ + +From 437e8def48f568de70ab2514d51e6f05cd52776b Mon Sep 17 00:00:00 2001 +From: Boris Brezillon +Date: Mon, 2 Nov 2020 21:05:51 +0200 +Subject: [PATCH] media: rkvdec: Add the VP9 backend + +The Rockchip VDEC supports VP9 profile 0 up to 4096x2304@30fps. Add +a backend for this new format. + +Signed-off-by: Boris Brezillon +Signed-off-by: Ezequiel Garcia +Signed-off-by: Adrian Ratiu +--- + drivers/staging/media/rkvdec/Makefile | 2 +- + drivers/staging/media/rkvdec/rkvdec-vp9.c | 1577 +++++++++++++++++++++ + drivers/staging/media/rkvdec/rkvdec.c | 60 +- + drivers/staging/media/rkvdec/rkvdec.h | 6 + + 4 files changed, 1643 insertions(+), 2 deletions(-) + create mode 100644 drivers/staging/media/rkvdec/rkvdec-vp9.c + +diff --git a/drivers/staging/media/rkvdec/Makefile b/drivers/staging/media/rkvdec/Makefile +index c08fed0a39f9..cb86b429cfaa 100644 +--- a/drivers/staging/media/rkvdec/Makefile ++++ b/drivers/staging/media/rkvdec/Makefile +@@ -1,3 +1,3 @@ + obj-$(CONFIG_VIDEO_ROCKCHIP_VDEC) += rockchip-vdec.o + +-rockchip-vdec-y += rkvdec.o rkvdec-h264.o ++rockchip-vdec-y += rkvdec.o rkvdec-h264.o rkvdec-vp9.o +diff --git a/drivers/staging/media/rkvdec/rkvdec-vp9.c b/drivers/staging/media/rkvdec/rkvdec-vp9.c +new file mode 100644 +index 000000000000..8b443ed511c9 +--- /dev/null ++++ b/drivers/staging/media/rkvdec/rkvdec-vp9.c +@@ -0,0 +1,1577 @@ ++// SPDX-License-Identifier: GPL-2.0 ++/* ++ * Rockchip Video Decoder VP9 backend ++ * ++ * Copyright (C) 2019 Collabora, Ltd. ++ * Boris Brezillon ++ * ++ * Copyright (C) 2016 Rockchip Electronics Co., Ltd. ++ * Alpha Lin ++ */ ++ ++#include ++#include ++#include ++ ++#include "rkvdec.h" ++#include "rkvdec-regs.h" ++ ++#define RKVDEC_VP9_PROBE_SIZE 4864 ++#define RKVDEC_VP9_COUNT_SIZE 13232 ++#define RKVDEC_VP9_MAX_SEGMAP_SIZE 73728 ++ ++struct rkvdec_vp9_intra_mode_probs { ++ u8 y_mode[105]; ++ u8 uv_mode[23]; ++}; ++ ++struct rkvdec_vp9_intra_only_frame_probs { ++ u8 coef_intra[4][2][128]; ++ struct rkvdec_vp9_intra_mode_probs intra_mode[10]; ++}; ++ ++struct rkvdec_vp9_inter_frame_probs { ++ u8 y_mode[4][9]; ++ u8 comp_mode[5]; ++ u8 comp_ref[5]; ++ u8 single_ref[5][2]; ++ u8 inter_mode[7][3]; ++ u8 interp_filter[4][2]; ++ u8 padding0[11]; ++ u8 coef[2][4][2][128]; ++ u8 uv_mode_0_2[3][9]; ++ u8 padding1[5]; ++ u8 uv_mode_3_5[3][9]; ++ u8 padding2[5]; ++ u8 uv_mode_6_8[3][9]; ++ u8 padding3[5]; ++ u8 uv_mode_9[9]; ++ u8 padding4[7]; ++ u8 padding5[16]; ++ struct { ++ u8 joint[3]; ++ u8 sign[2]; ++ u8 class[2][10]; ++ u8 class0_bit[2]; ++ u8 bits[2][10]; ++ u8 class0_fr[2][2][3]; ++ u8 fr[2][3]; ++ u8 class0_hp[2]; ++ u8 hp[2]; ++ } mv; ++}; ++ ++struct rkvdec_vp9_probs { ++ u8 partition[16][3]; ++ u8 pred[3]; ++ u8 tree[7]; ++ u8 skip[3]; ++ u8 tx32[2][3]; ++ u8 tx16[2][2]; ++ u8 tx8[2][1]; ++ u8 is_inter[4]; ++ /* 128 bit alignment */ ++ u8 padding0[3]; ++ union { ++ struct rkvdec_vp9_inter_frame_probs inter; ++ struct rkvdec_vp9_intra_only_frame_probs intra_only; ++ }; ++}; ++ ++/* Data structure describing auxiliary buffer format. */ ++struct rkvdec_vp9_priv_tbl { ++ struct rkvdec_vp9_probs probs; ++ u8 segmap[2][RKVDEC_VP9_MAX_SEGMAP_SIZE]; ++}; ++ ++struct rkvdec_vp9_refs_counts { ++ u32 eob[2]; ++ u32 coeff[3]; ++}; ++ ++struct rkvdec_vp9_inter_frame_symbol_counts { ++ u32 partition[16][4]; ++ u32 skip[3][2]; ++ u32 inter[4][2]; ++ u32 tx32p[2][4]; ++ u32 tx16p[2][4]; ++ u32 tx8p[2][2]; ++ u32 y_mode[4][10]; ++ u32 uv_mode[10][10]; ++ u32 comp[5][2]; ++ u32 comp_ref[5][2]; ++ u32 single_ref[5][2][2]; ++ u32 mv_mode[7][4]; ++ u32 filter[4][3]; ++ u32 mv_joint[4]; ++ u32 sign[2][2]; ++ /* add 1 element for align */ ++ u32 classes[2][11 + 1]; ++ u32 class0[2][2]; ++ u32 bits[2][10][2]; ++ u32 class0_fp[2][2][4]; ++ u32 fp[2][4]; ++ u32 class0_hp[2][2]; ++ u32 hp[2][2]; ++ struct rkvdec_vp9_refs_counts ref_cnt[2][4][2][6][6]; ++}; ++ ++struct rkvdec_vp9_intra_frame_symbol_counts { ++ u32 partition[4][4][4]; ++ u32 skip[3][2]; ++ u32 intra[4][2]; ++ u32 tx32p[2][4]; ++ u32 tx16p[2][4]; ++ u32 tx8p[2][2]; ++ struct rkvdec_vp9_refs_counts ref_cnt[2][4][2][6][6]; ++}; ++ ++struct rkvdec_vp9_run { ++ struct rkvdec_run base; ++ const struct v4l2_ctrl_vp9_frame_decode_params *decode_params; ++}; ++ ++struct rkvdec_vp9_frame_info { ++ u32 valid : 1; ++ u32 segmapid : 1; ++ u32 frame_context_idx : 2; ++ u32 reference_mode : 2; ++ u32 tx_mode : 3; ++ u32 interpolation_filter : 3; ++ u32 flags; ++ u64 timestamp; ++ struct v4l2_vp9_segmentation seg; ++ struct v4l2_vp9_loop_filter lf; ++}; ++ ++struct rkvdec_vp9_ctx { ++ struct rkvdec_aux_buf priv_tbl; ++ struct rkvdec_aux_buf count_tbl; ++ struct v4l2_ctrl_vp9_frame_ctx frame_context; ++ struct rkvdec_vp9_frame_info cur; ++ struct rkvdec_vp9_frame_info last; ++}; ++ ++static u32 rkvdec_fastdiv(u32 dividend, u16 divisor) ++{ ++#define DIV_INV(d) ((u32)(((1ULL << 32) + ((d) - 1)) / (d))) ++#define DIVS_INV(d0, d1, d2, d3, d4, d5, d6, d7, d8, d9) \ ++ DIV_INV(d0), DIV_INV(d1), DIV_INV(d2), DIV_INV(d3), \ ++ DIV_INV(d4), DIV_INV(d5), DIV_INV(d6), DIV_INV(d7), \ ++ DIV_INV(d8), DIV_INV(d9) ++ ++ static const u32 inv[] = { ++ DIV_INV(2), DIV_INV(3), DIV_INV(4), DIV_INV(5), ++ DIV_INV(6), DIV_INV(7), DIV_INV(8), DIV_INV(9), ++ DIVS_INV(10, 11, 12, 13, 14, 15, 16, 17, 18, 19), ++ DIVS_INV(20, 21, 22, 23, 24, 25, 26, 27, 28, 29), ++ DIVS_INV(30, 31, 32, 33, 34, 35, 36, 37, 38, 39), ++ DIVS_INV(40, 41, 42, 43, 44, 45, 46, 47, 48, 49), ++ DIVS_INV(50, 51, 52, 53, 54, 55, 56, 57, 58, 59), ++ DIVS_INV(60, 61, 62, 63, 64, 65, 66, 67, 68, 69), ++ DIVS_INV(70, 71, 72, 73, 74, 75, 76, 77, 78, 79), ++ DIVS_INV(80, 81, 82, 83, 84, 85, 86, 87, 88, 89), ++ DIVS_INV(90, 91, 92, 93, 94, 95, 96, 97, 98, 99), ++ DIVS_INV(100, 101, 102, 103, 104, 105, 106, 107, 108, 109), ++ DIVS_INV(110, 111, 112, 113, 114, 115, 116, 117, 118, 119), ++ DIVS_INV(120, 121, 122, 123, 124, 125, 126, 127, 128, 129), ++ DIVS_INV(130, 131, 132, 133, 134, 135, 136, 137, 138, 139), ++ DIVS_INV(140, 141, 142, 143, 144, 145, 146, 147, 148, 149), ++ DIVS_INV(150, 151, 152, 153, 154, 155, 156, 157, 158, 159), ++ DIVS_INV(160, 161, 162, 163, 164, 165, 166, 167, 168, 169), ++ DIVS_INV(170, 171, 172, 173, 174, 175, 176, 177, 178, 179), ++ DIVS_INV(180, 181, 182, 183, 184, 185, 186, 187, 188, 189), ++ DIVS_INV(190, 191, 192, 193, 194, 195, 196, 197, 198, 199), ++ DIVS_INV(200, 201, 202, 203, 204, 205, 206, 207, 208, 209), ++ DIVS_INV(210, 211, 212, 213, 214, 215, 216, 217, 218, 219), ++ DIVS_INV(220, 221, 222, 223, 224, 225, 226, 227, 228, 229), ++ DIVS_INV(230, 231, 232, 233, 234, 235, 236, 237, 238, 239), ++ DIVS_INV(240, 241, 242, 243, 244, 245, 246, 247, 248, 249), ++ DIV_INV(250), DIV_INV(251), DIV_INV(252), DIV_INV(253), ++ DIV_INV(254), DIV_INV(255), DIV_INV(256), ++ }; ++ ++ if (divisor == 0) ++ return 0; ++ else if (divisor == 1) ++ return dividend; ++ ++ if (WARN_ON(divisor - 2 >= ARRAY_SIZE(inv))) ++ return dividend; ++ ++ return ((u64)dividend * inv[divisor - 2]) >> 32; ++} ++ ++static const u8 vp9_kf_y_mode_prob[10][10][9] = { ++ { ++ /* above = dc */ ++ { 137, 30, 42, 148, 151, 207, 70, 52, 91 },/*left = dc */ ++ { 92, 45, 102, 136, 116, 180, 74, 90, 100 },/*left = v */ ++ { 73, 32, 19, 187, 222, 215, 46, 34, 100 },/*left = h */ ++ { 91, 30, 32, 116, 121, 186, 93, 86, 94 },/*left = d45 */ ++ { 72, 35, 36, 149, 68, 206, 68, 63, 105 },/*left = d135*/ ++ { 73, 31, 28, 138, 57, 124, 55, 122, 151 },/*left = d117*/ ++ { 67, 23, 21, 140, 126, 197, 40, 37, 171 },/*left = d153*/ ++ { 86, 27, 28, 128, 154, 212, 45, 43, 53 },/*left = d207*/ ++ { 74, 32, 27, 107, 86, 160, 63, 134, 102 },/*left = d63 */ ++ { 59, 67, 44, 140, 161, 202, 78, 67, 119 } /*left = tm */ ++ }, { /* above = v */ ++ { 63, 36, 126, 146, 123, 158, 60, 90, 96 },/*left = dc */ ++ { 43, 46, 168, 134, 107, 128, 69, 142, 92 },/*left = v */ ++ { 44, 29, 68, 159, 201, 177, 50, 57, 77 },/*left = h */ ++ { 58, 38, 76, 114, 97, 172, 78, 133, 92 },/*left = d45 */ ++ { 46, 41, 76, 140, 63, 184, 69, 112, 57 },/*left = d135*/ ++ { 38, 32, 85, 140, 46, 112, 54, 151, 133 },/*left = d117*/ ++ { 39, 27, 61, 131, 110, 175, 44, 75, 136 },/*left = d153*/ ++ { 52, 30, 74, 113, 130, 175, 51, 64, 58 },/*left = d207*/ ++ { 47, 35, 80, 100, 74, 143, 64, 163, 74 },/*left = d63 */ ++ { 36, 61, 116, 114, 128, 162, 80, 125, 82 } /*left = tm */ ++ }, { /* above = h */ ++ { 82, 26, 26, 171, 208, 204, 44, 32, 105 },/*left = dc */ ++ { 55, 44, 68, 166, 179, 192, 57, 57, 108 },/*left = v */ ++ { 42, 26, 11, 199, 241, 228, 23, 15, 85 },/*left = h */ ++ { 68, 42, 19, 131, 160, 199, 55, 52, 83 },/*left = d45 */ ++ { 58, 50, 25, 139, 115, 232, 39, 52, 118 },/*left = d135*/ ++ { 50, 35, 33, 153, 104, 162, 64, 59, 131 },/*left = d117*/ ++ { 44, 24, 16, 150, 177, 202, 33, 19, 156 },/*left = d153*/ ++ { 55, 27, 12, 153, 203, 218, 26, 27, 49 },/*left = d207*/ ++ { 53, 49, 21, 110, 116, 168, 59, 80, 76 },/*left = d63 */ ++ { 38, 72, 19, 168, 203, 212, 50, 50, 107 } /*left = tm */ ++ }, { /* above = d45 */ ++ { 103, 26, 36, 129, 132, 201, 83, 80, 93 },/*left = dc */ ++ { 59, 38, 83, 112, 103, 162, 98, 136, 90 },/*left = v */ ++ { 62, 30, 23, 158, 200, 207, 59, 57, 50 },/*left = h */ ++ { 67, 30, 29, 84, 86, 191, 102, 91, 59 },/*left = d45 */ ++ { 60, 32, 33, 112, 71, 220, 64, 89, 104 },/*left = d135*/ ++ { 53, 26, 34, 130, 56, 149, 84, 120, 103 },/*left = d117*/ ++ { 53, 21, 23, 133, 109, 210, 56, 77, 172 },/*left = d153*/ ++ { 77, 19, 29, 112, 142, 228, 55, 66, 36 },/*left = d207*/ ++ { 61, 29, 29, 93, 97, 165, 83, 175, 162 },/*left = d63 */ ++ { 47, 47, 43, 114, 137, 181, 100, 99, 95 } /*left = tm */ ++ }, { /* above = d135 */ ++ { 69, 23, 29, 128, 83, 199, 46, 44, 101 },/*left = dc */ ++ { 53, 40, 55, 139, 69, 183, 61, 80, 110 },/*left = v */ ++ { 40, 29, 19, 161, 180, 207, 43, 24, 91 },/*left = h */ ++ { 60, 34, 19, 105, 61, 198, 53, 64, 89 },/*left = d45 */ ++ { 52, 31, 22, 158, 40, 209, 58, 62, 89 },/*left = d135*/ ++ { 44, 31, 29, 147, 46, 158, 56, 102, 198 },/*left = d117*/ ++ { 35, 19, 12, 135, 87, 209, 41, 45, 167 },/*left = d153*/ ++ { 55, 25, 21, 118, 95, 215, 38, 39, 66 },/*left = d207*/ ++ { 51, 38, 25, 113, 58, 164, 70, 93, 97 },/*left = d63 */ ++ { 47, 54, 34, 146, 108, 203, 72, 103, 151 } /*left = tm */ ++ }, { /* above = d117 */ ++ { 64, 19, 37, 156, 66, 138, 49, 95, 133 },/*left = dc */ ++ { 46, 27, 80, 150, 55, 124, 55, 121, 135 },/*left = v */ ++ { 36, 23, 27, 165, 149, 166, 54, 64, 118 },/*left = h */ ++ { 53, 21, 36, 131, 63, 163, 60, 109, 81 },/*left = d45 */ ++ { 40, 26, 35, 154, 40, 185, 51, 97, 123 },/*left = d135*/ ++ { 35, 19, 34, 179, 19, 97, 48, 129, 124 },/*left = d117*/ ++ { 36, 20, 26, 136, 62, 164, 33, 77, 154 },/*left = d153*/ ++ { 45, 18, 32, 130, 90, 157, 40, 79, 91 },/*left = d207*/ ++ { 45, 26, 28, 129, 45, 129, 49, 147, 123 },/*left = d63 */ ++ { 38, 44, 51, 136, 74, 162, 57, 97, 121 } /*left = tm */ ++ }, { /* above = d153 */ ++ { 75, 17, 22, 136, 138, 185, 32, 34, 166 },/*left = dc */ ++ { 56, 39, 58, 133, 117, 173, 48, 53, 187 },/*left = v */ ++ { 35, 21, 12, 161, 212, 207, 20, 23, 145 },/*left = h */ ++ { 56, 29, 19, 117, 109, 181, 55, 68, 112 },/*left = d45 */ ++ { 47, 29, 17, 153, 64, 220, 59, 51, 114 },/*left = d135*/ ++ { 46, 16, 24, 136, 76, 147, 41, 64, 172 },/*left = d117*/ ++ { 34, 17, 11, 108, 152, 187, 13, 15, 209 },/*left = d153*/ ++ { 51, 24, 14, 115, 133, 209, 32, 26, 104 },/*left = d207*/ ++ { 55, 30, 18, 122, 79, 179, 44, 88, 116 },/*left = d63 */ ++ { 37, 49, 25, 129, 168, 164, 41, 54, 148 } /*left = tm */ ++ }, { /* above = d207 */ ++ { 82, 22, 32, 127, 143, 213, 39, 41, 70 },/*left = dc */ ++ { 62, 44, 61, 123, 105, 189, 48, 57, 64 },/*left = v */ ++ { 47, 25, 17, 175, 222, 220, 24, 30, 86 },/*left = h */ ++ { 68, 36, 17, 106, 102, 206, 59, 74, 74 },/*left = d45 */ ++ { 57, 39, 23, 151, 68, 216, 55, 63, 58 },/*left = d135*/ ++ { 49, 30, 35, 141, 70, 168, 82, 40, 115 },/*left = d117*/ ++ { 51, 25, 15, 136, 129, 202, 38, 35, 139 },/*left = d153*/ ++ { 68, 26, 16, 111, 141, 215, 29, 28, 28 },/*left = d207*/ ++ { 59, 39, 19, 114, 75, 180, 77, 104, 42 },/*left = d63 */ ++ { 40, 61, 26, 126, 152, 206, 61, 59, 93 } /*left = tm */ ++ }, { /* above = d63 */ ++ { 78, 23, 39, 111, 117, 170, 74, 124, 94 },/*left = dc */ ++ { 48, 34, 86, 101, 92, 146, 78, 179, 134 },/*left = v */ ++ { 47, 22, 24, 138, 187, 178, 68, 69, 59 },/*left = h */ ++ { 56, 25, 33, 105, 112, 187, 95, 177, 129 },/*left = d45 */ ++ { 48, 31, 27, 114, 63, 183, 82, 116, 56 },/*left = d135*/ ++ { 43, 28, 37, 121, 63, 123, 61, 192, 169 },/*left = d117*/ ++ { 42, 17, 24, 109, 97, 177, 56, 76, 122 },/*left = d153*/ ++ { 58, 18, 28, 105, 139, 182, 70, 92, 63 },/*left = d207*/ ++ { 46, 23, 32, 74, 86, 150, 67, 183, 88 },/*left = d63 */ ++ { 36, 38, 48, 92, 122, 165, 88, 137, 91 } /*left = tm */ ++ }, { /* above = tm */ ++ { 65, 70, 60, 155, 159, 199, 61, 60, 81 },/*left = dc */ ++ { 44, 78, 115, 132, 119, 173, 71, 112, 93 },/*left = v */ ++ { 39, 38, 21, 184, 227, 206, 42, 32, 64 },/*left = h */ ++ { 58, 47, 36, 124, 137, 193, 80, 82, 78 },/*left = d45 */ ++ { 49, 50, 35, 144, 95, 205, 63, 78, 59 },/*left = d135*/ ++ { 41, 53, 52, 148, 71, 142, 65, 128, 51 },/*left = d117*/ ++ { 40, 36, 28, 143, 143, 202, 40, 55, 137 },/*left = d153*/ ++ { 52, 34, 29, 129, 183, 227, 42, 35, 43 },/*left = d207*/ ++ { 42, 44, 44, 104, 105, 164, 64, 130, 80 },/*left = d63 */ ++ { 43, 81, 53, 140, 169, 204, 68, 84, 72 } /*left = tm */ ++ } ++}; ++ ++static const u8 kf_partition_probs[16][3] = { ++ /* 8x8 -> 4x4 */ ++ { 158, 97, 94 }, /* a/l both not split */ ++ { 93, 24, 99 }, /* a split, l not split */ ++ { 85, 119, 44 }, /* l split, a not split */ ++ { 62, 59, 67 }, /* a/l both split */ ++ /* 16x16 -> 8x8 */ ++ { 149, 53, 53 }, /* a/l both not split */ ++ { 94, 20, 48 }, /* a split, l not split */ ++ { 83, 53, 24 }, /* l split, a not split */ ++ { 52, 18, 18 }, /* a/l both split */ ++ /* 32x32 -> 16x16 */ ++ { 150, 40, 39 }, /* a/l both not split */ ++ { 78, 12, 26 }, /* a split, l not split */ ++ { 67, 33, 11 }, /* l split, a not split */ ++ { 24, 7, 5 }, /* a/l both split */ ++ /* 64x64 -> 32x32 */ ++ { 174, 35, 49 }, /* a/l both not split */ ++ { 68, 11, 27 }, /* a split, l not split */ ++ { 57, 15, 9 }, /* l split, a not split */ ++ { 12, 3, 3 }, /* a/l both split */ ++}; ++ ++static const u8 kf_uv_mode_prob[10][9] = { ++ { 144, 11, 54, 157, 195, 130, 46, 58, 108 }, /* y = dc */ ++ { 118, 15, 123, 148, 131, 101, 44, 93, 131 }, /* y = v */ ++ { 113, 12, 23, 188, 226, 142, 26, 32, 125 }, /* y = h */ ++ { 120, 11, 50, 123, 163, 135, 64, 77, 103 }, /* y = d45 */ ++ { 113, 9, 36, 155, 111, 157, 32, 44, 161 }, /* y = d135 */ ++ { 116, 9, 55, 176, 76, 96, 37, 61, 149 }, /* y = d117 */ ++ { 115, 9, 28, 141, 161, 167, 21, 25, 193 }, /* y = d153 */ ++ { 120, 12, 32, 145, 195, 142, 32, 38, 86 }, /* y = d207 */ ++ { 116, 12, 64, 120, 140, 125, 49, 115, 121 }, /* y = d63 */ ++ { 102, 19, 66, 162, 182, 122, 35, 59, 128 } /* y = tm */ ++}; ++ ++static void write_coeff_plane(const u8 coef[6][6][3], u8 *coeff_plane) ++{ ++ unsigned int idx = 0; ++ u8 byte_count = 0, p; ++ s32 k, m, n; ++ ++ for (k = 0; k < 6; k++) { ++ for (m = 0; m < 6; m++) { ++ for (n = 0; n < 3; n++) { ++ p = coef[k][m][n]; ++ coeff_plane[idx++] = p; ++ byte_count++; ++ if (byte_count == 27) { ++ idx += 5; ++ byte_count = 0; ++ } ++ } ++ } ++ } ++} ++ ++static void init_intra_only_probs(struct rkvdec_ctx *ctx, ++ const struct rkvdec_vp9_run *run) ++{ ++ const struct v4l2_ctrl_vp9_frame_decode_params *dec_params; ++ struct rkvdec_vp9_ctx *vp9_ctx = ctx->priv; ++ struct rkvdec_vp9_priv_tbl *tbl = vp9_ctx->priv_tbl.cpu; ++ struct rkvdec_vp9_intra_only_frame_probs *rkprobs; ++ const struct v4l2_vp9_probabilities *probs; ++ unsigned int i, j, k, m; ++ ++ rkprobs = &tbl->probs.intra_only; ++ dec_params = run->decode_params; ++ probs = &dec_params->probs; ++ ++ /* ++ * intra only 149 x 128 bits ,aligned to 152 x 128 bits coeff related ++ * prob 64 x 128 bits ++ */ ++ for (i = 0; i < ARRAY_SIZE(probs->coef); i++) { ++ for (j = 0; j < ARRAY_SIZE(probs->coef[0]); j++) ++ write_coeff_plane(probs->coef[i][j][0], ++ rkprobs->coef_intra[i][j]); ++ } ++ ++ /* intra mode prob 80 x 128 bits */ ++ for (i = 0; i < ARRAY_SIZE(vp9_kf_y_mode_prob); i++) { ++ u32 byte_count = 0; ++ int idx = 0; ++ ++ /* vp9_kf_y_mode_prob */ ++ for (j = 0; j < ARRAY_SIZE(vp9_kf_y_mode_prob[0]); j++) { ++ for (k = 0; k < ARRAY_SIZE(vp9_kf_y_mode_prob[0][0]); ++ k++) { ++ u8 val = vp9_kf_y_mode_prob[i][j][k]; ++ ++ rkprobs->intra_mode[i].y_mode[idx++] = val; ++ byte_count++; ++ if (byte_count == 27) { ++ byte_count = 0; ++ idx += 5; ++ } ++ } ++ } ++ ++ idx = 0; ++ if (i < 4) { ++ for (m = 0; m < (i < 3 ? 23 : 21); m++) { ++ const u8 *ptr = (const u8 *)kf_uv_mode_prob; ++ ++ rkprobs->intra_mode[i].uv_mode[idx++] = ptr[i * 23 + m]; ++ } ++ } ++ } ++} ++ ++static void init_inter_probs(struct rkvdec_ctx *ctx, ++ const struct rkvdec_vp9_run *run) ++{ ++ const struct v4l2_ctrl_vp9_frame_decode_params *dec_params; ++ struct rkvdec_vp9_ctx *vp9_ctx = ctx->priv; ++ struct rkvdec_vp9_priv_tbl *tbl = vp9_ctx->priv_tbl.cpu; ++ struct rkvdec_vp9_inter_frame_probs *rkprobs; ++ const struct v4l2_vp9_probabilities *probs; ++ unsigned int i, j, k; ++ ++ rkprobs = &tbl->probs.inter; ++ dec_params = run->decode_params; ++ probs = &dec_params->probs; ++ ++ /* ++ * inter probs ++ * 151 x 128 bits, aligned to 152 x 128 bits ++ * inter only ++ * intra_y_mode & inter_block info 6 x 128 bits ++ */ ++ ++ memcpy(rkprobs->y_mode, probs->y_mode, sizeof(rkprobs->y_mode)); ++ memcpy(rkprobs->comp_mode, probs->comp_mode, ++ sizeof(rkprobs->comp_mode)); ++ memcpy(rkprobs->comp_ref, probs->comp_ref, ++ sizeof(rkprobs->comp_ref)); ++ memcpy(rkprobs->single_ref, probs->single_ref, ++ sizeof(rkprobs->single_ref)); ++ memcpy(rkprobs->inter_mode, probs->inter_mode, ++ sizeof(rkprobs->inter_mode)); ++ memcpy(rkprobs->interp_filter, probs->interp_filter, ++ sizeof(rkprobs->interp_filter)); ++ ++ /* 128 x 128 bits coeff related */ ++ for (i = 0; i < ARRAY_SIZE(probs->coef); i++) { ++ for (j = 0; j < ARRAY_SIZE(probs->coef[0]); j++) { ++ for (k = 0; k < ARRAY_SIZE(probs->coef[0][0]); k++) ++ write_coeff_plane(probs->coef[i][j][k], ++ rkprobs->coef[k][i][j]); ++ } ++ } ++ ++ /* intra uv mode 6 x 128 */ ++ memcpy(rkprobs->uv_mode_0_2, &probs->uv_mode[0], ++ sizeof(rkprobs->uv_mode_0_2)); ++ memcpy(rkprobs->uv_mode_3_5, &probs->uv_mode[3], ++ sizeof(rkprobs->uv_mode_3_5)); ++ memcpy(rkprobs->uv_mode_6_8, &probs->uv_mode[6], ++ sizeof(rkprobs->uv_mode_6_8)); ++ memcpy(rkprobs->uv_mode_9, &probs->uv_mode[9], ++ sizeof(rkprobs->uv_mode_9)); ++ ++ /* mv related 6 x 128 */ ++ memcpy(rkprobs->mv.joint, probs->mv.joint, ++ sizeof(rkprobs->mv.joint)); ++ memcpy(rkprobs->mv.sign, probs->mv.sign, ++ sizeof(rkprobs->mv.sign)); ++ memcpy(rkprobs->mv.class, probs->mv.class, ++ sizeof(rkprobs->mv.class)); ++ memcpy(rkprobs->mv.class0_bit, probs->mv.class0_bit, ++ sizeof(rkprobs->mv.class0_bit)); ++ memcpy(rkprobs->mv.bits, probs->mv.bits, ++ sizeof(rkprobs->mv.bits)); ++ memcpy(rkprobs->mv.class0_fr, probs->mv.class0_fr, ++ sizeof(rkprobs->mv.class0_fr)); ++ memcpy(rkprobs->mv.fr, probs->mv.fr, ++ sizeof(rkprobs->mv.fr)); ++ memcpy(rkprobs->mv.class0_hp, probs->mv.class0_hp, ++ sizeof(rkprobs->mv.class0_hp)); ++ memcpy(rkprobs->mv.hp, probs->mv.hp, ++ sizeof(rkprobs->mv.hp)); ++} ++ ++static void init_probs(struct rkvdec_ctx *ctx, ++ const struct rkvdec_vp9_run *run) ++{ ++ const struct v4l2_ctrl_vp9_frame_decode_params *dec_params; ++ struct rkvdec_vp9_ctx *vp9_ctx = ctx->priv; ++ struct rkvdec_vp9_priv_tbl *tbl = vp9_ctx->priv_tbl.cpu; ++ struct rkvdec_vp9_probs *rkprobs = &tbl->probs; ++ const struct v4l2_vp9_segmentation *seg; ++ const struct v4l2_vp9_probabilities *probs; ++ bool intra_only; ++ ++ dec_params = run->decode_params; ++ probs = &dec_params->probs; ++ seg = &dec_params->seg; ++ ++ memset(rkprobs, 0, sizeof(*rkprobs)); ++ ++ intra_only = !!(dec_params->flags & ++ (V4L2_VP9_FRAME_FLAG_KEY_FRAME | ++ V4L2_VP9_FRAME_FLAG_INTRA_ONLY)); ++ ++ /* sb info 5 x 128 bit */ ++ memcpy(rkprobs->partition, ++ intra_only ? kf_partition_probs : probs->partition, ++ sizeof(rkprobs->partition)); ++ ++ memcpy(rkprobs->pred, seg->pred_probs, sizeof(rkprobs->pred)); ++ memcpy(rkprobs->tree, seg->tree_probs, sizeof(rkprobs->tree)); ++ memcpy(rkprobs->skip, probs->skip, sizeof(rkprobs->skip)); ++ memcpy(rkprobs->tx32, probs->tx32, sizeof(rkprobs->tx32)); ++ memcpy(rkprobs->tx16, probs->tx16, sizeof(rkprobs->tx16)); ++ memcpy(rkprobs->tx8, probs->tx8, sizeof(rkprobs->tx8)); ++ memcpy(rkprobs->is_inter, probs->is_inter, sizeof(rkprobs->is_inter)); ++ ++ if (intra_only) ++ init_intra_only_probs(ctx, run); ++ else ++ init_inter_probs(ctx, run); ++} ++ ++struct vp9d_ref_config { ++ u32 reg_frm_size; ++ u32 reg_hor_stride; ++ u32 reg_y_stride; ++ u32 reg_yuv_stride; ++ u32 reg_ref_base; ++}; ++ ++static struct vp9d_ref_config ref_config[3] = { ++ { ++ .reg_frm_size = RKVDEC_REG_VP9_FRAME_SIZE(0), ++ .reg_hor_stride = RKVDEC_VP9_HOR_VIRSTRIDE(0), ++ .reg_y_stride = RKVDEC_VP9_LAST_FRAME_YSTRIDE, ++ .reg_yuv_stride = RKVDEC_VP9_LAST_FRAME_YUVSTRIDE, ++ .reg_ref_base = RKVDEC_REG_VP9_LAST_FRAME_BASE, ++ }, ++ { ++ .reg_frm_size = RKVDEC_REG_VP9_FRAME_SIZE(1), ++ .reg_hor_stride = RKVDEC_VP9_HOR_VIRSTRIDE(1), ++ .reg_y_stride = RKVDEC_VP9_GOLDEN_FRAME_YSTRIDE, ++ .reg_yuv_stride = 0, ++ .reg_ref_base = RKVDEC_REG_VP9_GOLDEN_FRAME_BASE, ++ }, ++ { ++ .reg_frm_size = RKVDEC_REG_VP9_FRAME_SIZE(2), ++ .reg_hor_stride = RKVDEC_VP9_HOR_VIRSTRIDE(2), ++ .reg_y_stride = RKVDEC_VP9_ALTREF_FRAME_YSTRIDE, ++ .reg_yuv_stride = 0, ++ .reg_ref_base = RKVDEC_REG_VP9_ALTREF_FRAME_BASE, ++ } ++}; ++ ++static struct rkvdec_decoded_buffer * ++get_ref_buf(struct rkvdec_ctx *ctx, struct vb2_v4l2_buffer *dst, u64 timestamp) ++{ ++ struct v4l2_m2m_ctx *m2m_ctx = ctx->fh.m2m_ctx; ++ struct vb2_queue *cap_q = &m2m_ctx->cap_q_ctx.q; ++ int buf_idx; ++ ++ /* ++ * If a ref is unused or invalid, address of current destination ++ * buffer is returned. ++ */ ++ buf_idx = vb2_find_timestamp(cap_q, timestamp, 0); ++ if (buf_idx < 0) ++ return vb2_to_rkvdec_decoded_buf(&dst->vb2_buf); ++ ++ return vb2_to_rkvdec_decoded_buf(vb2_get_buffer(cap_q, buf_idx)); ++} ++ ++static dma_addr_t get_mv_base_addr(struct rkvdec_decoded_buffer *buf) ++{ ++ u32 aligned_pitch, aligned_height, yuv_len; ++ ++ aligned_height = round_up(buf->vp9.height, 64); ++ aligned_pitch = round_up(buf->vp9.width * buf->vp9.bit_depth, 512) / 8; ++ yuv_len = (aligned_height * aligned_pitch * 3) / 2; ++ ++ return vb2_dma_contig_plane_dma_addr(&buf->base.vb.vb2_buf, 0) + ++ yuv_len; ++} ++ ++static void ++config_ref_registers(struct rkvdec_ctx *ctx, ++ const struct rkvdec_vp9_run *run, ++ struct rkvdec_decoded_buffer **ref_bufs, ++ enum v4l2_vp9_ref_id id) ++{ ++ u32 aligned_pitch, aligned_height, y_len, yuv_len; ++ struct rkvdec_decoded_buffer *buf = ref_bufs[id]; ++ struct rkvdec_dev *rkvdec = ctx->dev; ++ ++ aligned_height = round_up(buf->vp9.height, 64); ++ writel_relaxed(RKVDEC_VP9_FRAMEWIDTH(buf->vp9.width) | ++ RKVDEC_VP9_FRAMEHEIGHT(buf->vp9.height), ++ rkvdec->regs + ref_config[id].reg_frm_size); ++ ++ writel_relaxed(vb2_dma_contig_plane_dma_addr(&buf->base.vb.vb2_buf, 0), ++ rkvdec->regs + ref_config[id].reg_ref_base); ++ ++ if (&buf->base.vb == run->base.bufs.dst) ++ return; ++ ++ aligned_pitch = round_up(buf->vp9.width * buf->vp9.bit_depth, 512) / 8; ++ y_len = aligned_height * aligned_pitch; ++ yuv_len = (y_len * 3) / 2; ++ ++ writel_relaxed(RKVDEC_HOR_Y_VIRSTRIDE(aligned_pitch / 16) | ++ RKVDEC_HOR_UV_VIRSTRIDE(aligned_pitch / 16), ++ rkvdec->regs + ref_config[id].reg_hor_stride); ++ writel_relaxed(RKVDEC_VP9_REF_YSTRIDE(y_len / 16), ++ rkvdec->regs + ref_config[id].reg_y_stride); ++ ++ if (!ref_config[id].reg_yuv_stride) ++ return; ++ ++ writel_relaxed(RKVDEC_VP9_REF_YUVSTRIDE(yuv_len / 16), ++ rkvdec->regs + ref_config[id].reg_yuv_stride); ++} ++ ++static bool seg_featured_enabled(const struct v4l2_vp9_segmentation *seg, ++ enum v4l2_vp9_segment_feature feature, ++ unsigned int segid) ++{ ++ u8 mask = V4L2_VP9_SEGMENT_FEATURE_ENABLED(feature); ++ ++ return !!(seg->feature_enabled[segid] & mask); ++} ++ ++static void ++config_seg_registers(struct rkvdec_ctx *ctx, ++ unsigned int segid) ++{ ++ struct rkvdec_vp9_ctx *vp9_ctx = ctx->priv; ++ const struct v4l2_vp9_segmentation *seg; ++ struct rkvdec_dev *rkvdec = ctx->dev; ++ s16 feature_val; ++ u8 feature_id; ++ u32 val = 0; ++ ++ seg = vp9_ctx->last.valid ? &vp9_ctx->last.seg : &vp9_ctx->cur.seg; ++ feature_id = V4L2_VP9_SEGMENT_FEATURE_QP_DELTA; ++ if (seg_featured_enabled(seg, feature_id, segid)) { ++ feature_val = seg->feature_data[segid][feature_id]; ++ val |= RKVDEC_SEGID_FRAME_QP_DELTA_EN(1) | ++ RKVDEC_SEGID_FRAME_QP_DELTA(feature_val); ++ } ++ ++ feature_id = V4L2_VP9_SEGMENT_FEATURE_LF; ++ if (seg_featured_enabled(seg, feature_id, segid)) { ++ feature_val = seg->feature_data[segid][feature_id]; ++ val |= RKVDEC_SEGID_FRAME_LOOPFILTER_VALUE_EN(1) | ++ RKVDEC_SEGID_FRAME_LOOPFILTER_VALUE(feature_val); ++ } ++ ++ feature_id = V4L2_VP9_SEGMENT_FEATURE_REF_FRAME; ++ if (seg_featured_enabled(seg, feature_id, segid)) { ++ feature_val = seg->feature_data[segid][feature_id]; ++ val |= RKVDEC_SEGID_REFERINFO_EN(1) | ++ RKVDEC_SEGID_REFERINFO(feature_val); ++ } ++ ++ feature_id = V4L2_VP9_SEGMENT_FEATURE_SKIP; ++ if (seg_featured_enabled(seg, feature_id, segid)) ++ val |= RKVDEC_SEGID_FRAME_SKIP_EN(1); ++ ++ if (!segid && ++ (seg->flags & V4L2_VP9_SEGMENTATION_FLAG_ABS_OR_DELTA_UPDATE)) ++ val |= RKVDEC_SEGID_ABS_DELTA(1); ++ ++ writel_relaxed(val, rkvdec->regs + RKVDEC_VP9_SEGID_GRP(segid)); ++} ++ ++static void ++update_dec_buf_info(struct rkvdec_decoded_buffer *buf, ++ const struct v4l2_ctrl_vp9_frame_decode_params *dec_params) ++{ ++ buf->vp9.width = dec_params->frame_width_minus_1 + 1; ++ buf->vp9.height = dec_params->frame_height_minus_1 + 1; ++ buf->vp9.bit_depth = dec_params->bit_depth; ++} ++ ++static void ++update_ctx_cur_info(struct rkvdec_vp9_ctx *vp9_ctx, ++ struct rkvdec_decoded_buffer *buf, ++ const struct v4l2_ctrl_vp9_frame_decode_params *dec_params) ++{ ++ vp9_ctx->cur.valid = true; ++ vp9_ctx->cur.frame_context_idx = dec_params->frame_context_idx; ++ vp9_ctx->cur.reference_mode = dec_params->reference_mode; ++ vp9_ctx->cur.tx_mode = dec_params->tx_mode; ++ vp9_ctx->cur.interpolation_filter = dec_params->interpolation_filter; ++ vp9_ctx->cur.flags = dec_params->flags; ++ vp9_ctx->cur.timestamp = buf->base.vb.vb2_buf.timestamp; ++ vp9_ctx->cur.seg = dec_params->seg; ++ vp9_ctx->cur.lf = dec_params->lf; ++} ++ ++static void ++update_ctx_last_info(struct rkvdec_vp9_ctx *vp9_ctx) ++{ ++ vp9_ctx->last = vp9_ctx->cur; ++} ++ ++static void config_registers(struct rkvdec_ctx *ctx, ++ const struct rkvdec_vp9_run *run) ++{ ++ u32 y_len, uv_len, yuv_len, bit_depth, aligned_height, aligned_pitch; ++ const struct v4l2_ctrl_vp9_frame_decode_params *dec_params; ++ struct rkvdec_decoded_buffer *ref_bufs[V4L2_REF_ID_CNT]; ++ struct rkvdec_decoded_buffer *dst, *last, *mv_ref; ++ struct rkvdec_vp9_ctx *vp9_ctx = ctx->priv; ++ u32 val, stream_len, last_frame_info = 0; ++ const struct v4l2_vp9_segmentation *seg; ++ struct rkvdec_dev *rkvdec = ctx->dev; ++ dma_addr_t addr; ++ bool intra_only; ++ unsigned int i; ++ ++ dec_params = run->decode_params; ++ dst = vb2_to_rkvdec_decoded_buf(&run->base.bufs.dst->vb2_buf); ++ for (i = 0; i < ARRAY_SIZE(ref_bufs); i++) ++ ref_bufs[i] = get_ref_buf(ctx, &dst->base.vb, ++ dec_params->refs[i]); ++ ++ if (vp9_ctx->last.valid) ++ last = get_ref_buf(ctx, &dst->base.vb, vp9_ctx->last.timestamp); ++ else ++ last = dst; ++ ++ update_dec_buf_info(dst, dec_params); ++ update_ctx_cur_info(vp9_ctx, dst, dec_params); ++ seg = &dec_params->seg; ++ ++ intra_only = !!(dec_params->flags & ++ (V4L2_VP9_FRAME_FLAG_KEY_FRAME | ++ V4L2_VP9_FRAME_FLAG_INTRA_ONLY)); ++ ++ writel_relaxed(RKVDEC_MODE(RKVDEC_MODE_VP9), ++ rkvdec->regs + RKVDEC_REG_SYSCTRL); ++ ++ bit_depth = dec_params->bit_depth; ++ aligned_height = round_up(ctx->decoded_fmt.fmt.pix_mp.height, 64); ++ ++ aligned_pitch = round_up(ctx->decoded_fmt.fmt.pix_mp.width * ++ bit_depth, ++ 512) / 8; ++ y_len = aligned_height * aligned_pitch; ++ uv_len = y_len / 2; ++ yuv_len = y_len + uv_len; ++ ++ writel_relaxed(RKVDEC_Y_HOR_VIRSTRIDE(aligned_pitch / 16) | ++ RKVDEC_UV_HOR_VIRSTRIDE(aligned_pitch / 16), ++ rkvdec->regs + RKVDEC_REG_PICPAR); ++ writel_relaxed(RKVDEC_Y_VIRSTRIDE(y_len / 16), ++ rkvdec->regs + RKVDEC_REG_Y_VIRSTRIDE); ++ writel_relaxed(RKVDEC_YUV_VIRSTRIDE(yuv_len / 16), ++ rkvdec->regs + RKVDEC_REG_YUV_VIRSTRIDE); ++ ++ stream_len = vb2_get_plane_payload(&run->base.bufs.src->vb2_buf, 0); ++ writel_relaxed(RKVDEC_STRM_LEN(stream_len), ++ rkvdec->regs + RKVDEC_REG_STRM_LEN); ++ ++ /* ++ * Reset count buffer, because decoder only output intra related syntax ++ * counts when decoding intra frame, but update entropy need to update ++ * all the probabilities. ++ */ ++ if (intra_only) ++ memset(vp9_ctx->count_tbl.cpu, 0, vp9_ctx->count_tbl.size); ++ ++ vp9_ctx->cur.segmapid = vp9_ctx->last.segmapid; ++ if (!intra_only && ++ !(dec_params->flags & V4L2_VP9_FRAME_FLAG_ERROR_RESILIENT) && ++ (!(seg->flags & V4L2_VP9_SEGMENTATION_FLAG_ENABLED) || ++ (seg->flags & V4L2_VP9_SEGMENTATION_FLAG_UPDATE_MAP))) ++ vp9_ctx->cur.segmapid++; ++ ++ for (i = 0; i < ARRAY_SIZE(ref_bufs); i++) ++ config_ref_registers(ctx, run, ref_bufs, i); ++ ++ for (i = 0; i < 8; i++) ++ config_seg_registers(ctx, i); ++ ++ writel_relaxed(RKVDEC_VP9_TX_MODE(dec_params->tx_mode) | ++ RKVDEC_VP9_FRAME_REF_MODE(dec_params->reference_mode), ++ rkvdec->regs + RKVDEC_VP9_CPRHEADER_CONFIG); ++ ++ if (!intra_only) { ++ const struct v4l2_vp9_loop_filter *lf; ++ s8 delta; ++ ++ if (vp9_ctx->last.valid) ++ lf = &vp9_ctx->last.lf; ++ else ++ lf = &vp9_ctx->cur.lf; ++ ++ val = 0; ++ for (i = 0; i < ARRAY_SIZE(lf->ref_deltas); i++) { ++ delta = lf->ref_deltas[i]; ++ val |= RKVDEC_REF_DELTAS_LASTFRAME(i, delta); ++ } ++ ++ writel_relaxed(val, ++ rkvdec->regs + RKVDEC_VP9_REF_DELTAS_LASTFRAME); ++ ++ for (i = 0; i < ARRAY_SIZE(lf->mode_deltas); i++) { ++ delta = lf->mode_deltas[i]; ++ last_frame_info |= RKVDEC_MODE_DELTAS_LASTFRAME(i, ++ delta); ++ } ++ } ++ ++ if (vp9_ctx->last.valid && !intra_only && ++ vp9_ctx->last.seg.flags & V4L2_VP9_SEGMENTATION_FLAG_ENABLED) ++ last_frame_info |= RKVDEC_SEG_EN_LASTFRAME; ++ ++ if (vp9_ctx->last.valid && ++ vp9_ctx->last.flags & V4L2_VP9_FRAME_FLAG_SHOW_FRAME) ++ last_frame_info |= RKVDEC_LAST_SHOW_FRAME; ++ ++ if (vp9_ctx->last.valid && ++ vp9_ctx->last.flags & ++ (V4L2_VP9_FRAME_FLAG_KEY_FRAME | V4L2_VP9_FRAME_FLAG_INTRA_ONLY)) ++ last_frame_info |= RKVDEC_LAST_INTRA_ONLY; ++ ++ if (vp9_ctx->last.valid && ++ last->vp9.width == dst->vp9.width && ++ last->vp9.height == dst->vp9.height) ++ last_frame_info |= RKVDEC_LAST_WIDHHEIGHT_EQCUR; ++ ++ writel_relaxed(last_frame_info, ++ rkvdec->regs + RKVDEC_VP9_INFO_LASTFRAME); ++ ++ writel_relaxed(stream_len - dec_params->compressed_header_size - ++ dec_params->uncompressed_header_size, ++ rkvdec->regs + RKVDEC_VP9_LASTTILE_SIZE); ++ ++ for (i = 0; !intra_only && i < ARRAY_SIZE(ref_bufs); i++) { ++ u32 refw = ref_bufs[i]->vp9.width; ++ u32 refh = ref_bufs[i]->vp9.height; ++ u32 hscale, vscale; ++ ++ hscale = (refw << 14) / dst->vp9.width; ++ vscale = (refh << 14) / dst->vp9.height; ++ writel_relaxed(RKVDEC_VP9_REF_HOR_SCALE(hscale) | ++ RKVDEC_VP9_REF_VER_SCALE(vscale), ++ rkvdec->regs + RKVDEC_VP9_REF_SCALE(i)); ++ } ++ ++ addr = vb2_dma_contig_plane_dma_addr(&dst->base.vb.vb2_buf, 0); ++ writel_relaxed(addr, rkvdec->regs + RKVDEC_REG_DECOUT_BASE); ++ addr = vb2_dma_contig_plane_dma_addr(&run->base.bufs.src->vb2_buf, 0); ++ writel_relaxed(addr, rkvdec->regs + RKVDEC_REG_STRM_RLC_BASE); ++ writel_relaxed(vp9_ctx->priv_tbl.dma + ++ offsetof(struct rkvdec_vp9_priv_tbl, probs), ++ rkvdec->regs + RKVDEC_REG_CABACTBL_PROB_BASE); ++ writel_relaxed(vp9_ctx->count_tbl.dma, ++ rkvdec->regs + RKVDEC_REG_VP9COUNT_BASE); ++ ++ writel_relaxed(vp9_ctx->priv_tbl.dma + ++ offsetof(struct rkvdec_vp9_priv_tbl, segmap) + ++ (RKVDEC_VP9_MAX_SEGMAP_SIZE * vp9_ctx->cur.segmapid), ++ rkvdec->regs + RKVDEC_REG_VP9_SEGIDCUR_BASE); ++ writel_relaxed(vp9_ctx->priv_tbl.dma + ++ offsetof(struct rkvdec_vp9_priv_tbl, segmap) + ++ (RKVDEC_VP9_MAX_SEGMAP_SIZE * (!vp9_ctx->cur.segmapid)), ++ rkvdec->regs + RKVDEC_REG_VP9_SEGIDLAST_BASE); ++ ++ if (!intra_only && ++ !(dec_params->flags & V4L2_VP9_FRAME_FLAG_ERROR_RESILIENT) && ++ vp9_ctx->last.valid) ++ mv_ref = last; ++ else ++ mv_ref = dst; ++ ++ writel_relaxed(get_mv_base_addr(mv_ref), ++ rkvdec->regs + RKVDEC_VP9_REF_COLMV_BASE); ++ ++ writel_relaxed(ctx->decoded_fmt.fmt.pix_mp.width | ++ (ctx->decoded_fmt.fmt.pix_mp.height << 16), ++ rkvdec->regs + RKVDEC_REG_PERFORMANCE_CYCLE); ++} ++ ++static int ++validate_dec_params(struct rkvdec_ctx *ctx, ++ const struct v4l2_ctrl_vp9_frame_decode_params *dec_params) ++{ ++ unsigned int aligned_width, aligned_height; ++ ++ /* We only support profile 0. */ ++ if (dec_params->profile != 0) { ++ dev_err(ctx->dev->dev, "unsupported profile %d\n", ++ dec_params->profile); ++ return -EINVAL; ++ } ++ ++ aligned_width = round_up(dec_params->frame_width_minus_1 + 1, 64); ++ aligned_height = round_up(dec_params->frame_height_minus_1 + 1, 64); ++ ++ /* ++ * Userspace should update the capture/decoded format when the ++ * resolution changes. ++ */ ++ if (aligned_width != ctx->decoded_fmt.fmt.pix_mp.width || ++ aligned_height != ctx->decoded_fmt.fmt.pix_mp.height) { ++ dev_err(ctx->dev->dev, ++ "unexpected bitstream resolution %dx%d\n", ++ dec_params->frame_width_minus_1 + 1, ++ dec_params->frame_height_minus_1 +1); ++ return -EINVAL; ++ } ++ ++ return 0; ++} ++ ++static int rkvdec_vp9_run_preamble(struct rkvdec_ctx *ctx, ++ struct rkvdec_vp9_run *run) ++{ ++ const struct v4l2_ctrl_vp9_frame_decode_params *dec_params; ++ const struct v4l2_ctrl_vp9_frame_ctx *fctx = NULL; ++ struct rkvdec_vp9_ctx *vp9_ctx = ctx->priv; ++ struct v4l2_ctrl *ctrl; ++ u8 frm_ctx; ++ int ret; ++ ++ rkvdec_run_preamble(ctx, &run->base); ++ ++ ctrl = v4l2_ctrl_find(&ctx->ctrl_hdl, ++ V4L2_CID_MPEG_VIDEO_VP9_FRAME_DECODE_PARAMS); ++ WARN_ON(!ctrl); ++ ++ dec_params = ctrl ? ctrl->p_cur.p : NULL; ++ if (WARN_ON(!dec_params)) ++ return -EINVAL; ++ ++ ret = validate_dec_params(ctx, dec_params); ++ if (ret) ++ return ret; ++ ++ run->decode_params = dec_params; ++ ++ /* No need to load the frame context if we don't need to update it. */ ++ if (!(dec_params->flags & V4L2_VP9_FRAME_FLAG_REFRESH_FRAME_CTX)) ++ return 0; ++ ++ /* ++ * When a refresh context is requested in parallel mode, we should just ++ * update the context with the probs passed in the decode parameters. ++ */ ++ if (dec_params->flags & V4L2_VP9_FRAME_FLAG_PARALLEL_DEC_MODE) { ++ vp9_ctx->frame_context.probs = dec_params->probs; ++ return 0; ++ } ++ ++ frm_ctx = run->decode_params->frame_context_idx; ++ ctrl = v4l2_ctrl_find(&ctx->ctrl_hdl, ++ V4L2_CID_MPEG_VIDEO_VP9_FRAME_CONTEXT(frm_ctx)); ++ if (WARN_ON(!ctrl)) ++ return 0; ++ ++ fctx = ctrl->p_cur.p; ++ vp9_ctx->frame_context = *fctx; ++ ++ /* ++ * For intra-only frames, we must update the context TX and skip probs ++ * with the value passed in the decode params. ++ */ ++ if (dec_params->flags & ++ (V4L2_VP9_FRAME_FLAG_KEY_FRAME | V4L2_VP9_FRAME_FLAG_INTRA_ONLY)) { ++ struct v4l2_vp9_probabilities *probs; ++ ++ probs = &vp9_ctx->frame_context.probs; ++ memcpy(probs->skip, dec_params->probs.skip, ++ sizeof(probs->skip)); ++ memcpy(probs->tx8, dec_params->probs.tx8, ++ sizeof(probs->tx8)); ++ memcpy(probs->tx16, dec_params->probs.tx16, ++ sizeof(probs->tx16)); ++ memcpy(probs->tx32, dec_params->probs.tx32, ++ sizeof(probs->tx32)); ++ } ++ ++ return 0; ++} ++ ++static int rkvdec_vp9_run(struct rkvdec_ctx *ctx) ++{ ++ struct rkvdec_dev *rkvdec = ctx->dev; ++ struct rkvdec_vp9_run run = { }; ++ int ret; ++ ++ ret = rkvdec_vp9_run_preamble(ctx, &run); ++ if (ret) { ++ rkvdec_run_postamble(ctx, &run.base); ++ return ret; ++ } ++ ++ /* Prepare probs. */ ++ init_probs(ctx, &run); ++ ++ /* Configure hardware registers. */ ++ config_registers(ctx, &run); ++ ++ rkvdec_run_postamble(ctx, &run.base); ++ ++ schedule_delayed_work(&rkvdec->watchdog_work, msecs_to_jiffies(2000)); ++ ++ writel(1, rkvdec->regs + RKVDEC_REG_PREF_LUMA_CACHE_COMMAND); ++ writel(1, rkvdec->regs + RKVDEC_REG_PREF_CHR_CACHE_COMMAND); ++ ++ writel(0xe, rkvdec->regs + RKVDEC_REG_STRMD_ERR_EN); ++ /* 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; ++} ++ ++static u8 adapt_prob(u8 p1, u32 ct0, u32 ct1, u16 max_count, u32 update_factor) ++{ ++ u32 ct = ct0 + ct1, p2; ++ u32 lo = 1; ++ u32 hi = 255; ++ ++ if (!ct) ++ return p1; ++ ++ p2 = ((ct0 << 8) + (ct >> 1)) / ct; ++ p2 = clamp(p2, lo, hi); ++ ct = min_t(u32, ct, max_count); ++ ++ if (WARN_ON(max_count >= 257)) ++ return p1; ++ ++ update_factor = rkvdec_fastdiv(update_factor * ct, max_count); ++ ++ return p1 + (((p2 - p1) * update_factor + 128) >> 8); ++} ++ ++#define BAND_6(band) ((band) == 0 ? 3 : 6) ++ ++static void adapt_coeff(u8 coef[6][6][3], ++ const struct rkvdec_vp9_refs_counts ref_cnt[6][6], ++ u32 uf) ++{ ++ s32 l, m, n; ++ ++ for (l = 0; l < 6; l++) { ++ for (m = 0; m < BAND_6(l); m++) { ++ u8 *p = coef[l][m]; ++ const u32 n0 = ref_cnt[l][m].coeff[0]; ++ const u32 n1 = ref_cnt[l][m].coeff[1]; ++ const u32 n2 = ref_cnt[l][m].coeff[2]; ++ const u32 neob = ref_cnt[l][m].eob[1]; ++ const u32 eob_count = ref_cnt[l][m].eob[0]; ++ const u32 branch_ct[3][2] = { ++ { neob, eob_count - neob }, ++ { n0, n1 + n2 }, ++ { n1, n2 } ++ }; ++ ++ for (n = 0; n < 3; n++) ++ p[n] = adapt_prob(p[n], branch_ct[n][0], ++ branch_ct[n][1], 24, uf); ++ } ++ } ++} ++ ++static void ++adapt_coef_probs(struct v4l2_vp9_probabilities *probs, ++ const struct rkvdec_vp9_refs_counts ref_cnt[2][4][2][6][6], ++ unsigned int uf) ++{ ++ unsigned int i, j, k; ++ ++ for (i = 0; i < ARRAY_SIZE(probs->coef); i++) { ++ for (j = 0; j < ARRAY_SIZE(probs->coef[0]); j++) { ++ for (k = 0; k < ARRAY_SIZE(probs->coef[0][0]); ++ k++) { ++ adapt_coeff(probs->coef[i][j][k], ++ ref_cnt[k][i][j], ++ uf); ++ } ++ } ++ } ++} ++ ++static void adapt_intra_frame_probs(struct rkvdec_ctx *ctx) ++{ ++ struct rkvdec_vp9_ctx *vp9_ctx = ctx->priv; ++ struct v4l2_vp9_probabilities *probs = &vp9_ctx->frame_context.probs; ++ const struct rkvdec_vp9_intra_frame_symbol_counts *sym_cnts; ++ ++ sym_cnts = vp9_ctx->count_tbl.cpu; ++ adapt_coef_probs(probs, sym_cnts->ref_cnt, 112); ++} ++ ++static void ++adapt_skip_probs(struct v4l2_vp9_probabilities *probs, ++ const struct rkvdec_vp9_inter_frame_symbol_counts *sym_cnts) ++{ ++ unsigned int i; ++ ++ for (i = 0; i < ARRAY_SIZE(probs->skip); i++) ++ probs->skip[i] = adapt_prob(probs->skip[i], ++ sym_cnts->skip[i][0], ++ sym_cnts->skip[i][1], ++ 20, 128); ++} ++ ++static void ++adapt_is_inter_probs(struct v4l2_vp9_probabilities *probs, ++ const struct rkvdec_vp9_inter_frame_symbol_counts *sym_cnts) ++{ ++ unsigned int i; ++ ++ for (i = 0; i < ARRAY_SIZE(probs->is_inter); i++) ++ probs->is_inter[i] = adapt_prob(probs->is_inter[i], ++ sym_cnts->inter[i][0], ++ sym_cnts->inter[i][1], ++ 20, 128); ++} ++ ++static void ++adapt_comp_mode_probs(struct v4l2_vp9_probabilities *probs, ++ const struct rkvdec_vp9_inter_frame_symbol_counts *sym_cnts) ++{ ++ unsigned int i; ++ ++ for (i = 0; i < ARRAY_SIZE(probs->comp_mode); i++) ++ probs->comp_mode[i] = adapt_prob(probs->comp_mode[i], ++ sym_cnts->comp[i][0], ++ sym_cnts->comp[i][1], ++ 20, 128); ++} ++ ++static void ++adapt_comp_ref_probs(struct v4l2_vp9_probabilities *probs, ++ const struct rkvdec_vp9_inter_frame_symbol_counts *sym_cnts) ++{ ++ unsigned int i; ++ ++ for (i = 0; i < ARRAY_SIZE(probs->comp_ref); i++) ++ probs->comp_ref[i] = adapt_prob(probs->comp_ref[i], ++ sym_cnts->comp_ref[i][0], ++ sym_cnts->comp_ref[i][1], ++ 20, 128); ++} ++ ++static void ++adapt_single_ref_probs(struct v4l2_vp9_probabilities *probs, ++ const struct rkvdec_vp9_inter_frame_symbol_counts *sym_cnts) ++{ ++ unsigned int i; ++ ++ for (i = 0; i < ARRAY_SIZE(probs->single_ref); i++) { ++ u8 *p = probs->single_ref[i]; ++ ++ p[0] = adapt_prob(p[0], sym_cnts->single_ref[i][0][0], ++ sym_cnts->single_ref[i][0][1], 20, 128); ++ p[1] = adapt_prob(p[1], sym_cnts->single_ref[i][1][0], ++ sym_cnts->single_ref[i][1][1], 20, 128); ++ } ++} ++ ++static void ++adapt_partition_probs(struct v4l2_vp9_probabilities *probs, ++ const struct rkvdec_vp9_inter_frame_symbol_counts *sym_cnts) ++{ ++ unsigned int i; ++ ++ for (i = 0; i < ARRAY_SIZE(probs->partition); i++) { ++ const u32 *c = sym_cnts->partition[i]; ++ u8 *p = probs->partition[i]; ++ ++ p[0] = adapt_prob(p[0], c[0], c[1] + c[2] + c[3], 20, 128); ++ p[1] = adapt_prob(p[1], c[1], c[2] + c[3], 20, 128); ++ p[2] = adapt_prob(p[2], c[2], c[3], 20, 128); ++ } ++} ++ ++static void ++adapt_tx_probs(struct v4l2_vp9_probabilities *probs, ++ const struct rkvdec_vp9_inter_frame_symbol_counts *sym_cnts) ++{ ++ unsigned int i; ++ ++ for (i = 0; i < ARRAY_SIZE(probs->tx8); i++) { ++ u8 *p16x16 = probs->tx16[i]; ++ u8 *p32x32 = probs->tx32[i]; ++ const u32 *c16 = sym_cnts->tx16p[i]; ++ const u32 *c32 = sym_cnts->tx32p[i]; ++ const u32 *c8 = sym_cnts->tx8p[i]; ++ u8 *p8x8 = probs->tx8[i]; ++ ++ p8x8[0] = adapt_prob(p8x8[0], c8[0], c8[1], 20, 128); ++ p16x16[0] = adapt_prob(p16x16[0], c16[0], c16[1] + c16[2], ++ 20, 128); ++ p16x16[1] = adapt_prob(p16x16[1], c16[1], c16[2], 20, 128); ++ p32x32[0] = adapt_prob(p32x32[0], c32[0], ++ c32[1] + c32[2] + c32[3], 20, 128); ++ p32x32[1] = adapt_prob(p32x32[1], c32[1], c32[2] + c32[3], ++ 20, 128); ++ p32x32[2] = adapt_prob(p32x32[2], c32[2], c32[3], 20, 128); ++ } ++} ++ ++static void ++adapt_interp_filter_probs(struct v4l2_vp9_probabilities *probs, ++ const struct rkvdec_vp9_inter_frame_symbol_counts *sym_cnts) ++{ ++ unsigned int i; ++ ++ for (i = 0; i < ARRAY_SIZE(probs->interp_filter); i++) { ++ u8 *p = probs->interp_filter[i]; ++ const u32 *c = sym_cnts->filter[i]; ++ ++ p[0] = adapt_prob(p[0], c[0], c[1] + c[2], 20, 128); ++ p[1] = adapt_prob(p[1], c[1], c[2], 20, 128); ++ } ++} ++ ++static void ++adapt_inter_mode_probs(struct v4l2_vp9_probabilities *probs, ++ const struct rkvdec_vp9_inter_frame_symbol_counts *sym_cnts) ++{ ++ unsigned int i; ++ ++ for (i = 0; i < ARRAY_SIZE(probs->inter_mode); i++) { ++ const u32 *c = sym_cnts->mv_mode[i]; ++ u8 *p = probs->inter_mode[i]; ++ ++ p[0] = adapt_prob(p[0], c[2], c[1] + c[0] + c[3], 20, 128); ++ p[1] = adapt_prob(p[1], c[0], c[1] + c[3], 20, 128); ++ p[2] = adapt_prob(p[2], c[1], c[3], 20, 128); ++ } ++} ++ ++static void ++adapt_mv_probs(struct v4l2_vp9_probabilities *probs, ++ const struct rkvdec_vp9_inter_frame_symbol_counts *sym_cnts, ++ bool high_prec_mv) ++{ ++ const u32 *c = sym_cnts->mv_joint; ++ u8 *p = probs->mv.joint; ++ unsigned int i, j; ++ u32 sum; ++ ++ p[0] = adapt_prob(p[0], c[0], c[1] + c[2] + c[3], 20, 128); ++ p[1] = adapt_prob(p[1], c[1], c[2] + c[3], 20, 128); ++ p[2] = adapt_prob(p[2], c[2], c[3], 20, 128); ++ ++ for (i = 0; i < ARRAY_SIZE(probs->mv.sign); i++) { ++ p = probs->mv.sign; ++ ++ p[i] = adapt_prob(p[i], sym_cnts->sign[i][0], ++ sym_cnts->sign[i][1], 20, 128); ++ ++ p = probs->mv.class[i]; ++ c = sym_cnts->classes[i]; ++ sum = c[1] + c[2] + c[3] + c[4] + c[5] + c[6] + c[7] + c[8] + ++ c[9] + c[10]; ++ p[0] = adapt_prob(p[0], c[0], sum, 20, 128); ++ sum -= c[1]; ++ p[1] = adapt_prob(p[1], c[1], sum, 20, 128); ++ sum -= c[2] + c[3]; ++ p[2] = adapt_prob(p[2], c[2] + c[3], sum, 20, 128); ++ p[3] = adapt_prob(p[3], c[2], c[3], 20, 128); ++ sum -= c[4] + c[5]; ++ p[4] = adapt_prob(p[4], c[4] + c[5], sum, 20, 128); ++ p[5] = adapt_prob(p[5], c[4], c[5], 20, 128); ++ sum -= c[6]; ++ p[6] = adapt_prob(p[6], c[6], sum, 20, 128); ++ p[7] = adapt_prob(p[7], c[7] + c[8], c[9] + c[10], 20, 128); ++ p[8] = adapt_prob(p[8], c[7], c[8], 20, 128); ++ p[9] = adapt_prob(p[9], c[9], c[10], 20, 128); ++ ++ p = probs->mv.class0_bit; ++ p[i] = adapt_prob(p[i], ++ sym_cnts->class0[i][0], ++ sym_cnts->class0[i][1], 20, 128); ++ ++ p = probs->mv.bits[i]; ++ for (j = 0; j < 10; j++) ++ p[j] = adapt_prob(p[j], sym_cnts->bits[i][j][0], ++ sym_cnts->bits[i][j][1], 20, 128); ++ ++ for (j = 0; j < 2; j++) { ++ p = probs->mv.class0_fr[i][j]; ++ c = sym_cnts->class0_fp[i][j]; ++ p[0] = adapt_prob(p[0], c[0], c[1] + c[2] + c[3], ++ 20, 128); ++ p[1] = adapt_prob(p[1], c[1], c[2] + c[3], 20, 128); ++ p[2] = adapt_prob(p[2], c[2], c[3], 20, 128); ++ } ++ ++ p = probs->mv.fr[i]; ++ c = sym_cnts->fp[i]; ++ p[0] = adapt_prob(p[0], c[0], c[1] + c[2] + c[3], 20, 128); ++ p[1] = adapt_prob(p[1], c[1], c[2] + c[3], 20, 128); ++ p[2] = adapt_prob(p[2], c[2], c[3], 20, 128); ++ ++ if (!high_prec_mv) ++ continue; ++ ++ p = probs->mv.class0_hp; ++ p[i] = adapt_prob(p[i], sym_cnts->class0_hp[i][0], ++ sym_cnts->class0_hp[i][1], 20, 128); ++ ++ p = probs->mv.hp; ++ p[i] = adapt_prob(p[i], sym_cnts->hp[i][0], ++ sym_cnts->hp[i][1], 20, 128); ++ } ++} ++ ++static void ++adapt_intra_mode_probs(u8 *p, const u32 *c) ++{ ++ u32 sum = 0, s2; ++ unsigned int i; ++ ++ for (i = V4L2_VP9_INTRA_PRED_MODE_V; i <= V4L2_VP9_INTRA_PRED_MODE_TM; ++ i++) ++ sum += c[i]; ++ ++ p[0] = adapt_prob(p[0], c[V4L2_VP9_INTRA_PRED_MODE_DC], sum, 20, 128); ++ sum -= c[V4L2_VP9_INTRA_PRED_MODE_TM]; ++ p[1] = adapt_prob(p[1], c[V4L2_VP9_INTRA_PRED_MODE_TM], sum, 20, 128); ++ sum -= c[V4L2_VP9_INTRA_PRED_MODE_V]; ++ p[2] = adapt_prob(p[2], c[V4L2_VP9_INTRA_PRED_MODE_V], sum, 20, 128); ++ s2 = c[V4L2_VP9_INTRA_PRED_MODE_H] + c[V4L2_VP9_INTRA_PRED_MODE_D135] + ++ c[V4L2_VP9_INTRA_PRED_MODE_D117]; ++ sum -= s2; ++ p[3] = adapt_prob(p[3], s2, sum, 20, 128); ++ s2 -= c[V4L2_VP9_INTRA_PRED_MODE_H]; ++ p[4] = adapt_prob(p[4], c[V4L2_VP9_INTRA_PRED_MODE_H], s2, 20, 128); ++ p[5] = adapt_prob(p[5], c[V4L2_VP9_INTRA_PRED_MODE_D135], ++ c[V4L2_VP9_INTRA_PRED_MODE_D117], 20, 128); ++ sum -= c[V4L2_VP9_INTRA_PRED_MODE_D45]; ++ p[6] = adapt_prob(p[6], c[V4L2_VP9_INTRA_PRED_MODE_D45], ++ sum, 20, 128); ++ sum -= c[V4L2_VP9_INTRA_PRED_MODE_D63]; ++ p[7] = adapt_prob(p[7], c[V4L2_VP9_INTRA_PRED_MODE_D63], sum, ++ 20, 128); ++ p[8] = adapt_prob(p[8], c[V4L2_VP9_INTRA_PRED_MODE_D153], ++ c[V4L2_VP9_INTRA_PRED_MODE_D207], 20, 128); ++} ++ ++static void ++adapt_y_intra_mode_probs(struct v4l2_vp9_probabilities *probs, ++ const struct rkvdec_vp9_inter_frame_symbol_counts *sym_cnts) ++{ ++ unsigned int i; ++ ++ for (i = 0; i < ARRAY_SIZE(probs->y_mode); i++) ++ adapt_intra_mode_probs(probs->y_mode[i], sym_cnts->y_mode[i]); ++} ++ ++static void ++adapt_uv_intra_mode_probs(struct v4l2_vp9_probabilities *probs, ++ const struct rkvdec_vp9_inter_frame_symbol_counts *sym_cnts) ++{ ++ unsigned int i; ++ ++ for (i = 0; i < ARRAY_SIZE(probs->uv_mode); i++) ++ adapt_intra_mode_probs(probs->uv_mode[i], ++ sym_cnts->uv_mode[i]); ++} ++ ++static void ++adapt_inter_frame_probs(struct rkvdec_ctx *ctx) ++{ ++ struct rkvdec_vp9_ctx *vp9_ctx = ctx->priv; ++ struct v4l2_vp9_probabilities *probs = &vp9_ctx->frame_context.probs; ++ const struct rkvdec_vp9_inter_frame_symbol_counts *sym_cnts; ++ ++ sym_cnts = vp9_ctx->count_tbl.cpu; ++ /* coefficients */ ++ if (vp9_ctx->last.valid && ++ !(vp9_ctx->last.flags & V4L2_VP9_FRAME_FLAG_KEY_FRAME)) ++ adapt_coef_probs(probs, sym_cnts->ref_cnt, 112); ++ else ++ adapt_coef_probs(probs, sym_cnts->ref_cnt, 128); ++ ++ /* skip flag */ ++ adapt_skip_probs(probs, sym_cnts); ++ ++ /* intra/inter flag */ ++ adapt_is_inter_probs(probs, sym_cnts); ++ ++ /* comppred flag */ ++ adapt_comp_mode_probs(probs, sym_cnts); ++ ++ /* reference frames */ ++ adapt_comp_ref_probs(probs, sym_cnts); ++ ++ if (vp9_ctx->cur.reference_mode != V4L2_VP9_REF_MODE_COMPOUND) ++ adapt_single_ref_probs(probs, sym_cnts); ++ ++ /* block partitioning */ ++ adapt_partition_probs(probs, sym_cnts); ++ ++ /* tx size */ ++ if (vp9_ctx->cur.tx_mode == V4L2_VP9_TX_MODE_SELECT) ++ adapt_tx_probs(probs, sym_cnts); ++ ++ /* interpolation filter */ ++ if (vp9_ctx->cur.interpolation_filter == V4L2_VP9_INTERP_FILTER_SWITCHABLE) ++ adapt_interp_filter_probs(probs, sym_cnts); ++ ++ /* inter modes */ ++ adapt_inter_mode_probs(probs, sym_cnts); ++ ++ /* mv probs */ ++ adapt_mv_probs(probs, sym_cnts, ++ !!(vp9_ctx->cur.flags & ++ V4L2_VP9_FRAME_FLAG_ALLOW_HIGH_PREC_MV)); ++ ++ /* y intra modes */ ++ adapt_y_intra_mode_probs(probs, sym_cnts); ++ ++ /* uv intra modes */ ++ adapt_uv_intra_mode_probs(probs, sym_cnts); ++} ++ ++static void adapt_probs(struct rkvdec_ctx *ctx) ++{ ++ struct rkvdec_vp9_ctx *vp9_ctx = ctx->priv; ++ bool intra_only; ++ ++ intra_only = !!(vp9_ctx->cur.flags & ++ (V4L2_VP9_FRAME_FLAG_KEY_FRAME | ++ V4L2_VP9_FRAME_FLAG_INTRA_ONLY)); ++ ++ if (intra_only) ++ adapt_intra_frame_probs(ctx); ++ else ++ adapt_inter_frame_probs(ctx); ++} ++ ++static void rkvdec_vp9_done(struct rkvdec_ctx *ctx, ++ struct vb2_v4l2_buffer *src_buf, ++ struct vb2_v4l2_buffer *dst_buf, ++ enum vb2_buffer_state result) ++{ ++ struct rkvdec_vp9_ctx *vp9_ctx = ctx->priv; ++ struct v4l2_ctrl *ctrl; ++ unsigned int fctx_idx; ++ ++ if (result == VB2_BUF_STATE_ERROR) ++ goto out_update_last; ++ ++ if (!(vp9_ctx->cur.flags & V4L2_VP9_FRAME_FLAG_REFRESH_FRAME_CTX)) ++ goto out_update_last; ++ ++ fctx_idx = vp9_ctx->cur.frame_context_idx; ++ ++ if (!(vp9_ctx->cur.flags & ++ (V4L2_VP9_FRAME_FLAG_ERROR_RESILIENT | ++ V4L2_VP9_FRAME_FLAG_PARALLEL_DEC_MODE))) ++ adapt_probs(ctx); ++ ++ ctrl = v4l2_ctrl_find(&ctx->ctrl_hdl, ++ V4L2_CID_MPEG_VIDEO_VP9_FRAME_CONTEXT(fctx_idx)); ++ if (WARN_ON(!ctrl)) ++ goto out_update_last; ++ ++ v4l2_ctrl_s_ctrl_compound(ctrl, V4L2_CTRL_TYPE_VP9_FRAME_CONTEXT, ++ &vp9_ctx->frame_context); ++ ++out_update_last: ++ update_ctx_last_info(vp9_ctx); ++} ++ ++static int rkvdec_vp9_start(struct rkvdec_ctx *ctx) ++{ ++ struct rkvdec_dev *rkvdec = ctx->dev; ++ struct rkvdec_vp9_priv_tbl *priv_tbl; ++ struct rkvdec_vp9_ctx *vp9_ctx; ++ u8 *count_tbl; ++ int ret; ++ ++ vp9_ctx = kzalloc(sizeof(*vp9_ctx), GFP_KERNEL); ++ if (!vp9_ctx) ++ return -ENOMEM; ++ ++ ctx->priv = vp9_ctx; ++ ++ priv_tbl = dma_alloc_coherent(rkvdec->dev, sizeof(*priv_tbl), ++ &vp9_ctx->priv_tbl.dma, GFP_KERNEL); ++ if (!priv_tbl) { ++ ret = -ENOMEM; ++ goto err_free_ctx; ++ } ++ ++ vp9_ctx->priv_tbl.size = sizeof(*priv_tbl); ++ vp9_ctx->priv_tbl.cpu = priv_tbl; ++ memset(priv_tbl, 0, sizeof(*priv_tbl)); ++ ++ count_tbl = dma_alloc_coherent(rkvdec->dev, RKVDEC_VP9_COUNT_SIZE, ++ &vp9_ctx->count_tbl.dma, GFP_KERNEL); ++ if (!count_tbl) { ++ ret = -ENOMEM; ++ goto err_free_priv_tbl; ++ } ++ ++ vp9_ctx->count_tbl.size = RKVDEC_VP9_COUNT_SIZE; ++ vp9_ctx->count_tbl.cpu = count_tbl; ++ memset(count_tbl, 0, sizeof(*count_tbl)); ++ ++ return 0; ++ ++err_free_priv_tbl: ++ dma_free_coherent(rkvdec->dev, vp9_ctx->priv_tbl.size, ++ vp9_ctx->priv_tbl.cpu, vp9_ctx->priv_tbl.dma); ++ ++err_free_ctx: ++ kfree(vp9_ctx); ++ return ret; ++} ++ ++static void rkvdec_vp9_stop(struct rkvdec_ctx *ctx) ++{ ++ struct rkvdec_vp9_ctx *vp9_ctx = ctx->priv; ++ struct rkvdec_dev *rkvdec = ctx->dev; ++ ++ dma_free_coherent(rkvdec->dev, vp9_ctx->count_tbl.size, ++ vp9_ctx->count_tbl.cpu, vp9_ctx->count_tbl.dma); ++ dma_free_coherent(rkvdec->dev, vp9_ctx->priv_tbl.size, ++ vp9_ctx->priv_tbl.cpu, vp9_ctx->priv_tbl.dma); ++ kfree(vp9_ctx); ++} ++ ++static int rkvdec_vp9_adjust_fmt(struct rkvdec_ctx *ctx, ++ struct v4l2_format *f) ++{ ++ struct v4l2_pix_format_mplane *fmt = &f->fmt.pix_mp; ++ ++ fmt->num_planes = 1; ++ if (!fmt->plane_fmt[0].sizeimage) ++ fmt->plane_fmt[0].sizeimage = fmt->width * fmt->height * 2; ++ return 0; ++} ++ ++const struct rkvdec_coded_fmt_ops rkvdec_vp9_fmt_ops = { ++ .adjust_fmt = rkvdec_vp9_adjust_fmt, ++ .start = rkvdec_vp9_start, ++ .stop = rkvdec_vp9_stop, ++ .run = rkvdec_vp9_run, ++ .done = rkvdec_vp9_done, ++}; +diff --git a/drivers/staging/media/rkvdec/rkvdec.c b/drivers/staging/media/rkvdec/rkvdec.c +index 86975cd4ebd0..e1eec79fe9a2 100644 +--- a/drivers/staging/media/rkvdec/rkvdec.c ++++ b/drivers/staging/media/rkvdec/rkvdec.c +@@ -159,6 +159,40 @@ static const u32 rkvdec_h264_decoded_fmts[] = { + V4L2_PIX_FMT_NV20, + }; + ++static const struct rkvdec_ctrl_desc rkvdec_vp9_ctrl_descs[] = { ++ { ++ .mandatory = true, ++ .cfg.id = V4L2_CID_MPEG_VIDEO_VP9_FRAME_DECODE_PARAMS, ++ }, ++ { ++ .cfg.id = V4L2_CID_MPEG_VIDEO_VP9_FRAME_CONTEXT(0), ++ }, ++ { ++ .cfg.id = V4L2_CID_MPEG_VIDEO_VP9_FRAME_CONTEXT(1), ++ }, ++ { ++ .cfg.id = V4L2_CID_MPEG_VIDEO_VP9_FRAME_CONTEXT(2), ++ }, ++ { ++ .cfg.id = V4L2_CID_MPEG_VIDEO_VP9_FRAME_CONTEXT(3), ++ }, ++ { ++ .cfg.id = V4L2_CID_MPEG_VIDEO_VP9_PROFILE, ++ .cfg.min = V4L2_MPEG_VIDEO_VP9_PROFILE_0, ++ .cfg.max = V4L2_MPEG_VIDEO_VP9_PROFILE_0, ++ .cfg.def = V4L2_MPEG_VIDEO_VP9_PROFILE_0, ++ }, ++}; ++ ++static const struct rkvdec_ctrls rkvdec_vp9_ctrls = { ++ .ctrls = rkvdec_vp9_ctrl_descs, ++ .num_ctrls = ARRAY_SIZE(rkvdec_vp9_ctrl_descs), ++}; ++ ++static const u32 rkvdec_vp9_decoded_fmts[] = { ++ V4L2_PIX_FMT_NV12, ++}; ++ + static const struct rkvdec_coded_fmt_desc rkvdec_coded_fmts[] = { + { + .fourcc = V4L2_PIX_FMT_H264_SLICE, +@@ -174,6 +208,21 @@ static const struct rkvdec_coded_fmt_desc rkvdec_coded_fmts[] = { + .ops = &rkvdec_h264_fmt_ops, + .num_decoded_fmts = ARRAY_SIZE(rkvdec_h264_decoded_fmts), + .decoded_fmts = rkvdec_h264_decoded_fmts, ++ }, ++ { ++ .fourcc = V4L2_PIX_FMT_VP9_FRAME, ++ .frmsize = { ++ .min_width = 64, ++ .max_width = 4096, ++ .step_width = 64, ++ .min_height = 64, ++ .max_height = 2304, ++ .step_height = 64, ++ }, ++ .ctrls = &rkvdec_vp9_ctrls, ++ .ops = &rkvdec_vp9_fmt_ops, ++ .num_decoded_fmts = ARRAY_SIZE(rkvdec_vp9_decoded_fmts), ++ .decoded_fmts = rkvdec_vp9_decoded_fmts, + } + }; + +@@ -373,7 +422,7 @@ static int rkvdec_s_output_fmt(struct file *file, void *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; ++ struct vb2_queue *peer_vq, *vq; + int ret; + + /* +@@ -385,6 +434,15 @@ static int rkvdec_s_output_fmt(struct file *file, void *priv, + if (vb2_is_busy(peer_vq)) + return -EBUSY; + ++ /* ++ * Some codecs like VP9 can contain dynamic resolution changes which ++ * are currently not supported by the V4L2 API or driver, so return ++ * an error if userspace tries to reconfigure the output format. ++ */ ++ vq = v4l2_m2m_get_vq(m2m_ctx, V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE); ++ if (vb2_is_busy(vq)) ++ return -EINVAL; ++ + ret = rkvdec_s_fmt(file, priv, f, rkvdec_try_output_fmt); + if (ret) + return ret; +diff --git a/drivers/staging/media/rkvdec/rkvdec.h b/drivers/staging/media/rkvdec/rkvdec.h +index e95c52e3168a..5f66f07acac5 100644 +--- a/drivers/staging/media/rkvdec/rkvdec.h ++++ b/drivers/staging/media/rkvdec/rkvdec.h +@@ -51,6 +51,10 @@ struct rkvdec_vp9_decoded_buffer_info { + struct rkvdec_decoded_buffer { + /* Must be the first field in this struct. */ + struct v4l2_m2m_buffer base; ++ ++ union { ++ struct rkvdec_vp9_decoded_buffer_info vp9; ++ }; + }; + + static inline struct rkvdec_decoded_buffer * +@@ -119,4 +123,6 @@ 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; ++extern const struct rkvdec_coded_fmt_ops rkvdec_vp9_fmt_ops; ++ + #endif /* RKVDEC_H_ */ diff --git a/projects/Rockchip/patches/linux/default/linux-2001-v4l-wip-rkvdec-hevc.patch b/projects/Rockchip/patches/linux/default/linux-2001-v4l-wip-rkvdec-hevc.patch new file mode 100644 index 0000000000..9616008761 --- /dev/null +++ b/projects/Rockchip/patches/linux/default/linux-2001-v4l-wip-rkvdec-hevc.patch @@ -0,0 +1,3087 @@ +From 675a97781f4a43807d29473f27ed7888bca0e3e5 Mon Sep 17 00:00:00 2001 +From: Jernej Skrabec +Date: Sat, 26 Oct 2019 13:55:15 +0200 +Subject: [PATCH] media: uapi: hevc: Add scaling matrix control + +HEVC has a scaling matrix concept. Add support for it. + +Signed-off-by: Jernej Skrabec +--- + .../media/v4l/ext-ctrls-codec.rst | 41 +++++++++++++++++++ + .../media/v4l/pixfmt-compressed.rst | 1 + + drivers/media/v4l2-core/v4l2-ctrls.c | 10 +++++ + include/media/hevc-ctrls.h | 11 +++++ + 4 files changed, 63 insertions(+) + +diff --git a/Documentation/userspace-api/media/v4l/ext-ctrls-codec.rst b/Documentation/userspace-api/media/v4l/ext-ctrls-codec.rst +index 456488f2b5ca..81529b1d8d69 100644 +--- a/Documentation/userspace-api/media/v4l/ext-ctrls-codec.rst ++++ b/Documentation/userspace-api/media/v4l/ext-ctrls-codec.rst +@@ -4866,6 +4866,47 @@ enum v4l2_mpeg_video_hevc_size_of_length_field - + - ``padding[6]`` + - Applications and drivers must set this to zero. + ++``V4L2_CID_MPEG_VIDEO_HEVC_SCALING_MATRIX (struct)`` ++ Specifies the scaling matrix (as extracted from the bitstream) for ++ the associated HEVC slice data. The bitstream parameters are ++ defined according to :ref:`hevc`, section 7.4.5 "Scaling list ++ data semantics". For further documentation, refer to the above ++ specification, unless there is an explicit comment stating ++ otherwise. ++ ++ .. note:: ++ ++ This compound control is not yet part of the public kernel API and ++ it is expected to change. ++ ++.. c:type:: v4l2_ctrl_hevc_scaling_matrix ++ ++.. cssclass:: longtable ++ ++.. flat-table:: struct v4l2_ctrl_hevc_scaling_matrix ++ :header-rows: 0 ++ :stub-columns: 0 ++ :widths: 1 1 2 ++ ++ * - __u8 ++ - ``scaling_list_4x4[6][16]`` ++ - ++ * - __u8 ++ - ``scaling_list_8x8[6][64]`` ++ - ++ * - __u8 ++ - ``scaling_list_16x16[6][64]`` ++ - ++ * - __u8 ++ - ``scaling_list_32x32[2][64]`` ++ - ++ * - __u8 ++ - ``scaling_list_dc_coef_16x16[6]`` ++ - ++ * - __u8 ++ - ``scaling_list_dc_coef_32x32[2]`` ++ - ++ + ``V4L2_CID_MPEG_VIDEO_HEVC_DECODE_MODE (enum)`` + Specifies the decoding mode to use. Currently exposes slice-based and + frame-based decoding but new modes might be added later on. +diff --git a/Documentation/userspace-api/media/v4l/pixfmt-compressed.rst b/Documentation/userspace-api/media/v4l/pixfmt-compressed.rst +index d585909bc4e2..f817c643761b 100644 +--- a/Documentation/userspace-api/media/v4l/pixfmt-compressed.rst ++++ b/Documentation/userspace-api/media/v4l/pixfmt-compressed.rst +@@ -200,6 +200,7 @@ Compressed Formats + * ``V4L2_CID_MPEG_VIDEO_HEVC_SPS`` + * ``V4L2_CID_MPEG_VIDEO_HEVC_PPS`` + * ``V4L2_CID_MPEG_VIDEO_HEVC_SLICE_PARAMS`` ++ * ``V4L2_CID_MPEG_VIDEO_HEVC_SCALING_MATRIX`` + See the :ref:`associated Codec Control IDs `. + Buffers associated with this pixel format must contain the appropriate + number of macroblocks to decode a full corresponding frame. +diff --git a/drivers/media/v4l2-core/v4l2-ctrls.c b/drivers/media/v4l2-core/v4l2-ctrls.c +index a88e962ac8a1..4267ba536013 100644 +--- a/drivers/media/v4l2-core/v4l2-ctrls.c ++++ b/drivers/media/v4l2-core/v4l2-ctrls.c +@@ -1026,6 +1026,7 @@ const char *v4l2_ctrl_get_name(u32 id) + case V4L2_CID_MPEG_VIDEO_HEVC_SPS: return "HEVC Sequence Parameter Set"; + case V4L2_CID_MPEG_VIDEO_HEVC_PPS: return "HEVC Picture Parameter Set"; + case V4L2_CID_MPEG_VIDEO_HEVC_SLICE_PARAMS: return "HEVC Slice Parameters"; ++ case V4L2_CID_MPEG_VIDEO_HEVC_SCALING_MATRIX: return "HEVC Scaling Matrix"; + case V4L2_CID_MPEG_VIDEO_HEVC_DECODE_MODE: return "HEVC Decode Mode"; + case V4L2_CID_MPEG_VIDEO_HEVC_START_CODE: return "HEVC Start Code"; + +@@ -1475,6 +1476,9 @@ void v4l2_ctrl_fill(u32 id, const char **name, enum v4l2_ctrl_type *type, + case V4L2_CID_MPEG_VIDEO_HEVC_SLICE_PARAMS: + *type = V4L2_CTRL_TYPE_HEVC_SLICE_PARAMS; + break; ++ case V4L2_CID_MPEG_VIDEO_HEVC_SCALING_MATRIX: ++ *type = V4L2_CTRL_TYPE_HEVC_SCALING_MATRIX; ++ break; + case V4L2_CID_UNIT_CELL_SIZE: + *type = V4L2_CTRL_TYPE_AREA; + *flags |= V4L2_CTRL_FLAG_READ_ONLY; +@@ -2167,6 +2171,9 @@ static int std_validate_compound(const struct v4l2_ctrl *ctrl, u32 idx, + zero_padding(*p_hevc_slice_params); + break; + ++ case V4L2_CTRL_TYPE_HEVC_SCALING_MATRIX: ++ break; ++ + case V4L2_CTRL_TYPE_AREA: + area = p; + if (!area->width || !area->height) +@@ -2865,6 +2872,9 @@ static struct v4l2_ctrl *v4l2_ctrl_new(struct v4l2_ctrl_handler *hdl, + case V4L2_CTRL_TYPE_HEVC_SLICE_PARAMS: + elem_size = sizeof(struct v4l2_ctrl_hevc_slice_params); + break; ++ case V4L2_CTRL_TYPE_HEVC_SCALING_MATRIX: ++ elem_size = sizeof(struct v4l2_ctrl_hevc_scaling_matrix); ++ break; + case V4L2_CTRL_TYPE_AREA: + elem_size = sizeof(struct v4l2_area); + break; +diff --git a/include/media/hevc-ctrls.h b/include/media/hevc-ctrls.h +index 1009cf0891cc..1592e52c3614 100644 +--- a/include/media/hevc-ctrls.h ++++ b/include/media/hevc-ctrls.h +@@ -19,6 +19,7 @@ + #define V4L2_CID_MPEG_VIDEO_HEVC_SPS (V4L2_CID_MPEG_BASE + 1008) + #define V4L2_CID_MPEG_VIDEO_HEVC_PPS (V4L2_CID_MPEG_BASE + 1009) + #define V4L2_CID_MPEG_VIDEO_HEVC_SLICE_PARAMS (V4L2_CID_MPEG_BASE + 1010) ++#define V4L2_CID_MPEG_VIDEO_HEVC_SCALING_MATRIX (V4L2_CID_MPEG_BASE + 1011) + #define V4L2_CID_MPEG_VIDEO_HEVC_DECODE_MODE (V4L2_CID_MPEG_BASE + 1015) + #define V4L2_CID_MPEG_VIDEO_HEVC_START_CODE (V4L2_CID_MPEG_BASE + 1016) + +@@ -26,6 +27,7 @@ + #define V4L2_CTRL_TYPE_HEVC_SPS 0x0120 + #define V4L2_CTRL_TYPE_HEVC_PPS 0x0121 + #define V4L2_CTRL_TYPE_HEVC_SLICE_PARAMS 0x0122 ++#define V4L2_CTRL_TYPE_HEVC_SCALING_MATRIX 0x0123 + + enum v4l2_mpeg_video_hevc_decode_mode { + V4L2_MPEG_VIDEO_HEVC_DECODE_MODE_SLICE_BASED, +@@ -209,4 +211,13 @@ struct v4l2_ctrl_hevc_slice_params { + __u64 flags; + }; + ++struct v4l2_ctrl_hevc_scaling_matrix { ++ __u8 scaling_list_4x4[6][16]; ++ __u8 scaling_list_8x8[6][64]; ++ __u8 scaling_list_16x16[6][64]; ++ __u8 scaling_list_32x32[2][64]; ++ __u8 scaling_list_dc_coef_16x16[6]; ++ __u8 scaling_list_dc_coef_32x32[2]; ++}; ++ + #endif + +From 3d1d4437c6cd686a171b1f0ba11e35e07328b70b Mon Sep 17 00:00:00 2001 +From: Jernej Skrabec +Date: Sat, 26 Oct 2019 15:42:28 +0200 +Subject: [PATCH] media: uapi: hevc: Add segment address field + +If HEVC frame consists of multiple slices, segment address has to be +known in order to properly decode it. + +Add segment address field to slice parameters. + +Signed-off-by: Jernej Skrabec +--- + Documentation/userspace-api/media/v4l/ext-ctrls-codec.rst | 5 ++++- + include/media/hevc-ctrls.h | 5 ++++- + 2 files changed, 8 insertions(+), 2 deletions(-) + +diff --git a/Documentation/userspace-api/media/v4l/ext-ctrls-codec.rst b/Documentation/userspace-api/media/v4l/ext-ctrls-codec.rst +index 81529b1d8d69..817773791888 100644 +--- a/Documentation/userspace-api/media/v4l/ext-ctrls-codec.rst ++++ b/Documentation/userspace-api/media/v4l/ext-ctrls-codec.rst +@@ -4661,6 +4661,9 @@ enum v4l2_mpeg_video_hevc_size_of_length_field - + * - __u32 + - ``data_bit_offset`` + - Offset (in bits) to the video data in the current slice data. ++ * - __u32 ++ - ``slice_segment_addr`` ++ - + * - __u8 + - ``nal_unit_type`` + - +@@ -4738,7 +4741,7 @@ enum v4l2_mpeg_video_hevc_size_of_length_field - + - ``num_rps_poc_lt_curr`` + - The number of reference pictures in the long-term set. + * - __u8 +- - ``padding[7]`` ++ - ``padding[5]`` + - Applications and drivers must set this to zero. + * - struct :c:type:`v4l2_hevc_dpb_entry` + - ``dpb[V4L2_HEVC_DPB_ENTRIES_NUM_MAX]`` +diff --git a/include/media/hevc-ctrls.h b/include/media/hevc-ctrls.h +index 1592e52c3614..3e2e32098312 100644 +--- a/include/media/hevc-ctrls.h ++++ b/include/media/hevc-ctrls.h +@@ -167,6 +167,9 @@ struct v4l2_ctrl_hevc_slice_params { + __u32 bit_size; + __u32 data_bit_offset; + ++ /* ISO/IEC 23008-2, ITU-T Rec. H.265: General slice segment header */ ++ __u32 slice_segment_addr; ++ + /* ISO/IEC 23008-2, ITU-T Rec. H.265: NAL unit header */ + __u8 nal_unit_type; + __u8 nuh_temporal_id_plus1; +@@ -200,7 +203,7 @@ struct v4l2_ctrl_hevc_slice_params { + __u8 num_rps_poc_st_curr_after; + __u8 num_rps_poc_lt_curr; + +- __u8 padding; ++ __u8 padding[5]; + + /* ISO/IEC 23008-2, ITU-T Rec. H.265: General slice segment header */ + struct v4l2_hevc_dpb_entry dpb[V4L2_HEVC_DPB_ENTRIES_NUM_MAX]; + +From 076ec99168f4ac51ad84f162521c162037b24387 Mon Sep 17 00:00:00 2001 +From: Jonas Karlman +Date: Sat, 23 May 2020 15:03:46 +0000 +Subject: [PATCH] WIP: media: uapi: hevc: add fields needed for rkvdec + +NOTE: these fields are used by rkvdec hevc backend + +Signed-off-by: Jonas Karlman +--- + include/media/hevc-ctrls.h | 16 ++++++++++++---- + 1 file changed, 12 insertions(+), 4 deletions(-) + +diff --git a/include/media/hevc-ctrls.h b/include/media/hevc-ctrls.h +index 3e2e32098312..3cc3b47e1417 100644 +--- a/include/media/hevc-ctrls.h ++++ b/include/media/hevc-ctrls.h +@@ -56,6 +56,9 @@ enum v4l2_mpeg_video_hevc_start_code { + /* The controls are not stable at the moment and will likely be reworked. */ + struct v4l2_ctrl_hevc_sps { + /* ISO/IEC 23008-2, ITU-T Rec. H.265: Sequence parameter set */ ++ __u8 video_parameter_set_id; ++ __u8 seq_parameter_set_id; ++ __u8 chroma_format_idc; + __u16 pic_width_in_luma_samples; + __u16 pic_height_in_luma_samples; + __u8 bit_depth_luma_minus8; +@@ -76,9 +79,8 @@ struct v4l2_ctrl_hevc_sps { + __u8 log2_diff_max_min_pcm_luma_coding_block_size; + __u8 num_short_term_ref_pic_sets; + __u8 num_long_term_ref_pics_sps; +- __u8 chroma_format_idc; + +- __u8 padding; ++ __u8 padding[7]; + + __u64 flags; + }; +@@ -105,7 +107,10 @@ struct v4l2_ctrl_hevc_sps { + + struct v4l2_ctrl_hevc_pps { + /* ISO/IEC 23008-2, ITU-T Rec. H.265: Picture parameter set */ ++ __u8 pic_parameter_set_id; + __u8 num_extra_slice_header_bits; ++ __u8 num_ref_idx_l0_default_active_minus1; ++ __u8 num_ref_idx_l1_default_active_minus1; + __s8 init_qp_minus26; + __u8 diff_cu_qp_delta_depth; + __s8 pps_cb_qp_offset; +@@ -118,7 +123,7 @@ struct v4l2_ctrl_hevc_pps { + __s8 pps_tc_offset_div2; + __u8 log2_parallel_merge_level_minus2; + +- __u8 padding[4]; ++ __u8 padding; + __u64 flags; + }; + +@@ -203,7 +208,10 @@ struct v4l2_ctrl_hevc_slice_params { + __u8 num_rps_poc_st_curr_after; + __u8 num_rps_poc_lt_curr; + +- __u8 padding[5]; ++ __u16 short_term_ref_pic_set_size; ++ __u16 long_term_ref_pic_set_size; ++ ++ __u8 padding; + + /* ISO/IEC 23008-2, ITU-T Rec. H.265: General slice segment header */ + struct v4l2_hevc_dpb_entry dpb[V4L2_HEVC_DPB_ENTRIES_NUM_MAX]; + +From d324ae4d5f4a68008b6f599225143dc83d24bfad Mon Sep 17 00:00:00 2001 +From: Jonas Karlman +Date: Sat, 23 May 2020 15:07:15 +0000 +Subject: [PATCH] HACK: media: uapi: hevc: tiles and num_slices + +--- + include/media/hevc-ctrls.h | 8 ++++++-- + 1 file changed, 6 insertions(+), 2 deletions(-) + +diff --git a/include/media/hevc-ctrls.h b/include/media/hevc-ctrls.h +index 3cc3b47e1417..b33e1a8141e1 100644 +--- a/include/media/hevc-ctrls.h ++++ b/include/media/hevc-ctrls.h +@@ -80,7 +80,8 @@ struct v4l2_ctrl_hevc_sps { + __u8 num_short_term_ref_pic_sets; + __u8 num_long_term_ref_pics_sps; + +- __u8 padding[7]; ++ __u8 num_slices; ++ __u8 padding[6]; + + __u64 flags; + }; +@@ -174,6 +175,7 @@ struct v4l2_ctrl_hevc_slice_params { + + /* ISO/IEC 23008-2, ITU-T Rec. H.265: General slice segment header */ + __u32 slice_segment_addr; ++ __u32 num_entry_point_offsets; + + /* ISO/IEC 23008-2, ITU-T Rec. H.265: NAL unit header */ + __u8 nal_unit_type; +@@ -211,7 +213,9 @@ struct v4l2_ctrl_hevc_slice_params { + __u16 short_term_ref_pic_set_size; + __u16 long_term_ref_pic_set_size; + +- __u8 padding; ++ __u8 padding[5]; ++ ++ __u32 entry_point_offset_minus1[256]; + + /* ISO/IEC 23008-2, ITU-T Rec. H.265: General slice segment header */ + struct v4l2_hevc_dpb_entry dpb[V4L2_HEVC_DPB_ENTRIES_NUM_MAX]; + +From 00f54f3488e9b9aef05c5555198d27eacc273da4 Mon Sep 17 00:00:00 2001 +From: Jonas Karlman +Date: Sat, 23 May 2020 15:17:45 +0000 +Subject: [PATCH] WIP: media: rkvdec: add HEVC backend + +NOTE: cabac table and scailing list code is copied 1:1 from mpp +TODO: fix lowdelay flag and rework the scaling list part + +Signed-off-by: Jonas Karlman +--- + drivers/staging/media/rkvdec/Makefile | 2 +- + drivers/staging/media/rkvdec/rkvdec-hevc.c | 2522 ++++++++++++++++++++ + drivers/staging/media/rkvdec/rkvdec-regs.h | 1 + + drivers/staging/media/rkvdec/rkvdec.c | 70 + + drivers/staging/media/rkvdec/rkvdec.h | 1 + + 5 files changed, 2595 insertions(+), 1 deletion(-) + create mode 100644 drivers/staging/media/rkvdec/rkvdec-hevc.c + +diff --git a/drivers/staging/media/rkvdec/Makefile b/drivers/staging/media/rkvdec/Makefile +index cb86b429cfaa..a77122641d14 100644 +--- a/drivers/staging/media/rkvdec/Makefile ++++ b/drivers/staging/media/rkvdec/Makefile +@@ -1,3 +1,3 @@ + obj-$(CONFIG_VIDEO_ROCKCHIP_VDEC) += rockchip-vdec.o + +-rockchip-vdec-y += rkvdec.o rkvdec-h264.o rkvdec-vp9.o ++rockchip-vdec-y += rkvdec.o rkvdec-h264.o rkvdec-hevc.o rkvdec-vp9.o +diff --git a/drivers/staging/media/rkvdec/rkvdec-hevc.c b/drivers/staging/media/rkvdec/rkvdec-hevc.c +new file mode 100644 +index 000000000000..03ba848411c6 +--- /dev/null ++++ b/drivers/staging/media/rkvdec/rkvdec-hevc.c +@@ -0,0 +1,2522 @@ ++// SPDX-License-Identifier: GPL-2.0 ++/* ++ * Rockchip Video Decoder HEVC backend ++ * ++ * Copyright (C) 2019 Collabora, Ltd. ++ * Boris Brezillon ++ * ++ * Copyright (C) 2016 Rockchip Electronics Co., Ltd. ++ * Jeffy Chen ++ */ ++ ++#include ++ ++#include "rkvdec.h" ++#include "rkvdec-regs.h" ++ ++/* Size in u8/u32 units. */ ++#define RKV_CABAC_TABLE_SIZE 27456 ++#define RKV_SCALING_LIST_SIZE 1360 ++#define RKV_PPS_SIZE (80 / 4) ++#define RKV_PPS_LEN 64 ++#define RKV_RPS_SIZE (32 / 4) ++#define RKV_RPS_LEN 600 ++ ++struct rkvdec_sps_pps_packet { ++ u32 info[RKV_PPS_SIZE]; ++}; ++ ++struct rkvdec_rps_packet { ++ u32 info[RKV_RPS_SIZE]; ++}; ++ ++struct rkvdec_ps_field { ++ u16 offset; ++ u8 len; ++}; ++ ++#define PS_FIELD(_offset, _len) \ ++ ((struct rkvdec_ps_field){ _offset, _len }) ++ ++/* SPS */ ++#define VIDEO_PARAMETER_SET_ID PS_FIELD(0, 4) ++#define SEQ_PARAMETER_SET_ID PS_FIELD(4, 4) ++#define CHROMA_FORMAT_IDC PS_FIELD(8, 2) ++#define PIC_WIDTH_IN_LUMA_SAMPLES PS_FIELD(10, 13) ++#define PIC_HEIGHT_IN_LUMA_SAMPLES PS_FIELD(23, 13) ++#define BIT_DEPTH_LUMA PS_FIELD(36, 4) ++#define BIT_DEPTH_CHROMA PS_FIELD(40, 4) ++#define LOG2_MAX_PIC_ORDER_CNT_LSB PS_FIELD(44, 5) ++#define LOG2_DIFF_MAX_MIN_LUMA_CODING_BLOCK_SIZE PS_FIELD(49, 2) ++#define LOG2_MIN_LUMA_CODING_BLOCK_SIZE PS_FIELD(51, 3) ++#define LOG2_MIN_TRANSFORM_BLOCK_SIZE PS_FIELD(54, 3) ++#define LOG2_DIFF_MAX_MIN_LUMA_TRANSFORM_BLOCK_SIZE PS_FIELD(57, 2) ++#define MAX_TRANSFORM_HIERARCHY_DEPTH_INTER PS_FIELD(59, 3) ++#define MAX_TRANSFORM_HIERARCHY_DEPTH_INTRA PS_FIELD(62, 3) ++#define SCALING_LIST_ENABLED_FLAG PS_FIELD(65, 1) ++#define AMP_ENABLED_FLAG PS_FIELD(66, 1) ++#define SAMPLE_ADAPTIVE_OFFSET_ENABLED_FLAG PS_FIELD(67, 1) ++#define PCM_ENABLED_FLAG PS_FIELD(68, 1) ++#define PCM_SAMPLE_BIT_DEPTH_LUMA PS_FIELD(69, 4) ++#define PCM_SAMPLE_BIT_DEPTH_CHROMA PS_FIELD(73, 4) ++#define PCM_LOOP_FILTER_DISABLED_FLAG PS_FIELD(77, 1) ++#define LOG2_DIFF_MAX_MIN_PCM_LUMA_CODING_BLOCK_SIZE PS_FIELD(78, 3) ++#define LOG2_MIN_PCM_LUMA_CODING_BLOCK_SIZE PS_FIELD(81, 3) ++#define NUM_SHORT_TERM_REF_PIC_SETS PS_FIELD(84, 7) ++#define LONG_TERM_REF_PICS_PRESENT_FLAG PS_FIELD(91, 1) ++#define NUM_LONG_TERM_REF_PICS_SPS PS_FIELD(92, 6) ++#define SPS_TEMPORAL_MVP_ENABLED_FLAG PS_FIELD(98, 1) ++#define STRONG_INTRA_SMOOTHING_ENABLED_FLAG PS_FIELD(99, 1) ++/* PPS */ ++#define PIC_PARAMETER_SET_ID PS_FIELD(128, 6) ++#define PPS_SEQ_PARAMETER_SET_ID PS_FIELD(134, 4) ++#define DEPENDENT_SLICE_SEGMENTS_ENABLED_FLAG PS_FIELD(138, 1) ++#define OUTPUT_FLAG_PRESENT_FLAG PS_FIELD(139, 1) ++#define NUM_EXTRA_SLICE_HEADER_BITS PS_FIELD(140, 13) ++#define SIGN_DATA_HIDING_ENABLED_FLAG PS_FIELD(153, 1) ++#define CABAC_INIT_PRESENT_FLAG PS_FIELD(154, 1) ++#define NUM_REF_IDX_L0_DEFAULT_ACTIVE PS_FIELD(155, 4) ++#define NUM_REF_IDX_L1_DEFAULT_ACTIVE PS_FIELD(159, 4) ++#define INIT_QP_MINUS26 PS_FIELD(163, 7) ++#define CONSTRAINED_INTRA_PRED_FLAG PS_FIELD(170, 1) ++#define TRANSFORM_SKIP_ENABLED_FLAG PS_FIELD(171, 1) ++#define CU_QP_DELTA_ENABLED_FLAG PS_FIELD(172, 1) ++#define LOG2_MIN_CU_QP_DELTA_SIZE PS_FIELD(173, 3) ++#define PPS_CB_QP_OFFSET PS_FIELD(176, 5) ++#define PPS_CR_QP_OFFSET PS_FIELD(181, 5) ++#define PPS_SLICE_CHROMA_QP_OFFSETS_PRESENT_FLAG PS_FIELD(186, 1) ++#define WEIGHTED_PRED_FLAG PS_FIELD(187, 1) ++#define WEIGHTED_BIPRED_FLAG PS_FIELD(188, 1) ++#define TRANSQUANT_BYPASS_ENABLED_FLAG PS_FIELD(189, 1) ++#define TILES_ENABLED_FLAG PS_FIELD(190, 1) ++#define ENTROPY_CODING_SYNC_ENABLED_FLAG PS_FIELD(191, 1) ++#define PPS_LOOP_FILTER_ACROSS_SLICES_ENABLED_FLAG PS_FIELD(192, 1) ++#define LOOP_FILTER_ACROSS_TILES_ENABLED_FLAG PS_FIELD(193, 1) ++#define DEBLOCKING_FILTER_OVERRIDE_ENABLED_FLAG PS_FIELD(194, 1) ++#define PPS_DEBLOCKING_FILTER_DISABLED_FLAG PS_FIELD(195, 1) ++#define PPS_BETA_OFFSET_DIV2 PS_FIELD(196, 4) ++#define PPS_TC_OFFSET_DIV2 PS_FIELD(200, 4) ++#define LISTS_MODIFICATION_PRESENT_FLAG PS_FIELD(204, 1) ++#define LOG2_PARALLEL_MERGE_LEVEL PS_FIELD(205, 3) ++#define SLICE_SEGMENT_HEADER_EXTENSION_PRESENT_FLAG PS_FIELD(208, 1) ++#define NUM_TILE_COLUMNS PS_FIELD(212, 5) ++#define NUM_TILE_ROWS PS_FIELD(217, 5) ++#define COLUMN_WIDTH(i) PS_FIELD(256 + (i * 8), 8) ++#define ROW_HEIGHT(i) PS_FIELD(416 + (i * 8), 8) ++#define SCALING_LIST_ADDRESS PS_FIELD(592, 32) ++ ++/* Data structure describing auxiliary buffer format. */ ++struct rkvdec_hevc_priv_tbl { ++ u8 cabac_table[RKV_CABAC_TABLE_SIZE]; ++ u8 scaling_list[RKV_SCALING_LIST_SIZE]; ++ struct rkvdec_sps_pps_packet param_set[RKV_PPS_LEN]; ++ struct rkvdec_rps_packet rps[RKV_RPS_LEN]; ++}; ++ ++struct rkvdec_hevc_run { ++ struct rkvdec_run base; ++ const struct v4l2_ctrl_hevc_slice_params *slices_params; ++ const struct v4l2_ctrl_hevc_sps *sps; ++ const struct v4l2_ctrl_hevc_pps *pps; ++ const struct v4l2_ctrl_hevc_scaling_matrix *scaling_matrix; ++ int num_slices; ++}; ++ ++struct rkvdec_hevc_ctx { ++ struct rkvdec_aux_buf priv_tbl; ++ struct v4l2_ctrl_hevc_scaling_matrix scaling_matrix_cache; ++}; ++ ++// TODO: refactor scaling list code, was copied 1:1 from mpp ++ ++typedef struct ScalingList { ++ /* This is a little wasteful, since sizeID 0 only needs 8 coeffs, ++ * and size ID 3 only has 2 arrays, not 6. */ ++ u8 sl[4][6][64]; ++ u8 sl_dc[2][6]; ++} scalingList_t; ++ ++typedef struct ScalingFactor_Model { ++ u8 scalingfactor0[1248]; ++ u8 scalingfactor1[96]; /*4X4 TU Rotate, total 16X4*/ ++ u8 scalingdc[12]; /*N1005 Vienna Meeting*/ ++ u8 reserverd[4]; /*16Bytes align*/ ++} scalingFactor_t; ++ ++#define SCALING_LIST_SIZE_NUM 4 ++ ++static void ++hal_record_scaling_list(scalingFactor_t *pScalingFactor_out, ++ scalingList_t *pScalingList) ++{ ++ int i; ++ u32 g_scalingListNum_model[SCALING_LIST_SIZE_NUM] = {6, 6, 6, 2}; // from C Model ++ u32 nIndex = 0; ++ u32 sizeId, matrixId, listId; ++ u8 *p = pScalingFactor_out->scalingfactor0; ++ u8 tmpBuf[8 * 8]; ++ ++ //output non-default scalingFactor Table (1248 BYTES) ++ for (sizeId = 0; sizeId < SCALING_LIST_SIZE_NUM; sizeId++) { ++ for (listId = 0; listId < g_scalingListNum_model[sizeId]; listId++) { ++ if (sizeId < 3) { ++ for (i = 0; i < (sizeId == 0 ? 16 : 64); i++) { ++ pScalingFactor_out->scalingfactor0[nIndex++] = (u8)pScalingList->sl[sizeId][listId][i]; ++ } ++ } else { ++ for (i = 0; i < 64; i ++) { ++ pScalingFactor_out->scalingfactor0[nIndex++] = (u8)pScalingList->sl[sizeId][listId][i]; ++ } ++ for (i = 0; i < 128; i ++) { ++ pScalingFactor_out->scalingfactor0[nIndex++] = 0; ++ } ++ } ++ } ++ } ++ //output non-default scalingFactor Table Rotation(96 Bytes) ++ nIndex = 0; ++ for (listId = 0; listId < g_scalingListNum_model[0]; listId++) { ++ u8 temp16[16] = {0}; ++ for (i = 0; i < 16; i ++) { ++ temp16[i] = (u8)pScalingList->sl[0][listId][i]; ++ } ++ for (i = 0; i < 4; i ++) { ++ pScalingFactor_out->scalingfactor1[nIndex++] = temp16[i]; ++ pScalingFactor_out->scalingfactor1[nIndex++] = temp16[i + 4]; ++ pScalingFactor_out->scalingfactor1[nIndex++] = temp16[i + 8]; ++ pScalingFactor_out->scalingfactor1[nIndex++] = temp16[i + 12]; ++ } ++ } ++ //output non-default ScalingList_DC_Coeff (12 BYTES) ++ nIndex = 0; ++ for (listId = 0; listId < g_scalingListNum_model[2]; listId++) { //sizeId = 2 ++ pScalingFactor_out->scalingdc[nIndex++] = (u8)pScalingList->sl_dc[0][listId];// zrh warning: sl_dc differed from scalingList->getScalingListDC ++ } ++ for (listId = 0; listId < g_scalingListNum_model[3]; listId++) { //sizeId = 3 ++ pScalingFactor_out->scalingdc[nIndex++] = (u8)pScalingList->sl_dc[1][listId];// zrh warning: sl_dc differed from scalingList->getScalingListDC ++ pScalingFactor_out->scalingdc[nIndex++] = 0; ++ pScalingFactor_out->scalingdc[nIndex++] = 0; ++ } ++ ++ //align 16X address ++ nIndex = 0; ++ for (i = 0; i < 4; i ++) { ++ pScalingFactor_out->reserverd[nIndex++] = 0; ++ } ++ ++ //----------------------All above code show the normal store way in HM-------------------------- ++ //--------from now on, the scalingfactor0 is rotated 90', the scalingfactor1 is also rotated 90' ++ ++ //sizeId == 0 ++ for (matrixId = 0; matrixId < 6; matrixId++) { ++ p = pScalingFactor_out->scalingfactor0 + matrixId * 16; ++ ++ for (i = 0; i < 4; i++) { ++ tmpBuf[4 * 0 + i] = p[i * 4 + 0]; ++ tmpBuf[4 * 1 + i] = p[i * 4 + 1]; ++ tmpBuf[4 * 2 + i] = p[i * 4 + 2]; ++ tmpBuf[4 * 3 + i] = p[i * 4 + 3]; ++ } ++ memcpy(p, tmpBuf, 4 * 4 * sizeof(u8)); ++ } ++ //sizeId == 1 ++ for (matrixId = 0; matrixId < 6; matrixId++) { ++ p = pScalingFactor_out->scalingfactor0 + 6 * 16 + matrixId * 64; ++ ++ for (i = 0; i < 8; i++) { ++ tmpBuf[8 * 0 + i] = p[i * 8 + 0]; ++ tmpBuf[8 * 1 + i] = p[i * 8 + 1]; ++ tmpBuf[8 * 2 + i] = p[i * 8 + 2]; ++ tmpBuf[8 * 3 + i] = p[i * 8 + 3]; ++ tmpBuf[8 * 4 + i] = p[i * 8 + 4]; ++ tmpBuf[8 * 5 + i] = p[i * 8 + 5]; ++ tmpBuf[8 * 6 + i] = p[i * 8 + 6]; ++ tmpBuf[8 * 7 + i] = p[i * 8 + 7]; ++ } ++ memcpy(p, tmpBuf, 8 * 8 * sizeof(u8)); ++ } ++ //sizeId == 2 ++ for (matrixId = 0; matrixId < 6; matrixId++) { ++ p = pScalingFactor_out->scalingfactor0 + 6 * 16 + 6 * 64 + matrixId * 64; ++ ++ for (i = 0; i < 8; i++) { ++ tmpBuf[8 * 0 + i] = p[i * 8 + 0]; ++ tmpBuf[8 * 1 + i] = p[i * 8 + 1]; ++ tmpBuf[8 * 2 + i] = p[i * 8 + 2]; ++ tmpBuf[8 * 3 + i] = p[i * 8 + 3]; ++ tmpBuf[8 * 4 + i] = p[i * 8 + 4]; ++ tmpBuf[8 * 5 + i] = p[i * 8 + 5]; ++ tmpBuf[8 * 6 + i] = p[i * 8 + 6]; ++ tmpBuf[8 * 7 + i] = p[i * 8 + 7]; ++ } ++ memcpy(p, tmpBuf, 8 * 8 * sizeof(u8)); ++ } ++ //sizeId == 3 ++ for (matrixId = 0; matrixId < 6; matrixId++) { ++ p = pScalingFactor_out->scalingfactor0 + 6 * 16 + 6 * 64 + 6 * 64 + matrixId * 64; ++ ++ for (i = 0; i < 8; i++) { ++ tmpBuf[8 * 0 + i] = p[i * 8 + 0]; ++ tmpBuf[8 * 1 + i] = p[i * 8 + 1]; ++ tmpBuf[8 * 2 + i] = p[i * 8 + 2]; ++ tmpBuf[8 * 3 + i] = p[i * 8 + 3]; ++ tmpBuf[8 * 4 + i] = p[i * 8 + 4]; ++ tmpBuf[8 * 5 + i] = p[i * 8 + 5]; ++ tmpBuf[8 * 6 + i] = p[i * 8 + 6]; ++ tmpBuf[8 * 7 + i] = p[i * 8 + 7]; ++ } ++ memcpy(p, tmpBuf, 8 * 8 * sizeof(u8)); ++ } ++ ++ //sizeId == 0 ++ for (matrixId = 0; matrixId < 6; matrixId++) { ++ p = pScalingFactor_out->scalingfactor1 + matrixId * 16; ++ ++ for (i = 0; i < 4; i++) { ++ tmpBuf[4 * 0 + i] = p[i * 4 + 0]; ++ tmpBuf[4 * 1 + i] = p[i * 4 + 1]; ++ tmpBuf[4 * 2 + i] = p[i * 4 + 2]; ++ tmpBuf[4 * 3 + i] = p[i * 4 + 3]; ++ } ++ memcpy(p, tmpBuf, 4 * 4 * sizeof(u8)); ++ } ++} ++ ++static const u8 rkvdec_hevc_cabac_table[RKV_CABAC_TABLE_SIZE] = { ++ 0x07, 0x0f, 0x48, 0x58, 0x58, 0x40, 0x40, 0x40, 0x40, 0x40, 0x0f, 0x40, 0x40, 0x40, 0x0f, 0x68, ++ 0x48, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x07, 0x40, 0x40, 0x68, ++ 0x58, 0x60, 0x40, 0x1f, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x48, 0x48, 0x60, 0x60, 0x50, 0x58, ++ 0x50, 0x07, 0x58, 0x68, 0x50, 0x58, 0x68, 0x68, 0x68, 0x68, 0x68, 0x50, 0x48, 0x68, 0x60, 0x60, ++ 0x50, 0x58, 0x50, 0x07, 0x58, 0x68, 0x50, 0x58, 0x68, 0x68, 0x68, 0x68, 0x68, 0x50, 0x48, 0x68, ++ 0x48, 0x48, 0x1f, 0x58, 0x68, 0x68, 0x58, 0x60, 0x60, 0x60, 0x50, 0x50, 0x50, 0x48, 0x58, 0x58, ++ 0x37, 0x07, 0x58, 0x48, 0x58, 0x58, 0x37, 0x07, 0x58, 0x48, 0x58, 0x58, 0x37, 0x07, 0x58, 0x50, ++ 0x48, 0x1f, 0x1f, 0x0f, 0x0f, 0x0f, 0x0f, 0x07, 0x0f, 0x48, 0x68, 0x0f, 0x48, 0x68, 0x40, 0x40, ++ 0x50, 0x50, 0x07, 0x40, 0x50, 0x0f, 0x40, 0x48, 0x07, 0x40, 0x27, 0x50, 0x48, 0x48, 0x40, 0x0f, ++ 0x50, 0x37, 0x1f, 0x1f, 0x50, 0x37, 0x40, 0x27, 0x40, 0x07, 0x0f, 0x17, 0x0f, 0x0f, 0x40, 0x40, ++ 0x40, 0x40, 0x40, 0x40, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x07, 0x0f, 0x47, 0x57, 0x58, 0x40, 0x40, 0x40, 0x40, 0x40, 0x0f, 0x40, 0x40, 0x40, 0x0f, 0x66, ++ 0x47, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x07, 0x00, 0x00, 0x67, ++ 0x57, 0x5e, 0x00, 0x1f, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x47, 0x47, 0x5f, 0x5f, 0x4f, 0x57, ++ 0x4f, 0x07, 0x57, 0x67, 0x4f, 0x57, 0x67, 0x67, 0x67, 0x67, 0x66, 0x4f, 0x47, 0x66, 0x5f, 0x5f, ++ 0x4f, 0x57, 0x4f, 0x07, 0x57, 0x67, 0x4f, 0x57, 0x67, 0x67, 0x67, 0x67, 0x66, 0x4f, 0x47, 0x66, ++ 0x46, 0x48, 0x20, 0x57, 0x67, 0x67, 0x57, 0x5f, 0x5f, 0x5e, 0x4f, 0x4f, 0x4f, 0x47, 0x57, 0x57, ++ 0x37, 0x07, 0x57, 0x47, 0x57, 0x57, 0x37, 0x07, 0x57, 0x47, 0x57, 0x57, 0x37, 0x07, 0x57, 0x4f, ++ 0x47, 0x1f, 0x1f, 0x0f, 0x10, 0x0f, 0x10, 0x07, 0x10, 0x47, 0x67, 0x10, 0x47, 0x67, 0x40, 0x40, ++ 0x4f, 0x4e, 0x08, 0x00, 0x4f, 0x0f, 0x00, 0x47, 0x07, 0x01, 0x27, 0x4e, 0x47, 0x47, 0x00, 0x0f, ++ 0x4f, 0x37, 0x1f, 0x1f, 0x4f, 0x36, 0x00, 0x27, 0x00, 0x07, 0x10, 0x17, 0x0f, 0x0f, 0x40, 0x40, ++ 0x40, 0x40, 0x40, 0x40, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x07, 0x0e, 0x47, 0x57, 0x58, 0x40, 0x40, 0x40, 0x40, 0x40, 0x0e, 0x40, 0x40, 0x40, 0x0e, 0x64, ++ 0x47, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x07, 0x00, 0x00, 0x66, ++ 0x57, 0x5d, 0x00, 0x1e, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x47, 0x47, 0x5e, 0x5e, 0x4e, 0x56, ++ 0x4f, 0x07, 0x56, 0x66, 0x4f, 0x56, 0x66, 0x67, 0x66, 0x66, 0x64, 0x4e, 0x46, 0x64, 0x5e, 0x5e, ++ 0x4e, 0x56, 0x4f, 0x07, 0x56, 0x66, 0x4f, 0x56, 0x66, 0x67, 0x66, 0x66, 0x64, 0x4e, 0x46, 0x64, ++ 0x45, 0x48, 0x20, 0x57, 0x66, 0x66, 0x56, 0x5e, 0x5e, 0x5d, 0x4e, 0x4e, 0x4e, 0x46, 0x56, 0x57, ++ 0x36, 0x07, 0x56, 0x46, 0x56, 0x57, 0x36, 0x07, 0x56, 0x46, 0x56, 0x57, 0x36, 0x07, 0x56, 0x4f, ++ 0x47, 0x1e, 0x1e, 0x0f, 0x10, 0x0f, 0x10, 0x07, 0x10, 0x47, 0x66, 0x10, 0x47, 0x66, 0x40, 0x40, ++ 0x4f, 0x4d, 0x08, 0x00, 0x4f, 0x0f, 0x00, 0x47, 0x07, 0x03, 0x27, 0x4d, 0x47, 0x46, 0x01, 0x0f, ++ 0x4f, 0x36, 0x1f, 0x1e, 0x4f, 0x34, 0x01, 0x26, 0x00, 0x07, 0x10, 0x17, 0x0f, 0x0f, 0x40, 0x40, ++ 0x40, 0x40, 0x40, 0x40, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x07, 0x0d, 0x47, 0x57, 0x58, 0x40, 0x40, 0x40, 0x40, 0x40, 0x0e, 0x40, 0x40, 0x40, 0x0e, 0x62, ++ 0x47, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x07, 0x00, 0x00, 0x65, ++ 0x57, 0x5c, 0x00, 0x1e, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x47, 0x47, 0x5d, 0x5d, 0x4e, 0x56, ++ 0x4f, 0x07, 0x56, 0x66, 0x4f, 0x55, 0x65, 0x67, 0x66, 0x65, 0x63, 0x4d, 0x46, 0x62, 0x5d, 0x5d, ++ 0x4e, 0x56, 0x4f, 0x07, 0x56, 0x66, 0x4f, 0x55, 0x65, 0x67, 0x66, 0x65, 0x63, 0x4d, 0x46, 0x62, ++ 0x44, 0x48, 0x20, 0x57, 0x65, 0x65, 0x56, 0x5d, 0x5d, 0x5c, 0x4e, 0x4d, 0x4e, 0x45, 0x56, 0x57, ++ 0x36, 0x07, 0x56, 0x45, 0x56, 0x57, 0x36, 0x07, 0x56, 0x45, 0x56, 0x57, 0x36, 0x07, 0x56, 0x4f, ++ 0x47, 0x1e, 0x1e, 0x0f, 0x10, 0x0f, 0x10, 0x07, 0x10, 0x47, 0x65, 0x10, 0x47, 0x65, 0x40, 0x40, ++ 0x4f, 0x4c, 0x08, 0x00, 0x4f, 0x0f, 0x00, 0x47, 0x07, 0x04, 0x27, 0x4c, 0x47, 0x45, 0x01, 0x0f, ++ 0x4f, 0x36, 0x1f, 0x1e, 0x4f, 0x33, 0x01, 0x25, 0x00, 0x07, 0x10, 0x17, 0x0f, 0x0f, 0x40, 0x40, ++ 0x40, 0x40, 0x40, 0x40, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x07, 0x0c, 0x46, 0x56, 0x58, 0x40, 0x40, 0x40, 0x40, 0x40, 0x0d, 0x40, 0x40, 0x40, 0x0d, 0x60, ++ 0x46, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x07, 0x01, 0x01, 0x64, ++ 0x56, 0x5b, 0x01, 0x1d, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x46, 0x46, 0x5c, 0x5c, 0x4d, 0x55, ++ 0x4e, 0x07, 0x55, 0x65, 0x4e, 0x54, 0x64, 0x66, 0x65, 0x64, 0x61, 0x4c, 0x45, 0x60, 0x5c, 0x5c, ++ 0x4d, 0x55, 0x4e, 0x07, 0x55, 0x65, 0x4e, 0x54, 0x64, 0x66, 0x65, 0x64, 0x61, 0x4c, 0x45, 0x60, ++ 0x43, 0x49, 0x21, 0x56, 0x64, 0x64, 0x55, 0x5c, 0x5c, 0x5b, 0x4d, 0x4c, 0x4d, 0x44, 0x55, 0x56, ++ 0x35, 0x07, 0x55, 0x44, 0x55, 0x56, 0x35, 0x07, 0x55, 0x44, 0x55, 0x56, 0x35, 0x07, 0x55, 0x4e, ++ 0x46, 0x1d, 0x1d, 0x0f, 0x11, 0x0f, 0x11, 0x07, 0x11, 0x46, 0x64, 0x11, 0x46, 0x64, 0x40, 0x40, ++ 0x4e, 0x4b, 0x09, 0x01, 0x4e, 0x0f, 0x01, 0x46, 0x07, 0x06, 0x27, 0x4b, 0x46, 0x44, 0x02, 0x0f, ++ 0x4e, 0x35, 0x1e, 0x1d, 0x4e, 0x31, 0x02, 0x24, 0x01, 0x07, 0x11, 0x16, 0x0f, 0x0f, 0x40, 0x40, ++ 0x40, 0x40, 0x40, 0x40, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x07, 0x0b, 0x46, 0x56, 0x58, 0x40, 0x40, 0x40, 0x40, 0x40, 0x0c, 0x40, 0x40, 0x40, 0x0c, 0x5e, ++ 0x46, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x07, 0x01, 0x01, 0x63, ++ 0x56, 0x59, 0x01, 0x1c, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x46, 0x46, 0x5b, 0x5b, 0x4c, 0x54, ++ 0x4e, 0x07, 0x54, 0x64, 0x4e, 0x53, 0x63, 0x66, 0x64, 0x63, 0x60, 0x4b, 0x44, 0x5e, 0x5b, 0x5b, ++ 0x4c, 0x54, 0x4e, 0x07, 0x54, 0x64, 0x4e, 0x53, 0x63, 0x66, 0x64, 0x63, 0x60, 0x4b, 0x44, 0x5e, ++ 0x41, 0x49, 0x21, 0x56, 0x63, 0x63, 0x54, 0x5b, 0x5b, 0x59, 0x4c, 0x4b, 0x4c, 0x43, 0x54, 0x56, ++ 0x34, 0x07, 0x54, 0x43, 0x54, 0x56, 0x34, 0x07, 0x54, 0x43, 0x54, 0x56, 0x34, 0x07, 0x54, 0x4e, ++ 0x46, 0x1c, 0x1c, 0x0f, 0x11, 0x0f, 0x11, 0x07, 0x11, 0x46, 0x63, 0x11, 0x46, 0x63, 0x40, 0x40, ++ 0x4e, 0x49, 0x09, 0x01, 0x4e, 0x0f, 0x01, 0x46, 0x07, 0x07, 0x27, 0x49, 0x46, 0x43, 0x03, 0x0f, ++ 0x4e, 0x34, 0x1e, 0x1c, 0x4e, 0x30, 0x03, 0x23, 0x01, 0x07, 0x11, 0x16, 0x0f, 0x0f, 0x40, 0x40, ++ 0x40, 0x40, 0x40, 0x40, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x07, 0x0a, 0x46, 0x56, 0x58, 0x40, 0x40, 0x40, 0x40, 0x40, 0x0c, 0x40, 0x40, 0x40, 0x0c, 0x5c, ++ 0x46, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x07, 0x01, 0x01, 0x62, ++ 0x56, 0x58, 0x01, 0x1c, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x46, 0x46, 0x5a, 0x5a, 0x4c, 0x54, ++ 0x4e, 0x07, 0x54, 0x64, 0x4e, 0x52, 0x62, 0x66, 0x64, 0x62, 0x5e, 0x4a, 0x44, 0x5c, 0x5a, 0x5a, ++ 0x4c, 0x54, 0x4e, 0x07, 0x54, 0x64, 0x4e, 0x52, 0x62, 0x66, 0x64, 0x62, 0x5e, 0x4a, 0x44, 0x5c, ++ 0x40, 0x49, 0x21, 0x56, 0x62, 0x62, 0x54, 0x5a, 0x5a, 0x58, 0x4c, 0x4a, 0x4c, 0x42, 0x54, 0x56, ++ 0x34, 0x07, 0x54, 0x42, 0x54, 0x56, 0x34, 0x07, 0x54, 0x42, 0x54, 0x56, 0x34, 0x07, 0x54, 0x4e, ++ 0x46, 0x1c, 0x1c, 0x0f, 0x11, 0x0f, 0x11, 0x07, 0x11, 0x46, 0x62, 0x11, 0x46, 0x62, 0x40, 0x40, ++ 0x4e, 0x48, 0x09, 0x01, 0x4e, 0x0f, 0x01, 0x46, 0x07, 0x09, 0x27, 0x48, 0x46, 0x42, 0x03, 0x0f, ++ 0x4e, 0x34, 0x1e, 0x1c, 0x4e, 0x2e, 0x03, 0x22, 0x01, 0x07, 0x11, 0x16, 0x0f, 0x0f, 0x40, 0x40, ++ 0x40, 0x40, 0x40, 0x40, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x07, 0x09, 0x45, 0x55, 0x58, 0x40, 0x40, 0x40, 0x40, 0x40, 0x0b, 0x40, 0x40, 0x40, 0x0b, 0x5a, ++ 0x45, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x07, 0x02, 0x02, 0x61, ++ 0x55, 0x57, 0x02, 0x1b, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x45, 0x45, 0x59, 0x59, 0x4b, 0x53, ++ 0x4d, 0x07, 0x53, 0x63, 0x4d, 0x51, 0x61, 0x65, 0x63, 0x61, 0x5d, 0x49, 0x43, 0x5a, 0x59, 0x59, ++ 0x4b, 0x53, 0x4d, 0x07, 0x53, 0x63, 0x4d, 0x51, 0x61, 0x65, 0x63, 0x61, 0x5d, 0x49, 0x43, 0x5a, ++ 0x00, 0x4a, 0x22, 0x55, 0x61, 0x61, 0x53, 0x59, 0x59, 0x57, 0x4b, 0x49, 0x4b, 0x41, 0x53, 0x55, ++ 0x33, 0x07, 0x53, 0x41, 0x53, 0x55, 0x33, 0x07, 0x53, 0x41, 0x53, 0x55, 0x33, 0x07, 0x53, 0x4d, ++ 0x45, 0x1b, 0x1b, 0x0f, 0x12, 0x0f, 0x12, 0x07, 0x12, 0x45, 0x61, 0x12, 0x45, 0x61, 0x40, 0x40, ++ 0x4d, 0x47, 0x0a, 0x02, 0x4d, 0x0f, 0x02, 0x45, 0x07, 0x0a, 0x27, 0x47, 0x45, 0x41, 0x04, 0x0f, ++ 0x4d, 0x33, 0x1d, 0x1b, 0x4d, 0x2d, 0x04, 0x21, 0x02, 0x07, 0x12, 0x15, 0x0f, 0x0f, 0x40, 0x40, ++ 0x40, 0x40, 0x40, 0x40, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x07, 0x08, 0x45, 0x55, 0x58, 0x40, 0x40, 0x40, 0x40, 0x40, 0x0a, 0x40, 0x40, 0x40, 0x0a, 0x59, ++ 0x45, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x07, 0x02, 0x02, 0x60, ++ 0x55, 0x56, 0x02, 0x1a, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x45, 0x45, 0x58, 0x58, 0x4b, 0x53, ++ 0x4d, 0x07, 0x53, 0x63, 0x4d, 0x50, 0x60, 0x65, 0x63, 0x60, 0x5b, 0x48, 0x43, 0x59, 0x58, 0x58, ++ 0x4b, 0x53, 0x4d, 0x07, 0x53, 0x63, 0x4d, 0x50, 0x60, 0x65, 0x63, 0x60, 0x5b, 0x48, 0x43, 0x59, ++ 0x01, 0x4a, 0x22, 0x55, 0x60, 0x60, 0x53, 0x58, 0x58, 0x56, 0x4b, 0x48, 0x4b, 0x40, 0x53, 0x55, ++ 0x32, 0x07, 0x53, 0x40, 0x53, 0x55, 0x32, 0x07, 0x53, 0x40, 0x53, 0x55, 0x32, 0x07, 0x53, 0x4d, ++ 0x45, 0x1a, 0x1a, 0x0f, 0x12, 0x0f, 0x12, 0x07, 0x12, 0x45, 0x60, 0x12, 0x45, 0x60, 0x40, 0x40, ++ 0x4d, 0x46, 0x0a, 0x02, 0x4d, 0x0f, 0x02, 0x45, 0x07, 0x0c, 0x27, 0x46, 0x45, 0x40, 0x04, 0x0f, ++ 0x4d, 0x32, 0x1d, 0x1a, 0x4d, 0x2b, 0x04, 0x20, 0x02, 0x07, 0x12, 0x15, 0x0f, 0x0f, 0x40, 0x40, ++ 0x40, 0x40, 0x40, 0x40, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x07, 0x07, 0x45, 0x55, 0x58, 0x40, 0x40, 0x40, 0x40, 0x40, 0x0a, 0x40, 0x40, 0x40, 0x0a, 0x57, ++ 0x45, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x07, 0x02, 0x02, 0x5f, ++ 0x55, 0x54, 0x02, 0x1a, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x45, 0x45, 0x57, 0x57, 0x4a, 0x52, ++ 0x4d, 0x07, 0x52, 0x62, 0x4d, 0x4f, 0x5f, 0x65, 0x62, 0x5f, 0x59, 0x47, 0x42, 0x57, 0x57, 0x57, ++ 0x4a, 0x52, 0x4d, 0x07, 0x52, 0x62, 0x4d, 0x4f, 0x5f, 0x65, 0x62, 0x5f, 0x59, 0x47, 0x42, 0x57, ++ 0x03, 0x4a, 0x22, 0x55, 0x5f, 0x5f, 0x52, 0x57, 0x57, 0x54, 0x4a, 0x47, 0x4a, 0x00, 0x52, 0x55, ++ 0x32, 0x07, 0x52, 0x00, 0x52, 0x55, 0x32, 0x07, 0x52, 0x00, 0x52, 0x55, 0x32, 0x07, 0x52, 0x4d, ++ 0x45, 0x1a, 0x1a, 0x0f, 0x12, 0x0f, 0x12, 0x07, 0x12, 0x45, 0x5f, 0x12, 0x45, 0x5f, 0x40, 0x40, ++ 0x4d, 0x44, 0x0a, 0x02, 0x4d, 0x0f, 0x02, 0x45, 0x07, 0x0e, 0x27, 0x44, 0x45, 0x00, 0x05, 0x0f, ++ 0x4d, 0x32, 0x1d, 0x1a, 0x4d, 0x29, 0x05, 0x1f, 0x02, 0x07, 0x12, 0x15, 0x0f, 0x0f, 0x40, 0x40, ++ 0x40, 0x40, 0x40, 0x40, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x07, 0x06, 0x44, 0x54, 0x58, 0x40, 0x40, 0x40, 0x40, 0x40, 0x09, 0x40, 0x40, 0x40, 0x09, 0x55, ++ 0x44, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x07, 0x03, 0x03, 0x5e, ++ 0x54, 0x53, 0x03, 0x19, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x44, 0x44, 0x56, 0x56, 0x49, 0x51, ++ 0x4c, 0x07, 0x51, 0x61, 0x4c, 0x4e, 0x5e, 0x64, 0x61, 0x5e, 0x58, 0x46, 0x41, 0x55, 0x56, 0x56, ++ 0x49, 0x51, 0x4c, 0x07, 0x51, 0x61, 0x4c, 0x4e, 0x5e, 0x64, 0x61, 0x5e, 0x58, 0x46, 0x41, 0x55, ++ 0x04, 0x4b, 0x23, 0x54, 0x5e, 0x5e, 0x51, 0x56, 0x56, 0x53, 0x49, 0x46, 0x49, 0x01, 0x51, 0x54, ++ 0x31, 0x07, 0x51, 0x01, 0x51, 0x54, 0x31, 0x07, 0x51, 0x01, 0x51, 0x54, 0x31, 0x07, 0x51, 0x4c, ++ 0x44, 0x19, 0x19, 0x0f, 0x13, 0x0f, 0x13, 0x07, 0x13, 0x44, 0x5e, 0x13, 0x44, 0x5e, 0x40, 0x40, ++ 0x4c, 0x43, 0x0b, 0x03, 0x4c, 0x0f, 0x03, 0x44, 0x07, 0x0f, 0x27, 0x43, 0x44, 0x01, 0x06, 0x0f, ++ 0x4c, 0x31, 0x1c, 0x19, 0x4c, 0x28, 0x06, 0x1e, 0x03, 0x07, 0x13, 0x14, 0x0f, 0x0f, 0x40, 0x40, ++ 0x40, 0x40, 0x40, 0x40, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x07, 0x05, 0x44, 0x54, 0x58, 0x40, 0x40, 0x40, 0x40, 0x40, 0x09, 0x40, 0x40, 0x40, 0x09, 0x53, ++ 0x44, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x07, 0x03, 0x03, 0x5d, ++ 0x54, 0x52, 0x03, 0x19, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x44, 0x44, 0x55, 0x55, 0x49, 0x51, ++ 0x4c, 0x07, 0x51, 0x61, 0x4c, 0x4d, 0x5d, 0x64, 0x61, 0x5d, 0x56, 0x45, 0x41, 0x53, 0x55, 0x55, ++ 0x49, 0x51, 0x4c, 0x07, 0x51, 0x61, 0x4c, 0x4d, 0x5d, 0x64, 0x61, 0x5d, 0x56, 0x45, 0x41, 0x53, ++ 0x05, 0x4b, 0x23, 0x54, 0x5d, 0x5d, 0x51, 0x55, 0x55, 0x52, 0x49, 0x45, 0x49, 0x02, 0x51, 0x54, ++ 0x31, 0x07, 0x51, 0x02, 0x51, 0x54, 0x31, 0x07, 0x51, 0x02, 0x51, 0x54, 0x31, 0x07, 0x51, 0x4c, ++ 0x44, 0x19, 0x19, 0x0f, 0x13, 0x0f, 0x13, 0x07, 0x13, 0x44, 0x5d, 0x13, 0x44, 0x5d, 0x40, 0x40, ++ 0x4c, 0x42, 0x0b, 0x03, 0x4c, 0x0f, 0x03, 0x44, 0x07, 0x11, 0x27, 0x42, 0x44, 0x02, 0x06, 0x0f, ++ 0x4c, 0x31, 0x1c, 0x19, 0x4c, 0x26, 0x06, 0x1d, 0x03, 0x07, 0x13, 0x14, 0x0f, 0x0f, 0x40, 0x40, ++ 0x40, 0x40, 0x40, 0x40, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x07, 0x04, 0x44, 0x54, 0x58, 0x40, 0x40, 0x40, 0x40, 0x40, 0x08, 0x40, 0x40, 0x40, 0x08, 0x51, ++ 0x44, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x07, 0x03, 0x03, 0x5c, ++ 0x54, 0x51, 0x03, 0x18, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x44, 0x44, 0x54, 0x54, 0x48, 0x50, ++ 0x4c, 0x07, 0x50, 0x60, 0x4c, 0x4c, 0x5c, 0x64, 0x60, 0x5c, 0x55, 0x44, 0x40, 0x51, 0x54, 0x54, ++ 0x48, 0x50, 0x4c, 0x07, 0x50, 0x60, 0x4c, 0x4c, 0x5c, 0x64, 0x60, 0x5c, 0x55, 0x44, 0x40, 0x51, ++ 0x06, 0x4b, 0x23, 0x54, 0x5c, 0x5c, 0x50, 0x54, 0x54, 0x51, 0x48, 0x44, 0x48, 0x03, 0x50, 0x54, ++ 0x30, 0x07, 0x50, 0x03, 0x50, 0x54, 0x30, 0x07, 0x50, 0x03, 0x50, 0x54, 0x30, 0x07, 0x50, 0x4c, ++ 0x44, 0x18, 0x18, 0x0f, 0x13, 0x0f, 0x13, 0x07, 0x13, 0x44, 0x5c, 0x13, 0x44, 0x5c, 0x40, 0x40, ++ 0x4c, 0x41, 0x0b, 0x03, 0x4c, 0x0f, 0x03, 0x44, 0x07, 0x12, 0x27, 0x41, 0x44, 0x03, 0x07, 0x0f, ++ 0x4c, 0x30, 0x1c, 0x18, 0x4c, 0x25, 0x07, 0x1c, 0x03, 0x07, 0x13, 0x14, 0x0f, 0x0f, 0x40, 0x40, ++ 0x40, 0x40, 0x40, 0x40, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x07, 0x03, 0x43, 0x53, 0x58, 0x40, 0x40, 0x40, 0x40, 0x40, 0x07, 0x40, 0x40, 0x40, 0x07, 0x4f, ++ 0x43, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x07, 0x04, 0x04, 0x5b, ++ 0x53, 0x4f, 0x04, 0x17, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x43, 0x43, 0x53, 0x53, 0x47, 0x4f, ++ 0x4b, 0x07, 0x4f, 0x5f, 0x4b, 0x4b, 0x5b, 0x63, 0x5f, 0x5b, 0x53, 0x43, 0x00, 0x4f, 0x53, 0x53, ++ 0x47, 0x4f, 0x4b, 0x07, 0x4f, 0x5f, 0x4b, 0x4b, 0x5b, 0x63, 0x5f, 0x5b, 0x53, 0x43, 0x00, 0x4f, ++ 0x08, 0x4c, 0x24, 0x53, 0x5b, 0x5b, 0x4f, 0x53, 0x53, 0x4f, 0x47, 0x43, 0x47, 0x04, 0x4f, 0x53, ++ 0x2f, 0x07, 0x4f, 0x04, 0x4f, 0x53, 0x2f, 0x07, 0x4f, 0x04, 0x4f, 0x53, 0x2f, 0x07, 0x4f, 0x4b, ++ 0x43, 0x17, 0x17, 0x0f, 0x14, 0x0f, 0x14, 0x07, 0x14, 0x43, 0x5b, 0x14, 0x43, 0x5b, 0x40, 0x40, ++ 0x4b, 0x00, 0x0c, 0x04, 0x4b, 0x0f, 0x04, 0x43, 0x07, 0x14, 0x27, 0x00, 0x43, 0x04, 0x08, 0x0f, ++ 0x4b, 0x2f, 0x1b, 0x17, 0x4b, 0x23, 0x08, 0x1b, 0x04, 0x07, 0x14, 0x13, 0x0f, 0x0f, 0x40, 0x40, ++ 0x40, 0x40, 0x40, 0x40, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x07, 0x02, 0x43, 0x53, 0x58, 0x40, 0x40, 0x40, 0x40, 0x40, 0x07, 0x40, 0x40, 0x40, 0x07, 0x4d, ++ 0x43, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x07, 0x04, 0x04, 0x5a, ++ 0x53, 0x4e, 0x04, 0x17, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x43, 0x43, 0x52, 0x52, 0x47, 0x4f, ++ 0x4b, 0x07, 0x4f, 0x5f, 0x4b, 0x4a, 0x5a, 0x63, 0x5f, 0x5a, 0x52, 0x42, 0x00, 0x4d, 0x52, 0x52, ++ 0x47, 0x4f, 0x4b, 0x07, 0x4f, 0x5f, 0x4b, 0x4a, 0x5a, 0x63, 0x5f, 0x5a, 0x52, 0x42, 0x00, 0x4d, ++ 0x09, 0x4c, 0x24, 0x53, 0x5a, 0x5a, 0x4f, 0x52, 0x52, 0x4e, 0x47, 0x42, 0x47, 0x05, 0x4f, 0x53, ++ 0x2f, 0x07, 0x4f, 0x05, 0x4f, 0x53, 0x2f, 0x07, 0x4f, 0x05, 0x4f, 0x53, 0x2f, 0x07, 0x4f, 0x4b, ++ 0x43, 0x17, 0x17, 0x0f, 0x14, 0x0f, 0x14, 0x07, 0x14, 0x43, 0x5a, 0x14, 0x43, 0x5a, 0x40, 0x40, ++ 0x4b, 0x01, 0x0c, 0x04, 0x4b, 0x0f, 0x04, 0x43, 0x07, 0x15, 0x27, 0x01, 0x43, 0x05, 0x08, 0x0f, ++ 0x4b, 0x2f, 0x1b, 0x17, 0x4b, 0x22, 0x08, 0x1a, 0x04, 0x07, 0x14, 0x13, 0x0f, 0x0f, 0x40, 0x40, ++ 0x40, 0x40, 0x40, 0x40, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x07, 0x01, 0x43, 0x53, 0x58, 0x40, 0x40, 0x40, 0x40, 0x40, 0x06, 0x40, 0x40, 0x40, 0x06, 0x4b, ++ 0x43, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x07, 0x04, 0x04, 0x59, ++ 0x53, 0x4d, 0x04, 0x16, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x43, 0x43, 0x51, 0x51, 0x46, 0x4e, ++ 0x4b, 0x07, 0x4e, 0x5e, 0x4b, 0x49, 0x59, 0x63, 0x5e, 0x59, 0x50, 0x41, 0x01, 0x4b, 0x51, 0x51, ++ 0x46, 0x4e, 0x4b, 0x07, 0x4e, 0x5e, 0x4b, 0x49, 0x59, 0x63, 0x5e, 0x59, 0x50, 0x41, 0x01, 0x4b, ++ 0x0a, 0x4c, 0x24, 0x53, 0x59, 0x59, 0x4e, 0x51, 0x51, 0x4d, 0x46, 0x41, 0x46, 0x06, 0x4e, 0x53, ++ 0x2e, 0x07, 0x4e, 0x06, 0x4e, 0x53, 0x2e, 0x07, 0x4e, 0x06, 0x4e, 0x53, 0x2e, 0x07, 0x4e, 0x4b, ++ 0x43, 0x16, 0x16, 0x0f, 0x14, 0x0f, 0x14, 0x07, 0x14, 0x43, 0x59, 0x14, 0x43, 0x59, 0x40, 0x40, ++ 0x4b, 0x02, 0x0c, 0x04, 0x4b, 0x0f, 0x04, 0x43, 0x07, 0x17, 0x27, 0x02, 0x43, 0x06, 0x09, 0x0f, ++ 0x4b, 0x2e, 0x1b, 0x16, 0x4b, 0x20, 0x09, 0x19, 0x04, 0x07, 0x14, 0x13, 0x0f, 0x0f, 0x40, 0x40, ++ 0x40, 0x40, 0x40, 0x40, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x07, 0x00, 0x43, 0x53, 0x58, 0x40, 0x40, 0x40, 0x40, 0x40, 0x05, 0x40, 0x40, 0x40, 0x05, 0x4a, ++ 0x43, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x07, 0x04, 0x04, 0x59, ++ 0x53, 0x4c, 0x04, 0x15, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x43, 0x43, 0x51, 0x51, 0x46, 0x4e, ++ 0x4b, 0x07, 0x4e, 0x5e, 0x4b, 0x49, 0x59, 0x63, 0x5e, 0x59, 0x4f, 0x41, 0x01, 0x4a, 0x51, 0x51, ++ 0x46, 0x4e, 0x4b, 0x07, 0x4e, 0x5e, 0x4b, 0x49, 0x59, 0x63, 0x5e, 0x59, 0x4f, 0x41, 0x01, 0x4a, ++ 0x0b, 0x4d, 0x24, 0x53, 0x59, 0x59, 0x4e, 0x51, 0x51, 0x4c, 0x46, 0x41, 0x46, 0x06, 0x4e, 0x53, ++ 0x2d, 0x07, 0x4e, 0x06, 0x4e, 0x53, 0x2d, 0x07, 0x4e, 0x06, 0x4e, 0x53, 0x2d, 0x07, 0x4e, 0x4b, ++ 0x43, 0x15, 0x15, 0x0f, 0x14, 0x0f, 0x14, 0x07, 0x14, 0x43, 0x59, 0x14, 0x43, 0x59, 0x40, 0x40, ++ 0x4b, 0x03, 0x0c, 0x04, 0x4b, 0x0f, 0x04, 0x43, 0x07, 0x18, 0x27, 0x03, 0x43, 0x06, 0x09, 0x0f, ++ 0x4b, 0x2d, 0x1a, 0x15, 0x4b, 0x1e, 0x09, 0x18, 0x04, 0x07, 0x14, 0x12, 0x0f, 0x0f, 0x40, 0x40, ++ 0x40, 0x40, 0x40, 0x40, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x07, 0x00, 0x42, 0x52, 0x58, 0x40, 0x40, 0x40, 0x40, 0x40, 0x05, 0x40, 0x40, 0x40, 0x05, 0x48, ++ 0x42, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x07, 0x05, 0x05, 0x58, ++ 0x52, 0x4a, 0x05, 0x15, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x42, 0x42, 0x50, 0x50, 0x45, 0x4d, ++ 0x4a, 0x07, 0x4d, 0x5d, 0x4a, 0x48, 0x58, 0x62, 0x5d, 0x58, 0x4d, 0x40, 0x02, 0x48, 0x50, 0x50, ++ 0x45, 0x4d, 0x4a, 0x07, 0x4d, 0x5d, 0x4a, 0x48, 0x58, 0x62, 0x5d, 0x58, 0x4d, 0x40, 0x02, 0x48, ++ 0x0d, 0x4d, 0x25, 0x52, 0x58, 0x58, 0x4d, 0x50, 0x50, 0x4a, 0x45, 0x40, 0x45, 0x07, 0x4d, 0x52, ++ 0x2d, 0x07, 0x4d, 0x07, 0x4d, 0x52, 0x2d, 0x07, 0x4d, 0x07, 0x4d, 0x52, 0x2d, 0x07, 0x4d, 0x4a, ++ 0x42, 0x15, 0x15, 0x0f, 0x15, 0x0f, 0x15, 0x07, 0x15, 0x42, 0x58, 0x15, 0x42, 0x58, 0x40, 0x40, ++ 0x4a, 0x05, 0x0d, 0x05, 0x4a, 0x0f, 0x05, 0x42, 0x07, 0x1a, 0x27, 0x05, 0x42, 0x07, 0x0a, 0x0f, ++ 0x4a, 0x2d, 0x1a, 0x15, 0x4a, 0x1d, 0x0a, 0x18, 0x05, 0x07, 0x15, 0x12, 0x0f, 0x0f, 0x40, 0x40, ++ 0x40, 0x40, 0x40, 0x40, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x07, 0x40, 0x42, 0x52, 0x58, 0x40, 0x40, 0x40, 0x40, 0x40, 0x04, 0x40, 0x40, 0x40, 0x04, 0x46, ++ 0x42, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x07, 0x05, 0x05, 0x57, ++ 0x52, 0x49, 0x05, 0x14, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x42, 0x42, 0x4f, 0x4f, 0x44, 0x4c, ++ 0x4a, 0x07, 0x4c, 0x5c, 0x4a, 0x47, 0x57, 0x62, 0x5c, 0x57, 0x4b, 0x00, 0x03, 0x46, 0x4f, 0x4f, ++ 0x44, 0x4c, 0x4a, 0x07, 0x4c, 0x5c, 0x4a, 0x47, 0x57, 0x62, 0x5c, 0x57, 0x4b, 0x00, 0x03, 0x46, ++ 0x0e, 0x4d, 0x25, 0x52, 0x57, 0x57, 0x4c, 0x4f, 0x4f, 0x49, 0x44, 0x00, 0x44, 0x08, 0x4c, 0x52, ++ 0x2c, 0x07, 0x4c, 0x08, 0x4c, 0x52, 0x2c, 0x07, 0x4c, 0x08, 0x4c, 0x52, 0x2c, 0x07, 0x4c, 0x4a, ++ 0x42, 0x14, 0x14, 0x0f, 0x15, 0x0f, 0x15, 0x07, 0x15, 0x42, 0x57, 0x15, 0x42, 0x57, 0x40, 0x40, ++ 0x4a, 0x06, 0x0d, 0x05, 0x4a, 0x0f, 0x05, 0x42, 0x07, 0x1c, 0x27, 0x06, 0x42, 0x08, 0x0b, 0x0f, ++ 0x4a, 0x2c, 0x1a, 0x14, 0x4a, 0x1b, 0x0b, 0x17, 0x05, 0x07, 0x15, 0x12, 0x0f, 0x0f, 0x40, 0x40, ++ 0x40, 0x40, 0x40, 0x40, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x07, 0x41, 0x42, 0x52, 0x58, 0x40, 0x40, 0x40, 0x40, 0x40, 0x04, 0x40, 0x40, 0x40, 0x04, 0x44, ++ 0x42, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x07, 0x05, 0x05, 0x56, ++ 0x52, 0x48, 0x05, 0x14, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x42, 0x42, 0x4e, 0x4e, 0x44, 0x4c, ++ 0x4a, 0x07, 0x4c, 0x5c, 0x4a, 0x46, 0x56, 0x62, 0x5c, 0x56, 0x4a, 0x01, 0x03, 0x44, 0x4e, 0x4e, ++ 0x44, 0x4c, 0x4a, 0x07, 0x4c, 0x5c, 0x4a, 0x46, 0x56, 0x62, 0x5c, 0x56, 0x4a, 0x01, 0x03, 0x44, ++ 0x0f, 0x4d, 0x25, 0x52, 0x56, 0x56, 0x4c, 0x4e, 0x4e, 0x48, 0x44, 0x01, 0x44, 0x09, 0x4c, 0x52, ++ 0x2c, 0x07, 0x4c, 0x09, 0x4c, 0x52, 0x2c, 0x07, 0x4c, 0x09, 0x4c, 0x52, 0x2c, 0x07, 0x4c, 0x4a, ++ 0x42, 0x14, 0x14, 0x0f, 0x15, 0x0f, 0x15, 0x07, 0x15, 0x42, 0x56, 0x15, 0x42, 0x56, 0x40, 0x40, ++ 0x4a, 0x07, 0x0d, 0x05, 0x4a, 0x0f, 0x05, 0x42, 0x07, 0x1d, 0x27, 0x07, 0x42, 0x09, 0x0b, 0x0f, ++ 0x4a, 0x2c, 0x1a, 0x14, 0x4a, 0x1a, 0x0b, 0x16, 0x05, 0x07, 0x15, 0x12, 0x0f, 0x0f, 0x40, 0x40, ++ 0x40, 0x40, 0x40, 0x40, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x07, 0x42, 0x41, 0x51, 0x58, 0x40, 0x40, 0x40, 0x40, 0x40, 0x03, 0x40, 0x40, 0x40, 0x03, 0x42, ++ 0x41, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x07, 0x06, 0x06, 0x55, ++ 0x51, 0x47, 0x06, 0x13, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x41, 0x41, 0x4d, 0x4d, 0x43, 0x4b, ++ 0x49, 0x07, 0x4b, 0x5b, 0x49, 0x45, 0x55, 0x61, 0x5b, 0x55, 0x48, 0x02, 0x04, 0x42, 0x4d, 0x4d, ++ 0x43, 0x4b, 0x49, 0x07, 0x4b, 0x5b, 0x49, 0x45, 0x55, 0x61, 0x5b, 0x55, 0x48, 0x02, 0x04, 0x42, ++ 0x10, 0x4e, 0x26, 0x51, 0x55, 0x55, 0x4b, 0x4d, 0x4d, 0x47, 0x43, 0x02, 0x43, 0x0a, 0x4b, 0x51, ++ 0x2b, 0x07, 0x4b, 0x0a, 0x4b, 0x51, 0x2b, 0x07, 0x4b, 0x0a, 0x4b, 0x51, 0x2b, 0x07, 0x4b, 0x49, ++ 0x41, 0x13, 0x13, 0x0f, 0x16, 0x0f, 0x16, 0x07, 0x16, 0x41, 0x55, 0x16, 0x41, 0x55, 0x40, 0x40, ++ 0x49, 0x08, 0x0e, 0x06, 0x49, 0x0f, 0x06, 0x41, 0x07, 0x1f, 0x27, 0x08, 0x41, 0x0a, 0x0c, 0x0f, ++ 0x49, 0x2b, 0x19, 0x13, 0x49, 0x18, 0x0c, 0x15, 0x06, 0x07, 0x16, 0x11, 0x0f, 0x0f, 0x40, 0x40, ++ 0x40, 0x40, 0x40, 0x40, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x07, 0x43, 0x41, 0x51, 0x58, 0x40, 0x40, 0x40, 0x40, 0x40, 0x02, 0x40, 0x40, 0x40, 0x02, 0x40, ++ 0x41, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x07, 0x06, 0x06, 0x54, ++ 0x51, 0x45, 0x06, 0x12, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x41, 0x41, 0x4c, 0x4c, 0x42, 0x4a, ++ 0x49, 0x07, 0x4a, 0x5a, 0x49, 0x44, 0x54, 0x61, 0x5a, 0x54, 0x47, 0x03, 0x05, 0x40, 0x4c, 0x4c, ++ 0x42, 0x4a, 0x49, 0x07, 0x4a, 0x5a, 0x49, 0x44, 0x54, 0x61, 0x5a, 0x54, 0x47, 0x03, 0x05, 0x40, ++ 0x12, 0x4e, 0x26, 0x51, 0x54, 0x54, 0x4a, 0x4c, 0x4c, 0x45, 0x42, 0x03, 0x42, 0x0b, 0x4a, 0x51, ++ 0x2a, 0x07, 0x4a, 0x0b, 0x4a, 0x51, 0x2a, 0x07, 0x4a, 0x0b, 0x4a, 0x51, 0x2a, 0x07, 0x4a, 0x49, ++ 0x41, 0x12, 0x12, 0x0f, 0x16, 0x0f, 0x16, 0x07, 0x16, 0x41, 0x54, 0x16, 0x41, 0x54, 0x40, 0x40, ++ 0x49, 0x0a, 0x0e, 0x06, 0x49, 0x0f, 0x06, 0x41, 0x07, 0x20, 0x27, 0x0a, 0x41, 0x0b, 0x0d, 0x0f, ++ 0x49, 0x2a, 0x19, 0x12, 0x49, 0x17, 0x0d, 0x14, 0x06, 0x07, 0x16, 0x11, 0x0f, 0x0f, 0x40, 0x40, ++ 0x40, 0x40, 0x40, 0x40, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x07, 0x44, 0x41, 0x51, 0x58, 0x40, 0x40, 0x40, 0x40, 0x40, 0x02, 0x40, 0x40, 0x40, 0x02, 0x01, ++ 0x41, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x07, 0x06, 0x06, 0x53, ++ 0x51, 0x44, 0x06, 0x12, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x41, 0x41, 0x4b, 0x4b, 0x42, 0x4a, ++ 0x49, 0x07, 0x4a, 0x5a, 0x49, 0x43, 0x53, 0x61, 0x5a, 0x53, 0x45, 0x04, 0x05, 0x01, 0x4b, 0x4b, ++ 0x42, 0x4a, 0x49, 0x07, 0x4a, 0x5a, 0x49, 0x43, 0x53, 0x61, 0x5a, 0x53, 0x45, 0x04, 0x05, 0x01, ++ 0x13, 0x4e, 0x26, 0x51, 0x53, 0x53, 0x4a, 0x4b, 0x4b, 0x44, 0x42, 0x04, 0x42, 0x0c, 0x4a, 0x51, ++ 0x2a, 0x07, 0x4a, 0x0c, 0x4a, 0x51, 0x2a, 0x07, 0x4a, 0x0c, 0x4a, 0x51, 0x2a, 0x07, 0x4a, 0x49, ++ 0x41, 0x12, 0x12, 0x0f, 0x16, 0x0f, 0x16, 0x07, 0x16, 0x41, 0x53, 0x16, 0x41, 0x53, 0x40, 0x40, ++ 0x49, 0x0b, 0x0e, 0x06, 0x49, 0x0f, 0x06, 0x41, 0x07, 0x22, 0x27, 0x0b, 0x41, 0x0c, 0x0d, 0x0f, ++ 0x49, 0x2a, 0x19, 0x12, 0x49, 0x15, 0x0d, 0x13, 0x06, 0x07, 0x16, 0x11, 0x0f, 0x0f, 0x40, 0x40, ++ 0x40, 0x40, 0x40, 0x40, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x07, 0x45, 0x40, 0x50, 0x58, 0x40, 0x40, 0x40, 0x40, 0x40, 0x01, 0x40, 0x40, 0x40, 0x01, 0x03, ++ 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x07, 0x07, 0x07, 0x52, ++ 0x50, 0x43, 0x07, 0x11, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x4a, 0x4a, 0x41, 0x49, ++ 0x48, 0x07, 0x49, 0x59, 0x48, 0x42, 0x52, 0x60, 0x59, 0x52, 0x44, 0x05, 0x06, 0x03, 0x4a, 0x4a, ++ 0x41, 0x49, 0x48, 0x07, 0x49, 0x59, 0x48, 0x42, 0x52, 0x60, 0x59, 0x52, 0x44, 0x05, 0x06, 0x03, ++ 0x14, 0x4f, 0x27, 0x50, 0x52, 0x52, 0x49, 0x4a, 0x4a, 0x43, 0x41, 0x05, 0x41, 0x0d, 0x49, 0x50, ++ 0x29, 0x07, 0x49, 0x0d, 0x49, 0x50, 0x29, 0x07, 0x49, 0x0d, 0x49, 0x50, 0x29, 0x07, 0x49, 0x48, ++ 0x40, 0x11, 0x11, 0x0f, 0x17, 0x0f, 0x17, 0x07, 0x17, 0x40, 0x52, 0x17, 0x40, 0x52, 0x40, 0x40, ++ 0x48, 0x0c, 0x0f, 0x07, 0x48, 0x0f, 0x07, 0x40, 0x07, 0x23, 0x27, 0x0c, 0x40, 0x0d, 0x0e, 0x0f, ++ 0x48, 0x29, 0x18, 0x11, 0x48, 0x14, 0x0e, 0x12, 0x07, 0x07, 0x17, 0x10, 0x0f, 0x0f, 0x40, 0x40, ++ 0x40, 0x40, 0x40, 0x40, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x07, 0x46, 0x40, 0x50, 0x58, 0x40, 0x40, 0x40, 0x40, 0x40, 0x00, 0x40, 0x40, 0x40, 0x00, 0x04, ++ 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x07, 0x07, 0x07, 0x51, ++ 0x50, 0x42, 0x07, 0x10, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x49, 0x49, 0x41, 0x49, ++ 0x48, 0x07, 0x49, 0x59, 0x48, 0x41, 0x51, 0x60, 0x59, 0x51, 0x42, 0x06, 0x06, 0x04, 0x49, 0x49, ++ 0x41, 0x49, 0x48, 0x07, 0x49, 0x59, 0x48, 0x41, 0x51, 0x60, 0x59, 0x51, 0x42, 0x06, 0x06, 0x04, ++ 0x15, 0x4f, 0x27, 0x50, 0x51, 0x51, 0x49, 0x49, 0x49, 0x42, 0x41, 0x06, 0x41, 0x0e, 0x49, 0x50, ++ 0x28, 0x07, 0x49, 0x0e, 0x49, 0x50, 0x28, 0x07, 0x49, 0x0e, 0x49, 0x50, 0x28, 0x07, 0x49, 0x48, ++ 0x40, 0x10, 0x10, 0x0f, 0x17, 0x0f, 0x17, 0x07, 0x17, 0x40, 0x51, 0x17, 0x40, 0x51, 0x40, 0x40, ++ 0x48, 0x0d, 0x0f, 0x07, 0x48, 0x0f, 0x07, 0x40, 0x07, 0x25, 0x27, 0x0d, 0x40, 0x0e, 0x0e, 0x0f, ++ 0x48, 0x28, 0x18, 0x10, 0x48, 0x12, 0x0e, 0x11, 0x07, 0x07, 0x17, 0x10, 0x0f, 0x0f, 0x40, 0x40, ++ 0x40, 0x40, 0x40, 0x40, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x07, 0x47, 0x40, 0x50, 0x58, 0x40, 0x40, 0x40, 0x40, 0x40, 0x00, 0x40, 0x40, 0x40, 0x00, 0x06, ++ 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x07, 0x07, 0x07, 0x50, ++ 0x50, 0x40, 0x07, 0x10, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x48, 0x48, 0x40, 0x48, ++ 0x48, 0x07, 0x48, 0x58, 0x48, 0x40, 0x50, 0x60, 0x58, 0x50, 0x40, 0x07, 0x07, 0x06, 0x48, 0x48, ++ 0x40, 0x48, 0x48, 0x07, 0x48, 0x58, 0x48, 0x40, 0x50, 0x60, 0x58, 0x50, 0x40, 0x07, 0x07, 0x06, ++ 0x17, 0x4f, 0x27, 0x50, 0x50, 0x50, 0x48, 0x48, 0x48, 0x40, 0x40, 0x07, 0x40, 0x0f, 0x48, 0x50, ++ 0x28, 0x07, 0x48, 0x0f, 0x48, 0x50, 0x28, 0x07, 0x48, 0x0f, 0x48, 0x50, 0x28, 0x07, 0x48, 0x48, ++ 0x40, 0x10, 0x10, 0x0f, 0x17, 0x0f, 0x17, 0x07, 0x17, 0x40, 0x50, 0x17, 0x40, 0x50, 0x40, 0x40, ++ 0x48, 0x0f, 0x0f, 0x07, 0x48, 0x0f, 0x07, 0x40, 0x07, 0x27, 0x27, 0x0f, 0x40, 0x0f, 0x0f, 0x0f, ++ 0x48, 0x28, 0x18, 0x10, 0x48, 0x10, 0x0f, 0x10, 0x07, 0x07, 0x17, 0x10, 0x0f, 0x0f, 0x40, 0x40, ++ 0x40, 0x40, 0x40, 0x40, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x07, 0x48, 0x00, 0x4f, 0x58, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x08, ++ 0x00, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x07, 0x08, 0x08, 0x4f, ++ 0x4f, 0x00, 0x08, 0x0f, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x00, 0x00, 0x47, 0x47, 0x00, 0x47, ++ 0x47, 0x07, 0x47, 0x57, 0x47, 0x00, 0x4f, 0x5f, 0x57, 0x4f, 0x00, 0x08, 0x08, 0x08, 0x47, 0x47, ++ 0x00, 0x47, 0x47, 0x07, 0x47, 0x57, 0x47, 0x00, 0x4f, 0x5f, 0x57, 0x4f, 0x00, 0x08, 0x08, 0x08, ++ 0x18, 0x50, 0x28, 0x4f, 0x4f, 0x4f, 0x47, 0x47, 0x47, 0x00, 0x00, 0x08, 0x00, 0x10, 0x47, 0x4f, ++ 0x27, 0x07, 0x47, 0x10, 0x47, 0x4f, 0x27, 0x07, 0x47, 0x10, 0x47, 0x4f, 0x27, 0x07, 0x47, 0x47, ++ 0x00, 0x0f, 0x0f, 0x0f, 0x18, 0x0f, 0x18, 0x07, 0x18, 0x00, 0x4f, 0x18, 0x00, 0x4f, 0x40, 0x40, ++ 0x47, 0x10, 0x10, 0x08, 0x47, 0x0f, 0x08, 0x00, 0x07, 0x28, 0x27, 0x10, 0x00, 0x10, 0x10, 0x0f, ++ 0x47, 0x27, 0x17, 0x0f, 0x47, 0x0f, 0x10, 0x0f, 0x08, 0x07, 0x18, 0x0f, 0x0f, 0x0f, 0x40, 0x40, ++ 0x40, 0x40, 0x40, 0x40, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x07, 0x49, 0x00, 0x4f, 0x58, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x0a, ++ 0x00, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x07, 0x08, 0x08, 0x4e, ++ 0x4f, 0x01, 0x08, 0x0f, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x00, 0x00, 0x46, 0x46, 0x00, 0x47, ++ 0x47, 0x07, 0x47, 0x57, 0x47, 0x01, 0x4e, 0x5f, 0x57, 0x4e, 0x02, 0x09, 0x08, 0x0a, 0x46, 0x46, ++ 0x00, 0x47, 0x47, 0x07, 0x47, 0x57, 0x47, 0x01, 0x4e, 0x5f, 0x57, 0x4e, 0x02, 0x09, 0x08, 0x0a, ++ 0x19, 0x50, 0x28, 0x4f, 0x4e, 0x4e, 0x47, 0x46, 0x46, 0x01, 0x00, 0x09, 0x00, 0x11, 0x47, 0x4f, ++ 0x27, 0x07, 0x47, 0x11, 0x47, 0x4f, 0x27, 0x07, 0x47, 0x11, 0x47, 0x4f, 0x27, 0x07, 0x47, 0x47, ++ 0x00, 0x0f, 0x0f, 0x0f, 0x18, 0x0f, 0x18, 0x07, 0x18, 0x00, 0x4e, 0x18, 0x00, 0x4e, 0x40, 0x40, ++ 0x47, 0x11, 0x10, 0x08, 0x47, 0x0f, 0x08, 0x00, 0x07, 0x2a, 0x27, 0x11, 0x00, 0x11, 0x10, 0x0f, ++ 0x47, 0x27, 0x17, 0x0f, 0x47, 0x0d, 0x10, 0x0e, 0x08, 0x07, 0x18, 0x0f, 0x0f, 0x0f, 0x40, 0x40, ++ 0x40, 0x40, 0x40, 0x40, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x07, 0x4a, 0x00, 0x4f, 0x58, 0x40, 0x40, 0x40, 0x40, 0x40, 0x41, 0x40, 0x40, 0x40, 0x41, 0x0c, ++ 0x00, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x07, 0x08, 0x08, 0x4d, ++ 0x4f, 0x02, 0x08, 0x0e, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x00, 0x00, 0x45, 0x45, 0x01, 0x46, ++ 0x47, 0x07, 0x46, 0x56, 0x47, 0x02, 0x4d, 0x5f, 0x56, 0x4d, 0x03, 0x0a, 0x09, 0x0c, 0x45, 0x45, ++ 0x01, 0x46, 0x47, 0x07, 0x46, 0x56, 0x47, 0x02, 0x4d, 0x5f, 0x56, 0x4d, 0x03, 0x0a, 0x09, 0x0c, ++ 0x1a, 0x50, 0x28, 0x4f, 0x4d, 0x4d, 0x46, 0x45, 0x45, 0x02, 0x01, 0x0a, 0x01, 0x12, 0x46, 0x4f, ++ 0x26, 0x07, 0x46, 0x12, 0x46, 0x4f, 0x26, 0x07, 0x46, 0x12, 0x46, 0x4f, 0x26, 0x07, 0x46, 0x47, ++ 0x00, 0x0e, 0x0e, 0x0f, 0x18, 0x0f, 0x18, 0x07, 0x18, 0x00, 0x4d, 0x18, 0x00, 0x4d, 0x40, 0x40, ++ 0x47, 0x12, 0x10, 0x08, 0x47, 0x0f, 0x08, 0x00, 0x07, 0x2b, 0x27, 0x12, 0x00, 0x12, 0x11, 0x0f, ++ 0x47, 0x26, 0x17, 0x0e, 0x47, 0x0c, 0x11, 0x0d, 0x08, 0x07, 0x18, 0x0f, 0x0f, 0x0f, 0x40, 0x40, ++ 0x40, 0x40, 0x40, 0x40, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x07, 0x4b, 0x01, 0x4e, 0x58, 0x40, 0x40, 0x40, 0x40, 0x40, 0x42, 0x40, 0x40, 0x40, 0x42, 0x0e, ++ 0x01, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x07, 0x09, 0x09, 0x4c, ++ 0x4e, 0x04, 0x09, 0x0d, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x01, 0x01, 0x44, 0x44, 0x02, 0x45, ++ 0x46, 0x07, 0x45, 0x55, 0x46, 0x03, 0x4c, 0x5e, 0x55, 0x4c, 0x05, 0x0b, 0x0a, 0x0e, 0x44, 0x44, ++ 0x02, 0x45, 0x46, 0x07, 0x45, 0x55, 0x46, 0x03, 0x4c, 0x5e, 0x55, 0x4c, 0x05, 0x0b, 0x0a, 0x0e, ++ 0x1c, 0x51, 0x29, 0x4e, 0x4c, 0x4c, 0x45, 0x44, 0x44, 0x04, 0x02, 0x0b, 0x02, 0x13, 0x45, 0x4e, ++ 0x25, 0x07, 0x45, 0x13, 0x45, 0x4e, 0x25, 0x07, 0x45, 0x13, 0x45, 0x4e, 0x25, 0x07, 0x45, 0x46, ++ 0x01, 0x0d, 0x0d, 0x0f, 0x19, 0x0f, 0x19, 0x07, 0x19, 0x01, 0x4c, 0x19, 0x01, 0x4c, 0x40, 0x40, ++ 0x46, 0x14, 0x11, 0x09, 0x46, 0x0f, 0x09, 0x01, 0x07, 0x2d, 0x27, 0x14, 0x01, 0x13, 0x12, 0x0f, ++ 0x46, 0x25, 0x16, 0x0d, 0x46, 0x0a, 0x12, 0x0c, 0x09, 0x07, 0x19, 0x0e, 0x0f, 0x0f, 0x40, 0x40, ++ 0x40, 0x40, 0x40, 0x40, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x07, 0x4c, 0x01, 0x4e, 0x58, 0x40, 0x40, 0x40, 0x40, 0x40, 0x42, 0x40, 0x40, 0x40, 0x42, 0x10, ++ 0x01, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x07, 0x09, 0x09, 0x4b, ++ 0x4e, 0x05, 0x09, 0x0d, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x01, 0x01, 0x43, 0x43, 0x02, 0x45, ++ 0x46, 0x07, 0x45, 0x55, 0x46, 0x04, 0x4b, 0x5e, 0x55, 0x4b, 0x06, 0x0c, 0x0a, 0x10, 0x43, 0x43, ++ 0x02, 0x45, 0x46, 0x07, 0x45, 0x55, 0x46, 0x04, 0x4b, 0x5e, 0x55, 0x4b, 0x06, 0x0c, 0x0a, 0x10, ++ 0x1d, 0x51, 0x29, 0x4e, 0x4b, 0x4b, 0x45, 0x43, 0x43, 0x05, 0x02, 0x0c, 0x02, 0x14, 0x45, 0x4e, ++ 0x25, 0x07, 0x45, 0x14, 0x45, 0x4e, 0x25, 0x07, 0x45, 0x14, 0x45, 0x4e, 0x25, 0x07, 0x45, 0x46, ++ 0x01, 0x0d, 0x0d, 0x0f, 0x19, 0x0f, 0x19, 0x07, 0x19, 0x01, 0x4b, 0x19, 0x01, 0x4b, 0x40, 0x40, ++ 0x46, 0x15, 0x11, 0x09, 0x46, 0x0f, 0x09, 0x01, 0x07, 0x2e, 0x27, 0x15, 0x01, 0x14, 0x12, 0x0f, ++ 0x46, 0x25, 0x16, 0x0d, 0x46, 0x09, 0x12, 0x0b, 0x09, 0x07, 0x19, 0x0e, 0x0f, 0x0f, 0x40, 0x40, ++ 0x40, 0x40, 0x40, 0x40, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x07, 0x4d, 0x01, 0x4e, 0x58, 0x40, 0x40, 0x40, 0x40, 0x40, 0x43, 0x40, 0x40, 0x40, 0x43, 0x12, ++ 0x01, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x07, 0x09, 0x09, 0x4a, ++ 0x4e, 0x06, 0x09, 0x0c, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x01, 0x01, 0x42, 0x42, 0x03, 0x44, ++ 0x46, 0x07, 0x44, 0x54, 0x46, 0x05, 0x4a, 0x5e, 0x54, 0x4a, 0x08, 0x0d, 0x0b, 0x12, 0x42, 0x42, ++ 0x03, 0x44, 0x46, 0x07, 0x44, 0x54, 0x46, 0x05, 0x4a, 0x5e, 0x54, 0x4a, 0x08, 0x0d, 0x0b, 0x12, ++ 0x1e, 0x51, 0x29, 0x4e, 0x4a, 0x4a, 0x44, 0x42, 0x42, 0x06, 0x03, 0x0d, 0x03, 0x15, 0x44, 0x4e, ++ 0x24, 0x07, 0x44, 0x15, 0x44, 0x4e, 0x24, 0x07, 0x44, 0x15, 0x44, 0x4e, 0x24, 0x07, 0x44, 0x46, ++ 0x01, 0x0c, 0x0c, 0x0f, 0x19, 0x0f, 0x19, 0x07, 0x19, 0x01, 0x4a, 0x19, 0x01, 0x4a, 0x40, 0x40, ++ 0x46, 0x16, 0x11, 0x09, 0x46, 0x0f, 0x09, 0x01, 0x07, 0x30, 0x27, 0x16, 0x01, 0x15, 0x13, 0x0f, ++ 0x46, 0x24, 0x16, 0x0c, 0x46, 0x07, 0x13, 0x0a, 0x09, 0x07, 0x19, 0x0e, 0x0f, 0x0f, 0x40, 0x40, ++ 0x40, 0x40, 0x40, 0x40, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x07, 0x4e, 0x01, 0x4e, 0x58, 0x40, 0x40, 0x40, 0x40, 0x40, 0x44, 0x40, 0x40, 0x40, 0x44, 0x13, ++ 0x01, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x07, 0x09, 0x09, 0x4a, ++ 0x4e, 0x07, 0x09, 0x0b, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x01, 0x01, 0x42, 0x42, 0x03, 0x44, ++ 0x46, 0x07, 0x44, 0x54, 0x46, 0x05, 0x4a, 0x5e, 0x54, 0x4a, 0x09, 0x0d, 0x0b, 0x13, 0x42, 0x42, ++ 0x03, 0x44, 0x46, 0x07, 0x44, 0x54, 0x46, 0x05, 0x4a, 0x5e, 0x54, 0x4a, 0x09, 0x0d, 0x0b, 0x13, ++ 0x1f, 0x52, 0x29, 0x4e, 0x4a, 0x4a, 0x44, 0x42, 0x42, 0x07, 0x03, 0x0d, 0x03, 0x15, 0x44, 0x4e, ++ 0x23, 0x07, 0x44, 0x15, 0x44, 0x4e, 0x23, 0x07, 0x44, 0x15, 0x44, 0x4e, 0x23, 0x07, 0x44, 0x46, ++ 0x01, 0x0b, 0x0b, 0x0f, 0x19, 0x0f, 0x19, 0x07, 0x19, 0x01, 0x4a, 0x19, 0x01, 0x4a, 0x40, 0x40, ++ 0x46, 0x17, 0x11, 0x09, 0x46, 0x0f, 0x09, 0x01, 0x07, 0x31, 0x27, 0x17, 0x01, 0x15, 0x13, 0x0f, ++ 0x46, 0x23, 0x15, 0x0b, 0x46, 0x05, 0x13, 0x09, 0x09, 0x07, 0x19, 0x0d, 0x0f, 0x0f, 0x40, 0x40, ++ 0x40, 0x40, 0x40, 0x40, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x07, 0x4e, 0x02, 0x4d, 0x58, 0x40, 0x40, 0x40, 0x40, 0x40, 0x44, 0x40, 0x40, 0x40, 0x44, 0x15, ++ 0x02, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x07, 0x0a, 0x0a, 0x49, ++ 0x4d, 0x09, 0x0a, 0x0b, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x02, 0x02, 0x41, 0x41, 0x04, 0x43, ++ 0x45, 0x07, 0x43, 0x53, 0x45, 0x06, 0x49, 0x5d, 0x53, 0x49, 0x0b, 0x0e, 0x0c, 0x15, 0x41, 0x41, ++ 0x04, 0x43, 0x45, 0x07, 0x43, 0x53, 0x45, 0x06, 0x49, 0x5d, 0x53, 0x49, 0x0b, 0x0e, 0x0c, 0x15, ++ 0x21, 0x52, 0x2a, 0x4d, 0x49, 0x49, 0x43, 0x41, 0x41, 0x09, 0x04, 0x0e, 0x04, 0x16, 0x43, 0x4d, ++ 0x23, 0x07, 0x43, 0x16, 0x43, 0x4d, 0x23, 0x07, 0x43, 0x16, 0x43, 0x4d, 0x23, 0x07, 0x43, 0x45, ++ 0x02, 0x0b, 0x0b, 0x0f, 0x1a, 0x0f, 0x1a, 0x07, 0x1a, 0x02, 0x49, 0x1a, 0x02, 0x49, 0x40, 0x40, ++ 0x45, 0x19, 0x12, 0x0a, 0x45, 0x0f, 0x0a, 0x02, 0x07, 0x33, 0x27, 0x19, 0x02, 0x16, 0x14, 0x0f, ++ 0x45, 0x23, 0x15, 0x0b, 0x45, 0x04, 0x14, 0x09, 0x0a, 0x07, 0x1a, 0x0d, 0x0f, 0x0f, 0x40, 0x40, ++ 0x40, 0x40, 0x40, 0x40, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x07, 0x4f, 0x02, 0x4d, 0x58, 0x40, 0x40, 0x40, 0x40, 0x40, 0x45, 0x40, 0x40, 0x40, 0x45, 0x17, ++ 0x02, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x07, 0x0a, 0x0a, 0x48, ++ 0x4d, 0x0a, 0x0a, 0x0a, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x02, 0x02, 0x40, 0x40, 0x05, 0x42, ++ 0x45, 0x07, 0x42, 0x52, 0x45, 0x07, 0x48, 0x5d, 0x52, 0x48, 0x0d, 0x0f, 0x0d, 0x17, 0x40, 0x40, ++ 0x05, 0x42, 0x45, 0x07, 0x42, 0x52, 0x45, 0x07, 0x48, 0x5d, 0x52, 0x48, 0x0d, 0x0f, 0x0d, 0x17, ++ 0x22, 0x52, 0x2a, 0x4d, 0x48, 0x48, 0x42, 0x40, 0x40, 0x0a, 0x05, 0x0f, 0x05, 0x17, 0x42, 0x4d, ++ 0x22, 0x07, 0x42, 0x17, 0x42, 0x4d, 0x22, 0x07, 0x42, 0x17, 0x42, 0x4d, 0x22, 0x07, 0x42, 0x45, ++ 0x02, 0x0a, 0x0a, 0x0f, 0x1a, 0x0f, 0x1a, 0x07, 0x1a, 0x02, 0x48, 0x1a, 0x02, 0x48, 0x40, 0x40, ++ 0x45, 0x1a, 0x12, 0x0a, 0x45, 0x0f, 0x0a, 0x02, 0x07, 0x35, 0x27, 0x1a, 0x02, 0x17, 0x15, 0x0f, ++ 0x45, 0x22, 0x15, 0x0a, 0x45, 0x02, 0x15, 0x08, 0x0a, 0x07, 0x1a, 0x0d, 0x0f, 0x0f, 0x40, 0x40, ++ 0x40, 0x40, 0x40, 0x40, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x07, 0x50, 0x02, 0x4d, 0x58, 0x40, 0x40, 0x40, 0x40, 0x40, 0x45, 0x40, 0x40, 0x40, 0x45, 0x19, ++ 0x02, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x07, 0x0a, 0x0a, 0x47, ++ 0x4d, 0x0b, 0x0a, 0x0a, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x02, 0x02, 0x00, 0x00, 0x05, 0x42, ++ 0x45, 0x07, 0x42, 0x52, 0x45, 0x08, 0x47, 0x5d, 0x52, 0x47, 0x0e, 0x10, 0x0d, 0x19, 0x00, 0x00, ++ 0x05, 0x42, 0x45, 0x07, 0x42, 0x52, 0x45, 0x08, 0x47, 0x5d, 0x52, 0x47, 0x0e, 0x10, 0x0d, 0x19, ++ 0x23, 0x52, 0x2a, 0x4d, 0x47, 0x47, 0x42, 0x00, 0x00, 0x0b, 0x05, 0x10, 0x05, 0x18, 0x42, 0x4d, ++ 0x22, 0x07, 0x42, 0x18, 0x42, 0x4d, 0x22, 0x07, 0x42, 0x18, 0x42, 0x4d, 0x22, 0x07, 0x42, 0x45, ++ 0x02, 0x0a, 0x0a, 0x0f, 0x1a, 0x0f, 0x1a, 0x07, 0x1a, 0x02, 0x47, 0x1a, 0x02, 0x47, 0x40, 0x40, ++ 0x45, 0x1b, 0x12, 0x0a, 0x45, 0x0f, 0x0a, 0x02, 0x07, 0x36, 0x27, 0x1b, 0x02, 0x18, 0x15, 0x0f, ++ 0x45, 0x22, 0x15, 0x0a, 0x45, 0x01, 0x15, 0x07, 0x0a, 0x07, 0x1a, 0x0d, 0x0f, 0x0f, 0x40, 0x40, ++ 0x40, 0x40, 0x40, 0x40, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x07, 0x51, 0x03, 0x4c, 0x58, 0x40, 0x40, 0x40, 0x40, 0x40, 0x46, 0x40, 0x40, 0x40, 0x46, 0x1b, ++ 0x03, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x07, 0x0b, 0x0b, 0x46, ++ 0x4c, 0x0c, 0x0b, 0x09, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x03, 0x03, 0x01, 0x01, 0x06, 0x41, ++ 0x44, 0x07, 0x41, 0x51, 0x44, 0x09, 0x46, 0x5c, 0x51, 0x46, 0x10, 0x11, 0x0e, 0x1b, 0x01, 0x01, ++ 0x06, 0x41, 0x44, 0x07, 0x41, 0x51, 0x44, 0x09, 0x46, 0x5c, 0x51, 0x46, 0x10, 0x11, 0x0e, 0x1b, ++ 0x24, 0x53, 0x2b, 0x4c, 0x46, 0x46, 0x41, 0x01, 0x01, 0x0c, 0x06, 0x11, 0x06, 0x19, 0x41, 0x4c, ++ 0x21, 0x07, 0x41, 0x19, 0x41, 0x4c, 0x21, 0x07, 0x41, 0x19, 0x41, 0x4c, 0x21, 0x07, 0x41, 0x44, ++ 0x03, 0x09, 0x09, 0x0f, 0x1b, 0x0f, 0x1b, 0x07, 0x1b, 0x03, 0x46, 0x1b, 0x03, 0x46, 0x40, 0x40, ++ 0x44, 0x1c, 0x13, 0x0b, 0x44, 0x0f, 0x0b, 0x03, 0x07, 0x38, 0x27, 0x1c, 0x03, 0x19, 0x16, 0x0f, ++ 0x44, 0x21, 0x14, 0x09, 0x44, 0x40, 0x16, 0x06, 0x0b, 0x07, 0x1b, 0x0c, 0x0f, 0x0f, 0x40, 0x40, ++ 0x40, 0x40, 0x40, 0x40, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x07, 0x52, 0x03, 0x4c, 0x58, 0x40, 0x40, 0x40, 0x40, 0x40, 0x47, 0x40, 0x40, 0x40, 0x47, 0x1d, ++ 0x03, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x07, 0x0b, 0x0b, 0x45, ++ 0x4c, 0x0e, 0x0b, 0x08, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x03, 0x03, 0x02, 0x02, 0x07, 0x40, ++ 0x44, 0x07, 0x40, 0x50, 0x44, 0x0a, 0x45, 0x5c, 0x50, 0x45, 0x11, 0x12, 0x0f, 0x1d, 0x02, 0x02, ++ 0x07, 0x40, 0x44, 0x07, 0x40, 0x50, 0x44, 0x0a, 0x45, 0x5c, 0x50, 0x45, 0x11, 0x12, 0x0f, 0x1d, ++ 0x26, 0x53, 0x2b, 0x4c, 0x45, 0x45, 0x40, 0x02, 0x02, 0x0e, 0x07, 0x12, 0x07, 0x1a, 0x40, 0x4c, ++ 0x20, 0x07, 0x40, 0x1a, 0x40, 0x4c, 0x20, 0x07, 0x40, 0x1a, 0x40, 0x4c, 0x20, 0x07, 0x40, 0x44, ++ 0x03, 0x08, 0x08, 0x0f, 0x1b, 0x0f, 0x1b, 0x07, 0x1b, 0x03, 0x45, 0x1b, 0x03, 0x45, 0x40, 0x40, ++ 0x44, 0x1e, 0x13, 0x0b, 0x44, 0x0f, 0x0b, 0x03, 0x07, 0x39, 0x27, 0x1e, 0x03, 0x1a, 0x17, 0x0f, ++ 0x44, 0x20, 0x14, 0x08, 0x44, 0x41, 0x17, 0x05, 0x0b, 0x07, 0x1b, 0x0c, 0x0f, 0x0f, 0x40, 0x40, ++ 0x40, 0x40, 0x40, 0x40, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x07, 0x53, 0x03, 0x4c, 0x58, 0x40, 0x40, 0x40, 0x40, 0x40, 0x47, 0x40, 0x40, 0x40, 0x47, 0x1f, ++ 0x03, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x07, 0x0b, 0x0b, 0x44, ++ 0x4c, 0x0f, 0x0b, 0x08, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x03, 0x03, 0x03, 0x03, 0x07, 0x40, ++ 0x44, 0x07, 0x40, 0x50, 0x44, 0x0b, 0x44, 0x5c, 0x50, 0x44, 0x13, 0x13, 0x0f, 0x1f, 0x03, 0x03, ++ 0x07, 0x40, 0x44, 0x07, 0x40, 0x50, 0x44, 0x0b, 0x44, 0x5c, 0x50, 0x44, 0x13, 0x13, 0x0f, 0x1f, ++ 0x27, 0x53, 0x2b, 0x4c, 0x44, 0x44, 0x40, 0x03, 0x03, 0x0f, 0x07, 0x13, 0x07, 0x1b, 0x40, 0x4c, ++ 0x20, 0x07, 0x40, 0x1b, 0x40, 0x4c, 0x20, 0x07, 0x40, 0x1b, 0x40, 0x4c, 0x20, 0x07, 0x40, 0x44, ++ 0x03, 0x08, 0x08, 0x0f, 0x1b, 0x0f, 0x1b, 0x07, 0x1b, 0x03, 0x44, 0x1b, 0x03, 0x44, 0x40, 0x40, ++ 0x44, 0x1f, 0x13, 0x0b, 0x44, 0x0f, 0x0b, 0x03, 0x07, 0x3b, 0x27, 0x1f, 0x03, 0x1b, 0x17, 0x0f, ++ 0x44, 0x20, 0x14, 0x08, 0x44, 0x43, 0x17, 0x04, 0x0b, 0x07, 0x1b, 0x0c, 0x0f, 0x0f, 0x40, 0x40, ++ 0x40, 0x40, 0x40, 0x40, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x07, 0x54, 0x04, 0x4b, 0x58, 0x40, 0x40, 0x40, 0x40, 0x40, 0x48, 0x40, 0x40, 0x40, 0x48, 0x21, ++ 0x04, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x07, 0x0c, 0x0c, 0x43, ++ 0x4b, 0x10, 0x0c, 0x07, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x04, 0x04, 0x04, 0x04, 0x08, 0x00, ++ 0x43, 0x07, 0x00, 0x4f, 0x43, 0x0c, 0x43, 0x5b, 0x4f, 0x43, 0x14, 0x14, 0x10, 0x21, 0x04, 0x04, ++ 0x08, 0x00, 0x43, 0x07, 0x00, 0x4f, 0x43, 0x0c, 0x43, 0x5b, 0x4f, 0x43, 0x14, 0x14, 0x10, 0x21, ++ 0x28, 0x54, 0x2c, 0x4b, 0x43, 0x43, 0x00, 0x04, 0x04, 0x10, 0x08, 0x14, 0x08, 0x1c, 0x00, 0x4b, ++ 0x1f, 0x07, 0x00, 0x1c, 0x00, 0x4b, 0x1f, 0x07, 0x00, 0x1c, 0x00, 0x4b, 0x1f, 0x07, 0x00, 0x43, ++ 0x04, 0x07, 0x07, 0x0f, 0x1c, 0x0f, 0x1c, 0x07, 0x1c, 0x04, 0x43, 0x1c, 0x04, 0x43, 0x40, 0x40, ++ 0x43, 0x20, 0x14, 0x0c, 0x43, 0x0f, 0x0c, 0x04, 0x07, 0x3c, 0x27, 0x20, 0x04, 0x1c, 0x18, 0x0f, ++ 0x43, 0x1f, 0x13, 0x07, 0x43, 0x44, 0x18, 0x03, 0x0c, 0x07, 0x1c, 0x0b, 0x0f, 0x0f, 0x40, 0x40, ++ 0x40, 0x40, 0x40, 0x40, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x07, 0x55, 0x04, 0x4b, 0x58, 0x40, 0x40, 0x40, 0x40, 0x40, 0x49, 0x40, 0x40, 0x40, 0x49, 0x22, ++ 0x04, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x07, 0x0c, 0x0c, 0x42, ++ 0x4b, 0x11, 0x0c, 0x06, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x04, 0x04, 0x05, 0x05, 0x08, 0x00, ++ 0x43, 0x07, 0x00, 0x4f, 0x43, 0x0d, 0x42, 0x5b, 0x4f, 0x42, 0x16, 0x15, 0x10, 0x22, 0x05, 0x05, ++ 0x08, 0x00, 0x43, 0x07, 0x00, 0x4f, 0x43, 0x0d, 0x42, 0x5b, 0x4f, 0x42, 0x16, 0x15, 0x10, 0x22, ++ 0x29, 0x54, 0x2c, 0x4b, 0x42, 0x42, 0x00, 0x05, 0x05, 0x11, 0x08, 0x15, 0x08, 0x1d, 0x00, 0x4b, ++ 0x1e, 0x07, 0x00, 0x1d, 0x00, 0x4b, 0x1e, 0x07, 0x00, 0x1d, 0x00, 0x4b, 0x1e, 0x07, 0x00, 0x43, ++ 0x04, 0x06, 0x06, 0x0f, 0x1c, 0x0f, 0x1c, 0x07, 0x1c, 0x04, 0x42, 0x1c, 0x04, 0x42, 0x40, 0x40, ++ 0x43, 0x21, 0x14, 0x0c, 0x43, 0x0f, 0x0c, 0x04, 0x07, 0x3e, 0x27, 0x21, 0x04, 0x1d, 0x18, 0x0f, ++ 0x43, 0x1e, 0x13, 0x06, 0x43, 0x46, 0x18, 0x02, 0x0c, 0x07, 0x1c, 0x0b, 0x0f, 0x0f, 0x40, 0x40, ++ 0x40, 0x40, 0x40, 0x40, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x07, 0x56, 0x04, 0x4b, 0x58, 0x40, 0x40, 0x40, 0x40, 0x40, 0x49, 0x40, 0x40, 0x40, 0x49, 0x24, ++ 0x04, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x07, 0x0c, 0x0c, 0x41, ++ 0x4b, 0x13, 0x0c, 0x06, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x04, 0x04, 0x06, 0x06, 0x09, 0x01, ++ 0x43, 0x07, 0x01, 0x4e, 0x43, 0x0e, 0x41, 0x5b, 0x4e, 0x41, 0x18, 0x16, 0x11, 0x24, 0x06, 0x06, ++ 0x09, 0x01, 0x43, 0x07, 0x01, 0x4e, 0x43, 0x0e, 0x41, 0x5b, 0x4e, 0x41, 0x18, 0x16, 0x11, 0x24, ++ 0x2b, 0x54, 0x2c, 0x4b, 0x41, 0x41, 0x01, 0x06, 0x06, 0x13, 0x09, 0x16, 0x09, 0x1e, 0x01, 0x4b, ++ 0x1e, 0x07, 0x01, 0x1e, 0x01, 0x4b, 0x1e, 0x07, 0x01, 0x1e, 0x01, 0x4b, 0x1e, 0x07, 0x01, 0x43, ++ 0x04, 0x06, 0x06, 0x0f, 0x1c, 0x0f, 0x1c, 0x07, 0x1c, 0x04, 0x41, 0x1c, 0x04, 0x41, 0x40, 0x40, ++ 0x43, 0x23, 0x14, 0x0c, 0x43, 0x0f, 0x0c, 0x04, 0x07, 0x3e, 0x27, 0x23, 0x04, 0x1e, 0x19, 0x0f, ++ 0x43, 0x1e, 0x13, 0x06, 0x43, 0x48, 0x19, 0x01, 0x0c, 0x07, 0x1c, 0x0b, 0x0f, 0x0f, 0x40, 0x40, ++ 0x40, 0x40, 0x40, 0x40, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x07, 0x57, 0x05, 0x4a, 0x58, 0x40, 0x40, 0x40, 0x40, 0x40, 0x4a, 0x40, 0x40, 0x40, 0x4a, 0x26, ++ 0x05, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x07, 0x0d, 0x0d, 0x40, ++ 0x4a, 0x14, 0x0d, 0x05, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x05, 0x05, 0x07, 0x07, 0x0a, 0x02, ++ 0x42, 0x07, 0x02, 0x4d, 0x42, 0x0f, 0x40, 0x5a, 0x4d, 0x40, 0x19, 0x17, 0x12, 0x26, 0x07, 0x07, ++ 0x0a, 0x02, 0x42, 0x07, 0x02, 0x4d, 0x42, 0x0f, 0x40, 0x5a, 0x4d, 0x40, 0x19, 0x17, 0x12, 0x26, ++ 0x2c, 0x55, 0x2d, 0x4a, 0x40, 0x40, 0x02, 0x07, 0x07, 0x14, 0x0a, 0x17, 0x0a, 0x1f, 0x02, 0x4a, ++ 0x1d, 0x07, 0x02, 0x1f, 0x02, 0x4a, 0x1d, 0x07, 0x02, 0x1f, 0x02, 0x4a, 0x1d, 0x07, 0x02, 0x42, ++ 0x05, 0x05, 0x05, 0x0f, 0x1d, 0x0f, 0x1d, 0x07, 0x1d, 0x05, 0x40, 0x1d, 0x05, 0x40, 0x40, 0x40, ++ 0x42, 0x24, 0x15, 0x0d, 0x42, 0x0f, 0x0d, 0x05, 0x07, 0x3e, 0x27, 0x24, 0x05, 0x1f, 0x1a, 0x0f, ++ 0x42, 0x1d, 0x12, 0x05, 0x42, 0x49, 0x1a, 0x00, 0x0d, 0x07, 0x1d, 0x0a, 0x0f, 0x0f, 0x40, 0x40, ++ 0x40, 0x40, 0x40, 0x40, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x07, 0x58, 0x05, 0x4a, 0x58, 0x40, 0x40, 0x40, 0x40, 0x40, 0x4a, 0x40, 0x40, 0x40, 0x4a, 0x28, ++ 0x05, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x07, 0x0d, 0x0d, 0x00, ++ 0x4a, 0x15, 0x0d, 0x05, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x05, 0x05, 0x08, 0x08, 0x0a, 0x02, ++ 0x42, 0x07, 0x02, 0x4d, 0x42, 0x10, 0x00, 0x5a, 0x4d, 0x00, 0x1b, 0x18, 0x12, 0x28, 0x08, 0x08, ++ 0x0a, 0x02, 0x42, 0x07, 0x02, 0x4d, 0x42, 0x10, 0x00, 0x5a, 0x4d, 0x00, 0x1b, 0x18, 0x12, 0x28, ++ 0x2d, 0x55, 0x2d, 0x4a, 0x00, 0x00, 0x02, 0x08, 0x08, 0x15, 0x0a, 0x18, 0x0a, 0x20, 0x02, 0x4a, ++ 0x1d, 0x07, 0x02, 0x20, 0x02, 0x4a, 0x1d, 0x07, 0x02, 0x20, 0x02, 0x4a, 0x1d, 0x07, 0x02, 0x42, ++ 0x05, 0x05, 0x05, 0x0f, 0x1d, 0x0f, 0x1d, 0x07, 0x1d, 0x05, 0x00, 0x1d, 0x05, 0x00, 0x40, 0x40, ++ 0x42, 0x25, 0x15, 0x0d, 0x42, 0x0f, 0x0d, 0x05, 0x07, 0x3e, 0x27, 0x25, 0x05, 0x20, 0x1a, 0x0f, ++ 0x42, 0x1d, 0x12, 0x05, 0x42, 0x4b, 0x1a, 0x40, 0x0d, 0x07, 0x1d, 0x0a, 0x0f, 0x0f, 0x40, 0x40, ++ 0x40, 0x40, 0x40, 0x40, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x07, 0x59, 0x05, 0x4a, 0x58, 0x40, 0x40, 0x40, 0x40, 0x40, 0x4b, 0x40, 0x40, 0x40, 0x4b, 0x2a, ++ 0x05, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x07, 0x0d, 0x0d, 0x01, ++ 0x4a, 0x16, 0x0d, 0x04, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x05, 0x05, 0x09, 0x09, 0x0b, 0x03, ++ 0x42, 0x07, 0x03, 0x4c, 0x42, 0x11, 0x01, 0x5a, 0x4c, 0x01, 0x1c, 0x19, 0x13, 0x2a, 0x09, 0x09, ++ 0x0b, 0x03, 0x42, 0x07, 0x03, 0x4c, 0x42, 0x11, 0x01, 0x5a, 0x4c, 0x01, 0x1c, 0x19, 0x13, 0x2a, ++ 0x2e, 0x55, 0x2d, 0x4a, 0x01, 0x01, 0x03, 0x09, 0x09, 0x16, 0x0b, 0x19, 0x0b, 0x21, 0x03, 0x4a, ++ 0x1c, 0x07, 0x03, 0x21, 0x03, 0x4a, 0x1c, 0x07, 0x03, 0x21, 0x03, 0x4a, 0x1c, 0x07, 0x03, 0x42, ++ 0x05, 0x04, 0x04, 0x0f, 0x1d, 0x0f, 0x1d, 0x07, 0x1d, 0x05, 0x01, 0x1d, 0x05, 0x01, 0x40, 0x40, ++ 0x42, 0x26, 0x15, 0x0d, 0x42, 0x0f, 0x0d, 0x05, 0x07, 0x3e, 0x27, 0x26, 0x05, 0x21, 0x1b, 0x0f, ++ 0x42, 0x1c, 0x12, 0x04, 0x42, 0x4c, 0x1b, 0x41, 0x0d, 0x07, 0x1d, 0x0a, 0x0f, 0x0f, 0x40, 0x40, ++ 0x40, 0x40, 0x40, 0x40, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x07, 0x5a, 0x06, 0x49, 0x58, 0x40, 0x40, 0x40, 0x40, 0x40, 0x4c, 0x40, 0x40, 0x40, 0x4c, 0x2c, ++ 0x06, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x07, 0x0e, 0x0e, 0x02, ++ 0x49, 0x18, 0x0e, 0x03, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x06, 0x06, 0x0a, 0x0a, 0x0c, 0x04, ++ 0x41, 0x07, 0x04, 0x4b, 0x41, 0x12, 0x02, 0x59, 0x4b, 0x02, 0x1e, 0x1a, 0x14, 0x2c, 0x0a, 0x0a, ++ 0x0c, 0x04, 0x41, 0x07, 0x04, 0x4b, 0x41, 0x12, 0x02, 0x59, 0x4b, 0x02, 0x1e, 0x1a, 0x14, 0x2c, ++ 0x30, 0x56, 0x2e, 0x49, 0x02, 0x02, 0x04, 0x0a, 0x0a, 0x18, 0x0c, 0x1a, 0x0c, 0x22, 0x04, 0x49, ++ 0x1b, 0x07, 0x04, 0x22, 0x04, 0x49, 0x1b, 0x07, 0x04, 0x22, 0x04, 0x49, 0x1b, 0x07, 0x04, 0x41, ++ 0x06, 0x03, 0x03, 0x0f, 0x1e, 0x0f, 0x1e, 0x07, 0x1e, 0x06, 0x02, 0x1e, 0x06, 0x02, 0x40, 0x40, ++ 0x41, 0x28, 0x16, 0x0e, 0x41, 0x0f, 0x0e, 0x06, 0x07, 0x3e, 0x27, 0x28, 0x06, 0x22, 0x1c, 0x0f, ++ 0x41, 0x1b, 0x11, 0x03, 0x41, 0x4e, 0x1c, 0x42, 0x0e, 0x07, 0x1e, 0x09, 0x0f, 0x0f, 0x40, 0x40, ++ 0x40, 0x40, 0x40, 0x40, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x07, 0x5b, 0x06, 0x49, 0x58, 0x40, 0x40, 0x40, 0x40, 0x40, 0x4c, 0x40, 0x40, 0x40, 0x4c, 0x2e, ++ 0x06, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x07, 0x0e, 0x0e, 0x03, ++ 0x49, 0x19, 0x0e, 0x03, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x06, 0x06, 0x0b, 0x0b, 0x0c, 0x04, ++ 0x41, 0x07, 0x04, 0x4b, 0x41, 0x13, 0x03, 0x59, 0x4b, 0x03, 0x1f, 0x1b, 0x14, 0x2e, 0x0b, 0x0b, ++ 0x0c, 0x04, 0x41, 0x07, 0x04, 0x4b, 0x41, 0x13, 0x03, 0x59, 0x4b, 0x03, 0x1f, 0x1b, 0x14, 0x2e, ++ 0x31, 0x56, 0x2e, 0x49, 0x03, 0x03, 0x04, 0x0b, 0x0b, 0x19, 0x0c, 0x1b, 0x0c, 0x23, 0x04, 0x49, ++ 0x1b, 0x07, 0x04, 0x23, 0x04, 0x49, 0x1b, 0x07, 0x04, 0x23, 0x04, 0x49, 0x1b, 0x07, 0x04, 0x41, ++ 0x06, 0x03, 0x03, 0x0f, 0x1e, 0x0f, 0x1e, 0x07, 0x1e, 0x06, 0x03, 0x1e, 0x06, 0x03, 0x40, 0x40, ++ 0x41, 0x29, 0x16, 0x0e, 0x41, 0x0f, 0x0e, 0x06, 0x07, 0x3e, 0x27, 0x29, 0x06, 0x23, 0x1c, 0x0f, ++ 0x41, 0x1b, 0x11, 0x03, 0x41, 0x4f, 0x1c, 0x43, 0x0e, 0x07, 0x1e, 0x09, 0x0f, 0x0f, 0x40, 0x40, ++ 0x40, 0x40, 0x40, 0x40, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x07, 0x5c, 0x06, 0x49, 0x58, 0x40, 0x40, 0x40, 0x40, 0x40, 0x4d, 0x40, 0x40, 0x40, 0x4d, 0x30, ++ 0x06, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x07, 0x0e, 0x0e, 0x04, ++ 0x49, 0x1a, 0x0e, 0x02, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x06, 0x06, 0x0c, 0x0c, 0x0d, 0x05, ++ 0x41, 0x07, 0x05, 0x4a, 0x41, 0x14, 0x04, 0x59, 0x4a, 0x04, 0x21, 0x1c, 0x15, 0x30, 0x0c, 0x0c, ++ 0x0d, 0x05, 0x41, 0x07, 0x05, 0x4a, 0x41, 0x14, 0x04, 0x59, 0x4a, 0x04, 0x21, 0x1c, 0x15, 0x30, ++ 0x32, 0x56, 0x2e, 0x49, 0x04, 0x04, 0x05, 0x0c, 0x0c, 0x1a, 0x0d, 0x1c, 0x0d, 0x24, 0x05, 0x49, ++ 0x1a, 0x07, 0x05, 0x24, 0x05, 0x49, 0x1a, 0x07, 0x05, 0x24, 0x05, 0x49, 0x1a, 0x07, 0x05, 0x41, ++ 0x06, 0x02, 0x02, 0x0f, 0x1e, 0x0f, 0x1e, 0x07, 0x1e, 0x06, 0x04, 0x1e, 0x06, 0x04, 0x40, 0x40, ++ 0x41, 0x2a, 0x16, 0x0e, 0x41, 0x0f, 0x0e, 0x06, 0x07, 0x3e, 0x27, 0x2a, 0x06, 0x24, 0x1d, 0x0f, ++ 0x41, 0x1a, 0x11, 0x02, 0x41, 0x51, 0x1d, 0x44, 0x0e, 0x07, 0x1e, 0x09, 0x0f, 0x0f, 0x40, 0x40, ++ 0x40, 0x40, 0x40, 0x40, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x07, 0x5d, 0x06, 0x49, 0x58, 0x40, 0x40, 0x40, 0x40, 0x40, 0x4e, 0x40, 0x40, 0x40, 0x4e, 0x31, ++ 0x06, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x07, 0x0e, 0x0e, 0x04, ++ 0x49, 0x1b, 0x0e, 0x01, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x06, 0x06, 0x0c, 0x0c, 0x0d, 0x05, ++ 0x41, 0x07, 0x05, 0x4a, 0x41, 0x14, 0x04, 0x59, 0x4a, 0x04, 0x22, 0x1c, 0x15, 0x31, 0x0c, 0x0c, ++ 0x0d, 0x05, 0x41, 0x07, 0x05, 0x4a, 0x41, 0x14, 0x04, 0x59, 0x4a, 0x04, 0x22, 0x1c, 0x15, 0x31, ++ 0x33, 0x57, 0x2e, 0x49, 0x04, 0x04, 0x05, 0x0c, 0x0c, 0x1b, 0x0d, 0x1c, 0x0d, 0x24, 0x05, 0x49, ++ 0x19, 0x07, 0x05, 0x24, 0x05, 0x49, 0x19, 0x07, 0x05, 0x24, 0x05, 0x49, 0x19, 0x07, 0x05, 0x41, ++ 0x06, 0x01, 0x01, 0x0f, 0x1e, 0x0f, 0x1e, 0x07, 0x1e, 0x06, 0x04, 0x1e, 0x06, 0x04, 0x40, 0x40, ++ 0x41, 0x2b, 0x16, 0x0e, 0x41, 0x0f, 0x0e, 0x06, 0x07, 0x3e, 0x27, 0x2b, 0x06, 0x24, 0x1d, 0x0f, ++ 0x41, 0x19, 0x10, 0x01, 0x41, 0x53, 0x1d, 0x45, 0x0e, 0x07, 0x1e, 0x08, 0x0f, 0x0f, 0x40, 0x40, ++ 0x40, 0x40, 0x40, 0x40, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x07, 0x5d, 0x07, 0x48, 0x58, 0x40, 0x40, 0x40, 0x40, 0x40, 0x4e, 0x40, 0x40, 0x40, 0x4e, 0x33, ++ 0x07, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x07, 0x0f, 0x0f, 0x05, ++ 0x48, 0x1d, 0x0f, 0x01, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x07, 0x07, 0x0d, 0x0d, 0x0e, 0x06, ++ 0x40, 0x07, 0x06, 0x49, 0x40, 0x15, 0x05, 0x58, 0x49, 0x05, 0x24, 0x1d, 0x16, 0x33, 0x0d, 0x0d, ++ 0x0e, 0x06, 0x40, 0x07, 0x06, 0x49, 0x40, 0x15, 0x05, 0x58, 0x49, 0x05, 0x24, 0x1d, 0x16, 0x33, ++ 0x35, 0x57, 0x2f, 0x48, 0x05, 0x05, 0x06, 0x0d, 0x0d, 0x1d, 0x0e, 0x1d, 0x0e, 0x25, 0x06, 0x48, ++ 0x19, 0x07, 0x06, 0x25, 0x06, 0x48, 0x19, 0x07, 0x06, 0x25, 0x06, 0x48, 0x19, 0x07, 0x06, 0x40, ++ 0x07, 0x01, 0x01, 0x0f, 0x1f, 0x0f, 0x1f, 0x07, 0x1f, 0x07, 0x05, 0x1f, 0x07, 0x05, 0x40, 0x40, ++ 0x40, 0x2d, 0x17, 0x0f, 0x40, 0x0f, 0x0f, 0x07, 0x07, 0x3e, 0x27, 0x2d, 0x07, 0x25, 0x1e, 0x0f, ++ 0x40, 0x19, 0x10, 0x01, 0x40, 0x54, 0x1e, 0x45, 0x0f, 0x07, 0x1f, 0x08, 0x0f, 0x0f, 0x40, 0x40, ++ 0x40, 0x40, 0x40, 0x40, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x07, 0x5e, 0x07, 0x48, 0x58, 0x40, 0x40, 0x40, 0x40, 0x40, 0x4f, 0x40, 0x40, 0x40, 0x4f, 0x35, ++ 0x07, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x07, 0x0f, 0x0f, 0x06, ++ 0x48, 0x1e, 0x0f, 0x00, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x07, 0x07, 0x0e, 0x0e, 0x0f, 0x07, ++ 0x40, 0x07, 0x07, 0x48, 0x40, 0x16, 0x06, 0x58, 0x48, 0x06, 0x26, 0x1e, 0x17, 0x35, 0x0e, 0x0e, ++ 0x0f, 0x07, 0x40, 0x07, 0x07, 0x48, 0x40, 0x16, 0x06, 0x58, 0x48, 0x06, 0x26, 0x1e, 0x17, 0x35, ++ 0x36, 0x57, 0x2f, 0x48, 0x06, 0x06, 0x07, 0x0e, 0x0e, 0x1e, 0x0f, 0x1e, 0x0f, 0x26, 0x07, 0x48, ++ 0x18, 0x07, 0x07, 0x26, 0x07, 0x48, 0x18, 0x07, 0x07, 0x26, 0x07, 0x48, 0x18, 0x07, 0x07, 0x40, ++ 0x07, 0x00, 0x00, 0x0f, 0x1f, 0x0f, 0x1f, 0x07, 0x1f, 0x07, 0x06, 0x1f, 0x07, 0x06, 0x40, 0x40, ++ 0x40, 0x2e, 0x17, 0x0f, 0x40, 0x0f, 0x0f, 0x07, 0x07, 0x3e, 0x27, 0x2e, 0x07, 0x26, 0x1f, 0x0f, ++ 0x40, 0x18, 0x10, 0x00, 0x40, 0x56, 0x1f, 0x46, 0x0f, 0x07, 0x1f, 0x08, 0x0f, 0x0f, 0x40, 0x40, ++ 0x40, 0x40, 0x40, 0x40, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x07, 0x5f, 0x07, 0x48, 0x58, 0x40, 0x40, 0x40, 0x40, 0x40, 0x4f, 0x40, 0x40, 0x40, 0x4f, 0x37, ++ 0x07, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x07, 0x0f, 0x0f, 0x07, ++ 0x48, 0x1f, 0x0f, 0x00, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x07, 0x07, 0x0f, 0x0f, 0x0f, 0x07, ++ 0x40, 0x07, 0x07, 0x48, 0x40, 0x17, 0x07, 0x58, 0x48, 0x07, 0x27, 0x1f, 0x17, 0x37, 0x0f, 0x0f, ++ 0x0f, 0x07, 0x40, 0x07, 0x07, 0x48, 0x40, 0x17, 0x07, 0x58, 0x48, 0x07, 0x27, 0x1f, 0x17, 0x37, ++ 0x37, 0x57, 0x2f, 0x48, 0x07, 0x07, 0x07, 0x0f, 0x0f, 0x1f, 0x0f, 0x1f, 0x0f, 0x27, 0x07, 0x48, ++ 0x18, 0x07, 0x07, 0x27, 0x07, 0x48, 0x18, 0x07, 0x07, 0x27, 0x07, 0x48, 0x18, 0x07, 0x07, 0x40, ++ 0x07, 0x00, 0x00, 0x0f, 0x1f, 0x0f, 0x1f, 0x07, 0x1f, 0x07, 0x07, 0x1f, 0x07, 0x07, 0x40, 0x40, ++ 0x40, 0x2f, 0x17, 0x0f, 0x40, 0x0f, 0x0f, 0x07, 0x07, 0x3e, 0x27, 0x2f, 0x07, 0x27, 0x1f, 0x0f, ++ 0x40, 0x18, 0x10, 0x00, 0x40, 0x57, 0x1f, 0x47, 0x0f, 0x07, 0x1f, 0x08, 0x0f, 0x0f, 0x40, 0x40, ++ 0x40, 0x40, 0x40, 0x40, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x07, 0x07, 0x48, 0x48, 0x60, 0x40, 0x27, 0x07, 0x07, 0x27, 0x40, 0x48, 0x40, 0x40, 0x40, 0x0f, ++ 0x48, 0x68, 0x60, 0x40, 0x68, 0x68, 0x68, 0x68, 0x68, 0x07, 0x07, 0x0f, 0x50, 0x40, 0x60, 0x07, ++ 0x68, 0x27, 0x48, 0x17, 0x40, 0x50, 0x1f, 0x40, 0x40, 0x40, 0x48, 0x48, 0x58, 0x60, 0x60, 0x60, ++ 0x68, 0x68, 0x58, 0x68, 0x60, 0x60, 0x60, 0x68, 0x68, 0x68, 0x60, 0x50, 0x48, 0x50, 0x58, 0x60, ++ 0x60, 0x60, 0x68, 0x68, 0x58, 0x68, 0x60, 0x60, 0x60, 0x68, 0x68, 0x68, 0x60, 0x50, 0x48, 0x50, ++ 0x07, 0x50, 0x58, 0x40, 0x48, 0x40, 0x48, 0x07, 0x48, 0x48, 0x48, 0x68, 0x07, 0x1f, 0x17, 0x50, ++ 0x0f, 0x07, 0x40, 0x1f, 0x17, 0x50, 0x0f, 0x07, 0x40, 0x1f, 0x17, 0x50, 0x0f, 0x07, 0x40, 0x40, ++ 0x07, 0x48, 0x48, 0x48, 0x07, 0x48, 0x07, 0x17, 0x17, 0x17, 0x50, 0x17, 0x17, 0x50, 0x40, 0x40, ++ 0x40, 0x2f, 0x2f, 0x17, 0x40, 0x0f, 0x17, 0x1f, 0x1f, 0x1f, 0x27, 0x0f, 0x07, 0x07, 0x0f, 0x07, ++ 0x07, 0x3e, 0x1f, 0x17, 0x40, 0x17, 0x07, 0x1f, 0x48, 0x17, 0x48, 0x40, 0x48, 0x17, 0x40, 0x40, ++ 0x40, 0x40, 0x40, 0x40, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x07, 0x07, 0x47, 0x47, 0x5f, 0x40, 0x27, 0x07, 0x07, 0x27, 0x40, 0x47, 0x40, 0x40, 0x40, 0x0f, ++ 0x47, 0x66, 0x5f, 0x00, 0x66, 0x66, 0x66, 0x65, 0x65, 0x07, 0x07, 0x0f, 0x4f, 0x00, 0x5e, 0x07, ++ 0x67, 0x27, 0x47, 0x17, 0x40, 0x4f, 0x1f, 0x40, 0x40, 0x40, 0x47, 0x47, 0x57, 0x5f, 0x5e, 0x5f, ++ 0x66, 0x66, 0x57, 0x67, 0x5f, 0x5e, 0x5f, 0x67, 0x67, 0x66, 0x5e, 0x4f, 0x47, 0x4f, 0x57, 0x5f, ++ 0x5e, 0x5f, 0x66, 0x66, 0x57, 0x67, 0x5f, 0x5e, 0x5f, 0x67, 0x67, 0x66, 0x5e, 0x4f, 0x47, 0x4f, ++ 0x08, 0x4f, 0x56, 0x40, 0x48, 0x40, 0x47, 0x07, 0x47, 0x47, 0x47, 0x66, 0x07, 0x1f, 0x17, 0x4f, ++ 0x10, 0x07, 0x40, 0x1f, 0x17, 0x4f, 0x10, 0x07, 0x40, 0x1f, 0x17, 0x4f, 0x10, 0x07, 0x40, 0x40, ++ 0x07, 0x47, 0x47, 0x47, 0x08, 0x47, 0x08, 0x17, 0x17, 0x17, 0x4f, 0x17, 0x17, 0x4f, 0x40, 0x40, ++ 0x40, 0x2f, 0x2f, 0x17, 0x40, 0x0f, 0x17, 0x1f, 0x1f, 0x20, 0x27, 0x10, 0x07, 0x08, 0x10, 0x08, ++ 0x07, 0x3e, 0x1f, 0x17, 0x40, 0x17, 0x08, 0x1f, 0x47, 0x17, 0x46, 0x00, 0x47, 0x17, 0x40, 0x40, ++ 0x40, 0x40, 0x40, 0x40, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x07, 0x06, 0x46, 0x47, 0x5e, 0x40, 0x26, 0x06, 0x06, 0x27, 0x40, 0x47, 0x40, 0x40, 0x40, 0x0f, ++ 0x47, 0x64, 0x5e, 0x01, 0x65, 0x64, 0x64, 0x63, 0x63, 0x07, 0x07, 0x0f, 0x4e, 0x00, 0x5d, 0x07, ++ 0x66, 0x27, 0x46, 0x17, 0x40, 0x4f, 0x1e, 0x40, 0x40, 0x40, 0x47, 0x47, 0x56, 0x5e, 0x5d, 0x5e, ++ 0x65, 0x64, 0x56, 0x66, 0x5e, 0x5c, 0x5e, 0x66, 0x66, 0x65, 0x5d, 0x4e, 0x46, 0x4e, 0x56, 0x5e, ++ 0x5d, 0x5e, 0x65, 0x64, 0x56, 0x66, 0x5e, 0x5c, 0x5e, 0x66, 0x66, 0x65, 0x5d, 0x4e, 0x46, 0x4e, ++ 0x09, 0x4f, 0x54, 0x40, 0x48, 0x40, 0x47, 0x07, 0x47, 0x46, 0x46, 0x64, 0x07, 0x1f, 0x16, 0x4f, ++ 0x10, 0x07, 0x40, 0x1f, 0x16, 0x4f, 0x10, 0x07, 0x40, 0x1f, 0x16, 0x4f, 0x10, 0x07, 0x40, 0x40, ++ 0x07, 0x46, 0x46, 0x46, 0x09, 0x46, 0x09, 0x17, 0x17, 0x16, 0x4f, 0x17, 0x16, 0x4f, 0x40, 0x40, ++ 0x40, 0x2e, 0x2e, 0x17, 0x40, 0x0f, 0x17, 0x1e, 0x1e, 0x20, 0x27, 0x10, 0x07, 0x09, 0x10, 0x08, ++ 0x07, 0x3e, 0x1f, 0x17, 0x40, 0x17, 0x08, 0x1e, 0x46, 0x17, 0x45, 0x01, 0x46, 0x17, 0x40, 0x40, ++ 0x40, 0x40, 0x40, 0x40, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x07, 0x06, 0x45, 0x47, 0x5e, 0x40, 0x25, 0x06, 0x05, 0x27, 0x40, 0x47, 0x40, 0x40, 0x40, 0x0f, ++ 0x47, 0x63, 0x5d, 0x01, 0x64, 0x63, 0x62, 0x60, 0x60, 0x07, 0x07, 0x0f, 0x4e, 0x00, 0x5c, 0x07, ++ 0x65, 0x27, 0x45, 0x17, 0x40, 0x4f, 0x1d, 0x40, 0x40, 0x40, 0x47, 0x47, 0x56, 0x5d, 0x5c, 0x5d, ++ 0x64, 0x63, 0x56, 0x65, 0x5d, 0x5b, 0x5d, 0x65, 0x65, 0x64, 0x5c, 0x4d, 0x46, 0x4d, 0x56, 0x5d, ++ 0x5c, 0x5d, 0x64, 0x63, 0x56, 0x65, 0x5d, 0x5b, 0x5d, 0x65, 0x65, 0x64, 0x5c, 0x4d, 0x46, 0x4d, ++ 0x09, 0x4f, 0x52, 0x40, 0x48, 0x40, 0x47, 0x07, 0x47, 0x46, 0x46, 0x62, 0x07, 0x1f, 0x16, 0x4f, ++ 0x10, 0x07, 0x40, 0x1f, 0x16, 0x4f, 0x10, 0x07, 0x40, 0x1f, 0x16, 0x4f, 0x10, 0x07, 0x40, 0x40, ++ 0x07, 0x46, 0x46, 0x45, 0x09, 0x45, 0x09, 0x17, 0x17, 0x16, 0x4f, 0x17, 0x16, 0x4f, 0x40, 0x40, ++ 0x40, 0x2d, 0x2d, 0x17, 0x40, 0x0f, 0x17, 0x1e, 0x1e, 0x20, 0x27, 0x10, 0x07, 0x09, 0x10, 0x08, ++ 0x07, 0x3d, 0x1f, 0x17, 0x40, 0x17, 0x08, 0x1e, 0x45, 0x17, 0x44, 0x01, 0x45, 0x17, 0x40, 0x40, ++ 0x40, 0x40, 0x40, 0x40, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x07, 0x05, 0x44, 0x46, 0x5d, 0x40, 0x24, 0x05, 0x04, 0x27, 0x40, 0x46, 0x40, 0x40, 0x40, 0x0f, ++ 0x46, 0x61, 0x5c, 0x02, 0x63, 0x61, 0x60, 0x5e, 0x5e, 0x07, 0x07, 0x0e, 0x4d, 0x01, 0x5b, 0x07, ++ 0x64, 0x27, 0x44, 0x16, 0x40, 0x4e, 0x1c, 0x40, 0x40, 0x40, 0x46, 0x46, 0x55, 0x5c, 0x5b, 0x5c, ++ 0x63, 0x61, 0x55, 0x64, 0x5c, 0x59, 0x5c, 0x64, 0x64, 0x63, 0x5b, 0x4c, 0x45, 0x4c, 0x55, 0x5c, ++ 0x5b, 0x5c, 0x63, 0x61, 0x55, 0x64, 0x5c, 0x59, 0x5c, 0x64, 0x64, 0x63, 0x5b, 0x4c, 0x45, 0x4c, ++ 0x0a, 0x4e, 0x50, 0x40, 0x48, 0x40, 0x46, 0x07, 0x46, 0x45, 0x45, 0x60, 0x07, 0x1e, 0x15, 0x4e, ++ 0x11, 0x07, 0x40, 0x1e, 0x15, 0x4e, 0x11, 0x07, 0x40, 0x1e, 0x15, 0x4e, 0x11, 0x07, 0x40, 0x41, ++ 0x07, 0x45, 0x45, 0x44, 0x0a, 0x44, 0x0a, 0x16, 0x17, 0x15, 0x4e, 0x17, 0x15, 0x4e, 0x40, 0x40, ++ 0x40, 0x2c, 0x2c, 0x16, 0x40, 0x0f, 0x16, 0x1d, 0x1d, 0x21, 0x27, 0x11, 0x07, 0x0a, 0x11, 0x09, ++ 0x06, 0x3c, 0x1e, 0x16, 0x40, 0x16, 0x09, 0x1d, 0x44, 0x16, 0x43, 0x02, 0x44, 0x16, 0x40, 0x40, ++ 0x40, 0x40, 0x40, 0x40, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x07, 0x04, 0x43, 0x46, 0x5c, 0x40, 0x23, 0x04, 0x03, 0x27, 0x40, 0x46, 0x40, 0x40, 0x40, 0x0f, ++ 0x46, 0x60, 0x5b, 0x03, 0x61, 0x60, 0x5e, 0x5b, 0x5b, 0x07, 0x07, 0x0e, 0x4c, 0x01, 0x59, 0x07, ++ 0x63, 0x27, 0x43, 0x16, 0x40, 0x4e, 0x1b, 0x40, 0x40, 0x40, 0x46, 0x46, 0x54, 0x5b, 0x59, 0x5b, ++ 0x61, 0x60, 0x54, 0x63, 0x5b, 0x58, 0x5b, 0x63, 0x63, 0x61, 0x59, 0x4b, 0x44, 0x4b, 0x54, 0x5b, ++ 0x59, 0x5b, 0x61, 0x60, 0x54, 0x63, 0x5b, 0x58, 0x5b, 0x63, 0x63, 0x61, 0x59, 0x4b, 0x44, 0x4b, ++ 0x0b, 0x4e, 0x4e, 0x40, 0x48, 0x40, 0x46, 0x07, 0x46, 0x44, 0x44, 0x5e, 0x07, 0x1e, 0x14, 0x4e, ++ 0x11, 0x07, 0x40, 0x1e, 0x14, 0x4e, 0x11, 0x07, 0x40, 0x1e, 0x14, 0x4e, 0x11, 0x07, 0x40, 0x41, ++ 0x07, 0x44, 0x44, 0x43, 0x0b, 0x43, 0x0b, 0x16, 0x17, 0x14, 0x4e, 0x17, 0x14, 0x4e, 0x40, 0x40, ++ 0x40, 0x2b, 0x2b, 0x16, 0x40, 0x0f, 0x16, 0x1c, 0x1c, 0x21, 0x27, 0x11, 0x07, 0x0b, 0x11, 0x09, ++ 0x06, 0x3b, 0x1e, 0x16, 0x40, 0x16, 0x09, 0x1c, 0x43, 0x16, 0x41, 0x03, 0x43, 0x16, 0x40, 0x40, ++ 0x40, 0x40, 0x40, 0x40, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x07, 0x04, 0x42, 0x46, 0x5c, 0x40, 0x22, 0x04, 0x02, 0x27, 0x40, 0x46, 0x40, 0x40, 0x40, 0x0f, ++ 0x46, 0x5e, 0x5a, 0x03, 0x60, 0x5e, 0x5c, 0x59, 0x59, 0x07, 0x07, 0x0e, 0x4c, 0x01, 0x58, 0x07, ++ 0x62, 0x27, 0x42, 0x16, 0x40, 0x4e, 0x1a, 0x40, 0x40, 0x40, 0x46, 0x46, 0x54, 0x5a, 0x58, 0x5a, ++ 0x60, 0x5e, 0x54, 0x62, 0x5a, 0x56, 0x5a, 0x62, 0x62, 0x60, 0x58, 0x4a, 0x44, 0x4a, 0x54, 0x5a, ++ 0x58, 0x5a, 0x60, 0x5e, 0x54, 0x62, 0x5a, 0x56, 0x5a, 0x62, 0x62, 0x60, 0x58, 0x4a, 0x44, 0x4a, ++ 0x0b, 0x4e, 0x4c, 0x40, 0x48, 0x40, 0x46, 0x07, 0x46, 0x44, 0x44, 0x5c, 0x07, 0x1e, 0x14, 0x4e, ++ 0x11, 0x07, 0x40, 0x1e, 0x14, 0x4e, 0x11, 0x07, 0x40, 0x1e, 0x14, 0x4e, 0x11, 0x07, 0x40, 0x41, ++ 0x07, 0x44, 0x44, 0x42, 0x0b, 0x42, 0x0b, 0x16, 0x17, 0x14, 0x4e, 0x17, 0x14, 0x4e, 0x40, 0x40, ++ 0x40, 0x2a, 0x2a, 0x16, 0x40, 0x0f, 0x16, 0x1c, 0x1c, 0x21, 0x27, 0x11, 0x07, 0x0b, 0x11, 0x09, ++ 0x06, 0x3a, 0x1e, 0x16, 0x40, 0x16, 0x09, 0x1c, 0x42, 0x16, 0x40, 0x03, 0x42, 0x16, 0x40, 0x40, ++ 0x40, 0x40, 0x40, 0x40, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x07, 0x03, 0x41, 0x45, 0x5b, 0x40, 0x21, 0x03, 0x01, 0x27, 0x40, 0x45, 0x40, 0x40, 0x40, 0x0f, ++ 0x45, 0x5d, 0x59, 0x04, 0x5f, 0x5d, 0x5a, 0x56, 0x56, 0x07, 0x07, 0x0d, 0x4b, 0x02, 0x57, 0x07, ++ 0x61, 0x27, 0x41, 0x15, 0x40, 0x4d, 0x19, 0x40, 0x40, 0x40, 0x45, 0x45, 0x53, 0x59, 0x57, 0x59, ++ 0x5f, 0x5d, 0x53, 0x61, 0x59, 0x55, 0x59, 0x61, 0x61, 0x5f, 0x57, 0x49, 0x43, 0x49, 0x53, 0x59, ++ 0x57, 0x59, 0x5f, 0x5d, 0x53, 0x61, 0x59, 0x55, 0x59, 0x61, 0x61, 0x5f, 0x57, 0x49, 0x43, 0x49, ++ 0x0c, 0x4d, 0x4a, 0x40, 0x48, 0x40, 0x45, 0x07, 0x45, 0x43, 0x43, 0x5a, 0x07, 0x1d, 0x13, 0x4d, ++ 0x12, 0x07, 0x40, 0x1d, 0x13, 0x4d, 0x12, 0x07, 0x40, 0x1d, 0x13, 0x4d, 0x12, 0x07, 0x40, 0x42, ++ 0x07, 0x43, 0x43, 0x41, 0x0c, 0x41, 0x0c, 0x15, 0x17, 0x13, 0x4d, 0x17, 0x13, 0x4d, 0x40, 0x40, ++ 0x40, 0x29, 0x29, 0x15, 0x40, 0x0f, 0x15, 0x1b, 0x1b, 0x22, 0x27, 0x12, 0x07, 0x0c, 0x12, 0x0a, ++ 0x05, 0x39, 0x1d, 0x15, 0x40, 0x15, 0x0a, 0x1b, 0x41, 0x15, 0x00, 0x04, 0x41, 0x15, 0x40, 0x40, ++ 0x40, 0x40, 0x40, 0x40, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x07, 0x02, 0x40, 0x45, 0x5b, 0x40, 0x20, 0x02, 0x00, 0x27, 0x40, 0x45, 0x40, 0x40, 0x40, 0x0f, ++ 0x45, 0x5b, 0x58, 0x04, 0x5e, 0x5b, 0x59, 0x54, 0x54, 0x07, 0x07, 0x0d, 0x4b, 0x02, 0x56, 0x07, ++ 0x60, 0x27, 0x40, 0x15, 0x40, 0x4d, 0x18, 0x40, 0x40, 0x40, 0x45, 0x45, 0x53, 0x58, 0x56, 0x58, ++ 0x5e, 0x5b, 0x53, 0x60, 0x58, 0x53, 0x58, 0x60, 0x60, 0x5e, 0x56, 0x48, 0x43, 0x48, 0x53, 0x58, ++ 0x56, 0x58, 0x5e, 0x5b, 0x53, 0x60, 0x58, 0x53, 0x58, 0x60, 0x60, 0x5e, 0x56, 0x48, 0x43, 0x48, ++ 0x0c, 0x4d, 0x49, 0x40, 0x48, 0x40, 0x45, 0x07, 0x45, 0x43, 0x43, 0x59, 0x07, 0x1d, 0x12, 0x4d, ++ 0x12, 0x07, 0x40, 0x1d, 0x12, 0x4d, 0x12, 0x07, 0x40, 0x1d, 0x12, 0x4d, 0x12, 0x07, 0x40, 0x42, ++ 0x07, 0x43, 0x43, 0x40, 0x0c, 0x40, 0x0c, 0x15, 0x17, 0x12, 0x4d, 0x17, 0x12, 0x4d, 0x40, 0x40, ++ 0x40, 0x28, 0x28, 0x15, 0x40, 0x0f, 0x15, 0x1a, 0x1a, 0x22, 0x27, 0x12, 0x07, 0x0c, 0x12, 0x0a, ++ 0x05, 0x38, 0x1d, 0x15, 0x40, 0x15, 0x0a, 0x1a, 0x40, 0x15, 0x01, 0x04, 0x40, 0x15, 0x40, 0x40, ++ 0x40, 0x40, 0x40, 0x40, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x07, 0x02, 0x00, 0x45, 0x5a, 0x40, 0x1f, 0x02, 0x40, 0x27, 0x40, 0x45, 0x40, 0x40, 0x40, 0x0f, ++ 0x45, 0x59, 0x57, 0x05, 0x5c, 0x59, 0x57, 0x51, 0x51, 0x07, 0x07, 0x0d, 0x4a, 0x02, 0x54, 0x07, ++ 0x5f, 0x27, 0x00, 0x15, 0x40, 0x4d, 0x17, 0x40, 0x40, 0x40, 0x45, 0x45, 0x52, 0x57, 0x54, 0x57, ++ 0x5c, 0x59, 0x52, 0x5f, 0x57, 0x51, 0x57, 0x5f, 0x5f, 0x5c, 0x54, 0x47, 0x42, 0x47, 0x52, 0x57, ++ 0x54, 0x57, 0x5c, 0x59, 0x52, 0x5f, 0x57, 0x51, 0x57, 0x5f, 0x5f, 0x5c, 0x54, 0x47, 0x42, 0x47, ++ 0x0d, 0x4d, 0x47, 0x40, 0x48, 0x40, 0x45, 0x07, 0x45, 0x42, 0x42, 0x57, 0x07, 0x1d, 0x12, 0x4d, ++ 0x12, 0x07, 0x40, 0x1d, 0x12, 0x4d, 0x12, 0x07, 0x40, 0x1d, 0x12, 0x4d, 0x12, 0x07, 0x40, 0x42, ++ 0x07, 0x42, 0x42, 0x00, 0x0d, 0x00, 0x0d, 0x15, 0x17, 0x12, 0x4d, 0x17, 0x12, 0x4d, 0x40, 0x40, ++ 0x40, 0x27, 0x27, 0x15, 0x40, 0x0f, 0x15, 0x1a, 0x1a, 0x22, 0x27, 0x12, 0x07, 0x0d, 0x12, 0x0a, ++ 0x05, 0x37, 0x1d, 0x15, 0x40, 0x15, 0x0a, 0x1a, 0x00, 0x15, 0x03, 0x05, 0x00, 0x15, 0x40, 0x40, ++ 0x40, 0x40, 0x40, 0x40, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x07, 0x01, 0x01, 0x44, 0x59, 0x40, 0x1e, 0x01, 0x41, 0x27, 0x40, 0x44, 0x40, 0x40, 0x40, 0x0f, ++ 0x44, 0x58, 0x56, 0x06, 0x5b, 0x58, 0x55, 0x4f, 0x4f, 0x07, 0x07, 0x0c, 0x49, 0x03, 0x53, 0x07, ++ 0x5e, 0x27, 0x01, 0x14, 0x40, 0x4c, 0x16, 0x40, 0x40, 0x40, 0x44, 0x44, 0x51, 0x56, 0x53, 0x56, ++ 0x5b, 0x58, 0x51, 0x5e, 0x56, 0x50, 0x56, 0x5e, 0x5e, 0x5b, 0x53, 0x46, 0x41, 0x46, 0x51, 0x56, ++ 0x53, 0x56, 0x5b, 0x58, 0x51, 0x5e, 0x56, 0x50, 0x56, 0x5e, 0x5e, 0x5b, 0x53, 0x46, 0x41, 0x46, ++ 0x0e, 0x4c, 0x45, 0x40, 0x48, 0x40, 0x44, 0x07, 0x44, 0x41, 0x41, 0x55, 0x07, 0x1c, 0x11, 0x4c, ++ 0x13, 0x07, 0x40, 0x1c, 0x11, 0x4c, 0x13, 0x07, 0x40, 0x1c, 0x11, 0x4c, 0x13, 0x07, 0x40, 0x43, ++ 0x07, 0x41, 0x41, 0x01, 0x0e, 0x01, 0x0e, 0x14, 0x17, 0x11, 0x4c, 0x17, 0x11, 0x4c, 0x40, 0x40, ++ 0x40, 0x26, 0x26, 0x14, 0x40, 0x0f, 0x14, 0x19, 0x19, 0x23, 0x27, 0x13, 0x07, 0x0e, 0x13, 0x0b, ++ 0x04, 0x36, 0x1c, 0x14, 0x40, 0x14, 0x0b, 0x19, 0x01, 0x14, 0x04, 0x06, 0x01, 0x14, 0x40, 0x40, ++ 0x40, 0x40, 0x40, 0x40, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x07, 0x01, 0x02, 0x44, 0x59, 0x40, 0x1d, 0x01, 0x42, 0x27, 0x40, 0x44, 0x40, 0x40, 0x40, 0x0f, ++ 0x44, 0x56, 0x55, 0x06, 0x5a, 0x56, 0x53, 0x4c, 0x4c, 0x07, 0x07, 0x0c, 0x49, 0x03, 0x52, 0x07, ++ 0x5d, 0x27, 0x02, 0x14, 0x40, 0x4c, 0x15, 0x40, 0x40, 0x40, 0x44, 0x44, 0x51, 0x55, 0x52, 0x55, ++ 0x5a, 0x56, 0x51, 0x5d, 0x55, 0x4e, 0x55, 0x5d, 0x5d, 0x5a, 0x52, 0x45, 0x41, 0x45, 0x51, 0x55, ++ 0x52, 0x55, 0x5a, 0x56, 0x51, 0x5d, 0x55, 0x4e, 0x55, 0x5d, 0x5d, 0x5a, 0x52, 0x45, 0x41, 0x45, ++ 0x0e, 0x4c, 0x43, 0x40, 0x48, 0x40, 0x44, 0x07, 0x44, 0x41, 0x41, 0x53, 0x07, 0x1c, 0x11, 0x4c, ++ 0x13, 0x07, 0x40, 0x1c, 0x11, 0x4c, 0x13, 0x07, 0x40, 0x1c, 0x11, 0x4c, 0x13, 0x07, 0x40, 0x43, ++ 0x07, 0x41, 0x41, 0x02, 0x0e, 0x02, 0x0e, 0x14, 0x17, 0x11, 0x4c, 0x17, 0x11, 0x4c, 0x40, 0x40, ++ 0x40, 0x25, 0x25, 0x14, 0x40, 0x0f, 0x14, 0x19, 0x19, 0x23, 0x27, 0x13, 0x07, 0x0e, 0x13, 0x0b, ++ 0x04, 0x35, 0x1c, 0x14, 0x40, 0x14, 0x0b, 0x19, 0x02, 0x14, 0x05, 0x06, 0x02, 0x14, 0x40, 0x40, ++ 0x40, 0x40, 0x40, 0x40, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x07, 0x00, 0x03, 0x44, 0x58, 0x40, 0x1c, 0x00, 0x43, 0x27, 0x40, 0x44, 0x40, 0x40, 0x40, 0x0f, ++ 0x44, 0x55, 0x54, 0x07, 0x59, 0x55, 0x51, 0x4a, 0x4a, 0x07, 0x07, 0x0c, 0x48, 0x03, 0x51, 0x07, ++ 0x5c, 0x27, 0x03, 0x14, 0x40, 0x4c, 0x14, 0x40, 0x40, 0x40, 0x44, 0x44, 0x50, 0x54, 0x51, 0x54, ++ 0x59, 0x55, 0x50, 0x5c, 0x54, 0x4d, 0x54, 0x5c, 0x5c, 0x59, 0x51, 0x44, 0x40, 0x44, 0x50, 0x54, ++ 0x51, 0x54, 0x59, 0x55, 0x50, 0x5c, 0x54, 0x4d, 0x54, 0x5c, 0x5c, 0x59, 0x51, 0x44, 0x40, 0x44, ++ 0x0f, 0x4c, 0x41, 0x40, 0x48, 0x40, 0x44, 0x07, 0x44, 0x40, 0x40, 0x51, 0x07, 0x1c, 0x10, 0x4c, ++ 0x13, 0x07, 0x40, 0x1c, 0x10, 0x4c, 0x13, 0x07, 0x40, 0x1c, 0x10, 0x4c, 0x13, 0x07, 0x40, 0x43, ++ 0x07, 0x40, 0x40, 0x03, 0x0f, 0x03, 0x0f, 0x14, 0x17, 0x10, 0x4c, 0x17, 0x10, 0x4c, 0x40, 0x40, ++ 0x40, 0x24, 0x24, 0x14, 0x40, 0x0f, 0x14, 0x18, 0x18, 0x23, 0x27, 0x13, 0x07, 0x0f, 0x13, 0x0b, ++ 0x04, 0x34, 0x1c, 0x14, 0x40, 0x14, 0x0b, 0x18, 0x03, 0x14, 0x06, 0x07, 0x03, 0x14, 0x40, 0x40, ++ 0x40, 0x40, 0x40, 0x40, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x07, 0x40, 0x04, 0x43, 0x57, 0x40, 0x1b, 0x40, 0x44, 0x27, 0x40, 0x43, 0x40, 0x40, 0x40, 0x0f, ++ 0x43, 0x53, 0x53, 0x08, 0x57, 0x53, 0x4f, 0x47, 0x47, 0x07, 0x07, 0x0b, 0x47, 0x04, 0x4f, 0x07, ++ 0x5b, 0x27, 0x04, 0x13, 0x40, 0x4b, 0x13, 0x40, 0x40, 0x40, 0x43, 0x43, 0x4f, 0x53, 0x4f, 0x53, ++ 0x57, 0x53, 0x4f, 0x5b, 0x53, 0x4b, 0x53, 0x5b, 0x5b, 0x57, 0x4f, 0x43, 0x00, 0x43, 0x4f, 0x53, ++ 0x4f, 0x53, 0x57, 0x53, 0x4f, 0x5b, 0x53, 0x4b, 0x53, 0x5b, 0x5b, 0x57, 0x4f, 0x43, 0x00, 0x43, ++ 0x10, 0x4b, 0x00, 0x40, 0x48, 0x40, 0x43, 0x07, 0x43, 0x00, 0x00, 0x4f, 0x07, 0x1b, 0x0f, 0x4b, ++ 0x14, 0x07, 0x40, 0x1b, 0x0f, 0x4b, 0x14, 0x07, 0x40, 0x1b, 0x0f, 0x4b, 0x14, 0x07, 0x40, 0x44, ++ 0x07, 0x00, 0x00, 0x04, 0x10, 0x04, 0x10, 0x13, 0x17, 0x0f, 0x4b, 0x17, 0x0f, 0x4b, 0x40, 0x40, ++ 0x40, 0x23, 0x23, 0x13, 0x40, 0x0f, 0x13, 0x17, 0x17, 0x24, 0x27, 0x14, 0x07, 0x10, 0x14, 0x0c, ++ 0x03, 0x33, 0x1b, 0x13, 0x40, 0x13, 0x0c, 0x17, 0x04, 0x13, 0x08, 0x08, 0x04, 0x13, 0x40, 0x40, ++ 0x40, 0x40, 0x40, 0x40, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x07, 0x40, 0x05, 0x43, 0x57, 0x40, 0x1a, 0x40, 0x45, 0x27, 0x40, 0x43, 0x40, 0x40, 0x40, 0x0f, ++ 0x43, 0x52, 0x52, 0x08, 0x56, 0x52, 0x4d, 0x45, 0x45, 0x07, 0x07, 0x0b, 0x47, 0x04, 0x4e, 0x07, ++ 0x5a, 0x27, 0x05, 0x13, 0x40, 0x4b, 0x12, 0x40, 0x40, 0x40, 0x43, 0x43, 0x4f, 0x52, 0x4e, 0x52, ++ 0x56, 0x52, 0x4f, 0x5a, 0x52, 0x4a, 0x52, 0x5a, 0x5a, 0x56, 0x4e, 0x42, 0x00, 0x42, 0x4f, 0x52, ++ 0x4e, 0x52, 0x56, 0x52, 0x4f, 0x5a, 0x52, 0x4a, 0x52, 0x5a, 0x5a, 0x56, 0x4e, 0x42, 0x00, 0x42, ++ 0x10, 0x4b, 0x02, 0x40, 0x48, 0x40, 0x43, 0x07, 0x43, 0x00, 0x00, 0x4d, 0x07, 0x1b, 0x0f, 0x4b, ++ 0x14, 0x07, 0x40, 0x1b, 0x0f, 0x4b, 0x14, 0x07, 0x40, 0x1b, 0x0f, 0x4b, 0x14, 0x07, 0x40, 0x44, ++ 0x07, 0x00, 0x00, 0x05, 0x10, 0x05, 0x10, 0x13, 0x17, 0x0f, 0x4b, 0x17, 0x0f, 0x4b, 0x40, 0x40, ++ 0x40, 0x22, 0x22, 0x13, 0x40, 0x0f, 0x13, 0x17, 0x17, 0x24, 0x27, 0x14, 0x07, 0x10, 0x14, 0x0c, ++ 0x03, 0x32, 0x1b, 0x13, 0x40, 0x13, 0x0c, 0x17, 0x05, 0x13, 0x09, 0x08, 0x05, 0x13, 0x40, 0x40, ++ 0x40, 0x40, 0x40, 0x40, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x07, 0x41, 0x06, 0x43, 0x56, 0x40, 0x19, 0x41, 0x46, 0x27, 0x40, 0x43, 0x40, 0x40, 0x40, 0x0f, ++ 0x43, 0x50, 0x51, 0x09, 0x55, 0x50, 0x4b, 0x42, 0x42, 0x07, 0x07, 0x0b, 0x46, 0x04, 0x4d, 0x07, ++ 0x59, 0x27, 0x06, 0x13, 0x40, 0x4b, 0x11, 0x40, 0x40, 0x40, 0x43, 0x43, 0x4e, 0x51, 0x4d, 0x51, ++ 0x55, 0x50, 0x4e, 0x59, 0x51, 0x48, 0x51, 0x59, 0x59, 0x55, 0x4d, 0x41, 0x01, 0x41, 0x4e, 0x51, ++ 0x4d, 0x51, 0x55, 0x50, 0x4e, 0x59, 0x51, 0x48, 0x51, 0x59, 0x59, 0x55, 0x4d, 0x41, 0x01, 0x41, ++ 0x11, 0x4b, 0x04, 0x40, 0x48, 0x40, 0x43, 0x07, 0x43, 0x01, 0x01, 0x4b, 0x07, 0x1b, 0x0e, 0x4b, ++ 0x14, 0x07, 0x40, 0x1b, 0x0e, 0x4b, 0x14, 0x07, 0x40, 0x1b, 0x0e, 0x4b, 0x14, 0x07, 0x40, 0x44, ++ 0x07, 0x01, 0x01, 0x06, 0x11, 0x06, 0x11, 0x13, 0x17, 0x0e, 0x4b, 0x17, 0x0e, 0x4b, 0x40, 0x40, ++ 0x40, 0x21, 0x21, 0x13, 0x40, 0x0f, 0x13, 0x16, 0x16, 0x24, 0x27, 0x14, 0x07, 0x11, 0x14, 0x0c, ++ 0x03, 0x31, 0x1b, 0x13, 0x40, 0x13, 0x0c, 0x16, 0x06, 0x13, 0x0a, 0x09, 0x06, 0x13, 0x40, 0x40, ++ 0x40, 0x40, 0x40, 0x40, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x07, 0x42, 0x06, 0x43, 0x56, 0x40, 0x18, 0x42, 0x47, 0x27, 0x40, 0x43, 0x40, 0x40, 0x40, 0x0f, ++ 0x43, 0x4f, 0x51, 0x09, 0x54, 0x4f, 0x4a, 0x40, 0x40, 0x07, 0x07, 0x0a, 0x46, 0x04, 0x4c, 0x07, ++ 0x59, 0x27, 0x06, 0x12, 0x40, 0x4b, 0x10, 0x40, 0x40, 0x40, 0x43, 0x43, 0x4e, 0x51, 0x4c, 0x51, ++ 0x54, 0x4f, 0x4e, 0x59, 0x51, 0x47, 0x51, 0x59, 0x59, 0x54, 0x4c, 0x41, 0x01, 0x41, 0x4e, 0x51, ++ 0x4c, 0x51, 0x54, 0x4f, 0x4e, 0x59, 0x51, 0x47, 0x51, 0x59, 0x59, 0x54, 0x4c, 0x41, 0x01, 0x41, ++ 0x11, 0x4b, 0x05, 0x40, 0x48, 0x40, 0x43, 0x07, 0x43, 0x01, 0x01, 0x4a, 0x07, 0x1a, 0x0d, 0x4b, ++ 0x14, 0x07, 0x40, 0x1a, 0x0d, 0x4b, 0x14, 0x07, 0x40, 0x1a, 0x0d, 0x4b, 0x14, 0x07, 0x40, 0x45, ++ 0x07, 0x01, 0x01, 0x06, 0x11, 0x06, 0x11, 0x12, 0x17, 0x0d, 0x4b, 0x17, 0x0d, 0x4b, 0x40, 0x40, ++ 0x40, 0x20, 0x20, 0x12, 0x40, 0x0f, 0x12, 0x15, 0x15, 0x24, 0x27, 0x14, 0x07, 0x11, 0x14, 0x0c, ++ 0x02, 0x30, 0x1a, 0x12, 0x40, 0x12, 0x0c, 0x15, 0x06, 0x12, 0x0b, 0x09, 0x06, 0x12, 0x40, 0x40, ++ 0x40, 0x40, 0x40, 0x40, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x07, 0x42, 0x07, 0x42, 0x55, 0x40, 0x18, 0x42, 0x47, 0x27, 0x40, 0x42, 0x40, 0x40, 0x40, 0x0f, ++ 0x42, 0x4d, 0x50, 0x0a, 0x52, 0x4d, 0x48, 0x02, 0x02, 0x07, 0x07, 0x0a, 0x45, 0x05, 0x4a, 0x07, ++ 0x58, 0x27, 0x07, 0x12, 0x40, 0x4a, 0x10, 0x40, 0x40, 0x40, 0x42, 0x42, 0x4d, 0x50, 0x4a, 0x50, ++ 0x52, 0x4d, 0x4d, 0x58, 0x50, 0x45, 0x50, 0x58, 0x58, 0x52, 0x4a, 0x40, 0x02, 0x40, 0x4d, 0x50, ++ 0x4a, 0x50, 0x52, 0x4d, 0x4d, 0x58, 0x50, 0x45, 0x50, 0x58, 0x58, 0x52, 0x4a, 0x40, 0x02, 0x40, ++ 0x12, 0x4a, 0x07, 0x40, 0x48, 0x40, 0x42, 0x07, 0x42, 0x02, 0x02, 0x48, 0x07, 0x1a, 0x0d, 0x4a, ++ 0x15, 0x07, 0x40, 0x1a, 0x0d, 0x4a, 0x15, 0x07, 0x40, 0x1a, 0x0d, 0x4a, 0x15, 0x07, 0x40, 0x45, ++ 0x07, 0x02, 0x02, 0x07, 0x12, 0x07, 0x12, 0x12, 0x17, 0x0d, 0x4a, 0x17, 0x0d, 0x4a, 0x40, 0x40, ++ 0x40, 0x20, 0x20, 0x12, 0x40, 0x0f, 0x12, 0x15, 0x15, 0x25, 0x27, 0x15, 0x07, 0x12, 0x15, 0x0d, ++ 0x02, 0x30, 0x1a, 0x12, 0x40, 0x12, 0x0d, 0x15, 0x07, 0x12, 0x0d, 0x0a, 0x07, 0x12, 0x40, 0x40, ++ 0x40, 0x40, 0x40, 0x40, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x07, 0x43, 0x08, 0x42, 0x54, 0x40, 0x17, 0x43, 0x48, 0x27, 0x40, 0x42, 0x40, 0x40, 0x40, 0x0f, ++ 0x42, 0x4b, 0x4f, 0x0b, 0x51, 0x4b, 0x46, 0x04, 0x04, 0x07, 0x07, 0x0a, 0x44, 0x05, 0x49, 0x07, ++ 0x57, 0x27, 0x08, 0x12, 0x40, 0x4a, 0x0f, 0x40, 0x40, 0x40, 0x42, 0x42, 0x4c, 0x4f, 0x49, 0x4f, ++ 0x51, 0x4b, 0x4c, 0x57, 0x4f, 0x43, 0x4f, 0x57, 0x57, 0x51, 0x49, 0x00, 0x03, 0x00, 0x4c, 0x4f, ++ 0x49, 0x4f, 0x51, 0x4b, 0x4c, 0x57, 0x4f, 0x43, 0x4f, 0x57, 0x57, 0x51, 0x49, 0x00, 0x03, 0x00, ++ 0x13, 0x4a, 0x09, 0x40, 0x48, 0x40, 0x42, 0x07, 0x42, 0x03, 0x03, 0x46, 0x07, 0x1a, 0x0c, 0x4a, ++ 0x15, 0x07, 0x40, 0x1a, 0x0c, 0x4a, 0x15, 0x07, 0x40, 0x1a, 0x0c, 0x4a, 0x15, 0x07, 0x40, 0x45, ++ 0x07, 0x03, 0x03, 0x08, 0x13, 0x08, 0x13, 0x12, 0x17, 0x0c, 0x4a, 0x17, 0x0c, 0x4a, 0x40, 0x40, ++ 0x40, 0x1f, 0x1f, 0x12, 0x40, 0x0f, 0x12, 0x14, 0x14, 0x25, 0x27, 0x15, 0x07, 0x13, 0x15, 0x0d, ++ 0x02, 0x2f, 0x1a, 0x12, 0x40, 0x12, 0x0d, 0x14, 0x08, 0x12, 0x0e, 0x0b, 0x08, 0x12, 0x40, 0x40, ++ 0x40, 0x40, 0x40, 0x40, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x07, 0x43, 0x09, 0x42, 0x54, 0x40, 0x16, 0x43, 0x49, 0x27, 0x40, 0x42, 0x40, 0x40, 0x40, 0x0f, ++ 0x42, 0x4a, 0x4e, 0x0b, 0x50, 0x4a, 0x44, 0x07, 0x07, 0x07, 0x07, 0x0a, 0x44, 0x05, 0x48, 0x07, ++ 0x56, 0x27, 0x09, 0x12, 0x40, 0x4a, 0x0e, 0x40, 0x40, 0x40, 0x42, 0x42, 0x4c, 0x4e, 0x48, 0x4e, ++ 0x50, 0x4a, 0x4c, 0x56, 0x4e, 0x42, 0x4e, 0x56, 0x56, 0x50, 0x48, 0x01, 0x03, 0x01, 0x4c, 0x4e, ++ 0x48, 0x4e, 0x50, 0x4a, 0x4c, 0x56, 0x4e, 0x42, 0x4e, 0x56, 0x56, 0x50, 0x48, 0x01, 0x03, 0x01, ++ 0x13, 0x4a, 0x0b, 0x40, 0x48, 0x40, 0x42, 0x07, 0x42, 0x03, 0x03, 0x44, 0x07, 0x1a, 0x0c, 0x4a, ++ 0x15, 0x07, 0x40, 0x1a, 0x0c, 0x4a, 0x15, 0x07, 0x40, 0x1a, 0x0c, 0x4a, 0x15, 0x07, 0x40, 0x45, ++ 0x07, 0x03, 0x03, 0x09, 0x13, 0x09, 0x13, 0x12, 0x17, 0x0c, 0x4a, 0x17, 0x0c, 0x4a, 0x40, 0x40, ++ 0x40, 0x1e, 0x1e, 0x12, 0x40, 0x0f, 0x12, 0x14, 0x14, 0x25, 0x27, 0x15, 0x07, 0x13, 0x15, 0x0d, ++ 0x02, 0x2e, 0x1a, 0x12, 0x40, 0x12, 0x0d, 0x14, 0x09, 0x12, 0x0f, 0x0b, 0x09, 0x12, 0x40, 0x40, ++ 0x40, 0x40, 0x40, 0x40, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x07, 0x44, 0x0a, 0x41, 0x53, 0x40, 0x15, 0x44, 0x4a, 0x27, 0x40, 0x41, 0x40, 0x40, 0x40, 0x0f, ++ 0x41, 0x48, 0x4d, 0x0c, 0x4f, 0x48, 0x42, 0x09, 0x09, 0x07, 0x07, 0x09, 0x43, 0x06, 0x47, 0x07, ++ 0x55, 0x27, 0x0a, 0x11, 0x40, 0x49, 0x0d, 0x40, 0x40, 0x40, 0x41, 0x41, 0x4b, 0x4d, 0x47, 0x4d, ++ 0x4f, 0x48, 0x4b, 0x55, 0x4d, 0x40, 0x4d, 0x55, 0x55, 0x4f, 0x47, 0x02, 0x04, 0x02, 0x4b, 0x4d, ++ 0x47, 0x4d, 0x4f, 0x48, 0x4b, 0x55, 0x4d, 0x40, 0x4d, 0x55, 0x55, 0x4f, 0x47, 0x02, 0x04, 0x02, ++ 0x14, 0x49, 0x0d, 0x40, 0x48, 0x40, 0x41, 0x07, 0x41, 0x04, 0x04, 0x42, 0x07, 0x19, 0x0b, 0x49, ++ 0x16, 0x07, 0x40, 0x19, 0x0b, 0x49, 0x16, 0x07, 0x40, 0x19, 0x0b, 0x49, 0x16, 0x07, 0x40, 0x46, ++ 0x07, 0x04, 0x04, 0x0a, 0x14, 0x0a, 0x14, 0x11, 0x17, 0x0b, 0x49, 0x17, 0x0b, 0x49, 0x40, 0x40, ++ 0x40, 0x1d, 0x1d, 0x11, 0x40, 0x0f, 0x11, 0x13, 0x13, 0x26, 0x27, 0x16, 0x07, 0x14, 0x16, 0x0e, ++ 0x01, 0x2d, 0x19, 0x11, 0x40, 0x11, 0x0e, 0x13, 0x0a, 0x11, 0x10, 0x0c, 0x0a, 0x11, 0x40, 0x40, ++ 0x40, 0x40, 0x40, 0x40, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x07, 0x45, 0x0b, 0x41, 0x52, 0x40, 0x14, 0x45, 0x4b, 0x27, 0x40, 0x41, 0x40, 0x40, 0x40, 0x0f, ++ 0x41, 0x47, 0x4c, 0x0d, 0x4d, 0x47, 0x40, 0x0c, 0x0c, 0x07, 0x07, 0x09, 0x42, 0x06, 0x45, 0x07, ++ 0x54, 0x27, 0x0b, 0x11, 0x40, 0x49, 0x0c, 0x40, 0x40, 0x40, 0x41, 0x41, 0x4a, 0x4c, 0x45, 0x4c, ++ 0x4d, 0x47, 0x4a, 0x54, 0x4c, 0x00, 0x4c, 0x54, 0x54, 0x4d, 0x45, 0x03, 0x05, 0x03, 0x4a, 0x4c, ++ 0x45, 0x4c, 0x4d, 0x47, 0x4a, 0x54, 0x4c, 0x00, 0x4c, 0x54, 0x54, 0x4d, 0x45, 0x03, 0x05, 0x03, ++ 0x15, 0x49, 0x0f, 0x40, 0x48, 0x40, 0x41, 0x07, 0x41, 0x05, 0x05, 0x40, 0x07, 0x19, 0x0a, 0x49, ++ 0x16, 0x07, 0x40, 0x19, 0x0a, 0x49, 0x16, 0x07, 0x40, 0x19, 0x0a, 0x49, 0x16, 0x07, 0x40, 0x46, ++ 0x07, 0x05, 0x05, 0x0b, 0x15, 0x0b, 0x15, 0x11, 0x17, 0x0a, 0x49, 0x17, 0x0a, 0x49, 0x40, 0x40, ++ 0x40, 0x1c, 0x1c, 0x11, 0x40, 0x0f, 0x11, 0x12, 0x12, 0x26, 0x27, 0x16, 0x07, 0x15, 0x16, 0x0e, ++ 0x01, 0x2c, 0x19, 0x11, 0x40, 0x11, 0x0e, 0x12, 0x0b, 0x11, 0x12, 0x0d, 0x0b, 0x11, 0x40, 0x40, ++ 0x40, 0x40, 0x40, 0x40, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x07, 0x45, 0x0c, 0x41, 0x52, 0x40, 0x13, 0x45, 0x4c, 0x27, 0x40, 0x41, 0x40, 0x40, 0x40, 0x0f, ++ 0x41, 0x45, 0x4b, 0x0d, 0x4c, 0x45, 0x01, 0x0e, 0x0e, 0x07, 0x07, 0x09, 0x42, 0x06, 0x44, 0x07, ++ 0x53, 0x27, 0x0c, 0x11, 0x40, 0x49, 0x0b, 0x40, 0x40, 0x40, 0x41, 0x41, 0x4a, 0x4b, 0x44, 0x4b, ++ 0x4c, 0x45, 0x4a, 0x53, 0x4b, 0x02, 0x4b, 0x53, 0x53, 0x4c, 0x44, 0x04, 0x05, 0x04, 0x4a, 0x4b, ++ 0x44, 0x4b, 0x4c, 0x45, 0x4a, 0x53, 0x4b, 0x02, 0x4b, 0x53, 0x53, 0x4c, 0x44, 0x04, 0x05, 0x04, ++ 0x15, 0x49, 0x11, 0x40, 0x48, 0x40, 0x41, 0x07, 0x41, 0x05, 0x05, 0x01, 0x07, 0x19, 0x0a, 0x49, ++ 0x16, 0x07, 0x40, 0x19, 0x0a, 0x49, 0x16, 0x07, 0x40, 0x19, 0x0a, 0x49, 0x16, 0x07, 0x40, 0x46, ++ 0x07, 0x05, 0x05, 0x0c, 0x15, 0x0c, 0x15, 0x11, 0x17, 0x0a, 0x49, 0x17, 0x0a, 0x49, 0x40, 0x40, ++ 0x40, 0x1b, 0x1b, 0x11, 0x40, 0x0f, 0x11, 0x12, 0x12, 0x26, 0x27, 0x16, 0x07, 0x15, 0x16, 0x0e, ++ 0x01, 0x2b, 0x19, 0x11, 0x40, 0x11, 0x0e, 0x12, 0x0c, 0x11, 0x13, 0x0d, 0x0c, 0x11, 0x40, 0x40, ++ 0x40, 0x40, 0x40, 0x40, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x07, 0x46, 0x0d, 0x40, 0x51, 0x40, 0x12, 0x46, 0x4d, 0x27, 0x40, 0x40, 0x40, 0x40, 0x40, 0x0f, ++ 0x40, 0x44, 0x4a, 0x0e, 0x4b, 0x44, 0x03, 0x11, 0x11, 0x07, 0x07, 0x08, 0x41, 0x07, 0x43, 0x07, ++ 0x52, 0x27, 0x0d, 0x10, 0x40, 0x48, 0x0a, 0x40, 0x40, 0x40, 0x40, 0x40, 0x49, 0x4a, 0x43, 0x4a, ++ 0x4b, 0x44, 0x49, 0x52, 0x4a, 0x03, 0x4a, 0x52, 0x52, 0x4b, 0x43, 0x05, 0x06, 0x05, 0x49, 0x4a, ++ 0x43, 0x4a, 0x4b, 0x44, 0x49, 0x52, 0x4a, 0x03, 0x4a, 0x52, 0x52, 0x4b, 0x43, 0x05, 0x06, 0x05, ++ 0x16, 0x48, 0x13, 0x40, 0x48, 0x40, 0x40, 0x07, 0x40, 0x06, 0x06, 0x03, 0x07, 0x18, 0x09, 0x48, ++ 0x17, 0x07, 0x40, 0x18, 0x09, 0x48, 0x17, 0x07, 0x40, 0x18, 0x09, 0x48, 0x17, 0x07, 0x40, 0x47, ++ 0x07, 0x06, 0x06, 0x0d, 0x16, 0x0d, 0x16, 0x10, 0x17, 0x09, 0x48, 0x17, 0x09, 0x48, 0x40, 0x40, ++ 0x40, 0x1a, 0x1a, 0x10, 0x40, 0x0f, 0x10, 0x11, 0x11, 0x27, 0x27, 0x17, 0x07, 0x16, 0x17, 0x0f, ++ 0x00, 0x2a, 0x18, 0x10, 0x40, 0x10, 0x0f, 0x11, 0x0d, 0x10, 0x14, 0x0e, 0x0d, 0x10, 0x40, 0x40, ++ 0x40, 0x40, 0x40, 0x40, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x07, 0x47, 0x0e, 0x40, 0x51, 0x40, 0x11, 0x47, 0x4e, 0x27, 0x40, 0x40, 0x40, 0x40, 0x40, 0x0f, ++ 0x40, 0x42, 0x49, 0x0e, 0x4a, 0x42, 0x04, 0x13, 0x13, 0x07, 0x07, 0x08, 0x41, 0x07, 0x42, 0x07, ++ 0x51, 0x27, 0x0e, 0x10, 0x40, 0x48, 0x09, 0x40, 0x40, 0x40, 0x40, 0x40, 0x49, 0x49, 0x42, 0x49, ++ 0x4a, 0x42, 0x49, 0x51, 0x49, 0x05, 0x49, 0x51, 0x51, 0x4a, 0x42, 0x06, 0x06, 0x06, 0x49, 0x49, ++ 0x42, 0x49, 0x4a, 0x42, 0x49, 0x51, 0x49, 0x05, 0x49, 0x51, 0x51, 0x4a, 0x42, 0x06, 0x06, 0x06, ++ 0x16, 0x48, 0x14, 0x40, 0x48, 0x40, 0x40, 0x07, 0x40, 0x06, 0x06, 0x04, 0x07, 0x18, 0x08, 0x48, ++ 0x17, 0x07, 0x40, 0x18, 0x08, 0x48, 0x17, 0x07, 0x40, 0x18, 0x08, 0x48, 0x17, 0x07, 0x40, 0x47, ++ 0x07, 0x06, 0x06, 0x0e, 0x16, 0x0e, 0x16, 0x10, 0x17, 0x08, 0x48, 0x17, 0x08, 0x48, 0x40, 0x40, ++ 0x40, 0x19, 0x19, 0x10, 0x40, 0x0f, 0x10, 0x10, 0x10, 0x27, 0x27, 0x17, 0x07, 0x16, 0x17, 0x0f, ++ 0x00, 0x29, 0x18, 0x10, 0x40, 0x10, 0x0f, 0x10, 0x0e, 0x10, 0x15, 0x0e, 0x0e, 0x10, 0x40, 0x40, ++ 0x40, 0x40, 0x40, 0x40, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x07, 0x47, 0x0f, 0x40, 0x50, 0x40, 0x10, 0x47, 0x4f, 0x27, 0x40, 0x40, 0x40, 0x40, 0x40, 0x0f, ++ 0x40, 0x40, 0x48, 0x0f, 0x48, 0x40, 0x06, 0x16, 0x16, 0x07, 0x07, 0x08, 0x40, 0x07, 0x40, 0x07, ++ 0x50, 0x27, 0x0f, 0x10, 0x40, 0x48, 0x08, 0x40, 0x40, 0x40, 0x40, 0x40, 0x48, 0x48, 0x40, 0x48, ++ 0x48, 0x40, 0x48, 0x50, 0x48, 0x07, 0x48, 0x50, 0x50, 0x48, 0x40, 0x07, 0x07, 0x07, 0x48, 0x48, ++ 0x40, 0x48, 0x48, 0x40, 0x48, 0x50, 0x48, 0x07, 0x48, 0x50, 0x50, 0x48, 0x40, 0x07, 0x07, 0x07, ++ 0x17, 0x48, 0x16, 0x40, 0x48, 0x40, 0x40, 0x07, 0x40, 0x07, 0x07, 0x06, 0x07, 0x18, 0x08, 0x48, ++ 0x17, 0x07, 0x40, 0x18, 0x08, 0x48, 0x17, 0x07, 0x40, 0x18, 0x08, 0x48, 0x17, 0x07, 0x40, 0x47, ++ 0x07, 0x07, 0x07, 0x0f, 0x17, 0x0f, 0x17, 0x10, 0x17, 0x08, 0x48, 0x17, 0x08, 0x48, 0x40, 0x40, ++ 0x40, 0x18, 0x18, 0x10, 0x40, 0x0f, 0x10, 0x10, 0x10, 0x27, 0x27, 0x17, 0x07, 0x17, 0x17, 0x0f, ++ 0x00, 0x28, 0x18, 0x10, 0x40, 0x10, 0x0f, 0x10, 0x0f, 0x10, 0x17, 0x0f, 0x0f, 0x10, 0x40, 0x40, ++ 0x40, 0x40, 0x40, 0x40, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x07, 0x48, 0x10, 0x00, 0x4f, 0x40, 0x0f, 0x48, 0x50, 0x27, 0x40, 0x00, 0x40, 0x40, 0x40, 0x0f, ++ 0x00, 0x00, 0x47, 0x10, 0x47, 0x00, 0x08, 0x18, 0x18, 0x07, 0x07, 0x07, 0x00, 0x08, 0x00, 0x07, ++ 0x4f, 0x27, 0x10, 0x0f, 0x40, 0x47, 0x07, 0x40, 0x40, 0x40, 0x00, 0x00, 0x47, 0x47, 0x00, 0x47, ++ 0x47, 0x00, 0x47, 0x4f, 0x47, 0x08, 0x47, 0x4f, 0x4f, 0x47, 0x00, 0x08, 0x08, 0x08, 0x47, 0x47, ++ 0x00, 0x47, 0x47, 0x00, 0x47, 0x4f, 0x47, 0x08, 0x47, 0x4f, 0x4f, 0x47, 0x00, 0x08, 0x08, 0x08, ++ 0x18, 0x47, 0x18, 0x40, 0x48, 0x40, 0x00, 0x07, 0x00, 0x08, 0x08, 0x08, 0x07, 0x17, 0x07, 0x47, ++ 0x18, 0x07, 0x40, 0x17, 0x07, 0x47, 0x18, 0x07, 0x40, 0x17, 0x07, 0x47, 0x18, 0x07, 0x40, 0x48, ++ 0x07, 0x08, 0x08, 0x10, 0x18, 0x10, 0x18, 0x0f, 0x17, 0x07, 0x47, 0x17, 0x07, 0x47, 0x40, 0x40, ++ 0x40, 0x17, 0x17, 0x0f, 0x40, 0x0f, 0x0f, 0x0f, 0x0f, 0x28, 0x27, 0x18, 0x07, 0x18, 0x18, 0x10, ++ 0x40, 0x27, 0x17, 0x0f, 0x40, 0x0f, 0x10, 0x0f, 0x10, 0x0f, 0x18, 0x10, 0x10, 0x0f, 0x40, 0x40, ++ 0x40, 0x40, 0x40, 0x40, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x07, 0x48, 0x11, 0x00, 0x4f, 0x40, 0x0e, 0x48, 0x51, 0x27, 0x40, 0x00, 0x40, 0x40, 0x40, 0x0f, ++ 0x00, 0x02, 0x46, 0x10, 0x46, 0x02, 0x0a, 0x1b, 0x1b, 0x07, 0x07, 0x07, 0x00, 0x08, 0x01, 0x07, ++ 0x4e, 0x27, 0x11, 0x0f, 0x40, 0x47, 0x06, 0x40, 0x40, 0x40, 0x00, 0x00, 0x47, 0x46, 0x01, 0x46, ++ 0x46, 0x02, 0x47, 0x4e, 0x46, 0x0a, 0x46, 0x4e, 0x4e, 0x46, 0x01, 0x09, 0x08, 0x09, 0x47, 0x46, ++ 0x01, 0x46, 0x46, 0x02, 0x47, 0x4e, 0x46, 0x0a, 0x46, 0x4e, 0x4e, 0x46, 0x01, 0x09, 0x08, 0x09, ++ 0x18, 0x47, 0x1a, 0x40, 0x48, 0x40, 0x00, 0x07, 0x00, 0x08, 0x08, 0x0a, 0x07, 0x17, 0x07, 0x47, ++ 0x18, 0x07, 0x40, 0x17, 0x07, 0x47, 0x18, 0x07, 0x40, 0x17, 0x07, 0x47, 0x18, 0x07, 0x40, 0x48, ++ 0x07, 0x08, 0x08, 0x11, 0x18, 0x11, 0x18, 0x0f, 0x17, 0x07, 0x47, 0x17, 0x07, 0x47, 0x40, 0x40, ++ 0x40, 0x16, 0x16, 0x0f, 0x40, 0x0f, 0x0f, 0x0f, 0x0f, 0x28, 0x27, 0x18, 0x07, 0x18, 0x18, 0x10, ++ 0x40, 0x26, 0x17, 0x0f, 0x40, 0x0f, 0x10, 0x0f, 0x11, 0x0f, 0x19, 0x10, 0x11, 0x0f, 0x40, 0x40, ++ 0x40, 0x40, 0x40, 0x40, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x07, 0x49, 0x12, 0x00, 0x4e, 0x40, 0x0d, 0x49, 0x52, 0x27, 0x40, 0x00, 0x40, 0x40, 0x40, 0x0f, ++ 0x00, 0x03, 0x45, 0x11, 0x45, 0x03, 0x0c, 0x1d, 0x1d, 0x07, 0x07, 0x07, 0x01, 0x08, 0x02, 0x07, ++ 0x4d, 0x27, 0x12, 0x0f, 0x40, 0x47, 0x05, 0x40, 0x40, 0x40, 0x00, 0x00, 0x46, 0x45, 0x02, 0x45, ++ 0x45, 0x03, 0x46, 0x4d, 0x45, 0x0b, 0x45, 0x4d, 0x4d, 0x45, 0x02, 0x0a, 0x09, 0x0a, 0x46, 0x45, ++ 0x02, 0x45, 0x45, 0x03, 0x46, 0x4d, 0x45, 0x0b, 0x45, 0x4d, 0x4d, 0x45, 0x02, 0x0a, 0x09, 0x0a, ++ 0x19, 0x47, 0x1c, 0x40, 0x48, 0x40, 0x00, 0x07, 0x00, 0x09, 0x09, 0x0c, 0x07, 0x17, 0x06, 0x47, ++ 0x18, 0x07, 0x40, 0x17, 0x06, 0x47, 0x18, 0x07, 0x40, 0x17, 0x06, 0x47, 0x18, 0x07, 0x40, 0x48, ++ 0x07, 0x09, 0x09, 0x12, 0x19, 0x12, 0x19, 0x0f, 0x17, 0x06, 0x47, 0x17, 0x06, 0x47, 0x40, 0x40, ++ 0x40, 0x15, 0x15, 0x0f, 0x40, 0x0f, 0x0f, 0x0e, 0x0e, 0x28, 0x27, 0x18, 0x07, 0x19, 0x18, 0x10, ++ 0x40, 0x25, 0x17, 0x0f, 0x40, 0x0f, 0x10, 0x0e, 0x12, 0x0f, 0x1a, 0x11, 0x12, 0x0f, 0x40, 0x40, ++ 0x40, 0x40, 0x40, 0x40, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x07, 0x4a, 0x13, 0x01, 0x4d, 0x40, 0x0c, 0x4a, 0x53, 0x27, 0x40, 0x01, 0x40, 0x40, 0x40, 0x0f, ++ 0x01, 0x05, 0x44, 0x12, 0x43, 0x05, 0x0e, 0x20, 0x20, 0x07, 0x07, 0x06, 0x02, 0x09, 0x04, 0x07, ++ 0x4c, 0x27, 0x13, 0x0e, 0x40, 0x46, 0x04, 0x40, 0x40, 0x40, 0x01, 0x01, 0x45, 0x44, 0x04, 0x44, ++ 0x43, 0x05, 0x45, 0x4c, 0x44, 0x0d, 0x44, 0x4c, 0x4c, 0x43, 0x04, 0x0b, 0x0a, 0x0b, 0x45, 0x44, ++ 0x04, 0x44, 0x43, 0x05, 0x45, 0x4c, 0x44, 0x0d, 0x44, 0x4c, 0x4c, 0x43, 0x04, 0x0b, 0x0a, 0x0b, ++ 0x1a, 0x46, 0x1e, 0x40, 0x48, 0x40, 0x01, 0x07, 0x01, 0x0a, 0x0a, 0x0e, 0x07, 0x16, 0x05, 0x46, ++ 0x19, 0x07, 0x40, 0x16, 0x05, 0x46, 0x19, 0x07, 0x40, 0x16, 0x05, 0x46, 0x19, 0x07, 0x40, 0x49, ++ 0x07, 0x0a, 0x0a, 0x13, 0x1a, 0x13, 0x1a, 0x0e, 0x17, 0x05, 0x46, 0x17, 0x05, 0x46, 0x40, 0x40, ++ 0x40, 0x14, 0x14, 0x0e, 0x40, 0x0f, 0x0e, 0x0d, 0x0d, 0x29, 0x27, 0x19, 0x07, 0x1a, 0x19, 0x11, ++ 0x41, 0x24, 0x16, 0x0e, 0x40, 0x0e, 0x11, 0x0d, 0x13, 0x0e, 0x1c, 0x12, 0x13, 0x0e, 0x40, 0x40, ++ 0x40, 0x40, 0x40, 0x40, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x07, 0x4a, 0x14, 0x01, 0x4d, 0x40, 0x0b, 0x4a, 0x54, 0x27, 0x40, 0x01, 0x40, 0x40, 0x40, 0x0f, ++ 0x01, 0x06, 0x43, 0x12, 0x42, 0x06, 0x10, 0x22, 0x22, 0x07, 0x07, 0x06, 0x02, 0x09, 0x05, 0x07, ++ 0x4b, 0x27, 0x14, 0x0e, 0x40, 0x46, 0x03, 0x40, 0x40, 0x40, 0x01, 0x01, 0x45, 0x43, 0x05, 0x43, ++ 0x42, 0x06, 0x45, 0x4b, 0x43, 0x0e, 0x43, 0x4b, 0x4b, 0x42, 0x05, 0x0c, 0x0a, 0x0c, 0x45, 0x43, ++ 0x05, 0x43, 0x42, 0x06, 0x45, 0x4b, 0x43, 0x0e, 0x43, 0x4b, 0x4b, 0x42, 0x05, 0x0c, 0x0a, 0x0c, ++ 0x1a, 0x46, 0x20, 0x40, 0x48, 0x40, 0x01, 0x07, 0x01, 0x0a, 0x0a, 0x10, 0x07, 0x16, 0x05, 0x46, ++ 0x19, 0x07, 0x40, 0x16, 0x05, 0x46, 0x19, 0x07, 0x40, 0x16, 0x05, 0x46, 0x19, 0x07, 0x40, 0x49, ++ 0x07, 0x0a, 0x0a, 0x14, 0x1a, 0x14, 0x1a, 0x0e, 0x17, 0x05, 0x46, 0x17, 0x05, 0x46, 0x40, 0x40, ++ 0x40, 0x13, 0x13, 0x0e, 0x40, 0x0f, 0x0e, 0x0d, 0x0d, 0x29, 0x27, 0x19, 0x07, 0x1a, 0x19, 0x11, ++ 0x41, 0x23, 0x16, 0x0e, 0x40, 0x0e, 0x11, 0x0d, 0x14, 0x0e, 0x1d, 0x12, 0x14, 0x0e, 0x40, 0x40, ++ 0x40, 0x40, 0x40, 0x40, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x07, 0x4b, 0x15, 0x01, 0x4c, 0x40, 0x0a, 0x4b, 0x55, 0x27, 0x40, 0x01, 0x40, 0x40, 0x40, 0x0f, ++ 0x01, 0x08, 0x42, 0x13, 0x41, 0x08, 0x12, 0x25, 0x25, 0x07, 0x07, 0x06, 0x03, 0x09, 0x06, 0x07, ++ 0x4a, 0x27, 0x15, 0x0e, 0x40, 0x46, 0x02, 0x40, 0x40, 0x40, 0x01, 0x01, 0x44, 0x42, 0x06, 0x42, ++ 0x41, 0x08, 0x44, 0x4a, 0x42, 0x10, 0x42, 0x4a, 0x4a, 0x41, 0x06, 0x0d, 0x0b, 0x0d, 0x44, 0x42, ++ 0x06, 0x42, 0x41, 0x08, 0x44, 0x4a, 0x42, 0x10, 0x42, 0x4a, 0x4a, 0x41, 0x06, 0x0d, 0x0b, 0x0d, ++ 0x1b, 0x46, 0x22, 0x40, 0x48, 0x40, 0x01, 0x07, 0x01, 0x0b, 0x0b, 0x12, 0x07, 0x16, 0x04, 0x46, ++ 0x19, 0x07, 0x40, 0x16, 0x04, 0x46, 0x19, 0x07, 0x40, 0x16, 0x04, 0x46, 0x19, 0x07, 0x40, 0x49, ++ 0x07, 0x0b, 0x0b, 0x15, 0x1b, 0x15, 0x1b, 0x0e, 0x17, 0x04, 0x46, 0x17, 0x04, 0x46, 0x40, 0x40, ++ 0x40, 0x12, 0x12, 0x0e, 0x40, 0x0f, 0x0e, 0x0c, 0x0c, 0x29, 0x27, 0x19, 0x07, 0x1b, 0x19, 0x11, ++ 0x41, 0x22, 0x16, 0x0e, 0x40, 0x0e, 0x11, 0x0c, 0x15, 0x0e, 0x1e, 0x13, 0x15, 0x0e, 0x40, 0x40, ++ 0x40, 0x40, 0x40, 0x40, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x07, 0x4c, 0x15, 0x01, 0x4c, 0x40, 0x09, 0x4c, 0x56, 0x27, 0x40, 0x01, 0x40, 0x40, 0x40, 0x0f, ++ 0x01, 0x09, 0x42, 0x13, 0x40, 0x09, 0x13, 0x27, 0x27, 0x07, 0x07, 0x05, 0x03, 0x09, 0x07, 0x07, ++ 0x4a, 0x27, 0x15, 0x0d, 0x40, 0x46, 0x01, 0x40, 0x40, 0x40, 0x01, 0x01, 0x44, 0x42, 0x07, 0x42, ++ 0x40, 0x09, 0x44, 0x4a, 0x42, 0x11, 0x42, 0x4a, 0x4a, 0x40, 0x07, 0x0d, 0x0b, 0x0d, 0x44, 0x42, ++ 0x07, 0x42, 0x40, 0x09, 0x44, 0x4a, 0x42, 0x11, 0x42, 0x4a, 0x4a, 0x40, 0x07, 0x0d, 0x0b, 0x0d, ++ 0x1b, 0x46, 0x23, 0x40, 0x48, 0x40, 0x01, 0x07, 0x01, 0x0b, 0x0b, 0x13, 0x07, 0x15, 0x03, 0x46, ++ 0x19, 0x07, 0x40, 0x15, 0x03, 0x46, 0x19, 0x07, 0x40, 0x15, 0x03, 0x46, 0x19, 0x07, 0x40, 0x4a, ++ 0x07, 0x0b, 0x0b, 0x15, 0x1b, 0x15, 0x1b, 0x0d, 0x17, 0x03, 0x46, 0x17, 0x03, 0x46, 0x40, 0x40, ++ 0x40, 0x11, 0x11, 0x0d, 0x40, 0x0f, 0x0d, 0x0b, 0x0b, 0x29, 0x27, 0x19, 0x07, 0x1b, 0x19, 0x11, ++ 0x42, 0x21, 0x15, 0x0d, 0x40, 0x0d, 0x11, 0x0b, 0x15, 0x0d, 0x1f, 0x13, 0x15, 0x0d, 0x40, 0x40, ++ 0x40, 0x40, 0x40, 0x40, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x07, 0x4c, 0x16, 0x02, 0x4b, 0x40, 0x09, 0x4c, 0x56, 0x27, 0x40, 0x02, 0x40, 0x40, 0x40, 0x0f, ++ 0x02, 0x0b, 0x41, 0x14, 0x01, 0x0b, 0x15, 0x2a, 0x2a, 0x07, 0x07, 0x05, 0x04, 0x0a, 0x09, 0x07, ++ 0x49, 0x27, 0x16, 0x0d, 0x40, 0x45, 0x01, 0x40, 0x40, 0x40, 0x02, 0x02, 0x43, 0x41, 0x09, 0x41, ++ 0x01, 0x0b, 0x43, 0x49, 0x41, 0x13, 0x41, 0x49, 0x49, 0x01, 0x09, 0x0e, 0x0c, 0x0e, 0x43, 0x41, ++ 0x09, 0x41, 0x01, 0x0b, 0x43, 0x49, 0x41, 0x13, 0x41, 0x49, 0x49, 0x01, 0x09, 0x0e, 0x0c, 0x0e, ++ 0x1c, 0x45, 0x25, 0x40, 0x48, 0x40, 0x02, 0x07, 0x02, 0x0c, 0x0c, 0x15, 0x07, 0x15, 0x03, 0x45, ++ 0x1a, 0x07, 0x40, 0x15, 0x03, 0x45, 0x1a, 0x07, 0x40, 0x15, 0x03, 0x45, 0x1a, 0x07, 0x40, 0x4a, ++ 0x07, 0x0c, 0x0c, 0x16, 0x1c, 0x16, 0x1c, 0x0d, 0x17, 0x03, 0x45, 0x17, 0x03, 0x45, 0x40, 0x40, ++ 0x40, 0x11, 0x11, 0x0d, 0x40, 0x0f, 0x0d, 0x0b, 0x0b, 0x2a, 0x27, 0x1a, 0x07, 0x1c, 0x1a, 0x12, ++ 0x42, 0x21, 0x15, 0x0d, 0x40, 0x0d, 0x12, 0x0b, 0x16, 0x0d, 0x21, 0x14, 0x16, 0x0d, 0x40, 0x40, ++ 0x40, 0x40, 0x40, 0x40, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x07, 0x4d, 0x17, 0x02, 0x4a, 0x40, 0x08, 0x4d, 0x57, 0x27, 0x40, 0x02, 0x40, 0x40, 0x40, 0x0f, ++ 0x02, 0x0d, 0x40, 0x15, 0x02, 0x0d, 0x17, 0x2c, 0x2c, 0x07, 0x07, 0x05, 0x05, 0x0a, 0x0a, 0x07, ++ 0x48, 0x27, 0x17, 0x0d, 0x40, 0x45, 0x00, 0x40, 0x40, 0x40, 0x02, 0x02, 0x42, 0x40, 0x0a, 0x40, ++ 0x02, 0x0d, 0x42, 0x48, 0x40, 0x15, 0x40, 0x48, 0x48, 0x02, 0x0a, 0x0f, 0x0d, 0x0f, 0x42, 0x40, ++ 0x0a, 0x40, 0x02, 0x0d, 0x42, 0x48, 0x40, 0x15, 0x40, 0x48, 0x48, 0x02, 0x0a, 0x0f, 0x0d, 0x0f, ++ 0x1d, 0x45, 0x27, 0x40, 0x48, 0x40, 0x02, 0x07, 0x02, 0x0d, 0x0d, 0x17, 0x07, 0x15, 0x02, 0x45, ++ 0x1a, 0x07, 0x40, 0x15, 0x02, 0x45, 0x1a, 0x07, 0x40, 0x15, 0x02, 0x45, 0x1a, 0x07, 0x40, 0x4a, ++ 0x07, 0x0d, 0x0d, 0x17, 0x1d, 0x17, 0x1d, 0x0d, 0x17, 0x02, 0x45, 0x17, 0x02, 0x45, 0x40, 0x40, ++ 0x40, 0x10, 0x10, 0x0d, 0x40, 0x0f, 0x0d, 0x0a, 0x0a, 0x2a, 0x27, 0x1a, 0x07, 0x1d, 0x1a, 0x12, ++ 0x42, 0x20, 0x15, 0x0d, 0x40, 0x0d, 0x12, 0x0a, 0x17, 0x0d, 0x22, 0x15, 0x17, 0x0d, 0x40, 0x40, ++ 0x40, 0x40, 0x40, 0x40, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x07, 0x4d, 0x18, 0x02, 0x4a, 0x40, 0x07, 0x4d, 0x58, 0x27, 0x40, 0x02, 0x40, 0x40, 0x40, 0x0f, ++ 0x02, 0x0e, 0x00, 0x15, 0x03, 0x0e, 0x19, 0x2f, 0x2f, 0x07, 0x07, 0x05, 0x05, 0x0a, 0x0b, 0x07, ++ 0x47, 0x27, 0x18, 0x0d, 0x40, 0x45, 0x40, 0x40, 0x40, 0x40, 0x02, 0x02, 0x42, 0x00, 0x0b, 0x00, ++ 0x03, 0x0e, 0x42, 0x47, 0x00, 0x16, 0x00, 0x47, 0x47, 0x03, 0x0b, 0x10, 0x0d, 0x10, 0x42, 0x00, ++ 0x0b, 0x00, 0x03, 0x0e, 0x42, 0x47, 0x00, 0x16, 0x00, 0x47, 0x47, 0x03, 0x0b, 0x10, 0x0d, 0x10, ++ 0x1d, 0x45, 0x29, 0x40, 0x48, 0x40, 0x02, 0x07, 0x02, 0x0d, 0x0d, 0x19, 0x07, 0x15, 0x02, 0x45, ++ 0x1a, 0x07, 0x40, 0x15, 0x02, 0x45, 0x1a, 0x07, 0x40, 0x15, 0x02, 0x45, 0x1a, 0x07, 0x40, 0x4a, ++ 0x07, 0x0d, 0x0d, 0x18, 0x1d, 0x18, 0x1d, 0x0d, 0x17, 0x02, 0x45, 0x17, 0x02, 0x45, 0x40, 0x40, ++ 0x40, 0x0f, 0x0f, 0x0d, 0x40, 0x0f, 0x0d, 0x0a, 0x0a, 0x2a, 0x27, 0x1a, 0x07, 0x1d, 0x1a, 0x12, ++ 0x42, 0x1f, 0x15, 0x0d, 0x40, 0x0d, 0x12, 0x0a, 0x18, 0x0d, 0x23, 0x15, 0x18, 0x0d, 0x40, 0x40, ++ 0x40, 0x40, 0x40, 0x40, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x07, 0x4e, 0x19, 0x03, 0x49, 0x40, 0x06, 0x4e, 0x59, 0x27, 0x40, 0x03, 0x40, 0x40, 0x40, 0x0f, ++ 0x03, 0x10, 0x01, 0x16, 0x04, 0x10, 0x1b, 0x31, 0x31, 0x07, 0x07, 0x04, 0x06, 0x0b, 0x0c, 0x07, ++ 0x46, 0x27, 0x19, 0x0c, 0x40, 0x44, 0x41, 0x40, 0x40, 0x40, 0x03, 0x03, 0x41, 0x01, 0x0c, 0x01, ++ 0x04, 0x10, 0x41, 0x46, 0x01, 0x18, 0x01, 0x46, 0x46, 0x04, 0x0c, 0x11, 0x0e, 0x11, 0x41, 0x01, ++ 0x0c, 0x01, 0x04, 0x10, 0x41, 0x46, 0x01, 0x18, 0x01, 0x46, 0x46, 0x04, 0x0c, 0x11, 0x0e, 0x11, ++ 0x1e, 0x44, 0x2b, 0x40, 0x48, 0x40, 0x03, 0x07, 0x03, 0x0e, 0x0e, 0x1b, 0x07, 0x14, 0x01, 0x44, ++ 0x1b, 0x07, 0x40, 0x14, 0x01, 0x44, 0x1b, 0x07, 0x40, 0x14, 0x01, 0x44, 0x1b, 0x07, 0x40, 0x4b, ++ 0x07, 0x0e, 0x0e, 0x19, 0x1e, 0x19, 0x1e, 0x0c, 0x17, 0x01, 0x44, 0x17, 0x01, 0x44, 0x40, 0x40, ++ 0x40, 0x0e, 0x0e, 0x0c, 0x40, 0x0f, 0x0c, 0x09, 0x09, 0x2b, 0x27, 0x1b, 0x07, 0x1e, 0x1b, 0x13, ++ 0x43, 0x1e, 0x14, 0x0c, 0x40, 0x0c, 0x13, 0x09, 0x19, 0x0c, 0x24, 0x16, 0x19, 0x0c, 0x40, 0x40, ++ 0x40, 0x40, 0x40, 0x40, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x07, 0x4f, 0x1a, 0x03, 0x48, 0x40, 0x05, 0x4f, 0x5a, 0x27, 0x40, 0x03, 0x40, 0x40, 0x40, 0x0f, ++ 0x03, 0x11, 0x02, 0x17, 0x06, 0x11, 0x1d, 0x34, 0x34, 0x07, 0x07, 0x04, 0x07, 0x0b, 0x0e, 0x07, ++ 0x45, 0x27, 0x1a, 0x0c, 0x40, 0x44, 0x42, 0x40, 0x40, 0x40, 0x03, 0x03, 0x40, 0x02, 0x0e, 0x02, ++ 0x06, 0x11, 0x40, 0x45, 0x02, 0x19, 0x02, 0x45, 0x45, 0x06, 0x0e, 0x12, 0x0f, 0x12, 0x40, 0x02, ++ 0x0e, 0x02, 0x06, 0x11, 0x40, 0x45, 0x02, 0x19, 0x02, 0x45, 0x45, 0x06, 0x0e, 0x12, 0x0f, 0x12, ++ 0x1f, 0x44, 0x2d, 0x40, 0x48, 0x40, 0x03, 0x07, 0x03, 0x0f, 0x0f, 0x1d, 0x07, 0x14, 0x00, 0x44, ++ 0x1b, 0x07, 0x40, 0x14, 0x00, 0x44, 0x1b, 0x07, 0x40, 0x14, 0x00, 0x44, 0x1b, 0x07, 0x40, 0x4b, ++ 0x07, 0x0f, 0x0f, 0x1a, 0x1f, 0x1a, 0x1f, 0x0c, 0x17, 0x00, 0x44, 0x17, 0x00, 0x44, 0x40, 0x40, ++ 0x40, 0x0d, 0x0d, 0x0c, 0x40, 0x0f, 0x0c, 0x08, 0x08, 0x2b, 0x27, 0x1b, 0x07, 0x1f, 0x1b, 0x13, ++ 0x43, 0x1d, 0x14, 0x0c, 0x40, 0x0c, 0x13, 0x08, 0x1a, 0x0c, 0x26, 0x17, 0x1a, 0x0c, 0x40, 0x40, ++ 0x40, 0x40, 0x40, 0x40, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x07, 0x4f, 0x1b, 0x03, 0x48, 0x40, 0x04, 0x4f, 0x5b, 0x27, 0x40, 0x03, 0x40, 0x40, 0x40, 0x0f, ++ 0x03, 0x13, 0x03, 0x17, 0x07, 0x13, 0x1f, 0x36, 0x36, 0x07, 0x07, 0x04, 0x07, 0x0b, 0x0f, 0x07, ++ 0x44, 0x27, 0x1b, 0x0c, 0x40, 0x44, 0x43, 0x40, 0x40, 0x40, 0x03, 0x03, 0x40, 0x03, 0x0f, 0x03, ++ 0x07, 0x13, 0x40, 0x44, 0x03, 0x1b, 0x03, 0x44, 0x44, 0x07, 0x0f, 0x13, 0x0f, 0x13, 0x40, 0x03, ++ 0x0f, 0x03, 0x07, 0x13, 0x40, 0x44, 0x03, 0x1b, 0x03, 0x44, 0x44, 0x07, 0x0f, 0x13, 0x0f, 0x13, ++ 0x1f, 0x44, 0x2f, 0x40, 0x48, 0x40, 0x03, 0x07, 0x03, 0x0f, 0x0f, 0x1f, 0x07, 0x14, 0x00, 0x44, ++ 0x1b, 0x07, 0x40, 0x14, 0x00, 0x44, 0x1b, 0x07, 0x40, 0x14, 0x00, 0x44, 0x1b, 0x07, 0x40, 0x4b, ++ 0x07, 0x0f, 0x0f, 0x1b, 0x1f, 0x1b, 0x1f, 0x0c, 0x17, 0x00, 0x44, 0x17, 0x00, 0x44, 0x40, 0x40, ++ 0x40, 0x0c, 0x0c, 0x0c, 0x40, 0x0f, 0x0c, 0x08, 0x08, 0x2b, 0x27, 0x1b, 0x07, 0x1f, 0x1b, 0x13, ++ 0x43, 0x1c, 0x14, 0x0c, 0x40, 0x0c, 0x13, 0x08, 0x1b, 0x0c, 0x27, 0x17, 0x1b, 0x0c, 0x40, 0x40, ++ 0x40, 0x40, 0x40, 0x40, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x07, 0x50, 0x1c, 0x04, 0x47, 0x40, 0x03, 0x50, 0x5c, 0x27, 0x40, 0x04, 0x40, 0x40, 0x40, 0x0f, ++ 0x04, 0x14, 0x04, 0x18, 0x08, 0x14, 0x21, 0x39, 0x39, 0x07, 0x07, 0x03, 0x08, 0x0c, 0x10, 0x07, ++ 0x43, 0x27, 0x1c, 0x0b, 0x40, 0x43, 0x44, 0x40, 0x40, 0x40, 0x04, 0x04, 0x00, 0x04, 0x10, 0x04, ++ 0x08, 0x14, 0x00, 0x43, 0x04, 0x1c, 0x04, 0x43, 0x43, 0x08, 0x10, 0x14, 0x10, 0x14, 0x00, 0x04, ++ 0x10, 0x04, 0x08, 0x14, 0x00, 0x43, 0x04, 0x1c, 0x04, 0x43, 0x43, 0x08, 0x10, 0x14, 0x10, 0x14, ++ 0x20, 0x43, 0x31, 0x40, 0x48, 0x40, 0x04, 0x07, 0x04, 0x10, 0x10, 0x21, 0x07, 0x13, 0x40, 0x43, ++ 0x1c, 0x07, 0x40, 0x13, 0x40, 0x43, 0x1c, 0x07, 0x40, 0x13, 0x40, 0x43, 0x1c, 0x07, 0x40, 0x4c, ++ 0x07, 0x10, 0x10, 0x1c, 0x20, 0x1c, 0x20, 0x0b, 0x17, 0x40, 0x43, 0x17, 0x40, 0x43, 0x40, 0x40, ++ 0x40, 0x0b, 0x0b, 0x0b, 0x40, 0x0f, 0x0b, 0x07, 0x07, 0x2c, 0x27, 0x1c, 0x07, 0x20, 0x1c, 0x14, ++ 0x44, 0x1b, 0x13, 0x0b, 0x40, 0x0b, 0x14, 0x07, 0x1c, 0x0b, 0x28, 0x18, 0x1c, 0x0b, 0x40, 0x40, ++ 0x40, 0x40, 0x40, 0x40, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x07, 0x51, 0x1d, 0x04, 0x47, 0x40, 0x02, 0x51, 0x5d, 0x27, 0x40, 0x04, 0x40, 0x40, 0x40, 0x0f, ++ 0x04, 0x16, 0x05, 0x18, 0x09, 0x16, 0x22, 0x3b, 0x3b, 0x07, 0x07, 0x03, 0x08, 0x0c, 0x11, 0x07, ++ 0x42, 0x27, 0x1d, 0x0b, 0x40, 0x43, 0x45, 0x40, 0x40, 0x40, 0x04, 0x04, 0x00, 0x05, 0x11, 0x05, ++ 0x09, 0x16, 0x00, 0x42, 0x05, 0x1e, 0x05, 0x42, 0x42, 0x09, 0x11, 0x15, 0x10, 0x15, 0x00, 0x05, ++ 0x11, 0x05, 0x09, 0x16, 0x00, 0x42, 0x05, 0x1e, 0x05, 0x42, 0x42, 0x09, 0x11, 0x15, 0x10, 0x15, ++ 0x20, 0x43, 0x32, 0x40, 0x48, 0x40, 0x04, 0x07, 0x04, 0x10, 0x10, 0x22, 0x07, 0x13, 0x41, 0x43, ++ 0x1c, 0x07, 0x40, 0x13, 0x41, 0x43, 0x1c, 0x07, 0x40, 0x13, 0x41, 0x43, 0x1c, 0x07, 0x40, 0x4c, ++ 0x07, 0x10, 0x10, 0x1d, 0x20, 0x1d, 0x20, 0x0b, 0x17, 0x41, 0x43, 0x17, 0x41, 0x43, 0x40, 0x40, ++ 0x40, 0x0a, 0x0a, 0x0b, 0x40, 0x0f, 0x0b, 0x06, 0x06, 0x2c, 0x27, 0x1c, 0x07, 0x20, 0x1c, 0x14, ++ 0x44, 0x1a, 0x13, 0x0b, 0x40, 0x0b, 0x14, 0x06, 0x1d, 0x0b, 0x29, 0x18, 0x1d, 0x0b, 0x40, 0x40, ++ 0x40, 0x40, 0x40, 0x40, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x07, 0x51, 0x1e, 0x04, 0x46, 0x40, 0x01, 0x51, 0x5e, 0x27, 0x40, 0x04, 0x40, 0x40, 0x40, 0x0f, ++ 0x04, 0x18, 0x06, 0x19, 0x0b, 0x18, 0x24, 0x3e, 0x3e, 0x07, 0x07, 0x03, 0x09, 0x0c, 0x13, 0x07, ++ 0x41, 0x27, 0x1e, 0x0b, 0x40, 0x43, 0x46, 0x40, 0x40, 0x40, 0x04, 0x04, 0x01, 0x06, 0x13, 0x06, ++ 0x0b, 0x18, 0x01, 0x41, 0x06, 0x20, 0x06, 0x41, 0x41, 0x0b, 0x13, 0x16, 0x11, 0x16, 0x01, 0x06, ++ 0x13, 0x06, 0x0b, 0x18, 0x01, 0x41, 0x06, 0x20, 0x06, 0x41, 0x41, 0x0b, 0x13, 0x16, 0x11, 0x16, ++ 0x21, 0x43, 0x34, 0x40, 0x48, 0x40, 0x04, 0x07, 0x04, 0x11, 0x11, 0x24, 0x07, 0x13, 0x41, 0x43, ++ 0x1c, 0x07, 0x40, 0x13, 0x41, 0x43, 0x1c, 0x07, 0x40, 0x13, 0x41, 0x43, 0x1c, 0x07, 0x40, 0x4c, ++ 0x07, 0x11, 0x11, 0x1e, 0x21, 0x1e, 0x21, 0x0b, 0x17, 0x41, 0x43, 0x17, 0x41, 0x43, 0x40, 0x40, ++ 0x40, 0x09, 0x09, 0x0b, 0x40, 0x0f, 0x0b, 0x06, 0x06, 0x2c, 0x27, 0x1c, 0x07, 0x21, 0x1c, 0x14, ++ 0x44, 0x19, 0x13, 0x0b, 0x40, 0x0b, 0x14, 0x06, 0x1e, 0x0b, 0x2b, 0x19, 0x1e, 0x0b, 0x40, 0x40, ++ 0x40, 0x40, 0x40, 0x40, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x07, 0x52, 0x1f, 0x05, 0x45, 0x40, 0x00, 0x52, 0x5f, 0x27, 0x40, 0x05, 0x40, 0x40, 0x40, 0x0f, ++ 0x05, 0x19, 0x07, 0x1a, 0x0c, 0x19, 0x26, 0x3e, 0x3e, 0x07, 0x07, 0x02, 0x0a, 0x0d, 0x14, 0x07, ++ 0x40, 0x27, 0x1f, 0x0a, 0x40, 0x42, 0x47, 0x40, 0x40, 0x40, 0x05, 0x05, 0x02, 0x07, 0x14, 0x07, ++ 0x0c, 0x19, 0x02, 0x40, 0x07, 0x21, 0x07, 0x40, 0x40, 0x0c, 0x14, 0x17, 0x12, 0x17, 0x02, 0x07, ++ 0x14, 0x07, 0x0c, 0x19, 0x02, 0x40, 0x07, 0x21, 0x07, 0x40, 0x40, 0x0c, 0x14, 0x17, 0x12, 0x17, ++ 0x22, 0x42, 0x36, 0x40, 0x48, 0x40, 0x05, 0x07, 0x05, 0x12, 0x12, 0x26, 0x07, 0x12, 0x42, 0x42, ++ 0x1d, 0x07, 0x40, 0x12, 0x42, 0x42, 0x1d, 0x07, 0x40, 0x12, 0x42, 0x42, 0x1d, 0x07, 0x40, 0x4d, ++ 0x07, 0x12, 0x12, 0x1f, 0x22, 0x1f, 0x22, 0x0a, 0x17, 0x42, 0x42, 0x17, 0x42, 0x42, 0x40, 0x40, ++ 0x40, 0x08, 0x08, 0x0a, 0x40, 0x0f, 0x0a, 0x05, 0x05, 0x2d, 0x27, 0x1d, 0x07, 0x22, 0x1d, 0x15, ++ 0x45, 0x18, 0x12, 0x0a, 0x40, 0x0a, 0x15, 0x05, 0x1f, 0x0a, 0x2c, 0x1a, 0x1f, 0x0a, 0x40, 0x40, ++ 0x40, 0x40, 0x40, 0x40, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x07, 0x52, 0x20, 0x05, 0x45, 0x40, 0x40, 0x52, 0x60, 0x27, 0x40, 0x05, 0x40, 0x40, 0x40, 0x0f, ++ 0x05, 0x1b, 0x08, 0x1a, 0x0d, 0x1b, 0x28, 0x3e, 0x3e, 0x07, 0x07, 0x02, 0x0a, 0x0d, 0x15, 0x07, ++ 0x00, 0x27, 0x20, 0x0a, 0x40, 0x42, 0x48, 0x40, 0x40, 0x40, 0x05, 0x05, 0x02, 0x08, 0x15, 0x08, ++ 0x0d, 0x1b, 0x02, 0x00, 0x08, 0x23, 0x08, 0x00, 0x00, 0x0d, 0x15, 0x18, 0x12, 0x18, 0x02, 0x08, ++ 0x15, 0x08, 0x0d, 0x1b, 0x02, 0x00, 0x08, 0x23, 0x08, 0x00, 0x00, 0x0d, 0x15, 0x18, 0x12, 0x18, ++ 0x22, 0x42, 0x38, 0x40, 0x48, 0x40, 0x05, 0x07, 0x05, 0x12, 0x12, 0x28, 0x07, 0x12, 0x42, 0x42, ++ 0x1d, 0x07, 0x40, 0x12, 0x42, 0x42, 0x1d, 0x07, 0x40, 0x12, 0x42, 0x42, 0x1d, 0x07, 0x40, 0x4d, ++ 0x07, 0x12, 0x12, 0x20, 0x22, 0x20, 0x22, 0x0a, 0x17, 0x42, 0x42, 0x17, 0x42, 0x42, 0x40, 0x40, ++ 0x40, 0x07, 0x07, 0x0a, 0x40, 0x0f, 0x0a, 0x05, 0x05, 0x2d, 0x27, 0x1d, 0x07, 0x22, 0x1d, 0x15, ++ 0x45, 0x17, 0x12, 0x0a, 0x40, 0x0a, 0x15, 0x05, 0x20, 0x0a, 0x2d, 0x1a, 0x20, 0x0a, 0x40, 0x40, ++ 0x40, 0x40, 0x40, 0x40, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x07, 0x53, 0x21, 0x05, 0x44, 0x40, 0x41, 0x53, 0x61, 0x27, 0x40, 0x05, 0x40, 0x40, 0x40, 0x0f, ++ 0x05, 0x1c, 0x09, 0x1b, 0x0e, 0x1c, 0x2a, 0x3e, 0x3e, 0x07, 0x07, 0x02, 0x0b, 0x0d, 0x16, 0x07, ++ 0x01, 0x27, 0x21, 0x0a, 0x40, 0x42, 0x49, 0x40, 0x40, 0x40, 0x05, 0x05, 0x03, 0x09, 0x16, 0x09, ++ 0x0e, 0x1c, 0x03, 0x01, 0x09, 0x24, 0x09, 0x01, 0x01, 0x0e, 0x16, 0x19, 0x13, 0x19, 0x03, 0x09, ++ 0x16, 0x09, 0x0e, 0x1c, 0x03, 0x01, 0x09, 0x24, 0x09, 0x01, 0x01, 0x0e, 0x16, 0x19, 0x13, 0x19, ++ 0x23, 0x42, 0x3a, 0x40, 0x48, 0x40, 0x05, 0x07, 0x05, 0x13, 0x13, 0x2a, 0x07, 0x12, 0x43, 0x42, ++ 0x1d, 0x07, 0x40, 0x12, 0x43, 0x42, 0x1d, 0x07, 0x40, 0x12, 0x43, 0x42, 0x1d, 0x07, 0x40, 0x4d, ++ 0x07, 0x13, 0x13, 0x21, 0x23, 0x21, 0x23, 0x0a, 0x17, 0x43, 0x42, 0x17, 0x43, 0x42, 0x40, 0x40, ++ 0x40, 0x06, 0x06, 0x0a, 0x40, 0x0f, 0x0a, 0x04, 0x04, 0x2d, 0x27, 0x1d, 0x07, 0x23, 0x1d, 0x15, ++ 0x45, 0x16, 0x12, 0x0a, 0x40, 0x0a, 0x15, 0x04, 0x21, 0x0a, 0x2e, 0x1b, 0x21, 0x0a, 0x40, 0x40, ++ 0x40, 0x40, 0x40, 0x40, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x07, 0x54, 0x22, 0x06, 0x43, 0x40, 0x42, 0x54, 0x62, 0x27, 0x40, 0x06, 0x40, 0x40, 0x40, 0x0f, ++ 0x06, 0x1e, 0x0a, 0x1c, 0x10, 0x1e, 0x2c, 0x3e, 0x3e, 0x07, 0x07, 0x01, 0x0c, 0x0e, 0x18, 0x07, ++ 0x02, 0x27, 0x22, 0x09, 0x40, 0x41, 0x4a, 0x40, 0x40, 0x40, 0x06, 0x06, 0x04, 0x0a, 0x18, 0x0a, ++ 0x10, 0x1e, 0x04, 0x02, 0x0a, 0x26, 0x0a, 0x02, 0x02, 0x10, 0x18, 0x1a, 0x14, 0x1a, 0x04, 0x0a, ++ 0x18, 0x0a, 0x10, 0x1e, 0x04, 0x02, 0x0a, 0x26, 0x0a, 0x02, 0x02, 0x10, 0x18, 0x1a, 0x14, 0x1a, ++ 0x24, 0x41, 0x3c, 0x40, 0x48, 0x40, 0x06, 0x07, 0x06, 0x14, 0x14, 0x2c, 0x07, 0x11, 0x44, 0x41, ++ 0x1e, 0x07, 0x40, 0x11, 0x44, 0x41, 0x1e, 0x07, 0x40, 0x11, 0x44, 0x41, 0x1e, 0x07, 0x40, 0x4e, ++ 0x07, 0x14, 0x14, 0x22, 0x24, 0x22, 0x24, 0x09, 0x17, 0x44, 0x41, 0x17, 0x44, 0x41, 0x40, 0x40, ++ 0x40, 0x05, 0x05, 0x09, 0x40, 0x0f, 0x09, 0x03, 0x03, 0x2e, 0x27, 0x1e, 0x07, 0x24, 0x1e, 0x16, ++ 0x46, 0x15, 0x11, 0x09, 0x40, 0x09, 0x16, 0x03, 0x22, 0x09, 0x30, 0x1c, 0x22, 0x09, 0x40, 0x40, ++ 0x40, 0x40, 0x40, 0x40, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x07, 0x54, 0x23, 0x06, 0x43, 0x40, 0x43, 0x54, 0x63, 0x27, 0x40, 0x06, 0x40, 0x40, 0x40, 0x0f, ++ 0x06, 0x1f, 0x0b, 0x1c, 0x11, 0x1f, 0x2e, 0x3e, 0x3e, 0x07, 0x07, 0x01, 0x0c, 0x0e, 0x19, 0x07, ++ 0x03, 0x27, 0x23, 0x09, 0x40, 0x41, 0x4b, 0x40, 0x40, 0x40, 0x06, 0x06, 0x04, 0x0b, 0x19, 0x0b, ++ 0x11, 0x1f, 0x04, 0x03, 0x0b, 0x27, 0x0b, 0x03, 0x03, 0x11, 0x19, 0x1b, 0x14, 0x1b, 0x04, 0x0b, ++ 0x19, 0x0b, 0x11, 0x1f, 0x04, 0x03, 0x0b, 0x27, 0x0b, 0x03, 0x03, 0x11, 0x19, 0x1b, 0x14, 0x1b, ++ 0x24, 0x41, 0x3e, 0x40, 0x48, 0x40, 0x06, 0x07, 0x06, 0x14, 0x14, 0x2e, 0x07, 0x11, 0x44, 0x41, ++ 0x1e, 0x07, 0x40, 0x11, 0x44, 0x41, 0x1e, 0x07, 0x40, 0x11, 0x44, 0x41, 0x1e, 0x07, 0x40, 0x4e, ++ 0x07, 0x14, 0x14, 0x23, 0x24, 0x23, 0x24, 0x09, 0x17, 0x44, 0x41, 0x17, 0x44, 0x41, 0x40, 0x40, ++ 0x40, 0x04, 0x04, 0x09, 0x40, 0x0f, 0x09, 0x03, 0x03, 0x2e, 0x27, 0x1e, 0x07, 0x24, 0x1e, 0x16, ++ 0x46, 0x14, 0x11, 0x09, 0x40, 0x09, 0x16, 0x03, 0x23, 0x09, 0x31, 0x1c, 0x23, 0x09, 0x40, 0x40, ++ 0x40, 0x40, 0x40, 0x40, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x07, 0x55, 0x24, 0x06, 0x42, 0x40, 0x44, 0x55, 0x64, 0x27, 0x40, 0x06, 0x40, 0x40, 0x40, 0x0f, ++ 0x06, 0x21, 0x0c, 0x1d, 0x12, 0x21, 0x30, 0x3e, 0x3e, 0x07, 0x07, 0x01, 0x0d, 0x0e, 0x1a, 0x07, ++ 0x04, 0x27, 0x24, 0x09, 0x40, 0x41, 0x4c, 0x40, 0x40, 0x40, 0x06, 0x06, 0x05, 0x0c, 0x1a, 0x0c, ++ 0x12, 0x21, 0x05, 0x04, 0x0c, 0x29, 0x0c, 0x04, 0x04, 0x12, 0x1a, 0x1c, 0x15, 0x1c, 0x05, 0x0c, ++ 0x1a, 0x0c, 0x12, 0x21, 0x05, 0x04, 0x0c, 0x29, 0x0c, 0x04, 0x04, 0x12, 0x1a, 0x1c, 0x15, 0x1c, ++ 0x25, 0x41, 0x3e, 0x40, 0x48, 0x40, 0x06, 0x07, 0x06, 0x15, 0x15, 0x30, 0x07, 0x11, 0x45, 0x41, ++ 0x1e, 0x07, 0x40, 0x11, 0x45, 0x41, 0x1e, 0x07, 0x40, 0x11, 0x45, 0x41, 0x1e, 0x07, 0x40, 0x4e, ++ 0x07, 0x15, 0x15, 0x24, 0x25, 0x24, 0x25, 0x09, 0x17, 0x45, 0x41, 0x17, 0x45, 0x41, 0x40, 0x40, ++ 0x40, 0x03, 0x03, 0x09, 0x40, 0x0f, 0x09, 0x02, 0x02, 0x2e, 0x27, 0x1e, 0x07, 0x25, 0x1e, 0x16, ++ 0x46, 0x13, 0x11, 0x09, 0x40, 0x09, 0x16, 0x02, 0x24, 0x09, 0x32, 0x1d, 0x24, 0x09, 0x40, 0x40, ++ 0x40, 0x40, 0x40, 0x40, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x07, 0x56, 0x24, 0x06, 0x42, 0x40, 0x45, 0x56, 0x65, 0x27, 0x40, 0x06, 0x40, 0x40, 0x40, 0x0f, ++ 0x06, 0x22, 0x0c, 0x1d, 0x13, 0x22, 0x31, 0x3e, 0x3e, 0x07, 0x07, 0x00, 0x0d, 0x0e, 0x1b, 0x07, ++ 0x04, 0x27, 0x24, 0x08, 0x40, 0x41, 0x4d, 0x40, 0x40, 0x40, 0x06, 0x06, 0x05, 0x0c, 0x1b, 0x0c, ++ 0x13, 0x22, 0x05, 0x04, 0x0c, 0x2a, 0x0c, 0x04, 0x04, 0x13, 0x1b, 0x1c, 0x15, 0x1c, 0x05, 0x0c, ++ 0x1b, 0x0c, 0x13, 0x22, 0x05, 0x04, 0x0c, 0x2a, 0x0c, 0x04, 0x04, 0x13, 0x1b, 0x1c, 0x15, 0x1c, ++ 0x25, 0x41, 0x3e, 0x40, 0x48, 0x40, 0x06, 0x07, 0x06, 0x15, 0x15, 0x31, 0x07, 0x10, 0x46, 0x41, ++ 0x1e, 0x07, 0x40, 0x10, 0x46, 0x41, 0x1e, 0x07, 0x40, 0x10, 0x46, 0x41, 0x1e, 0x07, 0x40, 0x4f, ++ 0x07, 0x15, 0x15, 0x24, 0x25, 0x24, 0x25, 0x08, 0x17, 0x46, 0x41, 0x17, 0x46, 0x41, 0x40, 0x40, ++ 0x40, 0x02, 0x02, 0x08, 0x40, 0x0f, 0x08, 0x01, 0x01, 0x2e, 0x27, 0x1e, 0x07, 0x25, 0x1e, 0x16, ++ 0x47, 0x12, 0x10, 0x08, 0x40, 0x08, 0x16, 0x01, 0x24, 0x08, 0x33, 0x1d, 0x24, 0x08, 0x40, 0x40, ++ 0x40, 0x40, 0x40, 0x40, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x07, 0x56, 0x25, 0x07, 0x41, 0x40, 0x45, 0x56, 0x65, 0x27, 0x40, 0x07, 0x40, 0x40, 0x40, 0x0f, ++ 0x07, 0x24, 0x0d, 0x1e, 0x15, 0x24, 0x33, 0x3e, 0x3e, 0x07, 0x07, 0x00, 0x0e, 0x0f, 0x1d, 0x07, ++ 0x05, 0x27, 0x25, 0x08, 0x40, 0x40, 0x4d, 0x40, 0x40, 0x40, 0x07, 0x07, 0x06, 0x0d, 0x1d, 0x0d, ++ 0x15, 0x24, 0x06, 0x05, 0x0d, 0x2c, 0x0d, 0x05, 0x05, 0x15, 0x1d, 0x1d, 0x16, 0x1d, 0x06, 0x0d, ++ 0x1d, 0x0d, 0x15, 0x24, 0x06, 0x05, 0x0d, 0x2c, 0x0d, 0x05, 0x05, 0x15, 0x1d, 0x1d, 0x16, 0x1d, ++ 0x26, 0x40, 0x3e, 0x40, 0x48, 0x40, 0x07, 0x07, 0x07, 0x16, 0x16, 0x33, 0x07, 0x10, 0x46, 0x40, ++ 0x1f, 0x07, 0x40, 0x10, 0x46, 0x40, 0x1f, 0x07, 0x40, 0x10, 0x46, 0x40, 0x1f, 0x07, 0x40, 0x4f, ++ 0x07, 0x16, 0x16, 0x25, 0x26, 0x25, 0x26, 0x08, 0x17, 0x46, 0x40, 0x17, 0x46, 0x40, 0x40, 0x40, ++ 0x40, 0x02, 0x02, 0x08, 0x40, 0x0f, 0x08, 0x01, 0x01, 0x2f, 0x27, 0x1f, 0x07, 0x26, 0x1f, 0x17, ++ 0x47, 0x12, 0x10, 0x08, 0x40, 0x08, 0x17, 0x01, 0x25, 0x08, 0x35, 0x1e, 0x25, 0x08, 0x40, 0x40, ++ 0x40, 0x40, 0x40, 0x40, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x07, 0x57, 0x26, 0x07, 0x40, 0x40, 0x46, 0x57, 0x66, 0x27, 0x40, 0x07, 0x40, 0x40, 0x40, 0x0f, ++ 0x07, 0x26, 0x0e, 0x1f, 0x16, 0x26, 0x35, 0x3e, 0x3e, 0x07, 0x07, 0x00, 0x0f, 0x0f, 0x1e, 0x07, ++ 0x06, 0x27, 0x26, 0x08, 0x40, 0x40, 0x4e, 0x40, 0x40, 0x40, 0x07, 0x07, 0x07, 0x0e, 0x1e, 0x0e, ++ 0x16, 0x26, 0x07, 0x06, 0x0e, 0x2e, 0x0e, 0x06, 0x06, 0x16, 0x1e, 0x1e, 0x17, 0x1e, 0x07, 0x0e, ++ 0x1e, 0x0e, 0x16, 0x26, 0x07, 0x06, 0x0e, 0x2e, 0x0e, 0x06, 0x06, 0x16, 0x1e, 0x1e, 0x17, 0x1e, ++ 0x27, 0x40, 0x3e, 0x40, 0x48, 0x40, 0x07, 0x07, 0x07, 0x17, 0x17, 0x35, 0x07, 0x10, 0x47, 0x40, ++ 0x1f, 0x07, 0x40, 0x10, 0x47, 0x40, 0x1f, 0x07, 0x40, 0x10, 0x47, 0x40, 0x1f, 0x07, 0x40, 0x4f, ++ 0x07, 0x17, 0x17, 0x26, 0x27, 0x26, 0x27, 0x08, 0x17, 0x47, 0x40, 0x17, 0x47, 0x40, 0x40, 0x40, ++ 0x40, 0x01, 0x01, 0x08, 0x40, 0x0f, 0x08, 0x00, 0x00, 0x2f, 0x27, 0x1f, 0x07, 0x27, 0x1f, 0x17, ++ 0x47, 0x11, 0x10, 0x08, 0x40, 0x08, 0x17, 0x00, 0x26, 0x08, 0x36, 0x1f, 0x26, 0x08, 0x40, 0x40, ++ 0x40, 0x40, 0x40, 0x40, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x07, 0x57, 0x27, 0x07, 0x40, 0x40, 0x47, 0x57, 0x67, 0x27, 0x40, 0x07, 0x40, 0x40, 0x40, 0x0f, ++ 0x07, 0x27, 0x0f, 0x1f, 0x17, 0x27, 0x37, 0x3e, 0x3e, 0x07, 0x07, 0x00, 0x0f, 0x0f, 0x1f, 0x07, ++ 0x07, 0x27, 0x27, 0x08, 0x40, 0x40, 0x4f, 0x40, 0x40, 0x40, 0x07, 0x07, 0x07, 0x0f, 0x1f, 0x0f, ++ 0x17, 0x27, 0x07, 0x07, 0x0f, 0x2f, 0x0f, 0x07, 0x07, 0x17, 0x1f, 0x1f, 0x17, 0x1f, 0x07, 0x0f, ++ 0x1f, 0x0f, 0x17, 0x27, 0x07, 0x07, 0x0f, 0x2f, 0x0f, 0x07, 0x07, 0x17, 0x1f, 0x1f, 0x17, 0x1f, ++ 0x27, 0x40, 0x3e, 0x40, 0x48, 0x40, 0x07, 0x07, 0x07, 0x17, 0x17, 0x37, 0x07, 0x10, 0x47, 0x40, ++ 0x1f, 0x07, 0x40, 0x10, 0x47, 0x40, 0x1f, 0x07, 0x40, 0x10, 0x47, 0x40, 0x1f, 0x07, 0x40, 0x4f, ++ 0x07, 0x17, 0x17, 0x27, 0x27, 0x27, 0x27, 0x08, 0x17, 0x47, 0x40, 0x17, 0x47, 0x40, 0x40, 0x40, ++ 0x40, 0x00, 0x00, 0x08, 0x40, 0x0f, 0x08, 0x00, 0x00, 0x2f, 0x27, 0x1f, 0x07, 0x27, 0x1f, 0x17, ++ 0x47, 0x10, 0x10, 0x08, 0x40, 0x08, 0x17, 0x00, 0x27, 0x08, 0x37, 0x1f, 0x27, 0x08, 0x40, 0x40, ++ 0x40, 0x40, 0x40, 0x40, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x07, 0x3e, 0x48, 0x48, 0x60, 0x40, 0x27, 0x07, 0x07, 0x1f, 0x40, 0x48, 0x40, 0x40, 0x17, 0x0f, ++ 0x48, 0x68, 0x40, 0x07, 0x68, 0x68, 0x68, 0x68, 0x68, 0x07, 0x07, 0x0f, 0x3e, 0x17, 0x40, 0x07, ++ 0x68, 0x27, 0x50, 0x17, 0x40, 0x07, 0x1f, 0x40, 0x40, 0x40, 0x48, 0x48, 0x58, 0x60, 0x50, 0x60, ++ 0x68, 0x60, 0x58, 0x68, 0x68, 0x68, 0x58, 0x60, 0x68, 0x68, 0x68, 0x50, 0x48, 0x58, 0x58, 0x60, ++ 0x50, 0x60, 0x68, 0x60, 0x58, 0x68, 0x68, 0x68, 0x58, 0x60, 0x68, 0x68, 0x68, 0x50, 0x48, 0x58, ++ 0x07, 0x50, 0x58, 0x40, 0x40, 0x40, 0x48, 0x07, 0x48, 0x48, 0x48, 0x68, 0x50, 0x1f, 0x17, 0x50, ++ 0x0f, 0x07, 0x40, 0x1f, 0x17, 0x50, 0x0f, 0x07, 0x40, 0x1f, 0x17, 0x50, 0x0f, 0x07, 0x40, 0x40, ++ 0x07, 0x40, 0x40, 0x40, 0x07, 0x40, 0x07, 0x17, 0x17, 0x17, 0x50, 0x17, 0x17, 0x50, 0x40, 0x40, ++ 0x40, 0x2f, 0x17, 0x17, 0x40, 0x0f, 0x17, 0x1f, 0x1f, 0x1f, 0x27, 0x0f, 0x07, 0x07, 0x0f, 0x40, ++ 0x07, 0x3e, 0x1f, 0x17, 0x40, 0x0f, 0x17, 0x1f, 0x48, 0x17, 0x48, 0x48, 0x48, 0x17, 0x40, 0x40, ++ 0x40, 0x40, 0x40, 0x40, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x07, 0x3e, 0x47, 0x47, 0x5f, 0x40, 0x27, 0x07, 0x07, 0x20, 0x40, 0x47, 0x40, 0x40, 0x17, 0x0f, ++ 0x47, 0x66, 0x40, 0x08, 0x66, 0x66, 0x66, 0x65, 0x65, 0x07, 0x07, 0x0f, 0x3e, 0x17, 0x00, 0x07, ++ 0x67, 0x27, 0x4e, 0x17, 0x40, 0x07, 0x1f, 0x40, 0x40, 0x40, 0x47, 0x47, 0x57, 0x5f, 0x4f, 0x5f, ++ 0x66, 0x5e, 0x57, 0x67, 0x67, 0x66, 0x57, 0x5f, 0x67, 0x67, 0x66, 0x4f, 0x47, 0x56, 0x57, 0x5f, ++ 0x4f, 0x5f, 0x66, 0x5e, 0x57, 0x67, 0x67, 0x66, 0x57, 0x5f, 0x67, 0x67, 0x66, 0x4f, 0x47, 0x56, ++ 0x08, 0x4f, 0x56, 0x40, 0x40, 0x40, 0x47, 0x07, 0x47, 0x47, 0x47, 0x66, 0x4f, 0x1f, 0x17, 0x4f, ++ 0x10, 0x07, 0x40, 0x1f, 0x17, 0x4f, 0x10, 0x07, 0x40, 0x1f, 0x17, 0x4f, 0x10, 0x07, 0x40, 0x40, ++ 0x07, 0x00, 0x00, 0x00, 0x08, 0x00, 0x08, 0x17, 0x17, 0x17, 0x4f, 0x17, 0x17, 0x4f, 0x40, 0x40, ++ 0x40, 0x2f, 0x17, 0x17, 0x40, 0x0f, 0x17, 0x1f, 0x1f, 0x20, 0x27, 0x10, 0x07, 0x08, 0x10, 0x00, ++ 0x07, 0x3e, 0x1f, 0x17, 0x40, 0x0f, 0x17, 0x1f, 0x47, 0x17, 0x46, 0x47, 0x47, 0x17, 0x40, 0x40, ++ 0x40, 0x40, 0x40, 0x40, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x07, 0x3e, 0x46, 0x47, 0x5e, 0x40, 0x26, 0x06, 0x06, 0x20, 0x40, 0x47, 0x40, 0x40, 0x16, 0x0f, ++ 0x47, 0x64, 0x40, 0x08, 0x65, 0x64, 0x64, 0x63, 0x63, 0x07, 0x07, 0x0f, 0x3e, 0x17, 0x01, 0x07, ++ 0x66, 0x27, 0x4d, 0x17, 0x40, 0x07, 0x1e, 0x40, 0x40, 0x40, 0x47, 0x47, 0x56, 0x5e, 0x4e, 0x5e, ++ 0x65, 0x5d, 0x56, 0x66, 0x66, 0x64, 0x56, 0x5e, 0x66, 0x66, 0x64, 0x4e, 0x46, 0x55, 0x56, 0x5e, ++ 0x4e, 0x5e, 0x65, 0x5d, 0x56, 0x66, 0x66, 0x64, 0x56, 0x5e, 0x66, 0x66, 0x64, 0x4e, 0x46, 0x55, ++ 0x09, 0x4f, 0x54, 0x40, 0x40, 0x40, 0x47, 0x07, 0x47, 0x46, 0x46, 0x64, 0x4e, 0x1f, 0x16, 0x4f, ++ 0x10, 0x07, 0x40, 0x1f, 0x16, 0x4f, 0x10, 0x07, 0x40, 0x1f, 0x16, 0x4f, 0x10, 0x07, 0x40, 0x40, ++ 0x07, 0x00, 0x00, 0x01, 0x09, 0x01, 0x09, 0x17, 0x17, 0x16, 0x4f, 0x17, 0x16, 0x4f, 0x40, 0x40, ++ 0x40, 0x2e, 0x17, 0x17, 0x40, 0x0f, 0x17, 0x1e, 0x1e, 0x20, 0x27, 0x10, 0x07, 0x09, 0x10, 0x01, ++ 0x07, 0x3e, 0x1f, 0x17, 0x40, 0x0f, 0x17, 0x1e, 0x46, 0x17, 0x45, 0x46, 0x46, 0x17, 0x40, 0x40, ++ 0x40, 0x40, 0x40, 0x40, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x07, 0x3e, 0x45, 0x47, 0x5e, 0x40, 0x25, 0x06, 0x05, 0x20, 0x40, 0x47, 0x40, 0x40, 0x16, 0x0f, ++ 0x47, 0x63, 0x40, 0x08, 0x64, 0x63, 0x62, 0x60, 0x60, 0x07, 0x07, 0x0f, 0x3e, 0x17, 0x01, 0x07, ++ 0x65, 0x27, 0x4c, 0x17, 0x40, 0x07, 0x1d, 0x40, 0x40, 0x40, 0x47, 0x47, 0x56, 0x5d, 0x4e, 0x5d, ++ 0x64, 0x5c, 0x56, 0x65, 0x65, 0x63, 0x56, 0x5e, 0x65, 0x65, 0x63, 0x4d, 0x46, 0x54, 0x56, 0x5d, ++ 0x4e, 0x5d, 0x64, 0x5c, 0x56, 0x65, 0x65, 0x63, 0x56, 0x5e, 0x65, 0x65, 0x63, 0x4d, 0x46, 0x54, ++ 0x09, 0x4f, 0x52, 0x40, 0x40, 0x40, 0x47, 0x07, 0x47, 0x46, 0x46, 0x62, 0x4e, 0x1f, 0x16, 0x4f, ++ 0x10, 0x07, 0x40, 0x1f, 0x16, 0x4f, 0x10, 0x07, 0x40, 0x1f, 0x16, 0x4f, 0x10, 0x07, 0x40, 0x40, ++ 0x07, 0x00, 0x00, 0x01, 0x09, 0x01, 0x09, 0x17, 0x17, 0x16, 0x4f, 0x17, 0x16, 0x4f, 0x40, 0x40, ++ 0x40, 0x2d, 0x17, 0x17, 0x40, 0x0f, 0x17, 0x1e, 0x1e, 0x20, 0x27, 0x10, 0x07, 0x09, 0x10, 0x01, ++ 0x07, 0x3e, 0x1f, 0x17, 0x40, 0x0f, 0x17, 0x1e, 0x45, 0x17, 0x44, 0x45, 0x45, 0x17, 0x40, 0x40, ++ 0x40, 0x40, 0x40, 0x40, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x07, 0x3e, 0x44, 0x46, 0x5d, 0x40, 0x24, 0x05, 0x04, 0x21, 0x40, 0x46, 0x40, 0x40, 0x15, 0x0f, ++ 0x46, 0x61, 0x40, 0x09, 0x63, 0x61, 0x60, 0x5e, 0x5e, 0x07, 0x07, 0x0e, 0x3e, 0x16, 0x02, 0x07, ++ 0x64, 0x27, 0x4b, 0x16, 0x40, 0x06, 0x1c, 0x40, 0x40, 0x40, 0x46, 0x46, 0x55, 0x5c, 0x4d, 0x5c, ++ 0x63, 0x5b, 0x55, 0x64, 0x64, 0x61, 0x55, 0x5d, 0x64, 0x64, 0x61, 0x4c, 0x45, 0x53, 0x55, 0x5c, ++ 0x4d, 0x5c, 0x63, 0x5b, 0x55, 0x64, 0x64, 0x61, 0x55, 0x5d, 0x64, 0x64, 0x61, 0x4c, 0x45, 0x53, ++ 0x0a, 0x4e, 0x50, 0x40, 0x41, 0x40, 0x46, 0x07, 0x46, 0x45, 0x45, 0x60, 0x4d, 0x1e, 0x15, 0x4e, ++ 0x11, 0x07, 0x40, 0x1e, 0x15, 0x4e, 0x11, 0x07, 0x40, 0x1e, 0x15, 0x4e, 0x11, 0x07, 0x40, 0x41, ++ 0x07, 0x01, 0x01, 0x02, 0x0a, 0x02, 0x0a, 0x16, 0x17, 0x15, 0x4e, 0x17, 0x15, 0x4e, 0x40, 0x40, ++ 0x40, 0x2c, 0x16, 0x16, 0x40, 0x0f, 0x16, 0x1d, 0x1d, 0x21, 0x27, 0x11, 0x07, 0x0a, 0x11, 0x02, ++ 0x06, 0x3e, 0x1e, 0x16, 0x40, 0x0f, 0x16, 0x1d, 0x44, 0x16, 0x43, 0x44, 0x44, 0x16, 0x40, 0x40, ++ 0x40, 0x40, 0x40, 0x40, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x07, 0x3e, 0x43, 0x46, 0x5c, 0x40, 0x23, 0x04, 0x03, 0x21, 0x40, 0x46, 0x40, 0x40, 0x14, 0x0f, ++ 0x46, 0x60, 0x40, 0x09, 0x61, 0x60, 0x5e, 0x5b, 0x5b, 0x07, 0x07, 0x0e, 0x3e, 0x16, 0x03, 0x07, ++ 0x63, 0x27, 0x49, 0x16, 0x40, 0x06, 0x1b, 0x40, 0x40, 0x40, 0x46, 0x46, 0x54, 0x5b, 0x4c, 0x5b, ++ 0x61, 0x59, 0x54, 0x63, 0x63, 0x60, 0x54, 0x5c, 0x63, 0x63, 0x60, 0x4b, 0x44, 0x51, 0x54, 0x5b, ++ 0x4c, 0x5b, 0x61, 0x59, 0x54, 0x63, 0x63, 0x60, 0x54, 0x5c, 0x63, 0x63, 0x60, 0x4b, 0x44, 0x51, ++ 0x0b, 0x4e, 0x4e, 0x40, 0x41, 0x40, 0x46, 0x07, 0x46, 0x44, 0x44, 0x5e, 0x4c, 0x1e, 0x14, 0x4e, ++ 0x11, 0x07, 0x40, 0x1e, 0x14, 0x4e, 0x11, 0x07, 0x40, 0x1e, 0x14, 0x4e, 0x11, 0x07, 0x40, 0x41, ++ 0x07, 0x01, 0x01, 0x03, 0x0b, 0x03, 0x0b, 0x16, 0x17, 0x14, 0x4e, 0x17, 0x14, 0x4e, 0x40, 0x40, ++ 0x40, 0x2b, 0x16, 0x16, 0x40, 0x0f, 0x16, 0x1c, 0x1c, 0x21, 0x27, 0x11, 0x07, 0x0b, 0x11, 0x03, ++ 0x06, 0x3e, 0x1e, 0x16, 0x40, 0x0f, 0x16, 0x1c, 0x43, 0x16, 0x41, 0x43, 0x43, 0x16, 0x40, 0x40, ++ 0x40, 0x40, 0x40, 0x40, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x07, 0x3e, 0x42, 0x46, 0x5c, 0x40, 0x22, 0x04, 0x02, 0x21, 0x40, 0x46, 0x40, 0x40, 0x14, 0x0f, ++ 0x46, 0x5e, 0x40, 0x09, 0x60, 0x5e, 0x5c, 0x59, 0x59, 0x07, 0x07, 0x0e, 0x3e, 0x16, 0x03, 0x07, ++ 0x62, 0x27, 0x48, 0x16, 0x40, 0x06, 0x1a, 0x40, 0x40, 0x40, 0x46, 0x46, 0x54, 0x5a, 0x4c, 0x5a, ++ 0x60, 0x58, 0x54, 0x62, 0x62, 0x5e, 0x54, 0x5c, 0x62, 0x62, 0x5e, 0x4a, 0x44, 0x50, 0x54, 0x5a, ++ 0x4c, 0x5a, 0x60, 0x58, 0x54, 0x62, 0x62, 0x5e, 0x54, 0x5c, 0x62, 0x62, 0x5e, 0x4a, 0x44, 0x50, ++ 0x0b, 0x4e, 0x4c, 0x40, 0x41, 0x40, 0x46, 0x07, 0x46, 0x44, 0x44, 0x5c, 0x4c, 0x1e, 0x14, 0x4e, ++ 0x11, 0x07, 0x40, 0x1e, 0x14, 0x4e, 0x11, 0x07, 0x40, 0x1e, 0x14, 0x4e, 0x11, 0x07, 0x40, 0x41, ++ 0x07, 0x01, 0x01, 0x03, 0x0b, 0x03, 0x0b, 0x16, 0x17, 0x14, 0x4e, 0x17, 0x14, 0x4e, 0x40, 0x40, ++ 0x40, 0x2a, 0x16, 0x16, 0x40, 0x0f, 0x16, 0x1c, 0x1c, 0x21, 0x27, 0x11, 0x07, 0x0b, 0x11, 0x03, ++ 0x06, 0x3e, 0x1e, 0x16, 0x40, 0x0f, 0x16, 0x1c, 0x42, 0x16, 0x40, 0x42, 0x42, 0x16, 0x40, 0x40, ++ 0x40, 0x40, 0x40, 0x40, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x07, 0x3e, 0x41, 0x45, 0x5b, 0x40, 0x21, 0x03, 0x01, 0x22, 0x40, 0x45, 0x40, 0x40, 0x13, 0x0f, ++ 0x45, 0x5d, 0x40, 0x0a, 0x5f, 0x5d, 0x5a, 0x56, 0x56, 0x07, 0x07, 0x0d, 0x3e, 0x15, 0x04, 0x07, ++ 0x61, 0x27, 0x47, 0x15, 0x40, 0x05, 0x19, 0x40, 0x40, 0x40, 0x45, 0x45, 0x53, 0x59, 0x4b, 0x59, ++ 0x5f, 0x57, 0x53, 0x61, 0x61, 0x5d, 0x53, 0x5b, 0x61, 0x61, 0x5d, 0x49, 0x43, 0x4f, 0x53, 0x59, ++ 0x4b, 0x59, 0x5f, 0x57, 0x53, 0x61, 0x61, 0x5d, 0x53, 0x5b, 0x61, 0x61, 0x5d, 0x49, 0x43, 0x4f, ++ 0x0c, 0x4d, 0x4a, 0x40, 0x42, 0x40, 0x45, 0x07, 0x45, 0x43, 0x43, 0x5a, 0x4b, 0x1d, 0x13, 0x4d, ++ 0x12, 0x07, 0x40, 0x1d, 0x13, 0x4d, 0x12, 0x07, 0x40, 0x1d, 0x13, 0x4d, 0x12, 0x07, 0x40, 0x42, ++ 0x07, 0x02, 0x02, 0x04, 0x0c, 0x04, 0x0c, 0x15, 0x17, 0x13, 0x4d, 0x17, 0x13, 0x4d, 0x40, 0x40, ++ 0x40, 0x29, 0x15, 0x15, 0x40, 0x0f, 0x15, 0x1b, 0x1b, 0x22, 0x27, 0x12, 0x07, 0x0c, 0x12, 0x04, ++ 0x05, 0x3e, 0x1d, 0x15, 0x40, 0x0f, 0x15, 0x1b, 0x41, 0x15, 0x00, 0x41, 0x41, 0x15, 0x40, 0x40, ++ 0x40, 0x40, 0x40, 0x40, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x07, 0x3e, 0x40, 0x45, 0x5b, 0x40, 0x20, 0x02, 0x00, 0x22, 0x40, 0x45, 0x40, 0x40, 0x12, 0x0f, ++ 0x45, 0x5b, 0x40, 0x0a, 0x5e, 0x5b, 0x59, 0x54, 0x54, 0x07, 0x07, 0x0d, 0x3e, 0x15, 0x04, 0x07, ++ 0x60, 0x27, 0x46, 0x15, 0x40, 0x05, 0x18, 0x40, 0x40, 0x40, 0x45, 0x45, 0x53, 0x58, 0x4b, 0x58, ++ 0x5e, 0x56, 0x53, 0x60, 0x60, 0x5b, 0x53, 0x5b, 0x60, 0x60, 0x5b, 0x48, 0x43, 0x4e, 0x53, 0x58, ++ 0x4b, 0x58, 0x5e, 0x56, 0x53, 0x60, 0x60, 0x5b, 0x53, 0x5b, 0x60, 0x60, 0x5b, 0x48, 0x43, 0x4e, ++ 0x0c, 0x4d, 0x49, 0x40, 0x42, 0x40, 0x45, 0x07, 0x45, 0x43, 0x43, 0x59, 0x4b, 0x1d, 0x12, 0x4d, ++ 0x12, 0x07, 0x40, 0x1d, 0x12, 0x4d, 0x12, 0x07, 0x40, 0x1d, 0x12, 0x4d, 0x12, 0x07, 0x40, 0x42, ++ 0x07, 0x02, 0x02, 0x04, 0x0c, 0x04, 0x0c, 0x15, 0x17, 0x12, 0x4d, 0x17, 0x12, 0x4d, 0x40, 0x40, ++ 0x40, 0x28, 0x15, 0x15, 0x40, 0x0f, 0x15, 0x1a, 0x1a, 0x22, 0x27, 0x12, 0x07, 0x0c, 0x12, 0x04, ++ 0x05, 0x3e, 0x1d, 0x15, 0x40, 0x0f, 0x15, 0x1a, 0x40, 0x15, 0x01, 0x40, 0x40, 0x15, 0x40, 0x40, ++ 0x40, 0x40, 0x40, 0x40, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x07, 0x3e, 0x00, 0x45, 0x5a, 0x40, 0x1f, 0x02, 0x40, 0x22, 0x40, 0x45, 0x40, 0x40, 0x12, 0x0f, ++ 0x45, 0x59, 0x40, 0x0a, 0x5c, 0x59, 0x57, 0x51, 0x51, 0x07, 0x07, 0x0d, 0x3e, 0x15, 0x05, 0x07, ++ 0x5f, 0x27, 0x44, 0x15, 0x40, 0x05, 0x17, 0x40, 0x40, 0x40, 0x45, 0x45, 0x52, 0x57, 0x4a, 0x57, ++ 0x5c, 0x54, 0x52, 0x5f, 0x5f, 0x59, 0x52, 0x5a, 0x5f, 0x5f, 0x59, 0x47, 0x42, 0x4c, 0x52, 0x57, ++ 0x4a, 0x57, 0x5c, 0x54, 0x52, 0x5f, 0x5f, 0x59, 0x52, 0x5a, 0x5f, 0x5f, 0x59, 0x47, 0x42, 0x4c, ++ 0x0d, 0x4d, 0x47, 0x40, 0x42, 0x40, 0x45, 0x07, 0x45, 0x42, 0x42, 0x57, 0x4a, 0x1d, 0x12, 0x4d, ++ 0x12, 0x07, 0x40, 0x1d, 0x12, 0x4d, 0x12, 0x07, 0x40, 0x1d, 0x12, 0x4d, 0x12, 0x07, 0x40, 0x42, ++ 0x07, 0x02, 0x02, 0x05, 0x0d, 0x05, 0x0d, 0x15, 0x17, 0x12, 0x4d, 0x17, 0x12, 0x4d, 0x40, 0x40, ++ 0x40, 0x27, 0x15, 0x15, 0x40, 0x0f, 0x15, 0x1a, 0x1a, 0x22, 0x27, 0x12, 0x07, 0x0d, 0x12, 0x05, ++ 0x05, 0x3e, 0x1d, 0x15, 0x40, 0x0f, 0x15, 0x1a, 0x00, 0x15, 0x03, 0x00, 0x00, 0x15, 0x40, 0x40, ++ 0x40, 0x40, 0x40, 0x40, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x07, 0x3e, 0x01, 0x44, 0x59, 0x40, 0x1e, 0x01, 0x41, 0x23, 0x40, 0x44, 0x40, 0x40, 0x11, 0x0f, ++ 0x44, 0x58, 0x40, 0x0b, 0x5b, 0x58, 0x55, 0x4f, 0x4f, 0x07, 0x07, 0x0c, 0x3e, 0x14, 0x06, 0x07, ++ 0x5e, 0x27, 0x43, 0x14, 0x40, 0x04, 0x16, 0x40, 0x40, 0x40, 0x44, 0x44, 0x51, 0x56, 0x49, 0x56, ++ 0x5b, 0x53, 0x51, 0x5e, 0x5e, 0x58, 0x51, 0x59, 0x5e, 0x5e, 0x58, 0x46, 0x41, 0x4b, 0x51, 0x56, ++ 0x49, 0x56, 0x5b, 0x53, 0x51, 0x5e, 0x5e, 0x58, 0x51, 0x59, 0x5e, 0x5e, 0x58, 0x46, 0x41, 0x4b, ++ 0x0e, 0x4c, 0x45, 0x40, 0x43, 0x40, 0x44, 0x07, 0x44, 0x41, 0x41, 0x55, 0x49, 0x1c, 0x11, 0x4c, ++ 0x13, 0x07, 0x40, 0x1c, 0x11, 0x4c, 0x13, 0x07, 0x40, 0x1c, 0x11, 0x4c, 0x13, 0x07, 0x40, 0x43, ++ 0x07, 0x03, 0x03, 0x06, 0x0e, 0x06, 0x0e, 0x14, 0x17, 0x11, 0x4c, 0x17, 0x11, 0x4c, 0x40, 0x40, ++ 0x40, 0x26, 0x14, 0x14, 0x40, 0x0f, 0x14, 0x19, 0x19, 0x23, 0x27, 0x13, 0x07, 0x0e, 0x13, 0x06, ++ 0x04, 0x3e, 0x1c, 0x14, 0x40, 0x0f, 0x14, 0x19, 0x01, 0x14, 0x04, 0x01, 0x01, 0x14, 0x40, 0x40, ++ 0x40, 0x40, 0x40, 0x40, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x07, 0x3e, 0x02, 0x44, 0x59, 0x40, 0x1d, 0x01, 0x42, 0x23, 0x40, 0x44, 0x40, 0x40, 0x11, 0x0f, ++ 0x44, 0x56, 0x40, 0x0b, 0x5a, 0x56, 0x53, 0x4c, 0x4c, 0x07, 0x07, 0x0c, 0x3e, 0x14, 0x06, 0x07, ++ 0x5d, 0x27, 0x42, 0x14, 0x40, 0x04, 0x15, 0x40, 0x40, 0x40, 0x44, 0x44, 0x51, 0x55, 0x49, 0x55, ++ 0x5a, 0x52, 0x51, 0x5d, 0x5d, 0x56, 0x51, 0x59, 0x5d, 0x5d, 0x56, 0x45, 0x41, 0x4a, 0x51, 0x55, ++ 0x49, 0x55, 0x5a, 0x52, 0x51, 0x5d, 0x5d, 0x56, 0x51, 0x59, 0x5d, 0x5d, 0x56, 0x45, 0x41, 0x4a, ++ 0x0e, 0x4c, 0x43, 0x40, 0x43, 0x40, 0x44, 0x07, 0x44, 0x41, 0x41, 0x53, 0x49, 0x1c, 0x11, 0x4c, ++ 0x13, 0x07, 0x40, 0x1c, 0x11, 0x4c, 0x13, 0x07, 0x40, 0x1c, 0x11, 0x4c, 0x13, 0x07, 0x40, 0x43, ++ 0x07, 0x03, 0x03, 0x06, 0x0e, 0x06, 0x0e, 0x14, 0x17, 0x11, 0x4c, 0x17, 0x11, 0x4c, 0x40, 0x40, ++ 0x40, 0x25, 0x14, 0x14, 0x40, 0x0f, 0x14, 0x19, 0x19, 0x23, 0x27, 0x13, 0x07, 0x0e, 0x13, 0x06, ++ 0x04, 0x3e, 0x1c, 0x14, 0x40, 0x0f, 0x14, 0x19, 0x02, 0x14, 0x05, 0x02, 0x02, 0x14, 0x40, 0x40, ++ 0x40, 0x40, 0x40, 0x40, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x07, 0x3e, 0x03, 0x44, 0x58, 0x40, 0x1c, 0x00, 0x43, 0x23, 0x40, 0x44, 0x40, 0x40, 0x10, 0x0f, ++ 0x44, 0x55, 0x40, 0x0b, 0x59, 0x55, 0x51, 0x4a, 0x4a, 0x07, 0x07, 0x0c, 0x3d, 0x14, 0x07, 0x07, ++ 0x5c, 0x27, 0x41, 0x14, 0x40, 0x04, 0x14, 0x40, 0x40, 0x40, 0x44, 0x44, 0x50, 0x54, 0x48, 0x54, ++ 0x59, 0x51, 0x50, 0x5c, 0x5c, 0x55, 0x50, 0x58, 0x5c, 0x5c, 0x55, 0x44, 0x40, 0x49, 0x50, 0x54, ++ 0x48, 0x54, 0x59, 0x51, 0x50, 0x5c, 0x5c, 0x55, 0x50, 0x58, 0x5c, 0x5c, 0x55, 0x44, 0x40, 0x49, ++ 0x0f, 0x4c, 0x41, 0x40, 0x43, 0x40, 0x44, 0x07, 0x44, 0x40, 0x40, 0x51, 0x48, 0x1c, 0x10, 0x4c, ++ 0x13, 0x07, 0x40, 0x1c, 0x10, 0x4c, 0x13, 0x07, 0x40, 0x1c, 0x10, 0x4c, 0x13, 0x07, 0x40, 0x43, ++ 0x07, 0x03, 0x03, 0x07, 0x0f, 0x07, 0x0f, 0x14, 0x17, 0x10, 0x4c, 0x17, 0x10, 0x4c, 0x40, 0x40, ++ 0x40, 0x24, 0x14, 0x14, 0x40, 0x0f, 0x14, 0x18, 0x18, 0x23, 0x27, 0x13, 0x07, 0x0f, 0x13, 0x07, ++ 0x04, 0x3e, 0x1c, 0x14, 0x40, 0x0f, 0x14, 0x18, 0x03, 0x14, 0x06, 0x03, 0x03, 0x14, 0x40, 0x40, ++ 0x40, 0x40, 0x40, 0x40, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x07, 0x3e, 0x04, 0x43, 0x57, 0x40, 0x1b, 0x40, 0x44, 0x24, 0x40, 0x43, 0x40, 0x40, 0x0f, 0x0f, ++ 0x43, 0x53, 0x40, 0x0c, 0x57, 0x53, 0x4f, 0x47, 0x47, 0x07, 0x07, 0x0b, 0x3b, 0x13, 0x08, 0x07, ++ 0x5b, 0x27, 0x00, 0x13, 0x40, 0x03, 0x13, 0x40, 0x40, 0x40, 0x43, 0x43, 0x4f, 0x53, 0x47, 0x53, ++ 0x57, 0x4f, 0x4f, 0x5b, 0x5b, 0x53, 0x4f, 0x57, 0x5b, 0x5b, 0x53, 0x43, 0x00, 0x47, 0x4f, 0x53, ++ 0x47, 0x53, 0x57, 0x4f, 0x4f, 0x5b, 0x5b, 0x53, 0x4f, 0x57, 0x5b, 0x5b, 0x53, 0x43, 0x00, 0x47, ++ 0x10, 0x4b, 0x00, 0x40, 0x44, 0x40, 0x43, 0x07, 0x43, 0x00, 0x00, 0x4f, 0x47, 0x1b, 0x0f, 0x4b, ++ 0x14, 0x07, 0x40, 0x1b, 0x0f, 0x4b, 0x14, 0x07, 0x40, 0x1b, 0x0f, 0x4b, 0x14, 0x07, 0x40, 0x44, ++ 0x07, 0x04, 0x04, 0x08, 0x10, 0x08, 0x10, 0x13, 0x17, 0x0f, 0x4b, 0x17, 0x0f, 0x4b, 0x40, 0x40, ++ 0x40, 0x23, 0x13, 0x13, 0x40, 0x0f, 0x13, 0x17, 0x17, 0x24, 0x27, 0x14, 0x07, 0x10, 0x14, 0x08, ++ 0x03, 0x3e, 0x1b, 0x13, 0x40, 0x0f, 0x13, 0x17, 0x04, 0x13, 0x08, 0x04, 0x04, 0x13, 0x40, 0x40, ++ 0x40, 0x40, 0x40, 0x40, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x07, 0x3e, 0x05, 0x43, 0x57, 0x40, 0x1a, 0x40, 0x45, 0x24, 0x40, 0x43, 0x40, 0x40, 0x0f, 0x0f, ++ 0x43, 0x52, 0x40, 0x0c, 0x56, 0x52, 0x4d, 0x45, 0x45, 0x07, 0x07, 0x0b, 0x3a, 0x13, 0x08, 0x07, ++ 0x5a, 0x27, 0x01, 0x13, 0x40, 0x03, 0x12, 0x40, 0x40, 0x40, 0x43, 0x43, 0x4f, 0x52, 0x47, 0x52, ++ 0x56, 0x4e, 0x4f, 0x5a, 0x5a, 0x52, 0x4f, 0x57, 0x5a, 0x5a, 0x52, 0x42, 0x00, 0x46, 0x4f, 0x52, ++ 0x47, 0x52, 0x56, 0x4e, 0x4f, 0x5a, 0x5a, 0x52, 0x4f, 0x57, 0x5a, 0x5a, 0x52, 0x42, 0x00, 0x46, ++ 0x10, 0x4b, 0x02, 0x40, 0x44, 0x40, 0x43, 0x07, 0x43, 0x00, 0x00, 0x4d, 0x47, 0x1b, 0x0f, 0x4b, ++ 0x14, 0x07, 0x40, 0x1b, 0x0f, 0x4b, 0x14, 0x07, 0x40, 0x1b, 0x0f, 0x4b, 0x14, 0x07, 0x40, 0x44, ++ 0x07, 0x04, 0x04, 0x08, 0x10, 0x08, 0x10, 0x13, 0x17, 0x0f, 0x4b, 0x17, 0x0f, 0x4b, 0x40, 0x40, ++ 0x40, 0x22, 0x13, 0x13, 0x40, 0x0f, 0x13, 0x17, 0x17, 0x24, 0x27, 0x14, 0x07, 0x10, 0x14, 0x08, ++ 0x03, 0x3e, 0x1b, 0x13, 0x40, 0x0f, 0x13, 0x17, 0x05, 0x13, 0x09, 0x05, 0x05, 0x13, 0x40, 0x40, ++ 0x40, 0x40, 0x40, 0x40, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x07, 0x3e, 0x06, 0x43, 0x56, 0x40, 0x19, 0x41, 0x46, 0x24, 0x40, 0x43, 0x40, 0x40, 0x0e, 0x0f, ++ 0x43, 0x50, 0x40, 0x0c, 0x55, 0x50, 0x4b, 0x42, 0x42, 0x07, 0x07, 0x0b, 0x38, 0x13, 0x09, 0x07, ++ 0x59, 0x27, 0x02, 0x13, 0x40, 0x03, 0x11, 0x40, 0x40, 0x40, 0x43, 0x43, 0x4e, 0x51, 0x46, 0x51, ++ 0x55, 0x4d, 0x4e, 0x59, 0x59, 0x50, 0x4e, 0x56, 0x59, 0x59, 0x50, 0x41, 0x01, 0x45, 0x4e, 0x51, ++ 0x46, 0x51, 0x55, 0x4d, 0x4e, 0x59, 0x59, 0x50, 0x4e, 0x56, 0x59, 0x59, 0x50, 0x41, 0x01, 0x45, ++ 0x11, 0x4b, 0x04, 0x40, 0x44, 0x40, 0x43, 0x07, 0x43, 0x01, 0x01, 0x4b, 0x46, 0x1b, 0x0e, 0x4b, ++ 0x14, 0x07, 0x40, 0x1b, 0x0e, 0x4b, 0x14, 0x07, 0x40, 0x1b, 0x0e, 0x4b, 0x14, 0x07, 0x40, 0x44, ++ 0x07, 0x04, 0x04, 0x09, 0x11, 0x09, 0x11, 0x13, 0x17, 0x0e, 0x4b, 0x17, 0x0e, 0x4b, 0x40, 0x40, ++ 0x40, 0x21, 0x13, 0x13, 0x40, 0x0f, 0x13, 0x16, 0x16, 0x24, 0x27, 0x14, 0x07, 0x11, 0x14, 0x09, ++ 0x03, 0x3d, 0x1b, 0x13, 0x40, 0x0f, 0x13, 0x16, 0x06, 0x13, 0x0a, 0x06, 0x06, 0x13, 0x40, 0x40, ++ 0x40, 0x40, 0x40, 0x40, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x07, 0x3e, 0x06, 0x43, 0x56, 0x40, 0x18, 0x42, 0x47, 0x24, 0x40, 0x43, 0x40, 0x40, 0x0d, 0x0f, ++ 0x43, 0x4f, 0x40, 0x0c, 0x54, 0x4f, 0x4a, 0x40, 0x40, 0x07, 0x07, 0x0a, 0x36, 0x12, 0x09, 0x07, ++ 0x59, 0x27, 0x03, 0x12, 0x40, 0x02, 0x10, 0x40, 0x40, 0x40, 0x43, 0x43, 0x4e, 0x51, 0x46, 0x51, ++ 0x54, 0x4c, 0x4e, 0x59, 0x59, 0x4f, 0x4e, 0x56, 0x59, 0x59, 0x4f, 0x41, 0x01, 0x44, 0x4e, 0x51, ++ 0x46, 0x51, 0x54, 0x4c, 0x4e, 0x59, 0x59, 0x4f, 0x4e, 0x56, 0x59, 0x59, 0x4f, 0x41, 0x01, 0x44, ++ 0x11, 0x4b, 0x05, 0x40, 0x45, 0x40, 0x43, 0x07, 0x43, 0x01, 0x01, 0x4a, 0x46, 0x1a, 0x0d, 0x4b, ++ 0x14, 0x07, 0x40, 0x1a, 0x0d, 0x4b, 0x14, 0x07, 0x40, 0x1a, 0x0d, 0x4b, 0x14, 0x07, 0x40, 0x45, ++ 0x07, 0x04, 0x04, 0x09, 0x11, 0x09, 0x11, 0x12, 0x17, 0x0d, 0x4b, 0x17, 0x0d, 0x4b, 0x40, 0x40, ++ 0x40, 0x20, 0x12, 0x12, 0x40, 0x0f, 0x12, 0x15, 0x15, 0x24, 0x27, 0x14, 0x07, 0x11, 0x14, 0x09, ++ 0x02, 0x3b, 0x1a, 0x12, 0x40, 0x0f, 0x12, 0x15, 0x06, 0x12, 0x0b, 0x06, 0x06, 0x12, 0x40, 0x40, ++ 0x40, 0x40, 0x40, 0x40, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x07, 0x3e, 0x07, 0x42, 0x55, 0x40, 0x18, 0x42, 0x47, 0x25, 0x40, 0x42, 0x40, 0x40, 0x0d, 0x0f, ++ 0x42, 0x4d, 0x40, 0x0d, 0x52, 0x4d, 0x48, 0x02, 0x02, 0x07, 0x07, 0x0a, 0x35, 0x12, 0x0a, 0x07, ++ 0x58, 0x27, 0x05, 0x12, 0x40, 0x02, 0x10, 0x40, 0x40, 0x40, 0x42, 0x42, 0x4d, 0x50, 0x45, 0x50, ++ 0x52, 0x4a, 0x4d, 0x58, 0x58, 0x4d, 0x4d, 0x55, 0x58, 0x58, 0x4d, 0x40, 0x02, 0x42, 0x4d, 0x50, ++ 0x45, 0x50, 0x52, 0x4a, 0x4d, 0x58, 0x58, 0x4d, 0x4d, 0x55, 0x58, 0x58, 0x4d, 0x40, 0x02, 0x42, ++ 0x12, 0x4a, 0x07, 0x40, 0x45, 0x40, 0x42, 0x07, 0x42, 0x02, 0x02, 0x48, 0x45, 0x1a, 0x0d, 0x4a, ++ 0x15, 0x07, 0x40, 0x1a, 0x0d, 0x4a, 0x15, 0x07, 0x40, 0x1a, 0x0d, 0x4a, 0x15, 0x07, 0x40, 0x45, ++ 0x07, 0x05, 0x05, 0x0a, 0x12, 0x0a, 0x12, 0x12, 0x17, 0x0d, 0x4a, 0x17, 0x0d, 0x4a, 0x40, 0x40, ++ 0x40, 0x20, 0x12, 0x12, 0x40, 0x0f, 0x12, 0x15, 0x15, 0x25, 0x27, 0x15, 0x07, 0x12, 0x15, 0x0a, ++ 0x02, 0x3a, 0x1a, 0x12, 0x40, 0x0f, 0x12, 0x15, 0x07, 0x12, 0x0d, 0x07, 0x07, 0x12, 0x40, 0x40, ++ 0x40, 0x40, 0x40, 0x40, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x07, 0x3e, 0x08, 0x42, 0x54, 0x40, 0x17, 0x43, 0x48, 0x25, 0x40, 0x42, 0x40, 0x40, 0x0c, 0x0f, ++ 0x42, 0x4b, 0x40, 0x0d, 0x51, 0x4b, 0x46, 0x04, 0x04, 0x07, 0x07, 0x0a, 0x33, 0x12, 0x0b, 0x07, ++ 0x57, 0x27, 0x06, 0x12, 0x40, 0x02, 0x0f, 0x40, 0x40, 0x40, 0x42, 0x42, 0x4c, 0x4f, 0x44, 0x4f, ++ 0x51, 0x49, 0x4c, 0x57, 0x57, 0x4b, 0x4c, 0x54, 0x57, 0x57, 0x4b, 0x00, 0x03, 0x41, 0x4c, 0x4f, ++ 0x44, 0x4f, 0x51, 0x49, 0x4c, 0x57, 0x57, 0x4b, 0x4c, 0x54, 0x57, 0x57, 0x4b, 0x00, 0x03, 0x41, ++ 0x13, 0x4a, 0x09, 0x40, 0x45, 0x40, 0x42, 0x07, 0x42, 0x03, 0x03, 0x46, 0x44, 0x1a, 0x0c, 0x4a, ++ 0x15, 0x07, 0x40, 0x1a, 0x0c, 0x4a, 0x15, 0x07, 0x40, 0x1a, 0x0c, 0x4a, 0x15, 0x07, 0x40, 0x45, ++ 0x07, 0x05, 0x05, 0x0b, 0x13, 0x0b, 0x13, 0x12, 0x17, 0x0c, 0x4a, 0x17, 0x0c, 0x4a, 0x40, 0x40, ++ 0x40, 0x1f, 0x12, 0x12, 0x40, 0x0f, 0x12, 0x14, 0x14, 0x25, 0x27, 0x15, 0x07, 0x13, 0x15, 0x0b, ++ 0x02, 0x39, 0x1a, 0x12, 0x40, 0x0f, 0x12, 0x14, 0x08, 0x12, 0x0e, 0x08, 0x08, 0x12, 0x40, 0x40, ++ 0x40, 0x40, 0x40, 0x40, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x07, 0x3e, 0x09, 0x42, 0x54, 0x40, 0x16, 0x43, 0x49, 0x25, 0x40, 0x42, 0x40, 0x40, 0x0c, 0x0f, ++ 0x42, 0x4a, 0x40, 0x0d, 0x50, 0x4a, 0x44, 0x07, 0x07, 0x07, 0x07, 0x0a, 0x32, 0x12, 0x0b, 0x07, ++ 0x56, 0x27, 0x07, 0x12, 0x40, 0x02, 0x0e, 0x40, 0x40, 0x40, 0x42, 0x42, 0x4c, 0x4e, 0x44, 0x4e, ++ 0x50, 0x48, 0x4c, 0x56, 0x56, 0x4a, 0x4c, 0x54, 0x56, 0x56, 0x4a, 0x01, 0x03, 0x40, 0x4c, 0x4e, ++ 0x44, 0x4e, 0x50, 0x48, 0x4c, 0x56, 0x56, 0x4a, 0x4c, 0x54, 0x56, 0x56, 0x4a, 0x01, 0x03, 0x40, ++ 0x13, 0x4a, 0x0b, 0x40, 0x45, 0x40, 0x42, 0x07, 0x42, 0x03, 0x03, 0x44, 0x44, 0x1a, 0x0c, 0x4a, ++ 0x15, 0x07, 0x40, 0x1a, 0x0c, 0x4a, 0x15, 0x07, 0x40, 0x1a, 0x0c, 0x4a, 0x15, 0x07, 0x40, 0x45, ++ 0x07, 0x05, 0x05, 0x0b, 0x13, 0x0b, 0x13, 0x12, 0x17, 0x0c, 0x4a, 0x17, 0x0c, 0x4a, 0x40, 0x40, ++ 0x40, 0x1e, 0x12, 0x12, 0x40, 0x0f, 0x12, 0x14, 0x14, 0x25, 0x27, 0x15, 0x07, 0x13, 0x15, 0x0b, ++ 0x02, 0x38, 0x1a, 0x12, 0x40, 0x0f, 0x12, 0x14, 0x09, 0x12, 0x0f, 0x09, 0x09, 0x12, 0x40, 0x40, ++ 0x40, 0x40, 0x40, 0x40, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x07, 0x3e, 0x0a, 0x41, 0x53, 0x40, 0x15, 0x44, 0x4a, 0x26, 0x40, 0x41, 0x40, 0x40, 0x0b, 0x0f, ++ 0x41, 0x48, 0x40, 0x0e, 0x4f, 0x48, 0x42, 0x09, 0x09, 0x07, 0x07, 0x09, 0x30, 0x11, 0x0c, 0x07, ++ 0x55, 0x27, 0x08, 0x11, 0x40, 0x01, 0x0d, 0x40, 0x40, 0x40, 0x41, 0x41, 0x4b, 0x4d, 0x43, 0x4d, ++ 0x4f, 0x47, 0x4b, 0x55, 0x55, 0x48, 0x4b, 0x53, 0x55, 0x55, 0x48, 0x02, 0x04, 0x00, 0x4b, 0x4d, ++ 0x43, 0x4d, 0x4f, 0x47, 0x4b, 0x55, 0x55, 0x48, 0x4b, 0x53, 0x55, 0x55, 0x48, 0x02, 0x04, 0x00, ++ 0x14, 0x49, 0x0d, 0x40, 0x46, 0x40, 0x41, 0x07, 0x41, 0x04, 0x04, 0x42, 0x43, 0x19, 0x0b, 0x49, ++ 0x16, 0x07, 0x40, 0x19, 0x0b, 0x49, 0x16, 0x07, 0x40, 0x19, 0x0b, 0x49, 0x16, 0x07, 0x40, 0x46, ++ 0x07, 0x06, 0x06, 0x0c, 0x14, 0x0c, 0x14, 0x11, 0x17, 0x0b, 0x49, 0x17, 0x0b, 0x49, 0x40, 0x40, ++ 0x40, 0x1d, 0x11, 0x11, 0x40, 0x0f, 0x11, 0x13, 0x13, 0x26, 0x27, 0x16, 0x07, 0x14, 0x16, 0x0c, ++ 0x01, 0x36, 0x19, 0x11, 0x40, 0x0f, 0x11, 0x13, 0x0a, 0x11, 0x10, 0x0a, 0x0a, 0x11, 0x40, 0x40, ++ 0x40, 0x40, 0x40, 0x40, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x07, 0x3e, 0x0b, 0x41, 0x52, 0x40, 0x14, 0x45, 0x4b, 0x26, 0x40, 0x41, 0x40, 0x40, 0x0a, 0x0f, ++ 0x41, 0x47, 0x40, 0x0e, 0x4d, 0x47, 0x40, 0x0c, 0x0c, 0x07, 0x07, 0x09, 0x2f, 0x11, 0x0d, 0x07, ++ 0x54, 0x27, 0x0a, 0x11, 0x40, 0x01, 0x0c, 0x40, 0x40, 0x40, 0x41, 0x41, 0x4a, 0x4c, 0x42, 0x4c, ++ 0x4d, 0x45, 0x4a, 0x54, 0x54, 0x47, 0x4a, 0x52, 0x54, 0x54, 0x47, 0x03, 0x05, 0x02, 0x4a, 0x4c, ++ 0x42, 0x4c, 0x4d, 0x45, 0x4a, 0x54, 0x54, 0x47, 0x4a, 0x52, 0x54, 0x54, 0x47, 0x03, 0x05, 0x02, ++ 0x15, 0x49, 0x0f, 0x40, 0x46, 0x40, 0x41, 0x07, 0x41, 0x05, 0x05, 0x40, 0x42, 0x19, 0x0a, 0x49, ++ 0x16, 0x07, 0x40, 0x19, 0x0a, 0x49, 0x16, 0x07, 0x40, 0x19, 0x0a, 0x49, 0x16, 0x07, 0x40, 0x46, ++ 0x07, 0x06, 0x06, 0x0d, 0x15, 0x0d, 0x15, 0x11, 0x17, 0x0a, 0x49, 0x17, 0x0a, 0x49, 0x40, 0x40, ++ 0x40, 0x1c, 0x11, 0x11, 0x40, 0x0f, 0x11, 0x12, 0x12, 0x26, 0x27, 0x16, 0x07, 0x15, 0x16, 0x0d, ++ 0x01, 0x35, 0x19, 0x11, 0x40, 0x0f, 0x11, 0x12, 0x0b, 0x11, 0x12, 0x0b, 0x0b, 0x11, 0x40, 0x40, ++ 0x40, 0x40, 0x40, 0x40, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x07, 0x3e, 0x0c, 0x41, 0x52, 0x40, 0x13, 0x45, 0x4c, 0x26, 0x40, 0x41, 0x40, 0x40, 0x0a, 0x0f, ++ 0x41, 0x45, 0x40, 0x0e, 0x4c, 0x45, 0x01, 0x0e, 0x0e, 0x07, 0x07, 0x09, 0x2d, 0x11, 0x0d, 0x07, ++ 0x53, 0x27, 0x0b, 0x11, 0x40, 0x01, 0x0b, 0x40, 0x40, 0x40, 0x41, 0x41, 0x4a, 0x4b, 0x42, 0x4b, ++ 0x4c, 0x44, 0x4a, 0x53, 0x53, 0x45, 0x4a, 0x52, 0x53, 0x53, 0x45, 0x04, 0x05, 0x03, 0x4a, 0x4b, ++ 0x42, 0x4b, 0x4c, 0x44, 0x4a, 0x53, 0x53, 0x45, 0x4a, 0x52, 0x53, 0x53, 0x45, 0x04, 0x05, 0x03, ++ 0x15, 0x49, 0x11, 0x40, 0x46, 0x40, 0x41, 0x07, 0x41, 0x05, 0x05, 0x01, 0x42, 0x19, 0x0a, 0x49, ++ 0x16, 0x07, 0x40, 0x19, 0x0a, 0x49, 0x16, 0x07, 0x40, 0x19, 0x0a, 0x49, 0x16, 0x07, 0x40, 0x46, ++ 0x07, 0x06, 0x06, 0x0d, 0x15, 0x0d, 0x15, 0x11, 0x17, 0x0a, 0x49, 0x17, 0x0a, 0x49, 0x40, 0x40, ++ 0x40, 0x1b, 0x11, 0x11, 0x40, 0x0f, 0x11, 0x12, 0x12, 0x26, 0x27, 0x16, 0x07, 0x15, 0x16, 0x0d, ++ 0x01, 0x34, 0x19, 0x11, 0x40, 0x0f, 0x11, 0x12, 0x0c, 0x11, 0x13, 0x0c, 0x0c, 0x11, 0x40, 0x40, ++ 0x40, 0x40, 0x40, 0x40, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x07, 0x3e, 0x0d, 0x40, 0x51, 0x40, 0x12, 0x46, 0x4d, 0x27, 0x40, 0x40, 0x40, 0x40, 0x09, 0x0f, ++ 0x40, 0x44, 0x40, 0x0f, 0x4b, 0x44, 0x03, 0x11, 0x11, 0x07, 0x07, 0x08, 0x2c, 0x10, 0x0e, 0x07, ++ 0x52, 0x27, 0x0c, 0x10, 0x40, 0x00, 0x0a, 0x40, 0x40, 0x40, 0x40, 0x40, 0x49, 0x4a, 0x41, 0x4a, ++ 0x4b, 0x43, 0x49, 0x52, 0x52, 0x44, 0x49, 0x51, 0x52, 0x52, 0x44, 0x05, 0x06, 0x04, 0x49, 0x4a, ++ 0x41, 0x4a, 0x4b, 0x43, 0x49, 0x52, 0x52, 0x44, 0x49, 0x51, 0x52, 0x52, 0x44, 0x05, 0x06, 0x04, ++ 0x16, 0x48, 0x13, 0x40, 0x47, 0x40, 0x40, 0x07, 0x40, 0x06, 0x06, 0x03, 0x41, 0x18, 0x09, 0x48, ++ 0x17, 0x07, 0x40, 0x18, 0x09, 0x48, 0x17, 0x07, 0x40, 0x18, 0x09, 0x48, 0x17, 0x07, 0x40, 0x47, ++ 0x07, 0x07, 0x07, 0x0e, 0x16, 0x0e, 0x16, 0x10, 0x17, 0x09, 0x48, 0x17, 0x09, 0x48, 0x40, 0x40, ++ 0x40, 0x1a, 0x10, 0x10, 0x40, 0x0f, 0x10, 0x11, 0x11, 0x27, 0x27, 0x17, 0x07, 0x16, 0x17, 0x0e, ++ 0x00, 0x33, 0x18, 0x10, 0x40, 0x0f, 0x10, 0x11, 0x0d, 0x10, 0x14, 0x0d, 0x0d, 0x10, 0x40, 0x40, ++ 0x40, 0x40, 0x40, 0x40, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x07, 0x3e, 0x0e, 0x40, 0x51, 0x40, 0x11, 0x47, 0x4e, 0x27, 0x40, 0x40, 0x40, 0x40, 0x08, 0x0f, ++ 0x40, 0x42, 0x40, 0x0f, 0x4a, 0x42, 0x04, 0x13, 0x13, 0x07, 0x07, 0x08, 0x2a, 0x10, 0x0e, 0x07, ++ 0x51, 0x27, 0x0d, 0x10, 0x40, 0x00, 0x09, 0x40, 0x40, 0x40, 0x40, 0x40, 0x49, 0x49, 0x41, 0x49, ++ 0x4a, 0x42, 0x49, 0x51, 0x51, 0x42, 0x49, 0x51, 0x51, 0x51, 0x42, 0x06, 0x06, 0x05, 0x49, 0x49, ++ 0x41, 0x49, 0x4a, 0x42, 0x49, 0x51, 0x51, 0x42, 0x49, 0x51, 0x51, 0x51, 0x42, 0x06, 0x06, 0x05, ++ 0x16, 0x48, 0x14, 0x40, 0x47, 0x40, 0x40, 0x07, 0x40, 0x06, 0x06, 0x04, 0x41, 0x18, 0x08, 0x48, ++ 0x17, 0x07, 0x40, 0x18, 0x08, 0x48, 0x17, 0x07, 0x40, 0x18, 0x08, 0x48, 0x17, 0x07, 0x40, 0x47, ++ 0x07, 0x07, 0x07, 0x0e, 0x16, 0x0e, 0x16, 0x10, 0x17, 0x08, 0x48, 0x17, 0x08, 0x48, 0x40, 0x40, ++ 0x40, 0x19, 0x10, 0x10, 0x40, 0x0f, 0x10, 0x10, 0x10, 0x27, 0x27, 0x17, 0x07, 0x16, 0x17, 0x0e, ++ 0x00, 0x31, 0x18, 0x10, 0x40, 0x0f, 0x10, 0x10, 0x0e, 0x10, 0x15, 0x0e, 0x0e, 0x10, 0x40, 0x40, ++ 0x40, 0x40, 0x40, 0x40, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x07, 0x3e, 0x0f, 0x40, 0x50, 0x40, 0x10, 0x47, 0x4f, 0x27, 0x40, 0x40, 0x40, 0x40, 0x08, 0x0f, ++ 0x40, 0x40, 0x40, 0x0f, 0x48, 0x40, 0x06, 0x16, 0x16, 0x07, 0x07, 0x08, 0x28, 0x10, 0x0f, 0x07, ++ 0x50, 0x27, 0x0f, 0x10, 0x40, 0x00, 0x08, 0x40, 0x40, 0x40, 0x40, 0x40, 0x48, 0x48, 0x40, 0x48, ++ 0x48, 0x40, 0x48, 0x50, 0x50, 0x40, 0x48, 0x50, 0x50, 0x50, 0x40, 0x07, 0x07, 0x07, 0x48, 0x48, ++ 0x40, 0x48, 0x48, 0x40, 0x48, 0x50, 0x50, 0x40, 0x48, 0x50, 0x50, 0x50, 0x40, 0x07, 0x07, 0x07, ++ 0x17, 0x48, 0x16, 0x40, 0x47, 0x40, 0x40, 0x07, 0x40, 0x07, 0x07, 0x06, 0x40, 0x18, 0x08, 0x48, ++ 0x17, 0x07, 0x40, 0x18, 0x08, 0x48, 0x17, 0x07, 0x40, 0x18, 0x08, 0x48, 0x17, 0x07, 0x40, 0x47, ++ 0x07, 0x07, 0x07, 0x0f, 0x17, 0x0f, 0x17, 0x10, 0x17, 0x08, 0x48, 0x17, 0x08, 0x48, 0x40, 0x40, ++ 0x40, 0x18, 0x10, 0x10, 0x40, 0x0f, 0x10, 0x10, 0x10, 0x27, 0x27, 0x17, 0x07, 0x17, 0x17, 0x0f, ++ 0x00, 0x30, 0x18, 0x10, 0x40, 0x0f, 0x10, 0x10, 0x0f, 0x10, 0x17, 0x0f, 0x0f, 0x10, 0x40, 0x40, ++ 0x40, 0x40, 0x40, 0x40, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x07, 0x3e, 0x10, 0x00, 0x4f, 0x40, 0x0f, 0x48, 0x50, 0x28, 0x40, 0x00, 0x40, 0x40, 0x07, 0x0f, ++ 0x00, 0x00, 0x40, 0x10, 0x47, 0x00, 0x08, 0x18, 0x18, 0x07, 0x07, 0x07, 0x27, 0x0f, 0x10, 0x07, ++ 0x4f, 0x27, 0x10, 0x0f, 0x40, 0x40, 0x07, 0x40, 0x40, 0x40, 0x00, 0x00, 0x47, 0x47, 0x00, 0x47, ++ 0x47, 0x00, 0x47, 0x4f, 0x4f, 0x00, 0x47, 0x4f, 0x4f, 0x4f, 0x00, 0x08, 0x08, 0x08, 0x47, 0x47, ++ 0x00, 0x47, 0x47, 0x00, 0x47, 0x4f, 0x4f, 0x00, 0x47, 0x4f, 0x4f, 0x4f, 0x00, 0x08, 0x08, 0x08, ++ 0x18, 0x47, 0x18, 0x40, 0x48, 0x40, 0x00, 0x07, 0x00, 0x08, 0x08, 0x08, 0x00, 0x17, 0x07, 0x47, ++ 0x18, 0x07, 0x40, 0x17, 0x07, 0x47, 0x18, 0x07, 0x40, 0x17, 0x07, 0x47, 0x18, 0x07, 0x40, 0x48, ++ 0x07, 0x08, 0x08, 0x10, 0x18, 0x10, 0x18, 0x0f, 0x17, 0x07, 0x47, 0x17, 0x07, 0x47, 0x40, 0x40, ++ 0x40, 0x17, 0x0f, 0x0f, 0x40, 0x0f, 0x0f, 0x0f, 0x0f, 0x28, 0x27, 0x18, 0x07, 0x18, 0x18, 0x10, ++ 0x40, 0x2f, 0x17, 0x0f, 0x40, 0x0f, 0x0f, 0x0f, 0x10, 0x0f, 0x18, 0x10, 0x10, 0x0f, 0x40, 0x40, ++ 0x40, 0x40, 0x40, 0x40, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x07, 0x3e, 0x11, 0x00, 0x4f, 0x40, 0x0e, 0x48, 0x51, 0x28, 0x40, 0x00, 0x40, 0x40, 0x07, 0x0f, ++ 0x00, 0x02, 0x40, 0x10, 0x46, 0x02, 0x0a, 0x1b, 0x1b, 0x07, 0x07, 0x07, 0x25, 0x0f, 0x10, 0x07, ++ 0x4e, 0x27, 0x11, 0x0f, 0x40, 0x40, 0x06, 0x40, 0x40, 0x40, 0x00, 0x00, 0x47, 0x46, 0x00, 0x46, ++ 0x46, 0x01, 0x47, 0x4e, 0x4e, 0x02, 0x47, 0x4f, 0x4e, 0x4e, 0x02, 0x09, 0x08, 0x09, 0x47, 0x46, ++ 0x00, 0x46, 0x46, 0x01, 0x47, 0x4e, 0x4e, 0x02, 0x47, 0x4f, 0x4e, 0x4e, 0x02, 0x09, 0x08, 0x09, ++ 0x18, 0x47, 0x1a, 0x40, 0x48, 0x40, 0x00, 0x07, 0x00, 0x08, 0x08, 0x0a, 0x00, 0x17, 0x07, 0x47, ++ 0x18, 0x07, 0x40, 0x17, 0x07, 0x47, 0x18, 0x07, 0x40, 0x17, 0x07, 0x47, 0x18, 0x07, 0x40, 0x48, ++ 0x07, 0x08, 0x08, 0x10, 0x18, 0x10, 0x18, 0x0f, 0x17, 0x07, 0x47, 0x17, 0x07, 0x47, 0x40, 0x40, ++ 0x40, 0x16, 0x0f, 0x0f, 0x40, 0x0f, 0x0f, 0x0f, 0x0f, 0x28, 0x27, 0x18, 0x07, 0x18, 0x18, 0x10, ++ 0x40, 0x2e, 0x17, 0x0f, 0x40, 0x0f, 0x0f, 0x0f, 0x11, 0x0f, 0x19, 0x11, 0x11, 0x0f, 0x40, 0x40, ++ 0x40, 0x40, 0x40, 0x40, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x07, 0x3e, 0x12, 0x00, 0x4e, 0x40, 0x0d, 0x49, 0x52, 0x28, 0x40, 0x00, 0x40, 0x40, 0x06, 0x0f, ++ 0x00, 0x03, 0x40, 0x10, 0x45, 0x03, 0x0c, 0x1d, 0x1d, 0x07, 0x07, 0x07, 0x24, 0x0f, 0x11, 0x07, ++ 0x4d, 0x27, 0x12, 0x0f, 0x40, 0x40, 0x05, 0x40, 0x40, 0x40, 0x00, 0x00, 0x46, 0x45, 0x01, 0x45, ++ 0x45, 0x02, 0x46, 0x4d, 0x4d, 0x03, 0x46, 0x4e, 0x4d, 0x4d, 0x03, 0x0a, 0x09, 0x0a, 0x46, 0x45, ++ 0x01, 0x45, 0x45, 0x02, 0x46, 0x4d, 0x4d, 0x03, 0x46, 0x4e, 0x4d, 0x4d, 0x03, 0x0a, 0x09, 0x0a, ++ 0x19, 0x47, 0x1c, 0x40, 0x48, 0x40, 0x00, 0x07, 0x00, 0x09, 0x09, 0x0c, 0x01, 0x17, 0x06, 0x47, ++ 0x18, 0x07, 0x40, 0x17, 0x06, 0x47, 0x18, 0x07, 0x40, 0x17, 0x06, 0x47, 0x18, 0x07, 0x40, 0x48, ++ 0x07, 0x08, 0x08, 0x11, 0x19, 0x11, 0x19, 0x0f, 0x17, 0x06, 0x47, 0x17, 0x06, 0x47, 0x40, 0x40, ++ 0x40, 0x15, 0x0f, 0x0f, 0x40, 0x0f, 0x0f, 0x0e, 0x0e, 0x28, 0x27, 0x18, 0x07, 0x19, 0x18, 0x11, ++ 0x40, 0x2c, 0x17, 0x0f, 0x40, 0x0f, 0x0f, 0x0e, 0x12, 0x0f, 0x1a, 0x12, 0x12, 0x0f, 0x40, 0x40, ++ 0x40, 0x40, 0x40, 0x40, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x07, 0x3e, 0x13, 0x01, 0x4d, 0x40, 0x0c, 0x4a, 0x53, 0x29, 0x40, 0x01, 0x40, 0x40, 0x05, 0x0f, ++ 0x01, 0x05, 0x40, 0x11, 0x43, 0x05, 0x0e, 0x20, 0x20, 0x07, 0x07, 0x06, 0x22, 0x0e, 0x12, 0x07, ++ 0x4c, 0x27, 0x14, 0x0e, 0x40, 0x41, 0x04, 0x40, 0x40, 0x40, 0x01, 0x01, 0x45, 0x44, 0x02, 0x44, ++ 0x43, 0x04, 0x45, 0x4c, 0x4c, 0x05, 0x45, 0x4d, 0x4c, 0x4c, 0x05, 0x0b, 0x0a, 0x0c, 0x45, 0x44, ++ 0x02, 0x44, 0x43, 0x04, 0x45, 0x4c, 0x4c, 0x05, 0x45, 0x4d, 0x4c, 0x4c, 0x05, 0x0b, 0x0a, 0x0c, ++ 0x1a, 0x46, 0x1e, 0x40, 0x49, 0x40, 0x01, 0x07, 0x01, 0x0a, 0x0a, 0x0e, 0x02, 0x16, 0x05, 0x46, ++ 0x19, 0x07, 0x40, 0x16, 0x05, 0x46, 0x19, 0x07, 0x40, 0x16, 0x05, 0x46, 0x19, 0x07, 0x40, 0x49, ++ 0x07, 0x09, 0x09, 0x12, 0x1a, 0x12, 0x1a, 0x0e, 0x17, 0x05, 0x46, 0x17, 0x05, 0x46, 0x40, 0x40, ++ 0x40, 0x14, 0x0e, 0x0e, 0x40, 0x0f, 0x0e, 0x0d, 0x0d, 0x29, 0x27, 0x19, 0x07, 0x1a, 0x19, 0x12, ++ 0x41, 0x2b, 0x16, 0x0e, 0x40, 0x0f, 0x0e, 0x0d, 0x13, 0x0e, 0x1c, 0x13, 0x13, 0x0e, 0x40, 0x40, ++ 0x40, 0x40, 0x40, 0x40, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x07, 0x3e, 0x14, 0x01, 0x4d, 0x40, 0x0b, 0x4a, 0x54, 0x29, 0x40, 0x01, 0x40, 0x40, 0x05, 0x0f, ++ 0x01, 0x06, 0x40, 0x11, 0x42, 0x06, 0x10, 0x22, 0x22, 0x07, 0x07, 0x06, 0x21, 0x0e, 0x12, 0x07, ++ 0x4b, 0x27, 0x15, 0x0e, 0x40, 0x41, 0x03, 0x40, 0x40, 0x40, 0x01, 0x01, 0x45, 0x43, 0x02, 0x43, ++ 0x42, 0x05, 0x45, 0x4b, 0x4b, 0x06, 0x45, 0x4d, 0x4b, 0x4b, 0x06, 0x0c, 0x0a, 0x0d, 0x45, 0x43, ++ 0x02, 0x43, 0x42, 0x05, 0x45, 0x4b, 0x4b, 0x06, 0x45, 0x4d, 0x4b, 0x4b, 0x06, 0x0c, 0x0a, 0x0d, ++ 0x1a, 0x46, 0x20, 0x40, 0x49, 0x40, 0x01, 0x07, 0x01, 0x0a, 0x0a, 0x10, 0x02, 0x16, 0x05, 0x46, ++ 0x19, 0x07, 0x40, 0x16, 0x05, 0x46, 0x19, 0x07, 0x40, 0x16, 0x05, 0x46, 0x19, 0x07, 0x40, 0x49, ++ 0x07, 0x09, 0x09, 0x12, 0x1a, 0x12, 0x1a, 0x0e, 0x17, 0x05, 0x46, 0x17, 0x05, 0x46, 0x40, 0x40, ++ 0x40, 0x13, 0x0e, 0x0e, 0x40, 0x0f, 0x0e, 0x0d, 0x0d, 0x29, 0x27, 0x19, 0x07, 0x1a, 0x19, 0x12, ++ 0x41, 0x2a, 0x16, 0x0e, 0x40, 0x0f, 0x0e, 0x0d, 0x14, 0x0e, 0x1d, 0x14, 0x14, 0x0e, 0x40, 0x40, ++ 0x40, 0x40, 0x40, 0x40, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x07, 0x3e, 0x15, 0x01, 0x4c, 0x40, 0x0a, 0x4b, 0x55, 0x29, 0x40, 0x01, 0x40, 0x40, 0x04, 0x0f, ++ 0x01, 0x08, 0x40, 0x11, 0x41, 0x08, 0x12, 0x25, 0x25, 0x07, 0x07, 0x06, 0x1f, 0x0e, 0x13, 0x07, ++ 0x4a, 0x27, 0x16, 0x0e, 0x40, 0x41, 0x02, 0x40, 0x40, 0x40, 0x01, 0x01, 0x44, 0x42, 0x03, 0x42, ++ 0x41, 0x06, 0x44, 0x4a, 0x4a, 0x08, 0x44, 0x4c, 0x4a, 0x4a, 0x08, 0x0d, 0x0b, 0x0e, 0x44, 0x42, ++ 0x03, 0x42, 0x41, 0x06, 0x44, 0x4a, 0x4a, 0x08, 0x44, 0x4c, 0x4a, 0x4a, 0x08, 0x0d, 0x0b, 0x0e, ++ 0x1b, 0x46, 0x22, 0x40, 0x49, 0x40, 0x01, 0x07, 0x01, 0x0b, 0x0b, 0x12, 0x03, 0x16, 0x04, 0x46, ++ 0x19, 0x07, 0x40, 0x16, 0x04, 0x46, 0x19, 0x07, 0x40, 0x16, 0x04, 0x46, 0x19, 0x07, 0x40, 0x49, ++ 0x07, 0x09, 0x09, 0x13, 0x1b, 0x13, 0x1b, 0x0e, 0x17, 0x04, 0x46, 0x17, 0x04, 0x46, 0x40, 0x40, ++ 0x40, 0x12, 0x0e, 0x0e, 0x40, 0x0f, 0x0e, 0x0c, 0x0c, 0x29, 0x27, 0x19, 0x07, 0x1b, 0x19, 0x13, ++ 0x41, 0x29, 0x16, 0x0e, 0x40, 0x0f, 0x0e, 0x0c, 0x15, 0x0e, 0x1e, 0x15, 0x15, 0x0e, 0x40, 0x40, ++ 0x40, 0x40, 0x40, 0x40, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x07, 0x3e, 0x15, 0x01, 0x4c, 0x40, 0x09, 0x4c, 0x56, 0x29, 0x40, 0x01, 0x40, 0x40, 0x03, 0x0f, ++ 0x01, 0x09, 0x40, 0x11, 0x40, 0x09, 0x13, 0x27, 0x27, 0x07, 0x07, 0x05, 0x1d, 0x0d, 0x13, 0x07, ++ 0x4a, 0x27, 0x17, 0x0d, 0x40, 0x42, 0x01, 0x40, 0x40, 0x40, 0x01, 0x01, 0x44, 0x42, 0x03, 0x42, ++ 0x40, 0x07, 0x44, 0x4a, 0x4a, 0x09, 0x44, 0x4c, 0x4a, 0x4a, 0x09, 0x0d, 0x0b, 0x0f, 0x44, 0x42, ++ 0x03, 0x42, 0x40, 0x07, 0x44, 0x4a, 0x4a, 0x09, 0x44, 0x4c, 0x4a, 0x4a, 0x09, 0x0d, 0x0b, 0x0f, ++ 0x1b, 0x46, 0x23, 0x40, 0x4a, 0x40, 0x01, 0x07, 0x01, 0x0b, 0x0b, 0x13, 0x03, 0x15, 0x03, 0x46, ++ 0x19, 0x07, 0x40, 0x15, 0x03, 0x46, 0x19, 0x07, 0x40, 0x15, 0x03, 0x46, 0x19, 0x07, 0x40, 0x4a, ++ 0x07, 0x09, 0x09, 0x13, 0x1b, 0x13, 0x1b, 0x0d, 0x17, 0x03, 0x46, 0x17, 0x03, 0x46, 0x40, 0x40, ++ 0x40, 0x11, 0x0d, 0x0d, 0x40, 0x0f, 0x0d, 0x0b, 0x0b, 0x29, 0x27, 0x19, 0x07, 0x1b, 0x19, 0x13, ++ 0x42, 0x27, 0x15, 0x0d, 0x40, 0x0f, 0x0d, 0x0b, 0x15, 0x0d, 0x1f, 0x15, 0x15, 0x0d, 0x40, 0x40, ++ 0x40, 0x40, 0x40, 0x40, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x07, 0x3e, 0x16, 0x02, 0x4b, 0x40, 0x09, 0x4c, 0x56, 0x2a, 0x40, 0x02, 0x40, 0x40, 0x03, 0x0f, ++ 0x02, 0x0b, 0x40, 0x12, 0x01, 0x0b, 0x15, 0x2a, 0x2a, 0x07, 0x07, 0x05, 0x1c, 0x0d, 0x14, 0x07, ++ 0x49, 0x27, 0x19, 0x0d, 0x40, 0x42, 0x01, 0x40, 0x40, 0x40, 0x02, 0x02, 0x43, 0x41, 0x04, 0x41, ++ 0x01, 0x09, 0x43, 0x49, 0x49, 0x0b, 0x43, 0x4b, 0x49, 0x49, 0x0b, 0x0e, 0x0c, 0x11, 0x43, 0x41, ++ 0x04, 0x41, 0x01, 0x09, 0x43, 0x49, 0x49, 0x0b, 0x43, 0x4b, 0x49, 0x49, 0x0b, 0x0e, 0x0c, 0x11, ++ 0x1c, 0x45, 0x25, 0x40, 0x4a, 0x40, 0x02, 0x07, 0x02, 0x0c, 0x0c, 0x15, 0x04, 0x15, 0x03, 0x45, ++ 0x1a, 0x07, 0x40, 0x15, 0x03, 0x45, 0x1a, 0x07, 0x40, 0x15, 0x03, 0x45, 0x1a, 0x07, 0x40, 0x4a, ++ 0x07, 0x0a, 0x0a, 0x14, 0x1c, 0x14, 0x1c, 0x0d, 0x17, 0x03, 0x45, 0x17, 0x03, 0x45, 0x40, 0x40, ++ 0x40, 0x11, 0x0d, 0x0d, 0x40, 0x0f, 0x0d, 0x0b, 0x0b, 0x2a, 0x27, 0x1a, 0x07, 0x1c, 0x1a, 0x14, ++ 0x42, 0x26, 0x15, 0x0d, 0x40, 0x0f, 0x0d, 0x0b, 0x16, 0x0d, 0x21, 0x16, 0x16, 0x0d, 0x40, 0x40, ++ 0x40, 0x40, 0x40, 0x40, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x07, 0x3e, 0x17, 0x02, 0x4a, 0x40, 0x08, 0x4d, 0x57, 0x2a, 0x40, 0x02, 0x40, 0x40, 0x02, 0x0f, ++ 0x02, 0x0d, 0x40, 0x12, 0x02, 0x0d, 0x17, 0x2c, 0x2c, 0x07, 0x07, 0x05, 0x1a, 0x0d, 0x15, 0x07, ++ 0x48, 0x27, 0x1a, 0x0d, 0x40, 0x42, 0x00, 0x40, 0x40, 0x40, 0x02, 0x02, 0x42, 0x40, 0x05, 0x40, ++ 0x02, 0x0a, 0x42, 0x48, 0x48, 0x0d, 0x42, 0x4a, 0x48, 0x48, 0x0d, 0x0f, 0x0d, 0x12, 0x42, 0x40, ++ 0x05, 0x40, 0x02, 0x0a, 0x42, 0x48, 0x48, 0x0d, 0x42, 0x4a, 0x48, 0x48, 0x0d, 0x0f, 0x0d, 0x12, ++ 0x1d, 0x45, 0x27, 0x40, 0x4a, 0x40, 0x02, 0x07, 0x02, 0x0d, 0x0d, 0x17, 0x05, 0x15, 0x02, 0x45, ++ 0x1a, 0x07, 0x40, 0x15, 0x02, 0x45, 0x1a, 0x07, 0x40, 0x15, 0x02, 0x45, 0x1a, 0x07, 0x40, 0x4a, ++ 0x07, 0x0a, 0x0a, 0x15, 0x1d, 0x15, 0x1d, 0x0d, 0x17, 0x02, 0x45, 0x17, 0x02, 0x45, 0x40, 0x40, ++ 0x40, 0x10, 0x0d, 0x0d, 0x40, 0x0f, 0x0d, 0x0a, 0x0a, 0x2a, 0x27, 0x1a, 0x07, 0x1d, 0x1a, 0x15, ++ 0x42, 0x25, 0x15, 0x0d, 0x40, 0x0f, 0x0d, 0x0a, 0x17, 0x0d, 0x22, 0x17, 0x17, 0x0d, 0x40, 0x40, ++ 0x40, 0x40, 0x40, 0x40, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x07, 0x3e, 0x18, 0x02, 0x4a, 0x40, 0x07, 0x4d, 0x58, 0x2a, 0x40, 0x02, 0x40, 0x40, 0x02, 0x0f, ++ 0x02, 0x0e, 0x40, 0x12, 0x03, 0x0e, 0x19, 0x2f, 0x2f, 0x07, 0x07, 0x05, 0x19, 0x0d, 0x15, 0x07, ++ 0x47, 0x27, 0x1b, 0x0d, 0x40, 0x42, 0x40, 0x40, 0x40, 0x40, 0x02, 0x02, 0x42, 0x00, 0x05, 0x00, ++ 0x03, 0x0b, 0x42, 0x47, 0x47, 0x0e, 0x42, 0x4a, 0x47, 0x47, 0x0e, 0x10, 0x0d, 0x13, 0x42, 0x00, ++ 0x05, 0x00, 0x03, 0x0b, 0x42, 0x47, 0x47, 0x0e, 0x42, 0x4a, 0x47, 0x47, 0x0e, 0x10, 0x0d, 0x13, ++ 0x1d, 0x45, 0x29, 0x40, 0x4a, 0x40, 0x02, 0x07, 0x02, 0x0d, 0x0d, 0x19, 0x05, 0x15, 0x02, 0x45, ++ 0x1a, 0x07, 0x40, 0x15, 0x02, 0x45, 0x1a, 0x07, 0x40, 0x15, 0x02, 0x45, 0x1a, 0x07, 0x40, 0x4a, ++ 0x07, 0x0a, 0x0a, 0x15, 0x1d, 0x15, 0x1d, 0x0d, 0x17, 0x02, 0x45, 0x17, 0x02, 0x45, 0x40, 0x40, ++ 0x40, 0x0f, 0x0d, 0x0d, 0x40, 0x0f, 0x0d, 0x0a, 0x0a, 0x2a, 0x27, 0x1a, 0x07, 0x1d, 0x1a, 0x15, ++ 0x42, 0x24, 0x15, 0x0d, 0x40, 0x0f, 0x0d, 0x0a, 0x18, 0x0d, 0x23, 0x18, 0x18, 0x0d, 0x40, 0x40, ++ 0x40, 0x40, 0x40, 0x40, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x07, 0x3e, 0x19, 0x03, 0x49, 0x40, 0x06, 0x4e, 0x59, 0x2b, 0x40, 0x03, 0x40, 0x40, 0x01, 0x0f, ++ 0x03, 0x10, 0x40, 0x13, 0x04, 0x10, 0x1b, 0x31, 0x31, 0x07, 0x07, 0x04, 0x17, 0x0c, 0x16, 0x07, ++ 0x46, 0x27, 0x1c, 0x0c, 0x40, 0x43, 0x41, 0x40, 0x40, 0x40, 0x03, 0x03, 0x41, 0x01, 0x06, 0x01, ++ 0x04, 0x0c, 0x41, 0x46, 0x46, 0x10, 0x41, 0x49, 0x46, 0x46, 0x10, 0x11, 0x0e, 0x14, 0x41, 0x01, ++ 0x06, 0x01, 0x04, 0x0c, 0x41, 0x46, 0x46, 0x10, 0x41, 0x49, 0x46, 0x46, 0x10, 0x11, 0x0e, 0x14, ++ 0x1e, 0x44, 0x2b, 0x40, 0x4b, 0x40, 0x03, 0x07, 0x03, 0x0e, 0x0e, 0x1b, 0x06, 0x14, 0x01, 0x44, ++ 0x1b, 0x07, 0x40, 0x14, 0x01, 0x44, 0x1b, 0x07, 0x40, 0x14, 0x01, 0x44, 0x1b, 0x07, 0x40, 0x4b, ++ 0x07, 0x0b, 0x0b, 0x16, 0x1e, 0x16, 0x1e, 0x0c, 0x17, 0x01, 0x44, 0x17, 0x01, 0x44, 0x40, 0x40, ++ 0x40, 0x0e, 0x0c, 0x0c, 0x40, 0x0f, 0x0c, 0x09, 0x09, 0x2b, 0x27, 0x1b, 0x07, 0x1e, 0x1b, 0x16, ++ 0x43, 0x22, 0x14, 0x0c, 0x40, 0x0f, 0x0c, 0x09, 0x19, 0x0c, 0x24, 0x19, 0x19, 0x0c, 0x40, 0x40, ++ 0x40, 0x40, 0x40, 0x40, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x07, 0x3e, 0x1a, 0x03, 0x48, 0x40, 0x05, 0x4f, 0x5a, 0x2b, 0x40, 0x03, 0x40, 0x40, 0x00, 0x0f, ++ 0x03, 0x11, 0x40, 0x13, 0x06, 0x11, 0x1d, 0x34, 0x34, 0x07, 0x07, 0x04, 0x16, 0x0c, 0x17, 0x07, ++ 0x45, 0x27, 0x1e, 0x0c, 0x40, 0x43, 0x42, 0x40, 0x40, 0x40, 0x03, 0x03, 0x40, 0x02, 0x07, 0x02, ++ 0x06, 0x0e, 0x40, 0x45, 0x45, 0x11, 0x40, 0x48, 0x45, 0x45, 0x11, 0x12, 0x0f, 0x16, 0x40, 0x02, ++ 0x07, 0x02, 0x06, 0x0e, 0x40, 0x45, 0x45, 0x11, 0x40, 0x48, 0x45, 0x45, 0x11, 0x12, 0x0f, 0x16, ++ 0x1f, 0x44, 0x2d, 0x40, 0x4b, 0x40, 0x03, 0x07, 0x03, 0x0f, 0x0f, 0x1d, 0x07, 0x14, 0x00, 0x44, ++ 0x1b, 0x07, 0x40, 0x14, 0x00, 0x44, 0x1b, 0x07, 0x40, 0x14, 0x00, 0x44, 0x1b, 0x07, 0x40, 0x4b, ++ 0x07, 0x0b, 0x0b, 0x17, 0x1f, 0x17, 0x1f, 0x0c, 0x17, 0x00, 0x44, 0x17, 0x00, 0x44, 0x40, 0x40, ++ 0x40, 0x0d, 0x0c, 0x0c, 0x40, 0x0f, 0x0c, 0x08, 0x08, 0x2b, 0x27, 0x1b, 0x07, 0x1f, 0x1b, 0x17, ++ 0x43, 0x21, 0x14, 0x0c, 0x40, 0x0f, 0x0c, 0x08, 0x1a, 0x0c, 0x26, 0x1a, 0x1a, 0x0c, 0x40, 0x40, ++ 0x40, 0x40, 0x40, 0x40, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x07, 0x3e, 0x1b, 0x03, 0x48, 0x40, 0x04, 0x4f, 0x5b, 0x2b, 0x40, 0x03, 0x40, 0x40, 0x00, 0x0f, ++ 0x03, 0x13, 0x40, 0x13, 0x07, 0x13, 0x1f, 0x36, 0x36, 0x07, 0x07, 0x04, 0x14, 0x0c, 0x17, 0x07, ++ 0x44, 0x27, 0x1f, 0x0c, 0x40, 0x43, 0x43, 0x40, 0x40, 0x40, 0x03, 0x03, 0x40, 0x03, 0x07, 0x03, ++ 0x07, 0x0f, 0x40, 0x44, 0x44, 0x13, 0x40, 0x48, 0x44, 0x44, 0x13, 0x13, 0x0f, 0x17, 0x40, 0x03, ++ 0x07, 0x03, 0x07, 0x0f, 0x40, 0x44, 0x44, 0x13, 0x40, 0x48, 0x44, 0x44, 0x13, 0x13, 0x0f, 0x17, ++ 0x1f, 0x44, 0x2f, 0x40, 0x4b, 0x40, 0x03, 0x07, 0x03, 0x0f, 0x0f, 0x1f, 0x07, 0x14, 0x00, 0x44, ++ 0x1b, 0x07, 0x40, 0x14, 0x00, 0x44, 0x1b, 0x07, 0x40, 0x14, 0x00, 0x44, 0x1b, 0x07, 0x40, 0x4b, ++ 0x07, 0x0b, 0x0b, 0x17, 0x1f, 0x17, 0x1f, 0x0c, 0x17, 0x00, 0x44, 0x17, 0x00, 0x44, 0x40, 0x40, ++ 0x40, 0x0c, 0x0c, 0x0c, 0x40, 0x0f, 0x0c, 0x08, 0x08, 0x2b, 0x27, 0x1b, 0x07, 0x1f, 0x1b, 0x17, ++ 0x43, 0x20, 0x14, 0x0c, 0x40, 0x0f, 0x0c, 0x08, 0x1b, 0x0c, 0x27, 0x1b, 0x1b, 0x0c, 0x40, 0x40, ++ 0x40, 0x40, 0x40, 0x40, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x07, 0x3e, 0x1c, 0x04, 0x47, 0x40, 0x03, 0x50, 0x5c, 0x2c, 0x40, 0x04, 0x40, 0x40, 0x40, 0x0f, ++ 0x04, 0x14, 0x40, 0x14, 0x08, 0x14, 0x21, 0x39, 0x39, 0x07, 0x07, 0x03, 0x13, 0x0b, 0x18, 0x07, ++ 0x43, 0x27, 0x20, 0x0b, 0x40, 0x44, 0x44, 0x40, 0x40, 0x40, 0x04, 0x04, 0x00, 0x04, 0x08, 0x04, ++ 0x08, 0x10, 0x00, 0x43, 0x43, 0x14, 0x00, 0x47, 0x43, 0x43, 0x14, 0x14, 0x10, 0x18, 0x00, 0x04, ++ 0x08, 0x04, 0x08, 0x10, 0x00, 0x43, 0x43, 0x14, 0x00, 0x47, 0x43, 0x43, 0x14, 0x14, 0x10, 0x18, ++ 0x20, 0x43, 0x31, 0x40, 0x4c, 0x40, 0x04, 0x07, 0x04, 0x10, 0x10, 0x21, 0x08, 0x13, 0x40, 0x43, ++ 0x1c, 0x07, 0x40, 0x13, 0x40, 0x43, 0x1c, 0x07, 0x40, 0x13, 0x40, 0x43, 0x1c, 0x07, 0x40, 0x4c, ++ 0x07, 0x0c, 0x0c, 0x18, 0x20, 0x18, 0x20, 0x0b, 0x17, 0x40, 0x43, 0x17, 0x40, 0x43, 0x40, 0x40, ++ 0x40, 0x0b, 0x0b, 0x0b, 0x40, 0x0f, 0x0b, 0x07, 0x07, 0x2c, 0x27, 0x1c, 0x07, 0x20, 0x1c, 0x18, ++ 0x44, 0x1f, 0x13, 0x0b, 0x40, 0x0f, 0x0b, 0x07, 0x1c, 0x0b, 0x28, 0x1c, 0x1c, 0x0b, 0x40, 0x40, ++ 0x40, 0x40, 0x40, 0x40, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x07, 0x3e, 0x1d, 0x04, 0x47, 0x40, 0x02, 0x51, 0x5d, 0x2c, 0x40, 0x04, 0x40, 0x40, 0x41, 0x0f, ++ 0x04, 0x16, 0x40, 0x14, 0x09, 0x16, 0x22, 0x3b, 0x3b, 0x07, 0x07, 0x03, 0x11, 0x0b, 0x18, 0x07, ++ 0x42, 0x27, 0x21, 0x0b, 0x40, 0x44, 0x45, 0x40, 0x40, 0x40, 0x04, 0x04, 0x00, 0x05, 0x08, 0x05, ++ 0x09, 0x11, 0x00, 0x42, 0x42, 0x16, 0x00, 0x47, 0x42, 0x42, 0x16, 0x15, 0x10, 0x19, 0x00, 0x05, ++ 0x08, 0x05, 0x09, 0x11, 0x00, 0x42, 0x42, 0x16, 0x00, 0x47, 0x42, 0x42, 0x16, 0x15, 0x10, 0x19, ++ 0x20, 0x43, 0x32, 0x40, 0x4c, 0x40, 0x04, 0x07, 0x04, 0x10, 0x10, 0x22, 0x08, 0x13, 0x41, 0x43, ++ 0x1c, 0x07, 0x40, 0x13, 0x41, 0x43, 0x1c, 0x07, 0x40, 0x13, 0x41, 0x43, 0x1c, 0x07, 0x40, 0x4c, ++ 0x07, 0x0c, 0x0c, 0x18, 0x20, 0x18, 0x20, 0x0b, 0x17, 0x41, 0x43, 0x17, 0x41, 0x43, 0x40, 0x40, ++ 0x40, 0x0a, 0x0b, 0x0b, 0x40, 0x0f, 0x0b, 0x06, 0x06, 0x2c, 0x27, 0x1c, 0x07, 0x20, 0x1c, 0x18, ++ 0x44, 0x1d, 0x13, 0x0b, 0x40, 0x0f, 0x0b, 0x06, 0x1d, 0x0b, 0x29, 0x1d, 0x1d, 0x0b, 0x40, 0x40, ++ 0x40, 0x40, 0x40, 0x40, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x07, 0x3e, 0x1e, 0x04, 0x46, 0x40, 0x01, 0x51, 0x5e, 0x2c, 0x40, 0x04, 0x40, 0x40, 0x41, 0x0f, ++ 0x04, 0x18, 0x40, 0x14, 0x0b, 0x18, 0x24, 0x3e, 0x3e, 0x07, 0x07, 0x03, 0x0f, 0x0b, 0x19, 0x07, ++ 0x41, 0x27, 0x23, 0x0b, 0x40, 0x44, 0x46, 0x40, 0x40, 0x40, 0x04, 0x04, 0x01, 0x06, 0x09, 0x06, ++ 0x0b, 0x13, 0x01, 0x41, 0x41, 0x18, 0x01, 0x46, 0x41, 0x41, 0x18, 0x16, 0x11, 0x1b, 0x01, 0x06, ++ 0x09, 0x06, 0x0b, 0x13, 0x01, 0x41, 0x41, 0x18, 0x01, 0x46, 0x41, 0x41, 0x18, 0x16, 0x11, 0x1b, ++ 0x21, 0x43, 0x34, 0x40, 0x4c, 0x40, 0x04, 0x07, 0x04, 0x11, 0x11, 0x24, 0x09, 0x13, 0x41, 0x43, ++ 0x1c, 0x07, 0x40, 0x13, 0x41, 0x43, 0x1c, 0x07, 0x40, 0x13, 0x41, 0x43, 0x1c, 0x07, 0x40, 0x4c, ++ 0x07, 0x0c, 0x0c, 0x19, 0x21, 0x19, 0x21, 0x0b, 0x17, 0x41, 0x43, 0x17, 0x41, 0x43, 0x40, 0x40, ++ 0x40, 0x09, 0x0b, 0x0b, 0x40, 0x0f, 0x0b, 0x06, 0x06, 0x2c, 0x27, 0x1c, 0x07, 0x21, 0x1c, 0x19, ++ 0x44, 0x1c, 0x13, 0x0b, 0x40, 0x0f, 0x0b, 0x06, 0x1e, 0x0b, 0x2b, 0x1e, 0x1e, 0x0b, 0x40, 0x40, ++ 0x40, 0x40, 0x40, 0x40, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x07, 0x3e, 0x1f, 0x05, 0x45, 0x40, 0x00, 0x52, 0x5f, 0x2d, 0x40, 0x05, 0x40, 0x40, 0x42, 0x0f, ++ 0x05, 0x19, 0x40, 0x15, 0x0c, 0x19, 0x26, 0x3e, 0x3e, 0x07, 0x07, 0x02, 0x0e, 0x0a, 0x1a, 0x07, ++ 0x40, 0x27, 0x24, 0x0a, 0x40, 0x45, 0x47, 0x40, 0x40, 0x40, 0x05, 0x05, 0x02, 0x07, 0x0a, 0x07, ++ 0x0c, 0x14, 0x02, 0x40, 0x40, 0x19, 0x02, 0x45, 0x40, 0x40, 0x19, 0x17, 0x12, 0x1c, 0x02, 0x07, ++ 0x0a, 0x07, 0x0c, 0x14, 0x02, 0x40, 0x40, 0x19, 0x02, 0x45, 0x40, 0x40, 0x19, 0x17, 0x12, 0x1c, ++ 0x22, 0x42, 0x36, 0x40, 0x4d, 0x40, 0x05, 0x07, 0x05, 0x12, 0x12, 0x26, 0x0a, 0x12, 0x42, 0x42, ++ 0x1d, 0x07, 0x40, 0x12, 0x42, 0x42, 0x1d, 0x07, 0x40, 0x12, 0x42, 0x42, 0x1d, 0x07, 0x40, 0x4d, ++ 0x07, 0x0d, 0x0d, 0x1a, 0x22, 0x1a, 0x22, 0x0a, 0x17, 0x42, 0x42, 0x17, 0x42, 0x42, 0x40, 0x40, ++ 0x40, 0x08, 0x0a, 0x0a, 0x40, 0x0f, 0x0a, 0x05, 0x05, 0x2d, 0x27, 0x1d, 0x07, 0x22, 0x1d, 0x1a, ++ 0x45, 0x1b, 0x12, 0x0a, 0x40, 0x0f, 0x0a, 0x05, 0x1f, 0x0a, 0x2c, 0x1f, 0x1f, 0x0a, 0x40, 0x40, ++ 0x40, 0x40, 0x40, 0x40, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x07, 0x3e, 0x20, 0x05, 0x45, 0x40, 0x40, 0x52, 0x60, 0x2d, 0x40, 0x05, 0x40, 0x40, 0x42, 0x0f, ++ 0x05, 0x1b, 0x40, 0x15, 0x0d, 0x1b, 0x28, 0x3e, 0x3e, 0x07, 0x07, 0x02, 0x0c, 0x0a, 0x1a, 0x07, ++ 0x00, 0x27, 0x25, 0x0a, 0x40, 0x45, 0x48, 0x40, 0x40, 0x40, 0x05, 0x05, 0x02, 0x08, 0x0a, 0x08, ++ 0x0d, 0x15, 0x02, 0x00, 0x00, 0x1b, 0x02, 0x45, 0x00, 0x00, 0x1b, 0x18, 0x12, 0x1d, 0x02, 0x08, ++ 0x0a, 0x08, 0x0d, 0x15, 0x02, 0x00, 0x00, 0x1b, 0x02, 0x45, 0x00, 0x00, 0x1b, 0x18, 0x12, 0x1d, ++ 0x22, 0x42, 0x38, 0x40, 0x4d, 0x40, 0x05, 0x07, 0x05, 0x12, 0x12, 0x28, 0x0a, 0x12, 0x42, 0x42, ++ 0x1d, 0x07, 0x40, 0x12, 0x42, 0x42, 0x1d, 0x07, 0x40, 0x12, 0x42, 0x42, 0x1d, 0x07, 0x40, 0x4d, ++ 0x07, 0x0d, 0x0d, 0x1a, 0x22, 0x1a, 0x22, 0x0a, 0x17, 0x42, 0x42, 0x17, 0x42, 0x42, 0x40, 0x40, ++ 0x40, 0x07, 0x0a, 0x0a, 0x40, 0x0f, 0x0a, 0x05, 0x05, 0x2d, 0x27, 0x1d, 0x07, 0x22, 0x1d, 0x1a, ++ 0x45, 0x1a, 0x12, 0x0a, 0x40, 0x0f, 0x0a, 0x05, 0x20, 0x0a, 0x2d, 0x20, 0x20, 0x0a, 0x40, 0x40, ++ 0x40, 0x40, 0x40, 0x40, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x07, 0x3e, 0x21, 0x05, 0x44, 0x40, 0x41, 0x53, 0x61, 0x2d, 0x40, 0x05, 0x40, 0x40, 0x43, 0x0f, ++ 0x05, 0x1c, 0x40, 0x15, 0x0e, 0x1c, 0x2a, 0x3e, 0x3e, 0x07, 0x07, 0x02, 0x0b, 0x0a, 0x1b, 0x07, ++ 0x01, 0x27, 0x26, 0x0a, 0x40, 0x45, 0x49, 0x40, 0x40, 0x40, 0x05, 0x05, 0x03, 0x09, 0x0b, 0x09, ++ 0x0e, 0x16, 0x03, 0x01, 0x01, 0x1c, 0x03, 0x44, 0x01, 0x01, 0x1c, 0x19, 0x13, 0x1e, 0x03, 0x09, ++ 0x0b, 0x09, 0x0e, 0x16, 0x03, 0x01, 0x01, 0x1c, 0x03, 0x44, 0x01, 0x01, 0x1c, 0x19, 0x13, 0x1e, ++ 0x23, 0x42, 0x3a, 0x40, 0x4d, 0x40, 0x05, 0x07, 0x05, 0x13, 0x13, 0x2a, 0x0b, 0x12, 0x43, 0x42, ++ 0x1d, 0x07, 0x40, 0x12, 0x43, 0x42, 0x1d, 0x07, 0x40, 0x12, 0x43, 0x42, 0x1d, 0x07, 0x40, 0x4d, ++ 0x07, 0x0d, 0x0d, 0x1b, 0x23, 0x1b, 0x23, 0x0a, 0x17, 0x43, 0x42, 0x17, 0x43, 0x42, 0x40, 0x40, ++ 0x40, 0x06, 0x0a, 0x0a, 0x40, 0x0f, 0x0a, 0x04, 0x04, 0x2d, 0x27, 0x1d, 0x07, 0x23, 0x1d, 0x1b, ++ 0x45, 0x18, 0x12, 0x0a, 0x40, 0x0f, 0x0a, 0x04, 0x21, 0x0a, 0x2e, 0x21, 0x21, 0x0a, 0x40, 0x40, ++ 0x40, 0x40, 0x40, 0x40, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x07, 0x3e, 0x22, 0x06, 0x43, 0x40, 0x42, 0x54, 0x62, 0x2e, 0x40, 0x06, 0x40, 0x40, 0x44, 0x0f, ++ 0x06, 0x1e, 0x40, 0x16, 0x10, 0x1e, 0x2c, 0x3e, 0x3e, 0x07, 0x07, 0x01, 0x09, 0x09, 0x1c, 0x07, ++ 0x02, 0x27, 0x28, 0x09, 0x40, 0x46, 0x4a, 0x40, 0x40, 0x40, 0x06, 0x06, 0x04, 0x0a, 0x0c, 0x0a, ++ 0x10, 0x18, 0x04, 0x02, 0x02, 0x1e, 0x04, 0x43, 0x02, 0x02, 0x1e, 0x1a, 0x14, 0x20, 0x04, 0x0a, ++ 0x0c, 0x0a, 0x10, 0x18, 0x04, 0x02, 0x02, 0x1e, 0x04, 0x43, 0x02, 0x02, 0x1e, 0x1a, 0x14, 0x20, ++ 0x24, 0x41, 0x3c, 0x40, 0x4e, 0x40, 0x06, 0x07, 0x06, 0x14, 0x14, 0x2c, 0x0c, 0x11, 0x44, 0x41, ++ 0x1e, 0x07, 0x40, 0x11, 0x44, 0x41, 0x1e, 0x07, 0x40, 0x11, 0x44, 0x41, 0x1e, 0x07, 0x40, 0x4e, ++ 0x07, 0x0e, 0x0e, 0x1c, 0x24, 0x1c, 0x24, 0x09, 0x17, 0x44, 0x41, 0x17, 0x44, 0x41, 0x40, 0x40, ++ 0x40, 0x05, 0x09, 0x09, 0x40, 0x0f, 0x09, 0x03, 0x03, 0x2e, 0x27, 0x1e, 0x07, 0x24, 0x1e, 0x1c, ++ 0x46, 0x17, 0x11, 0x09, 0x40, 0x0f, 0x09, 0x03, 0x22, 0x09, 0x30, 0x22, 0x22, 0x09, 0x40, 0x40, ++ 0x40, 0x40, 0x40, 0x40, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x07, 0x3e, 0x23, 0x06, 0x43, 0x40, 0x43, 0x54, 0x63, 0x2e, 0x40, 0x06, 0x40, 0x40, 0x44, 0x0f, ++ 0x06, 0x1f, 0x40, 0x16, 0x11, 0x1f, 0x2e, 0x3e, 0x3e, 0x07, 0x07, 0x01, 0x08, 0x09, 0x1c, 0x07, ++ 0x03, 0x27, 0x29, 0x09, 0x40, 0x46, 0x4b, 0x40, 0x40, 0x40, 0x06, 0x06, 0x04, 0x0b, 0x0c, 0x0b, ++ 0x11, 0x19, 0x04, 0x03, 0x03, 0x1f, 0x04, 0x43, 0x03, 0x03, 0x1f, 0x1b, 0x14, 0x21, 0x04, 0x0b, ++ 0x0c, 0x0b, 0x11, 0x19, 0x04, 0x03, 0x03, 0x1f, 0x04, 0x43, 0x03, 0x03, 0x1f, 0x1b, 0x14, 0x21, ++ 0x24, 0x41, 0x3e, 0x40, 0x4e, 0x40, 0x06, 0x07, 0x06, 0x14, 0x14, 0x2e, 0x0c, 0x11, 0x44, 0x41, ++ 0x1e, 0x07, 0x40, 0x11, 0x44, 0x41, 0x1e, 0x07, 0x40, 0x11, 0x44, 0x41, 0x1e, 0x07, 0x40, 0x4e, ++ 0x07, 0x0e, 0x0e, 0x1c, 0x24, 0x1c, 0x24, 0x09, 0x17, 0x44, 0x41, 0x17, 0x44, 0x41, 0x40, 0x40, ++ 0x40, 0x04, 0x09, 0x09, 0x40, 0x0f, 0x09, 0x03, 0x03, 0x2e, 0x27, 0x1e, 0x07, 0x24, 0x1e, 0x1c, ++ 0x46, 0x16, 0x11, 0x09, 0x40, 0x0f, 0x09, 0x03, 0x23, 0x09, 0x31, 0x23, 0x23, 0x09, 0x40, 0x40, ++ 0x40, 0x40, 0x40, 0x40, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x07, 0x3e, 0x24, 0x06, 0x42, 0x40, 0x44, 0x55, 0x64, 0x2e, 0x40, 0x06, 0x40, 0x40, 0x45, 0x0f, ++ 0x06, 0x21, 0x40, 0x16, 0x12, 0x21, 0x30, 0x3e, 0x3e, 0x07, 0x07, 0x01, 0x06, 0x09, 0x1d, 0x07, ++ 0x04, 0x27, 0x2a, 0x09, 0x40, 0x46, 0x4c, 0x40, 0x40, 0x40, 0x06, 0x06, 0x05, 0x0c, 0x0d, 0x0c, ++ 0x12, 0x1a, 0x05, 0x04, 0x04, 0x21, 0x05, 0x42, 0x04, 0x04, 0x21, 0x1c, 0x15, 0x22, 0x05, 0x0c, ++ 0x0d, 0x0c, 0x12, 0x1a, 0x05, 0x04, 0x04, 0x21, 0x05, 0x42, 0x04, 0x04, 0x21, 0x1c, 0x15, 0x22, ++ 0x25, 0x41, 0x3e, 0x40, 0x4e, 0x40, 0x06, 0x07, 0x06, 0x15, 0x15, 0x30, 0x0d, 0x11, 0x45, 0x41, ++ 0x1e, 0x07, 0x40, 0x11, 0x45, 0x41, 0x1e, 0x07, 0x40, 0x11, 0x45, 0x41, 0x1e, 0x07, 0x40, 0x4e, ++ 0x07, 0x0e, 0x0e, 0x1d, 0x25, 0x1d, 0x25, 0x09, 0x17, 0x45, 0x41, 0x17, 0x45, 0x41, 0x40, 0x40, ++ 0x40, 0x03, 0x09, 0x09, 0x40, 0x0f, 0x09, 0x02, 0x02, 0x2e, 0x27, 0x1e, 0x07, 0x25, 0x1e, 0x1d, ++ 0x46, 0x15, 0x11, 0x09, 0x40, 0x0f, 0x09, 0x02, 0x24, 0x09, 0x32, 0x24, 0x24, 0x09, 0x40, 0x40, ++ 0x40, 0x40, 0x40, 0x40, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x07, 0x3e, 0x24, 0x06, 0x42, 0x40, 0x45, 0x56, 0x65, 0x2e, 0x40, 0x06, 0x40, 0x40, 0x46, 0x0f, ++ 0x06, 0x22, 0x40, 0x16, 0x13, 0x22, 0x31, 0x3e, 0x3e, 0x07, 0x07, 0x00, 0x04, 0x08, 0x1d, 0x07, ++ 0x04, 0x27, 0x2b, 0x08, 0x40, 0x47, 0x4d, 0x40, 0x40, 0x40, 0x06, 0x06, 0x05, 0x0c, 0x0d, 0x0c, ++ 0x13, 0x1b, 0x05, 0x04, 0x04, 0x22, 0x05, 0x42, 0x04, 0x04, 0x22, 0x1c, 0x15, 0x23, 0x05, 0x0c, ++ 0x0d, 0x0c, 0x13, 0x1b, 0x05, 0x04, 0x04, 0x22, 0x05, 0x42, 0x04, 0x04, 0x22, 0x1c, 0x15, 0x23, ++ 0x25, 0x41, 0x3e, 0x40, 0x4f, 0x40, 0x06, 0x07, 0x06, 0x15, 0x15, 0x31, 0x0d, 0x10, 0x46, 0x41, ++ 0x1e, 0x07, 0x40, 0x10, 0x46, 0x41, 0x1e, 0x07, 0x40, 0x10, 0x46, 0x41, 0x1e, 0x07, 0x40, 0x4f, ++ 0x07, 0x0e, 0x0e, 0x1d, 0x25, 0x1d, 0x25, 0x08, 0x17, 0x46, 0x41, 0x17, 0x46, 0x41, 0x40, 0x40, ++ 0x40, 0x02, 0x08, 0x08, 0x40, 0x0f, 0x08, 0x01, 0x01, 0x2e, 0x27, 0x1e, 0x07, 0x25, 0x1e, 0x1d, ++ 0x47, 0x13, 0x10, 0x08, 0x40, 0x0f, 0x08, 0x01, 0x24, 0x08, 0x33, 0x24, 0x24, 0x08, 0x40, 0x40, ++ 0x40, 0x40, 0x40, 0x40, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x07, 0x3e, 0x25, 0x07, 0x41, 0x40, 0x45, 0x56, 0x65, 0x2f, 0x40, 0x07, 0x40, 0x40, 0x46, 0x0f, ++ 0x07, 0x24, 0x40, 0x17, 0x15, 0x24, 0x33, 0x3e, 0x3e, 0x07, 0x07, 0x00, 0x03, 0x08, 0x1e, 0x07, ++ 0x05, 0x27, 0x2d, 0x08, 0x40, 0x47, 0x4d, 0x40, 0x40, 0x40, 0x07, 0x07, 0x06, 0x0d, 0x0e, 0x0d, ++ 0x15, 0x1d, 0x06, 0x05, 0x05, 0x24, 0x06, 0x41, 0x05, 0x05, 0x24, 0x1d, 0x16, 0x25, 0x06, 0x0d, ++ 0x0e, 0x0d, 0x15, 0x1d, 0x06, 0x05, 0x05, 0x24, 0x06, 0x41, 0x05, 0x05, 0x24, 0x1d, 0x16, 0x25, ++ 0x26, 0x40, 0x3e, 0x40, 0x4f, 0x40, 0x07, 0x07, 0x07, 0x16, 0x16, 0x33, 0x0e, 0x10, 0x46, 0x40, ++ 0x1f, 0x07, 0x40, 0x10, 0x46, 0x40, 0x1f, 0x07, 0x40, 0x10, 0x46, 0x40, 0x1f, 0x07, 0x40, 0x4f, ++ 0x07, 0x0f, 0x0f, 0x1e, 0x26, 0x1e, 0x26, 0x08, 0x17, 0x46, 0x40, 0x17, 0x46, 0x40, 0x40, 0x40, ++ 0x40, 0x02, 0x08, 0x08, 0x40, 0x0f, 0x08, 0x01, 0x01, 0x2f, 0x27, 0x1f, 0x07, 0x26, 0x1f, 0x1e, ++ 0x47, 0x12, 0x10, 0x08, 0x40, 0x0f, 0x08, 0x01, 0x25, 0x08, 0x35, 0x25, 0x25, 0x08, 0x40, 0x40, ++ 0x40, 0x40, 0x40, 0x40, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x07, 0x3e, 0x26, 0x07, 0x40, 0x40, 0x46, 0x57, 0x66, 0x2f, 0x40, 0x07, 0x40, 0x40, 0x47, 0x0f, ++ 0x07, 0x26, 0x40, 0x17, 0x16, 0x26, 0x35, 0x3e, 0x3e, 0x07, 0x07, 0x00, 0x01, 0x08, 0x1f, 0x07, ++ 0x06, 0x27, 0x2e, 0x08, 0x40, 0x47, 0x4e, 0x40, 0x40, 0x40, 0x07, 0x07, 0x07, 0x0e, 0x0f, 0x0e, ++ 0x16, 0x1e, 0x07, 0x06, 0x06, 0x26, 0x07, 0x40, 0x06, 0x06, 0x26, 0x1e, 0x17, 0x26, 0x07, 0x0e, ++ 0x0f, 0x0e, 0x16, 0x1e, 0x07, 0x06, 0x06, 0x26, 0x07, 0x40, 0x06, 0x06, 0x26, 0x1e, 0x17, 0x26, ++ 0x27, 0x40, 0x3e, 0x40, 0x4f, 0x40, 0x07, 0x07, 0x07, 0x17, 0x17, 0x35, 0x0f, 0x10, 0x47, 0x40, ++ 0x1f, 0x07, 0x40, 0x10, 0x47, 0x40, 0x1f, 0x07, 0x40, 0x10, 0x47, 0x40, 0x1f, 0x07, 0x40, 0x4f, ++ 0x07, 0x0f, 0x0f, 0x1f, 0x27, 0x1f, 0x27, 0x08, 0x17, 0x47, 0x40, 0x17, 0x47, 0x40, 0x40, 0x40, ++ 0x40, 0x01, 0x08, 0x08, 0x40, 0x0f, 0x08, 0x00, 0x00, 0x2f, 0x27, 0x1f, 0x07, 0x27, 0x1f, 0x1f, ++ 0x47, 0x11, 0x10, 0x08, 0x40, 0x0f, 0x08, 0x00, 0x26, 0x08, 0x36, 0x26, 0x26, 0x08, 0x40, 0x40, ++ 0x40, 0x40, 0x40, 0x40, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x07, 0x3e, 0x27, 0x07, 0x40, 0x40, 0x47, 0x57, 0x67, 0x2f, 0x40, 0x07, 0x40, 0x40, 0x47, 0x0f, ++ 0x07, 0x27, 0x40, 0x17, 0x17, 0x27, 0x37, 0x3e, 0x3e, 0x07, 0x07, 0x00, 0x00, 0x08, 0x1f, 0x07, ++ 0x07, 0x27, 0x2f, 0x08, 0x40, 0x47, 0x4f, 0x40, 0x40, 0x40, 0x07, 0x07, 0x07, 0x0f, 0x0f, 0x0f, ++ 0x17, 0x1f, 0x07, 0x07, 0x07, 0x27, 0x07, 0x40, 0x07, 0x07, 0x27, 0x1f, 0x17, 0x27, 0x07, 0x0f, ++ 0x0f, 0x0f, 0x17, 0x1f, 0x07, 0x07, 0x07, 0x27, 0x07, 0x40, 0x07, 0x07, 0x27, 0x1f, 0x17, 0x27, ++ 0x27, 0x40, 0x3e, 0x40, 0x4f, 0x40, 0x07, 0x07, 0x07, 0x17, 0x17, 0x37, 0x0f, 0x10, 0x47, 0x40, ++ 0x1f, 0x07, 0x40, 0x10, 0x47, 0x40, 0x1f, 0x07, 0x40, 0x10, 0x47, 0x40, 0x1f, 0x07, 0x40, 0x4f, ++ 0x07, 0x0f, 0x0f, 0x1f, 0x27, 0x1f, 0x27, 0x08, 0x17, 0x47, 0x40, 0x17, 0x47, 0x40, 0x40, 0x40, ++ 0x40, 0x00, 0x08, 0x08, 0x40, 0x0f, 0x08, 0x00, 0x00, 0x2f, 0x27, 0x1f, 0x07, 0x27, 0x1f, 0x1f, ++ 0x47, 0x10, 0x10, 0x08, 0x40, 0x0f, 0x08, 0x00, 0x27, 0x08, 0x37, 0x27, 0x27, 0x08, 0x40, 0x40, ++ 0x40, 0x40, 0x40, 0x40, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++}; ++ ++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_hevc_run *run) ++{ ++ struct rkvdec_hevc_ctx *hevc_ctx = ctx->priv; ++ const struct v4l2_ctrl_hevc_sps *sps = run->sps; ++ const struct v4l2_ctrl_hevc_pps *pps = run->pps; ++ struct rkvdec_hevc_priv_tbl *priv_tbl = hevc_ctx->priv_tbl.cpu; ++ struct rkvdec_sps_pps_packet *hw_ps; ++ u32 min_cb_log2_size_y, ctb_log2_size_y, ctb_size_y; ++ u32 log2_min_cu_qp_delta_size; ++ dma_addr_t scaling_list_address; ++ u32 scaling_distance; ++ int i; ++ ++ /* ++ * HW read the SPS/PPS information from PPS packet index by PPS id. ++ * offset from the base can be calculated by PPS_id * 80 (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)); ++ ++ min_cb_log2_size_y = sps->log2_min_luma_coding_block_size_minus3 + 3; ++ ctb_log2_size_y = min_cb_log2_size_y + ++ sps->log2_diff_max_min_luma_coding_block_size; ++ ctb_size_y = 1 << ctb_log2_size_y; ++ ++#define WRITE_PPS(value, field) set_ps_field(hw_ps->info, field, value) ++ /* write sps */ ++ WRITE_PPS(sps->video_parameter_set_id, VIDEO_PARAMETER_SET_ID); ++ WRITE_PPS(sps->seq_parameter_set_id, SEQ_PARAMETER_SET_ID); ++ WRITE_PPS(1, CHROMA_FORMAT_IDC); ++ WRITE_PPS(sps->pic_width_in_luma_samples, PIC_WIDTH_IN_LUMA_SAMPLES); ++ WRITE_PPS(sps->pic_height_in_luma_samples, PIC_HEIGHT_IN_LUMA_SAMPLES); ++ 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->log2_max_pic_order_cnt_lsb_minus4 + 4, ++ LOG2_MAX_PIC_ORDER_CNT_LSB); ++ WRITE_PPS(sps->log2_diff_max_min_luma_coding_block_size, ++ LOG2_DIFF_MAX_MIN_LUMA_CODING_BLOCK_SIZE); ++ WRITE_PPS(sps->log2_min_luma_coding_block_size_minus3 + 3, ++ LOG2_MIN_LUMA_CODING_BLOCK_SIZE); ++ WRITE_PPS(sps->log2_min_luma_transform_block_size_minus2 + 2, ++ LOG2_MIN_TRANSFORM_BLOCK_SIZE); ++ WRITE_PPS(sps->log2_diff_max_min_luma_transform_block_size, ++ LOG2_DIFF_MAX_MIN_LUMA_TRANSFORM_BLOCK_SIZE); ++ WRITE_PPS(sps->max_transform_hierarchy_depth_inter, ++ MAX_TRANSFORM_HIERARCHY_DEPTH_INTER); ++ WRITE_PPS(sps->max_transform_hierarchy_depth_intra, ++ MAX_TRANSFORM_HIERARCHY_DEPTH_INTRA); ++ WRITE_PPS(!!(sps->flags & V4L2_HEVC_SPS_FLAG_SCALING_LIST_ENABLED), ++ SCALING_LIST_ENABLED_FLAG); ++ WRITE_PPS(!!(sps->flags & V4L2_HEVC_SPS_FLAG_AMP_ENABLED), ++ AMP_ENABLED_FLAG); ++ WRITE_PPS(!!(sps->flags & V4L2_HEVC_SPS_FLAG_SAMPLE_ADAPTIVE_OFFSET), ++ SAMPLE_ADAPTIVE_OFFSET_ENABLED_FLAG); ++ if (sps->flags & V4L2_HEVC_SPS_FLAG_PCM_ENABLED) { ++ WRITE_PPS(1, PCM_ENABLED_FLAG); ++ WRITE_PPS(sps->pcm_sample_bit_depth_luma_minus1 + 1, ++ PCM_SAMPLE_BIT_DEPTH_LUMA); ++ WRITE_PPS(sps->pcm_sample_bit_depth_chroma_minus1 + 1, ++ PCM_SAMPLE_BIT_DEPTH_CHROMA); ++ WRITE_PPS(!!(sps->flags & V4L2_HEVC_SPS_FLAG_PCM_LOOP_FILTER_DISABLED), ++ PCM_LOOP_FILTER_DISABLED_FLAG); ++ WRITE_PPS(sps->log2_diff_max_min_pcm_luma_coding_block_size, ++ LOG2_DIFF_MAX_MIN_PCM_LUMA_CODING_BLOCK_SIZE); ++ WRITE_PPS(sps->log2_min_pcm_luma_coding_block_size_minus3 + 3, ++ LOG2_MIN_PCM_LUMA_CODING_BLOCK_SIZE); ++ } ++ WRITE_PPS(sps->num_short_term_ref_pic_sets, NUM_SHORT_TERM_REF_PIC_SETS); ++ WRITE_PPS(!!(sps->flags & V4L2_HEVC_SPS_FLAG_LONG_TERM_REF_PICS_PRESENT), ++ LONG_TERM_REF_PICS_PRESENT_FLAG); ++ WRITE_PPS(sps->num_long_term_ref_pics_sps, NUM_LONG_TERM_REF_PICS_SPS); ++ WRITE_PPS(!!(sps->flags & V4L2_HEVC_SPS_FLAG_SPS_TEMPORAL_MVP_ENABLED), ++ SPS_TEMPORAL_MVP_ENABLED_FLAG); ++ WRITE_PPS(!!(sps->flags & V4L2_HEVC_SPS_FLAG_STRONG_INTRA_SMOOTHING_ENABLED), ++ STRONG_INTRA_SMOOTHING_ENABLED_FLAG); ++ //WRITE_PPS(0, PS_FIELD(100, 7)); ++ //WRITE_PPS(0x1fffff, PS_FIELD(107, 21)); ++ ++ /* write pps */ ++ WRITE_PPS(pps->pic_parameter_set_id, PIC_PARAMETER_SET_ID); ++ WRITE_PPS(sps->seq_parameter_set_id, PPS_SEQ_PARAMETER_SET_ID); ++ WRITE_PPS(!!(pps->flags & V4L2_HEVC_PPS_FLAG_DEPENDENT_SLICE_SEGMENT), ++ DEPENDENT_SLICE_SEGMENTS_ENABLED_FLAG); ++ WRITE_PPS(!!(pps->flags & V4L2_HEVC_PPS_FLAG_OUTPUT_FLAG_PRESENT), ++ OUTPUT_FLAG_PRESENT_FLAG); ++ WRITE_PPS(pps->num_extra_slice_header_bits, NUM_EXTRA_SLICE_HEADER_BITS); ++ WRITE_PPS(!!(pps->flags & V4L2_HEVC_PPS_FLAG_SIGN_DATA_HIDING_ENABLED), ++ SIGN_DATA_HIDING_ENABLED_FLAG); ++ WRITE_PPS(!!(pps->flags & V4L2_HEVC_PPS_FLAG_CABAC_INIT_PRESENT), ++ CABAC_INIT_PRESENT_FLAG); ++ WRITE_PPS(pps->num_ref_idx_l0_default_active_minus1 + 1, ++ NUM_REF_IDX_L0_DEFAULT_ACTIVE); ++ WRITE_PPS(pps->num_ref_idx_l1_default_active_minus1 + 1, ++ NUM_REF_IDX_L1_DEFAULT_ACTIVE); ++ WRITE_PPS(pps->init_qp_minus26, INIT_QP_MINUS26); ++ WRITE_PPS(!!(pps->flags & V4L2_HEVC_PPS_FLAG_CONSTRAINED_INTRA_PRED), ++ CONSTRAINED_INTRA_PRED_FLAG); ++ WRITE_PPS(!!(pps->flags & V4L2_HEVC_PPS_FLAG_TRANSFORM_SKIP_ENABLED), ++ TRANSFORM_SKIP_ENABLED_FLAG); ++ WRITE_PPS(!!(pps->flags & V4L2_HEVC_PPS_FLAG_CU_QP_DELTA_ENABLED), ++ CU_QP_DELTA_ENABLED_FLAG); ++ ++ log2_min_cu_qp_delta_size = ctb_log2_size_y - pps->diff_cu_qp_delta_depth; ++ WRITE_PPS(log2_min_cu_qp_delta_size, LOG2_MIN_CU_QP_DELTA_SIZE); ++ ++ WRITE_PPS(pps->pps_cb_qp_offset, PPS_CB_QP_OFFSET); ++ WRITE_PPS(pps->pps_cr_qp_offset, PPS_CR_QP_OFFSET); ++ WRITE_PPS(!!(pps->flags & V4L2_HEVC_PPS_FLAG_PPS_SLICE_CHROMA_QP_OFFSETS_PRESENT), ++ PPS_SLICE_CHROMA_QP_OFFSETS_PRESENT_FLAG); ++ WRITE_PPS(!!(pps->flags & V4L2_HEVC_PPS_FLAG_WEIGHTED_PRED), ++ WEIGHTED_PRED_FLAG); ++ WRITE_PPS(!!(pps->flags & V4L2_HEVC_PPS_FLAG_WEIGHTED_BIPRED), ++ WEIGHTED_BIPRED_FLAG); ++ WRITE_PPS(!!(pps->flags & V4L2_HEVC_PPS_FLAG_TRANSQUANT_BYPASS_ENABLED), ++ TRANSQUANT_BYPASS_ENABLED_FLAG); ++ WRITE_PPS(!!(pps->flags & V4L2_HEVC_PPS_FLAG_TILES_ENABLED), ++ TILES_ENABLED_FLAG); ++ WRITE_PPS(!!(pps->flags & V4L2_HEVC_PPS_FLAG_ENTROPY_CODING_SYNC_ENABLED), ++ ENTROPY_CODING_SYNC_ENABLED_FLAG); ++ WRITE_PPS(!!(pps->flags & V4L2_HEVC_PPS_FLAG_PPS_LOOP_FILTER_ACROSS_SLICES_ENABLED), ++ PPS_LOOP_FILTER_ACROSS_SLICES_ENABLED_FLAG); ++ WRITE_PPS(!!(pps->flags & V4L2_HEVC_PPS_FLAG_LOOP_FILTER_ACROSS_TILES_ENABLED), ++ LOOP_FILTER_ACROSS_TILES_ENABLED_FLAG); ++ WRITE_PPS(!!(pps->flags & V4L2_HEVC_PPS_FLAG_DEBLOCKING_FILTER_OVERRIDE_ENABLED), ++ DEBLOCKING_FILTER_OVERRIDE_ENABLED_FLAG); ++ WRITE_PPS(!!(pps->flags & V4L2_HEVC_PPS_FLAG_PPS_DISABLE_DEBLOCKING_FILTER), ++ PPS_DEBLOCKING_FILTER_DISABLED_FLAG); ++ WRITE_PPS(pps->pps_beta_offset_div2, PPS_BETA_OFFSET_DIV2); ++ WRITE_PPS(pps->pps_tc_offset_div2, PPS_TC_OFFSET_DIV2); ++ WRITE_PPS(!!(pps->flags & V4L2_HEVC_PPS_FLAG_LISTS_MODIFICATION_PRESENT), ++ LISTS_MODIFICATION_PRESENT_FLAG); ++ WRITE_PPS(pps->log2_parallel_merge_level_minus2 + 2, LOG2_PARALLEL_MERGE_LEVEL); ++ WRITE_PPS(!!(pps->flags & V4L2_HEVC_PPS_FLAG_SLICE_SEGMENT_HEADER_EXTENSION_PRESENT), ++ SLICE_SEGMENT_HEADER_EXTENSION_PRESENT_FLAG); ++ //WRITE_PPS(0, PS_FIELD(209, 3)); ++ WRITE_PPS(pps->num_tile_columns_minus1 + 1, NUM_TILE_COLUMNS); ++ WRITE_PPS(pps->num_tile_rows_minus1 + 1, NUM_TILE_ROWS); ++ //WRITE_PPS(0x2, PS_FIELD(222, 2)); ++ //WRITE_PPS(0xffffffff, PS_FIELD(224, 32)); ++ ++ if (pps->flags & V4L2_HEVC_PPS_FLAG_TILES_ENABLED) { ++ for (i = 0; i <= pps->num_tile_columns_minus1; i++) ++ WRITE_PPS(pps->column_width_minus1[i], COLUMN_WIDTH(i)); ++ for (i = 0; i <= pps->num_tile_rows_minus1; i++) ++ WRITE_PPS(pps->row_height_minus1[i], ROW_HEIGHT(i)); ++ } else { ++ WRITE_PPS(round_up(sps->pic_width_in_luma_samples, ctb_size_y) - 1, ++ COLUMN_WIDTH(0)); ++ WRITE_PPS(round_up(sps->pic_height_in_luma_samples, ctb_size_y) - 1, ++ ROW_HEIGHT(0)); ++ } ++ ++ scaling_distance = offsetof(struct rkvdec_hevc_priv_tbl, scaling_list); ++ scaling_list_address = hevc_ctx->priv_tbl.dma + scaling_distance; ++ WRITE_PPS(scaling_list_address, SCALING_LIST_ADDRESS); ++ //WRITE_PPS(0xffff, PS_FIELD(624, 16)); ++} ++ ++static void assemble_hw_rps(struct rkvdec_ctx *ctx, ++ struct rkvdec_hevc_run *run) ++{ ++ const struct v4l2_ctrl_hevc_slice_params *sl_params; ++ const struct v4l2_hevc_dpb_entry *dpb; ++ struct rkvdec_hevc_ctx *hevc_ctx = ctx->priv; ++ struct rkvdec_hevc_priv_tbl *priv_tbl = hevc_ctx->priv_tbl.cpu; ++ struct rkvdec_rps_packet *hw_ps; ++ int i, j; ++ ++#define WRITE_RPS(value, field) set_ps_field(hw_ps->info, field, value) ++ ++#define REF_PIC_LONG_TERM_L0(i) PS_FIELD(i * 5, 1) ++#define REF_PIC_IDX_L0(i) PS_FIELD(1 + (i * 5), 4) ++#define REF_PIC_LONG_TERM_L1(i) PS_FIELD((i < 5 ? 75 : 132) + (i * 5), 1) ++#define REF_PIC_IDX_L1(i) PS_FIELD((i < 4 ? 76 : 128) + (i * 5), 4) ++ ++#define LOWDELAY PS_FIELD(182, 1) ++#define SHORT_TERM_REF_PIC_SET_SIZE PS_FIELD(183, 10) ++#define LONG_TERM_REF_PIC_SET_SIZE PS_FIELD(193, 9) ++#define NUM_RPS_POC PS_FIELD(202, 4) ++ ++ for (j = 0; j < run->num_slices; j++) { ++ sl_params = &run->slices_params[j]; ++ dpb = sl_params->dpb; ++ ++ hw_ps = &priv_tbl->rps[j]; ++ memset(hw_ps, 0, sizeof(*hw_ps)); ++ ++ for (i = 0; i <= sl_params->num_ref_idx_l0_active_minus1; i++) { ++ WRITE_RPS(!!(dpb[sl_params->ref_idx_l0[i]].rps == V4L2_HEVC_DPB_ENTRY_RPS_LT_CURR), ++ REF_PIC_LONG_TERM_L0(i)); ++ WRITE_RPS(sl_params->ref_idx_l0[i], REF_PIC_IDX_L0(i)); ++ } ++ ++ for (i = 0; i <= sl_params->num_ref_idx_l1_active_minus1; i++) { ++ WRITE_RPS(!!(dpb[sl_params->ref_idx_l1[i]].rps == V4L2_HEVC_DPB_ENTRY_RPS_LT_CURR), ++ REF_PIC_LONG_TERM_L1(i)); ++ WRITE_RPS(sl_params->ref_idx_l1[i], REF_PIC_IDX_L1(i)); ++ } ++ ++ //WRITE_RPS(0xffffffff, PS_FIELD(96, 32)); ++ ++ // TODO: lowdelay ++ WRITE_RPS(0, LOWDELAY); ++ ++ // NOTE: these two differs from mpp ++ WRITE_RPS(sl_params->short_term_ref_pic_set_size, ++ SHORT_TERM_REF_PIC_SET_SIZE); ++ WRITE_RPS(sl_params->long_term_ref_pic_set_size, ++ LONG_TERM_REF_PIC_SET_SIZE); ++ ++ WRITE_RPS(sl_params->num_rps_poc_st_curr_before + ++ sl_params->num_rps_poc_st_curr_after + ++ sl_params->num_rps_poc_lt_curr, ++ NUM_RPS_POC); ++ ++ //WRITE_RPS(0x3ffff, PS_FIELD(206, 18)); ++ //WRITE_RPS(0xffffffff, PS_FIELD(224, 32)); ++ } ++} ++ ++static void assemble_hw_scaling_list(struct rkvdec_ctx *ctx, ++ struct rkvdec_hevc_run *run) ++{ ++ const struct v4l2_ctrl_hevc_scaling_matrix *scaling = run->scaling_matrix; ++ struct rkvdec_hevc_ctx *hevc_ctx = ctx->priv; ++ struct rkvdec_hevc_priv_tbl *tbl = hevc_ctx->priv_tbl.cpu; ++ u8 *dst; ++ scalingList_t sl; ++ int i, j; ++ ++ if (!memcmp((void*)&hevc_ctx->scaling_matrix_cache, scaling, ++ sizeof(struct v4l2_ctrl_hevc_scaling_matrix))) ++ return; ++ ++ memset(&sl, 0, sizeof(scalingList_t)); ++ ++ for (i = 0; i < 6; i++) { ++ for (j = 0; j < 16; j++) ++ sl.sl[0][i][j] = scaling->scaling_list_4x4[i][j]; ++ for (j = 0; j < 64; j++) { ++ sl.sl[1][i][j] = scaling->scaling_list_8x8[i][j]; ++ sl.sl[2][i][j] = scaling->scaling_list_16x16[i][j]; ++ if (i < 2) ++ sl.sl[3][i][j] = scaling->scaling_list_32x32[i][j]; ++ } ++ sl.sl_dc[0][i] = scaling->scaling_list_dc_coef_16x16[i]; ++ if (i < 2) ++ sl.sl_dc[1][i] = scaling->scaling_list_dc_coef_32x32[i]; ++ } ++ ++ dst = tbl->scaling_list; ++ hal_record_scaling_list((scalingFactor_t *)dst, &sl); ++ ++ memcpy((void*)&hevc_ctx->scaling_matrix_cache, scaling, ++ sizeof(struct v4l2_ctrl_hevc_scaling_matrix)); ++} ++ ++static struct vb2_buffer * ++get_ref_buf(struct rkvdec_ctx *ctx, struct rkvdec_hevc_run *run, ++ unsigned int dpb_idx) ++{ ++ struct v4l2_m2m_ctx *m2m_ctx = ctx->fh.m2m_ctx; ++ const struct v4l2_ctrl_hevc_slice_params *sl_params = &run->slices_params[0]; ++ const struct v4l2_hevc_dpb_entry *dpb = sl_params->dpb; ++ struct vb2_queue *cap_q = &m2m_ctx->cap_q_ctx.q; ++ int buf_idx = -1; ++ ++ if (dpb_idx < sl_params->num_active_dpb_entries) ++ buf_idx = vb2_find_timestamp(cap_q, ++ dpb[dpb_idx].timestamp, 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_hevc_run *run) ++{ ++ struct rkvdec_dev *rkvdec = ctx->dev; ++ const struct v4l2_ctrl_hevc_slice_params *sl_params = &run->slices_params[0]; ++ const struct v4l2_hevc_dpb_entry *dpb = sl_params->dpb; ++ struct rkvdec_hevc_ctx *hevc_ctx = ctx->priv; ++ dma_addr_t priv_start_addr = hevc_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; ++ u32 ver_virstride; ++ u32 y_virstride; ++ u32 uv_virstride; ++ u32 yuv_virstride; ++ u32 offset; ++ dma_addr_t dst_addr; ++ u32 reg, i; ++ ++ reg = RKVDEC_MODE(RKVDEC_MODE_HEVC); ++ writel_relaxed(reg, rkvdec->regs + RKVDEC_REG_SYSCTRL); ++ ++ f = &ctx->decoded_fmt; ++ dst_fmt = &f->fmt.pix_mp; ++ hor_virstride = dst_fmt->plane_fmt[0].bytesperline; ++ ver_virstride = dst_fmt->height; ++ y_virstride = hor_virstride * ver_virstride; ++ uv_virstride = y_virstride / 2; ++ yuv_virstride = y_virstride + uv_virstride; ++ ++ reg = RKVDEC_Y_HOR_VIRSTRIDE(hor_virstride / 16) | ++ RKVDEC_UV_HOR_VIRSTRIDE(hor_virstride / 16) | ++ RKVDEC_SLICE_NUM_LOWBITS(run->num_slices); ++ 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); ++ ++ rlc_len = vb2_get_plane_payload(&src_buf->vb2_buf, 0); ++ reg = RKVDEC_STRM_LEN(round_up(rlc_len, 16) + 64); ++ writel_relaxed(reg, rkvdec->regs + RKVDEC_REG_STRM_LEN); ++ ++ /* config cabac table */ ++ offset = offsetof(struct rkvdec_hevc_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 */ ++ for (i = 0; i < 15; i++) { ++ struct vb2_buffer *vb_buf = get_ref_buf(ctx, run, i); ++ ++ if (i < 4 && sl_params->num_active_dpb_entries) { ++ reg = GENMASK(sl_params->num_active_dpb_entries - 1, 0); ++ reg = (reg >> (i * 4)) & 0xf; ++ } else ++ reg = 0; ++ ++ refer_addr = vb2_dma_contig_plane_dma_addr(vb_buf, 0); ++ writel_relaxed(refer_addr | reg, ++ rkvdec->regs + RKVDEC_REG_H264_BASE_REFER(i)); ++ ++ reg = RKVDEC_POC_REFER(i < sl_params->num_active_dpb_entries ? dpb[i].pic_order_cnt[0] : 0); ++ writel_relaxed(reg, ++ rkvdec->regs + RKVDEC_REG_H264_POC_REFER0(i)); ++ } ++ ++ reg = RKVDEC_CUR_POC(sl_params->slice_pic_order_cnt); ++ writel_relaxed(reg, rkvdec->regs + RKVDEC_REG_CUR_POC0); ++ ++ /* config hw pps address */ ++ offset = offsetof(struct rkvdec_hevc_priv_tbl, param_set); ++ writel_relaxed(priv_start_addr + offset, ++ rkvdec->regs + RKVDEC_REG_PPS_BASE); ++ ++ /* config hw rps address */ ++ offset = offsetof(struct rkvdec_hevc_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); ++} ++ ++#define RKVDEC_HEVC_MAX_DEPTH_IN_BYTES 2 ++ ++static int rkvdec_hevc_adjust_fmt(struct rkvdec_ctx *ctx, ++ struct v4l2_format *f) ++{ ++ struct v4l2_pix_format_mplane *fmt = &f->fmt.pix_mp; ++ ++ fmt->num_planes = 1; ++ if (!fmt->plane_fmt[0].sizeimage) ++ fmt->plane_fmt[0].sizeimage = fmt->width * fmt->height * ++ RKVDEC_HEVC_MAX_DEPTH_IN_BYTES; ++ return 0; ++} ++ ++static int rkvdec_hevc_start(struct rkvdec_ctx *ctx) ++{ ++ struct rkvdec_dev *rkvdec = ctx->dev; ++ struct rkvdec_hevc_priv_tbl *priv_tbl; ++ struct rkvdec_hevc_ctx *hevc_ctx; ++ int ret; ++ ++ hevc_ctx = kzalloc(sizeof(*hevc_ctx), GFP_KERNEL); ++ if (!hevc_ctx) ++ return -ENOMEM; ++ ++ priv_tbl = dma_alloc_coherent(rkvdec->dev, sizeof(*priv_tbl), ++ &hevc_ctx->priv_tbl.dma, GFP_KERNEL); ++ if (!priv_tbl) { ++ ret = -ENOMEM; ++ goto err_free_ctx; ++ } ++ ++ hevc_ctx->priv_tbl.size = sizeof(*priv_tbl); ++ hevc_ctx->priv_tbl.cpu = priv_tbl; ++ memset(priv_tbl, 0, sizeof(*priv_tbl)); ++ memcpy(priv_tbl->cabac_table, rkvdec_hevc_cabac_table, ++ sizeof(rkvdec_hevc_cabac_table)); ++ ++ ctx->priv = hevc_ctx; ++ return 0; ++ ++err_free_ctx: ++ kfree(hevc_ctx); ++ return ret; ++} ++ ++static void rkvdec_hevc_stop(struct rkvdec_ctx *ctx) ++{ ++ struct rkvdec_hevc_ctx *hevc_ctx = ctx->priv; ++ struct rkvdec_dev *rkvdec = ctx->dev; ++ ++ dma_free_coherent(rkvdec->dev, hevc_ctx->priv_tbl.size, ++ hevc_ctx->priv_tbl.cpu, hevc_ctx->priv_tbl.dma); ++ kfree(hevc_ctx); ++} ++ ++static void rkvdec_hevc_run_preamble(struct rkvdec_ctx *ctx, ++ struct rkvdec_hevc_run *run) ++{ ++ struct v4l2_ctrl *ctrl; ++ ++ ctrl = v4l2_ctrl_find(&ctx->ctrl_hdl, ++ V4L2_CID_MPEG_VIDEO_HEVC_SLICE_PARAMS); ++ run->slices_params = ctrl ? ctrl->p_cur.p : NULL; ++ ctrl = v4l2_ctrl_find(&ctx->ctrl_hdl, ++ V4L2_CID_MPEG_VIDEO_HEVC_SPS); ++ run->sps = ctrl ? ctrl->p_cur.p : NULL; ++ ctrl = v4l2_ctrl_find(&ctx->ctrl_hdl, ++ V4L2_CID_MPEG_VIDEO_HEVC_PPS); ++ run->pps = ctrl ? ctrl->p_cur.p : NULL; ++ ctrl = v4l2_ctrl_find(&ctx->ctrl_hdl, ++ V4L2_CID_MPEG_VIDEO_HEVC_SCALING_MATRIX); ++ run->scaling_matrix = ctrl ? ctrl->p_cur.p : NULL; ++ ++ rkvdec_run_preamble(ctx, &run->base); ++ ++ // HACK: we need num slices from somewhere ++ run->num_slices = run->sps->num_slices; ++} ++ ++static int rkvdec_hevc_run(struct rkvdec_ctx *ctx) ++{ ++ struct rkvdec_dev *rkvdec = ctx->dev; ++ struct rkvdec_hevc_run run; ++ ++ rkvdec_hevc_run_preamble(ctx, &run); ++ ++ assemble_hw_scaling_list(ctx, &run); ++ assemble_hw_pps(ctx, &run); ++ assemble_hw_rps(ctx, &run); ++ config_registers(ctx, &run); ++ ++ rkvdec_run_postamble(ctx, &run.base); ++ ++ // sw_cabac_error_e - cabac error enable ++ writel_relaxed(0xfdfffffd, rkvdec->regs + RKVDEC_REG_STRMD_ERR_EN); ++ // slice end error enable = BIT(28) ++ // frame end error enable = BIT(29) ++ writel_relaxed(0x30000000, rkvdec->regs + RKVDEC_REG_H264_ERR_E); ++ ++ schedule_delayed_work(&rkvdec->watchdog_work, msecs_to_jiffies(2000)); ++ ++ 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_hevc_fmt_ops = { ++ .adjust_fmt = rkvdec_hevc_adjust_fmt, ++ .start = rkvdec_hevc_start, ++ .stop = rkvdec_hevc_stop, ++ .run = rkvdec_hevc_run, ++}; +diff --git a/drivers/staging/media/rkvdec/rkvdec-regs.h b/drivers/staging/media/rkvdec/rkvdec-regs.h +index 15b9bee92016..83bf790ed9b7 100644 +--- a/drivers/staging/media/rkvdec/rkvdec-regs.h ++++ b/drivers/staging/media/rkvdec/rkvdec-regs.h +@@ -43,6 +43,7 @@ + #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_HEVC 0 + #define RKVDEC_MODE_H264 1 + #define RKVDEC_MODE_VP9 2 + #define RKVDEC_RPS_MODE BIT(24) +diff --git a/drivers/staging/media/rkvdec/rkvdec.c b/drivers/staging/media/rkvdec/rkvdec.c +index e1eec79fe9a2..880a70c9291e 100644 +--- a/drivers/staging/media/rkvdec/rkvdec.c ++++ b/drivers/staging/media/rkvdec/rkvdec.c +@@ -159,6 +159,61 @@ static const u32 rkvdec_h264_decoded_fmts[] = { + V4L2_PIX_FMT_NV20, + }; + ++static const struct rkvdec_ctrl_desc rkvdec_hevc_ctrl_descs[] = { ++ { ++ .mandatory = true, ++ .cfg.id = V4L2_CID_MPEG_VIDEO_HEVC_SLICE_PARAMS, ++ // HACK: match ffmpeg v4l2 request api hwaccel size, ++ // we should support variable length up to 600 slices ++ .cfg.dims = { 16 }, ++ }, ++ { ++ .mandatory = true, ++ .cfg.id = V4L2_CID_MPEG_VIDEO_HEVC_SPS, ++ }, ++ { ++ .mandatory = true, ++ .cfg.id = V4L2_CID_MPEG_VIDEO_HEVC_PPS, ++ }, ++ { ++ .mandatory = true, ++ .cfg.id = V4L2_CID_MPEG_VIDEO_HEVC_SCALING_MATRIX, ++ }, ++ { ++ .cfg.id = V4L2_CID_MPEG_VIDEO_HEVC_DECODE_MODE, ++ .cfg.min = V4L2_MPEG_VIDEO_HEVC_DECODE_MODE_FRAME_BASED, ++ .cfg.max = V4L2_MPEG_VIDEO_HEVC_DECODE_MODE_FRAME_BASED, ++ .cfg.def = V4L2_MPEG_VIDEO_HEVC_DECODE_MODE_FRAME_BASED, ++ }, ++ { ++ .cfg.id = V4L2_CID_MPEG_VIDEO_HEVC_START_CODE, ++ .cfg.min = V4L2_MPEG_VIDEO_HEVC_START_CODE_ANNEX_B, ++ .cfg.def = V4L2_MPEG_VIDEO_HEVC_START_CODE_ANNEX_B, ++ .cfg.max = V4L2_MPEG_VIDEO_HEVC_START_CODE_ANNEX_B, ++ }, ++ { ++ .cfg.id = V4L2_CID_MPEG_VIDEO_HEVC_PROFILE, ++ .cfg.min = V4L2_MPEG_VIDEO_HEVC_PROFILE_MAIN, ++ .cfg.max = V4L2_MPEG_VIDEO_HEVC_PROFILE_MAIN_10, ++ .cfg.def = V4L2_MPEG_VIDEO_HEVC_PROFILE_MAIN, ++ }, ++ { ++ .cfg.id = V4L2_CID_MPEG_VIDEO_HEVC_LEVEL, ++ .cfg.min = V4L2_MPEG_VIDEO_HEVC_LEVEL_1, ++ .cfg.max = V4L2_MPEG_VIDEO_HEVC_LEVEL_5_1, ++ }, ++}; ++ ++static const struct rkvdec_ctrls rkvdec_hevc_ctrls = { ++ .ctrls = rkvdec_hevc_ctrl_descs, ++ .num_ctrls = ARRAY_SIZE(rkvdec_hevc_ctrl_descs), ++}; ++ ++static const u32 rkvdec_hevc_decoded_fmts[] = { ++ V4L2_PIX_FMT_NV12, ++ V4L2_PIX_FMT_NV15, ++}; ++ + static const struct rkvdec_ctrl_desc rkvdec_vp9_ctrl_descs[] = { + { + .mandatory = true, +@@ -209,6 +264,21 @@ static const struct rkvdec_coded_fmt_desc rkvdec_coded_fmts[] = { + .num_decoded_fmts = ARRAY_SIZE(rkvdec_h264_decoded_fmts), + .decoded_fmts = rkvdec_h264_decoded_fmts, + }, ++ { ++ .fourcc = V4L2_PIX_FMT_HEVC_SLICE, ++ .frmsize = { ++ .min_width = 64, ++ .max_width = 4096, ++ .step_width = 64, ++ .min_height = 64, ++ .max_height = 2304, ++ .step_height = 16, ++ }, ++ .ctrls = &rkvdec_hevc_ctrls, ++ .ops = &rkvdec_hevc_fmt_ops, ++ .num_decoded_fmts = ARRAY_SIZE(rkvdec_hevc_decoded_fmts), ++ .decoded_fmts = rkvdec_hevc_decoded_fmts, ++ }, + { + .fourcc = V4L2_PIX_FMT_VP9_FRAME, + .frmsize = { +diff --git a/drivers/staging/media/rkvdec/rkvdec.h b/drivers/staging/media/rkvdec/rkvdec.h +index 5f66f07acac5..d5600c6a4c17 100644 +--- a/drivers/staging/media/rkvdec/rkvdec.h ++++ b/drivers/staging/media/rkvdec/rkvdec.h +@@ -123,6 +123,7 @@ 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; ++extern const struct rkvdec_coded_fmt_ops rkvdec_hevc_fmt_ops; + extern const struct rkvdec_coded_fmt_ops rkvdec_vp9_fmt_ops; + + #endif /* RKVDEC_H_ */ + +From de25bd06e32aeea9644cce18620a56a1aea02655 Mon Sep 17 00:00:00 2001 +From: Jonas Karlman +Date: Sat, 1 Aug 2020 12:24:58 +0000 +Subject: [PATCH] WIP: media: rkvdec: add HEVC format validation + +--- + drivers/staging/media/rkvdec/rkvdec-hevc.c | 11 +++++++++++ + drivers/staging/media/rkvdec/rkvdec.c | 23 +++++++++++++++++++++- + 2 files changed, 33 insertions(+), 1 deletion(-) + +diff --git a/drivers/staging/media/rkvdec/rkvdec-hevc.c b/drivers/staging/media/rkvdec/rkvdec-hevc.c +index 03ba848411c6..b8ad7fc2271c 100644 +--- a/drivers/staging/media/rkvdec/rkvdec-hevc.c ++++ b/drivers/staging/media/rkvdec/rkvdec-hevc.c +@@ -2415,6 +2415,16 @@ static int rkvdec_hevc_adjust_fmt(struct rkvdec_ctx *ctx, + return 0; + } + ++static u32 rkvdec_hevc_valid_fmt(struct rkvdec_ctx *ctx, struct v4l2_ctrl *ctrl) ++{ ++ const struct v4l2_ctrl_hevc_sps *sps = ctrl->p_new.p_hevc_sps; ++ ++ if (sps->bit_depth_luma_minus8 == 2) ++ return V4L2_PIX_FMT_NV15; ++ else ++ return V4L2_PIX_FMT_NV12; ++} ++ + static int rkvdec_hevc_start(struct rkvdec_ctx *ctx) + { + struct rkvdec_dev *rkvdec = ctx->dev; +@@ -2516,6 +2526,7 @@ static int rkvdec_hevc_run(struct rkvdec_ctx *ctx) + + const struct rkvdec_coded_fmt_ops rkvdec_hevc_fmt_ops = { + .adjust_fmt = rkvdec_hevc_adjust_fmt, ++ .valid_fmt = rkvdec_hevc_valid_fmt, + .start = rkvdec_hevc_start, + .stop = rkvdec_hevc_stop, + .run = rkvdec_hevc_run, +diff --git a/drivers/staging/media/rkvdec/rkvdec.c b/drivers/staging/media/rkvdec/rkvdec.c +index 880a70c9291e..5eec0ed710b2 100644 +--- a/drivers/staging/media/rkvdec/rkvdec.c ++++ b/drivers/staging/media/rkvdec/rkvdec.c +@@ -76,6 +76,26 @@ static int rkvdec_try_ctrl(struct v4l2_ctrl *ctrl) + if (width > ctx->coded_fmt.fmt.pix_mp.width || + height > ctx->coded_fmt.fmt.pix_mp.height) + return -EINVAL; ++ } else if (ctrl->id == V4L2_CID_MPEG_VIDEO_HEVC_SPS) { ++ const struct v4l2_ctrl_hevc_sps *sps = ctrl->p_new.p_hevc_sps; ++ ++ 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 && 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)) ++ /* Only current valid format */ ++ return -EINVAL; ++ ++ if (sps->pic_width_in_luma_samples > ctx->coded_fmt.fmt.pix_mp.width || ++ sps->pic_height_in_luma_samples > ctx->coded_fmt.fmt.pix_mp.height) ++ return -EINVAL; + } + return 0; + } +@@ -84,7 +104,7 @@ 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) { ++ if (!ctx->valid_fmt) { + ctx->valid_fmt = rkvdec_valid_fmt(ctx, ctrl); + if (ctx->valid_fmt) { + struct v4l2_pix_format_mplane *pix_mp; +@@ -170,6 +190,7 @@ static const struct rkvdec_ctrl_desc rkvdec_hevc_ctrl_descs[] = { + { + .mandatory = true, + .cfg.id = V4L2_CID_MPEG_VIDEO_HEVC_SPS, ++ .cfg.ops = &rkvdec_ctrl_ops, + }, + { + .mandatory = true, From 8535bcf27be19ea45de4d28e50edabc00ce57f57 Mon Sep 17 00:00:00 2001 From: Alex Bee Date: Mon, 18 Jan 2021 00:32:09 +0100 Subject: [PATCH 6/6] rockchip: disallow upgrades from legacy kernels --- projects/Rockchip/bootloader/canupdate.sh | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/projects/Rockchip/bootloader/canupdate.sh b/projects/Rockchip/bootloader/canupdate.sh index b9b32ca914..908179b820 100644 --- a/projects/Rockchip/bootloader/canupdate.sh +++ b/projects/Rockchip/bootloader/canupdate.sh @@ -1,6 +1,15 @@ # SPDX-License-Identifier: GPL-2.0 # Copyright (C) 2017-present Team LibreELEC (https://libreelec.tv) +# detect legacy kernel installs and abort to prevent upgrades +case $(uname -r) in + 4.4*) + echo "Updates from legacy kernels are not supported!" + sleep 10 + exit 1 + ;; +esac + # Allow upgrades between arm and aarch64 if [ "$1" = "@PROJECT@.arm" -o "$1" = "@PROJECT@.aarch64" ]; then exit 0