From d3ffc4ac7cf675acca5bbf4f52188f9c4a83311b Mon Sep 17 00:00:00 2001 From: paolo Date: Fri, 29 Jan 2021 19:20:50 +0000 Subject: [PATCH] [rk322x] Moved rk322x-current to kernel 5.10.y, added alternative wlan wiring for some boards --- config/kernel/linux-rk322x-current.config | 204 +- config/kernel/linux-rk322x-dev.config | 32 +- config/sources/families/rk322x.conf | 4 +- .../01-linux-0001-rockchip-from-5.10.patch | 2967 ----------- .../01-linux-0001-rockchip-from-5.11.patch | 3068 ++++++++++++ ...=> 01-linux-0002-rockchip-from-list.patch} | 4425 +++++++++-------- ...atch => 01-linux-0010-v4l-from-list.patch} | 1492 +----- .../01-linux-0011-v4l2-from-5.10.patch | 2632 ---------- ...atch => 01-linux-0020-drm-from-5.11.patch} | 169 +- .../01-linux-0021-drm-from-5.10.patch | 2194 -------- .../01-linux-0021-drm-from-list.patch | 1753 +++++++ ...patch => 01-linux-1000-rockchip-wip.patch} | 1421 ++++-- ...-wip.patch => 01-linux-1001-drm-wip.patch} | 3439 +++++-------- ...-wip.patch => 01-linux-1002-v4l-wip.patch} | 2241 ++++++++- ...tch => 01-linux-9000-rk322x-box-DTs.patch} | 54 +- .../01-linux-9001-rk3188-rbox-DTs.patch | 799 +++ .../01-linux-9002-rk3066a-rbox-DTs.patch | 1060 ++++ .../01-linux-0001-rockchip-from-5.11.patch | 130 - .../01-linux-0020-drm-from-5.11.patch | 159 - 19 files changed, 13882 insertions(+), 14361 deletions(-) delete mode 100644 patch/kernel/rk322x-current/01-linux-0001-rockchip-from-5.10.patch create mode 100644 patch/kernel/rk322x-current/01-linux-0001-rockchip-from-5.11.patch rename patch/kernel/rk322x-current/{01-linux-1000-rockchip-soc-from-list.patch => 01-linux-0002-rockchip-from-list.patch} (83%) rename patch/kernel/rk322x-current/{01-linux-1003-rockchip-v4l-next-from-list.patch => 01-linux-0010-v4l-from-list.patch} (73%) delete mode 100644 patch/kernel/rk322x-current/01-linux-0011-v4l2-from-5.10.patch rename patch/kernel/rk322x-current/{01-linux-0022-drm-from-next.patch => 01-linux-0020-drm-from-5.11.patch} (61%) delete mode 100644 patch/kernel/rk322x-current/01-linux-0021-drm-from-5.10.patch create mode 100644 patch/kernel/rk322x-current/01-linux-0021-drm-from-list.patch rename patch/kernel/rk322x-current/{01-linux-1001-rockchip-soc-wip.patch => 01-linux-1000-rockchip-wip.patch} (59%) rename patch/kernel/rk322x-current/{01-linux-1002-rockchip-drm-wip.patch => 01-linux-1001-drm-wip.patch} (65%) rename patch/kernel/rk322x-current/{01-linux-1004-rockchip-v4l-wip.patch => 01-linux-1002-v4l-wip.patch} (80%) rename patch/kernel/rk322x-current/{01-linux-9000-rk322x-boxes.patch => 01-linux-9000-rk322x-box-DTs.patch} (94%) create mode 100644 patch/kernel/rk322x-current/01-linux-9001-rk3188-rbox-DTs.patch create mode 100644 patch/kernel/rk322x-current/01-linux-9002-rk3066a-rbox-DTs.patch diff --git a/config/kernel/linux-rk322x-current.config b/config/kernel/linux-rk322x-current.config index f8181f574..4d07a82b7 100644 --- a/config/kernel/linux-rk322x-current.config +++ b/config/kernel/linux-rk322x-current.config @@ -1,12 +1,13 @@ # # Automatically generated file; DO NOT EDIT. -# Linux/arm 5.9.0 Kernel Configuration +# Linux/arm 5.10.11 Kernel Configuration # CONFIG_CC_VERSION_TEXT="arm-none-linux-gnueabihf-gcc (GNU Toolchain for the A-profile Architecture 9.2-2019.12 (arm-9.10)) 9.2.1 20191025" CONFIG_CC_IS_GCC=y CONFIG_GCC_VERSION=90201 CONFIG_LD_VERSION=233010000 CONFIG_CLANG_VERSION=0 +CONFIG_LLD_VERSION=0 CONFIG_CC_CAN_LINK=y CONFIG_CC_CAN_LINK_STATIC=y CONFIG_CC_HAS_ASM_GOTO=y @@ -58,6 +59,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 @@ -174,6 +176,7 @@ CONFIG_RD_ZSTD=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 @@ -455,11 +458,10 @@ CONFIG_HIGHMEM=y CONFIG_CPU_SW_DOMAIN_PAN=y CONFIG_HW_PERF_EVENTS=y CONFIG_ARCH_WANT_GENERAL_HUGETLB=y -# CONFIG_ARM_MODULE_PLTS is not set +CONFIG_ARM_MODULE_PLTS=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 @@ -619,6 +621,7 @@ CONFIG_AS_VFP_VMRS_FPINST=y # # General architecture-dependent options # +CONFIG_SET_FS=y # CONFIG_OPROFILE is not set CONFIG_HAVE_OPROFILE=y # CONFIG_KPROBES is not set @@ -645,7 +648,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 @@ -672,6 +677,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 @@ -701,8 +707,9 @@ CONFIG_BLOCK=y CONFIG_BLK_SCSI_REQUEST=y CONFIG_BLK_CGROUP_RWSTAT=y CONFIG_BLK_DEV_BSG=y -# CONFIG_BLK_DEV_BSGLIB is not set -# CONFIG_BLK_DEV_INTEGRITY is not set +CONFIG_BLK_DEV_BSGLIB=y +CONFIG_BLK_DEV_INTEGRITY=y +CONFIG_BLK_DEV_INTEGRITY_T10=y # CONFIG_BLK_DEV_ZONED is not set CONFIG_BLK_DEV_THROTTLING=y # CONFIG_BLK_DEV_THROTTLING_LOW is not set @@ -820,7 +827,6 @@ CONFIG_ZPOOL=y CONFIG_ZBUD=y CONFIG_Z3FOLD=y CONFIG_ZSMALLOC=y -# CONFIG_ZSMALLOC_PGTABLE_MAPPING is not set # CONFIG_ZSMALLOC_STAT is not set CONFIG_GENERIC_EARLY_IOREMAP=y CONFIG_IDLE_PAGE_TRACKING=y @@ -1556,6 +1562,7 @@ CONFIG_CAN_RAW=m CONFIG_CAN_BCM=m CONFIG_CAN_GW=m CONFIG_CAN_J1939=m +# CONFIG_CAN_ISOTP is not set # # CAN Device Drivers @@ -1589,6 +1596,7 @@ CONFIG_CAN_SOFTING=m # CONFIG_CAN_HI311X=m CONFIG_CAN_MCP251X=y +# CONFIG_CAN_MCP251XFD is not set # end of CAN SPI interfaces # @@ -1809,7 +1817,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 @@ -1863,6 +1870,7 @@ CONFIG_VIRTIO_BLK=m # CONFIG_XILINX_SDFEC is not set CONFIG_MISC_RTSX=m # CONFIG_PVPANIC is not set +# CONFIG_HISI_HIKEY_USB is not set # CONFIG_C2PORT is not set # @@ -1887,13 +1895,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 is not set -# end of Intel MIC & related support - # CONFIG_ECHO is not set CONFIG_MISC_RTSX_USB=m # CONFIG_UACCE is not set @@ -1984,6 +1985,12 @@ CONFIG_DM_VERITY=y # CONFIG_DM_SWITCH is not set # CONFIG_DM_LOG_WRITES is not set # CONFIG_DM_INTEGRITY is not set +CONFIG_TARGET_CORE=m +CONFIG_TCM_IBLOCK=m +CONFIG_TCM_FILEIO=m +CONFIG_TCM_PSCSI=m +# CONFIG_LOOPBACK_TARGET is not set +CONFIG_ISCSI_TARGET=m CONFIG_NETDEVICES=y CONFIG_MII=y CONFIG_NET_CORE=y @@ -2036,6 +2043,7 @@ CONFIG_NET_DSA_MICROCHIP_KSZ8795_SPI=m CONFIG_NET_DSA_MV88E6XXX=m CONFIG_NET_DSA_MV88E6XXX_GLOBAL2=y # CONFIG_NET_DSA_MV88E6XXX_PTP is not set +# CONFIG_NET_DSA_MSCC_SEVILLE is not set # CONFIG_NET_DSA_AR9331 is not set CONFIG_NET_DSA_SJA1105=m # CONFIG_NET_DSA_SJA1105_PTP is not set @@ -2100,59 +2108,40 @@ CONFIG_STMMAC_PLATFORM=y # CONFIG_DWMAC_DWC_QOS_ETH is not set 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=y # CONFIG_XILINX_AXI_EMAC is not set # CONFIG_XILINX_LL_TEMAC 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=m -# CONFIG_MDIO_BUS_MUX_GPIO is not set -# CONFIG_MDIO_BUS_MUX_MMIOREG is not set -CONFIG_MDIO_BUS_MUX_MULTIPLEXER=m -# CONFIG_MDIO_HISI_FEMAC is not set -# CONFIG_MDIO_IPQ4019 is not set -# CONFIG_MDIO_IPQ8064 is not set -CONFIG_MDIO_MSCC_MIIM=m -# CONFIG_MDIO_MVUSB is not set -CONFIG_MDIO_XPCS=y CONFIG_PHYLINK=y CONFIG_PHYLIB=y CONFIG_SWPHY=y CONFIG_LED_TRIGGER_PHY=y +CONFIG_FIXED_PHY=y +# CONFIG_SFP is not set # # MII PHY device drivers # -# CONFIG_SFP is not set -CONFIG_ADIN_PHY=m # CONFIG_AMD_PHY is not set +CONFIG_ADIN_PHY=m # CONFIG_AQUANTIA_PHY is not set CONFIG_AX88796B_PHY=m -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=m -# 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 @@ -2166,12 +2155,43 @@ CONFIG_MICROCHIP_T1_PHY=m CONFIG_REALTEK_PHY=m # 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=m +# CONFIG_DP83848_PHY is not set +# CONFIG_DP83867_PHY is not set +# CONFIG_DP83869_PHY is not set CONFIG_VITESSE_PHY=m # 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=m +# CONFIG_MDIO_IPQ4019 is not set +# CONFIG_MDIO_IPQ8064 is not set + +# +# MDIO Multiplexers +# +CONFIG_MDIO_BUS_MUX=m +# CONFIG_MDIO_BUS_MUX_GPIO is not set +CONFIG_MDIO_BUS_MUX_MULTIPLEXER=m +# CONFIG_MDIO_BUS_MUX_MMIOREG is not set + +# +# PCS device drivers +# +CONFIG_PCS_XPCS=y +# end of PCS device drivers + CONFIG_PPP=m CONFIG_PPP_BSDCOMP=m CONFIG_PPP_DEFLATE=m @@ -2269,6 +2289,7 @@ CONFIG_ATH10K_USB=m # CONFIG_ATH10K_TRACING is not set CONFIG_WCN36XX=m # CONFIG_WCN36XX_DEBUGFS is not set +# CONFIG_ATH11K is not set CONFIG_WLAN_VENDOR_ATMEL=y CONFIG_AT76C50X_USB=m CONFIG_WLAN_VENDOR_BROADCOM=y @@ -2361,7 +2382,6 @@ CONFIG_WLAN_VENDOR_TI=y CONFIG_RTL8723DU=m CONFIG_RTL8723DS=m CONFIG_RTL8822BU=m -# CONFIG_RTL8188EU is not set CONFIG_RTL8821CU=m CONFIG_88XXAU=m CONFIG_RTL8192EU=m @@ -2452,6 +2472,7 @@ CONFIG_MOUSE_ELAN_I2C_I2C=y CONFIG_INPUT_JOYSTICK=y # CONFIG_JOYSTICK_ANALOG is not set # CONFIG_JOYSTICK_A3D is not set +# CONFIG_JOYSTICK_ADC is not set # CONFIG_JOYSTICK_ADI is not set # CONFIG_JOYSTICK_COBRA is not set # CONFIG_JOYSTICK_GF2K is not set @@ -2572,6 +2593,7 @@ CONFIG_TOUCHSCREEN_ZET6223=m # CONFIG_TOUCHSCREEN_ZFORCE is not set # CONFIG_TOUCHSCREEN_ROHM_BU21023 is not set CONFIG_TOUCHSCREEN_IQS5XX=m +# CONFIG_TOUCHSCREEN_ZINITIX is not set CONFIG_INPUT_MISC=y # CONFIG_INPUT_AD714X is not set # CONFIG_INPUT_ATMEL_CAPTOUCH is not set @@ -2615,6 +2637,7 @@ CONFIG_RMI4_F11=y CONFIG_RMI4_F12=y CONFIG_RMI4_F30=y # CONFIG_RMI4_F34 is not set +# CONFIG_RMI4_F3A is not set # CONFIG_RMI4_F54 is not set # CONFIG_RMI4_F55 is not set @@ -2717,6 +2740,7 @@ CONFIG_HW_RANDOM=y CONFIG_HW_RANDOM_VIRTIO=m 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 @@ -2798,6 +2822,7 @@ CONFIG_I2C_RK3X=y CONFIG_I2C_STUB=m CONFIG_I2C_SLAVE=y # CONFIG_I2C_SLAVE_EEPROM is not set +# 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 @@ -2883,6 +2908,12 @@ CONFIG_PINCTRL_ROCKCHIP=y # CONFIG_PINCTRL_STMFX is not set # CONFIG_PINCTRL_RK805 is not set # CONFIG_PINCTRL_OCELOT is not set + +# +# Renesas pinctrl drivers +# +# end of Renesas pinctrl drivers + CONFIG_PINCTRL_MADERA=m CONFIG_ARCH_HAVE_CUSTOM_GPIO_H=y CONFIG_GPIOLIB=y @@ -2891,6 +2922,8 @@ CONFIG_OF_GPIO=y CONFIG_GPIOLIB_IRQCHIP=y CONFIG_DEBUG_GPIO=y CONFIG_GPIO_SYSFS=y +CONFIG_GPIO_CDEV=y +CONFIG_GPIO_CDEV_V1=y CONFIG_GPIO_GENERIC=y # @@ -2995,9 +3028,6 @@ CONFIG_W1_SLAVE_DS2781=m # CONFIG_W1_SLAVE_DS28E17 is not set # end of 1-wire Slaves -CONFIG_POWER_AVS=y -# CONFIG_QCOM_CPR is not set -CONFIG_ROCKCHIP_IODOMAIN=y CONFIG_POWER_RESET=y # CONFIG_POWER_RESET_BRCMKONA is not set # CONFIG_POWER_RESET_BRCMSTB is not set @@ -3024,7 +3054,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=y # CONFIG_CHARGER_SBS is not set # CONFIG_MANAGER_SBS is not set @@ -3045,6 +3074,7 @@ CONFIG_CHARGER_GPIO=m # 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 @@ -3120,6 +3150,7 @@ CONFIG_SENSORS_GPIO_FAN=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 @@ -3364,6 +3395,7 @@ CONFIG_MFD_STPMIC1=m CONFIG_MFD_STMFX=m # 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 @@ -3410,7 +3442,10 @@ CONFIG_REGULATOR_GPIO=y # CONFIG_REGULATOR_PV88080 is not set # CONFIG_REGULATOR_PV88090 is not set CONFIG_REGULATOR_PWM=y +# 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_SLG51000 is not set # CONFIG_REGULATOR_STPMIC1 is not set # CONFIG_REGULATOR_SY8106A is not set @@ -3714,6 +3749,7 @@ CONFIG_VIDEO_XILINX_TPG=m CONFIG_VIDEO_XILINX_VTC=m CONFIG_V4L_MEM2MEM_DRIVERS=y # CONFIG_VIDEO_MEM2MEM_DEINTERLACE is not set +CONFIG_VIDEO_ROCKCHIP_IEP=m CONFIG_VIDEO_ROCKCHIP_RGA=m CONFIG_DVB_PLATFORM_DRIVERS=y CONFIG_DVB_C8SECTPFE=m @@ -4183,7 +4219,6 @@ CONFIG_DRM_UDL=y # CONFIG_DRM_RCAR_LVDS is not set # CONFIG_DRM_OMAP is not set # CONFIG_DRM_TILCDC is not set -# CONFIG_DRM_VIRTIO_GPU is not set # CONFIG_DRM_FSL_DCU is not set # CONFIG_DRM_STM is not set CONFIG_DRM_PANEL=y @@ -4222,6 +4257,7 @@ CONFIG_DRM_PANEL_BRIDGE=y # CONFIG_DRM_CDNS_DSI is not set # CONFIG_DRM_CHRONTEL_CH7033 is not set CONFIG_DRM_DISPLAY_CONNECTOR=m +# CONFIG_DRM_LONTIUM_LT9611 is not set # CONFIG_DRM_ITE_IT66121 is not set # CONFIG_DRM_LVDS_CODEC is not set # CONFIG_DRM_MEGACHIPS_STDPXXXX_GE_B850V3_FW is not set @@ -4234,15 +4270,18 @@ CONFIG_DRM_DISPLAY_CONNECTOR=m # CONFIG_DRM_SII9234 is not set CONFIG_DRM_SIMPLE_BRIDGE=m # 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=m @@ -4312,6 +4351,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 @@ -4482,6 +4522,7 @@ CONFIG_SND_SOC_CS35L36=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 @@ -4544,6 +4585,7 @@ CONFIG_SND_SOC_SSM2305=m # 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 @@ -4647,6 +4689,7 @@ CONFIG_HID_GFRM=m # CONFIG_HID_GLORIOUS is not set CONFIG_HID_HOLTEK=m CONFIG_HOLTEK_FF=y +# CONFIG_HID_VIVALDI is not set CONFIG_HID_GT683R=m CONFIG_HID_KEYTOUCH=m CONFIG_HID_KYE=m @@ -4753,6 +4796,7 @@ CONFIG_USB_ANNOUNCE_NEW_DEVICES=y # Miscellaneous USB options # # CONFIG_USB_DEFAULT_PERSIST is not set +# 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 @@ -4999,6 +5043,7 @@ CONFIG_USB_CONFIGFS_F_FS=y # CONFIG_USB_CONFIGFS_F_HID is not set # CONFIG_USB_CONFIGFS_F_UVC is not set # CONFIG_USB_CONFIGFS_F_PRINTER is not set +# CONFIG_USB_CONFIGFS_F_TCM is not set # # USB Gadget precomposed configurations @@ -5010,6 +5055,7 @@ CONFIG_USB_CONFIGFS_F_FS=y CONFIG_USB_GADGETFS=m # CONFIG_USB_FUNCTIONFS is not set CONFIG_USB_MASS_STORAGE=m +# CONFIG_USB_GADGET_TARGET is not set CONFIG_USB_G_SERIAL=m # CONFIG_USB_MIDI_GADGET is not set # CONFIG_USB_G_PRINTER is not set @@ -5023,7 +5069,7 @@ CONFIG_USB_G_HID=m # end of USB Gadget precomposed configurations # CONFIG_TYPEC is not set -CONFIG_USB_ROLE_SWITCH=m +CONFIG_USB_ROLE_SWITCH=y CONFIG_MMC=y CONFIG_PWRSEQ_EMMC=y CONFIG_PWRSEQ_SD8787=m @@ -5079,6 +5125,7 @@ CONFIG_LEDS_LM3532=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 @@ -5184,6 +5231,7 @@ CONFIG_RTC_DRV_RX8581=m CONFIG_RTC_DRV_RX8025=m CONFIG_RTC_DRV_EM3027=m CONFIG_RTC_DRV_RV3028=m +# CONFIG_RTC_DRV_RV3032 is not set CONFIG_RTC_DRV_RV8803=m CONFIG_RTC_DRV_SD3078=m @@ -5302,6 +5350,7 @@ CONFIG_VIRTIO=m # CONFIG_VDPA is not set CONFIG_VHOST_MENU=y # CONFIG_VHOST_NET is not set +# CONFIG_VHOST_SCSI is not set # CONFIG_VHOST_CROSS_ENDIAN_LEGACY is not set # @@ -5381,9 +5430,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=m # # Android @@ -5445,14 +5492,12 @@ CONFIG_ARCX_ANYBUS_CONTROLLER=m CONFIG_HMS_PROFINET=m # CONFIG_WFX is not set # CONFIG_GOLDFISH is not set -# CONFIG_MFD_CROS_EC is not set # CONFIG_CHROME_PLATFORMS is not set # CONFIG_MELLANOX_PLATFORM is not set 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_MAX9485=m CONFIG_COMMON_CLK_RK808=y # CONFIG_COMMON_CLK_SI5341 is not set @@ -5469,17 +5514,12 @@ CONFIG_COMMON_CLK_VC5=m # CONFIG_COMMON_CLK_BD718XX is not set # CONFIG_COMMON_CLK_FIXED_MMIO is not set CONFIG_COMMON_CLK_ROCKCHIP=y -# CONFIG_CLK_PX30 is not set # CONFIG_CLK_RV110X is not set # CONFIG_CLK_RK3036 is not set # CONFIG_CLK_RK312X is not set # CONFIG_CLK_RK3188 is not set CONFIG_CLK_RK322X=y # CONFIG_CLK_RK3288 is not set -# CONFIG_CLK_RK3308 is not set -# CONFIG_CLK_RK3328 is not set -# CONFIG_CLK_RK3368 is not set -# CONFIG_CLK_RK3399 is not set # CONFIG_HWSPINLOCK is not set # @@ -5576,6 +5616,7 @@ CONFIG_ROCKCHIP_IOMMU=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 @@ -5621,6 +5662,8 @@ CONFIG_PL353_SMC=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 @@ -5629,6 +5672,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 @@ -5844,6 +5888,7 @@ CONFIG_TI_DAC7612=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=m @@ -5875,6 +5920,7 @@ CONFIG_MAX30102=m # CONFIG_AM2315 is not set # CONFIG_DHT11 is not set # CONFIG_HDC100X is not set +# CONFIG_HDC2010 is not set CONFIG_HID_SENSOR_HUMIDITY=m # CONFIG_HTS221 is not set # CONFIG_HTU21 is not set @@ -5913,6 +5959,7 @@ CONFIG_IIO_ADIS_LIB_BUFFER=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 @@ -6112,6 +6159,7 @@ CONFIG_RESET_CONTROLLER=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 @@ -6125,6 +6173,7 @@ CONFIG_GENERIC_PHY=y # CONFIG_PHY_MAPPHONE_MDM6600 is not set # CONFIG_PHY_OCELOT_SERDES 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 @@ -6199,6 +6248,7 @@ CONFIG_PM_OPP=y # CONFIG_COUNTER is not set CONFIG_MOST=m # CONFIG_MOST_USB_HDM is not set +# CONFIG_MOST_CDEV is not set # end of Device Drivers # @@ -6229,6 +6279,7 @@ CONFIG_JFS_FS=m # CONFIG_JFS_DEBUG is not set # CONFIG_JFS_STATISTICS is not set CONFIG_XFS_FS=y +CONFIG_XFS_SUPPORT_V4=y CONFIG_XFS_QUOTA=y CONFIG_XFS_POSIX_ACL=y CONFIG_XFS_RT=y @@ -6393,6 +6444,24 @@ CONFIG_PSTORE_RAM=y # CONFIG_SYSV_FS is not set # CONFIG_UFS_FS is not set # CONFIG_EROFS_FS is not set +CONFIG_AUFS_FS=m +CONFIG_AUFS_BRANCH_MAX_127=y +# CONFIG_AUFS_BRANCH_MAX_511 is not set +# CONFIG_AUFS_BRANCH_MAX_1023 is not set +# CONFIG_AUFS_BRANCH_MAX_32767 is not set +CONFIG_AUFS_SBILIST=y +# CONFIG_AUFS_HNOTIFY is not set +# CONFIG_AUFS_EXPORT is not set +# CONFIG_AUFS_XATTR is not set +# CONFIG_AUFS_FHSM is not set +# CONFIG_AUFS_RDU is not set +# CONFIG_AUFS_DIRREN is not set +# CONFIG_AUFS_SHWH is not set +# CONFIG_AUFS_BR_RAMFS is not set +# CONFIG_AUFS_BR_FUSE is not set +CONFIG_AUFS_BR_HFSPLUS=y +CONFIG_AUFS_BDEV_LOOP=y +# CONFIG_AUFS_DEBUG is not set CONFIG_NETWORK_FILESYSTEMS=y CONFIG_NFS_FS=y CONFIG_NFS_V2=y @@ -6413,6 +6482,7 @@ CONFIG_NFS_FSCACHE=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=m CONFIG_NFSD_V2_ACL=y CONFIG_NFSD_V3=y @@ -6605,6 +6675,7 @@ CONFIG_CRYPTO_DH=m CONFIG_CRYPTO_ECC=y CONFIG_CRYPTO_ECDH=y CONFIG_CRYPTO_ECRDSA=m +# CONFIG_CRYPTO_SM2 is not set CONFIG_CRYPTO_CURVE25519=m # @@ -6703,7 +6774,7 @@ CONFIG_CRYPTO_LZO=y CONFIG_CRYPTO_842=m CONFIG_CRYPTO_LZ4=m CONFIG_CRYPTO_LZ4HC=m -CONFIG_CRYPTO_ZSTD=m +CONFIG_CRYPTO_ZSTD=y # # Random Number Generation @@ -6719,7 +6790,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 @@ -6854,6 +6927,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: @@ -7015,6 +7089,7 @@ CONFIG_DEBUG_SPINLOCK=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 @@ -7036,7 +7111,7 @@ CONFIG_DEBUG_CREDENTIALS=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=60 @@ -7122,12 +7197,3 @@ CONFIG_CC_HAS_SANCOV_TRACE_PC=y # CONFIG_MEMTEST is not set # end of Kernel Testing and Coverage # end of Kernel hacking - -## LinuxIO - iSCSI Target modules -CONFIG_TARGET_CORE=m -CONFIG_ISCSI_TARGET=m -CONFIG_TCM_IBLOCK=m -CONFIG_TCM_FILEIO=m -CONFIG_TCM_PSCSI=m -CONFIG_TCM_USER2=m - diff --git a/config/kernel/linux-rk322x-dev.config b/config/kernel/linux-rk322x-dev.config index e98336c7e..4d07a82b7 100644 --- a/config/kernel/linux-rk322x-dev.config +++ b/config/kernel/linux-rk322x-dev.config @@ -1,11 +1,11 @@ # # Automatically generated file; DO NOT EDIT. -# Linux/arm 5.10.2 Kernel Configuration +# Linux/arm 5.10.11 Kernel Configuration # -CONFIG_CC_VERSION_TEXT="arm-linux-gnueabihf-gcc (GNU Toolchain for the A-profile Architecture 8.3-2019.03 (arm-rel-8.36)) 8.3.0" +CONFIG_CC_VERSION_TEXT="arm-none-linux-gnueabihf-gcc (GNU Toolchain for the A-profile Architecture 9.2-2019.12 (arm-9.10)) 9.2.1 20191025" CONFIG_CC_IS_GCC=y -CONFIG_GCC_VERSION=80300 -CONFIG_LD_VERSION=232000000 +CONFIG_GCC_VERSION=90201 +CONFIG_LD_VERSION=233010000 CONFIG_CLANG_VERSION=0 CONFIG_LLD_VERSION=0 CONFIG_CC_CAN_LINK=y @@ -458,7 +458,7 @@ CONFIG_HIGHMEM=y CONFIG_CPU_SW_DOMAIN_PAN=y CONFIG_HW_PERF_EVENTS=y CONFIG_ARCH_WANT_GENERAL_HUGETLB=y -# CONFIG_ARM_MODULE_PLTS is not set +CONFIG_ARM_MODULE_PLTS=y CONFIG_FORCE_MAX_ZONEORDER=11 CONFIG_ALIGNMENT_TRAP=y # CONFIG_UACCESS_WITH_MEMCPY is not set @@ -2382,7 +2382,6 @@ CONFIG_WLAN_VENDOR_TI=y CONFIG_RTL8723DU=m CONFIG_RTL8723DS=m CONFIG_RTL8822BU=m -# CONFIG_RTL8188EU is not set CONFIG_RTL8821CU=m CONFIG_88XXAU=m CONFIG_RTL8192EU=m @@ -3348,7 +3347,6 @@ CONFIG_MFD_RK808=y # CONFIG_MFD_RN5T618 is not set # CONFIG_MFD_SEC_CORE is not set # CONFIG_MFD_SI476X_CORE is not set -# CONFIG_MFD_SL28CPLD is not set # CONFIG_MFD_SM501 is not set # CONFIG_MFD_SKY81452 is not set # CONFIG_ABX500_CORE is not set @@ -6446,6 +6444,24 @@ CONFIG_PSTORE_RAM=y # CONFIG_SYSV_FS is not set # CONFIG_UFS_FS is not set # CONFIG_EROFS_FS is not set +CONFIG_AUFS_FS=m +CONFIG_AUFS_BRANCH_MAX_127=y +# CONFIG_AUFS_BRANCH_MAX_511 is not set +# CONFIG_AUFS_BRANCH_MAX_1023 is not set +# CONFIG_AUFS_BRANCH_MAX_32767 is not set +CONFIG_AUFS_SBILIST=y +# CONFIG_AUFS_HNOTIFY is not set +# CONFIG_AUFS_EXPORT is not set +# CONFIG_AUFS_XATTR is not set +# CONFIG_AUFS_FHSM is not set +# CONFIG_AUFS_RDU is not set +# CONFIG_AUFS_DIRREN is not set +# CONFIG_AUFS_SHWH is not set +# CONFIG_AUFS_BR_RAMFS is not set +# CONFIG_AUFS_BR_FUSE is not set +CONFIG_AUFS_BR_HFSPLUS=y +CONFIG_AUFS_BDEV_LOOP=y +# CONFIG_AUFS_DEBUG is not set CONFIG_NETWORK_FILESYSTEMS=y CONFIG_NFS_FS=y CONFIG_NFS_V2=y @@ -6758,7 +6774,7 @@ CONFIG_CRYPTO_LZO=y CONFIG_CRYPTO_842=m CONFIG_CRYPTO_LZ4=m CONFIG_CRYPTO_LZ4HC=m -CONFIG_CRYPTO_ZSTD=m +CONFIG_CRYPTO_ZSTD=y # # Random Number Generation diff --git a/config/sources/families/rk322x.conf b/config/sources/families/rk322x.conf index 87d9f4b10..55fccedcf 100644 --- a/config/sources/families/rk322x.conf +++ b/config/sources/families/rk322x.conf @@ -19,13 +19,13 @@ case $BRANCH in current) - KERNELBRANCH='branch:linux-5.9.y' + KERNELBRANCH='branch:linux-5.10.y' AUFS=no ;; dev) - + KERNELBRANCH='branch:linux-5.10.y' ;; diff --git a/patch/kernel/rk322x-current/01-linux-0001-rockchip-from-5.10.patch b/patch/kernel/rk322x-current/01-linux-0001-rockchip-from-5.10.patch deleted file mode 100644 index e1b9d3fd2..000000000 --- a/patch/kernel/rk322x-current/01-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/patch/kernel/rk322x-current/01-linux-0001-rockchip-from-5.11.patch b/patch/kernel/rk322x-current/01-linux-0001-rockchip-from-5.11.patch new file mode 100644 index 000000000..13b9e2f14 --- /dev/null +++ b/patch/kernel/rk322x-current/01-linux-0001-rockchip-from-5.11.patch @@ -0,0 +1,3068 @@ +From 93de290d002cac9222e016bb48d282b35c689353 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 df8307c7c4dcf0bcf76f69a5c6b8ecb47c566de3 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 57cf1e01e2ed0c872497e718bce48b98a06ccb1d 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 c5be4065b3fb2d42db4e7d6d95423511dfffa596 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 bd1838a094e5113fd1c7d8c3d5e36ec49f614f08 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 96e1b41524b9c3cb8b9d450521ad30b938859a31 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 f15b2a03cbc0cbfd08b0b543b7c273a6d753e631 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 1de943bc8e6bf152225132d3b567fadc8bc2ff33 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 305d5bd60f58e8cd6dfab32816d12d02e2abc588 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 5ef3bab6462c92e5c00c797f3dcef44aee443e9a 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 9270ef5be7427db50b66203333c6cf0ffb191eee 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 81ca19e8c044c0c9da10e67388e2da9826d93522 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 b9c5dc81af0fa847fb92e0cb00ed5667d5e5ec60 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 eece97f97ef8..d13d2d497720 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 ade714b4c3d73ce2b15553b48e688e8a48bdd507 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 136e645cf9702547dba873c750a4a75fc493b72b 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 d7d96382a38e550f3e71a7493bb2117dae59f97e 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 c601f0d90ef10d5eb0a75afc5c80247f3132323a 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 893d460175d5f58b6b8261e52d6f82194e272c9d 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 edec2b3926f851d98de012957e82e4f589befac1 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 4ddefb6af82f66601c6a4eaf1314079ec1db1ead 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 a5c4a953bb29f031ab5a49a708ef301359944edd 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 91cb8ac48a887d5618ee0fd5a350f73a9245253d 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 9ebf52a74362a2d2b2c3dfb420e8ade811a43515 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 df1d881202ddf2b96a0c5b439871d5959393312a 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 3cb90f8d11317b126a800de92315ed9a0a9cf8c8 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 68aedb4279e38d8239d1d21bd41b1b5d5e78c58c 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 747e7ee30c4449248930b59ad3fc85b00755a7ae 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 ffc19f1963ebb4486fb937d414d28f11c8fa75cc 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 88fb28b232443748f7d042edca3642af886f3db2 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 ecd43c736a17fd2b94fbf6906f82644d59308578 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 d01ef5f08562372dc033e10c57013441648e2e92 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 2e2289b3f7d5d2cef6839b8c4a2a306c215ef3c2 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 fc75f80b0ad9c752c1b6577b08345f239c3bffa1 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 c6c8b0eb1d8c2b9d5304d4ab499a85e547191c2e 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 4d3a2f9408852759d9ce29942492b71404c313a9 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 0c65b8b53cf672fc0a61187831cb5afe4324541d 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 6e7e897fb23b7291fbabda014628aba1a71dff79 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 7625c015b090c9519be3f8bd803707cb40cc78cb 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 fbefd7709351bf494227d8f17c1baf65e97a01a1 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/patch/kernel/rk322x-current/01-linux-1000-rockchip-soc-from-list.patch b/patch/kernel/rk322x-current/01-linux-0002-rockchip-from-list.patch similarity index 83% rename from patch/kernel/rk322x-current/01-linux-1000-rockchip-soc-from-list.patch rename to patch/kernel/rk322x-current/01-linux-0002-rockchip-from-list.patch index dad45e753..57995c53f 100644 --- a/patch/kernel/rk322x-current/01-linux-1000-rockchip-soc-from-list.patch +++ b/patch/kernel/rk322x-current/01-linux-0002-rockchip-from-list.patch @@ -1,1997 +1,4 @@ -From faf0035972ca91afdf899bd9e5150b6a1e91bf8a Mon Sep 17 00:00:00 2001 -From: Yifeng Zhao -Date: Wed, 28 Oct 2020 17:53:23 +0800 -Subject: [PATCH] dt-bindings: mtd: Describe Rockchip RK3xxx NAND flash - controller - -Documentation support for Rockchip RK3xxx NAND flash controllers - -Signed-off-by: Yifeng Zhao ---- - .../mtd/rockchip,nand-controller.yaml | 161 ++++++++++++++++++ - 1 file changed, 161 insertions(+) - create mode 100644 Documentation/devicetree/bindings/mtd/rockchip,nand-controller.yaml - -diff --git a/Documentation/devicetree/bindings/mtd/rockchip,nand-controller.yaml b/Documentation/devicetree/bindings/mtd/rockchip,nand-controller.yaml -new file mode 100644 -index 000000000000..0922536b1811 ---- /dev/null -+++ b/Documentation/devicetree/bindings/mtd/rockchip,nand-controller.yaml -@@ -0,0 +1,161 @@ -+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) -+%YAML 1.2 -+--- -+$id: http://devicetree.org/schemas/mtd/rockchip,nand-controller.yaml# -+$schema: http://devicetree.org/meta-schemas/core.yaml# -+ -+title: Rockchip SoCs NAND FLASH Controller (NFC) -+ -+allOf: -+ - $ref: "nand-controller.yaml#" -+ -+maintainers: -+ - Heiko Stuebner -+ -+properties: -+ compatible: -+ oneOf: -+ - const: rockchip,px30-nfc -+ - const: rockchip,rk2928-nfc -+ - const: rockchip,rv1108-nfc -+ - items: -+ - const: rockchip,rk3036-nfc -+ - const: rockchip,rk2928-nfc -+ - items: -+ - const: rockchip,rk3308-nfc -+ - const: rockchip,rv1108-nfc -+ -+ reg: -+ maxItems: 1 -+ -+ interrupts: -+ maxItems: 1 -+ -+ clocks: -+ minItems: 1 -+ items: -+ - description: Bus Clock -+ - description: Module Clock -+ -+ clock-names: -+ minItems: 1 -+ items: -+ - const: ahb -+ - const: nfc -+ -+ assigned-clocks: -+ maxItems: 1 -+ -+ assigned-clock-rates: -+ maxItems: 1 -+ -+ power-domains: -+ maxItems: 1 -+ -+patternProperties: -+ "^nand@[0-7]$": -+ type: object -+ properties: -+ reg: -+ minimum: 0 -+ maximum: 7 -+ -+ nand-ecc-mode: -+ const: hw -+ -+ nand-ecc-step-size: -+ const: 1024 -+ -+ nand-ecc-strength: -+ enum: [16, 24, 40, 60, 70] -+ description: | -+ The ECC configurations that can be supported are as follows. -+ NFC v600 ECC 16, 24, 40, 60 -+ RK2928, RK3066, RK3188 -+ -+ NFC v622 ECC 16, 24, 40, 60 -+ RK3036, RK3128 -+ -+ NFC v800 ECC 16 -+ RK3308, RV1108 -+ -+ NFC v900 ECC 16, 40, 60, 70 -+ RK3326, PX30 -+ -+ nand-bus-width: -+ const: 8 -+ -+ rockchip,boot-blks: -+ $ref: /schemas/types.yaml#/definitions/uint32 -+ minimum: 2 -+ default: 16 -+ description: -+ The NFC driver need this information to select ECC -+ algorithms supported by the boot ROM. -+ Only used in combination with 'nand-is-boot-medium'. -+ -+ rockchip,boot-ecc-strength: -+ enum: [16, 24, 40, 60, 70] -+ allOf: -+ - $ref: /schemas/types.yaml#/definitions/uint32 -+ description: | -+ If specified it indicates that a different BCH/ECC setting is -+ supported by the boot ROM. -+ NFC v600 ECC 16, 24 -+ RK2928, RK3066, RK3188 -+ -+ NFC v622 ECC 16, 24, 40, 60 -+ RK3036, RK3128 -+ -+ NFC v800 ECC 16 -+ RK3308, RV1108 -+ -+ NFC v900 ECC 16, 70 -+ RK3326, PX30 -+ -+ Only used in combination with 'nand-is-boot-medium'. -+ -+required: -+ - compatible -+ - reg -+ - interrupts -+ - clocks -+ - clock-names -+ -+unevaluatedProperties: false -+ -+examples: -+ - | -+ #include -+ #include -+ nfc: nand-controller@ff4b0000 { -+ compatible = "rockchip,rk3308-nfc", -+ "rockchip,rv1108-nfc"; -+ reg = <0xff4b0000 0x4000>; -+ interrupts = ; -+ clocks = <&cru HCLK_NANDC>, <&cru SCLK_NANDC>; -+ clock-names = "ahb", "nfc"; -+ assigned-clocks = <&clks SCLK_NANDC>; -+ assigned-clock-rates = <150000000>; -+ -+ pinctrl-0 = <&flash_ale &flash_bus8 &flash_cle &flash_csn0 -+ &flash_rdn &flash_rdy &flash_wrn>; -+ pinctrl-names = "default"; -+ -+ #address-cells = <1>; -+ #size-cells = <0>; -+ -+ nand@0 { -+ reg = <0>; -+ label = "rk-nand"; -+ nand-bus-width = <8>; -+ nand-ecc-mode = "hw"; -+ nand-ecc-step-size = <1024>; -+ nand-ecc-strength = <16>; -+ nand-is-boot-medium; -+ rockchip,boot-blks = <8>; -+ rockchip,boot-ecc-strength = <16>; -+ }; -+ }; -+ -+... - -From f64fb6b73198e05bdd443330c56f67f32152604f Mon Sep 17 00:00:00 2001 -From: Yifeng Zhao -Date: Wed, 28 Oct 2020 17:53:24 +0800 -Subject: [PATCH] mtd: rawnand: rockchip: NFC drivers for RK3308, RK2928 and - others - -This driver supports Rockchip NFC (NAND Flash Controller) found on RK3308, -RK2928, RKPX30, RV1108 and other SOCs. The driver has been tested using -8-bit NAND interface on the ARM based RK3308 platform. - -Support Rockchip SoCs and NFC versions: -- PX30 and RK3326(NFCv900). - ECC: 16/40/60/70 bits/1KB. - CLOCK: ahb and nfc. -- RK3308 and RV1108(NFCv800). - ECC: 16 bits/1KB. - CLOCK: ahb and nfc. -- RK3036 and RK3128(NFCv622). - ECC: 16/24/40/60 bits/1KB. - CLOCK: ahb and nfc. -- RK3066, RK3188 and RK2928(NFCv600). - ECC: 16/24/40/60 bits/1KB. - CLOCK: ahb. - -Supported features: -- Read full page data by DMA. -- Support HW ECC(one step is 1KB). -- Support 2 - 32K page size. -- Support 8 CS(depend on SoCs) - -Limitations: -- No support for the ecc step size is 512. -- Untested on some SoCs. -- No support for subpages. -- No support for the builtin randomizer. -- The original bad block mask is not supported. It is recommended to use - the BBT(bad block table). - -Signed-off-by: Yifeng Zhao ---- - drivers/mtd/nand/raw/Kconfig | 12 + - drivers/mtd/nand/raw/Makefile | 1 + - .../mtd/nand/raw/rockchip-nand-controller.c | 1460 +++++++++++++++++ - 3 files changed, 1473 insertions(+) - create mode 100644 drivers/mtd/nand/raw/rockchip-nand-controller.c - -diff --git a/drivers/mtd/nand/raw/Kconfig b/drivers/mtd/nand/raw/Kconfig -index 1203775023ad..af0ed098ca0c 100644 ---- a/drivers/mtd/nand/raw/Kconfig -+++ b/drivers/mtd/nand/raw/Kconfig -@@ -461,6 +461,18 @@ config MTD_NAND_ARASAN - Enables the driver for the Arasan NAND flash controller on - Zynq Ultrascale+ MPSoC. - -+config MTD_NAND_ROCKCHIP -+ tristate "Rockchip NAND controller" -+ depends on ARCH_ROCKCHIP && HAS_IOMEM -+ help -+ Enables support for NAND controller on Rockchip SoCs. -+ There are four different versions of NAND FLASH Controllers, -+ including: -+ NFC v600: RK2928, RK3066, RK3188 -+ NFC v622: RK3036, RK3128 -+ NFC v800: RK3308, RV1108 -+ NFC v900: PX30, RK3326 -+ - comment "Misc" - - config MTD_SM_COMMON -diff --git a/drivers/mtd/nand/raw/Makefile b/drivers/mtd/nand/raw/Makefile -index 2930f5b9015d..960c9be25204 100644 ---- a/drivers/mtd/nand/raw/Makefile -+++ b/drivers/mtd/nand/raw/Makefile -@@ -58,6 +58,7 @@ obj-$(CONFIG_MTD_NAND_STM32_FMC2) += stm32_fmc2_nand.o - obj-$(CONFIG_MTD_NAND_MESON) += meson_nand.o - obj-$(CONFIG_MTD_NAND_CADENCE) += cadence-nand-controller.o - obj-$(CONFIG_MTD_NAND_ARASAN) += arasan-nand-controller.o -+obj-$(CONFIG_MTD_NAND_ROCKCHIP) += rockchip-nand-controller.o - - nand-objs := nand_base.o nand_legacy.o nand_bbt.o nand_timings.o nand_ids.o - nand-objs += nand_onfi.o -diff --git a/drivers/mtd/nand/raw/rockchip-nand-controller.c b/drivers/mtd/nand/raw/rockchip-nand-controller.c -new file mode 100644 -index 000000000000..2e96fd314346 ---- /dev/null -+++ b/drivers/mtd/nand/raw/rockchip-nand-controller.c -@@ -0,0 +1,1460 @@ -+// SPDX-License-Identifier: GPL-2.0 OR MIT -+/* -+ * Rockchip NAND Flash controller driver. -+ * Copyright (C) 2020 Rockchip Inc. -+ * Author: Yifeng Zhao -+ */ -+ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+ -+/* -+ * NFC Page Data Layout: -+ * 1024 Bytes Data + 4Bytes sys data + 28Bytes~124Bytes ecc + -+ * 1024 Bytes Data + 4Bytes sys data + 28Bytes~124Bytes ecc + -+ * ...... -+ * NAND Page Data Layout: -+ * 1024 * n Data + m Bytes oob -+ * Original Bad Block Mask Location: -+ * First byte of oob(spare). -+ * nand_chip->oob_poi data layout: -+ * 4Bytes sys data + .... + 4Bytes sys data + ecc data. -+ */ -+ -+/* NAND controller register definition */ -+#define NFC_READ (0) -+#define NFC_WRITE (1) -+ -+#define NFC_FMCTL (0x00) -+#define FMCTL_CE_SEL_M 0xFF -+#define FMCTL_CE_SEL(x) (1 << (x)) -+#define FMCTL_WP BIT(8) -+#define FMCTL_RDY BIT(9) -+ -+#define NFC_FMWAIT (0x04) -+#define FLCTL_RST BIT(0) -+#define FLCTL_WR (1) /* 0: read, 1: write */ -+#define FLCTL_XFER_ST BIT(2) -+#define FLCTL_XFER_EN BIT(3) -+#define FLCTL_ACORRECT BIT(10) /* Auto correct error bits. */ -+#define FLCTL_XFER_READY BIT(20) -+#define FLCTL_XFER_SECTOR (22) -+#define FLCTL_TOG_FIX BIT(29) -+ -+#define BCHCTL_BANK_M (7 << 5) -+#define BCHCTL_BANK (5) -+ -+#define DMA_ST BIT(0) -+#define DMA_WR (1) /* 0: write, 1: read */ -+#define DMA_EN BIT(2) -+#define DMA_AHB_SIZE (3) /* 0: 1, 1: 2, 2: 4 */ -+#define DMA_BURST_SIZE (6) /* 0: 1, 3: 4, 5: 8, 7: 16 */ -+#define DMA_INC_NUM (9) /* 1 - 16 */ -+ -+#define ECC_ERR_CNT(x, e) ((((x) >> (e).low) & (e).low_mask) |\ -+ (((x) >> (e).high) & (e).high_mask) << (e).low_bn) -+#define INT_DMA BIT(0) -+#define NFC_BANK (0x800) -+#define NFC_BANK_STEP (0x100) -+#define BANK_DATA (0x00) -+#define BANK_ADDR (0x04) -+#define BANK_CMD (0x08) -+#define NFC_SRAM0 (0x1000) -+#define NFC_SRAM1 (0x1400) -+#define NFC_SRAM_SIZE (0x400) -+#define NFC_TIMEOUT (500000) -+#define NFC_MAX_OOB_PER_STEP 128 -+#define NFC_MIN_OOB_PER_STEP 64 -+#define MAX_DATA_SIZE 0xFFFC -+#define MAX_ADDRESS_CYC 6 -+#define NFC_ECC_MAX_MODES 4 -+#define NFC_MAX_NSELS (8) /* Some Socs only have 1 or 2 CSs. */ -+#define NFC_SYS_DATA_SIZE (4) /* 4 bytes sys data in oob pre 1024 data.*/ -+#define RK_DEFAULT_CLOCK_RATE (150 * 1000 * 1000) /* 150 Mhz */ -+#define ACCTIMING(csrw, rwpw, rwcs) ((csrw) << 12 | (rwpw) << 5 | (rwcs)) -+ -+enum nfc_type { -+ NFC_V6, -+ NFC_V8, -+ NFC_V9, -+}; -+ -+/** -+ * struct rk_ecc_cnt_status: represent a ecc status data. -+ * @err_flag_bit: error flag bit index at register. -+ * @low: ecc count low bit index at register. -+ * @low_mask: mask bit. -+ * @low_bn: ecc count low bit number. -+ * @high: ecc count high bit index at register. -+ * @high_mask: mask bit -+ */ -+struct ecc_cnt_status { -+ u8 err_flag_bit; -+ u8 low; -+ u8 low_mask; -+ u8 low_bn; -+ u8 high; -+ u8 high_mask; -+}; -+ -+/* -+ * @type: nfc version -+ * @ecc_strengths: ecc strengths -+ * @ecc_cfgs: ecc config values -+ * @flctl_off: FLCTL register offset -+ * @bchctl_off: BCHCTL register offset -+ * @dma_data_buf_off: DMA_DATA_BUF register offset -+ * @dma_oob_buf_off: DMA_OOB_BUF register offset -+ * @dma_cfg_off: DMA_CFG register offset -+ * @dma_st_off: DMA_ST register offset -+ * @bch_st_off: BCG_ST register offset -+ * @randmz_off: RANDMZ register offset -+ * @int_en_off: interrupt enable register offset -+ * @int_clr_off: interrupt clean register offset -+ * @int_st_off: interrupt status register offset -+ * @oob0_off: oob0 register offset -+ * @oob1_off: oob1 register offset -+ * @ecc0: represent ECC0 status data -+ * @ecc1: represent ECC1 status data -+ */ -+struct nfc_cfg { -+ enum nfc_type type; -+ u8 ecc_strengths[NFC_ECC_MAX_MODES]; -+ u32 ecc_cfgs[NFC_ECC_MAX_MODES]; -+ u32 flctl_off; -+ u32 bchctl_off; -+ u32 dma_cfg_off; -+ u32 dma_data_buf_off; -+ u32 dma_oob_buf_off; -+ u32 dma_st_off; -+ u32 bch_st_off; -+ u32 randmz_off; -+ u32 int_en_off; -+ u32 int_clr_off; -+ u32 int_st_off; -+ u32 oob0_off; -+ u32 oob1_off; -+ struct ecc_cnt_status ecc0; -+ struct ecc_cnt_status ecc1; -+}; -+ -+struct rk_nfc_nand_chip { -+ struct list_head node; -+ struct nand_chip chip; -+ -+ u16 spare_per_sector; -+ u16 oob_buf_per_sector; -+ u16 boot_blks; -+ u16 boot_ecc; -+ u16 metadata_size; -+ -+ u8 nsels; -+ u8 sels[0]; -+ /* Nothing after this field. */ -+}; -+ -+struct rk_nfc { -+ struct nand_controller controller; -+ const struct nfc_cfg *cfg; -+ struct device *dev; -+ -+ struct clk *nfc_clk; -+ struct clk *ahb_clk; -+ void __iomem *regs; -+ -+ u32 selected_bank; -+ u32 band_offset; -+ u32 cur_clk; -+ -+ struct completion done; -+ struct list_head chips; -+ -+ u8 *buffer; -+ u8 *page_buf; -+ u32 *oob_buf; -+ u32 buffer_size; -+ u32 oob_buf_size; -+ -+ unsigned long assigned_cs; -+}; -+ -+static inline struct rk_nfc_nand_chip *rk_nfc_to_rknand(struct nand_chip *chip) -+{ -+ return container_of(chip, struct rk_nfc_nand_chip, chip); -+} -+ -+static inline u8 *rk_nfc_buf_to_data_ptr(struct nand_chip *chip, const u8 *p, int i) -+{ -+ return (u8 *)p + i * chip->ecc.size; -+} -+ -+static inline u8 *rk_nfc_buf_to_oob_ptr(struct nand_chip *chip, int i) -+{ -+ u8 *poi; -+ -+ poi = chip->oob_poi + i * NFC_SYS_DATA_SIZE; -+ -+ return poi; -+} -+ -+static inline u8 *rk_nfc_buf_to_oob_ecc_ptr(struct nand_chip *chip, int i) -+{ -+ struct rk_nfc_nand_chip *rknand = rk_nfc_to_rknand(chip); -+ u8 *poi; -+ -+ poi = chip->oob_poi + rknand->metadata_size + -+ chip->ecc.bytes * i; -+ -+ return poi; -+} -+ -+static inline int rk_nfc_data_len(struct nand_chip *chip) -+{ -+ struct rk_nfc_nand_chip *rknand = rk_nfc_to_rknand(chip); -+ -+ return chip->ecc.size + rknand->spare_per_sector; -+} -+ -+static inline u8 *rk_nfc_data_ptr(struct nand_chip *chip, int i) -+{ -+ struct rk_nfc *nfc = nand_get_controller_data(chip); -+ -+ return nfc->buffer + i * rk_nfc_data_len(chip); -+} -+ -+static inline u8 *rk_nfc_oob_ptr(struct nand_chip *chip, int i) -+{ -+ struct rk_nfc *nfc = nand_get_controller_data(chip); -+ -+ return nfc->buffer + i * rk_nfc_data_len(chip) + chip->ecc.size; -+} -+ -+static void rk_nfc_select_chip(struct nand_chip *chip, int cs) -+{ -+ struct rk_nfc *nfc = nand_get_controller_data(chip); -+ struct rk_nfc_nand_chip *rknand = rk_nfc_to_rknand(chip); -+ u32 val; -+ -+ if (cs < 0) { -+ nfc->selected_bank = -1; -+ /* Deselect the currently selected target. */ -+ val = readl_relaxed(nfc->regs + NFC_FMCTL); -+ val &= ~FMCTL_CE_SEL_M; -+ writel(val, nfc->regs + NFC_FMCTL); -+ return; -+ } -+ -+ nfc->selected_bank = rknand->sels[cs]; -+ nfc->band_offset = NFC_BANK + nfc->selected_bank * NFC_BANK_STEP; -+ -+ val = readl_relaxed(nfc->regs + NFC_FMCTL); -+ val &= ~FMCTL_CE_SEL_M; -+ val |= FMCTL_CE_SEL(nfc->selected_bank); -+ -+ writel(val, nfc->regs + NFC_FMCTL); -+} -+ -+static inline int rk_nfc_wait_ioready(struct rk_nfc *nfc) -+{ -+ int rc; -+ u32 val; -+ -+ rc = readl_relaxed_poll_timeout(nfc->regs + NFC_FMCTL, val, -+ val & FMCTL_RDY, 10, NFC_TIMEOUT); -+ -+ return rc; -+} -+ -+static void rk_nfc_read_buf(struct rk_nfc *nfc, u8 *buf, int len) -+{ -+ int i; -+ -+ for (i = 0; i < len; i++) -+ buf[i] = readb_relaxed(nfc->regs + nfc->band_offset + -+ BANK_DATA); -+} -+ -+static void rk_nfc_write_buf(struct rk_nfc *nfc, const u8 *buf, int len) -+{ -+ int i; -+ -+ for (i = 0; i < len; i++) -+ writeb(buf[i], nfc->regs + nfc->band_offset + BANK_DATA); -+} -+ -+static int rk_nfc_cmd(struct nand_chip *chip, -+ const struct nand_subop *subop) -+{ -+ struct rk_nfc *nfc = nand_get_controller_data(chip); -+ unsigned int i, j, remaining, start; -+ int reg_offset = nfc->band_offset; -+ u8 *inbuf = NULL; -+ const u8 *outbuf; -+ u32 cnt = 0; -+ int ret = 0; -+ -+ for (i = 0; i < subop->ninstrs; i++) { -+ const struct nand_op_instr *instr = &subop->instrs[i]; -+ -+ switch (instr->type) { -+ case NAND_OP_CMD_INSTR: -+ writeb(instr->ctx.cmd.opcode, -+ nfc->regs + reg_offset + BANK_CMD); -+ break; -+ -+ case NAND_OP_ADDR_INSTR: -+ remaining = nand_subop_get_num_addr_cyc(subop, i); -+ start = nand_subop_get_addr_start_off(subop, i); -+ -+ for (j = 0; j < 8 && j + start < remaining; j++) -+ writeb(instr->ctx.addr.addrs[j + start], -+ nfc->regs + reg_offset + BANK_ADDR); -+ break; -+ -+ case NAND_OP_DATA_IN_INSTR: -+ case NAND_OP_DATA_OUT_INSTR: -+ start = nand_subop_get_data_start_off(subop, i); -+ cnt = nand_subop_get_data_len(subop, i); -+ -+ if (instr->type == NAND_OP_DATA_OUT_INSTR) { -+ outbuf = instr->ctx.data.buf.out + start; -+ rk_nfc_write_buf(nfc, outbuf, cnt); -+ } else { -+ inbuf = instr->ctx.data.buf.in + start; -+ rk_nfc_read_buf(nfc, inbuf, cnt); -+ } -+ break; -+ -+ case NAND_OP_WAITRDY_INSTR: -+ if (rk_nfc_wait_ioready(nfc) < 0) { -+ ret = -ETIMEDOUT; -+ dev_err(nfc->dev, "IO not ready\n"); -+ } -+ break; -+ } -+ } -+ -+ return ret; -+} -+ -+static const struct nand_op_parser rk_nfc_op_parser = NAND_OP_PARSER( -+ NAND_OP_PARSER_PATTERN( -+ rk_nfc_cmd, -+ NAND_OP_PARSER_PAT_CMD_ELEM(true), -+ NAND_OP_PARSER_PAT_ADDR_ELEM(true, MAX_ADDRESS_CYC), -+ NAND_OP_PARSER_PAT_CMD_ELEM(true), -+ NAND_OP_PARSER_PAT_WAITRDY_ELEM(true), -+ NAND_OP_PARSER_PAT_DATA_IN_ELEM(true, MAX_DATA_SIZE)), -+ NAND_OP_PARSER_PATTERN( -+ rk_nfc_cmd, -+ NAND_OP_PARSER_PAT_CMD_ELEM(true), -+ NAND_OP_PARSER_PAT_ADDR_ELEM(true, MAX_ADDRESS_CYC), -+ NAND_OP_PARSER_PAT_DATA_OUT_ELEM(true, MAX_DATA_SIZE), -+ NAND_OP_PARSER_PAT_CMD_ELEM(true), -+ NAND_OP_PARSER_PAT_WAITRDY_ELEM(true)), -+); -+ -+static int rk_nfc_exec_op(struct nand_chip *chip, -+ const struct nand_operation *op, -+ bool check_only) -+{ -+ if (!check_only) -+ rk_nfc_select_chip(chip, op->cs); -+ -+ return nand_op_parser_exec_op(chip, &rk_nfc_op_parser, op, -+ check_only); -+} -+ -+static int rk_nfc_setup_data_interface(struct nand_chip *chip, int csline, -+ const struct nand_interface_config *conf) -+{ -+ struct rk_nfc *nfc = nand_get_controller_data(chip); -+ const struct nand_sdr_timings *timings; -+ u32 rate, tc2rw, trwpw, trw2c; -+ u32 temp; -+ -+ if (csline == NAND_DATA_IFACE_CHECK_ONLY) -+ return 0; -+ -+ timings = nand_get_sdr_timings(conf); -+ if (IS_ERR(timings)) -+ return -EOPNOTSUPP; -+ -+ if (IS_ERR(nfc->nfc_clk)) -+ rate = clk_get_rate(nfc->ahb_clk); -+ else -+ rate = clk_get_rate(nfc->nfc_clk); -+ -+ /* Turn clock rate into kHz. */ -+ rate /= 1000; -+ -+ tc2rw = 1; -+ trw2c = 1; -+ -+ trwpw = max(timings->tWC_min, timings->tRC_min) / 1000; -+ trwpw = DIV_ROUND_UP(trwpw * rate, 1000000); -+ -+ temp = timings->tREA_max / 1000; -+ temp = DIV_ROUND_UP(temp * rate, 1000000); -+ -+ if (trwpw < temp) -+ trwpw = temp; -+ -+ /* -+ * ACCON: access timing control register -+ * ------------------------------------- -+ * 31:18: reserved -+ * 17:12: csrw, clock cycles from the falling edge of CSn to the -+ * falling edge of RDn or WRn -+ * 11:11: reserved -+ * 10:05: rwpw, the width of RDn or WRn in processor clock cycles -+ * 04:00: rwcs, clock cycles from the rising edge of RDn or WRn to the -+ * rising edge of CSn -+ */ -+ temp = ACCTIMING(tc2rw, trwpw, trw2c); -+ writel(temp, nfc->regs + NFC_FMWAIT); -+ -+ return 0; -+} -+ -+static int rk_nfc_hw_ecc_setup(struct nand_chip *chip, -+ struct nand_ecc_ctrl *ecc, -+ uint32_t strength) -+{ -+ struct rk_nfc *nfc = nand_get_controller_data(chip); -+ u32 reg, i; -+ -+ for (i = 0; i < NFC_ECC_MAX_MODES; i++) { -+ if (ecc->strength == nfc->cfg->ecc_strengths[i]) { -+ reg = nfc->cfg->ecc_cfgs[i]; -+ break; -+ } -+ } -+ -+ if (i >= NFC_ECC_MAX_MODES) -+ return -EINVAL; -+ -+ writel(reg, nfc->regs + nfc->cfg->bchctl_off); -+ -+ return 0; -+} -+ -+static void rk_nfc_xfer_start(struct rk_nfc *nfc, u8 rw, u8 n_KB, -+ dma_addr_t dma_data, dma_addr_t dma_oob) -+{ -+ u32 dma_reg, fl_reg, bch_reg; -+ -+ dma_reg = DMA_ST | ((!rw) << DMA_WR) | DMA_EN | (2 << DMA_AHB_SIZE) | -+ (7 << DMA_BURST_SIZE) | (16 << DMA_INC_NUM); -+ -+ fl_reg = (rw << FLCTL_WR) | FLCTL_XFER_EN | FLCTL_ACORRECT | -+ (n_KB << FLCTL_XFER_SECTOR) | FLCTL_TOG_FIX; -+ -+ if (nfc->cfg->type == NFC_V6 || nfc->cfg->type == NFC_V8) { -+ bch_reg = readl_relaxed(nfc->regs + nfc->cfg->bchctl_off); -+ bch_reg = (bch_reg & (~BCHCTL_BANK_M)) | -+ (nfc->selected_bank << BCHCTL_BANK); -+ writel(bch_reg, nfc->regs + nfc->cfg->bchctl_off); -+ } -+ -+ writel(dma_reg, nfc->regs + nfc->cfg->dma_cfg_off); -+ writel((u32)dma_data, nfc->regs + nfc->cfg->dma_data_buf_off); -+ writel((u32)dma_oob, nfc->regs + nfc->cfg->dma_oob_buf_off); -+ writel(fl_reg, nfc->regs + nfc->cfg->flctl_off); -+ fl_reg |= FLCTL_XFER_ST; -+ writel(fl_reg, nfc->regs + nfc->cfg->flctl_off); -+} -+ -+static int rk_nfc_wait_for_xfer_done(struct rk_nfc *nfc) -+{ -+ void __iomem *ptr; -+ int ret = 0; -+ u32 reg; -+ -+ ptr = nfc->regs + nfc->cfg->flctl_off; -+ -+ ret = readl_relaxed_poll_timeout(ptr, reg, -+ reg & FLCTL_XFER_READY, -+ 10, NFC_TIMEOUT); -+ -+ return ret; -+} -+ -+static int rk_nfc_write_page_raw(struct nand_chip *chip, const u8 *buf, -+ int oob_on, int page) -+{ -+ struct mtd_info *mtd = nand_to_mtd(chip); -+ struct rk_nfc *nfc = nand_get_controller_data(chip); -+ struct nand_ecc_ctrl *ecc = &chip->ecc; -+ int ret = 0; -+ u32 i; -+ -+ if (!buf) -+ memset(nfc->buffer, 0xff, mtd->writesize + mtd->oobsize); -+ -+ for (i = 0; i < ecc->steps; i++) { -+ /* Copy data to nfc buffer. */ -+ if (buf) -+ memcpy(rk_nfc_data_ptr(chip, i), -+ rk_nfc_buf_to_data_ptr(chip, buf, i), -+ ecc->size); -+ /* -+ * The first four bytes of OOB are reserved for the -+ * boot ROM. In some debugging cases, such as with a -+ * read, erase and write back test these 4 bytes stored -+ * in OOB also need to be written back. -+ */ -+ if (!i) -+ memcpy(rk_nfc_oob_ptr(chip, i), -+ rk_nfc_buf_to_oob_ptr(chip, ecc->steps - 1), -+ NFC_SYS_DATA_SIZE); -+ else -+ memcpy(rk_nfc_oob_ptr(chip, i), -+ rk_nfc_buf_to_oob_ptr(chip, i - 1), -+ NFC_SYS_DATA_SIZE); -+ /* Copy ECC data to the NFC buffer. */ -+ memcpy(rk_nfc_oob_ptr(chip, i) + NFC_SYS_DATA_SIZE, -+ rk_nfc_buf_to_oob_ecc_ptr(chip, i), -+ ecc->bytes); -+ } -+ -+ nand_prog_page_begin_op(chip, page, 0, NULL, 0); -+ rk_nfc_write_buf(nfc, buf, mtd->writesize + mtd->oobsize); -+ ret = nand_prog_page_end_op(chip); -+ -+ /* -+ * Deselect the currently selected target after the ops is done -+ * to reduce the power consumption. -+ */ -+ rk_nfc_select_chip(chip, -1); -+ -+ return ret; -+} -+ -+static int rk_nfc_write_oob(struct nand_chip *chip, int page) -+{ -+ return rk_nfc_write_page_raw(chip, NULL, 1, page); -+} -+ -+static int rk_nfc_write_page_hwecc(struct nand_chip *chip, const u8 *buf, -+ int oob_on, int page) -+{ -+ struct mtd_info *mtd = nand_to_mtd(chip); -+ struct rk_nfc *nfc = nand_get_controller_data(chip); -+ struct rk_nfc_nand_chip *rknand = rk_nfc_to_rknand(chip); -+ struct nand_ecc_ctrl *ecc = &chip->ecc; -+ int oob_step = (ecc->bytes > 60) ? NFC_MAX_OOB_PER_STEP : -+ NFC_MIN_OOB_PER_STEP; -+ int pages_per_blk = mtd->erasesize / mtd->writesize; -+ int ret = 0, i, boot_rom_mode = 0; -+ dma_addr_t dma_data, dma_oob; -+ u32 reg; -+ u8 *oob; -+ -+ nand_prog_page_begin_op(chip, page, 0, NULL, 0); -+ -+ memcpy(nfc->page_buf, buf, mtd->writesize); -+ -+ /* -+ * The first blocks (4, 8 or 16 depending on the device) are used -+ * by the boot ROM and the first 32 bits of OOB need to link to -+ * the next page address in the same block. We can't directly copy -+ * OOB data from the MTD framework, because this page address -+ * conflicts for example with the bad block marker (BBM), -+ * so we shift all OOB data including the BBM with 4 byte positions. -+ * As a consequence the OOB size available to the MTD framework is -+ * also reduced with 4 bytes. -+ * -+ * PA0 PA1 PA2 PA3 | BBM OOB1 OOB2 OOB3 | ... -+ * -+ * If a NAND is not a boot medium or the page is not a boot block, -+ * the first 4 bytes are left untouched by writing 0xFF to them. -+ * -+ * 0xFF 0xFF 0xFF 0xFF | BBM OOB1 OOB2 OOB3 | ... -+ * -+ * Configure the ECC algorithm supported by the boot ROM. -+ */ -+ if ((page < pages_per_blk * rknand->boot_blks) && -+ (chip->options & NAND_IS_BOOT_MEDIUM)) { -+ boot_rom_mode = 1; -+ if (rknand->boot_ecc != ecc->strength) -+ rk_nfc_hw_ecc_setup(chip, ecc, -+ rknand->boot_ecc); -+ } -+ -+ for (i = 0; i < ecc->steps; i++) { -+ if (!i) { -+ reg = 0xFFFFFFFF; -+ } else { -+ oob = chip->oob_poi + (i - 1) * NFC_SYS_DATA_SIZE; -+ reg = oob[0] | oob[1] << 8 | oob[2] << 16 | -+ oob[3] << 24; -+ } -+ if (!i && boot_rom_mode) -+ reg = (page & (pages_per_blk - 1)) * 4; -+ -+ if (nfc->cfg->type == NFC_V9) -+ nfc->oob_buf[i] = reg; -+ else -+ nfc->oob_buf[i * (oob_step / 4)] = reg; -+ } -+ -+ dma_data = dma_map_single(nfc->dev, (void *)nfc->page_buf, -+ mtd->writesize, DMA_TO_DEVICE); -+ dma_oob = dma_map_single(nfc->dev, nfc->oob_buf, -+ ecc->steps * oob_step, -+ DMA_TO_DEVICE); -+ -+ reinit_completion(&nfc->done); -+ writel(INT_DMA, nfc->regs + nfc->cfg->int_en_off); -+ -+ rk_nfc_xfer_start(nfc, NFC_WRITE, ecc->steps, dma_data, -+ dma_oob); -+ ret = wait_for_completion_timeout(&nfc->done, -+ msecs_to_jiffies(100)); -+ if (!ret) -+ dev_warn(nfc->dev, "write: wait dma done timeout.\n"); -+ /* -+ * Whether the DMA transfer is completed or not. The driver -+ * needs to check the NFC`s status register to see if the data -+ * transfer was completed. -+ */ -+ ret = rk_nfc_wait_for_xfer_done(nfc); -+ -+ dma_unmap_single(nfc->dev, dma_data, mtd->writesize, -+ DMA_TO_DEVICE); -+ dma_unmap_single(nfc->dev, dma_oob, ecc->steps * oob_step, -+ DMA_TO_DEVICE); -+ -+ if (boot_rom_mode && rknand->boot_ecc != ecc->strength) -+ rk_nfc_hw_ecc_setup(chip, ecc, ecc->strength); -+ -+ if (ret) { -+ ret = -EIO; -+ dev_err(nfc->dev, -+ "write: wait transfer done timeout.\n"); -+ } -+ -+ if (ret) -+ return ret; -+ -+ ret = nand_prog_page_end_op(chip); -+ -+ /* -+ * Deselect the currently selected target after the ops is done -+ * to reduce the power consumption. -+ */ -+ rk_nfc_select_chip(chip, -1); -+ -+ return ret; -+} -+ -+static int rk_nfc_read_page_raw(struct nand_chip *chip, u8 *buf, int oob_on, -+ int page) -+{ -+ struct mtd_info *mtd = nand_to_mtd(chip); -+ struct rk_nfc *nfc = nand_get_controller_data(chip); -+ struct nand_ecc_ctrl *ecc = &chip->ecc; -+ int i; -+ -+ nand_read_page_op(chip, page, 0, NULL, 0); -+ rk_nfc_read_buf(nfc, nfc->buffer, mtd->writesize + mtd->oobsize); -+ -+ /* -+ * Deselect the currently selected target after the ops is done -+ * to reduce the power consumption. -+ */ -+ rk_nfc_select_chip(chip, -1); -+ -+ for (i = 0; i < ecc->steps; i++) { -+ /* -+ * The first four bytes of OOB are reserved for the -+ * boot ROM. In some debugging cases, such as with a read, -+ * erase and write back test, these 4 bytes also must be -+ * saved somewhere, otherwise this information will be -+ * lost during a write back. -+ */ -+ if (!i) -+ memcpy(rk_nfc_buf_to_oob_ptr(chip, ecc->steps - 1), -+ rk_nfc_oob_ptr(chip, i), -+ NFC_SYS_DATA_SIZE); -+ else -+ memcpy(rk_nfc_buf_to_oob_ptr(chip, i - 1), -+ rk_nfc_oob_ptr(chip, i), -+ NFC_SYS_DATA_SIZE); -+ /* Copy ECC data from the NFC buffer. */ -+ memcpy(rk_nfc_buf_to_oob_ecc_ptr(chip, i), -+ rk_nfc_oob_ptr(chip, i) + NFC_SYS_DATA_SIZE, -+ ecc->bytes); -+ /* Copy data from the NFC buffer. */ -+ if (buf) -+ memcpy(rk_nfc_buf_to_data_ptr(chip, buf, i), -+ rk_nfc_data_ptr(chip, i), -+ ecc->size); -+ } -+ -+ return 0; -+} -+ -+static int rk_nfc_read_oob(struct nand_chip *chip, int page) -+{ -+ return rk_nfc_read_page_raw(chip, NULL, 1, page); -+} -+ -+static int rk_nfc_read_page_hwecc(struct nand_chip *chip, u8 *buf, int oob_on, -+ int page) -+{ -+ struct mtd_info *mtd = nand_to_mtd(chip); -+ struct rk_nfc *nfc = nand_get_controller_data(chip); -+ struct rk_nfc_nand_chip *rknand = rk_nfc_to_rknand(chip); -+ struct nand_ecc_ctrl *ecc = &chip->ecc; -+ int oob_step = (ecc->bytes > 60) ? NFC_MAX_OOB_PER_STEP : -+ NFC_MIN_OOB_PER_STEP; -+ int pages_per_blk = mtd->erasesize / mtd->writesize; -+ dma_addr_t dma_data, dma_oob; -+ int ret = 0, i, boot_rom_mode = 0; -+ int bitflips = 0, bch_st; -+ u8 *oob; -+ u32 tmp; -+ -+ nand_read_page_op(chip, page, 0, NULL, 0); -+ -+ dma_data = dma_map_single(nfc->dev, nfc->page_buf, -+ mtd->writesize, -+ DMA_FROM_DEVICE); -+ dma_oob = dma_map_single(nfc->dev, nfc->oob_buf, -+ ecc->steps * oob_step, -+ DMA_FROM_DEVICE); -+ -+ /* -+ * The first blocks (4, 8 or 16 depending on the device) -+ * are used by the boot ROM. -+ * Configure the ECC algorithm supported by the boot ROM. -+ */ -+ if ((page < pages_per_blk * rknand->boot_blks) && -+ (chip->options & NAND_IS_BOOT_MEDIUM)) { -+ boot_rom_mode = 1; -+ if (rknand->boot_ecc != ecc->strength) -+ rk_nfc_hw_ecc_setup(chip, ecc, -+ rknand->boot_ecc); -+ } -+ -+ reinit_completion(&nfc->done); -+ writel(INT_DMA, nfc->regs + nfc->cfg->int_en_off); -+ rk_nfc_xfer_start(nfc, NFC_READ, ecc->steps, dma_data, -+ dma_oob); -+ ret = wait_for_completion_timeout(&nfc->done, -+ msecs_to_jiffies(100)); -+ if (!ret) -+ dev_warn(nfc->dev, "read: wait dma done timeout.\n"); -+ /* -+ * Whether the DMA transfer is completed or not. The driver -+ * needs to check the NFC`s status register to see if the data -+ * transfer was completed. -+ */ -+ ret = rk_nfc_wait_for_xfer_done(nfc); -+ dma_unmap_single(nfc->dev, dma_data, mtd->writesize, -+ DMA_FROM_DEVICE); -+ dma_unmap_single(nfc->dev, dma_oob, ecc->steps * oob_step, -+ DMA_FROM_DEVICE); -+ -+ if (ret) { -+ bitflips = -EIO; -+ dev_err(nfc->dev, -+ "read: wait transfer done timeout.\n"); -+ goto out; -+ } -+ -+ for (i = 1; i < ecc->steps; i++) { -+ oob = chip->oob_poi + (i - 1) * NFC_SYS_DATA_SIZE; -+ if (nfc->cfg->type == NFC_V9) -+ tmp = nfc->oob_buf[i]; -+ else -+ tmp = nfc->oob_buf[i * (oob_step / 4)]; -+ *oob++ = (u8)tmp; -+ *oob++ = (u8)(tmp >> 8); -+ *oob++ = (u8)(tmp >> 16); -+ *oob++ = (u8)(tmp >> 24); -+ } -+ -+ for (i = 0; i < (ecc->steps / 2); i++) { -+ bch_st = readl_relaxed(nfc->regs + -+ nfc->cfg->bch_st_off + i * 4); -+ if (bch_st & BIT(nfc->cfg->ecc0.err_flag_bit) || -+ bch_st & BIT(nfc->cfg->ecc1.err_flag_bit)) { -+ mtd->ecc_stats.failed++; -+ bitflips = 0; -+ } else { -+ ret = ECC_ERR_CNT(bch_st, nfc->cfg->ecc0); -+ mtd->ecc_stats.corrected += ret; -+ bitflips = max_t(u32, bitflips, ret); -+ -+ ret = ECC_ERR_CNT(bch_st, nfc->cfg->ecc1); -+ mtd->ecc_stats.corrected += ret; -+ bitflips = max_t(u32, bitflips, ret); -+ } -+ } -+out: -+ memcpy(buf, nfc->page_buf, mtd->writesize); -+ -+ if (boot_rom_mode && rknand->boot_ecc != ecc->strength) -+ rk_nfc_hw_ecc_setup(chip, ecc, ecc->strength); -+ -+ if (bitflips > ecc->strength) -+ dev_err(nfc->dev, "read page: %x ecc error!\n", page); -+ -+ /* -+ * Deselect the currently selected target after the ops is done -+ * to reduce the power consumption. -+ */ -+ rk_nfc_select_chip(chip, -1); -+ -+ return bitflips; -+} -+ -+static inline void rk_nfc_hw_init(struct rk_nfc *nfc) -+{ -+ /* Disable flash wp. */ -+ writel(FMCTL_WP, nfc->regs + NFC_FMCTL); -+ /* Config default timing 40ns at 150 Mhz nfc clock. */ -+ writel(0x1081, nfc->regs + NFC_FMWAIT); -+ /* Disable randomizer and DMA. */ -+ writel(0, nfc->regs + nfc->cfg->randmz_off); -+ writel(0, nfc->regs + nfc->cfg->dma_cfg_off); -+ writel(FLCTL_RST, nfc->regs + nfc->cfg->flctl_off); -+} -+ -+static irqreturn_t rk_nfc_irq(int irq, void *id) -+{ -+ struct rk_nfc *nfc = id; -+ u32 sta, ien; -+ -+ sta = readl_relaxed(nfc->regs + nfc->cfg->int_st_off); -+ ien = readl_relaxed(nfc->regs + nfc->cfg->int_en_off); -+ -+ if (!(sta & ien)) -+ return IRQ_NONE; -+ -+ writel(sta, nfc->regs + nfc->cfg->int_clr_off); -+ writel(~sta & ien, nfc->regs + nfc->cfg->int_en_off); -+ -+ complete(&nfc->done); -+ -+ return IRQ_HANDLED; -+} -+ -+static int rk_nfc_enable_clks(struct device *dev, struct rk_nfc *nfc) -+{ -+ int ret; -+ -+ if (!IS_ERR(nfc->nfc_clk)) { -+ ret = clk_prepare_enable(nfc->nfc_clk); -+ if (ret) { -+ dev_err(dev, "failed to enable nfc clk\n"); -+ return ret; -+ } -+ } -+ -+ ret = clk_prepare_enable(nfc->ahb_clk); -+ if (ret) { -+ dev_err(dev, "failed to enable ahb clk\n"); -+ if (!IS_ERR(nfc->nfc_clk)) -+ clk_disable_unprepare(nfc->nfc_clk); -+ return ret; -+ } -+ -+ return 0; -+} -+ -+static void rk_nfc_disable_clks(struct rk_nfc *nfc) -+{ -+ if (!IS_ERR(nfc->nfc_clk)) -+ clk_disable_unprepare(nfc->nfc_clk); -+ clk_disable_unprepare(nfc->ahb_clk); -+} -+ -+static int rk_nfc_ooblayout_free(struct mtd_info *mtd, int section, -+ struct mtd_oob_region *oob_region) -+{ -+ struct nand_chip *chip = mtd_to_nand(mtd); -+ struct rk_nfc_nand_chip *rknand = rk_nfc_to_rknand(chip); -+ -+ if (section) -+ return -ERANGE; -+ -+ /* -+ * The beginning of the OOB area stores the reserved data for the NFC, -+ * the size of the reserved data is NFC_SYS_DATA_SIZE bytes. -+ */ -+ oob_region->length = rknand->metadata_size - NFC_SYS_DATA_SIZE - 2; -+ oob_region->offset = NFC_SYS_DATA_SIZE + 2; -+ -+ return 0; -+} -+ -+static int rk_nfc_ooblayout_ecc(struct mtd_info *mtd, int section, -+ struct mtd_oob_region *oob_region) -+{ -+ struct nand_chip *chip = mtd_to_nand(mtd); -+ struct rk_nfc_nand_chip *rknand = rk_nfc_to_rknand(chip); -+ -+ if (section) -+ return -ERANGE; -+ -+ oob_region->length = mtd->oobsize - rknand->metadata_size; -+ oob_region->offset = rknand->metadata_size; -+ -+ return 0; -+} -+ -+static const struct mtd_ooblayout_ops rk_nfc_ooblayout_ops = { -+ .free = rk_nfc_ooblayout_free, -+ .ecc = rk_nfc_ooblayout_ecc, -+}; -+ -+static int rk_nfc_ecc_init(struct device *dev, struct mtd_info *mtd) -+{ -+ struct nand_chip *chip = mtd_to_nand(mtd); -+ struct rk_nfc *nfc = nand_get_controller_data(chip); -+ struct nand_ecc_ctrl *ecc = &chip->ecc; -+ const u8 *strengths = nfc->cfg->ecc_strengths; -+ u8 max_strength, nfc_max_strength; -+ int i; -+ -+ nfc_max_strength = nfc->cfg->ecc_strengths[0]; -+ /* If optional dt settings not present. */ -+ if (!ecc->size || !ecc->strength || -+ ecc->strength > nfc_max_strength) { -+ chip->ecc.size = 1024; -+ ecc->steps = mtd->writesize / ecc->size; -+ -+ /* -+ * HW ECC always requests the number of ECC bytes per 1024 byte -+ * blocks. The first 4 OOB bytes are reserved for sys data. -+ */ -+ max_strength = ((mtd->oobsize / ecc->steps) - 4) * 8 / -+ fls(8 * 1024); -+ if (max_strength > nfc_max_strength) -+ max_strength = nfc_max_strength; -+ -+ for (i = 0; i < 4; i++) { -+ if (max_strength >= strengths[i]) -+ break; -+ } -+ -+ if (i >= 4) { -+ dev_err(nfc->dev, "Unsupported ECC strength\n"); -+ return -EOPNOTSUPP; -+ } -+ -+ ecc->strength = strengths[i]; -+ } -+ ecc->steps = mtd->writesize / ecc->size; -+ ecc->bytes = DIV_ROUND_UP(ecc->strength * fls(8 * 1024), 8); -+ /* HW ECC always work with even numbers of ECC bytes. */ -+ ecc->bytes = ALIGN(ecc->bytes, 2); -+ -+ rk_nfc_hw_ecc_setup(chip, ecc, ecc->strength); -+ -+ return 0; -+} -+ -+static int rk_nfc_attach_chip(struct nand_chip *chip) -+{ -+ struct mtd_info *mtd = nand_to_mtd(chip); -+ struct device *dev = mtd->dev.parent; -+ struct rk_nfc *nfc = nand_get_controller_data(chip); -+ struct rk_nfc_nand_chip *rknand = rk_nfc_to_rknand(chip); -+ struct nand_ecc_ctrl *ecc = &chip->ecc; -+ int new_len, new_oob_len; -+ void *buf; -+ int ret; -+ -+ if (chip->options & NAND_BUSWIDTH_16) { -+ dev_err(dev, "16 bits bus width not supported"); -+ return -EINVAL; -+ } -+ -+ if (ecc->engine_type != NAND_ECC_ENGINE_TYPE_ON_HOST) -+ return 0; -+ -+ ret = rk_nfc_ecc_init(dev, mtd); -+ if (ret) -+ return ret; -+ rknand->spare_per_sector = ecc->bytes + NFC_SYS_DATA_SIZE; -+ rknand->metadata_size = NFC_SYS_DATA_SIZE * ecc->steps; -+ -+ if (rknand->metadata_size < NFC_SYS_DATA_SIZE + 2) { -+ dev_err(dev, -+ "Driver needs at least %d bytes of meta data\n", -+ NFC_SYS_DATA_SIZE + 2); -+ return -EIO; -+ } -+ -+ /* Check buffer first, avoid duplicate alloc buffer. */ -+ new_len = mtd->writesize + mtd->oobsize; -+ if (nfc->buffer && new_len > nfc->buffer_size) { -+ buf = krealloc(nfc->buffer, new_len, GFP_KERNEL | GFP_DMA); -+ if (!buf) -+ return -ENOMEM; -+ nfc->buffer = buf; -+ nfc->buffer_size = new_len; -+ } -+ -+ new_oob_len = ecc->steps * NFC_MAX_OOB_PER_STEP; -+ if (nfc->oob_buf && new_oob_len > nfc->oob_buf_size) { -+ buf = krealloc(nfc->oob_buf, new_oob_len, -+ GFP_KERNEL | GFP_DMA); -+ if (!buf) { -+ kfree(nfc->buffer); -+ nfc->buffer = NULL; -+ return -ENOMEM; -+ } -+ nfc->oob_buf = buf; -+ nfc->oob_buf_size = new_oob_len; -+ } -+ -+ if (!nfc->buffer) { -+ nfc->buffer = kzalloc(new_len, GFP_KERNEL | GFP_DMA); -+ if (!nfc->buffer) -+ return -ENOMEM; -+ nfc->buffer_size = new_len; -+ } -+ -+ if (!nfc->oob_buf) { -+ nfc->oob_buf = kzalloc(new_oob_len, GFP_KERNEL | GFP_DMA); -+ if (!nfc->oob_buf) { -+ kfree(nfc->buffer); -+ nfc->buffer = NULL; -+ return -ENOMEM; -+ } -+ nfc->oob_buf_size = new_oob_len; -+ } -+ -+ nfc->page_buf = nfc->buffer; -+ -+ chip->ecc.write_page_raw = rk_nfc_write_page_raw; -+ chip->ecc.write_page = rk_nfc_write_page_hwecc; -+ chip->ecc.write_oob_raw = rk_nfc_write_oob; -+ chip->ecc.write_oob = rk_nfc_write_oob; -+ -+ chip->ecc.read_page_raw = rk_nfc_read_page_raw; -+ chip->ecc.read_page = rk_nfc_read_page_hwecc; -+ chip->ecc.read_oob_raw = rk_nfc_read_oob; -+ chip->ecc.read_oob = rk_nfc_read_oob; -+ -+ return 0; -+} -+ -+static const struct nand_controller_ops rk_nfc_controller_ops = { -+ .attach_chip = rk_nfc_attach_chip, -+ .exec_op = rk_nfc_exec_op, -+ .setup_interface = rk_nfc_setup_data_interface, -+}; -+ -+static int rk_nfc_nand_chip_init(struct device *dev, struct rk_nfc *nfc, -+ struct device_node *np) -+{ -+ struct rk_nfc_nand_chip *rknand; -+ struct nand_chip *chip; -+ struct mtd_info *mtd; -+ int nsels; -+ u32 tmp; -+ int ret; -+ int i; -+ -+ if (!of_get_property(np, "reg", &nsels)) -+ return -ENODEV; -+ nsels /= sizeof(u32); -+ if (!nsels || nsels > NFC_MAX_NSELS) { -+ dev_err(dev, "invalid reg property size %d\n", nsels); -+ return -EINVAL; -+ } -+ -+ rknand = devm_kzalloc(dev, sizeof(*rknand) + nsels * sizeof(u8), -+ GFP_KERNEL); -+ if (!rknand) -+ return -ENOMEM; -+ -+ rknand->nsels = nsels; -+ for (i = 0; i < nsels; i++) { -+ ret = of_property_read_u32_index(np, "reg", i, &tmp); -+ if (ret) { -+ dev_err(dev, "reg property failure : %d\n", ret); -+ return ret; -+ } -+ -+ if (tmp >= NFC_MAX_NSELS) { -+ dev_err(dev, "invalid CS: %u\n", tmp); -+ return -EINVAL; -+ } -+ -+ if (test_and_set_bit(tmp, &nfc->assigned_cs)) { -+ dev_err(dev, "CS %u already assigned\n", tmp); -+ return -EINVAL; -+ } -+ -+ rknand->sels[i] = tmp; -+ } -+ -+ chip = &rknand->chip; -+ chip->controller = &nfc->controller; -+ -+ nand_set_flash_node(chip, np); -+ -+ nand_set_controller_data(chip, nfc); -+ -+ chip->options |= NAND_USES_DMA | NAND_NO_SUBPAGE_WRITE; -+ chip->bbt_options = NAND_BBT_USE_FLASH | NAND_BBT_NO_OOB; -+ -+ /* Set default mode in case dt entry is missing. */ -+ chip->ecc.engine_type = NAND_ECC_ENGINE_TYPE_ON_HOST; -+ -+ mtd = nand_to_mtd(chip); -+ mtd->owner = THIS_MODULE; -+ mtd->dev.parent = dev; -+ -+ if (!mtd->name) { -+ dev_err(nfc->dev, "NAND label property is mandatory\n"); -+ return -EINVAL; -+ } -+ -+ mtd_set_ooblayout(mtd, &rk_nfc_ooblayout_ops); -+ rk_nfc_hw_init(nfc); -+ ret = nand_scan(chip, nsels); -+ if (ret) -+ return ret; -+ -+ if (chip->options & NAND_IS_BOOT_MEDIUM) { -+ ret = of_property_read_u32(np, "rockchip,boot-blks", &tmp); -+ rknand->boot_blks = ret ? 0 : tmp; -+ -+ ret = of_property_read_u32(np, "rockchip,boot-ecc-strength", -+ &tmp); -+ rknand->boot_ecc = ret ? chip->ecc.strength : tmp; -+ } -+ -+ ret = mtd_device_register(mtd, NULL, 0); -+ if (ret) { -+ dev_err(dev, "mtd parse partition error\n"); -+ nand_cleanup(chip); -+ return ret; -+ } -+ -+ list_add_tail(&rknand->node, &nfc->chips); -+ -+ return 0; -+} -+ -+static void rk_nfc_chips_cleanup(struct rk_nfc *nfc) -+{ -+ struct rk_nfc_nand_chip *rknand, *tmp; -+ struct nand_chip *chip; -+ int ret; -+ -+ list_for_each_entry_safe(rknand, tmp, &nfc->chips, node) { -+ chip = &rknand->chip; -+ ret = mtd_device_unregister(nand_to_mtd(chip)); -+ WARN_ON(ret); -+ nand_cleanup(chip); -+ list_del(&rknand->node); -+ } -+} -+ -+static int rk_nfc_nand_chips_init(struct device *dev, struct rk_nfc *nfc) -+{ -+ struct device_node *np = dev->of_node, *nand_np; -+ int nchips = of_get_child_count(np); -+ int ret; -+ -+ if (!nchips || nchips > NFC_MAX_NSELS) { -+ dev_err(nfc->dev, "Incorrect number of NAND chips (%d)\n", -+ nchips); -+ return -EINVAL; -+ } -+ -+ for_each_child_of_node(np, nand_np) { -+ ret = rk_nfc_nand_chip_init(dev, nfc, nand_np); -+ if (ret) { -+ of_node_put(nand_np); -+ rk_nfc_chips_cleanup(nfc); -+ return ret; -+ } -+ } -+ -+ return 0; -+} -+ -+static struct nfc_cfg nfc_v6_cfg = { -+ .type = NFC_V6, -+ .ecc_strengths = {60, 40, 24, 16}, -+ .ecc_cfgs = { -+ 0x00040011, 0x00040001, 0x00000011, 0x00000001, -+ }, -+ .flctl_off = 0x08, -+ .bchctl_off = 0x0C, -+ .dma_cfg_off = 0x10, -+ .dma_data_buf_off = 0x14, -+ .dma_oob_buf_off = 0x18, -+ .dma_st_off = 0x1C, -+ .bch_st_off = 0x20, -+ .randmz_off = 0x150, -+ .int_en_off = 0x16C, -+ .int_clr_off = 0x170, -+ .int_st_off = 0x174, -+ .oob0_off = 0x200, -+ .oob1_off = 0x230, -+ .ecc0 = { -+ .err_flag_bit = 2, -+ .low = 3, -+ .low_mask = 0x1F, -+ .low_bn = 5, -+ .high = 27, -+ .high_mask = 0x1, -+ }, -+ .ecc1 = { -+ .err_flag_bit = 15, -+ .low = 16, -+ .low_mask = 0x1F, -+ .low_bn = 5, -+ .high = 29, -+ .high_mask = 0x1, -+ }, -+}; -+ -+static struct nfc_cfg nfc_v8_cfg = { -+ .type = NFC_V8, -+ .ecc_strengths = {16, 16, 16, 16}, -+ .ecc_cfgs = { -+ 0x00000001, 0x00000001, 0x00000001, 0x00000001, -+ }, -+ .flctl_off = 0x08, -+ .bchctl_off = 0x0C, -+ .dma_cfg_off = 0x10, -+ .dma_data_buf_off = 0x14, -+ .dma_oob_buf_off = 0x18, -+ .dma_st_off = 0x1C, -+ .bch_st_off = 0x20, -+ .randmz_off = 0x150, -+ .int_en_off = 0x16C, -+ .int_clr_off = 0x170, -+ .int_st_off = 0x174, -+ .oob0_off = 0x200, -+ .oob1_off = 0x230, -+ .ecc0 = { -+ .err_flag_bit = 2, -+ .low = 3, -+ .low_mask = 0x1F, -+ .low_bn = 5, -+ .high = 27, -+ .high_mask = 0x1, -+ }, -+ .ecc1 = { -+ .err_flag_bit = 15, -+ .low = 16, -+ .low_mask = 0x1F, -+ .low_bn = 5, -+ .high = 29, -+ .high_mask = 0x1, -+ }, -+}; -+ -+static struct nfc_cfg nfc_v9_cfg = { -+ .type = NFC_V9, -+ .ecc_strengths = {70, 60, 40, 16}, -+ .ecc_cfgs = { -+ 0x00000001, 0x06000001, 0x04000001, 0x02000001, -+ }, -+ .flctl_off = 0x10, -+ .bchctl_off = 0x20, -+ .dma_cfg_off = 0x30, -+ .dma_data_buf_off = 0x34, -+ .dma_oob_buf_off = 0x38, -+ .dma_st_off = 0x3C, -+ .bch_st_off = 0x150, -+ .randmz_off = 0x208, -+ .int_en_off = 0x120, -+ .int_clr_off = 0x124, -+ .int_st_off = 0x128, -+ .oob0_off = 0x200, -+ .oob1_off = 0x204, -+ .ecc0 = { -+ .err_flag_bit = 2, -+ .low = 3, -+ .low_mask = 0x7F, -+ .low_bn = 7, -+ .high = 0, -+ .high_mask = 0x0, -+ }, -+ .ecc1 = { -+ .err_flag_bit = 18, -+ .low = 19, -+ .low_mask = 0x7F, -+ .low_bn = 7, -+ .high = 0, -+ .high_mask = 0x0, -+ }, -+}; -+ -+static const struct of_device_id rk_nfc_id_table[] = { -+ { -+ .compatible = "rockchip,px30-nfc", -+ .data = &nfc_v9_cfg -+ }, -+ { -+ .compatible = "rockchip,rk2928-nfc", -+ .data = &nfc_v6_cfg -+ }, -+ { -+ .compatible = "rockchip,rv1108-nfc", -+ .data = &nfc_v8_cfg -+ }, -+ { /* sentinel */ } -+}; -+MODULE_DEVICE_TABLE(of, rk_nfc_id_table); -+ -+static int rk_nfc_probe(struct platform_device *pdev) -+{ -+ struct device *dev = &pdev->dev; -+ struct rk_nfc *nfc; -+ int ret, irq; -+ -+ nfc = devm_kzalloc(dev, sizeof(*nfc), GFP_KERNEL); -+ if (!nfc) -+ return -ENOMEM; -+ -+ nand_controller_init(&nfc->controller); -+ INIT_LIST_HEAD(&nfc->chips); -+ nfc->controller.ops = &rk_nfc_controller_ops; -+ -+ nfc->cfg = of_device_get_match_data(dev); -+ nfc->dev = dev; -+ -+ init_completion(&nfc->done); -+ -+ nfc->regs = devm_platform_ioremap_resource(pdev, 0); -+ if (IS_ERR(nfc->regs)) { -+ ret = PTR_ERR(nfc->regs); -+ goto release_nfc; -+ } -+ -+ nfc->nfc_clk = devm_clk_get(dev, "nfc"); -+ if (IS_ERR(nfc->nfc_clk)) { -+ dev_dbg(dev, "no nfc clk\n"); -+ /* Some earlier models, such as rk3066, have no nfc clk. */ -+ } -+ -+ nfc->ahb_clk = devm_clk_get(dev, "ahb"); -+ if (IS_ERR(nfc->ahb_clk)) { -+ dev_err(dev, "no ahb clk\n"); -+ ret = PTR_ERR(nfc->ahb_clk); -+ goto release_nfc; -+ } -+ -+ ret = rk_nfc_enable_clks(dev, nfc); -+ if (ret) -+ goto release_nfc; -+ -+ irq = platform_get_irq(pdev, 0); -+ if (irq < 0) { -+ dev_err(dev, "no nfc irq resource\n"); -+ ret = -EINVAL; -+ goto clk_disable; -+ } -+ -+ writel(0, nfc->regs + nfc->cfg->int_en_off); -+ ret = devm_request_irq(dev, irq, rk_nfc_irq, 0x0, "rk-nand", nfc); -+ if (ret) { -+ dev_err(dev, "failed to request nfc irq\n"); -+ goto clk_disable; -+ } -+ -+ platform_set_drvdata(pdev, nfc); -+ -+ ret = rk_nfc_nand_chips_init(dev, nfc); -+ if (ret) { -+ dev_err(dev, "failed to init NAND chips\n"); -+ goto clk_disable; -+ } -+ return 0; -+ -+clk_disable: -+ rk_nfc_disable_clks(nfc); -+release_nfc: -+ return ret; -+} -+ -+static int rk_nfc_remove(struct platform_device *pdev) -+{ -+ struct rk_nfc *nfc = platform_get_drvdata(pdev); -+ -+ kfree(nfc->buffer); -+ kfree(nfc->oob_buf); -+ rk_nfc_chips_cleanup(nfc); -+ rk_nfc_disable_clks(nfc); -+ -+ return 0; -+} -+ -+static int __maybe_unused rk_nfc_suspend(struct device *dev) -+{ -+ struct rk_nfc *nfc = dev_get_drvdata(dev); -+ -+ rk_nfc_disable_clks(nfc); -+ -+ return 0; -+} -+ -+static int __maybe_unused rk_nfc_resume(struct device *dev) -+{ -+ struct rk_nfc *nfc = dev_get_drvdata(dev); -+ struct rk_nfc_nand_chip *rknand; -+ struct nand_chip *chip; -+ int ret; -+ u32 i; -+ -+ ret = rk_nfc_enable_clks(dev, nfc); -+ if (ret) -+ return ret; -+ -+ /* Reset NAND chip if VCC was powered off. */ -+ list_for_each_entry(rknand, &nfc->chips, node) { -+ chip = &rknand->chip; -+ for (i = 0; i < rknand->nsels; i++) -+ nand_reset(chip, i); -+ } -+ -+ return 0; -+} -+ -+static const struct dev_pm_ops rk_nfc_pm_ops = { -+ SET_SYSTEM_SLEEP_PM_OPS(rk_nfc_suspend, rk_nfc_resume) -+}; -+ -+static struct platform_driver rk_nfc_driver = { -+ .probe = rk_nfc_probe, -+ .remove = rk_nfc_remove, -+ .driver = { -+ .name = "rockchip-nfc", -+ .of_match_table = rk_nfc_id_table, -+ .pm = &rk_nfc_pm_ops, -+ }, -+}; -+ -+module_platform_driver(rk_nfc_driver); -+ -+MODULE_LICENSE("Dual MIT/GPL"); -+MODULE_AUTHOR("Yifeng Zhao "); -+MODULE_DESCRIPTION("Rockchip Nand Flash Controller Driver"); -+MODULE_ALIAS("platform:rockchip-nand-controller"); - -From b02351f0d62ff722f4f9ab87ad39607bc1993640 Mon Sep 17 00:00:00 2001 -From: Yifeng Zhao -Date: Wed, 28 Oct 2020 17:53:25 +0800 -Subject: [PATCH] MAINTAINERS: add maintainers to ROCKCHIP NFC - -Add maintainers to ROCKCHIP NFC. - -Signed-off-by: Yifeng Zhao ---- - MAINTAINERS | 4 ++-- - 1 file changed, 2 insertions(+), 2 deletions(-) - -diff --git a/MAINTAINERS b/MAINTAINERS -index 867157311dc8..0a14444b5f65 100644 ---- a/MAINTAINERS -+++ b/MAINTAINERS -@@ -2387,12 +2387,12 @@ L: linux-arm-kernel@lists.infradead.org (moderated for non-subscribers) - L: linux-rockchip@lists.infradead.org - S: Maintained - T: git git://git.kernel.org/pub/scm/linux/kernel/git/mmind/linux-rockchip.git -+F: Documentation/devicetree/bindings/*/*rockchip*.yaml - F: Documentation/devicetree/bindings/i2c/i2c-rk3x.yaml --F: Documentation/devicetree/bindings/mmc/rockchip-dw-mshc.yaml --F: Documentation/devicetree/bindings/spi/spi-rockchip.yaml - F: arch/arm/boot/dts/rk3* - F: arch/arm/boot/dts/rv1108* - F: arch/arm/mach-rockchip/ -+F: drivers/*/*/*/*rockchip* - F: drivers/*/*/*rockchip* - F: drivers/*/*rockchip* - F: drivers/clk/rockchip/ - -From 821a95a89d8384743e96c984f37fb364bfe8b011 Mon Sep 17 00:00:00 2001 -From: Yifeng Zhao -Date: Wed, 28 Oct 2020 17:53:26 +0800 -Subject: [PATCH] arm64: dts: rockchip: Add NFC node for RK3308 SoC - -Add NAND FLASH Controller(NFC) node for RK3308 SoC. - -Signed-off-by: Yifeng Zhao -Signed-off-by: Yifeng Zhao ---- - arch/arm64/boot/dts/rockchip/rk3308.dtsi | 15 +++++++++++++++ - 1 file changed, 15 insertions(+) - -diff --git a/arch/arm64/boot/dts/rockchip/rk3308.dtsi b/arch/arm64/boot/dts/rockchip/rk3308.dtsi -index 2560b98771ca..7211fab7a6e4 100644 ---- a/arch/arm64/boot/dts/rockchip/rk3308.dtsi -+++ b/arch/arm64/boot/dts/rockchip/rk3308.dtsi -@@ -629,6 +629,21 @@ sdio: mmc@ff4a0000 { - status = "disabled"; - }; - -+ nfc: nand-controller@ff4b0000 { -+ compatible = "rockchip,rk3308-nfc", -+ "rockchip,rv1108-nfc"; -+ reg = <0x0 0xff4b0000 0x0 0x4000>; -+ interrupts = ; -+ clocks = <&cru HCLK_NANDC>, <&cru SCLK_NANDC>; -+ clock-names = "ahb", "nfc"; -+ assigned-clocks = <&cru SCLK_NANDC>; -+ assigned-clock-rates = <150000000>; -+ pinctrl-0 = <&flash_ale &flash_bus8 &flash_cle &flash_csn0 -+ &flash_rdn &flash_rdy &flash_wrn>; -+ pinctrl-names = "default"; -+ status = "disabled"; -+ }; -+ - cru: clock-controller@ff500000 { - compatible = "rockchip,rk3308-cru"; - reg = <0x0 0xff500000 0x0 0x1000>; - -From 75679412eebab96c9a9dc190a8e5b2a9f5d0d8d7 Mon Sep 17 00:00:00 2001 -From: Yifeng Zhao -Date: Wed, 28 Oct 2020 17:54:14 +0800 -Subject: [PATCH] arm64: dts: rockchip: Add NFC node for PX30 SoC - -Add NAND FLASH Controller(NFC) node for PX30 SoC. - -Signed-off-by: Yifeng Zhao ---- - arch/arm64/boot/dts/rockchip/px30.dtsi | 15 +++++++++++++++ - 1 file changed, 15 insertions(+) - -diff --git a/arch/arm64/boot/dts/rockchip/px30.dtsi b/arch/arm64/boot/dts/rockchip/px30.dtsi -index 2695ea8cda14..6cd67e80d623 100644 ---- a/arch/arm64/boot/dts/rockchip/px30.dtsi -+++ b/arch/arm64/boot/dts/rockchip/px30.dtsi -@@ -973,6 +973,21 @@ emmc: mmc@ff390000 { - status = "disabled"; - }; - -+ nfc: nand-controller@ff3b0000 { -+ compatible = "rockchip,px30-nfc"; -+ reg = <0x0 0xff3b0000 0x0 0x4000>; -+ interrupts = ; -+ clocks = <&cru HCLK_NANDC>, <&cru SCLK_NANDC>; -+ clock-names = "ahb", "nfc"; -+ assigned-clocks = <&cru SCLK_NANDC>; -+ assigned-clock-rates = <150000000>; -+ pinctrl-names = "default"; -+ pinctrl-0 = <&flash_ale &flash_bus8 &flash_cle &flash_cs0 -+ &flash_rdn &flash_rdy &flash_wrn &flash_dqs>; -+ power-domains = <&power PX30_PD_MMC_NAND>; -+ status = "disabled"; -+ }; -+ - gpu: gpu@ff400000 { - compatible = "rockchip,px30-mali", "arm,mali-bifrost"; - reg = <0x0 0xff400000 0x0 0x4000>; - -From 4427805765fdfe5840894eac2b440e7c6e5f0e8b Mon Sep 17 00:00:00 2001 -From: Yifeng Zhao -Date: Wed, 28 Oct 2020 17:54:15 +0800 -Subject: [PATCH] arm: dts: rockchip: Add NFC node for RV1108 SoC - -Add NAND FLASH Controller(NFC) node for RV1108 SoC. - -Signed-off-by: Yifeng Zhao ---- - arch/arm/boot/dts/rv1108.dtsi | 11 +++++++++++ - 1 file changed, 11 insertions(+) - -diff --git a/arch/arm/boot/dts/rv1108.dtsi b/arch/arm/boot/dts/rv1108.dtsi -index a1a08cb9364e..1696ea19488b 100644 ---- a/arch/arm/boot/dts/rv1108.dtsi -+++ b/arch/arm/boot/dts/rv1108.dtsi -@@ -452,6 +452,17 @@ cru: clock-controller@20200000 { - #reset-cells = <1>; - }; - -+ nfc: nand-controller@30100000 { -+ compatible = "rockchip,rv1108-nfc"; -+ reg = <0x30100000 0x1000>; -+ interrupts = ; -+ clocks = <&cru HCLK_NANDC>, <&cru SCLK_NANDC>; -+ clock-names = "ahb", "nfc"; -+ assigned-clocks = <&cru SCLK_NANDC>; -+ assigned-clock-rates = <150000000>; -+ status = "disabled"; -+ }; -+ - emmc: mmc@30110000 { - compatible = "rockchip,rv1108-dw-mshc", "rockchip,rk3288-dw-mshc"; - reg = <0x30110000 0x4000>; - -From f0424cb442feb3431de15631b3a757bdf828db95 Mon Sep 17 00:00:00 2001 -From: Yifeng Zhao -Date: Wed, 28 Oct 2020 17:54:16 +0800 -Subject: [PATCH] arm: dts: rockchip: Add NFC node for RK2928 and other SoCs - -Add NAND FLASH Controller(NFC) node for RK2928, RK3066, RK3168 -and RK3188 SoCs. - -Signed-off-by: Yifeng Zhao ---- - arch/arm/boot/dts/rk3xxx.dtsi | 9 +++++++++ - 1 file changed, 9 insertions(+) - -diff --git a/arch/arm/boot/dts/rk3xxx.dtsi b/arch/arm/boot/dts/rk3xxx.dtsi -index 859a7477909f..97415180d5bb 100644 ---- a/arch/arm/boot/dts/rk3xxx.dtsi -+++ b/arch/arm/boot/dts/rk3xxx.dtsi -@@ -276,6 +276,15 @@ emmc: mmc@1021c000 { - status = "disabled"; - }; - -+ nfc: nand-controller@10500000 { -+ compatible = "rockchip,rk2928-nfc"; -+ reg = <0x10500000 0x4000>; -+ interrupts = ; -+ clocks = <&cru HCLK_NANDC0>; -+ clock-names = "ahb"; -+ status = "disabled"; -+ }; -+ - pmu: pmu@20004000 { - compatible = "rockchip,rk3066-pmu", "syscon", "simple-mfd"; - reg = <0x20004000 0x100>; - -From 39e1fd8036bac7c31ee7409b9f248d6f76e9cf87 Mon Sep 17 00:00:00 2001 -From: Yifeng Zhao -Date: Wed, 28 Oct 2020 17:54:17 +0800 -Subject: [PATCH] arm: dts: rockchip: Add NFC node for RK3036 SoC - -Add NAND FLASH Controller(NFC) node for RK3036 SoC. - -Signed-off-by: Yifeng Zhao ---- - arch/arm/boot/dts/rk3036.dtsi | 52 +++++++++++++++++++++++++++++++++++ - 1 file changed, 52 insertions(+) - -diff --git a/arch/arm/boot/dts/rk3036.dtsi b/arch/arm/boot/dts/rk3036.dtsi -index 093567022386..dda5a1f79aca 100644 ---- a/arch/arm/boot/dts/rk3036.dtsi -+++ b/arch/arm/boot/dts/rk3036.dtsi -@@ -292,6 +292,21 @@ i2s: i2s@10220000 { - status = "disabled"; - }; - -+ nfc: nand-controller@10500000 { -+ compatible = "rockchip,rk3036-nfc", -+ "rockchip,rk2928-nfc"; -+ reg = <0x10500000 0x4000>; -+ interrupts = ; -+ clocks = <&cru HCLK_NANDC>, <&cru SCLK_NANDC>; -+ clock-names = "ahb", "nfc"; -+ assigned-clocks = <&cru SCLK_NANDC>; -+ assigned-clock-rates = <150000000>; -+ pinctrl-0 = <&flash_ale &flash_bus8 &flash_cle &flash_csn0 -+ &flash_rdn &flash_rdy &flash_wrn>; -+ pinctrl-names = "default"; -+ status = "disabled"; -+ }; -+ - cru: clock-controller@20000000 { - compatible = "rockchip,rk3036-cru"; - reg = <0x20000000 0x1000>; -@@ -643,6 +658,43 @@ emmc_bus8: emmc-bus8 { - }; - }; - -+ nfc { -+ flash_ale: flash-ale { -+ rockchip,pins = <2 RK_PA0 1 &pcfg_pull_default>; -+ }; -+ -+ flash_bus8: flash-bus8 { -+ rockchip,pins = <1 RK_PD0 1 &pcfg_pull_default>, -+ <1 RK_PD1 1 &pcfg_pull_default>, -+ <1 RK_PD2 1 &pcfg_pull_default>, -+ <1 RK_PD3 1 &pcfg_pull_default>, -+ <1 RK_PD4 1 &pcfg_pull_default>, -+ <1 RK_PD5 1 &pcfg_pull_default>, -+ <1 RK_PD6 1 &pcfg_pull_default>, -+ <1 RK_PD7 1 &pcfg_pull_default>; -+ }; -+ -+ flash_cle: flash-cle { -+ rockchip,pins = <2 RK_PA1 1 &pcfg_pull_default>; -+ }; -+ -+ flash_csn0: flash-csn0 { -+ rockchip,pins = <2 RK_PA6 1 &pcfg_pull_default>; -+ }; -+ -+ flash_rdn: flash-rdn { -+ rockchip,pins = <2 RK_PA3 1 &pcfg_pull_default>; -+ }; -+ -+ flash_rdy: flash-rdy { -+ rockchip,pins = <2 RK_PA4 1 &pcfg_pull_default>; -+ }; -+ -+ flash_wrn: flash-wrn { -+ rockchip,pins = <2 RK_PA2 1 &pcfg_pull_default>; -+ }; -+ }; -+ - emac { - emac_xfer: emac-xfer { - rockchip,pins = <2 RK_PB2 1 &pcfg_pull_default>, /* crs_dvalid */ - -From ab3efcbbee3a7009cc6321d9f74f4123d308673b Mon Sep 17 00:00:00 2001 +From 6197ff4fc8190d487ab907ecd86477c3812c042c Mon Sep 17 00:00:00 2001 From: Elaine Zhang Date: Wed, 14 Oct 2020 10:28:08 +0800 Subject: [PATCH] clk: rockchip: Add supprot to limit input rate for fractional @@ -2281,7 +288,7 @@ index 4b1122e98e16..9eecd56d06db 100644 COMPOSITE(SCLK_MAC_SRC, "sclk_gmac_src", mux_pll_src_3plls_p, 0, RK2928_CLKSEL_CON(5), 6, 2, MFLAGS, 0, 5, DFLAGS, diff --git a/drivers/clk/rockchip/clk-rk3188.c b/drivers/clk/rockchip/clk-rk3188.c -index 730020fcc7fe..3970b68e9d9c 100644 +index 0b76ad34de00..78c3d0c80edf 100644 --- a/drivers/clk/rockchip/clk-rk3188.c +++ b/drivers/clk/rockchip/clk-rk3188.c @@ -14,6 +14,10 @@ @@ -2314,7 +321,7 @@ index 730020fcc7fe..3970b68e9d9c 100644 /* * Clock-Architecture Diagram 4 @@ -411,28 +415,28 @@ static struct rockchip_clk_branch common_clk_branches[] __initdata = { - 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), @@ -2322,7 +329,7 @@ index 730020fcc7fe..3970b68e9d9c 100644 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), @@ -2330,7 +337,7 @@ index 730020fcc7fe..3970b68e9d9c 100644 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), @@ -2338,7 +345,7 @@ index 730020fcc7fe..3970b68e9d9c 100644 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), @@ -2346,8 +353,8 @@ index 730020fcc7fe..3970b68e9d9c 100644 GATE(SCLK_JTAG, "jtag", "ext_jtag", 0, RK2928_CLKGATE_CON(1), 3, GFLAGS), -@@ -618,21 +622,21 @@ static struct rockchip_clk_branch rk3066a_clk_branches[] __initdata = { - COMPOSITE_FRACMUX(0, "i2s0_frac", "i2s0_pre", 0, +@@ -617,21 +621,21 @@ static struct rockchip_clk_branch rk3066a_clk_branches[] __initdata = { + 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), @@ -2355,7 +362,7 @@ index 730020fcc7fe..3970b68e9d9c 100644 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), @@ -2363,14 +370,14 @@ index 730020fcc7fe..3970b68e9d9c 100644 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), + &rk3066a_i2s2_fracmux, RK3188_I2S_FRAC_MAX_PRATE), - 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), @@ -726,7 +730,7 @@ static struct rockchip_clk_branch rk3188_clk_branches[] __initdata = { COMPOSITE_FRACMUX(0, "i2s0_frac", "i2s0_pre", CLK_SET_RATE_PARENT, RK2928_CLKSEL_CON(7), 0, @@ -2378,8 +385,8 @@ index 730020fcc7fe..3970b68e9d9c 100644 - &rk3188_i2s0_fracmux), + &rk3188_i2s0_fracmux, RK3188_I2S_FRAC_MAX_PRATE), + 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), diff --git a/drivers/clk/rockchip/clk-rk3228.c b/drivers/clk/rockchip/clk-rk3228.c index 47d6482dda9d..c1ef00247e26 100644 --- a/drivers/clk/rockchip/clk-rk3228.c @@ -3070,7 +1077,7 @@ index 5947d3192866..04b7f1161942 100644 RV1108_CLKGATE_CON(13), 10, GFLAGS), GATE(PCLK_UART1, "pclk_uart1", "pclk_bus_pre", 0, diff --git a/drivers/clk/rockchip/clk.c b/drivers/clk/rockchip/clk.c -index b443169dd408..9d56a93e854c 100644 +index 336481bc6cc7..fcbe33c4027f 100644 --- a/drivers/clk/rockchip/clk.c +++ b/drivers/clk/rockchip/clk.c @@ -182,12 +182,26 @@ static void rockchip_fractional_approximation(struct clk_hw *hw, @@ -3201,7 +1208,7 @@ index 03a5de5f99f4..b6b28a097526 100644 unsigned long rate, unsigned long *parent_rate, unsigned long *m, unsigned long *n); -From 1d1bb3b1942d5f45e1f57f2656375f046039bfdb Mon Sep 17 00:00:00 2001 +From 40a00285ecec36dbf0581904f91735c26a87a157 Mon Sep 17 00:00:00 2001 From: Elaine Zhang Date: Wed, 14 Oct 2020 10:28:09 +0800 Subject: [PATCH] clk: rockchip: fix up the frac clk get rate error @@ -3244,7 +1251,7 @@ Signed-off-by: Elaine Zhang 1 file changed, 12 insertions(+), 7 deletions(-) diff --git a/drivers/clk/rockchip/clk.c b/drivers/clk/rockchip/clk.c -index 9d56a93e854c..d8ca75f90b25 100644 +index fcbe33c4027f..92aee3e8be36 100644 --- a/drivers/clk/rockchip/clk.c +++ b/drivers/clk/rockchip/clk.c @@ -188,16 +188,21 @@ static void rockchip_fractional_approximation(struct clk_hw *hw, @@ -3277,7 +1284,7 @@ index 9d56a93e854c..d8ca75f90b25 100644 *n = 1; return; -From 4b0116e4c469fc0d2393b5c8e0f672fdd6e6a9b3 Mon Sep 17 00:00:00 2001 +From d03627a3b247b65dcd6935d23e75792b9aa56505 Mon Sep 17 00:00:00 2001 From: Elaine Zhang Date: Wed, 14 Oct 2020 10:28:10 +0800 Subject: [PATCH] clk: rockchip: add a clock-type for muxes based in the pmugrf @@ -3293,7 +1300,7 @@ Signed-off-by: Elaine Zhang 2 files changed, 26 insertions(+) diff --git a/drivers/clk/rockchip/clk.c b/drivers/clk/rockchip/clk.c -index d8ca75f90b25..66639a610172 100644 +index 92aee3e8be36..2df0a239448e 100644 --- a/drivers/clk/rockchip/clk.c +++ b/drivers/clk/rockchip/clk.c @@ -407,6 +407,8 @@ struct rockchip_clk_provider *rockchip_clk_init(struct device_node *np, @@ -3362,7 +1369,7 @@ index 0d401ce09a54..ae059b7744f9 100644 { \ .id = _id, \ -From a6daf8322c498e61804e02f2c02ad48187659de9 Mon Sep 17 00:00:00 2001 +From 51dc79ce294c10b8fd7cd787d60107ab84ba77bb Mon Sep 17 00:00:00 2001 From: Elaine Zhang Date: Wed, 14 Oct 2020 10:28:11 +0800 Subject: [PATCH] clk: rockchip: add pll up and down when change pll freq @@ -3439,7 +1446,7 @@ index 4c6c9167ef50..8adc6f54a605 100644 ret = rockchip_rk3399_pll_wait_lock(pll); if (ret) { -From 381edaef837e98a052a60374d6bbbf914cf3bdb2 Mon Sep 17 00:00:00 2001 +From c08635123f25692c92cc0ac30a54661ae4f552e8 Mon Sep 17 00:00:00 2001 From: Elaine Zhang Date: Wed, 14 Oct 2020 10:28:53 +0800 Subject: [PATCH] clk: rockchip: support pll setting by auto @@ -3711,3 +1718,2395 @@ index 8adc6f54a605..e8ca86f5b7d1 100644 do_div(frac_rate64, cur.refdiv); rate64 += frac_rate64 >> 24; + +From a408bfd669ef9e3f1a135d568dd13d4a460029c6 Mon Sep 17 00:00:00 2001 +From: Yifeng Zhao +Date: Thu, 10 Dec 2020 08:21:31 +0800 +Subject: [PATCH] dt-bindings: mtd: Describe Rockchip RK3xxx NAND flash + controller + +Documentation support for Rockchip RK3xxx NAND flash controllers + +Reviewed-by: Rob Herring +Signed-off-by: Yifeng Zhao +--- + .../mtd/rockchip,nand-controller.yaml | 161 ++++++++++++++++++ + 1 file changed, 161 insertions(+) + create mode 100644 Documentation/devicetree/bindings/mtd/rockchip,nand-controller.yaml + +diff --git a/Documentation/devicetree/bindings/mtd/rockchip,nand-controller.yaml b/Documentation/devicetree/bindings/mtd/rockchip,nand-controller.yaml +new file mode 100644 +index 000000000000..0922536b1811 +--- /dev/null ++++ b/Documentation/devicetree/bindings/mtd/rockchip,nand-controller.yaml +@@ -0,0 +1,161 @@ ++# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) ++%YAML 1.2 ++--- ++$id: http://devicetree.org/schemas/mtd/rockchip,nand-controller.yaml# ++$schema: http://devicetree.org/meta-schemas/core.yaml# ++ ++title: Rockchip SoCs NAND FLASH Controller (NFC) ++ ++allOf: ++ - $ref: "nand-controller.yaml#" ++ ++maintainers: ++ - Heiko Stuebner ++ ++properties: ++ compatible: ++ oneOf: ++ - const: rockchip,px30-nfc ++ - const: rockchip,rk2928-nfc ++ - const: rockchip,rv1108-nfc ++ - items: ++ - const: rockchip,rk3036-nfc ++ - const: rockchip,rk2928-nfc ++ - items: ++ - const: rockchip,rk3308-nfc ++ - const: rockchip,rv1108-nfc ++ ++ reg: ++ maxItems: 1 ++ ++ interrupts: ++ maxItems: 1 ++ ++ clocks: ++ minItems: 1 ++ items: ++ - description: Bus Clock ++ - description: Module Clock ++ ++ clock-names: ++ minItems: 1 ++ items: ++ - const: ahb ++ - const: nfc ++ ++ assigned-clocks: ++ maxItems: 1 ++ ++ assigned-clock-rates: ++ maxItems: 1 ++ ++ power-domains: ++ maxItems: 1 ++ ++patternProperties: ++ "^nand@[0-7]$": ++ type: object ++ properties: ++ reg: ++ minimum: 0 ++ maximum: 7 ++ ++ nand-ecc-mode: ++ const: hw ++ ++ nand-ecc-step-size: ++ const: 1024 ++ ++ nand-ecc-strength: ++ enum: [16, 24, 40, 60, 70] ++ description: | ++ The ECC configurations that can be supported are as follows. ++ NFC v600 ECC 16, 24, 40, 60 ++ RK2928, RK3066, RK3188 ++ ++ NFC v622 ECC 16, 24, 40, 60 ++ RK3036, RK3128 ++ ++ NFC v800 ECC 16 ++ RK3308, RV1108 ++ ++ NFC v900 ECC 16, 40, 60, 70 ++ RK3326, PX30 ++ ++ nand-bus-width: ++ const: 8 ++ ++ rockchip,boot-blks: ++ $ref: /schemas/types.yaml#/definitions/uint32 ++ minimum: 2 ++ default: 16 ++ description: ++ The NFC driver need this information to select ECC ++ algorithms supported by the boot ROM. ++ Only used in combination with 'nand-is-boot-medium'. ++ ++ rockchip,boot-ecc-strength: ++ enum: [16, 24, 40, 60, 70] ++ allOf: ++ - $ref: /schemas/types.yaml#/definitions/uint32 ++ description: | ++ If specified it indicates that a different BCH/ECC setting is ++ supported by the boot ROM. ++ NFC v600 ECC 16, 24 ++ RK2928, RK3066, RK3188 ++ ++ NFC v622 ECC 16, 24, 40, 60 ++ RK3036, RK3128 ++ ++ NFC v800 ECC 16 ++ RK3308, RV1108 ++ ++ NFC v900 ECC 16, 70 ++ RK3326, PX30 ++ ++ Only used in combination with 'nand-is-boot-medium'. ++ ++required: ++ - compatible ++ - reg ++ - interrupts ++ - clocks ++ - clock-names ++ ++unevaluatedProperties: false ++ ++examples: ++ - | ++ #include ++ #include ++ nfc: nand-controller@ff4b0000 { ++ compatible = "rockchip,rk3308-nfc", ++ "rockchip,rv1108-nfc"; ++ reg = <0xff4b0000 0x4000>; ++ interrupts = ; ++ clocks = <&cru HCLK_NANDC>, <&cru SCLK_NANDC>; ++ clock-names = "ahb", "nfc"; ++ assigned-clocks = <&clks SCLK_NANDC>; ++ assigned-clock-rates = <150000000>; ++ ++ pinctrl-0 = <&flash_ale &flash_bus8 &flash_cle &flash_csn0 ++ &flash_rdn &flash_rdy &flash_wrn>; ++ pinctrl-names = "default"; ++ ++ #address-cells = <1>; ++ #size-cells = <0>; ++ ++ nand@0 { ++ reg = <0>; ++ label = "rk-nand"; ++ nand-bus-width = <8>; ++ nand-ecc-mode = "hw"; ++ nand-ecc-step-size = <1024>; ++ nand-ecc-strength = <16>; ++ nand-is-boot-medium; ++ rockchip,boot-blks = <8>; ++ rockchip,boot-ecc-strength = <16>; ++ }; ++ }; ++ ++... + +From 7cce4b781394b2f4f31b4dd4e2c0ce9e7c10f4ca Mon Sep 17 00:00:00 2001 +From: Yifeng Zhao +Date: Thu, 10 Dec 2020 08:21:32 +0800 +Subject: [PATCH] mtd: rawnand: rockchip: NFC drivers for RK3308, RK2928 and + others + +This driver supports Rockchip NFC (NAND Flash Controller) found on RK3308, +RK2928, RKPX30, RV1108 and other SOCs. The driver has been tested using +8-bit NAND interface on the ARM based RK3308 platform. + +Support Rockchip SoCs and NFC versions: +- PX30 and RK3326(NFCv900). + ECC: 16/40/60/70 bits/1KB. + CLOCK: ahb and nfc. +- RK3308 and RV1108(NFCv800). + ECC: 16 bits/1KB. + CLOCK: ahb and nfc. +- RK3036 and RK3128(NFCv622). + ECC: 16/24/40/60 bits/1KB. + CLOCK: ahb and nfc. +- RK3066, RK3188 and RK2928(NFCv600). + ECC: 16/24/40/60 bits/1KB. + CLOCK: ahb. + +Supported features: +- Read full page data by DMA. +- Support HW ECC(one step is 1KB). +- Support 2 - 32K page size. +- Support 8 CS(depend on SoCs) + +Limitations: +- No support for the ecc step size is 512. +- Untested on some SoCs. +- No support for subpages. +- No support for the builtin randomizer. +- The original bad block mask is not supported. It is recommended to use + the BBT(bad block table). + +Suggested-by: Johan Jonker +Signed-off-by: Yifeng Zhao +--- + drivers/mtd/nand/raw/Kconfig | 12 + + drivers/mtd/nand/raw/Makefile | 1 + + .../mtd/nand/raw/rockchip-nand-controller.c | 1495 +++++++++++++++++ + 3 files changed, 1508 insertions(+) + create mode 100644 drivers/mtd/nand/raw/rockchip-nand-controller.c + +diff --git a/drivers/mtd/nand/raw/Kconfig b/drivers/mtd/nand/raw/Kconfig +index 6c46f25b57e2..2cc533e4e239 100644 +--- a/drivers/mtd/nand/raw/Kconfig ++++ b/drivers/mtd/nand/raw/Kconfig +@@ -462,6 +462,18 @@ config MTD_NAND_ARASAN + Enables the driver for the Arasan NAND flash controller on + Zynq Ultrascale+ MPSoC. + ++config MTD_NAND_ROCKCHIP ++ tristate "Rockchip NAND controller" ++ depends on ARCH_ROCKCHIP && HAS_IOMEM ++ help ++ Enables support for NAND controller on Rockchip SoCs. ++ There are four different versions of NAND FLASH Controllers, ++ including: ++ NFC v600: RK2928, RK3066, RK3188 ++ NFC v622: RK3036, RK3128 ++ NFC v800: RK3308, RV1108 ++ NFC v900: PX30, RK3326 ++ + comment "Misc" + + config MTD_SM_COMMON +diff --git a/drivers/mtd/nand/raw/Makefile b/drivers/mtd/nand/raw/Makefile +index 2930f5b9015d..960c9be25204 100644 +--- a/drivers/mtd/nand/raw/Makefile ++++ b/drivers/mtd/nand/raw/Makefile +@@ -58,6 +58,7 @@ obj-$(CONFIG_MTD_NAND_STM32_FMC2) += stm32_fmc2_nand.o + obj-$(CONFIG_MTD_NAND_MESON) += meson_nand.o + obj-$(CONFIG_MTD_NAND_CADENCE) += cadence-nand-controller.o + obj-$(CONFIG_MTD_NAND_ARASAN) += arasan-nand-controller.o ++obj-$(CONFIG_MTD_NAND_ROCKCHIP) += rockchip-nand-controller.o + + nand-objs := nand_base.o nand_legacy.o nand_bbt.o nand_timings.o nand_ids.o + nand-objs += nand_onfi.o +diff --git a/drivers/mtd/nand/raw/rockchip-nand-controller.c b/drivers/mtd/nand/raw/rockchip-nand-controller.c +new file mode 100644 +index 000000000000..796b678cb108 +--- /dev/null ++++ b/drivers/mtd/nand/raw/rockchip-nand-controller.c +@@ -0,0 +1,1495 @@ ++// SPDX-License-Identifier: GPL-2.0 OR MIT ++/* ++ * Rockchip NAND Flash controller driver. ++ * Copyright (C) 2020 Rockchip Inc. ++ * Author: Yifeng Zhao ++ */ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++/* ++ * NFC Page Data Layout: ++ * 1024 bytes data + 4Bytes sys data + 28Bytes~124Bytes ECC data + ++ * 1024 bytes data + 4Bytes sys data + 28Bytes~124Bytes ECC data + ++ * ...... ++ * NAND Page Data Layout: ++ * 1024 * n data + m Bytes oob ++ * Original Bad Block Mask Location: ++ * First byte of oob(spare). ++ * nand_chip->oob_poi data layout: ++ * 4Bytes sys data + .... + 4Bytes sys data + ECC data. ++ */ ++ ++/* NAND controller register definition */ ++#define NFC_READ (0) ++#define NFC_WRITE (1) ++ ++#define NFC_FMCTL (0x00) ++#define FMCTL_CE_SEL_M 0xFF ++#define FMCTL_CE_SEL(x) (1 << (x)) ++#define FMCTL_WP BIT(8) ++#define FMCTL_RDY BIT(9) ++ ++#define NFC_FMWAIT (0x04) ++#define FLCTL_RST BIT(0) ++#define FLCTL_WR (1) /* 0: read, 1: write */ ++#define FLCTL_XFER_ST BIT(2) ++#define FLCTL_XFER_EN BIT(3) ++#define FLCTL_ACORRECT BIT(10) /* Auto correct error bits. */ ++#define FLCTL_XFER_READY BIT(20) ++#define FLCTL_XFER_SECTOR (22) ++#define FLCTL_TOG_FIX BIT(29) ++ ++#define BCHCTL_BANK_M (7 << 5) ++#define BCHCTL_BANK (5) ++ ++#define DMA_ST BIT(0) ++#define DMA_WR (1) /* 0: write, 1: read */ ++#define DMA_EN BIT(2) ++#define DMA_AHB_SIZE (3) /* 0: 1, 1: 2, 2: 4 */ ++#define DMA_BURST_SIZE (6) /* 0: 1, 3: 4, 5: 8, 7: 16 */ ++#define DMA_INC_NUM (9) /* 1 - 16 */ ++ ++#define ECC_ERR_CNT(x, e) ((((x) >> (e).low) & (e).low_mask) |\ ++ (((x) >> (e).high) & (e).high_mask) << (e).low_bn) ++#define INT_DMA BIT(0) ++#define NFC_BANK (0x800) ++#define NFC_BANK_STEP (0x100) ++#define BANK_DATA (0x00) ++#define BANK_ADDR (0x04) ++#define BANK_CMD (0x08) ++#define NFC_SRAM0 (0x1000) ++#define NFC_SRAM1 (0x1400) ++#define NFC_SRAM_SIZE (0x400) ++#define NFC_TIMEOUT (500000) ++#define NFC_MAX_OOB_PER_STEP 128 ++#define NFC_MIN_OOB_PER_STEP 64 ++#define MAX_DATA_SIZE 0xFFFC ++#define MAX_ADDRESS_CYC 6 ++#define NFC_ECC_MAX_MODES 4 ++#define NFC_MAX_NSELS (8) /* Some Socs only have 1 or 2 CSs. */ ++#define NFC_SYS_DATA_SIZE (4) /* 4 bytes sys data in oob pre 1024 data.*/ ++#define RK_DEFAULT_CLOCK_RATE (150 * 1000 * 1000) /* 150 Mhz */ ++#define ACCTIMING(csrw, rwpw, rwcs) ((csrw) << 12 | (rwpw) << 5 | (rwcs)) ++ ++enum nfc_type { ++ NFC_V6, ++ NFC_V8, ++ NFC_V9, ++}; ++ ++/** ++ * struct rk_ecc_cnt_status: represent a ecc status data. ++ * @err_flag_bit: error flag bit index at register. ++ * @low: ECC count low bit index at register. ++ * @low_mask: mask bit. ++ * @low_bn: ECC count low bit number. ++ * @high: ECC count high bit index at register. ++ * @high_mask: mask bit ++ */ ++struct ecc_cnt_status { ++ u8 err_flag_bit; ++ u8 low; ++ u8 low_mask; ++ u8 low_bn; ++ u8 high; ++ u8 high_mask; ++}; ++ ++/** ++ * @type: NFC version ++ * @ecc_strengths: ECC strengths ++ * @ecc_cfgs: ECC config values ++ * @flctl_off: FLCTL register offset ++ * @bchctl_off: BCHCTL register offset ++ * @dma_data_buf_off: DMA_DATA_BUF register offset ++ * @dma_oob_buf_off: DMA_OOB_BUF register offset ++ * @dma_cfg_off: DMA_CFG register offset ++ * @dma_st_off: DMA_ST register offset ++ * @bch_st_off: BCG_ST register offset ++ * @randmz_off: RANDMZ register offset ++ * @int_en_off: interrupt enable register offset ++ * @int_clr_off: interrupt clean register offset ++ * @int_st_off: interrupt status register offset ++ * @oob0_off: oob0 register offset ++ * @oob1_off: oob1 register offset ++ * @ecc0: represent ECC0 status data ++ * @ecc1: represent ECC1 status data ++ */ ++struct nfc_cfg { ++ enum nfc_type type; ++ u8 ecc_strengths[NFC_ECC_MAX_MODES]; ++ u32 ecc_cfgs[NFC_ECC_MAX_MODES]; ++ u32 flctl_off; ++ u32 bchctl_off; ++ u32 dma_cfg_off; ++ u32 dma_data_buf_off; ++ u32 dma_oob_buf_off; ++ u32 dma_st_off; ++ u32 bch_st_off; ++ u32 randmz_off; ++ u32 int_en_off; ++ u32 int_clr_off; ++ u32 int_st_off; ++ u32 oob0_off; ++ u32 oob1_off; ++ struct ecc_cnt_status ecc0; ++ struct ecc_cnt_status ecc1; ++}; ++ ++struct rk_nfc_nand_chip { ++ struct list_head node; ++ struct nand_chip chip; ++ ++ u16 boot_blks; ++ u16 metadata_size; ++ u32 boot_ecc; ++ u32 timing; ++ ++ u8 nsels; ++ u8 sels[0]; ++ /* Nothing after this field. */ ++}; ++ ++struct rk_nfc { ++ struct nand_controller controller; ++ const struct nfc_cfg *cfg; ++ struct device *dev; ++ ++ struct clk *nfc_clk; ++ struct clk *ahb_clk; ++ void __iomem *regs; ++ ++ u32 selected_bank; ++ u32 band_offset; ++ u32 cur_ecc; ++ u32 cur_timing; ++ ++ struct completion done; ++ struct list_head chips; ++ ++ u8 *page_buf; ++ u32 *oob_buf; ++ u32 page_buf_size; ++ u32 oob_buf_size; ++ ++ unsigned long assigned_cs; ++}; ++ ++static inline struct rk_nfc_nand_chip *rk_nfc_to_rknand(struct nand_chip *chip) ++{ ++ return container_of(chip, struct rk_nfc_nand_chip, chip); ++} ++ ++static inline u8 *rk_nfc_buf_to_data_ptr(struct nand_chip *chip, const u8 *p, int i) ++{ ++ return (u8 *)p + i * chip->ecc.size; ++} ++ ++static inline u8 *rk_nfc_buf_to_oob_ptr(struct nand_chip *chip, int i) ++{ ++ u8 *poi; ++ ++ poi = chip->oob_poi + i * NFC_SYS_DATA_SIZE; ++ ++ return poi; ++} ++ ++static inline u8 *rk_nfc_buf_to_oob_ecc_ptr(struct nand_chip *chip, int i) ++{ ++ struct rk_nfc_nand_chip *rknand = rk_nfc_to_rknand(chip); ++ u8 *poi; ++ ++ poi = chip->oob_poi + rknand->metadata_size + chip->ecc.bytes * i; ++ ++ return poi; ++} ++ ++static inline int rk_nfc_data_len(struct nand_chip *chip) ++{ ++ return chip->ecc.size + chip->ecc.bytes + NFC_SYS_DATA_SIZE; ++} ++ ++static inline u8 *rk_nfc_data_ptr(struct nand_chip *chip, int i) ++{ ++ struct rk_nfc *nfc = nand_get_controller_data(chip); ++ ++ return nfc->page_buf + i * rk_nfc_data_len(chip); ++} ++ ++static inline u8 *rk_nfc_oob_ptr(struct nand_chip *chip, int i) ++{ ++ struct rk_nfc *nfc = nand_get_controller_data(chip); ++ ++ return nfc->page_buf + i * rk_nfc_data_len(chip) + chip->ecc.size; ++} ++ ++static int rk_nfc_hw_ecc_setup(struct nand_chip *chip, u32 strength) ++{ ++ struct rk_nfc *nfc = nand_get_controller_data(chip); ++ u32 reg, i; ++ ++ for (i = 0; i < NFC_ECC_MAX_MODES; i++) { ++ if (strength == nfc->cfg->ecc_strengths[i]) { ++ reg = nfc->cfg->ecc_cfgs[i]; ++ break; ++ } ++ } ++ ++ if (i >= NFC_ECC_MAX_MODES) ++ return -EINVAL; ++ ++ writel(reg, nfc->regs + nfc->cfg->bchctl_off); ++ ++ /* Save chip ECC setting */ ++ nfc->cur_ecc = strength; ++ ++ return 0; ++} ++ ++static void rk_nfc_select_chip(struct nand_chip *chip, int cs) ++{ ++ struct rk_nfc *nfc = nand_get_controller_data(chip); ++ struct rk_nfc_nand_chip *rknand = rk_nfc_to_rknand(chip); ++ struct nand_ecc_ctrl *ecc = &chip->ecc; ++ u32 val; ++ ++ if (cs < 0) { ++ nfc->selected_bank = -1; ++ /* Deselect the currently selected target. */ ++ val = readl_relaxed(nfc->regs + NFC_FMCTL); ++ val &= ~FMCTL_CE_SEL_M; ++ writel(val, nfc->regs + NFC_FMCTL); ++ return; ++ } ++ ++ nfc->selected_bank = rknand->sels[cs]; ++ nfc->band_offset = NFC_BANK + nfc->selected_bank * NFC_BANK_STEP; ++ ++ val = readl_relaxed(nfc->regs + NFC_FMCTL); ++ val &= ~FMCTL_CE_SEL_M; ++ val |= FMCTL_CE_SEL(nfc->selected_bank); ++ ++ writel(val, nfc->regs + NFC_FMCTL); ++ ++ /* ++ * Compare current chip timing with selected chip timing and ++ * change if needed. ++ */ ++ if (nfc->cur_timing != rknand->timing) { ++ writel(rknand->timing, nfc->regs + NFC_FMWAIT); ++ nfc->cur_timing = rknand->timing; ++ } ++ ++ /* ++ * Compare current chip ECC setting with selected chip ECC setting and ++ * change if needed. ++ */ ++ if (nfc->cur_ecc != ecc->strength) ++ rk_nfc_hw_ecc_setup(chip, ecc->strength); ++} ++ ++static inline int rk_nfc_wait_ioready(struct rk_nfc *nfc) ++{ ++ int rc; ++ u32 val; ++ ++ rc = readl_relaxed_poll_timeout(nfc->regs + NFC_FMCTL, val, ++ val & FMCTL_RDY, 10, NFC_TIMEOUT); ++ ++ return rc; ++} ++ ++static void rk_nfc_read_buf(struct rk_nfc *nfc, u8 *buf, int len) ++{ ++ int i; ++ ++ for (i = 0; i < len; i++) ++ buf[i] = readb_relaxed(nfc->regs + nfc->band_offset + ++ BANK_DATA); ++} ++ ++static void rk_nfc_write_buf(struct rk_nfc *nfc, const u8 *buf, int len) ++{ ++ int i; ++ ++ for (i = 0; i < len; i++) ++ writeb(buf[i], nfc->regs + nfc->band_offset + BANK_DATA); ++} ++ ++static int rk_nfc_cmd(struct nand_chip *chip, ++ const struct nand_subop *subop) ++{ ++ struct rk_nfc *nfc = nand_get_controller_data(chip); ++ unsigned int i, j, remaining, start; ++ int reg_offset = nfc->band_offset; ++ u8 *inbuf = NULL; ++ const u8 *outbuf; ++ u32 cnt = 0; ++ int ret = 0; ++ ++ for (i = 0; i < subop->ninstrs; i++) { ++ const struct nand_op_instr *instr = &subop->instrs[i]; ++ ++ switch (instr->type) { ++ case NAND_OP_CMD_INSTR: ++ writeb(instr->ctx.cmd.opcode, ++ nfc->regs + reg_offset + BANK_CMD); ++ break; ++ ++ case NAND_OP_ADDR_INSTR: ++ remaining = nand_subop_get_num_addr_cyc(subop, i); ++ start = nand_subop_get_addr_start_off(subop, i); ++ ++ for (j = 0; j < 8 && j + start < remaining; j++) ++ writeb(instr->ctx.addr.addrs[j + start], ++ nfc->regs + reg_offset + BANK_ADDR); ++ break; ++ ++ case NAND_OP_DATA_IN_INSTR: ++ case NAND_OP_DATA_OUT_INSTR: ++ start = nand_subop_get_data_start_off(subop, i); ++ cnt = nand_subop_get_data_len(subop, i); ++ ++ if (instr->type == NAND_OP_DATA_OUT_INSTR) { ++ outbuf = instr->ctx.data.buf.out + start; ++ rk_nfc_write_buf(nfc, outbuf, cnt); ++ } else { ++ inbuf = instr->ctx.data.buf.in + start; ++ rk_nfc_read_buf(nfc, inbuf, cnt); ++ } ++ break; ++ ++ case NAND_OP_WAITRDY_INSTR: ++ if (rk_nfc_wait_ioready(nfc) < 0) { ++ ret = -ETIMEDOUT; ++ dev_err(nfc->dev, "IO not ready\n"); ++ } ++ break; ++ } ++ } ++ ++ return ret; ++} ++ ++static const struct nand_op_parser rk_nfc_op_parser = NAND_OP_PARSER( ++ NAND_OP_PARSER_PATTERN( ++ rk_nfc_cmd, ++ NAND_OP_PARSER_PAT_CMD_ELEM(true), ++ NAND_OP_PARSER_PAT_ADDR_ELEM(true, MAX_ADDRESS_CYC), ++ NAND_OP_PARSER_PAT_CMD_ELEM(true), ++ NAND_OP_PARSER_PAT_WAITRDY_ELEM(true), ++ NAND_OP_PARSER_PAT_DATA_IN_ELEM(true, MAX_DATA_SIZE)), ++ NAND_OP_PARSER_PATTERN( ++ rk_nfc_cmd, ++ NAND_OP_PARSER_PAT_CMD_ELEM(true), ++ NAND_OP_PARSER_PAT_ADDR_ELEM(true, MAX_ADDRESS_CYC), ++ NAND_OP_PARSER_PAT_DATA_OUT_ELEM(true, MAX_DATA_SIZE), ++ NAND_OP_PARSER_PAT_CMD_ELEM(true), ++ NAND_OP_PARSER_PAT_WAITRDY_ELEM(true)), ++); ++ ++static int rk_nfc_exec_op(struct nand_chip *chip, ++ const struct nand_operation *op, ++ bool check_only) ++{ ++ if (!check_only) ++ rk_nfc_select_chip(chip, op->cs); ++ ++ return nand_op_parser_exec_op(chip, &rk_nfc_op_parser, op, ++ check_only); ++} ++ ++static int rk_nfc_setup_interface(struct nand_chip *chip, int target, ++ const struct nand_interface_config *conf) ++{ ++ struct rk_nfc_nand_chip *rknand = rk_nfc_to_rknand(chip); ++ struct rk_nfc *nfc = nand_get_controller_data(chip); ++ const struct nand_sdr_timings *timings; ++ u32 rate, tc2rw, trwpw, trw2c; ++ u32 temp; ++ ++ if (target < 0) ++ return 0; ++ ++ timings = nand_get_sdr_timings(conf); ++ if (IS_ERR(timings)) ++ return -EOPNOTSUPP; ++ ++ if (IS_ERR(nfc->nfc_clk)) ++ rate = clk_get_rate(nfc->ahb_clk); ++ else ++ rate = clk_get_rate(nfc->nfc_clk); ++ ++ /* Turn clock rate into kHz. */ ++ rate /= 1000; ++ ++ tc2rw = 1; ++ trw2c = 1; ++ ++ trwpw = max(timings->tWC_min, timings->tRC_min) / 1000; ++ trwpw = DIV_ROUND_UP(trwpw * rate, 1000000); ++ ++ temp = timings->tREA_max / 1000; ++ temp = DIV_ROUND_UP(temp * rate, 1000000); ++ ++ if (trwpw < temp) ++ trwpw = temp; ++ ++ /* ++ * ACCON: access timing control register ++ * ------------------------------------- ++ * 31:18: reserved ++ * 17:12: csrw, clock cycles from the falling edge of CSn to the ++ * falling edge of RDn or WRn ++ * 11:11: reserved ++ * 10:05: rwpw, the width of RDn or WRn in processor clock cycles ++ * 04:00: rwcs, clock cycles from the rising edge of RDn or WRn to the ++ * rising edge of CSn ++ */ ++ ++ /* Save chip timing */ ++ rknand->timing = ACCTIMING(tc2rw, trwpw, trw2c); ++ ++ return 0; ++} ++ ++static void rk_nfc_xfer_start(struct rk_nfc *nfc, u8 rw, u8 n_KB, ++ dma_addr_t dma_data, dma_addr_t dma_oob) ++{ ++ u32 dma_reg, fl_reg, bch_reg; ++ ++ dma_reg = DMA_ST | ((!rw) << DMA_WR) | DMA_EN | (2 << DMA_AHB_SIZE) | ++ (7 << DMA_BURST_SIZE) | (16 << DMA_INC_NUM); ++ ++ fl_reg = (rw << FLCTL_WR) | FLCTL_XFER_EN | FLCTL_ACORRECT | ++ (n_KB << FLCTL_XFER_SECTOR) | FLCTL_TOG_FIX; ++ ++ if (nfc->cfg->type == NFC_V6 || nfc->cfg->type == NFC_V8) { ++ bch_reg = readl_relaxed(nfc->regs + nfc->cfg->bchctl_off); ++ bch_reg = (bch_reg & (~BCHCTL_BANK_M)) | ++ (nfc->selected_bank << BCHCTL_BANK); ++ writel(bch_reg, nfc->regs + nfc->cfg->bchctl_off); ++ } ++ ++ writel(dma_reg, nfc->regs + nfc->cfg->dma_cfg_off); ++ writel((u32)dma_data, nfc->regs + nfc->cfg->dma_data_buf_off); ++ writel((u32)dma_oob, nfc->regs + nfc->cfg->dma_oob_buf_off); ++ writel(fl_reg, nfc->regs + nfc->cfg->flctl_off); ++ fl_reg |= FLCTL_XFER_ST; ++ writel(fl_reg, nfc->regs + nfc->cfg->flctl_off); ++} ++ ++static int rk_nfc_wait_for_xfer_done(struct rk_nfc *nfc) ++{ ++ void __iomem *ptr; ++ u32 reg; ++ ++ ptr = nfc->regs + nfc->cfg->flctl_off; ++ ++ return readl_relaxed_poll_timeout(ptr, reg, ++ reg & FLCTL_XFER_READY, ++ 10, NFC_TIMEOUT); ++} ++ ++static int rk_nfc_write_page_raw(struct nand_chip *chip, const u8 *buf, ++ int oob_on, int page) ++{ ++ struct rk_nfc_nand_chip *rknand = rk_nfc_to_rknand(chip); ++ struct rk_nfc *nfc = nand_get_controller_data(chip); ++ struct mtd_info *mtd = nand_to_mtd(chip); ++ struct nand_ecc_ctrl *ecc = &chip->ecc; ++ int i, pages_per_blk; ++ ++ pages_per_blk = mtd->erasesize / mtd->writesize; ++ if ((chip->options & NAND_IS_BOOT_MEDIUM) && ++ (page < (pages_per_blk * rknand->boot_blks)) && ++ rknand->boot_ecc != ecc->strength) { ++ /* ++ * There's currently no method to notify the MTD framework that ++ * a different ECC strength is in use for the boot blocks. ++ */ ++ return -EIO; ++ } ++ ++ if (!buf) ++ memset(nfc->page_buf, 0xff, mtd->writesize + mtd->oobsize); ++ ++ for (i = 0; i < ecc->steps; i++) { ++ /* Copy data to the NFC buffer. */ ++ if (buf) ++ memcpy(rk_nfc_data_ptr(chip, i), ++ rk_nfc_buf_to_data_ptr(chip, buf, i), ++ ecc->size); ++ /* ++ * The first four bytes of OOB are reserved for the ++ * boot ROM. In some debugging cases, such as with a ++ * read, erase and write back test these 4 bytes stored ++ * in OOB also need to be written back. ++ * ++ * The function nand_block_bad detects bad blocks like: ++ * ++ * bad = chip->oob_poi[chip->badblockpos]; ++ * ++ * chip->badblockpos == 0 for a large page NAND Flash, ++ * so chip->oob_poi[0] is the bad block mask (BBM). ++ * ++ * The OOB data layout on the NFC is: ++ * ++ * PA0 PA1 PA2 PA3 | BBM OOB1 OOB2 OOB3 | ... ++ * ++ * or ++ * ++ * 0xFF 0xFF 0xFF 0xFF | BBM OOB1 OOB2 OOB3 | ... ++ * ++ * The code here just swaps the first 4 bytes with the last ++ * 4 bytes without losing any data. ++ * ++ * The chip->oob_poi data layout: ++ * ++ * BBM OOB1 OOB2 OOB3 |......| PA0 PA1 PA2 PA3 ++ * ++ * The rk_nfc_ooblayout_free() function already has reserved ++ * these 4 bytes with: ++ * ++ * oob_region->offset = NFC_SYS_DATA_SIZE + 2; ++ */ ++ if (!i) ++ memcpy(rk_nfc_oob_ptr(chip, i), ++ rk_nfc_buf_to_oob_ptr(chip, ecc->steps - 1), ++ NFC_SYS_DATA_SIZE); ++ else ++ memcpy(rk_nfc_oob_ptr(chip, i), ++ rk_nfc_buf_to_oob_ptr(chip, i - 1), ++ NFC_SYS_DATA_SIZE); ++ /* Copy ECC data to the NFC buffer. */ ++ memcpy(rk_nfc_oob_ptr(chip, i) + NFC_SYS_DATA_SIZE, ++ rk_nfc_buf_to_oob_ecc_ptr(chip, i), ++ ecc->bytes); ++ } ++ ++ nand_prog_page_begin_op(chip, page, 0, NULL, 0); ++ rk_nfc_write_buf(nfc, buf, mtd->writesize + mtd->oobsize); ++ return nand_prog_page_end_op(chip); ++} ++ ++static int rk_nfc_write_page_hwecc(struct nand_chip *chip, const u8 *buf, ++ int oob_on, int page) ++{ ++ struct mtd_info *mtd = nand_to_mtd(chip); ++ struct rk_nfc *nfc = nand_get_controller_data(chip); ++ struct rk_nfc_nand_chip *rknand = rk_nfc_to_rknand(chip); ++ struct nand_ecc_ctrl *ecc = &chip->ecc; ++ int oob_step = (ecc->bytes > 60) ? NFC_MAX_OOB_PER_STEP : ++ NFC_MIN_OOB_PER_STEP; ++ int pages_per_blk = mtd->erasesize / mtd->writesize; ++ int ret = 0, i, boot_rom_mode = 0; ++ dma_addr_t dma_data, dma_oob; ++ u32 reg; ++ u8 *oob; ++ ++ nand_prog_page_begin_op(chip, page, 0, NULL, 0); ++ ++ if (buf) ++ memcpy(nfc->page_buf, buf, mtd->writesize); ++ else ++ memset(nfc->page_buf, 0xFF, mtd->writesize); ++ ++ /* ++ * The first blocks (4, 8 or 16 depending on the device) are used ++ * by the boot ROM and the first 32 bits of OOB need to link to ++ * the next page address in the same block. We can't directly copy ++ * OOB data from the MTD framework, because this page address ++ * conflicts for example with the bad block marker (BBM), ++ * so we shift all OOB data including the BBM with 4 byte positions. ++ * As a consequence the OOB size available to the MTD framework is ++ * also reduced with 4 bytes. ++ * ++ * PA0 PA1 PA2 PA3 | BBM OOB1 OOB2 OOB3 | ... ++ * ++ * If a NAND is not a boot medium or the page is not a boot block, ++ * the first 4 bytes are left untouched by writing 0xFF to them. ++ * ++ * 0xFF 0xFF 0xFF 0xFF | BBM OOB1 OOB2 OOB3 | ... ++ * ++ * Configure the ECC algorithm supported by the boot ROM. ++ */ ++ if ((page < (pages_per_blk * rknand->boot_blks)) && ++ (chip->options & NAND_IS_BOOT_MEDIUM)) { ++ boot_rom_mode = 1; ++ if (rknand->boot_ecc != ecc->strength) ++ rk_nfc_hw_ecc_setup(chip, rknand->boot_ecc); ++ } ++ ++ for (i = 0; i < ecc->steps; i++) { ++ if (!i) { ++ reg = 0xFFFFFFFF; ++ } else { ++ oob = chip->oob_poi + (i - 1) * NFC_SYS_DATA_SIZE; ++ reg = oob[0] | oob[1] << 8 | oob[2] << 16 | ++ oob[3] << 24; ++ } ++ ++ if (!i && boot_rom_mode) ++ reg = (page & (pages_per_blk - 1)) * 4; ++ ++ if (nfc->cfg->type == NFC_V9) ++ nfc->oob_buf[i] = reg; ++ else ++ nfc->oob_buf[i * (oob_step / 4)] = reg; ++ } ++ ++ dma_data = dma_map_single(nfc->dev, (void *)nfc->page_buf, ++ mtd->writesize, DMA_TO_DEVICE); ++ dma_oob = dma_map_single(nfc->dev, nfc->oob_buf, ++ ecc->steps * oob_step, ++ DMA_TO_DEVICE); ++ ++ reinit_completion(&nfc->done); ++ writel(INT_DMA, nfc->regs + nfc->cfg->int_en_off); ++ ++ rk_nfc_xfer_start(nfc, NFC_WRITE, ecc->steps, dma_data, ++ dma_oob); ++ ret = wait_for_completion_timeout(&nfc->done, ++ msecs_to_jiffies(100)); ++ if (!ret) ++ dev_warn(nfc->dev, "write: wait dma done timeout.\n"); ++ /* ++ * Whether the DMA transfer is completed or not. The driver ++ * needs to check the NFC`s status register to see if the data ++ * transfer was completed. ++ */ ++ ret = rk_nfc_wait_for_xfer_done(nfc); ++ ++ dma_unmap_single(nfc->dev, dma_data, mtd->writesize, ++ DMA_TO_DEVICE); ++ dma_unmap_single(nfc->dev, dma_oob, ecc->steps * oob_step, ++ DMA_TO_DEVICE); ++ ++ if (boot_rom_mode && rknand->boot_ecc != ecc->strength) ++ rk_nfc_hw_ecc_setup(chip, ecc->strength); ++ ++ if (ret) { ++ dev_err(nfc->dev, "write: wait transfer done timeout.\n"); ++ return -ETIMEDOUT; ++ } ++ ++ return nand_prog_page_end_op(chip); ++} ++ ++static int rk_nfc_write_oob(struct nand_chip *chip, int page) ++{ ++ return rk_nfc_write_page_hwecc(chip, NULL, 1, page); ++} ++ ++static int rk_nfc_read_page_raw(struct nand_chip *chip, u8 *buf, int oob_on, ++ int page) ++{ ++ struct rk_nfc_nand_chip *rknand = rk_nfc_to_rknand(chip); ++ struct rk_nfc *nfc = nand_get_controller_data(chip); ++ struct mtd_info *mtd = nand_to_mtd(chip); ++ struct nand_ecc_ctrl *ecc = &chip->ecc; ++ int i, pages_per_blk; ++ ++ pages_per_blk = mtd->erasesize / mtd->writesize; ++ if ((chip->options & NAND_IS_BOOT_MEDIUM) && ++ (page < (pages_per_blk * rknand->boot_blks)) && ++ rknand->boot_ecc != ecc->strength) { ++ /* ++ * There's currently no method to notify the MTD framework that ++ * a different ECC strength is in use for the boot blocks. ++ */ ++ return -EIO; ++ } ++ ++ nand_read_page_op(chip, page, 0, NULL, 0); ++ rk_nfc_read_buf(nfc, nfc->page_buf, mtd->writesize + mtd->oobsize); ++ for (i = 0; i < ecc->steps; i++) { ++ /* ++ * The first four bytes of OOB are reserved for the ++ * boot ROM. In some debugging cases, such as with a read, ++ * erase and write back test, these 4 bytes also must be ++ * saved somewhere, otherwise this information will be ++ * lost during a write back. ++ */ ++ if (!i) ++ memcpy(rk_nfc_buf_to_oob_ptr(chip, ecc->steps - 1), ++ rk_nfc_oob_ptr(chip, i), ++ NFC_SYS_DATA_SIZE); ++ else ++ memcpy(rk_nfc_buf_to_oob_ptr(chip, i - 1), ++ rk_nfc_oob_ptr(chip, i), ++ NFC_SYS_DATA_SIZE); ++ ++ /* Copy ECC data from the NFC buffer. */ ++ memcpy(rk_nfc_buf_to_oob_ecc_ptr(chip, i), ++ rk_nfc_oob_ptr(chip, i) + NFC_SYS_DATA_SIZE, ++ ecc->bytes); ++ ++ /* Copy data from the NFC buffer. */ ++ if (buf) ++ memcpy(rk_nfc_buf_to_data_ptr(chip, buf, i), ++ rk_nfc_data_ptr(chip, i), ++ ecc->size); ++ } ++ ++ return 0; ++} ++ ++static int rk_nfc_read_page_hwecc(struct nand_chip *chip, u8 *buf, int oob_on, ++ int page) ++{ ++ struct mtd_info *mtd = nand_to_mtd(chip); ++ struct rk_nfc *nfc = nand_get_controller_data(chip); ++ struct rk_nfc_nand_chip *rknand = rk_nfc_to_rknand(chip); ++ struct nand_ecc_ctrl *ecc = &chip->ecc; ++ int oob_step = (ecc->bytes > 60) ? NFC_MAX_OOB_PER_STEP : ++ NFC_MIN_OOB_PER_STEP; ++ int pages_per_blk = mtd->erasesize / mtd->writesize; ++ dma_addr_t dma_data, dma_oob; ++ int ret = 0, i, cnt, boot_rom_mode = 0; ++ int max_bitflips = 0, bch_st, ecc_fail = 0; ++ u8 *oob; ++ u32 tmp; ++ ++ nand_read_page_op(chip, page, 0, NULL, 0); ++ ++ dma_data = dma_map_single(nfc->dev, nfc->page_buf, ++ mtd->writesize, ++ DMA_FROM_DEVICE); ++ dma_oob = dma_map_single(nfc->dev, nfc->oob_buf, ++ ecc->steps * oob_step, ++ DMA_FROM_DEVICE); ++ ++ /* ++ * The first blocks (4, 8 or 16 depending on the device) ++ * are used by the boot ROM. ++ * Configure the ECC algorithm supported by the boot ROM. ++ */ ++ if ((page < (pages_per_blk * rknand->boot_blks)) && ++ (chip->options & NAND_IS_BOOT_MEDIUM)) { ++ boot_rom_mode = 1; ++ if (rknand->boot_ecc != ecc->strength) ++ rk_nfc_hw_ecc_setup(chip, rknand->boot_ecc); ++ } ++ ++ reinit_completion(&nfc->done); ++ writel(INT_DMA, nfc->regs + nfc->cfg->int_en_off); ++ rk_nfc_xfer_start(nfc, NFC_READ, ecc->steps, dma_data, ++ dma_oob); ++ ret = wait_for_completion_timeout(&nfc->done, ++ msecs_to_jiffies(100)); ++ if (!ret) ++ dev_warn(nfc->dev, "read: wait dma done timeout.\n"); ++ /* ++ * Whether the DMA transfer is completed or not. The driver ++ * needs to check the NFC`s status register to see if the data ++ * transfer was completed. ++ */ ++ ret = rk_nfc_wait_for_xfer_done(nfc); ++ ++ dma_unmap_single(nfc->dev, dma_data, mtd->writesize, ++ DMA_FROM_DEVICE); ++ dma_unmap_single(nfc->dev, dma_oob, ecc->steps * oob_step, ++ DMA_FROM_DEVICE); ++ ++ if (ret) { ++ ret = -ETIMEDOUT; ++ dev_err(nfc->dev, "read: wait transfer done timeout.\n"); ++ goto timeout_err; ++ } ++ ++ for (i = 1; i < ecc->steps; i++) { ++ oob = chip->oob_poi + (i - 1) * NFC_SYS_DATA_SIZE; ++ if (nfc->cfg->type == NFC_V9) ++ tmp = nfc->oob_buf[i]; ++ else ++ tmp = nfc->oob_buf[i * (oob_step / 4)]; ++ *oob++ = (u8)tmp; ++ *oob++ = (u8)(tmp >> 8); ++ *oob++ = (u8)(tmp >> 16); ++ *oob++ = (u8)(tmp >> 24); ++ } ++ ++ for (i = 0; i < (ecc->steps / 2); i++) { ++ bch_st = readl_relaxed(nfc->regs + ++ nfc->cfg->bch_st_off + i * 4); ++ if (bch_st & BIT(nfc->cfg->ecc0.err_flag_bit) || ++ bch_st & BIT(nfc->cfg->ecc1.err_flag_bit)) { ++ mtd->ecc_stats.failed++; ++ ecc_fail = 1; ++ } else { ++ cnt = ECC_ERR_CNT(bch_st, nfc->cfg->ecc0); ++ mtd->ecc_stats.corrected += cnt; ++ max_bitflips = max_t(u32, max_bitflips, cnt); ++ ++ cnt = ECC_ERR_CNT(bch_st, nfc->cfg->ecc1); ++ mtd->ecc_stats.corrected += cnt; ++ max_bitflips = max_t(u32, max_bitflips, cnt); ++ } ++ } ++ ++ if (buf) ++ memcpy(buf, nfc->page_buf, mtd->writesize); ++ ++timeout_err: ++ if (boot_rom_mode && rknand->boot_ecc != ecc->strength) ++ rk_nfc_hw_ecc_setup(chip, ecc->strength); ++ ++ if (ret) ++ return ret; ++ ++ if (ecc_fail) { ++ dev_err(nfc->dev, "read page: %x ecc error!\n", page); ++ return 0; ++ } ++ ++ return max_bitflips; ++} ++ ++static int rk_nfc_read_oob(struct nand_chip *chip, int page) ++{ ++ return rk_nfc_read_page_hwecc(chip, NULL, 1, page); ++} ++ ++static inline void rk_nfc_hw_init(struct rk_nfc *nfc) ++{ ++ /* Disable flash wp. */ ++ writel(FMCTL_WP, nfc->regs + NFC_FMCTL); ++ /* Config default timing 40ns at 150 Mhz NFC clock. */ ++ writel(0x1081, nfc->regs + NFC_FMWAIT); ++ nfc->cur_timing = 0x1081; ++ /* Disable randomizer and DMA. */ ++ writel(0, nfc->regs + nfc->cfg->randmz_off); ++ writel(0, nfc->regs + nfc->cfg->dma_cfg_off); ++ writel(FLCTL_RST, nfc->regs + nfc->cfg->flctl_off); ++} ++ ++static irqreturn_t rk_nfc_irq(int irq, void *id) ++{ ++ struct rk_nfc *nfc = id; ++ u32 sta, ien; ++ ++ sta = readl_relaxed(nfc->regs + nfc->cfg->int_st_off); ++ ien = readl_relaxed(nfc->regs + nfc->cfg->int_en_off); ++ ++ if (!(sta & ien)) ++ return IRQ_NONE; ++ ++ writel(sta, nfc->regs + nfc->cfg->int_clr_off); ++ writel(~sta & ien, nfc->regs + nfc->cfg->int_en_off); ++ ++ complete(&nfc->done); ++ ++ return IRQ_HANDLED; ++} ++ ++static int rk_nfc_enable_clks(struct device *dev, struct rk_nfc *nfc) ++{ ++ int ret; ++ ++ if (!IS_ERR(nfc->nfc_clk)) { ++ ret = clk_prepare_enable(nfc->nfc_clk); ++ if (ret) { ++ dev_err(dev, "failed to enable NFC clk\n"); ++ return ret; ++ } ++ } ++ ++ ret = clk_prepare_enable(nfc->ahb_clk); ++ if (ret) { ++ dev_err(dev, "failed to enable ahb clk\n"); ++ if (!IS_ERR(nfc->nfc_clk)) ++ clk_disable_unprepare(nfc->nfc_clk); ++ return ret; ++ } ++ ++ return 0; ++} ++ ++static void rk_nfc_disable_clks(struct rk_nfc *nfc) ++{ ++ if (!IS_ERR(nfc->nfc_clk)) ++ clk_disable_unprepare(nfc->nfc_clk); ++ clk_disable_unprepare(nfc->ahb_clk); ++} ++ ++static int rk_nfc_ooblayout_free(struct mtd_info *mtd, int section, ++ struct mtd_oob_region *oob_region) ++{ ++ struct nand_chip *chip = mtd_to_nand(mtd); ++ struct rk_nfc_nand_chip *rknand = rk_nfc_to_rknand(chip); ++ ++ if (section) ++ return -ERANGE; ++ ++ /* ++ * The beginning of the OOB area stores the reserved data for the NFC, ++ * the size of the reserved data is NFC_SYS_DATA_SIZE bytes. ++ */ ++ oob_region->length = rknand->metadata_size - NFC_SYS_DATA_SIZE - 2; ++ oob_region->offset = NFC_SYS_DATA_SIZE + 2; ++ ++ return 0; ++} ++ ++static int rk_nfc_ooblayout_ecc(struct mtd_info *mtd, int section, ++ struct mtd_oob_region *oob_region) ++{ ++ struct nand_chip *chip = mtd_to_nand(mtd); ++ struct rk_nfc_nand_chip *rknand = rk_nfc_to_rknand(chip); ++ ++ if (section) ++ return -ERANGE; ++ ++ oob_region->length = mtd->oobsize - rknand->metadata_size; ++ oob_region->offset = rknand->metadata_size; ++ ++ return 0; ++} ++ ++static const struct mtd_ooblayout_ops rk_nfc_ooblayout_ops = { ++ .free = rk_nfc_ooblayout_free, ++ .ecc = rk_nfc_ooblayout_ecc, ++}; ++ ++static int rk_nfc_ecc_init(struct device *dev, struct mtd_info *mtd) ++{ ++ struct nand_chip *chip = mtd_to_nand(mtd); ++ struct rk_nfc *nfc = nand_get_controller_data(chip); ++ struct nand_ecc_ctrl *ecc = &chip->ecc; ++ const u8 *strengths = nfc->cfg->ecc_strengths; ++ u8 max_strength, nfc_max_strength; ++ int i; ++ ++ nfc_max_strength = nfc->cfg->ecc_strengths[0]; ++ /* If optional dt settings not present. */ ++ if (!ecc->size || !ecc->strength || ++ ecc->strength > nfc_max_strength) { ++ chip->ecc.size = 1024; ++ ecc->steps = mtd->writesize / ecc->size; ++ ++ /* ++ * HW ECC always requests the number of ECC bytes per 1024 byte ++ * blocks. The first 4 OOB bytes are reserved for sys data. ++ */ ++ max_strength = ((mtd->oobsize / ecc->steps) - 4) * 8 / ++ fls(8 * 1024); ++ if (max_strength > nfc_max_strength) ++ max_strength = nfc_max_strength; ++ ++ for (i = 0; i < 4; i++) { ++ if (max_strength >= strengths[i]) ++ break; ++ } ++ ++ if (i >= 4) { ++ dev_err(nfc->dev, "unsupported ECC strength\n"); ++ return -EOPNOTSUPP; ++ } ++ ++ ecc->strength = strengths[i]; ++ } ++ ecc->steps = mtd->writesize / ecc->size; ++ ecc->bytes = DIV_ROUND_UP(ecc->strength * fls(8 * chip->ecc.size), 8); ++ ++ return 0; ++} ++ ++static int rk_nfc_attach_chip(struct nand_chip *chip) ++{ ++ struct mtd_info *mtd = nand_to_mtd(chip); ++ struct device *dev = mtd->dev.parent; ++ struct rk_nfc *nfc = nand_get_controller_data(chip); ++ struct rk_nfc_nand_chip *rknand = rk_nfc_to_rknand(chip); ++ struct nand_ecc_ctrl *ecc = &chip->ecc; ++ int new_page_len, new_oob_len; ++ void *buf; ++ int ret; ++ ++ if (chip->options & NAND_BUSWIDTH_16) { ++ dev_err(dev, "16 bits bus width not supported"); ++ return -EINVAL; ++ } ++ ++ if (ecc->engine_type != NAND_ECC_ENGINE_TYPE_ON_HOST) ++ return 0; ++ ++ ret = rk_nfc_ecc_init(dev, mtd); ++ if (ret) ++ return ret; ++ ++ rknand->metadata_size = NFC_SYS_DATA_SIZE * ecc->steps; ++ ++ if (rknand->metadata_size < NFC_SYS_DATA_SIZE + 2) { ++ dev_err(dev, ++ "driver needs at least %d bytes of meta data\n", ++ NFC_SYS_DATA_SIZE + 2); ++ return -EIO; ++ } ++ ++ /* Check buffer first, avoid duplicate alloc buffer. */ ++ new_page_len = mtd->writesize + mtd->oobsize; ++ if (nfc->page_buf && new_page_len > nfc->page_buf_size) { ++ buf = krealloc(nfc->page_buf, new_page_len, ++ GFP_KERNEL | GFP_DMA); ++ if (!buf) ++ return -ENOMEM; ++ nfc->page_buf = buf; ++ nfc->page_buf_size = new_page_len; ++ } ++ ++ new_oob_len = ecc->steps * NFC_MAX_OOB_PER_STEP; ++ if (nfc->oob_buf && new_oob_len > nfc->oob_buf_size) { ++ buf = krealloc(nfc->oob_buf, new_oob_len, ++ GFP_KERNEL | GFP_DMA); ++ if (!buf) { ++ kfree(nfc->page_buf); ++ nfc->page_buf = NULL; ++ return -ENOMEM; ++ } ++ nfc->oob_buf = buf; ++ nfc->oob_buf_size = new_oob_len; ++ } ++ ++ if (!nfc->page_buf) { ++ nfc->page_buf = kzalloc(new_page_len, GFP_KERNEL | GFP_DMA); ++ if (!nfc->page_buf) ++ return -ENOMEM; ++ nfc->page_buf_size = new_page_len; ++ } ++ ++ if (!nfc->oob_buf) { ++ nfc->oob_buf = kzalloc(new_oob_len, GFP_KERNEL | GFP_DMA); ++ if (!nfc->oob_buf) { ++ kfree(nfc->page_buf); ++ nfc->page_buf = NULL; ++ return -ENOMEM; ++ } ++ nfc->oob_buf_size = new_oob_len; ++ } ++ ++ chip->ecc.write_page_raw = rk_nfc_write_page_raw; ++ chip->ecc.write_page = rk_nfc_write_page_hwecc; ++ chip->ecc.write_oob = rk_nfc_write_oob; ++ ++ chip->ecc.read_page_raw = rk_nfc_read_page_raw; ++ chip->ecc.read_page = rk_nfc_read_page_hwecc; ++ chip->ecc.read_oob = rk_nfc_read_oob; ++ ++ return 0; ++} ++ ++static const struct nand_controller_ops rk_nfc_controller_ops = { ++ .attach_chip = rk_nfc_attach_chip, ++ .exec_op = rk_nfc_exec_op, ++ .setup_interface = rk_nfc_setup_interface, ++}; ++ ++static int rk_nfc_nand_chip_init(struct device *dev, struct rk_nfc *nfc, ++ struct device_node *np) ++{ ++ struct rk_nfc_nand_chip *rknand; ++ struct nand_chip *chip; ++ struct mtd_info *mtd; ++ int nsels; ++ u32 tmp; ++ int ret; ++ int i; ++ ++ if (!of_get_property(np, "reg", &nsels)) ++ return -ENODEV; ++ nsels /= sizeof(u32); ++ if (!nsels || nsels > NFC_MAX_NSELS) { ++ dev_err(dev, "invalid reg property size %d\n", nsels); ++ return -EINVAL; ++ } ++ ++ rknand = devm_kzalloc(dev, sizeof(*rknand) + nsels * sizeof(u8), ++ GFP_KERNEL); ++ if (!rknand) ++ return -ENOMEM; ++ ++ rknand->nsels = nsels; ++ for (i = 0; i < nsels; i++) { ++ ret = of_property_read_u32_index(np, "reg", i, &tmp); ++ if (ret) { ++ dev_err(dev, "reg property failure : %d\n", ret); ++ return ret; ++ } ++ ++ if (tmp >= NFC_MAX_NSELS) { ++ dev_err(dev, "invalid CS: %u\n", tmp); ++ return -EINVAL; ++ } ++ ++ if (test_and_set_bit(tmp, &nfc->assigned_cs)) { ++ dev_err(dev, "CS %u already assigned\n", tmp); ++ return -EINVAL; ++ } ++ ++ rknand->sels[i] = tmp; ++ } ++ ++ chip = &rknand->chip; ++ chip->controller = &nfc->controller; ++ ++ nand_set_flash_node(chip, np); ++ ++ nand_set_controller_data(chip, nfc); ++ ++ chip->options |= NAND_USES_DMA | NAND_NO_SUBPAGE_WRITE; ++ chip->bbt_options = NAND_BBT_USE_FLASH | NAND_BBT_NO_OOB; ++ ++ /* Set default mode in case dt entry is missing. */ ++ chip->ecc.engine_type = NAND_ECC_ENGINE_TYPE_ON_HOST; ++ ++ mtd = nand_to_mtd(chip); ++ mtd->owner = THIS_MODULE; ++ mtd->dev.parent = dev; ++ ++ if (!mtd->name) { ++ dev_err(nfc->dev, "NAND label property is mandatory\n"); ++ return -EINVAL; ++ } ++ ++ mtd_set_ooblayout(mtd, &rk_nfc_ooblayout_ops); ++ rk_nfc_hw_init(nfc); ++ ret = nand_scan(chip, nsels); ++ if (ret) ++ return ret; ++ ++ if (chip->options & NAND_IS_BOOT_MEDIUM) { ++ ret = of_property_read_u32(np, "rockchip,boot-blks", &tmp); ++ rknand->boot_blks = ret ? 0 : tmp; ++ ++ ret = of_property_read_u32(np, "rockchip,boot-ecc-strength", ++ &tmp); ++ rknand->boot_ecc = ret ? chip->ecc.strength : tmp; ++ } ++ ++ ret = mtd_device_register(mtd, NULL, 0); ++ if (ret) { ++ dev_err(dev, "MTD parse partition error\n"); ++ nand_cleanup(chip); ++ return ret; ++ } ++ ++ list_add_tail(&rknand->node, &nfc->chips); ++ ++ return 0; ++} ++ ++static void rk_nfc_chips_cleanup(struct rk_nfc *nfc) ++{ ++ struct rk_nfc_nand_chip *rknand, *tmp; ++ struct nand_chip *chip; ++ int ret; ++ ++ list_for_each_entry_safe(rknand, tmp, &nfc->chips, node) { ++ chip = &rknand->chip; ++ ret = mtd_device_unregister(nand_to_mtd(chip)); ++ WARN_ON(ret); ++ nand_cleanup(chip); ++ list_del(&rknand->node); ++ } ++} ++ ++static int rk_nfc_nand_chips_init(struct device *dev, struct rk_nfc *nfc) ++{ ++ struct device_node *np = dev->of_node, *nand_np; ++ int nchips = of_get_child_count(np); ++ int ret; ++ ++ if (!nchips || nchips > NFC_MAX_NSELS) { ++ dev_err(nfc->dev, "incorrect number of NAND chips (%d)\n", ++ nchips); ++ return -EINVAL; ++ } ++ ++ for_each_child_of_node(np, nand_np) { ++ ret = rk_nfc_nand_chip_init(dev, nfc, nand_np); ++ if (ret) { ++ of_node_put(nand_np); ++ rk_nfc_chips_cleanup(nfc); ++ return ret; ++ } ++ } ++ ++ return 0; ++} ++ ++static struct nfc_cfg nfc_v6_cfg = { ++ .type = NFC_V6, ++ .ecc_strengths = {60, 40, 24, 16}, ++ .ecc_cfgs = { ++ 0x00040011, 0x00040001, 0x00000011, 0x00000001, ++ }, ++ .flctl_off = 0x08, ++ .bchctl_off = 0x0C, ++ .dma_cfg_off = 0x10, ++ .dma_data_buf_off = 0x14, ++ .dma_oob_buf_off = 0x18, ++ .dma_st_off = 0x1C, ++ .bch_st_off = 0x20, ++ .randmz_off = 0x150, ++ .int_en_off = 0x16C, ++ .int_clr_off = 0x170, ++ .int_st_off = 0x174, ++ .oob0_off = 0x200, ++ .oob1_off = 0x230, ++ .ecc0 = { ++ .err_flag_bit = 2, ++ .low = 3, ++ .low_mask = 0x1F, ++ .low_bn = 5, ++ .high = 27, ++ .high_mask = 0x1, ++ }, ++ .ecc1 = { ++ .err_flag_bit = 15, ++ .low = 16, ++ .low_mask = 0x1F, ++ .low_bn = 5, ++ .high = 29, ++ .high_mask = 0x1, ++ }, ++}; ++ ++static struct nfc_cfg nfc_v8_cfg = { ++ .type = NFC_V8, ++ .ecc_strengths = {16, 16, 16, 16}, ++ .ecc_cfgs = { ++ 0x00000001, 0x00000001, 0x00000001, 0x00000001, ++ }, ++ .flctl_off = 0x08, ++ .bchctl_off = 0x0C, ++ .dma_cfg_off = 0x10, ++ .dma_data_buf_off = 0x14, ++ .dma_oob_buf_off = 0x18, ++ .dma_st_off = 0x1C, ++ .bch_st_off = 0x20, ++ .randmz_off = 0x150, ++ .int_en_off = 0x16C, ++ .int_clr_off = 0x170, ++ .int_st_off = 0x174, ++ .oob0_off = 0x200, ++ .oob1_off = 0x230, ++ .ecc0 = { ++ .err_flag_bit = 2, ++ .low = 3, ++ .low_mask = 0x1F, ++ .low_bn = 5, ++ .high = 27, ++ .high_mask = 0x1, ++ }, ++ .ecc1 = { ++ .err_flag_bit = 15, ++ .low = 16, ++ .low_mask = 0x1F, ++ .low_bn = 5, ++ .high = 29, ++ .high_mask = 0x1, ++ }, ++}; ++ ++static struct nfc_cfg nfc_v9_cfg = { ++ .type = NFC_V9, ++ .ecc_strengths = {70, 60, 40, 16}, ++ .ecc_cfgs = { ++ 0x00000001, 0x06000001, 0x04000001, 0x02000001, ++ }, ++ .flctl_off = 0x10, ++ .bchctl_off = 0x20, ++ .dma_cfg_off = 0x30, ++ .dma_data_buf_off = 0x34, ++ .dma_oob_buf_off = 0x38, ++ .dma_st_off = 0x3C, ++ .bch_st_off = 0x150, ++ .randmz_off = 0x208, ++ .int_en_off = 0x120, ++ .int_clr_off = 0x124, ++ .int_st_off = 0x128, ++ .oob0_off = 0x200, ++ .oob1_off = 0x204, ++ .ecc0 = { ++ .err_flag_bit = 2, ++ .low = 3, ++ .low_mask = 0x7F, ++ .low_bn = 7, ++ .high = 0, ++ .high_mask = 0x0, ++ }, ++ .ecc1 = { ++ .err_flag_bit = 18, ++ .low = 19, ++ .low_mask = 0x7F, ++ .low_bn = 7, ++ .high = 0, ++ .high_mask = 0x0, ++ }, ++}; ++ ++static const struct of_device_id rk_nfc_id_table[] = { ++ { ++ .compatible = "rockchip,px30-nfc", ++ .data = &nfc_v9_cfg ++ }, ++ { ++ .compatible = "rockchip,rk2928-nfc", ++ .data = &nfc_v6_cfg ++ }, ++ { ++ .compatible = "rockchip,rv1108-nfc", ++ .data = &nfc_v8_cfg ++ }, ++ { /* sentinel */ } ++}; ++MODULE_DEVICE_TABLE(of, rk_nfc_id_table); ++ ++static int rk_nfc_probe(struct platform_device *pdev) ++{ ++ struct device *dev = &pdev->dev; ++ struct rk_nfc *nfc; ++ int ret, irq; ++ ++ nfc = devm_kzalloc(dev, sizeof(*nfc), GFP_KERNEL); ++ if (!nfc) ++ return -ENOMEM; ++ ++ nand_controller_init(&nfc->controller); ++ INIT_LIST_HEAD(&nfc->chips); ++ nfc->controller.ops = &rk_nfc_controller_ops; ++ ++ nfc->cfg = of_device_get_match_data(dev); ++ nfc->dev = dev; ++ ++ init_completion(&nfc->done); ++ ++ nfc->regs = devm_platform_ioremap_resource(pdev, 0); ++ if (IS_ERR(nfc->regs)) { ++ ret = PTR_ERR(nfc->regs); ++ goto release_nfc; ++ } ++ ++ nfc->nfc_clk = devm_clk_get(dev, "nfc"); ++ if (IS_ERR(nfc->nfc_clk)) { ++ dev_dbg(dev, "no NFC clk\n"); ++ /* Some earlier models, such as rk3066, have no NFC clk. */ ++ } ++ ++ nfc->ahb_clk = devm_clk_get(dev, "ahb"); ++ if (IS_ERR(nfc->ahb_clk)) { ++ dev_err(dev, "no ahb clk\n"); ++ ret = PTR_ERR(nfc->ahb_clk); ++ goto release_nfc; ++ } ++ ++ ret = rk_nfc_enable_clks(dev, nfc); ++ if (ret) ++ goto release_nfc; ++ ++ irq = platform_get_irq(pdev, 0); ++ if (irq < 0) { ++ dev_err(dev, "no NFC irq resource\n"); ++ ret = -EINVAL; ++ goto clk_disable; ++ } ++ ++ writel(0, nfc->regs + nfc->cfg->int_en_off); ++ ret = devm_request_irq(dev, irq, rk_nfc_irq, 0x0, "rk-nand", nfc); ++ if (ret) { ++ dev_err(dev, "failed to request NFC irq\n"); ++ goto clk_disable; ++ } ++ ++ platform_set_drvdata(pdev, nfc); ++ ++ ret = rk_nfc_nand_chips_init(dev, nfc); ++ if (ret) { ++ dev_err(dev, "failed to init NAND chips\n"); ++ goto clk_disable; ++ } ++ return 0; ++ ++clk_disable: ++ rk_nfc_disable_clks(nfc); ++release_nfc: ++ return ret; ++} ++ ++static int rk_nfc_remove(struct platform_device *pdev) ++{ ++ struct rk_nfc *nfc = platform_get_drvdata(pdev); ++ ++ kfree(nfc->page_buf); ++ kfree(nfc->oob_buf); ++ rk_nfc_chips_cleanup(nfc); ++ rk_nfc_disable_clks(nfc); ++ ++ return 0; ++} ++ ++static int __maybe_unused rk_nfc_suspend(struct device *dev) ++{ ++ struct rk_nfc *nfc = dev_get_drvdata(dev); ++ ++ rk_nfc_disable_clks(nfc); ++ ++ return 0; ++} ++ ++static int __maybe_unused rk_nfc_resume(struct device *dev) ++{ ++ struct rk_nfc *nfc = dev_get_drvdata(dev); ++ struct rk_nfc_nand_chip *rknand; ++ struct nand_chip *chip; ++ int ret; ++ u32 i; ++ ++ ret = rk_nfc_enable_clks(dev, nfc); ++ if (ret) ++ return ret; ++ ++ /* Reset NAND chip if VCC was powered off. */ ++ list_for_each_entry(rknand, &nfc->chips, node) { ++ chip = &rknand->chip; ++ for (i = 0; i < rknand->nsels; i++) ++ nand_reset(chip, i); ++ } ++ ++ return 0; ++} ++ ++static const struct dev_pm_ops rk_nfc_pm_ops = { ++ SET_SYSTEM_SLEEP_PM_OPS(rk_nfc_suspend, rk_nfc_resume) ++}; ++ ++static struct platform_driver rk_nfc_driver = { ++ .probe = rk_nfc_probe, ++ .remove = rk_nfc_remove, ++ .driver = { ++ .name = "rockchip-nfc", ++ .of_match_table = rk_nfc_id_table, ++ .pm = &rk_nfc_pm_ops, ++ }, ++}; ++ ++module_platform_driver(rk_nfc_driver); ++ ++MODULE_LICENSE("Dual MIT/GPL"); ++MODULE_AUTHOR("Yifeng Zhao "); ++MODULE_DESCRIPTION("Rockchip Nand Flash Controller Driver"); ++MODULE_ALIAS("platform:rockchip-nand-controller"); + +From eaf9cd3f96b027c7e51aa7031315a32bc4f1abd3 Mon Sep 17 00:00:00 2001 +From: Yifeng Zhao +Date: Thu, 10 Dec 2020 08:21:33 +0800 +Subject: [PATCH] MAINTAINERS: add maintainers to ROCKCHIP NFC + +Add maintainers to ROCKCHIP NFC. + +Signed-off-by: Yifeng Zhao +--- + MAINTAINERS | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +diff --git a/MAINTAINERS b/MAINTAINERS +index 281de213ef47..af53d0c45407 100644 +--- a/MAINTAINERS ++++ b/MAINTAINERS +@@ -2371,12 +2371,12 @@ L: linux-arm-kernel@lists.infradead.org (moderated for non-subscribers) + L: linux-rockchip@lists.infradead.org + S: Maintained + T: git git://git.kernel.org/pub/scm/linux/kernel/git/mmind/linux-rockchip.git ++F: Documentation/devicetree/bindings/*/*rockchip*.yaml + F: Documentation/devicetree/bindings/i2c/i2c-rk3x.yaml +-F: Documentation/devicetree/bindings/mmc/rockchip-dw-mshc.yaml +-F: Documentation/devicetree/bindings/spi/spi-rockchip.yaml + F: arch/arm/boot/dts/rk3* + F: arch/arm/boot/dts/rv1108* + F: arch/arm/mach-rockchip/ ++F: drivers/*/*/*/*rockchip* + F: drivers/*/*/*rockchip* + F: drivers/*/*rockchip* + F: drivers/clk/rockchip/ + +From 49f112f3169f78312b6879c3e1b4959d6060b6dc Mon Sep 17 00:00:00 2001 +From: Yifeng Zhao +Date: Thu, 10 Dec 2020 08:21:34 +0800 +Subject: [PATCH] arm64: dts: rockchip: Add NFC node for RK3308 SoC + +Add NAND FLASH Controller(NFC) node for RK3308 SoC. + +Signed-off-by: Yifeng Zhao +--- + arch/arm64/boot/dts/rockchip/rk3308.dtsi | 15 +++++++++++++++ + 1 file changed, 15 insertions(+) + +diff --git a/arch/arm64/boot/dts/rockchip/rk3308.dtsi b/arch/arm64/boot/dts/rockchip/rk3308.dtsi +index 2560b98771ca..7211fab7a6e4 100644 +--- a/arch/arm64/boot/dts/rockchip/rk3308.dtsi ++++ b/arch/arm64/boot/dts/rockchip/rk3308.dtsi +@@ -629,6 +629,21 @@ sdio: mmc@ff4a0000 { + status = "disabled"; + }; + ++ nfc: nand-controller@ff4b0000 { ++ compatible = "rockchip,rk3308-nfc", ++ "rockchip,rv1108-nfc"; ++ reg = <0x0 0xff4b0000 0x0 0x4000>; ++ interrupts = ; ++ clocks = <&cru HCLK_NANDC>, <&cru SCLK_NANDC>; ++ clock-names = "ahb", "nfc"; ++ assigned-clocks = <&cru SCLK_NANDC>; ++ assigned-clock-rates = <150000000>; ++ pinctrl-0 = <&flash_ale &flash_bus8 &flash_cle &flash_csn0 ++ &flash_rdn &flash_rdy &flash_wrn>; ++ pinctrl-names = "default"; ++ status = "disabled"; ++ }; ++ + cru: clock-controller@ff500000 { + compatible = "rockchip,rk3308-cru"; + reg = <0x0 0xff500000 0x0 0x1000>; + +From 4f115c807f1f8cf6899798bc3f2a01adc68bc593 Mon Sep 17 00:00:00 2001 +From: Yifeng Zhao +Date: Thu, 10 Dec 2020 08:22:16 +0800 +Subject: [PATCH] arm64: dts: rockchip: Add NFC node for PX30 SoC + +Add NAND FLASH Controller(NFC) node for PX30 SoC. + +Signed-off-by: Yifeng Zhao +--- + arch/arm64/boot/dts/rockchip/px30.dtsi | 15 +++++++++++++++ + 1 file changed, 15 insertions(+) + +diff --git a/arch/arm64/boot/dts/rockchip/px30.dtsi b/arch/arm64/boot/dts/rockchip/px30.dtsi +index 2695ea8cda14..6cd67e80d623 100644 +--- a/arch/arm64/boot/dts/rockchip/px30.dtsi ++++ b/arch/arm64/boot/dts/rockchip/px30.dtsi +@@ -973,6 +973,21 @@ emmc: mmc@ff390000 { + status = "disabled"; + }; + ++ nfc: nand-controller@ff3b0000 { ++ compatible = "rockchip,px30-nfc"; ++ reg = <0x0 0xff3b0000 0x0 0x4000>; ++ interrupts = ; ++ clocks = <&cru HCLK_NANDC>, <&cru SCLK_NANDC>; ++ clock-names = "ahb", "nfc"; ++ assigned-clocks = <&cru SCLK_NANDC>; ++ assigned-clock-rates = <150000000>; ++ pinctrl-names = "default"; ++ pinctrl-0 = <&flash_ale &flash_bus8 &flash_cle &flash_cs0 ++ &flash_rdn &flash_rdy &flash_wrn &flash_dqs>; ++ power-domains = <&power PX30_PD_MMC_NAND>; ++ status = "disabled"; ++ }; ++ + gpu: gpu@ff400000 { + compatible = "rockchip,px30-mali", "arm,mali-bifrost"; + reg = <0x0 0xff400000 0x0 0x4000>; + +From c078249d7f7f201bb0a4f1daaf38a7aade05882f Mon Sep 17 00:00:00 2001 +From: Yifeng Zhao +Date: Thu, 10 Dec 2020 08:22:17 +0800 +Subject: [PATCH] arm: dts: rockchip: Add NFC node for RV1108 SoC + +Add NAND FLASH Controller(NFC) node for RV1108 SoC. + +Signed-off-by: Yifeng Zhao +--- + arch/arm/boot/dts/rv1108.dtsi | 11 +++++++++++ + 1 file changed, 11 insertions(+) + +diff --git a/arch/arm/boot/dts/rv1108.dtsi b/arch/arm/boot/dts/rv1108.dtsi +index e491964b1c3d..15fa25585ea4 100644 +--- a/arch/arm/boot/dts/rv1108.dtsi ++++ b/arch/arm/boot/dts/rv1108.dtsi +@@ -452,6 +452,17 @@ cru: clock-controller@20200000 { + #reset-cells = <1>; + }; + ++ nfc: nand-controller@30100000 { ++ compatible = "rockchip,rv1108-nfc"; ++ reg = <0x30100000 0x1000>; ++ interrupts = ; ++ clocks = <&cru HCLK_NANDC>, <&cru SCLK_NANDC>; ++ clock-names = "ahb", "nfc"; ++ assigned-clocks = <&cru SCLK_NANDC>; ++ assigned-clock-rates = <150000000>; ++ status = "disabled"; ++ }; ++ + emmc: mmc@30110000 { + compatible = "rockchip,rv1108-dw-mshc", "rockchip,rk3288-dw-mshc"; + reg = <0x30110000 0x4000>; + +From a2b3dcfa3009e4a5626619ece0b4e863e0b80c6e Mon Sep 17 00:00:00 2001 +From: Yifeng Zhao +Date: Thu, 10 Dec 2020 08:22:18 +0800 +Subject: [PATCH] arm: dts: rockchip: Add NFC node for RK2928 and other SoCs + +Add NAND FLASH Controller(NFC) node for RK2928, RK3066, RK3168 +and RK3188 SoCs. + +Signed-off-by: Yifeng Zhao +--- + arch/arm/boot/dts/rk3xxx.dtsi | 9 +++++++++ + 1 file changed, 9 insertions(+) + +diff --git a/arch/arm/boot/dts/rk3xxx.dtsi b/arch/arm/boot/dts/rk3xxx.dtsi +index 859a7477909f..97415180d5bb 100644 +--- a/arch/arm/boot/dts/rk3xxx.dtsi ++++ b/arch/arm/boot/dts/rk3xxx.dtsi +@@ -276,6 +276,15 @@ emmc: mmc@1021c000 { + status = "disabled"; + }; + ++ nfc: nand-controller@10500000 { ++ compatible = "rockchip,rk2928-nfc"; ++ reg = <0x10500000 0x4000>; ++ interrupts = ; ++ clocks = <&cru HCLK_NANDC0>; ++ clock-names = "ahb"; ++ status = "disabled"; ++ }; ++ + pmu: pmu@20004000 { + compatible = "rockchip,rk3066-pmu", "syscon", "simple-mfd"; + reg = <0x20004000 0x100>; + +From 30fdf17b93046c1836b53a4e029433a898e0b0ff Mon Sep 17 00:00:00 2001 +From: Yifeng Zhao +Date: Thu, 10 Dec 2020 08:22:19 +0800 +Subject: [PATCH] arm: dts: rockchip: Add NFC node for RK3036 SoC + +Add NAND FLASH Controller(NFC) node for RK3036 SoC. + +Signed-off-by: Yifeng Zhao +--- + arch/arm/boot/dts/rk3036.dtsi | 52 +++++++++++++++++++++++++++++++++++ + 1 file changed, 52 insertions(+) + +diff --git a/arch/arm/boot/dts/rk3036.dtsi b/arch/arm/boot/dts/rk3036.dtsi +index 093567022386..dda5a1f79aca 100644 +--- a/arch/arm/boot/dts/rk3036.dtsi ++++ b/arch/arm/boot/dts/rk3036.dtsi +@@ -292,6 +292,21 @@ i2s: i2s@10220000 { + status = "disabled"; + }; + ++ nfc: nand-controller@10500000 { ++ compatible = "rockchip,rk3036-nfc", ++ "rockchip,rk2928-nfc"; ++ reg = <0x10500000 0x4000>; ++ interrupts = ; ++ clocks = <&cru HCLK_NANDC>, <&cru SCLK_NANDC>; ++ clock-names = "ahb", "nfc"; ++ assigned-clocks = <&cru SCLK_NANDC>; ++ assigned-clock-rates = <150000000>; ++ pinctrl-0 = <&flash_ale &flash_bus8 &flash_cle &flash_csn0 ++ &flash_rdn &flash_rdy &flash_wrn>; ++ pinctrl-names = "default"; ++ status = "disabled"; ++ }; ++ + cru: clock-controller@20000000 { + compatible = "rockchip,rk3036-cru"; + reg = <0x20000000 0x1000>; +@@ -643,6 +658,43 @@ emmc_bus8: emmc-bus8 { + }; + }; + ++ nfc { ++ flash_ale: flash-ale { ++ rockchip,pins = <2 RK_PA0 1 &pcfg_pull_default>; ++ }; ++ ++ flash_bus8: flash-bus8 { ++ rockchip,pins = <1 RK_PD0 1 &pcfg_pull_default>, ++ <1 RK_PD1 1 &pcfg_pull_default>, ++ <1 RK_PD2 1 &pcfg_pull_default>, ++ <1 RK_PD3 1 &pcfg_pull_default>, ++ <1 RK_PD4 1 &pcfg_pull_default>, ++ <1 RK_PD5 1 &pcfg_pull_default>, ++ <1 RK_PD6 1 &pcfg_pull_default>, ++ <1 RK_PD7 1 &pcfg_pull_default>; ++ }; ++ ++ flash_cle: flash-cle { ++ rockchip,pins = <2 RK_PA1 1 &pcfg_pull_default>; ++ }; ++ ++ flash_csn0: flash-csn0 { ++ rockchip,pins = <2 RK_PA6 1 &pcfg_pull_default>; ++ }; ++ ++ flash_rdn: flash-rdn { ++ rockchip,pins = <2 RK_PA3 1 &pcfg_pull_default>; ++ }; ++ ++ flash_rdy: flash-rdy { ++ rockchip,pins = <2 RK_PA4 1 &pcfg_pull_default>; ++ }; ++ ++ flash_wrn: flash-wrn { ++ rockchip,pins = <2 RK_PA2 1 &pcfg_pull_default>; ++ }; ++ }; ++ + emac { + emac_xfer: emac-xfer { + rockchip,pins = <2 RK_PB2 1 &pcfg_pull_default>, /* crs_dvalid */ + +From cbfd2b0ef3a8f9fd9f01c624ec8c6d1f2d88c03e 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 c06d0adeb1b8a7ac9425babd62735b8a0c6b9d56 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 6dc85616fe294fb654e9fb56dd0337dc8db7c327 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 632faab3a9357dfafa106dfb9dc79a8fda5b9244 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 e56866c52176763055e0e40c7d252d2ff186f56d 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 f9ca0e800d2db88c3e8e25d8183b35c5ea2cdbc4 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 */ } + }; + diff --git a/patch/kernel/rk322x-current/01-linux-1003-rockchip-v4l-next-from-list.patch b/patch/kernel/rk322x-current/01-linux-0010-v4l-from-list.patch similarity index 73% rename from patch/kernel/rk322x-current/01-linux-1003-rockchip-v4l-next-from-list.patch rename to patch/kernel/rk322x-current/01-linux-0010-v4l-from-list.patch index 55c2ca8d2..cbdca440a 100644 --- a/patch/kernel/rk322x-current/01-linux-1003-rockchip-v4l-next-from-list.patch +++ b/patch/kernel/rk322x-current/01-linux-0010-v4l-from-list.patch @@ -1,1438 +1,4 @@ -From 870dd90b0125166814242569481782060ca018c4 Mon Sep 17 00:00:00 2001 -From: Jacopo Mondi -Date: Fri, 17 Jul 2020 16:53:16 +0200 -Subject: [PATCH] media: i2c: Use the new get_mbus_config pad op - -Move the existing users of the g_mbus_config video operation to use the -newly introduced get_mbus_config pad operations. - -All the ported drivers report a static media bus configuration and do no -support s_mbus_config so the operation implementation has not changed. - -Bridge drivers needs to call the new pad operation and will receive an --ENOICTLCMD when calling the old g_mbus_config video operation - -Signed-off-by: Jacopo Mondi -Signed-off-by: Hans Verkuil -Signed-off-by: Mauro Carvalho Chehab ---- - drivers/media/i2c/adv7180.c | 7 ++++--- - drivers/media/i2c/ml86v7667.c | 7 ++++--- - drivers/media/i2c/mt9m001.c | 7 ++++--- - drivers/media/i2c/mt9m111.c | 7 ++++--- - drivers/media/i2c/ov9640.c | 7 ++++--- - drivers/media/i2c/tc358743.c | 7 ++++--- - drivers/media/i2c/tvp5150.c | 7 ++++--- - 7 files changed, 28 insertions(+), 21 deletions(-) - -diff --git a/drivers/media/i2c/adv7180.c b/drivers/media/i2c/adv7180.c -index 00159daa6fcd..e8744efe3cf0 100644 ---- a/drivers/media/i2c/adv7180.c -+++ b/drivers/media/i2c/adv7180.c -@@ -760,8 +760,9 @@ static int adv7180_init_cfg(struct v4l2_subdev *sd, - return adv7180_set_pad_format(sd, cfg, &fmt); - } - --static int adv7180_g_mbus_config(struct v4l2_subdev *sd, -- struct v4l2_mbus_config *cfg) -+static int adv7180_get_mbus_config(struct v4l2_subdev *sd, -+ unsigned int pad, -+ struct v4l2_mbus_config *cfg) - { - struct adv7180_state *state = to_state(sd); - -@@ -852,7 +853,6 @@ static const struct v4l2_subdev_video_ops adv7180_video_ops = { - .querystd = adv7180_querystd, - .g_input_status = adv7180_g_input_status, - .s_routing = adv7180_s_routing, -- .g_mbus_config = adv7180_g_mbus_config, - .g_pixelaspect = adv7180_g_pixelaspect, - .g_tvnorms = adv7180_g_tvnorms, - .s_stream = adv7180_s_stream, -@@ -869,6 +869,7 @@ static const struct v4l2_subdev_pad_ops adv7180_pad_ops = { - .enum_mbus_code = adv7180_enum_mbus_code, - .set_fmt = adv7180_set_pad_format, - .get_fmt = adv7180_get_pad_format, -+ .get_mbus_config = adv7180_get_mbus_config, - }; - - static const struct v4l2_subdev_sensor_ops adv7180_sensor_ops = { -diff --git a/drivers/media/i2c/ml86v7667.c b/drivers/media/i2c/ml86v7667.c -index c444bd6a0658..ff212335326a 100644 ---- a/drivers/media/i2c/ml86v7667.c -+++ b/drivers/media/i2c/ml86v7667.c -@@ -219,8 +219,9 @@ static int ml86v7667_fill_fmt(struct v4l2_subdev *sd, - return 0; - } - --static int ml86v7667_g_mbus_config(struct v4l2_subdev *sd, -- struct v4l2_mbus_config *cfg) -+static int ml86v7667_get_mbus_config(struct v4l2_subdev *sd, -+ unsigned int pad, -+ struct v4l2_mbus_config *cfg) - { - cfg->flags = V4L2_MBUS_MASTER | V4L2_MBUS_PCLK_SAMPLE_RISING | - V4L2_MBUS_DATA_ACTIVE_HIGH; -@@ -291,13 +292,13 @@ static const struct v4l2_subdev_video_ops ml86v7667_subdev_video_ops = { - .s_std = ml86v7667_s_std, - .querystd = ml86v7667_querystd, - .g_input_status = ml86v7667_g_input_status, -- .g_mbus_config = ml86v7667_g_mbus_config, - }; - - static const struct v4l2_subdev_pad_ops ml86v7667_subdev_pad_ops = { - .enum_mbus_code = ml86v7667_enum_mbus_code, - .get_fmt = ml86v7667_fill_fmt, - .set_fmt = ml86v7667_fill_fmt, -+ .get_mbus_config = ml86v7667_get_mbus_config, - }; - - static const struct v4l2_subdev_core_ops ml86v7667_subdev_core_ops = { -diff --git a/drivers/media/i2c/mt9m001.c b/drivers/media/i2c/mt9m001.c -index 210ea76adb53..3b0ba8ed5233 100644 ---- a/drivers/media/i2c/mt9m001.c -+++ b/drivers/media/i2c/mt9m001.c -@@ -689,8 +689,9 @@ static int mt9m001_enum_mbus_code(struct v4l2_subdev *sd, - return 0; - } - --static int mt9m001_g_mbus_config(struct v4l2_subdev *sd, -- struct v4l2_mbus_config *cfg) -+static int mt9m001_get_mbus_config(struct v4l2_subdev *sd, -+ unsigned int pad, -+ struct v4l2_mbus_config *cfg) - { - /* MT9M001 has all capture_format parameters fixed */ - cfg->flags = V4L2_MBUS_PCLK_SAMPLE_FALLING | -@@ -703,7 +704,6 @@ static int mt9m001_g_mbus_config(struct v4l2_subdev *sd, - - static const struct v4l2_subdev_video_ops mt9m001_subdev_video_ops = { - .s_stream = mt9m001_s_stream, -- .g_mbus_config = mt9m001_g_mbus_config, - }; - - static const struct v4l2_subdev_sensor_ops mt9m001_subdev_sensor_ops = { -@@ -717,6 +717,7 @@ static const struct v4l2_subdev_pad_ops mt9m001_subdev_pad_ops = { - .set_selection = mt9m001_set_selection, - .get_fmt = mt9m001_get_fmt, - .set_fmt = mt9m001_set_fmt, -+ .get_mbus_config = mt9m001_get_mbus_config, - }; - - static const struct v4l2_subdev_ops mt9m001_subdev_ops = { -diff --git a/drivers/media/i2c/mt9m111.c b/drivers/media/i2c/mt9m111.c -index 17e8253f5748..69697386ffcd 100644 ---- a/drivers/media/i2c/mt9m111.c -+++ b/drivers/media/i2c/mt9m111.c -@@ -1137,8 +1137,9 @@ static int mt9m111_init_cfg(struct v4l2_subdev *sd, - return 0; - } - --static int mt9m111_g_mbus_config(struct v4l2_subdev *sd, -- struct v4l2_mbus_config *cfg) -+static int mt9m111_get_mbus_config(struct v4l2_subdev *sd, -+ unsigned int pad, -+ struct v4l2_mbus_config *cfg) - { - struct mt9m111 *mt9m111 = container_of(sd, struct mt9m111, subdev); - -@@ -1155,7 +1156,6 @@ static int mt9m111_g_mbus_config(struct v4l2_subdev *sd, - } - - static const struct v4l2_subdev_video_ops mt9m111_subdev_video_ops = { -- .g_mbus_config = mt9m111_g_mbus_config, - .s_stream = mt9m111_s_stream, - .g_frame_interval = mt9m111_g_frame_interval, - .s_frame_interval = mt9m111_s_frame_interval, -@@ -1168,6 +1168,7 @@ static const struct v4l2_subdev_pad_ops mt9m111_subdev_pad_ops = { - .set_selection = mt9m111_set_selection, - .get_fmt = mt9m111_get_fmt, - .set_fmt = mt9m111_set_fmt, -+ .get_mbus_config = mt9m111_get_mbus_config, - }; - - static const struct v4l2_subdev_ops mt9m111_subdev_ops = { -diff --git a/drivers/media/i2c/ov9640.c b/drivers/media/i2c/ov9640.c -index 3a21f51d9325..fbd5d7b75811 100644 ---- a/drivers/media/i2c/ov9640.c -+++ b/drivers/media/i2c/ov9640.c -@@ -648,8 +648,9 @@ static const struct v4l2_subdev_core_ops ov9640_core_ops = { - }; - - /* Request bus settings on camera side */ --static int ov9640_g_mbus_config(struct v4l2_subdev *sd, -- struct v4l2_mbus_config *cfg) -+static int ov9640_get_mbus_config(struct v4l2_subdev *sd, -+ unsigned int pad, -+ struct v4l2_mbus_config *cfg) - { - cfg->flags = V4L2_MBUS_PCLK_SAMPLE_RISING | V4L2_MBUS_MASTER | - V4L2_MBUS_VSYNC_ACTIVE_HIGH | V4L2_MBUS_HSYNC_ACTIVE_HIGH | -@@ -661,13 +662,13 @@ static int ov9640_g_mbus_config(struct v4l2_subdev *sd, - - static const struct v4l2_subdev_video_ops ov9640_video_ops = { - .s_stream = ov9640_s_stream, -- .g_mbus_config = ov9640_g_mbus_config, - }; - - static const struct v4l2_subdev_pad_ops ov9640_pad_ops = { - .enum_mbus_code = ov9640_enum_mbus_code, - .get_selection = ov9640_get_selection, - .set_fmt = ov9640_set_fmt, -+ .get_mbus_config = ov9640_get_mbus_config, - }; - - static const struct v4l2_subdev_ops ov9640_subdev_ops = { -diff --git a/drivers/media/i2c/tc358743.c b/drivers/media/i2c/tc358743.c -index cff99cf61ed4..831b5b54fd78 100644 ---- a/drivers/media/i2c/tc358743.c -+++ b/drivers/media/i2c/tc358743.c -@@ -1604,8 +1604,9 @@ static int tc358743_dv_timings_cap(struct v4l2_subdev *sd, - return 0; - } - --static int tc358743_g_mbus_config(struct v4l2_subdev *sd, -- struct v4l2_mbus_config *cfg) -+static int tc358743_get_mbus_config(struct v4l2_subdev *sd, -+ unsigned int pad, -+ struct v4l2_mbus_config *cfg) - { - struct tc358743_state *state = to_state(sd); - -@@ -1838,7 +1839,6 @@ static const struct v4l2_subdev_video_ops tc358743_video_ops = { - .s_dv_timings = tc358743_s_dv_timings, - .g_dv_timings = tc358743_g_dv_timings, - .query_dv_timings = tc358743_query_dv_timings, -- .g_mbus_config = tc358743_g_mbus_config, - .s_stream = tc358743_s_stream, - }; - -@@ -1850,6 +1850,7 @@ static const struct v4l2_subdev_pad_ops tc358743_pad_ops = { - .set_edid = tc358743_s_edid, - .enum_dv_timings = tc358743_enum_dv_timings, - .dv_timings_cap = tc358743_dv_timings_cap, -+ .get_mbus_config = tc358743_get_mbus_config, - }; - - static const struct v4l2_subdev_ops tc358743_ops = { -diff --git a/drivers/media/i2c/tvp5150.c b/drivers/media/i2c/tvp5150.c -index 9df575238952..1c2050944b92 100644 ---- a/drivers/media/i2c/tvp5150.c -+++ b/drivers/media/i2c/tvp5150.c -@@ -1191,8 +1191,9 @@ static int tvp5150_get_selection(struct v4l2_subdev *sd, - } - } - --static int tvp5150_g_mbus_config(struct v4l2_subdev *sd, -- struct v4l2_mbus_config *cfg) -+static int tvp5150_get_mbus_config(struct v4l2_subdev *sd, -+ unsigned int pad, -+ struct v4l2_mbus_config *cfg) - { - struct tvp5150 *decoder = to_tvp5150(sd); - -@@ -1721,7 +1722,6 @@ static const struct v4l2_subdev_video_ops tvp5150_video_ops = { - .querystd = tvp5150_querystd, - .s_stream = tvp5150_s_stream, - .s_routing = tvp5150_s_routing, -- .g_mbus_config = tvp5150_g_mbus_config, - }; - - static const struct v4l2_subdev_vbi_ops tvp5150_vbi_ops = { -@@ -1739,6 +1739,7 @@ static const struct v4l2_subdev_pad_ops tvp5150_pad_ops = { - .get_fmt = tvp5150_fill_fmt, - .get_selection = tvp5150_get_selection, - .set_selection = tvp5150_set_selection, -+ .get_mbus_config = tvp5150_get_mbus_config, - }; - - static const struct v4l2_subdev_ops tvp5150_ops = { - -From f26311a09822168657c37ba946a3f74710a3bedc Mon Sep 17 00:00:00 2001 -From: Jacopo Mondi -Date: Tue, 21 Jul 2020 09:53:17 +0200 -Subject: [PATCH] media: i2c: ov6650: Use new [get|set]_mbus_config ops - -Use the new get_mbus_config and set_mbus_config pad operations in place -of the video operations currently in use. - -Compared to other drivers where the same conversion has been performed, -ov6650 proved to be a bit more tricky, as the existing g_mbus_config -implementation did not report the currently applied configuration but -the set of all possible configuration options. - -Adapt the driver to support the semantic of the two newly introduced -operations: -- get_mbus_config reports the current media bus configuration -- set_mbus_config applies only changes explicitly requested and updates - the provided cfg parameter to report what has actually been applied to - the hardware. - -Compile-tested only. - -Signed-off-by: Jacopo Mondi -Signed-off-by: Hans Verkuil -Signed-off-by: Mauro Carvalho Chehab ---- - drivers/media/i2c/ov6650.c | 53 ++++++++++++++++++++++++++------------ - 1 file changed, 37 insertions(+), 16 deletions(-) - -diff --git a/drivers/media/i2c/ov6650.c b/drivers/media/i2c/ov6650.c -index 91906b94f978..48493af81198 100644 ---- a/drivers/media/i2c/ov6650.c -+++ b/drivers/media/i2c/ov6650.c -@@ -921,55 +921,74 @@ static const struct v4l2_subdev_core_ops ov6650_core_ops = { - }; - - /* Request bus settings on camera side */ --static int ov6650_g_mbus_config(struct v4l2_subdev *sd, -- struct v4l2_mbus_config *cfg) -+static int ov6650_get_mbus_config(struct v4l2_subdev *sd, -+ unsigned int pad, -+ struct v4l2_mbus_config *cfg) - { -+ struct i2c_client *client = v4l2_get_subdevdata(sd); -+ u8 comj, comf; -+ int ret; -+ -+ ret = ov6650_reg_read(client, REG_COMJ, &comj); -+ if (ret) -+ return ret; - -- cfg->flags = V4L2_MBUS_MASTER | -- V4L2_MBUS_PCLK_SAMPLE_RISING | V4L2_MBUS_PCLK_SAMPLE_FALLING | -- V4L2_MBUS_HSYNC_ACTIVE_HIGH | V4L2_MBUS_HSYNC_ACTIVE_LOW | -- V4L2_MBUS_VSYNC_ACTIVE_HIGH | V4L2_MBUS_VSYNC_ACTIVE_LOW | -- V4L2_MBUS_DATA_ACTIVE_HIGH; -+ ret = ov6650_reg_read(client, REG_COMF, &comf); -+ if (ret) -+ return ret; -+ -+ cfg->flags = V4L2_MBUS_MASTER | V4L2_MBUS_DATA_ACTIVE_HIGH -+ | ((comj & COMJ_VSYNC_HIGH) ? V4L2_MBUS_VSYNC_ACTIVE_HIGH -+ : V4L2_MBUS_VSYNC_ACTIVE_LOW) -+ | ((comf & COMF_HREF_LOW) ? V4L2_MBUS_HSYNC_ACTIVE_LOW -+ : V4L2_MBUS_HSYNC_ACTIVE_HIGH) -+ | ((comj & COMJ_PCLK_RISING) ? V4L2_MBUS_PCLK_SAMPLE_RISING -+ : V4L2_MBUS_PCLK_SAMPLE_FALLING); - cfg->type = V4L2_MBUS_PARALLEL; - - return 0; - } - - /* Alter bus settings on camera side */ --static int ov6650_s_mbus_config(struct v4l2_subdev *sd, -- const struct v4l2_mbus_config *cfg) -+static int ov6650_set_mbus_config(struct v4l2_subdev *sd, -+ unsigned int pad, -+ struct v4l2_mbus_config *cfg) - { - struct i2c_client *client = v4l2_get_subdevdata(sd); -- int ret; -+ int ret = 0; - - if (cfg->flags & V4L2_MBUS_PCLK_SAMPLE_RISING) - ret = ov6650_reg_rmw(client, REG_COMJ, COMJ_PCLK_RISING, 0); -- else -+ else if (cfg->flags & V4L2_MBUS_PCLK_SAMPLE_FALLING) - ret = ov6650_reg_rmw(client, REG_COMJ, 0, COMJ_PCLK_RISING); - if (ret) - return ret; - - if (cfg->flags & V4L2_MBUS_HSYNC_ACTIVE_LOW) - ret = ov6650_reg_rmw(client, REG_COMF, COMF_HREF_LOW, 0); -- else -+ else if (cfg->flags & V4L2_MBUS_HSYNC_ACTIVE_HIGH) - ret = ov6650_reg_rmw(client, REG_COMF, 0, COMF_HREF_LOW); - if (ret) - return ret; - - if (cfg->flags & V4L2_MBUS_VSYNC_ACTIVE_HIGH) - ret = ov6650_reg_rmw(client, REG_COMJ, COMJ_VSYNC_HIGH, 0); -- else -+ else if (cfg->flags & V4L2_MBUS_VSYNC_ACTIVE_LOW) - ret = ov6650_reg_rmw(client, REG_COMJ, 0, COMJ_VSYNC_HIGH); -+ if (ret) -+ return ret; - -- return ret; -+ /* -+ * Update the configuration to report what is actually applied to -+ * the hardware. -+ */ -+ return ov6650_get_mbus_config(sd, pad, cfg); - } - - static const struct v4l2_subdev_video_ops ov6650_video_ops = { - .s_stream = ov6650_s_stream, - .g_frame_interval = ov6650_g_frame_interval, - .s_frame_interval = ov6650_s_frame_interval, -- .g_mbus_config = ov6650_g_mbus_config, -- .s_mbus_config = ov6650_s_mbus_config, - }; - - static const struct v4l2_subdev_pad_ops ov6650_pad_ops = { -@@ -978,6 +997,8 @@ static const struct v4l2_subdev_pad_ops ov6650_pad_ops = { - .set_selection = ov6650_set_selection, - .get_fmt = ov6650_get_fmt, - .set_fmt = ov6650_set_fmt, -+ .get_mbus_config = ov6650_get_mbus_config, -+ .set_mbus_config = ov6650_set_mbus_config, - }; - - static const struct v4l2_subdev_ops ov6650_subdev_ops = { - -From f5afe4b33b9c89ee9261a164e1c69e7b6ba8cbe9 Mon Sep 17 00:00:00 2001 -From: Jacopo Mondi -Date: Fri, 17 Jul 2020 16:53:18 +0200 -Subject: [PATCH] media: pxa_camera: Use the new set_mbus_config op - -Move the PXA camera driver to use the new set_mbus_config pad operation. -For this platform the change is not only cosmetic, as the pxa driver is -currently the only driver in mainline to make use of the g_mbus_config -and s_mbus_config video operations. - -The existing driver semantic is the following: -- Collect all supported mbus config flags from the remote end -- Match them with the supported PXA mbus configuration flags -- If the remote subdevice allows multiple options for for VSYNC, HSYNC - and PCLK polarity, use platform data requested settings - -The semantic of the new get_mbus_config and set_mbus_config differs from -the corresponding video ops, particularly in the fact get_mbus_config -reports the current mbus configuration and not the set of supported -configuration options, with set_mbus_config always reporting the actual -mbus configuration applied to the remote subdevice. - -Adapt the driver to perform the following -- Set the remote subdevice mbus configuration according to the PXA - platform data preferences. -- If the applied configuration differs from the requested one (i.e. the - remote subdevice does not allow changing one setting) make sure that - - The remote end does not claim for DATA_ACTIVE_LOW, which seems not - supported by the platform - - The bus mastering roles match - -While at there remove a few checks performed on the media bus -configuration at get_format() time as they do not belong there. - -Compile-tested only. - -Signed-off-by: Jacopo Mondi -Signed-off-by: Hans Verkuil -Signed-off-by: Mauro Carvalho Chehab ---- - drivers/media/platform/pxa_camera.c | 189 ++++++++-------------------- - 1 file changed, 51 insertions(+), 138 deletions(-) - -diff --git a/drivers/media/platform/pxa_camera.c b/drivers/media/platform/pxa_camera.c -index 6dce33f35041..0366c4a813ce 100644 ---- a/drivers/media/platform/pxa_camera.c -+++ b/drivers/media/platform/pxa_camera.c -@@ -605,42 +605,6 @@ static const struct pxa_mbus_pixelfmt *pxa_mbus_get_fmtdesc( - return pxa_mbus_find_fmtdesc(code, mbus_fmt, ARRAY_SIZE(mbus_fmt)); - } - --static unsigned int pxa_mbus_config_compatible(const struct v4l2_mbus_config *cfg, -- unsigned int flags) --{ -- unsigned long common_flags; -- bool hsync = true, vsync = true, pclk, data, mode; -- bool mipi_lanes, mipi_clock; -- -- common_flags = cfg->flags & flags; -- -- switch (cfg->type) { -- case V4L2_MBUS_PARALLEL: -- hsync = common_flags & (V4L2_MBUS_HSYNC_ACTIVE_HIGH | -- V4L2_MBUS_HSYNC_ACTIVE_LOW); -- vsync = common_flags & (V4L2_MBUS_VSYNC_ACTIVE_HIGH | -- V4L2_MBUS_VSYNC_ACTIVE_LOW); -- /* fall through */ -- case V4L2_MBUS_BT656: -- pclk = common_flags & (V4L2_MBUS_PCLK_SAMPLE_RISING | -- V4L2_MBUS_PCLK_SAMPLE_FALLING); -- data = common_flags & (V4L2_MBUS_DATA_ACTIVE_HIGH | -- V4L2_MBUS_DATA_ACTIVE_LOW); -- mode = common_flags & (V4L2_MBUS_MASTER | V4L2_MBUS_SLAVE); -- return (!hsync || !vsync || !pclk || !data || !mode) ? -- 0 : common_flags; -- case V4L2_MBUS_CSI2_DPHY: -- mipi_lanes = common_flags & V4L2_MBUS_CSI2_LANES; -- mipi_clock = common_flags & (V4L2_MBUS_CSI2_NONCONTINUOUS_CLOCK | -- V4L2_MBUS_CSI2_CONTINUOUS_CLOCK); -- return (!mipi_lanes || !mipi_clock) ? 0 : common_flags; -- default: -- WARN_ON(1); -- return -EINVAL; -- } -- return 0; --} -- - /** - * struct pxa_camera_format_xlate - match between host and sensor formats - * @code: code of a sensor provided format -@@ -1231,31 +1195,6 @@ static irqreturn_t pxa_camera_irq(int irq, void *data) - return IRQ_HANDLED; - } - --static int test_platform_param(struct pxa_camera_dev *pcdev, -- unsigned char buswidth, unsigned long *flags) --{ -- /* -- * Platform specified synchronization and pixel clock polarities are -- * only a recommendation and are only used during probing. The PXA270 -- * quick capture interface supports both. -- */ -- *flags = (pcdev->platform_flags & PXA_CAMERA_MASTER ? -- V4L2_MBUS_MASTER : V4L2_MBUS_SLAVE) | -- V4L2_MBUS_HSYNC_ACTIVE_HIGH | -- V4L2_MBUS_HSYNC_ACTIVE_LOW | -- V4L2_MBUS_VSYNC_ACTIVE_HIGH | -- V4L2_MBUS_VSYNC_ACTIVE_LOW | -- V4L2_MBUS_DATA_ACTIVE_HIGH | -- V4L2_MBUS_PCLK_SAMPLE_RISING | -- V4L2_MBUS_PCLK_SAMPLE_FALLING; -- -- /* If requested data width is supported by the platform, use it */ -- if ((1 << (buswidth - 1)) & pcdev->width_flags) -- return 0; -- -- return -EINVAL; --} -- - static void pxa_camera_setup_cicr(struct pxa_camera_dev *pcdev, - unsigned long flags, __u32 pixfmt) - { -@@ -1598,99 +1537,78 @@ static int pxa_camera_init_videobuf2(struct pxa_camera_dev *pcdev) - */ - static int pxa_camera_set_bus_param(struct pxa_camera_dev *pcdev) - { -+ unsigned int bus_width = pcdev->current_fmt->host_fmt->bits_per_sample; - struct v4l2_mbus_config cfg = {.type = V4L2_MBUS_PARALLEL,}; - u32 pixfmt = pcdev->current_fmt->host_fmt->fourcc; -- unsigned long bus_flags, common_flags; -+ int mbus_config; - int ret; - -- ret = test_platform_param(pcdev, -- pcdev->current_fmt->host_fmt->bits_per_sample, -- &bus_flags); -- if (ret < 0) -- return ret; -- -- ret = sensor_call(pcdev, video, g_mbus_config, &cfg); -- if (!ret) { -- common_flags = pxa_mbus_config_compatible(&cfg, -- bus_flags); -- if (!common_flags) { -- dev_warn(pcdev_to_dev(pcdev), -- "Flags incompatible: camera 0x%x, host 0x%lx\n", -- cfg.flags, bus_flags); -- return -EINVAL; -- } -- } else if (ret != -ENOIOCTLCMD) { -- return ret; -- } else { -- common_flags = bus_flags; -+ if (!((1 << (bus_width - 1)) & pcdev->width_flags)) { -+ dev_err(pcdev_to_dev(pcdev), "Unsupported bus width %u", -+ bus_width); -+ return -EINVAL; - } - - pcdev->channels = 1; - - /* Make choices, based on platform preferences */ -- if ((common_flags & V4L2_MBUS_HSYNC_ACTIVE_HIGH) && -- (common_flags & V4L2_MBUS_HSYNC_ACTIVE_LOW)) { -- if (pcdev->platform_flags & PXA_CAMERA_HSP) -- common_flags &= ~V4L2_MBUS_HSYNC_ACTIVE_HIGH; -- else -- common_flags &= ~V4L2_MBUS_HSYNC_ACTIVE_LOW; -- } -+ mbus_config = 0; -+ if (pcdev->platform_flags & PXA_CAMERA_MASTER) -+ mbus_config |= V4L2_MBUS_MASTER; -+ else -+ mbus_config |= V4L2_MBUS_SLAVE; - -- if ((common_flags & V4L2_MBUS_VSYNC_ACTIVE_HIGH) && -- (common_flags & V4L2_MBUS_VSYNC_ACTIVE_LOW)) { -- if (pcdev->platform_flags & PXA_CAMERA_VSP) -- common_flags &= ~V4L2_MBUS_VSYNC_ACTIVE_HIGH; -- else -- common_flags &= ~V4L2_MBUS_VSYNC_ACTIVE_LOW; -- } -+ if (pcdev->platform_flags & PXA_CAMERA_HSP) -+ mbus_config |= V4L2_MBUS_HSYNC_ACTIVE_HIGH; -+ else -+ mbus_config |= V4L2_MBUS_HSYNC_ACTIVE_LOW; - -- if ((common_flags & V4L2_MBUS_PCLK_SAMPLE_RISING) && -- (common_flags & V4L2_MBUS_PCLK_SAMPLE_FALLING)) { -- if (pcdev->platform_flags & PXA_CAMERA_PCP) -- common_flags &= ~V4L2_MBUS_PCLK_SAMPLE_RISING; -- else -- common_flags &= ~V4L2_MBUS_PCLK_SAMPLE_FALLING; -- } -+ if (pcdev->platform_flags & PXA_CAMERA_VSP) -+ mbus_config |= V4L2_MBUS_VSYNC_ACTIVE_HIGH; -+ else -+ mbus_config |= V4L2_MBUS_VSYNC_ACTIVE_LOW; - -- cfg.flags = common_flags; -- ret = sensor_call(pcdev, video, s_mbus_config, &cfg); -+ if (pcdev->platform_flags & PXA_CAMERA_PCP) -+ mbus_config |= V4L2_MBUS_PCLK_SAMPLE_RISING; -+ else -+ mbus_config |= V4L2_MBUS_PCLK_SAMPLE_FALLING; -+ mbus_config |= V4L2_MBUS_DATA_ACTIVE_HIGH; -+ -+ cfg.flags = mbus_config; -+ ret = sensor_call(pcdev, pad, set_mbus_config, 0, &cfg); - if (ret < 0 && ret != -ENOIOCTLCMD) { -- dev_dbg(pcdev_to_dev(pcdev), -- "camera s_mbus_config(0x%lx) returned %d\n", -- common_flags, ret); -+ dev_err(pcdev_to_dev(pcdev), -+ "Failed to call set_mbus_config: %d\n", ret); - return ret; - } - -- pxa_camera_setup_cicr(pcdev, common_flags, pixfmt); -- -- return 0; --} -- --static int pxa_camera_try_bus_param(struct pxa_camera_dev *pcdev, -- unsigned char buswidth) --{ -- struct v4l2_mbus_config cfg = {.type = V4L2_MBUS_PARALLEL,}; -- unsigned long bus_flags, common_flags; -- int ret = test_platform_param(pcdev, buswidth, &bus_flags); -- -- if (ret < 0) -- return ret; -+ /* -+ * If the requested media bus configuration has not been fully applied -+ * make sure it is supported by the platform. -+ * -+ * PXA does not support V4L2_MBUS_DATA_ACTIVE_LOW and the bus mastering -+ * roles should match. -+ */ -+ if (cfg.flags != mbus_config) { -+ unsigned int pxa_mbus_role = mbus_config & (V4L2_MBUS_MASTER | -+ V4L2_MBUS_SLAVE); -+ if (pxa_mbus_role != (cfg.flags & (V4L2_MBUS_MASTER | -+ V4L2_MBUS_SLAVE))) { -+ dev_err(pcdev_to_dev(pcdev), -+ "Unsupported mbus configuration: bus mastering\n"); -+ return -EINVAL; -+ } - -- ret = sensor_call(pcdev, video, g_mbus_config, &cfg); -- if (!ret) { -- common_flags = pxa_mbus_config_compatible(&cfg, -- bus_flags); -- if (!common_flags) { -- dev_warn(pcdev_to_dev(pcdev), -- "Flags incompatible: camera 0x%x, host 0x%lx\n", -- cfg.flags, bus_flags); -+ if (cfg.flags & V4L2_MBUS_DATA_ACTIVE_LOW) { -+ dev_err(pcdev_to_dev(pcdev), -+ "Unsupported mbus configuration: DATA_ACTIVE_LOW\n"); - return -EINVAL; - } -- } else if (ret == -ENOIOCTLCMD) { -- ret = 0; - } - -- return ret; -+ pxa_camera_setup_cicr(pcdev, cfg.flags, pixfmt); -+ -+ return 0; - } - - static const struct pxa_mbus_pixelfmt pxa_camera_formats[] = { -@@ -1738,11 +1656,6 @@ static int pxa_camera_get_formats(struct v4l2_device *v4l2_dev, - return 0; - } - -- /* This also checks support for the requested bits-per-sample */ -- ret = pxa_camera_try_bus_param(pcdev, fmt->bits_per_sample); -- if (ret < 0) -- return 0; -- - switch (code.code) { - case MEDIA_BUS_FMT_UYVY8_2X8: - formats++; - -From 05669687ac2eebd879109223a9a7e90aa9414535 Mon Sep 17 00:00:00 2001 -From: Jacopo Mondi -Date: Fri, 17 Jul 2020 16:53:19 +0200 -Subject: [PATCH] media: v4l2-subdev: Remove [s|g]_mbus_config video ops - -With all sensor and platform drivers now converted to use the new -get_mbus_config and set_mbus_config pad operations, remove the -deprecated video operations g_mbus_config and s_mbus_config. - -Signed-off-by: Jacopo Mondi -Signed-off-by: Hans Verkuil -Signed-off-by: Mauro Carvalho Chehab ---- - include/media/v4l2-subdev.h | 10 ---------- - 1 file changed, 10 deletions(-) - -diff --git a/include/media/v4l2-subdev.h b/include/media/v4l2-subdev.h -index d4e3b44cf14c..14f95cf325e9 100644 ---- a/include/media/v4l2-subdev.h -+++ b/include/media/v4l2-subdev.h -@@ -402,12 +402,6 @@ struct v4l2_mbus_frame_desc { - * - * @query_dv_timings: callback for VIDIOC_QUERY_DV_TIMINGS() ioctl handler code. - * -- * @g_mbus_config: get supported mediabus configurations -- * -- * @s_mbus_config: set a certain mediabus configuration. This operation is added -- * for compatibility with soc-camera drivers and should not be used by new -- * software. -- * - * @s_rx_buffer: set a host allocated memory buffer for the subdev. The subdev - * can adjust @size to a lower value and must not write more data to the - * buffer starting at @data than the original value of @size. -@@ -435,10 +429,6 @@ struct v4l2_subdev_video_ops { - struct v4l2_dv_timings *timings); - int (*query_dv_timings)(struct v4l2_subdev *sd, - struct v4l2_dv_timings *timings); -- int (*g_mbus_config)(struct v4l2_subdev *sd, -- struct v4l2_mbus_config *cfg); -- int (*s_mbus_config)(struct v4l2_subdev *sd, -- const struct v4l2_mbus_config *cfg); - int (*s_rx_buffer)(struct v4l2_subdev *sd, void *buf, - unsigned int *size); - }; - -From 59facb6d664b8cc8747a4ca491bd3ecd70fd3728 Mon Sep 17 00:00:00 2001 -From: Jacopo Mondi -Date: Fri, 17 Jul 2020 16:53:20 +0200 -Subject: [PATCH] media: v4l2- mediabus: Add usage note for V4L2_MBUS_* - -With the removal of the legacy g_mbus_config and s_mbus_config video -operations, the sole users of V4L2_MBUS_* flags are now the newly -introduced get_mbus_config and set_mbus_config pad operations. - -As the semantic of the new operations differs from the semantic of -the legacy ones, add a usage note in the v4l2-mediabus.h header to -specify how to use the flags. - -Also add a TODO note to record that we intend to replace the existing -flags with fields, to prevent users from mixing conflicting values -in a single operation call. - -Signed-off-by: Jacopo Mondi -Signed-off-by: Hans Verkuil -Signed-off-by: Mauro Carvalho Chehab ---- - include/media/v4l2-mediabus.h | 33 +++++++++++++++++++++++++++++---- - 1 file changed, 29 insertions(+), 4 deletions(-) - -diff --git a/include/media/v4l2-mediabus.h b/include/media/v4l2-mediabus.h -index 45f88f0248c4..59b1de197114 100644 ---- a/include/media/v4l2-mediabus.h -+++ b/include/media/v4l2-mediabus.h -@@ -11,9 +11,34 @@ - #include - #include - -+/* -+ * How to use the V4L2_MBUS_* flags: -+ * Flags are defined for each of the possible states and values of a media -+ * bus configuration parameter. One and only one bit of each group of flags -+ * shall be set by the users of the v4l2_subdev_pad_ops.get_mbus_config and -+ * v4l2_subdev_pad_ops.set_mbus_config operations to ensure that no -+ * conflicting settings are specified when reporting and setting the media bus -+ * configuration with the two operations respectively. For example, it is -+ * invalid to set or clear both the V4L2_MBUS_HSYNC_ACTIVE_HIGH and the -+ * V4L2_MBUS_HSYNC_ACTIVE_LOW flag at the same time. Instead either flag -+ * V4L2_MBUS_HSYNC_ACTIVE_HIGH or flag V4L2_MBUS_HSYNC_ACTIVE_LOW shall be -+ * set. The same is true for the V4L2_MBUS_CSI2_1/2/3/4_LANE flags group: only -+ * one of these four bits shall be set. -+ * -+ * TODO: replace the existing V4L2_MBUS_* flags with structures of fields -+ * to avoid conflicting settings. -+ * -+ * In example: -+ * #define V4L2_MBUS_HSYNC_ACTIVE_HIGH BIT(2) -+ * #define V4L2_MBUS_HSYNC_ACTIVE_LOW BIT(3) -+ * will be replaced by a field whose value reports the intended active state of -+ * the signal: -+ * unsigned int v4l2_mbus_hsync_active : 1; -+ */ -+ - /* Parallel flags */ - /* -- * Can the client run in master or in slave mode. By "Master mode" an operation -+ * The client runs in master or in slave mode. By "Master mode" an operation - * mode is meant, when the client (e.g., a camera sensor) is producing - * horizontal and vertical synchronisation. In "Slave mode" the host is - * providing these signals to the slave. -@@ -45,17 +70,17 @@ - #define V4L2_MBUS_DATA_ENABLE_LOW BIT(15) - - /* Serial flags */ --/* How many lanes the client can use */ -+/* CSI-2 D-PHY number of data lanes. */ - #define V4L2_MBUS_CSI2_1_LANE BIT(0) - #define V4L2_MBUS_CSI2_2_LANE BIT(1) - #define V4L2_MBUS_CSI2_3_LANE BIT(2) - #define V4L2_MBUS_CSI2_4_LANE BIT(3) --/* On which channels it can send video data */ -+/* CSI-2 Virtual Channel identifiers. */ - #define V4L2_MBUS_CSI2_CHANNEL_0 BIT(4) - #define V4L2_MBUS_CSI2_CHANNEL_1 BIT(5) - #define V4L2_MBUS_CSI2_CHANNEL_2 BIT(6) - #define V4L2_MBUS_CSI2_CHANNEL_3 BIT(7) --/* Does it support only continuous or also non-continuous clock mode */ -+/* Clock non-continuous mode support. */ - #define V4L2_MBUS_CSI2_CONTINUOUS_CLOCK BIT(8) - #define V4L2_MBUS_CSI2_NONCONTINUOUS_CLOCK BIT(9) - - -From 50141d5a085e30f8623fec818ae07d4934074a3d Mon Sep 17 00:00:00 2001 -From: Jacopo Mondi -Date: Fri, 17 Jul 2020 16:53:21 +0200 -Subject: [PATCH] media: staging: media: imx: Update TODO entry - -Update the TODO entry that mentioned a potential use case for the now -removed g_mbus_config video operation. - -Signed-off-by: Jacopo Mondi -Signed-off-by: Hans Verkuil -Signed-off-by: Mauro Carvalho Chehab ---- - drivers/staging/media/imx/TODO | 4 ++++ - 1 file changed, 4 insertions(+) - -diff --git a/drivers/staging/media/imx/TODO b/drivers/staging/media/imx/TODO -index a371cdedcdb0..9cfc1c1e78dc 100644 ---- a/drivers/staging/media/imx/TODO -+++ b/drivers/staging/media/imx/TODO -@@ -10,6 +10,10 @@ - driver uses the parsed DT bus config method until this issue is - resolved. - -+ 2020-06: g_mbus has been removed in favour of the get_mbus_config pad -+ operation which should be used to avoid parsing the remote endpoint -+ configuration. -+ - - This media driver supports inheriting V4L2 controls to the - video capture devices, from the subdevices in the capture device's - pipeline. The controls for each capture device are updated in the - -From 2f7253cd2b4895e844ed859aec148d0b2c96db1c Mon Sep 17 00:00:00 2001 -From: Jacopo Mondi -Date: Fri, 17 Jul 2020 16:53:22 +0200 -Subject: [PATCH] media: i2c: adv748x: Adjust TXA data lanes number -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -When outputting SD-Core output through the TXA MIPI CSI-2 interface, -the number of enabled data lanes should be reduced in order to guarantee -that the two video formats produced by the SD-Core (480i and 576i) -generate a MIPI CSI-2 link clock frequency compatible with the MIPI D-PHY -specifications. - -Limit the number of enabled data lanes to 2, which is guaranteed to -support 480i and 576i formats. - -Cache the number of enabled data lanes to be able to report it through -the new get_mbus_config operation. - -Reviewed-by: Kieran Bingham -Reviewed-by: Laurent Pinchart -Reviewed-by: Niklas Söderlund -Signed-off-by: Jacopo Mondi -Signed-off-by: Hans Verkuil -Signed-off-by: Mauro Carvalho Chehab ---- - drivers/media/i2c/adv748x/adv748x-core.c | 31 ++++++++++++++++++------ - drivers/media/i2c/adv748x/adv748x.h | 1 + - 2 files changed, 25 insertions(+), 7 deletions(-) - -diff --git a/drivers/media/i2c/adv748x/adv748x-core.c b/drivers/media/i2c/adv748x/adv748x-core.c -index 23e02ff27b17..1fe7f97c6d52 100644 ---- a/drivers/media/i2c/adv748x/adv748x-core.c -+++ b/drivers/media/i2c/adv748x/adv748x-core.c -@@ -241,10 +241,10 @@ static int adv748x_power_up_tx(struct adv748x_csi2 *tx) - int ret = 0; - - /* Enable n-lane MIPI */ -- adv748x_write_check(state, page, 0x00, 0x80 | tx->num_lanes, &ret); -+ adv748x_write_check(state, page, 0x00, 0x80 | tx->active_lanes, &ret); - - /* Set Auto DPHY Timing */ -- adv748x_write_check(state, page, 0x00, 0xa0 | tx->num_lanes, &ret); -+ adv748x_write_check(state, page, 0x00, 0xa0 | tx->active_lanes, &ret); - - /* ADI Required Write */ - if (tx->src == &state->hdmi.sd) { -@@ -270,7 +270,7 @@ static int adv748x_power_up_tx(struct adv748x_csi2 *tx) - usleep_range(2000, 2500); - - /* Power-up CSI-TX */ -- adv748x_write_check(state, page, 0x00, 0x20 | tx->num_lanes, &ret); -+ adv748x_write_check(state, page, 0x00, 0x20 | tx->active_lanes, &ret); - usleep_range(1000, 1500); - - /* ADI Required Writes */ -@@ -292,7 +292,7 @@ static int adv748x_power_down_tx(struct adv748x_csi2 *tx) - adv748x_write_check(state, page, 0x1e, 0x00, &ret); - - /* Enable n-lane MIPI */ -- adv748x_write_check(state, page, 0x00, 0x80 | tx->num_lanes, &ret); -+ adv748x_write_check(state, page, 0x00, 0x80 | tx->active_lanes, &ret); - - /* i2c_mipi_pll_en - 1'b1 */ - adv748x_write_check(state, page, 0xda, 0x01, &ret); -@@ -357,14 +357,29 @@ static int adv748x_link_setup(struct media_entity *entity, - if (state->afe.tx) { - /* AFE Requires TXA enabled, even when output to TXB */ - io10 |= ADV748X_IO_10_CSI4_EN; -- if (is_txa(tx)) -+ if (is_txa(tx)) { -+ /* -+ * Output from the SD-core (480i and 576i) from the TXA -+ * interface requires reducing the number of enabled -+ * data lanes in order to guarantee a valid link -+ * frequency. -+ */ -+ tx->active_lanes = min(tx->num_lanes, 2U); - io10 |= ADV748X_IO_10_CSI4_IN_SEL_AFE; -- else -+ } else { -+ /* TXB has a single data lane, no need to adjust. */ - io10 |= ADV748X_IO_10_CSI1_EN; -+ } - } - -- if (state->hdmi.tx) -+ if (state->hdmi.tx) { -+ /* -+ * Restore the number of active lanes, in case we have gone -+ * through an AFE->TXA streaming sessions. -+ */ -+ tx->active_lanes = tx->num_lanes; - io10 |= ADV748X_IO_10_CSI4_EN; -+ } - - return io_clrset(state, ADV748X_IO_10, io10_mask, io10); - } -@@ -596,6 +611,7 @@ static int adv748x_parse_csi2_lanes(struct adv748x_state *state, - } - - state->txa.num_lanes = num_lanes; -+ state->txa.active_lanes = num_lanes; - adv_dbg(state, "TXA: using %u lanes\n", state->txa.num_lanes); - } - -@@ -607,6 +623,7 @@ static int adv748x_parse_csi2_lanes(struct adv748x_state *state, - } - - state->txb.num_lanes = num_lanes; -+ state->txb.active_lanes = num_lanes; - adv_dbg(state, "TXB: using %u lanes\n", state->txb.num_lanes); - } - -diff --git a/drivers/media/i2c/adv748x/adv748x.h b/drivers/media/i2c/adv748x/adv748x.h -index fccb388ce179..1061f425ece5 100644 ---- a/drivers/media/i2c/adv748x/adv748x.h -+++ b/drivers/media/i2c/adv748x/adv748x.h -@@ -79,6 +79,7 @@ struct adv748x_csi2 { - unsigned int page; - unsigned int port; - unsigned int num_lanes; -+ unsigned int active_lanes; - - struct media_pad pads[ADV748X_CSI2_NR_PADS]; - struct v4l2_ctrl_handler ctrl_hdl; - -From 619f2a61c2d6ada89a508342078dc5ac9e1b9681 Mon Sep 17 00:00:00 2001 -From: Jacopo Mondi -Date: Fri, 17 Jul 2020 16:53:23 +0200 -Subject: [PATCH] media: i2c: adv748x: Implement get_mbus_config -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -Implement the newly introduced get_mbus_config operation to report the -number of currently used data lanes on the MIPI CSI-2 interface. - -Reviewed-by: Kieran Bingham -Reviewed-by: Niklas Söderlund -Signed-off-by: Jacopo Mondi -Signed-off-by: Hans Verkuil -Signed-off-by: Mauro Carvalho Chehab ---- - drivers/media/i2c/adv748x/adv748x-csi2.c | 31 ++++++++++++++++++++++++ - 1 file changed, 31 insertions(+) - -diff --git a/drivers/media/i2c/adv748x/adv748x-csi2.c b/drivers/media/i2c/adv748x/adv748x-csi2.c -index 2091cda50935..99bb63d05eef 100644 ---- a/drivers/media/i2c/adv748x/adv748x-csi2.c -+++ b/drivers/media/i2c/adv748x/adv748x-csi2.c -@@ -214,9 +214,40 @@ static int adv748x_csi2_set_format(struct v4l2_subdev *sd, - return ret; - } - -+static int adv748x_csi2_get_mbus_config(struct v4l2_subdev *sd, unsigned int pad, -+ struct v4l2_mbus_config *config) -+{ -+ struct adv748x_csi2 *tx = adv748x_sd_to_csi2(sd); -+ -+ if (pad != ADV748X_CSI2_SOURCE) -+ return -EINVAL; -+ -+ config->type = V4L2_MBUS_CSI2_DPHY; -+ switch (tx->active_lanes) { -+ case 1: -+ config->flags = V4L2_MBUS_CSI2_1_LANE; -+ break; -+ -+ case 2: -+ config->flags = V4L2_MBUS_CSI2_2_LANE; -+ break; -+ -+ case 3: -+ config->flags = V4L2_MBUS_CSI2_3_LANE; -+ break; -+ -+ case 4: -+ config->flags = V4L2_MBUS_CSI2_4_LANE; -+ break; -+ } -+ -+ return 0; -+} -+ - static const struct v4l2_subdev_pad_ops adv748x_csi2_pad_ops = { - .get_fmt = adv748x_csi2_get_format, - .set_fmt = adv748x_csi2_set_format, -+ .get_mbus_config = adv748x_csi2_get_mbus_config, - }; - - /* ----------------------------------------------------------------------------- - -From f1db9862ef926d7183b7e5c407a6bd95d5d72128 Mon Sep 17 00:00:00 2001 -From: Jacopo Mondi -Date: Fri, 17 Jul 2020 16:53:24 +0200 -Subject: [PATCH] media: rcar-csi2: Negotiate data lanes number -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -Use the newly introduced get_mbus_config() subdevice pad operation to -retrieve the remote subdevice MIPI CSI-2 bus configuration and configure -the number of active data lanes accordingly. - -In order to be able to call the remote subdevice operation cache the -index of the remote pad connected to the single CSI-2 input port. - -Reviewed-by: Niklas Söderlund -Signed-off-by: Jacopo Mondi -Signed-off-by: Hans Verkuil -Signed-off-by: Mauro Carvalho Chehab ---- - drivers/media/platform/rcar-vin/rcar-csi2.c | 75 +++++++++++++++++++-- - 1 file changed, 68 insertions(+), 7 deletions(-) - -diff --git a/drivers/media/platform/rcar-vin/rcar-csi2.c b/drivers/media/platform/rcar-vin/rcar-csi2.c -index a16c492b3143..511cd4984777 100644 ---- a/drivers/media/platform/rcar-vin/rcar-csi2.c -+++ b/drivers/media/platform/rcar-vin/rcar-csi2.c -@@ -363,6 +363,7 @@ struct rcar_csi2 { - - struct v4l2_async_notifier notifier; - struct v4l2_subdev *remote; -+ unsigned int remote_pad; - - struct v4l2_mbus_framefmt mf; - -@@ -408,13 +409,14 @@ static void rcsi2_exit_standby(struct rcar_csi2 *priv) - reset_control_deassert(priv->rstc); - } - --static int rcsi2_wait_phy_start(struct rcar_csi2 *priv) -+static int rcsi2_wait_phy_start(struct rcar_csi2 *priv, -+ unsigned int lanes) - { - unsigned int timeout; - - /* Wait for the clock and data lanes to enter LP-11 state. */ - for (timeout = 0; timeout <= 20; timeout++) { -- const u32 lane_mask = (1 << priv->lanes) - 1; -+ const u32 lane_mask = (1 << lanes) - 1; - - if ((rcsi2_read(priv, PHCLM_REG) & PHCLM_STOPSTATECKL) && - (rcsi2_read(priv, PHDLM_REG) & lane_mask) == lane_mask) -@@ -446,7 +448,8 @@ static int rcsi2_set_phypll(struct rcar_csi2 *priv, unsigned int mbps) - return 0; - } - --static int rcsi2_calc_mbps(struct rcar_csi2 *priv, unsigned int bpp) -+static int rcsi2_calc_mbps(struct rcar_csi2 *priv, unsigned int bpp, -+ unsigned int lanes) - { - struct v4l2_subdev *source; - struct v4l2_ctrl *ctrl; -@@ -471,15 +474,64 @@ static int rcsi2_calc_mbps(struct rcar_csi2 *priv, unsigned int bpp) - * bps = link_freq * 2 - */ - mbps = v4l2_ctrl_g_ctrl_int64(ctrl) * bpp; -- do_div(mbps, priv->lanes * 1000000); -+ do_div(mbps, lanes * 1000000); - - return mbps; - } - -+static int rcsi2_get_active_lanes(struct rcar_csi2 *priv, -+ unsigned int *lanes) -+{ -+ struct v4l2_mbus_config mbus_config = { 0 }; -+ unsigned int num_lanes = UINT_MAX; -+ int ret; -+ -+ *lanes = priv->lanes; -+ -+ ret = v4l2_subdev_call(priv->remote, pad, get_mbus_config, -+ priv->remote_pad, &mbus_config); -+ if (ret == -ENOIOCTLCMD) { -+ dev_dbg(priv->dev, "No remote mbus configuration available\n"); -+ return 0; -+ } -+ -+ if (ret) { -+ dev_err(priv->dev, "Failed to get remote mbus configuration\n"); -+ return ret; -+ } -+ -+ if (mbus_config.type != V4L2_MBUS_CSI2_DPHY) { -+ dev_err(priv->dev, "Unsupported media bus type %u\n", -+ mbus_config.type); -+ return -EINVAL; -+ } -+ -+ if (mbus_config.flags & V4L2_MBUS_CSI2_1_LANE) -+ num_lanes = 1; -+ else if (mbus_config.flags & V4L2_MBUS_CSI2_2_LANE) -+ num_lanes = 2; -+ else if (mbus_config.flags & V4L2_MBUS_CSI2_3_LANE) -+ num_lanes = 3; -+ else if (mbus_config.flags & V4L2_MBUS_CSI2_4_LANE) -+ num_lanes = 4; -+ -+ if (num_lanes > priv->lanes) { -+ dev_err(priv->dev, -+ "Unsupported mbus config: too many data lanes %u\n", -+ num_lanes); -+ return -EINVAL; -+ } -+ -+ *lanes = num_lanes; -+ -+ return 0; -+} -+ - static int rcsi2_start_receiver(struct rcar_csi2 *priv) - { - const struct rcar_csi2_format *format; - u32 phycnt, vcdt = 0, vcdt2 = 0, fld = 0; -+ unsigned int lanes; - unsigned int i; - int mbps, ret; - -@@ -521,10 +573,18 @@ static int rcsi2_start_receiver(struct rcar_csi2 *priv) - fld |= FLD_FLD_NUM(1); - } - -+ /* -+ * Get the number of active data lanes inspecting the remote mbus -+ * configuration. -+ */ -+ ret = rcsi2_get_active_lanes(priv, &lanes); -+ if (ret) -+ return ret; -+ - phycnt = PHYCNT_ENABLECLK; -- phycnt |= (1 << priv->lanes) - 1; -+ phycnt |= (1 << lanes) - 1; - -- mbps = rcsi2_calc_mbps(priv, format->bpp); -+ mbps = rcsi2_calc_mbps(priv, format->bpp, lanes); - if (mbps < 0) - return mbps; - -@@ -571,7 +631,7 @@ static int rcsi2_start_receiver(struct rcar_csi2 *priv) - rcsi2_write(priv, PHYCNT_REG, phycnt | PHYCNT_SHUTDOWNZ); - rcsi2_write(priv, PHYCNT_REG, phycnt | PHYCNT_SHUTDOWNZ | PHYCNT_RSTZ); - -- ret = rcsi2_wait_phy_start(priv); -+ ret = rcsi2_wait_phy_start(priv, lanes); - if (ret) - return ret; - -@@ -748,6 +808,7 @@ static int rcsi2_notify_bound(struct v4l2_async_notifier *notifier, - } - - priv->remote = subdev; -+ priv->remote_pad = pad; - - dev_dbg(priv->dev, "Bound %s pad: %d\n", subdev->name, pad); - - -From 4ba604bb7c63e8643c94ff804faa8cb9ff5b2847 Mon Sep 17 00:00:00 2001 -From: Rajendra Nayak -Date: Wed, 29 Jul 2020 09:16:43 +0200 -Subject: [PATCH] media: venus: core: Add support for opp tables/perf voting - -Add support to add OPP tables and perf voting on the OPP powerdomain. -This is needed so venus votes on the corresponding performance state -for the OPP powerdomain along with setting the core clock rate. - -Signed-off-by: Rajendra Nayak -Reviewed-by: Matthias Kaehlcke -Reviewed-by: Bjorn Andersson -Signed-off-by: Stanimir Varbanov -Signed-off-by: Mauro Carvalho Chehab ---- - drivers/media/platform/qcom/venus/core.c | 2 + - drivers/media/platform/qcom/venus/core.h | 5 + - .../media/platform/qcom/venus/pm_helpers.c | 92 +++++++++++++++++-- - 3 files changed, 92 insertions(+), 7 deletions(-) - -diff --git a/drivers/media/platform/qcom/venus/core.c b/drivers/media/platform/qcom/venus/core.c -index 321ad77cb6cf..5fd70f8cf857 100644 ---- a/drivers/media/platform/qcom/venus/core.c -+++ b/drivers/media/platform/qcom/venus/core.c -@@ -528,6 +528,7 @@ static const struct venus_resources sdm845_res_v2 = { - .vcodec_clks_num = 2, - .vcodec_pmdomains = { "venus", "vcodec0", "vcodec1" }, - .vcodec_pmdomains_num = 3, -+ .opp_pmdomain = (const char *[]) { "cx", NULL }, - .vcodec_num = 2, - .max_load = 3110400, /* 4096x2160@90 */ - .hfi_version = HFI_VERSION_4XX, -@@ -573,6 +574,7 @@ static const struct venus_resources sc7180_res = { - .vcodec_clks_num = 2, - .vcodec_pmdomains = { "venus", "vcodec0" }, - .vcodec_pmdomains_num = 2, -+ .opp_pmdomain = (const char *[]) { "cx", NULL }, - .vcodec_num = 1, - .hfi_version = HFI_VERSION_4XX, - .vmem_id = VIDC_RESOURCE_NONE, -diff --git a/drivers/media/platform/qcom/venus/core.h b/drivers/media/platform/qcom/venus/core.h -index 7118612673c9..b0cc544ad39f 100644 ---- a/drivers/media/platform/qcom/venus/core.h -+++ b/drivers/media/platform/qcom/venus/core.h -@@ -62,6 +62,7 @@ struct venus_resources { - unsigned int vcodec_clks_num; - const char * const vcodec_pmdomains[VIDC_PMDOMAINS_NUM_MAX]; - unsigned int vcodec_pmdomains_num; -+ const char **opp_pmdomain; - unsigned int vcodec_num; - enum hfi_version hfi_version; - u32 max_load; -@@ -145,8 +146,12 @@ struct venus_core { - struct clk *vcodec1_clks[VIDC_VCODEC_CLKS_NUM_MAX]; - struct icc_path *video_path; - struct icc_path *cpucfg_path; -+ struct opp_table *opp_table; -+ bool has_opp_table; - struct device_link *pd_dl_venus; - struct device *pmdomains[VIDC_PMDOMAINS_NUM_MAX]; -+ struct device_link *opp_dl_venus; -+ struct device *opp_pmdomain; - struct video_device *vdev_dec; - struct video_device *vdev_enc; - struct v4l2_device v4l2_dev; -diff --git a/drivers/media/platform/qcom/venus/pm_helpers.c b/drivers/media/platform/qcom/venus/pm_helpers.c -index 531e7a41658f..3127af8985cf 100644 ---- a/drivers/media/platform/qcom/venus/pm_helpers.c -+++ b/drivers/media/platform/qcom/venus/pm_helpers.c -@@ -9,6 +9,7 @@ - #include - #include - #include -+#include - #include - #include - #include -@@ -66,10 +67,9 @@ static void core_clks_disable(struct venus_core *core) - - static int core_clks_set_rate(struct venus_core *core, unsigned long freq) - { -- struct clk *clk = core->clks[0]; - int ret; - -- ret = clk_set_rate(clk, freq); -+ ret = dev_pm_opp_set_rate(core->dev, freq); - if (ret) - return ret; - -@@ -744,13 +744,16 @@ static int venc_power_v4(struct device *dev, int on) - - static int vcodec_domains_get(struct device *dev) - { -+ int ret; -+ struct opp_table *opp_table; -+ struct device **opp_virt_dev; - struct venus_core *core = dev_get_drvdata(dev); - const struct venus_resources *res = core->res; - struct device *pd; - unsigned int i; - - if (!res->vcodec_pmdomains_num) -- return -ENODEV; -+ goto skip_pmdomains; - - for (i = 0; i < res->vcodec_pmdomains_num; i++) { - pd = dev_pm_domain_attach_by_name(dev, -@@ -767,7 +770,41 @@ static int vcodec_domains_get(struct device *dev) - if (!core->pd_dl_venus) - return -ENODEV; - -+skip_pmdomains: -+ if (!core->has_opp_table) -+ return 0; -+ -+ /* Attach the power domain for setting performance state */ -+ opp_table = dev_pm_opp_attach_genpd(dev, res->opp_pmdomain, &opp_virt_dev); -+ if (IS_ERR(opp_table)) { -+ ret = PTR_ERR(opp_table); -+ goto opp_attach_err; -+ } -+ -+ core->opp_pmdomain = *opp_virt_dev; -+ core->opp_dl_venus = device_link_add(dev, core->opp_pmdomain, -+ DL_FLAG_RPM_ACTIVE | -+ DL_FLAG_PM_RUNTIME | -+ DL_FLAG_STATELESS); -+ if (!core->opp_dl_venus) { -+ ret = -ENODEV; -+ goto opp_dl_add_err; -+ } -+ - return 0; -+ -+opp_dl_add_err: -+ dev_pm_domain_detach(core->opp_pmdomain, true); -+opp_attach_err: -+ if (core->pd_dl_venus) { -+ device_link_del(core->pd_dl_venus); -+ for (i = 0; i < res->vcodec_pmdomains_num; i++) { -+ if (IS_ERR_OR_NULL(core->pmdomains[i])) -+ continue; -+ dev_pm_domain_detach(core->pmdomains[i], true); -+ } -+ } -+ return ret; - } - - static void vcodec_domains_put(struct device *dev) -@@ -777,7 +814,7 @@ static void vcodec_domains_put(struct device *dev) - unsigned int i; - - if (!res->vcodec_pmdomains_num) -- return; -+ goto skip_pmdomains; - - if (core->pd_dl_venus) - device_link_del(core->pd_dl_venus); -@@ -787,6 +824,15 @@ static void vcodec_domains_put(struct device *dev) - continue; - dev_pm_domain_detach(core->pmdomains[i], true); - } -+ -+skip_pmdomains: -+ if (!core->has_opp_table) -+ return; -+ -+ if (core->opp_dl_venus) -+ device_link_del(core->opp_dl_venus); -+ -+ dev_pm_domain_detach(core->opp_pmdomain, true); - } - - static int core_get_v4(struct device *dev) -@@ -815,19 +861,46 @@ static int core_get_v4(struct device *dev) - if (legacy_binding) - return 0; - -+ core->opp_table = dev_pm_opp_set_clkname(dev, "core"); -+ if (IS_ERR(core->opp_table)) -+ return PTR_ERR(core->opp_table); -+ -+ if (core->res->opp_pmdomain) { -+ ret = dev_pm_opp_of_add_table(dev); -+ if (!ret) { -+ core->has_opp_table = true; -+ } else if (ret != -ENODEV) { -+ dev_err(dev, "invalid OPP table in device tree\n"); -+ dev_pm_opp_put_clkname(core->opp_table); -+ return ret; -+ } -+ } -+ - ret = vcodec_domains_get(dev); -- if (ret) -+ if (ret) { -+ if (core->has_opp_table) -+ dev_pm_opp_of_remove_table(dev); -+ dev_pm_opp_put_clkname(core->opp_table); - return ret; -+ } - - return 0; - } - - static void core_put_v4(struct device *dev) - { -+ struct venus_core *core = dev_get_drvdata(dev); -+ - if (legacy_binding) - return; - - vcodec_domains_put(dev); -+ -+ if (core->has_opp_table) -+ dev_pm_opp_of_remove_table(dev); -+ if (core->opp_table) -+ dev_pm_opp_put_clkname(core->opp_table); -+ - } - - static int core_power_v4(struct device *dev, int on) -@@ -835,10 +908,15 @@ static int core_power_v4(struct device *dev, int on) - struct venus_core *core = dev_get_drvdata(dev); - int ret = 0; - -- if (on == POWER_ON) -+ if (on == POWER_ON) { - ret = core_clks_enable(core); -- else -+ } else { -+ /* Drop the performance state vote */ -+ if (core->opp_pmdomain) -+ dev_pm_opp_set_rate(dev, 0); -+ - core_clks_disable(core); -+ } - - return ret; - } - -From a2f3daa9ceca0fb5cec47ed9811aedc06143e3e9 Mon Sep 17 00:00:00 2001 +From df70311e9ceb74ced1d16f58d26b1b0939878cd3 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 @@ -1467,7 +33,7 @@ index 7cc3b478a5f4..054d2e3eed67 100644 continue; } -From 7a7fcc627de3c7013b99808501bbcbe923f94b12 Mon Sep 17 00:00:00 2001 +From 226b2391c4fac1651979a069e31c3356df6b9042 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 @@ -1494,7 +60,7 @@ index d25c4a37e2af..b3e067031c83 100644 &pix_mp->height, &coded_desc->frmsize); -From 834c4972ae1fd39072ade7be12c5254f1c87a534 Mon Sep 17 00:00:00 2001 +From eb75d2223e1a64e2e623b50d6fbb8dd3e92d9869 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 @@ -1562,7 +128,7 @@ index b3e067031c83..06fc58440cd3 100644 return 0; } -From e2e5c40dd4ef465b899a34ff9a7ba9bf50bf3ddb Mon Sep 17 00:00:00 2001 +From e97a5b83858e9e23d9c507c23fd79bbb139a33a1 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 @@ -1595,7 +161,7 @@ index d46424ba88e8..6536cf0d6054 100644 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 4600401f6112febf5c9bb0b1b6f3a0bd6fac5156 Mon Sep 17 00:00:00 2001 +From c875840c995082de33ca342b4ff2e620abf54abf 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 @@ -1629,7 +195,7 @@ index 6536cf0d6054..bf632d45282b 100644 } -From a8208557b2287493020e50dd42aaa1011ecfdd9e Mon Sep 17 00:00:00 2001 +From 0b8704eecf6b6a77daa4a5aa5b78f2359895f065 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 @@ -1758,7 +324,7 @@ index 3dc17ebe14fa..4102c373b48a 100644 } EXPORT_SYMBOL_GPL(v4l2_fill_pixfmt); -From 2ef43aefb977ef604378f80692ce4148cff35dd5 Mon Sep 17 00:00:00 2001 +From 28d45e94fc74ebdad92e561c0f99f604f2a4adc3 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 @@ -2002,10 +568,10 @@ index 000000000000..a8123be0baa3 + - C + - Y diff --git a/Documentation/userspace-api/media/v4l/yuv-formats.rst b/Documentation/userspace-api/media/v4l/yuv-formats.rst -index 8ee92d0cd769..7cca883f178a 100644 +index 4a05a105a9e6..e08e5dbdacea 100644 --- a/Documentation/userspace-api/media/v4l/yuv-formats.rst +++ b/Documentation/userspace-api/media/v4l/yuv-formats.rst -@@ -61,4 +61,6 @@ to brightness information. +@@ -54,4 +54,6 @@ to brightness information. pixfmt-nv16 pixfmt-nv16m pixfmt-nv24 @@ -2040,7 +606,7 @@ index eeff398fbdcc..80cb42450a1b 100644 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 f717826d5d7c..d620f6adfd60 100644 +index 534eaa4d39bc..f21eba15ceae 100644 --- a/include/uapi/linux/videodev2.h +++ b/include/uapi/linux/videodev2.h @@ -609,6 +609,9 @@ struct v4l2_pix_format { @@ -2054,7 +620,7 @@ index f717826d5d7c..d620f6adfd60 100644 #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 171786dacd72b7da9c6cb4850d10dad849cd8997 Mon Sep 17 00:00:00 2001 +From 1e18a042326b9e3b659b259b36c0d006ce0f48ad 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 @@ -2099,7 +665,7 @@ index bf632d45282b..6f2d41b2e076 100644 if (sps->chroma_format_idc == 0) -From 86741c8a5fdf92ea27d28d12aae2658063b0af8b Mon Sep 17 00:00:00 2001 +From f4eb3cf298b45fd835483bcc92e299031c45b8f7 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 @@ -2170,7 +736,7 @@ index 06fc58440cd3..dc16bf8d57a9 100644 return 0; } -From ee6e5c79c9eda12d0d1587fc23d07be95f6f7cca Mon Sep 17 00:00:00 2001 +From a63d03a5130710d6ff90846c26534a819617ee3a 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 @@ -2323,7 +889,7 @@ index 77a137cca88e..e95c52e3168a 100644 struct v4l2_ctrl_handler ctrl_hdl; struct rkvdec_dev *dev; -From 2b34935e33c4f70d0bc9fec87f79949453759a4e Mon Sep 17 00:00:00 2001 +From e146c2ad5f79b68d1f84aebfdcee7afa1b0da450 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 @@ -2429,7 +995,7 @@ index 6b2a2f4164b2..bd8ec2915fe9 100644 static const struct rkvdec_coded_fmt_desc rkvdec_coded_fmts[] = { -From 69722a78bf0e3917c10a292f78832d98345ec26b Mon Sep 17 00:00:00 2001 +From bc3510d94b7f2ccaa8152e8d08522fb166583806 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 @@ -2472,7 +1038,7 @@ index bd8ec2915fe9..87987a782d75 100644 static const struct rkvdec_ctrls rkvdec_h264_ctrls = { -From 52bb06e99669a434f2ef63d81eabc1c6a9bc3599 Mon Sep 17 00:00:00 2001 +From 22900938ef269ca5c54d6c5e5fc83d4ba24f6d37 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 @@ -2510,7 +1076,7 @@ index 87987a782d75..2e1d272a3af7 100644 } -From a1860966b04711a9460f22c8ee41c13884d2b6b9 Mon Sep 17 00:00:00 2001 +From 7541cecc1d80a0072c9286411052dd24f0bcc14c 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 @@ -2532,10 +1098,10 @@ Signed-off-by: Adrian Ratiu 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 3c9634173e82..e09102e572fd 100644 +index 7869b6f6ff72..6b4a83b053f5 100644 --- a/Documentation/userspace-api/media/v4l/biblio.rst +++ b/Documentation/userspace-api/media/v4l/biblio.rst -@@ -414,3 +414,13 @@ VP8 +@@ -407,3 +407,13 @@ VP8 :title: RFC 6386: "VP8 Data Format and Decoding Guide" :author: J. Bankoski et al. @@ -2550,10 +1116,10 @@ index 3c9634173e82..e09102e572fd 100644 + +: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 e2b94b1d0ab0..d29aed416fda 100644 +index ce728c757eaf..456488f2b5ca 100644 --- a/Documentation/userspace-api/media/v4l/ext-ctrls-codec.rst +++ b/Documentation/userspace-api/media/v4l/ext-ctrls-codec.rst -@@ -2689,6 +2689,556 @@ enum v4l2_mpeg_video_h264_hierarchical_coding_type - +@@ -2730,6 +2730,556 @@ enum v4l2_mpeg_video_h264_hierarchical_coding_type - - ``padding[3]`` - Applications and drivers must set this to zero. @@ -3111,12 +1677,12 @@ index e2b94b1d0ab0..d29aed416fda 100644 \normalsize diff --git a/drivers/media/v4l2-core/v4l2-ctrls.c b/drivers/media/v4l2-core/v4l2-ctrls.c -index d4a6c0346c2a..3948bee0f5e1 100644 +index bd7f330c941c..a88e962ac8a1 100644 --- a/drivers/media/v4l2-core/v4l2-ctrls.c +++ b/drivers/media/v4l2-core/v4l2-ctrls.c -@@ -940,6 +940,11 @@ const char *v4l2_ctrl_get_name(u32 id) - case V4L2_CID_MPEG_VIDEO_VP8_PROFILE: return "VP8 Profile"; +@@ -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"; @@ -3126,7 +1692,7 @@ index d4a6c0346c2a..3948bee0f5e1 100644 /* HEVC controls */ case V4L2_CID_MPEG_VIDEO_HEVC_I_FRAME_QP: return "HEVC I-Frame QP Value"; -@@ -1419,6 +1424,15 @@ void v4l2_ctrl_fill(u32 id, const char **name, enum v4l2_ctrl_type *type, +@@ -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; @@ -3142,7 +1708,7 @@ index d4a6c0346c2a..3948bee0f5e1 100644 case V4L2_CID_MPEG_VIDEO_HEVC_SPS: *type = V4L2_CTRL_TYPE_HEVC_SPS; break; -@@ -1721,6 +1735,219 @@ static void std_log(const struct v4l2_ctrl *ctrl) +@@ -1754,6 +1768,219 @@ static void std_log(const struct v4l2_ctrl *ctrl) 0; \ }) @@ -3362,7 +1928,7 @@ index d4a6c0346c2a..3948bee0f5e1 100644 /* Validate a new control */ #define zero_padding(s) \ -@@ -1838,6 +2065,12 @@ static int std_validate_compound(const struct v4l2_ctrl *ctrl, u32 idx, +@@ -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; @@ -3375,7 +1941,7 @@ index d4a6c0346c2a..3948bee0f5e1 100644 case V4L2_CTRL_TYPE_HEVC_SPS: p_hevc_sps = p; -@@ -2584,6 +2817,12 @@ static struct v4l2_ctrl *v4l2_ctrl_new(struct v4l2_ctrl_handler *hdl, +@@ -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; @@ -3923,7 +2489,7 @@ index 000000000000..a14fffb3ad61 + +#endif /* _VP9_CTRLS_H_ */ -From b936bc23ae74d501fabf0fbdd07c59b25e6347dd Mon Sep 17 00:00:00 2001 +From 4e75ff472abd06d88758d73146697a0f4817d4f2 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 diff --git a/patch/kernel/rk322x-current/01-linux-0011-v4l2-from-5.10.patch b/patch/kernel/rk322x-current/01-linux-0011-v4l2-from-5.10.patch deleted file mode 100644 index d9f311803..000000000 --- a/patch/kernel/rk322x-current/01-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/patch/kernel/rk322x-current/01-linux-0022-drm-from-next.patch b/patch/kernel/rk322x-current/01-linux-0020-drm-from-5.11.patch similarity index 61% rename from patch/kernel/rk322x-current/01-linux-0022-drm-from-next.patch rename to patch/kernel/rk322x-current/01-linux-0020-drm-from-5.11.patch index 86615ef33..ea8e5c5f1 100644 --- a/patch/kernel/rk322x-current/01-linux-0022-drm-from-next.patch +++ b/patch/kernel/rk322x-current/01-linux-0020-drm-from-5.11.patch @@ -1,4 +1,4 @@ -From 0898302e2ab75165acf8ad43726e67f3f0f6ab32 Mon Sep 17 00:00:00 2001 +From b9335b9a01fc5eadeec6c50a81e68a9e9799de2d 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 @@ -82,7 +82,7 @@ index 62e5d0970525..1cf4631461c9 100644 */ void rockchip_gem_free_object(struct drm_gem_object *obj) -From 411c1e880514d8903890c1fe67c4b532d8f0c21c Mon Sep 17 00:00:00 2001 +From ba7e8c9f9c79119c569466b08b58a3b20aa0dca9 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 @@ -125,7 +125,7 @@ index 1cf4631461c9..7d5ebb10323b 100644 #include -From 4ddb01c2866cd57b134d739e9e88e00dc88453ae Mon Sep 17 00:00:00 2001 +From 40175ca66971e6bde3e4c3e466616da07711271d 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 @@ -169,7 +169,7 @@ index e6896733838a..ea8d31863c50 100644 static void panfrost_reset_fini(struct panfrost_device *pfdev) -From b75473ce0e84aa528eef4f805c95fc5e2f6f766a Mon Sep 17 00:00:00 2001 +From 7e4d1ac491e3ac8b8b03d74129ef9521cdf479ef 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 @@ -211,7 +211,7 @@ index 8ab025d0035f..913eaa6d0bc6 100644 static void panfrost_devfreq_reset(struct panfrost_devfreq *pfdevfreq) -From f3f98ffb76cdbf06f0549ce904007a7725b76c6f Mon Sep 17 00:00:00 2001 +From 7efe8c0d9576db34e4d5427d5a939a20f4afe96f 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 @@ -242,162 +242,3 @@ index 9fef6413741d..feb04f127b55 100644 .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/patch/kernel/rk322x-current/01-linux-0021-drm-from-5.10.patch b/patch/kernel/rk322x-current/01-linux-0021-drm-from-5.10.patch deleted file mode 100644 index c87b42921..000000000 --- a/patch/kernel/rk322x-current/01-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/patch/kernel/rk322x-current/01-linux-0021-drm-from-list.patch b/patch/kernel/rk322x-current/01-linux-0021-drm-from-list.patch new file mode 100644 index 000000000..c8c85873d --- /dev/null +++ b/patch/kernel/rk322x-current/01-linux-0021-drm-from-list.patch @@ -0,0 +1,1753 @@ +From cff5461f765441936c710f2091a45fb4984444c7 Mon Sep 17 00:00:00 2001 +From: Johan Jonker +Date: Sun, 6 Dec 2020 14:33:51 +0100 +Subject: [PATCH] dt-bindings: display: add #sound-dai-cells property to + rockchip rk3066 hdmi + +'#sound-dai-cells' is required to properly interpret +the list of DAI specified in the 'sound-dai' property. +Add it to rockchip,rk3066-hdmi.yaml to document that the +rk3066 HDMI TX also can be used to transmit some audio. + +Signed-off-by: Johan Jonker +Reviewed-by: Rob Herring +--- + .../bindings/display/rockchip/rockchip,rk3066-hdmi.yaml | 4 ++++ + 1 file changed, 4 insertions(+) + +diff --git a/Documentation/devicetree/bindings/display/rockchip/rockchip,rk3066-hdmi.yaml b/Documentation/devicetree/bindings/display/rockchip/rockchip,rk3066-hdmi.yaml +index 4110d003ce1f..585a8d3b9500 100644 +--- a/Documentation/devicetree/bindings/display/rockchip/rockchip,rk3066-hdmi.yaml ++++ b/Documentation/devicetree/bindings/display/rockchip/rockchip,rk3066-hdmi.yaml +@@ -42,6 +42,9 @@ properties: + description: + This soc uses GRF regs to switch the HDMI TX input between vop0 and vop1. + ++ "#sound-dai-cells": ++ const: 0 ++ + ports: + type: object + +@@ -101,6 +104,7 @@ examples: + pinctrl-names = "default"; + power-domains = <&power RK3066_PD_VIO>; + rockchip,grf = <&grf>; ++ #sound-dai-cells = <0>; + + ports { + #address-cells = <1>; + +From 17675dc4df56268f059cab8a33cf28e90f8431d7 Mon Sep 17 00:00:00 2001 +From: Zheng Yang +Date: Sun, 6 Dec 2020 14:33:52 +0100 +Subject: [PATCH] drm: rockchip: add sound support to rk3066 hdmi driver + +Add sound support to the rk3066 HDMI driver. + +The I2S input of the HDMI TX allows transmission of +DVD-Audio and decoded Dolby Digital +to A/V Receivers and high-end displays. +The interface supports 2 to 8 channels audio up to 192 kHz. +The HDMI TX supports variable word length of +16bits to 32bits for I2S audio inputs.(This driver 24bit max) +There are three I2S input modes supported.(This driver HDMI_I2S only) +On RK3066/PX2 the HDMI TX audio source is connected to I2S_8CH. + +Signed-off-by: Zheng Yang +Signed-off-by: Johan Jonker +--- + drivers/gpu/drm/rockchip/Kconfig | 2 + + drivers/gpu/drm/rockchip/rk3066_hdmi.c | 277 ++++++++++++++++++++++++- + 2 files changed, 278 insertions(+), 1 deletion(-) + +diff --git a/drivers/gpu/drm/rockchip/Kconfig b/drivers/gpu/drm/rockchip/Kconfig +index 310aa1546893..4c20445dc35c 100644 +--- a/drivers/gpu/drm/rockchip/Kconfig ++++ b/drivers/gpu/drm/rockchip/Kconfig +@@ -11,6 +11,8 @@ config DRM_ROCKCHIP + select DRM_DW_MIPI_DSI if ROCKCHIP_DW_MIPI_DSI + select DRM_RGB if ROCKCHIP_RGB + select SND_SOC_HDMI_CODEC if ROCKCHIP_CDN_DP && SND_SOC ++ select SND_SOC_HDMI_CODEC if ROCKCHIP_RK3066_HDMI && SND_SOC ++ select SND_SOC_ROCKCHIP_I2S if ROCKCHIP_RK3066_HDMI && SND_SOC + help + Choose this option if you have a Rockchip soc chipset. + This driver provides kernel mode setting and buffer +diff --git a/drivers/gpu/drm/rockchip/rk3066_hdmi.c b/drivers/gpu/drm/rockchip/rk3066_hdmi.c +index 1c546c3a8998..2f865402354f 100644 +--- a/drivers/gpu/drm/rockchip/rk3066_hdmi.c ++++ b/drivers/gpu/drm/rockchip/rk3066_hdmi.c +@@ -13,6 +13,8 @@ + #include + #include + ++#include ++ + #include "rk3066_hdmi.h" + + #include "rockchip_drm_drv.h" +@@ -20,9 +22,16 @@ + + #define DEFAULT_PLLA_RATE 30000000 + ++struct audio_info { ++ int channels; ++ int sample_rate; ++ int sample_width; ++}; ++ + struct hdmi_data_info { + int vic; /* The CEA Video ID (VIC) of the current drm display mode. */ + bool sink_is_hdmi; ++ bool sink_has_audio; + unsigned int enc_out_format; + unsigned int colorimetry; + }; +@@ -54,12 +63,19 @@ struct rk3066_hdmi { + + unsigned int tmdsclk; + ++ struct platform_device *audio_pdev; ++ struct audio_info audio; ++ bool audio_enable; ++ + struct hdmi_data_info hdmi_data; + struct drm_display_mode previous_mode; + }; + + #define to_rk3066_hdmi(x) container_of(x, struct rk3066_hdmi, x) + ++static int ++rk3066_hdmi_config_audio(struct rk3066_hdmi *hdmi, struct audio_info *audio); ++ + static inline u8 hdmi_readb(struct rk3066_hdmi *hdmi, u16 offset) + { + return readl_relaxed(hdmi->regs + offset); +@@ -205,6 +221,23 @@ static int rk3066_hdmi_config_avi(struct rk3066_hdmi *hdmi, + HDMI_INFOFRAME_AVI, 0, 0, 0); + } + ++static int rk3066_hdmi_config_aai(struct rk3066_hdmi *hdmi, ++ struct audio_info *audio) ++{ ++ union hdmi_infoframe frame; ++ int rc; ++ ++ rc = hdmi_audio_infoframe_init(&frame.audio); ++ ++ frame.audio.coding_type = HDMI_AUDIO_CODING_TYPE_STREAM; ++ frame.audio.sample_frequency = HDMI_AUDIO_SAMPLE_FREQUENCY_STREAM; ++ frame.audio.sample_size = HDMI_AUDIO_SAMPLE_SIZE_STREAM; ++ frame.audio.channels = hdmi->audio.channels; ++ ++ return rk3066_hdmi_upload_frame(hdmi, rc, &frame, ++ HDMI_INFOFRAME_AAI, 0, 0, 0); ++} ++ + static int rk3066_hdmi_config_video_timing(struct rk3066_hdmi *hdmi, + struct drm_display_mode *mode) + { +@@ -353,6 +386,7 @@ static int rk3066_hdmi_setup(struct rk3066_hdmi *hdmi, + hdmi_modb(hdmi, HDMI_HDCP_CTRL, HDMI_VIDEO_MODE_MASK, + HDMI_VIDEO_MODE_HDMI); + rk3066_hdmi_config_avi(hdmi, mode); ++ rk3066_hdmi_config_audio(hdmi, &hdmi->audio); + } else { + hdmi_modb(hdmi, HDMI_HDCP_CTRL, HDMI_VIDEO_MODE_MASK, 0); + } +@@ -369,9 +403,20 @@ static int rk3066_hdmi_setup(struct rk3066_hdmi *hdmi, + */ + rk3066_hdmi_i2c_init(hdmi); + +- /* Unmute video output. */ ++ /* Unmute video and audio output. */ + hdmi_modb(hdmi, HDMI_VIDEO_CTRL2, + HDMI_VIDEO_AUDIO_DISABLE_MASK, HDMI_AUDIO_DISABLE); ++ if (hdmi->audio_enable) { ++ hdmi_modb(hdmi, HDMI_VIDEO_CTRL2, HDMI_AUDIO_DISABLE, 0); ++ /* Reset audio capture logic. */ ++ hdmi_modb(hdmi, HDMI_VIDEO_CTRL2, ++ HDMI_AUDIO_CP_LOGIC_RESET_MASK, ++ HDMI_AUDIO_CP_LOGIC_RESET); ++ usleep_range(900, 1000); ++ hdmi_modb(hdmi, HDMI_VIDEO_CTRL2, ++ HDMI_AUDIO_CP_LOGIC_RESET_MASK, 0); ++ } ++ + return 0; + } + +@@ -473,9 +518,13 @@ static int rk3066_hdmi_connector_get_modes(struct drm_connector *connector) + edid = drm_get_edid(connector, hdmi->ddc); + if (edid) { + hdmi->hdmi_data.sink_is_hdmi = drm_detect_hdmi_monitor(edid); ++ hdmi->hdmi_data.sink_has_audio = drm_detect_monitor_audio(edid); + drm_connector_update_edid_property(connector, edid); + ret = drm_add_edid_modes(connector, edid); + kfree(edid); ++ } else { ++ hdmi->hdmi_data.sink_is_hdmi = true; ++ hdmi->hdmi_data.sink_has_audio = true; + } + + return ret; +@@ -535,6 +584,228 @@ struct drm_connector_helper_funcs rk3066_hdmi_connector_helper_funcs = { + .best_encoder = rk3066_hdmi_connector_best_encoder, + }; + ++static int ++rk3066_hdmi_config_audio(struct rk3066_hdmi *hdmi, struct audio_info *audio) ++{ ++ u32 rate, channel, word_length, N, CTS; ++ u64 tmp; ++ ++ if (audio->channels < 3) ++ channel = HDMI_AUDIO_I2S_CHANNEL_1_2; ++ else if (audio->channels < 5) ++ channel = HDMI_AUDIO_I2S_CHANNEL_3_4; ++ else if (audio->channels < 7) ++ channel = HDMI_AUDIO_I2S_CHANNEL_5_6; ++ else ++ channel = HDMI_AUDIO_I2S_CHANNEL_7_8; ++ ++ switch (audio->sample_rate) { ++ case 32000: ++ rate = HDMI_AUDIO_SAMPLE_FRE_32000; ++ N = N_32K; ++ break; ++ case 44100: ++ rate = HDMI_AUDIO_SAMPLE_FRE_44100; ++ N = N_441K; ++ break; ++ case 48000: ++ rate = HDMI_AUDIO_SAMPLE_FRE_48000; ++ N = N_48K; ++ break; ++ case 88200: ++ rate = HDMI_AUDIO_SAMPLE_FRE_88200; ++ N = N_882K; ++ break; ++ case 96000: ++ rate = HDMI_AUDIO_SAMPLE_FRE_96000; ++ N = N_96K; ++ break; ++ case 176400: ++ rate = HDMI_AUDIO_SAMPLE_FRE_176400; ++ N = N_1764K; ++ break; ++ case 192000: ++ rate = HDMI_AUDIO_SAMPLE_FRE_192000; ++ N = N_192K; ++ break; ++ default: ++ DRM_DEV_ERROR(hdmi->dev, "no support for sample rate %d\n", ++ audio->sample_rate); ++ return -ENOENT; ++ } ++ ++ switch (audio->sample_width) { ++ case 16: ++ word_length = 0x02; ++ break; ++ case 20: ++ word_length = 0x0a; ++ break; ++ case 24: ++ word_length = 0x0b; ++ break; ++ default: ++ DRM_DEV_ERROR(hdmi->dev, "no support for word length %d\n", ++ audio->sample_width); ++ return -ENOENT; ++ } ++ ++ tmp = (u64)hdmi->tmdsclk * N; ++ do_div(tmp, 128 * audio->sample_rate); ++ CTS = tmp; ++ ++ /* Set_audio source I2S. */ ++ hdmi_writeb(hdmi, HDMI_AUDIO_CTRL1, 0x00); ++ hdmi_writeb(hdmi, HDMI_AUDIO_CTRL2, 0x40); ++ hdmi_writeb(hdmi, HDMI_I2S_AUDIO_CTRL, ++ HDMI_AUDIO_I2S_FORMAT_STANDARD | channel); ++ hdmi_writeb(hdmi, HDMI_I2S_SWAP, 0x00); ++ hdmi_modb(hdmi, HDMI_AV_CTRL1, HDMI_AUDIO_SAMPLE_FRE_MASK, rate); ++ hdmi_writeb(hdmi, HDMI_AUDIO_SRC_NUM_AND_LENGTH, word_length); ++ ++ /* Set N value. */ ++ hdmi_modb(hdmi, HDMI_LR_SWAP_N3, ++ HDMI_AUDIO_N_19_16_MASK, (N >> 16) & 0x0F); ++ hdmi_writeb(hdmi, HDMI_N2, (N >> 8) & 0xFF); ++ hdmi_writeb(hdmi, HDMI_N1, N & 0xFF); ++ ++ /* Set CTS value. */ ++ hdmi_writeb(hdmi, HDMI_CTS_EXT1, CTS & 0xff); ++ hdmi_writeb(hdmi, HDMI_CTS_EXT2, (CTS >> 8) & 0xff); ++ hdmi_writeb(hdmi, HDMI_CTS_EXT3, (CTS >> 16) & 0xff); ++ ++ if (audio->channels > 2) ++ hdmi_modb(hdmi, HDMI_LR_SWAP_N3, ++ HDMI_AUDIO_LR_SWAP_MASK, ++ HDMI_AUDIO_LR_SWAP_SUBPACKET1); ++ rate = (~(rate >> 4)) & 0x0f; ++ hdmi_writeb(hdmi, HDMI_AUDIO_STA_BIT_CTRL1, rate); ++ hdmi_writeb(hdmi, HDMI_AUDIO_STA_BIT_CTRL2, 0); ++ ++ return rk3066_hdmi_config_aai(hdmi, audio); ++} ++ ++static int rk3066_hdmi_audio_hw_params(struct device *dev, void *d, ++ struct hdmi_codec_daifmt *daifmt, ++ struct hdmi_codec_params *params) ++{ ++ struct rk3066_hdmi *hdmi = dev_get_drvdata(dev); ++ ++ if (!hdmi->hdmi_data.sink_has_audio) { ++ DRM_DEV_ERROR(hdmi->dev, "no audio support\n"); ++ return -ENODEV; ++ } ++ ++ if (!hdmi->encoder.crtc) ++ return -ENODEV; ++ ++ switch (daifmt->fmt) { ++ case HDMI_I2S: ++ break; ++ default: ++ DRM_DEV_ERROR(dev, "invalid format %d\n", daifmt->fmt); ++ return -EINVAL; ++ } ++ ++ hdmi->audio.channels = params->channels; ++ hdmi->audio.sample_rate = params->sample_rate; ++ hdmi->audio.sample_width = params->sample_width; ++ ++ return rk3066_hdmi_config_audio(hdmi, &hdmi->audio); ++} ++ ++static void rk3066_hdmi_audio_shutdown(struct device *dev, void *d) ++{ ++ /* do nothing */ ++} ++ ++static int ++rk3066_hdmi_audio_mute_stream(struct device *dev, void *d, ++ bool mute, int direction) ++{ ++ struct rk3066_hdmi *hdmi = dev_get_drvdata(dev); ++ ++ if (!hdmi->hdmi_data.sink_has_audio) { ++ DRM_DEV_ERROR(hdmi->dev, "no audio support\n"); ++ return -ENODEV; ++ } ++ ++ hdmi->audio_enable = !mute; ++ ++ if (mute) ++ hdmi_modb(hdmi, HDMI_VIDEO_CTRL2, ++ HDMI_AUDIO_DISABLE, HDMI_AUDIO_DISABLE); ++ else ++ hdmi_modb(hdmi, HDMI_VIDEO_CTRL2, HDMI_AUDIO_DISABLE, 0); ++ ++ /* ++ * Under power mode E we need to reset the audio capture logic to ++ * make the audio setting update. ++ */ ++ if (rk3066_hdmi_get_power_mode(hdmi) == HDMI_SYS_POWER_MODE_E) { ++ hdmi_modb(hdmi, HDMI_VIDEO_CTRL2, ++ HDMI_AUDIO_CP_LOGIC_RESET_MASK, ++ HDMI_AUDIO_CP_LOGIC_RESET); ++ usleep_range(900, 1000); ++ hdmi_modb(hdmi, HDMI_VIDEO_CTRL2, ++ HDMI_AUDIO_CP_LOGIC_RESET_MASK, 0); ++ } ++ ++ return 0; ++} ++ ++static int rk3066_hdmi_audio_get_eld(struct device *dev, void *d, ++ u8 *buf, size_t len) ++{ ++ struct rk3066_hdmi *hdmi = dev_get_drvdata(dev); ++ struct drm_mode_config *config = &hdmi->encoder.dev->mode_config; ++ struct drm_connector *connector; ++ int ret = -ENODEV; ++ ++ mutex_lock(&config->mutex); ++ list_for_each_entry(connector, &config->connector_list, head) { ++ if (&hdmi->encoder == connector->encoder) { ++ memcpy(buf, connector->eld, ++ min(sizeof(connector->eld), len)); ++ ret = 0; ++ } ++ } ++ mutex_unlock(&config->mutex); ++ ++ return ret; ++} ++ ++static const struct hdmi_codec_ops audio_codec_ops = { ++ .hw_params = rk3066_hdmi_audio_hw_params, ++ .audio_shutdown = rk3066_hdmi_audio_shutdown, ++ .mute_stream = rk3066_hdmi_audio_mute_stream, ++ .get_eld = rk3066_hdmi_audio_get_eld, ++ .no_capture_mute = 1, ++}; ++ ++static int rk3066_hdmi_audio_codec_init(struct rk3066_hdmi *hdmi, ++ struct device *dev) ++{ ++ struct hdmi_codec_pdata codec_data = { ++ .i2s = 1, ++ .ops = &audio_codec_ops, ++ .max_i2s_channels = 8, ++ }; ++ ++ hdmi->audio.channels = 2; ++ hdmi->audio.sample_rate = 48000; ++ hdmi->audio.sample_width = 16; ++ hdmi->audio_enable = false; ++ hdmi->audio_pdev = ++ platform_device_register_data(dev, ++ HDMI_CODEC_DRV_NAME, ++ PLATFORM_DEVID_NONE, ++ &codec_data, ++ sizeof(codec_data)); ++ ++ return PTR_ERR_OR_ZERO(hdmi->audio_pdev); ++} ++ + static int + rk3066_hdmi_register(struct drm_device *drm, struct rk3066_hdmi *hdmi) + { +@@ -567,6 +838,8 @@ rk3066_hdmi_register(struct drm_device *drm, struct rk3066_hdmi *hdmi) + + drm_connector_attach_encoder(&hdmi->connector, encoder); + ++ rk3066_hdmi_audio_codec_init(hdmi, dev); ++ + return 0; + } + +@@ -815,6 +1088,7 @@ static int rk3066_hdmi_bind(struct device *dev, struct device *master, + return 0; + + err_cleanup_hdmi: ++ platform_device_unregister(hdmi->audio_pdev); + hdmi->connector.funcs->destroy(&hdmi->connector); + hdmi->encoder.funcs->destroy(&hdmi->encoder); + err_disable_i2c: +@@ -830,6 +1104,7 @@ static void rk3066_hdmi_unbind(struct device *dev, struct device *master, + { + struct rk3066_hdmi *hdmi = dev_get_drvdata(dev); + ++ platform_device_unregister(hdmi->audio_pdev); + hdmi->connector.funcs->destroy(&hdmi->connector); + hdmi->encoder.funcs->destroy(&hdmi->encoder); + + +From 699d1968c786ca9d6f27597e7f02df8bec39a82c Mon Sep 17 00:00:00 2001 +From: Johan Jonker +Date: Sun, 6 Dec 2020 14:33:53 +0100 +Subject: [PATCH] ARM: dts: rockchip: rk3066a: add #sound-dai-cells to hdmi + node + +'#sound-dai-cells' is required to properly interpret +the list of DAI specified in the 'sound-dai' property, +so add them to the 'hdmi' node for 'rk3066a.dtsi'. + +Signed-off-by: Johan Jonker +--- + arch/arm/boot/dts/rk3066a.dtsi | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/arch/arm/boot/dts/rk3066a.dtsi b/arch/arm/boot/dts/rk3066a.dtsi +index 252750c97f97..67fcb0dc94c6 100644 +--- a/arch/arm/boot/dts/rk3066a.dtsi ++++ b/arch/arm/boot/dts/rk3066a.dtsi +@@ -124,6 +124,7 @@ hdmi: hdmi@10116000 { + pinctrl-0 = <&hdmii2c_xfer>, <&hdmi_hpd>; + power-domains = <&power RK3066_PD_VIO>; + rockchip,grf = <&grf>; ++ #sound-dai-cells = <0>; + status = "disabled"; + + ports { + +From e03e49cc9c2788948323231517aa8a3ffa9022cb Mon Sep 17 00:00:00 2001 +From: Johan Jonker +Date: Sun, 6 Dec 2020 14:33:54 +0100 +Subject: [PATCH] ARM: dts: rockchip: add hdmi-sound node to rk3066a.dtsi + +Add hdmi-sound node to rk3066a.dtsi, so that it +can be reused by boards with HDMI support. + +Signed-off-by: Johan Jonker +--- + arch/arm/boot/dts/rk3066a.dtsi | 16 ++++++++++++++++ + 1 file changed, 16 insertions(+) + +diff --git a/arch/arm/boot/dts/rk3066a.dtsi b/arch/arm/boot/dts/rk3066a.dtsi +index 67fcb0dc94c6..f91ce30549c2 100644 +--- a/arch/arm/boot/dts/rk3066a.dtsi ++++ b/arch/arm/boot/dts/rk3066a.dtsi +@@ -49,6 +49,22 @@ display-subsystem { + ports = <&vop0_out>, <&vop1_out>; + }; + ++ hdmi_sound: hdmi-sound { ++ compatible = "simple-audio-card"; ++ simple-audio-card,name = "HDMI"; ++ simple-audio-card,format = "i2s"; ++ simple-audio-card,mclk-fs = <256>; ++ status = "disabled"; ++ ++ simple-audio-card,codec { ++ sound-dai = <&hdmi>; ++ }; ++ ++ simple-audio-card,cpu { ++ sound-dai = <&i2s0>; ++ }; ++ }; ++ + sram: sram@10080000 { + compatible = "mmio-sram"; + reg = <0x10080000 0x10000>; + +From 06ed130f2c53fb7bfe3f02b0bc289add1722ed3f Mon Sep 17 00:00:00 2001 +From: Johan Jonker +Date: Sun, 6 Dec 2020 14:33:55 +0100 +Subject: [PATCH] ARM: dts: rockchip: enable hdmi_sound and i2s0 for + rk3066a-mk808 + +Make some noise with mk808. Enable the hdmi_sound node and +add i2s0 as sound source for hdmi. + +Signed-off-by: Johan Jonker +--- + arch/arm/boot/dts/rk3066a-mk808.dts | 8 ++++++++ + 1 file changed, 8 insertions(+) + +diff --git a/arch/arm/boot/dts/rk3066a-mk808.dts b/arch/arm/boot/dts/rk3066a-mk808.dts +index eed9e60cffa2..5fe74c097587 100644 +--- a/arch/arm/boot/dts/rk3066a-mk808.dts ++++ b/arch/arm/boot/dts/rk3066a-mk808.dts +@@ -116,6 +116,14 @@ hdmi_out_con: endpoint { + }; + }; + ++&hdmi_sound { ++ status = "okay"; ++}; ++ ++&i2s0 { ++ status = "okay"; ++}; ++ + &mmc0 { + bus-width = <4>; + cap-mmc-highspeed; + +From c10e2ba88fda1f85630de4cef840ce146fd4889a Mon Sep 17 00:00:00 2001 +From: Phong LE +Date: Wed, 11 Mar 2020 13:51:33 +0100 +Subject: [PATCH] dt-bindings: display: bridge: add it66121 bindings + +Add the ITE bridge HDMI it66121 bindings. + +Signed-off-by: Phong LE +--- + .../bindings/display/bridge/ite,it66121.yaml | 98 +++++++++++++++++++ + 1 file changed, 98 insertions(+) + create mode 100644 Documentation/devicetree/bindings/display/bridge/ite,it66121.yaml + +diff --git a/Documentation/devicetree/bindings/display/bridge/ite,it66121.yaml b/Documentation/devicetree/bindings/display/bridge/ite,it66121.yaml +new file mode 100644 +index 000000000000..1717e880d130 +--- /dev/null ++++ b/Documentation/devicetree/bindings/display/bridge/ite,it66121.yaml +@@ -0,0 +1,98 @@ ++# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause) ++%YAML 1.2 ++--- ++$id: http://devicetree.org/schemas/display/bridge/ite,it66121.yaml# ++$schema: http://devicetree.org/meta-schemas/core.yaml# ++ ++title: ITE it66121 HDMI bridge Device Tree Bindings ++ ++maintainers: ++ - Phong LE ++ - Neil Armstrong ++ ++description: | ++ The IT66121 is a high-performance and low-power single channel HDMI ++ transmitter, fully compliant with HDMI 1.3a, HDCP 1.2 and backward compatible ++ to DVI 1.0 specifications. ++ ++properties: ++ compatible: ++ const: ite,it66121 ++ ++ reg: ++ maxItems: 1 ++ description: base I2C address of the device ++ ++ reset-gpios: ++ maxItems: 1 ++ description: GPIO connected to active low reset ++ ++ vrf12-supply: ++ maxItems: 1 ++ description: Regulator for 1.2V analog core power. ++ ++ vcn33-supply: ++ maxItems: 1 ++ description: Regulator for 3.3V digital core power. ++ ++ vcn18-supply: ++ maxItems: 1 ++ description: Regulator for 1.8V IO core power. ++ ++ interrupts: ++ maxItems: 1 ++ ++ pclk-dual-edge: ++ maxItems: 1 ++ description: enable pclk dual edge mode. ++ ++ port: ++ type: object ++ ++ properties: ++ endpoint: ++ type: object ++ description: | ++ Input endpoints of the bridge. ++ ++ required: ++ - endpoint ++ ++required: ++ - compatible ++ - reg ++ - reset-gpios ++ - vrf12-supply ++ - vcn33-supply ++ - vcn18-supply ++ - interrupts ++ - port ++ ++additionalProperties: false ++ ++examples: ++ - | ++ i2c6 { ++ #address-cells = <1>; ++ #size-cells = <0>; ++ ++ it66121hdmitx: it66121hdmitx@4c { ++ compatible = "ite,it66121"; ++ pinctrl-names = "default"; ++ pinctrl-0 = <&ite_pins_default>; ++ vcn33-supply = <&mt6358_vcn33_wifi_reg>; ++ vcn18-supply = <&mt6358_vcn18_reg>; ++ vrf12-supply = <&mt6358_vrf12_reg>; ++ reset-gpios = <&pio 160 1 /* GPIO_ACTIVE_LOW */>; ++ interrupt-parent = <&pio>; ++ interrupts = <4 8 /* IRQ_TYPE_LEVEL_LOW */>; ++ reg = <0x4c>; ++ pclk-dual-edge; ++ ++ port { ++ it66121_in: endpoint { ++ remote-endpoint = <&display_out>; ++ }; ++ }; ++ }; ++ }; + +From 87c7f65fcfebabb40fe4a09ebc5ffb78b9870678 Mon Sep 17 00:00:00 2001 +From: Phong LE +Date: Wed, 11 Mar 2020 13:51:34 +0100 +Subject: [PATCH] drm: bridge: add it66121 driver + +This commit is a simple driver for bridge HMDI it66121. +The input format is RBG and there is no color conversion. +Audio, HDCP and CEC are not supported yet. + +Signed-off-by: Phong LE +--- + drivers/gpu/drm/bridge/Kconfig | 8 + + drivers/gpu/drm/bridge/Makefile | 1 + + drivers/gpu/drm/bridge/ite-it66121.c | 997 +++++++++++++++++++++++++++ + 3 files changed, 1006 insertions(+) + create mode 100644 drivers/gpu/drm/bridge/ite-it66121.c + +diff --git a/drivers/gpu/drm/bridge/Kconfig b/drivers/gpu/drm/bridge/Kconfig +index ef91646441b1..6fe281070602 100644 +--- a/drivers/gpu/drm/bridge/Kconfig ++++ b/drivers/gpu/drm/bridge/Kconfig +@@ -61,6 +61,14 @@ config DRM_LONTIUM_LT9611 + HDMI signals + Please say Y if you have such hardware. + ++config DRM_ITE_IT66121 ++ tristate "ITE IT66121 HDMI bridge" ++ depends on OF ++ select DRM_KMS_HELPER ++ select REGMAP_I2C ++ help ++ Support for ITE IT66121 HDMI bridge. ++ + config DRM_LVDS_CODEC + tristate "Transparent LVDS encoders and decoders support" + depends on OF +diff --git a/drivers/gpu/drm/bridge/Makefile b/drivers/gpu/drm/bridge/Makefile +index 2b3aff104e46..b3ae861c355f 100644 +--- a/drivers/gpu/drm/bridge/Makefile ++++ b/drivers/gpu/drm/bridge/Makefile +@@ -2,6 +2,7 @@ + obj-$(CONFIG_DRM_CDNS_DSI) += cdns-dsi.o + obj-$(CONFIG_DRM_CHRONTEL_CH7033) += chrontel-ch7033.o + obj-$(CONFIG_DRM_DISPLAY_CONNECTOR) += display-connector.o ++obj-$(CONFIG_DRM_ITE_IT66121) += ite-it66121.o + obj-$(CONFIG_DRM_LONTIUM_LT9611) += lontium-lt9611.o + obj-$(CONFIG_DRM_LVDS_CODEC) += lvds-codec.o + obj-$(CONFIG_DRM_MEGACHIPS_STDPXXXX_GE_B850V3_FW) += megachips-stdpxxxx-ge-b850v3-fw.o +diff --git a/drivers/gpu/drm/bridge/ite-it66121.c b/drivers/gpu/drm/bridge/ite-it66121.c +new file mode 100644 +index 000000000000..7e1a90319a6a +--- /dev/null ++++ b/drivers/gpu/drm/bridge/ite-it66121.c +@@ -0,0 +1,997 @@ ++// SPDX-License-Identifier: GPL-2.0-only ++/* ++ * Copyright (C) 2020 BayLibre, SAS ++ * Author: Phong LE ++ * Copyright (C) 2018-2019, Artem Mygaiev ++ * Copyright (C) 2017, Fresco Logic, Incorporated. ++ * ++ */ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#define IT66121_MASTER_SEL_REG 0x10 ++#define IT66121_MASTER_SEL_HOST BIT(0) ++ ++#define IT66121_AFE_DRV_REG 0x61 ++#define IT66121_AFE_DRV_RST BIT(4) ++#define IT66121_AFE_DRV_PWD BIT(5) ++ ++#define IT66121_INPUT_MODE_REG 0x70 ++#define IT66121_INPUT_MODE_RGB (0 << 6) ++#define IT66121_INPUT_MODE_YUV422 BIT(6) ++#define IT66121_INPUT_MODE_YUV444 (2 << 6) ++#define IT66121_INPUT_MODE_CCIR656 BIT(4) ++#define IT66121_INPUT_MODE_SYNCEMB BIT(3) ++#define IT66121_INPUT_MODE_DDR BIT(2) ++ ++#define IT66121_INPUT_CSC_REG 0x72 ++#define IT66121_INPUT_CSC_ENDITHER BIT(7) ++#define IT66121_INPUT_CSC_ENUDFILTER BIT(6) ++#define IT66121_INPUT_CSC_DNFREE_GO BIT(5) ++#define IT66121_INPUT_CSC_RGB_TO_YUV 0x02 ++#define IT66121_INPUT_CSC_YUV_TO_RGB 0x03 ++#define IT66121_INPUT_CSC_NO_CONV 0x00 ++ ++#define IT66121_AFE_XP_REG 0x62 ++#define IT66121_AFE_XP_GAINBIT BIT(7) ++#define IT66121_AFE_XP_PWDPLL BIT(6) ++#define IT66121_AFE_XP_ENI BIT(5) ++#define IT66121_AFE_XP_ENO BIT(4) ++#define IT66121_AFE_XP_RESETB BIT(3) ++#define IT66121_AFE_XP_PWDI BIT(2) ++ ++#define IT66121_AFE_IP_REG 0x64 ++#define IT66121_AFE_IP_GAINBIT BIT(7) ++#define IT66121_AFE_IP_PWDPLL BIT(6) ++#define IT66121_AFE_IP_CKSEL_05 (0 << 4) ++#define IT66121_AFE_IP_CKSEL_1 BIT(4) ++#define IT66121_AFE_IP_CKSEL_2 (2 << 4) ++#define IT66121_AFE_IP_CKSEL_2OR4 (3 << 4) ++#define IT66121_AFE_IP_ER0 BIT(3) ++#define IT66121_AFE_IP_RESETB BIT(2) ++#define IT66121_AFE_IP_ENC BIT(1) ++#define IT66121_AFE_IP_EC1 BIT(0) ++ ++#define IT66121_AFE_XP_EC1_REG 0x68 ++#define IT66121_AFE_XP_EC1_LOWCLK BIT(4) ++ ++#define IT66121_SW_RST_REG 0x04 ++#define IT66121_SW_RST_REF BIT(5) ++#define IT66121_SW_RST_AREF BIT(4) ++#define IT66121_SW_RST_VID BIT(3) ++#define IT66121_SW_RST_AUD BIT(2) ++#define IT66121_SW_RST_HDCP BIT(0) ++ ++#define IT66121_DDC_COMMAND_REG 0x15 ++#define IT66121_DDC_COMMAND_BURST_READ 0x0 ++#define IT66121_DDC_COMMAND_EDID_READ 0x3 ++#define IT66121_DDC_COMMAND_FIFO_CLR 0x9 ++#define IT66121_DDC_COMMAND_SCL_PULSE 0xA ++#define IT66121_DDC_COMMAND_ABORT 0xF ++ ++#define IT66121_HDCP_REG 0x20 ++#define IT66121_HDCP_CPDESIRED BIT(0) ++#define IT66121_HDCP_EN1P1FEAT BIT(1) ++ ++#define IT66121_INT_STATUS1_REG 0x06 ++#define IT66121_INT_STATUS1_AUD_OVF BIT(7) ++#define IT66121_INT_STATUS1_DDC_NOACK BIT(5) ++#define IT66121_INT_STATUS1_DDC_FIFOERR BIT(4) ++#define IT66121_INT_STATUS1_DDC_BUSHANG BIT(2) ++#define IT66121_INT_STATUS1_RX_SENS_STATUS BIT(1) ++#define IT66121_INT_STATUS1_HPD_STATUS BIT(0) ++ ++#define IT66121_DDC_HEADER_REG 0x11 ++#define IT66121_DDC_HEADER_HDCP 0x74 ++#define IT66121_DDC_HEADER_EDID 0xA0 ++ ++#define IT66121_DDC_OFFSET_REG 0x12 ++#define IT66121_DDC_BYTE_REG 0x13 ++#define IT66121_DDC_SEGMENT_REG 0x14 ++#define IT66121_DDC_RD_FIFO_REG 0x17 ++ ++#define IT66121_CLK_BANK_REG 0x0F ++#define IT66121_CLK_BANK_PWROFF_RCLK BIT(6) ++#define IT66121_CLK_BANK_PWROFF_ACLK BIT(5) ++#define IT66121_CLK_BANK_PWROFF_TXCLK BIT(4) ++#define IT66121_CLK_BANK_PWROFF_CRCLK BIT(3) ++#define IT66121_CLK_BANK_0 0 ++#define IT66121_CLK_BANK_1 1 ++ ++#define IT66121_INT_REG 0x05 ++#define IT66121_INT_ACTIVE_HIGH BIT(7) ++#define IT66121_INT_OPEN_DRAIN BIT(6) ++#define IT66121_INT_TX_CLK_OFF BIT(0) ++ ++#define IT66121_INT_MASK1_REG 0x09 ++#define IT66121_INT_MASK1_AUD_OVF BIT(7) ++#define IT66121_INT_MASK1_DDC_NOACK BIT(5) ++#define IT66121_INT_MASK1_DDC_FIFOERR BIT(4) ++#define IT66121_INT_MASK1_DDC_BUSHANG BIT(2) ++#define IT66121_INT_MASK1_RX_SENS BIT(1) ++#define IT66121_INT_MASK1_HPD BIT(0) ++ ++#define IT66121_INT_CLR1_REG 0x0C ++#define IT66121_INT_CLR1_PKTACP BIT(7) ++#define IT66121_INT_CLR1_PKTNULL BIT(6) ++#define IT66121_INT_CLR1_PKTGEN BIT(5) ++#define IT66121_INT_CLR1_KSVLISTCHK BIT(4) ++#define IT66121_INT_CLR1_AUTHDONE BIT(3) ++#define IT66121_INT_CLR1_AUTHFAIL BIT(2) ++#define IT66121_INT_CLR1_RX_SENS BIT(1) ++#define IT66121_INT_CLR1_HPD BIT(0) ++ ++#define IT66121_AV_MUTE_REG 0xC1 ++#define IT66121_AV_MUTE_ON BIT(0) ++#define IT66121_AV_MUTE_BLUESCR BIT(1) ++ ++#define IT66121_PKT_GEN_CTRL_REG 0xC6 ++#define IT66121_PKT_GEN_CTRL_ON BIT(0) ++#define IT66121_PKT_GEN_CTRL_RPT BIT(1) ++ ++#define IT66121_AVIINFO_DB1_REG 0x158 ++#define IT66121_AVIINFO_DB2_REG 0x159 ++#define IT66121_AVIINFO_DB3_REG 0x15A ++#define IT66121_AVIINFO_DB4_REG 0x15B ++#define IT66121_AVIINFO_DB5_REG 0x15C ++#define IT66121_AVIINFO_CSUM_REG 0x15D ++#define IT66121_AVIINFO_DB6_REG 0x15E ++#define IT66121_AVIINFO_DB7_REG 0x15F ++#define IT66121_AVIINFO_DB8_REG 0x160 ++#define IT66121_AVIINFO_DB9_REG 0x161 ++#define IT66121_AVIINFO_DB10_REG 0x162 ++#define IT66121_AVIINFO_DB11_REG 0x163 ++#define IT66121_AVIINFO_DB12_REG 0x164 ++#define IT66121_AVIINFO_DB13_REG 0x165 ++ ++#define IT66121_AVI_INFO_PKT_REG 0xCD ++#define IT66121_AVI_INFO_PKT_ON BIT(0) ++#define IT66121_AVI_INFO_PKT_RPT BIT(1) ++ ++#define IT66121_HDMI_MODE_REG 0xC0 ++#define IT66121_HDMI_MODE_HDMI BIT(0) ++ ++#define IT66121_SYS_STATUS_REG 0x0E ++#define IT66121_SYS_STATUS_ACTIVE_IRQ BIT(7) ++#define IT66121_SYS_STATUS_HPDETECT BIT(6) ++#define IT66121_SYS_STATUS_SENDECTECT BIT(5) ++#define IT66121_SYS_STATUS_VID_STABLE BIT(4) ++#define IT66121_SYS_STATUS_AUD_CTS_CLR BIT(1) ++#define IT66121_SYS_STATUS_CLEAR_IRQ BIT(0) ++ ++#define IT66121_DDC_STATUS_REG 0x16 ++#define IT66121_DDC_STATUS_TX_DONE BIT(7) ++#define IT66121_DDC_STATUS_ACTIVE BIT(6) ++#define IT66121_DDC_STATUS_NOACK BIT(5) ++#define IT66121_DDC_STATUS_WAIT_BUS BIT(4) ++#define IT66121_DDC_STATUS_ARBI_LOSE BIT(3) ++#define IT66121_DDC_STATUS_FIFO_FULL BIT(2) ++#define IT66121_DDC_STATUS_FIFO_EMPTY BIT(1) ++#define IT66121_DDC_STATUS_FIFO_VALID BIT(0) ++ ++#define IT66121_VENDOR_ID0 0x54 ++#define IT66121_VENDOR_ID1 0x49 ++#define IT66121_DEVICE_ID0 0x12 ++#define IT66121_DEVICE_ID1 0x06 ++#define IT66121_DEVICE_MASK 0x0F ++#define IT66121_EDID_SLEEP 20000 ++#define IT66121_EDID_TIMEOUT 200000 ++#define IT66121_EDID_FIFO_SIZE 32 ++#define IT66121_AFE_CLK_HIGH 80000 ++ ++struct it66121_conf { ++ unsigned int input_mode_reg; ++ unsigned int input_conversion_reg; ++}; ++ ++struct it66121_ctx { ++ struct regmap *regmap; ++ struct drm_bridge bridge; ++ struct drm_connector connector; ++ struct device *dev; ++ struct gpio_desc *gpio_reset; ++ struct i2c_client *client; ++ struct regulator_bulk_data supplies[3]; ++ bool dual_edge; ++ const struct it66121_conf *conf; ++ struct mutex lock; /* Protects fields below and device registers */ ++ struct edid *edid; ++ struct hdmi_avi_infoframe hdmi_avi_infoframe; ++}; ++ ++static const struct regmap_range_cfg it66121_regmap_banks[] = { ++ { ++ .name = "it66121", ++ .range_min = 0x00, ++ .range_max = 0x1FF, ++ .selector_reg = IT66121_CLK_BANK_REG, ++ .selector_mask = 0x1, ++ .selector_shift = 0, ++ .window_start = 0x00, ++ .window_len = 0x130, ++ }, ++}; ++ ++static const struct regmap_config it66121_regmap_config = { ++ .val_bits = 8, ++ .reg_bits = 8, ++ .max_register = 0x1FF, ++ .ranges = it66121_regmap_banks, ++ .num_ranges = ARRAY_SIZE(it66121_regmap_banks), ++}; ++ ++static const struct it66121_conf it66121_conf_simple = { ++ .input_mode_reg = IT66121_INPUT_MODE_RGB | IT66121_INPUT_MODE_DDR, ++ .input_conversion_reg = IT66121_INPUT_CSC_NO_CONV, ++}; ++ ++static void it66121_hw_reset(struct it66121_ctx *ctx) ++{ ++ gpiod_set_value(ctx->gpio_reset, 1); ++ msleep(20); ++ gpiod_set_value(ctx->gpio_reset, 0); ++} ++ ++static int ite66121_power_on(struct it66121_ctx *ctx) ++{ ++ return regulator_bulk_enable(ARRAY_SIZE(ctx->supplies), ctx->supplies); ++} ++ ++static int ite66121_power_off(struct it66121_ctx *ctx) ++{ ++ return regulator_bulk_disable(ARRAY_SIZE(ctx->supplies), ctx->supplies); ++} ++ ++static int it66121_preamble_ddc(struct it66121_ctx *ctx) ++{ ++ return regmap_write(ctx->regmap, IT66121_MASTER_SEL_REG, ++ IT66121_MASTER_SEL_HOST); ++} ++ ++static int it66121_fire_afe(struct it66121_ctx *ctx) ++{ ++ return regmap_write(ctx->regmap, IT66121_AFE_DRV_REG, 0); ++} ++ ++static int it66121_configure_input(struct it66121_ctx *ctx) ++{ ++ int ret; ++ ++ ret = regmap_write(ctx->regmap, IT66121_INPUT_MODE_REG, ++ ctx->conf->input_mode_reg); ++ if (ret) ++ return ret; ++ ++ return regmap_write(ctx->regmap, IT66121_INPUT_CSC_REG, ++ ctx->conf->input_conversion_reg); ++} ++ ++/** ++ * it66121_configure_afe() - Configure the analog front end ++ * @ctx: it66121_ctx object ++ * ++ * RETURNS: ++ * zero if success, a negative error code otherwise. ++ */ ++static int it66121_configure_afe(struct it66121_ctx *ctx, ++ const struct drm_display_mode *mode) ++{ ++ int ret; ++ ++ ret = regmap_write(ctx->regmap, IT66121_AFE_DRV_REG, ++ IT66121_AFE_DRV_RST); ++ if (ret) ++ return ret; ++ ++ if (mode->clock > IT66121_AFE_CLK_HIGH) { ++ ret = regmap_write_bits(ctx->regmap, IT66121_AFE_XP_REG, ++ IT66121_AFE_XP_GAINBIT | ++ IT66121_AFE_XP_ENO, ++ IT66121_AFE_XP_GAINBIT); ++ if (ret) ++ return ret; ++ ++ ret = regmap_write_bits(ctx->regmap, IT66121_AFE_IP_REG, ++ IT66121_AFE_IP_GAINBIT | ++ IT66121_AFE_IP_ER0 | ++ IT66121_AFE_IP_EC1, ++ IT66121_AFE_IP_GAINBIT); ++ if (ret) ++ return ret; ++ ++ ret = regmap_write_bits(ctx->regmap, IT66121_AFE_XP_EC1_REG, ++ IT66121_AFE_XP_EC1_LOWCLK, 0x80); ++ if (ret) ++ return ret; ++ } else { ++ ret = regmap_write_bits(ctx->regmap, IT66121_AFE_XP_REG, ++ IT66121_AFE_XP_GAINBIT | ++ IT66121_AFE_XP_ENO, ++ IT66121_AFE_XP_ENO); ++ if (ret) ++ return ret; ++ ++ ret = regmap_write_bits(ctx->regmap, IT66121_AFE_IP_REG, ++ IT66121_AFE_IP_GAINBIT | ++ IT66121_AFE_IP_ER0 | ++ IT66121_AFE_IP_EC1, IT66121_AFE_IP_ER0 | ++ IT66121_AFE_IP_EC1); ++ if (ret) ++ return ret; ++ ++ ret = regmap_write_bits(ctx->regmap, IT66121_AFE_XP_EC1_REG, ++ IT66121_AFE_XP_EC1_LOWCLK, ++ IT66121_AFE_XP_EC1_LOWCLK); ++ if (ret) ++ return ret; ++ } ++ ++ /* Clear reset flags */ ++ ret = regmap_write_bits(ctx->regmap, IT66121_SW_RST_REG, ++ IT66121_SW_RST_REF | IT66121_SW_RST_VID, ++ ~(IT66121_SW_RST_REF | IT66121_SW_RST_VID) & ++ 0xFF); ++ if (ret) ++ return ret; ++ ++ return it66121_fire_afe(ctx); ++} ++ ++static inline int it66121_wait_ddc_ready(struct it66121_ctx *ctx) ++{ ++ int ret, val; ++ ++ ret = regmap_read_poll_timeout(ctx->regmap, IT66121_DDC_STATUS_REG, ++ val, true, ++ IT66121_EDID_SLEEP, ++ IT66121_EDID_TIMEOUT); ++ if (ret) ++ return ret; ++ ++ if (val & (IT66121_DDC_STATUS_NOACK | IT66121_DDC_STATUS_WAIT_BUS | ++ IT66121_DDC_STATUS_ARBI_LOSE)) ++ return -EAGAIN; ++ ++ return 0; ++} ++ ++static int it66121_clear_ddc_fifo(struct it66121_ctx *ctx) ++{ ++ int ret; ++ ++ ret = it66121_preamble_ddc(ctx); ++ if (ret) ++ return ret; ++ ++ return regmap_write(ctx->regmap, IT66121_DDC_COMMAND_REG, ++ IT66121_DDC_COMMAND_FIFO_CLR); ++} ++ ++static int it66121_abort_ddc_ops(struct it66121_ctx *ctx) ++{ ++ int ret; ++ unsigned int swreset, cpdesire; ++ ++ ret = regmap_read(ctx->regmap, IT66121_SW_RST_REG, &swreset); ++ if (ret) ++ return ret; ++ ++ ret = regmap_read(ctx->regmap, IT66121_HDCP_REG, &cpdesire); ++ if (ret) ++ return ret; ++ ++ ret = regmap_write(ctx->regmap, IT66121_HDCP_REG, ++ cpdesire & (~IT66121_HDCP_CPDESIRED & 0xFF)); ++ if (ret) ++ return ret; ++ ++ ret = regmap_write(ctx->regmap, IT66121_SW_RST_REG, ++ swreset | IT66121_SW_RST_HDCP); ++ if (ret) ++ return ret; ++ ++ ret = it66121_preamble_ddc(ctx); ++ if (ret) ++ return ret; ++ ++ ret = regmap_write(ctx->regmap, IT66121_DDC_COMMAND_REG, ++ IT66121_DDC_COMMAND_ABORT); ++ if (ret) ++ return ret; ++ ++ return it66121_wait_ddc_ready(ctx); ++} ++ ++static int it66121_get_edid_block(void *context, u8 *buf, ++ unsigned int block, size_t len) ++{ ++ struct it66121_ctx *ctx = context; ++ unsigned int val; ++ int remain = len; ++ int offset = 0; ++ int ret, cnt; ++ ++ offset = (block % 2) * len; ++ block = block / 2; ++ ++ ret = regmap_read(ctx->regmap, IT66121_INT_STATUS1_REG, &val); ++ if (ret) ++ return ret; ++ ++ if (val & IT66121_INT_STATUS1_DDC_BUSHANG) { ++ ret = it66121_abort_ddc_ops(ctx); ++ if (ret) ++ return ret; ++ } ++ ++ ret = it66121_clear_ddc_fifo(ctx); ++ if (ret) ++ return ret; ++ ++ while (remain > 0) { ++ cnt = (remain > IT66121_EDID_FIFO_SIZE) ? ++ IT66121_EDID_FIFO_SIZE : remain; ++ ret = it66121_preamble_ddc(ctx); ++ if (ret) ++ return ret; ++ ++ ret = regmap_write(ctx->regmap, IT66121_DDC_COMMAND_REG, ++ IT66121_DDC_COMMAND_FIFO_CLR); ++ if (ret) ++ return ret; ++ ++ ret = it66121_wait_ddc_ready(ctx); ++ if (ret) ++ return ret; ++ ++ ret = regmap_read(ctx->regmap, IT66121_INT_STATUS1_REG, &val); ++ if (ret) ++ return ret; ++ ++ if (val & IT66121_INT_STATUS1_DDC_BUSHANG) { ++ ret = it66121_abort_ddc_ops(ctx); ++ if (ret) ++ return ret; ++ } ++ ++ ret = it66121_preamble_ddc(ctx); ++ if (ret) ++ return ret; ++ ++ ret = regmap_write(ctx->regmap, IT66121_DDC_HEADER_REG, ++ IT66121_DDC_HEADER_EDID); ++ if (ret) ++ return ret; ++ ++ ret = regmap_write(ctx->regmap, IT66121_DDC_OFFSET_REG, offset); ++ if (ret) ++ return ret; ++ ++ ret = regmap_write(ctx->regmap, IT66121_DDC_BYTE_REG, cnt); ++ if (ret) ++ return ret; ++ ++ ret = regmap_write(ctx->regmap, IT66121_DDC_SEGMENT_REG, block); ++ if (ret) ++ return ret; ++ ++ ret = regmap_write(ctx->regmap, IT66121_DDC_COMMAND_REG, ++ IT66121_DDC_COMMAND_EDID_READ); ++ if (ret) ++ return ret; ++ ++ offset += cnt; ++ remain -= cnt; ++ msleep(20); ++ ++ ret = it66121_wait_ddc_ready(ctx); ++ if (ret) ++ return ret; ++ ++ do { ++ ret = regmap_read(ctx->regmap, ++ IT66121_DDC_RD_FIFO_REG, &val); ++ if (ret) ++ return ret; ++ *(buf++) = val; ++ cnt--; ++ } while (cnt > 0); ++ } ++ ++ return 0; ++} ++ ++static int it66121_connector_get_modes(struct drm_connector *connector) ++{ ++ int ret, num_modes = 0; ++ struct it66121_ctx *ctx = container_of(connector, struct it66121_ctx, ++ connector); ++ ++ if (ctx->edid) ++ return drm_add_edid_modes(connector, ctx->edid); ++ ++ mutex_lock(&ctx->lock); ++ ++ ctx->edid = drm_do_get_edid(connector, it66121_get_edid_block, ctx); ++ if (!ctx->edid) { ++ DRM_ERROR("Failed to read EDID\n"); ++ goto unlock; ++ } ++ ++ ret = drm_connector_update_edid_property(connector, ++ ctx->edid); ++ if (ret) { ++ DRM_ERROR("Failed to update EDID property: %d\n", ret); ++ goto unlock; ++ } ++ ++ num_modes = drm_add_edid_modes(connector, ctx->edid); ++ ++unlock: ++ mutex_unlock(&ctx->lock); ++ ++ return num_modes; ++} ++ ++static bool it66121_is_hpd_detect(struct it66121_ctx *ctx) ++{ ++ int val; ++ ++ if (regmap_read(ctx->regmap, IT66121_SYS_STATUS_REG, &val)) ++ return false; ++ ++ return (val & IT66121_SYS_STATUS_HPDETECT); ++} ++ ++static int it66121_connector_detect_ctx(struct drm_connector *connector, ++ struct drm_modeset_acquire_ctx *c, ++ bool force) ++{ ++ struct it66121_ctx *ctx = container_of(connector, struct it66121_ctx, ++ connector); ++ ++ return (it66121_is_hpd_detect(ctx)) ? ++ connector_status_connected : connector_status_disconnected; ++} ++ ++static enum drm_mode_status ++it66121_connector_mode_valid(struct drm_connector *connector, ++ struct drm_display_mode *mode) ++{ ++ unsigned long max_clock; ++ struct it66121_ctx *ctx = container_of(connector, struct it66121_ctx, ++ connector); ++ ++ max_clock = ctx->dual_edge ? 74250 : 148500; ++ ++ if (mode->clock > max_clock) ++ return MODE_CLOCK_HIGH; ++ ++ if (mode->clock < 25000) ++ return MODE_CLOCK_LOW; ++ ++ return MODE_OK; ++} ++ ++static struct drm_connector_helper_funcs it66121_connector_helper_funcs = { ++ .get_modes = it66121_connector_get_modes, ++ .detect_ctx = it66121_connector_detect_ctx, ++ .mode_valid = it66121_connector_mode_valid, ++}; ++ ++static const struct drm_connector_funcs it66121_connector_funcs = { ++ .reset = drm_atomic_helper_connector_reset, ++ .fill_modes = drm_helper_probe_single_connector_modes, ++ .destroy = drm_connector_cleanup, ++ .atomic_duplicate_state = drm_atomic_helper_connector_duplicate_state, ++ .atomic_destroy_state = drm_atomic_helper_connector_destroy_state, ++}; ++ ++static int it66121_bridge_attach(struct drm_bridge *bridge, ++ enum drm_bridge_attach_flags flags) ++{ ++ int ret; ++ struct it66121_ctx *ctx = container_of(bridge, struct it66121_ctx, ++ bridge); ++ ++ if (flags & DRM_BRIDGE_ATTACH_NO_CONNECTOR) { ++ DRM_ERROR("Fix bridge driver to make connector optional!"); ++ return -EINVAL; ++ } ++ ++ if (!bridge->encoder) { ++ DRM_ERROR("Parent encoder object not found"); ++ return -ENODEV; ++ } ++ ++ ret = regmap_write_bits(ctx->regmap, IT66121_CLK_BANK_REG, ++ IT66121_CLK_BANK_PWROFF_RCLK, 0); ++ if (ret) ++ return ret; ++ ++ ret = regmap_write_bits(ctx->regmap, IT66121_INT_REG, ++ IT66121_INT_TX_CLK_OFF, 0); ++ if (ret) ++ return ret; ++ ++ ret = regmap_write_bits(ctx->regmap, IT66121_AFE_DRV_REG, ++ IT66121_AFE_DRV_PWD, 0); ++ if (ret) ++ return ret; ++ ++ ret = regmap_write_bits(ctx->regmap, IT66121_AFE_XP_REG, ++ IT66121_AFE_XP_PWDI | IT66121_AFE_XP_PWDPLL, 0); ++ if (ret) ++ return ret; ++ ++ ret = regmap_write_bits(ctx->regmap, IT66121_AFE_IP_REG, ++ IT66121_AFE_IP_PWDPLL, 0); ++ if (ret) ++ return ret; ++ ++ ret = regmap_write_bits(ctx->regmap, IT66121_AFE_DRV_REG, ++ IT66121_AFE_DRV_RST, 0); ++ if (ret) ++ return ret; ++ ++ ret = regmap_write_bits(ctx->regmap, IT66121_AFE_XP_REG, ++ IT66121_AFE_XP_RESETB, IT66121_AFE_XP_RESETB); ++ if (ret) ++ return ret; ++ ++ ret = regmap_write_bits(ctx->regmap, IT66121_AFE_IP_REG, ++ IT66121_AFE_IP_RESETB, IT66121_AFE_IP_RESETB); ++ if (ret) ++ return ret; ++ ++ ret = regmap_write_bits(ctx->regmap, IT66121_SW_RST_REG, ++ IT66121_SW_RST_REF, ++ IT66121_SW_RST_REF); ++ if (ret) ++ return ret; ++ ++ msleep(50); ++ ++ ret = drm_connector_init(bridge->dev, &ctx->connector, ++ &it66121_connector_funcs, ++ DRM_MODE_CONNECTOR_HDMIA); ++ if (ret) ++ return ret; ++ ++ ctx->connector.polled = DRM_CONNECTOR_POLL_HPD; ++ drm_connector_helper_add(&ctx->connector, ++ &it66121_connector_helper_funcs); ++ ++ ret = drm_connector_attach_encoder(&ctx->connector, bridge->encoder); ++ if (ret) ++ return ret; ++ ++ ret = drm_connector_register(&ctx->connector); ++ if (ret) ++ return ret; ++ ++ /* Start interrupts */ ++ return regmap_write_bits(ctx->regmap, IT66121_INT_MASK1_REG, ++ IT66121_INT_MASK1_DDC_NOACK | ++ IT66121_INT_MASK1_HPD | ++ IT66121_INT_MASK1_DDC_FIFOERR | ++ IT66121_INT_MASK1_DDC_BUSHANG, ++ ~(IT66121_INT_MASK1_DDC_NOACK | ++ IT66121_INT_MASK1_HPD | ++ IT66121_INT_MASK1_DDC_FIFOERR | ++ IT66121_INT_MASK1_DDC_BUSHANG) & 0xFF); ++} ++ ++static int it66121_set_mute(struct it66121_ctx *ctx, bool mute) ++{ ++ int ret; ++ unsigned int val; ++ ++ val = mute ? IT66121_AV_MUTE_ON : (~IT66121_AV_MUTE_ON & 0xFF); ++ ret = regmap_write_bits(ctx->regmap, IT66121_AV_MUTE_REG, ++ IT66121_AV_MUTE_ON, val); ++ if (ret) ++ return ret; ++ ++ return regmap_write(ctx->regmap, IT66121_PKT_GEN_CTRL_REG, ++ IT66121_PKT_GEN_CTRL_ON | ++ IT66121_PKT_GEN_CTRL_RPT); ++} ++ ++static void it66121_bridge_enable(struct drm_bridge *bridge) ++{ ++ struct it66121_ctx *ctx = container_of(bridge, struct it66121_ctx, ++ bridge); ++ ++ it66121_set_mute(ctx, false); ++} ++ ++static void it66121_bridge_disable(struct drm_bridge *bridge) ++{ ++ struct it66121_ctx *ctx = container_of(bridge, struct it66121_ctx, ++ bridge); ++ ++ it66121_set_mute(ctx, true); ++} ++ ++static ++void it66121_bridge_mode_set(struct drm_bridge *bridge, ++ const struct drm_display_mode *mode, ++ const struct drm_display_mode *adjusted_mode) ++{ ++ int ret, i; ++ u8 buf[HDMI_INFOFRAME_SIZE(AVI)]; ++ struct it66121_ctx *ctx = container_of(bridge, struct it66121_ctx, ++ bridge); ++ const u16 aviinfo_reg[HDMI_AVI_INFOFRAME_SIZE] = { ++ IT66121_AVIINFO_DB1_REG, ++ IT66121_AVIINFO_DB2_REG, ++ IT66121_AVIINFO_DB3_REG, ++ IT66121_AVIINFO_DB4_REG, ++ IT66121_AVIINFO_DB5_REG, ++ IT66121_AVIINFO_DB6_REG, ++ IT66121_AVIINFO_DB7_REG, ++ IT66121_AVIINFO_DB8_REG, ++ IT66121_AVIINFO_DB9_REG, ++ IT66121_AVIINFO_DB10_REG, ++ IT66121_AVIINFO_DB11_REG, ++ IT66121_AVIINFO_DB12_REG, ++ IT66121_AVIINFO_DB13_REG ++ }; ++ ++ mutex_lock(&ctx->lock); ++ ++ hdmi_avi_infoframe_init(&ctx->hdmi_avi_infoframe); ++ ++ ret = drm_hdmi_avi_infoframe_from_display_mode(&ctx->hdmi_avi_infoframe, ++ &ctx->connector, ++ adjusted_mode); ++ if (ret) { ++ DRM_ERROR("Failed to setup AVI infoframe: %d\n", ret); ++ goto unlock; ++ } ++ ++ ret = hdmi_avi_infoframe_pack(&ctx->hdmi_avi_infoframe, buf, ++ sizeof(buf)); ++ if (ret < 0) { ++ DRM_ERROR("Failed to pack infoframe: %d\n", ret); ++ goto unlock; ++ } ++ ++ /* Write new AVI infoframe packet */ ++ for (i = 0; i < HDMI_AVI_INFOFRAME_SIZE; i++) { ++ if (regmap_write(ctx->regmap, aviinfo_reg[i], ++ buf[i + HDMI_INFOFRAME_HEADER_SIZE])) ++ goto unlock; ++ } ++ if (regmap_write(ctx->regmap, IT66121_AVIINFO_CSUM_REG, buf[3])) ++ goto unlock; ++ ++ /* Enable AVI infoframe */ ++ if (regmap_write(ctx->regmap, IT66121_AVI_INFO_PKT_REG, ++ IT66121_AVI_INFO_PKT_ON | ++ IT66121_AVI_INFO_PKT_RPT)) ++ goto unlock; ++ ++ /* Set TX mode to HDMI */ ++ if (regmap_write(ctx->regmap, IT66121_HDMI_MODE_REG, ++ IT66121_HDMI_MODE_HDMI)) ++ goto unlock; ++ ++ if (regmap_write_bits(ctx->regmap, IT66121_CLK_BANK_REG, ++ IT66121_CLK_BANK_PWROFF_TXCLK, ++ IT66121_CLK_BANK_PWROFF_TXCLK)) ++ goto unlock; ++ ++ if (it66121_configure_input(ctx)) ++ goto unlock; ++ ++ if (it66121_configure_afe(ctx, adjusted_mode)) ++ goto unlock; ++ ++ regmap_write_bits(ctx->regmap, IT66121_CLK_BANK_REG, ++ IT66121_CLK_BANK_PWROFF_TXCLK, ++ ~IT66121_CLK_BANK_PWROFF_TXCLK & 0xFF); ++ ++unlock: ++ mutex_unlock(&ctx->lock); ++} ++ ++static const struct drm_bridge_funcs it66121_bridge_funcs = { ++ .attach = it66121_bridge_attach, ++ .enable = it66121_bridge_enable, ++ .disable = it66121_bridge_disable, ++ .mode_set = it66121_bridge_mode_set, ++}; ++ ++static irqreturn_t it66121_irq_threaded_handler(int irq, void *dev_id) ++{ ++ int ret; ++ unsigned int val; ++ struct it66121_ctx *ctx = dev_id; ++ struct device *dev = ctx->dev; ++ bool event = false; ++ ++ mutex_lock(&ctx->lock); ++ ++ ret = regmap_read(ctx->regmap, IT66121_SYS_STATUS_REG, &val); ++ if (ret) ++ goto unlock; ++ ++ if (val & IT66121_SYS_STATUS_ACTIVE_IRQ) { ++ ret = regmap_read(ctx->regmap, IT66121_INT_STATUS1_REG, &val); ++ if (ret) { ++ dev_err(dev, "Cannot read STATUS1_REG %d\n", ret); ++ } else { ++ if (val & IT66121_INT_STATUS1_DDC_FIFOERR) ++ it66121_clear_ddc_fifo(ctx); ++ if (val & (IT66121_INT_STATUS1_DDC_BUSHANG | ++ IT66121_INT_STATUS1_DDC_NOACK)) ++ it66121_abort_ddc_ops(ctx); ++ if (val & IT66121_INT_STATUS1_HPD_STATUS) { ++ regmap_write_bits(ctx->regmap, ++ IT66121_INT_CLR1_REG, ++ IT66121_INT_CLR1_HPD, ++ IT66121_INT_CLR1_HPD); ++ ++ if (!it66121_is_hpd_detect(ctx)) { ++ kfree(ctx->edid); ++ ctx->edid = NULL; ++ } ++ event = true; ++ } ++ } ++ ++ regmap_write_bits(ctx->regmap, IT66121_SYS_STATUS_REG, ++ IT66121_SYS_STATUS_CLEAR_IRQ, ++ IT66121_SYS_STATUS_CLEAR_IRQ); ++ } ++ ++unlock: ++ mutex_unlock(&ctx->lock); ++ ++ if (event) ++ drm_helper_hpd_irq_event(ctx->bridge.dev); ++ ++ return IRQ_HANDLED; ++} ++ ++static int it66121_probe(struct i2c_client *client, ++ const struct i2c_device_id *id) ++{ ++ u8 ids[4]; ++ int i, ret; ++ struct it66121_ctx *ctx; ++ struct device *dev = &client->dev; ++ ++ if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C)) { ++ dev_err(dev, "I2C check functionality failed.\n"); ++ return -ENXIO; ++ } ++ ++ ctx = devm_kzalloc(dev, sizeof(*ctx), GFP_KERNEL); ++ if (!ctx) ++ return -ENOMEM; ++ ++ ctx->dev = dev; ++ ctx->client = client; ++ i2c_set_clientdata(client, ctx); ++ mutex_init(&ctx->lock); ++ ctx->conf = (struct it66121_conf *)of_device_get_match_data(dev); ++ if (!ctx->conf) ++ return -ENODEV; ++ ++ ctx->supplies[0].supply = "vcn33"; ++ ctx->supplies[1].supply = "vcn18"; ++ ctx->supplies[2].supply = "vrf12"; ++ ret = devm_regulator_bulk_get(ctx->dev, 3, ctx->supplies); ++ if (ret) { ++ dev_err(ctx->dev, "regulator_bulk failed\n"); ++ return ret; ++ } ++ ++ ctx->dual_edge = of_property_read_bool(dev->of_node, "pclk-dual-edge"); ++ ++ ret = ite66121_power_on(ctx); ++ if (ret) ++ return ret; ++ ++ it66121_hw_reset(ctx); ++ ++ ctx->regmap = devm_regmap_init_i2c(client, &it66121_regmap_config); ++ if (IS_ERR(ctx->regmap)) { ++ ite66121_power_off(ctx); ++ return PTR_ERR(ctx); ++ } ++ ++ for (i = 0; i < 4; i++) { ++ regmap_read(ctx->regmap, i, &ret); ++ ids[i] = ret; ++ } ++ ++ if (ids[0] != IT66121_VENDOR_ID0 || ++ ids[1] != IT66121_VENDOR_ID1 || ++ ids[2] != IT66121_DEVICE_ID0 || ++ ((ids[3] & IT66121_DEVICE_MASK) != IT66121_DEVICE_ID1)) { ++ ite66121_power_off(ctx); ++ return -ENODEV; ++ } ++ ++ ctx->bridge.funcs = &it66121_bridge_funcs; ++ ctx->bridge.of_node = dev->of_node; ++ ++ ret = devm_request_threaded_irq(dev, client->irq, NULL, ++ it66121_irq_threaded_handler, ++ IRQF_SHARED | IRQF_TRIGGER_LOW | ++ IRQF_ONESHOT, ++ dev_name(dev), ++ ctx); ++ if (ret < 0) { ++ dev_err(dev, "Failed to request irq %d:%d\n", client->irq, ret); ++ ite66121_power_off(ctx); ++ return ret; ++ } ++ ++ drm_bridge_add(&ctx->bridge); ++ ++ return 0; ++} ++ ++static int it66121_remove(struct i2c_client *client) ++{ ++ struct it66121_ctx *ctx = i2c_get_clientdata(client); ++ ++ ite66121_power_off(ctx); ++ drm_bridge_remove(&ctx->bridge); ++ kfree(ctx->edid); ++ mutex_destroy(&ctx->lock); ++ ++ return 0; ++} ++ ++static const struct of_device_id it66121_dt_match[] = { ++ { .compatible = "ite,it66121", ++ .data = &it66121_conf_simple, ++ }, ++ { }, ++}; ++MODULE_DEVICE_TABLE(of, it66121_dt_match); ++ ++static const struct i2c_device_id it66121_id[] = { ++ { "it66121", 0 }, ++ { }, ++}; ++MODULE_DEVICE_TABLE(i2c, it66121_id); ++ ++static struct i2c_driver it66121_driver = { ++ .driver = { ++ .name = "it66121", ++ .of_match_table = it66121_dt_match, ++ }, ++ .probe = it66121_probe, ++ .remove = it66121_remove, ++ .id_table = it66121_id, ++}; ++ ++module_i2c_driver(it66121_driver); ++ ++MODULE_AUTHOR("Phong LE"); ++MODULE_DESCRIPTION("IT66121 HDMI transmitter driver"); ++MODULE_LICENSE("GPL v2"); + +From 0298604c589cd54e3680e957c20c23892a1d3621 Mon Sep 17 00:00:00 2001 +From: Phong LE +Date: Wed, 11 Mar 2020 13:51:35 +0100 +Subject: [PATCH] MAINTAINERS: add it66121 HDMI bridge driver entry + +Add Neil Armstrong and myself as maintainers + +Signed-off-by: Phong LE +--- + MAINTAINERS | 8 ++++++++ + 1 file changed, 8 insertions(+) + +diff --git a/MAINTAINERS b/MAINTAINERS +index af53d0c45407..cfe65317b19f 100644 +--- a/MAINTAINERS ++++ b/MAINTAINERS +@@ -9369,6 +9369,14 @@ Q: http://patchwork.linuxtv.org/project/linux-media/list/ + T: git git://linuxtv.org/anttip/media_tree.git + F: drivers/media/tuners/it913x* + ++ITE IT66121 HDMI BRIDGE DRIVER ++M: Phong LE ++M: Neil Armstrong ++S: Maintained ++F: drivers/gpu/drm/bridge/ite-it66121.c ++T: git git://anongit.freedesktop.org/drm/drm-misc ++F: Documentation/devicetree/bindings/display/bridge/ite,it66121.yaml ++ + IVTV VIDEO4LINUX DRIVER + M: Andy Walls + L: linux-media@vger.kernel.org diff --git a/patch/kernel/rk322x-current/01-linux-1001-rockchip-soc-wip.patch b/patch/kernel/rk322x-current/01-linux-1000-rockchip-wip.patch similarity index 59% rename from patch/kernel/rk322x-current/01-linux-1001-rockchip-soc-wip.patch rename to patch/kernel/rk322x-current/01-linux-1000-rockchip-wip.patch index 0cbf1ced8..8bf3720d9 100644 --- a/patch/kernel/rk322x-current/01-linux-1001-rockchip-soc-wip.patch +++ b/patch/kernel/rk322x-current/01-linux-1000-rockchip-wip.patch @@ -1,4 +1,4 @@ -From 8eafcb00f736dbf25623e30f48a971c77efc839d Mon Sep 17 00:00:00 2001 +From 4707a7fe2103b7600b2ca6097ce9d12bda37d4cf Mon Sep 17 00:00:00 2001 From: Finley Xiao Date: Thu, 22 Jun 2017 20:22:25 +0800 Subject: [PATCH] clk: rockchip: rk3228: fix some PLL_NUX_CLKs' gates @@ -9,11 +9,11 @@ so move the gates to composite clocks and amend their parent clocks. Change-Id: Ib6043caa61e9df0473f2d0bdc756850968bb2a55 Signed-off-by: Finley Xiao --- - drivers/clk/rockchip/clk-rk3228.c | 53 ++++++++----------------------- - 1 file changed, 14 insertions(+), 39 deletions(-) + drivers/clk/rockchip/clk-rk3228.c | 49 ++++++++++--------------------- + 1 file changed, 15 insertions(+), 34 deletions(-) diff --git a/drivers/clk/rockchip/clk-rk3228.c b/drivers/clk/rockchip/clk-rk3228.c -index c1ef00247e26..1f1909b50eb4 100644 +index c1ef00247e26..6da33172c6ba 100644 --- a/drivers/clk/rockchip/clk-rk3228.c +++ b/drivers/clk/rockchip/clk-rk3228.c @@ -134,24 +134,22 @@ static const struct rockchip_cpuclk_reg_data rk3228_cpuclk_data = { @@ -21,9 +21,8 @@ index c1ef00247e26..1f1909b50eb4 100644 PNAME(mux_pll_p) = { "clk_24m", "xin24m" }; -PNAME(mux_ddrphy_p) = { "dpll_ddr", "gpll_ddr", "apll_ddr" }; --PNAME(mux_armclk_p) = { "apll_core", "gpll_core", "dpll_core" }; +PNAME(mux_ddrphy_p) = { "dpll", "gpll", "apll" }; -+PNAME(mux_armclk_p) = { "apll", "gpll", "dpll" }; + PNAME(mux_armclk_p) = { "apll_core", "gpll_core", "dpll_core" }; PNAME(mux_usb480m_phy_p) = { "usb480m_phy0", "usb480m_phy1" }; PNAME(mux_usb480m_p) = { "usb480m_phy", "xin24m" }; PNAME(mux_hdmiphy_p) = { "hdmiphy_phy", "xin24m" }; @@ -44,7 +43,7 @@ index c1ef00247e26..1f1909b50eb4 100644 PNAME(mux_dclk_vop_p) = { "hdmiphy", "sclk_vop_pre" }; PNAME(mux_i2s0_p) = { "i2s0_src", "i2s0_frac", "ext_i2s", "xin12m" }; -@@ -220,27 +218,17 @@ static struct rockchip_clk_branch rk3228_clk_branches[] __initdata = { +@@ -220,27 +218,23 @@ static struct rockchip_clk_branch rk3228_clk_branches[] __initdata = { RK2928_CLKSEL_CON(4), 8, 5, DFLAGS), /* PD_DDR */ @@ -70,40 +69,42 @@ index c1ef00247e26..1f1909b50eb4 100644 /* PD_CORE */ - GATE(0, "dpll_core", "dpll", CLK_IGNORE_UNUSED, - RK2928_CLKGATE_CON(0), 6, GFLAGS), -- GATE(0, "apll_core", "apll", CLK_IGNORE_UNUSED, -- RK2928_CLKGATE_CON(0), 6, GFLAGS), -- GATE(0, "gpll_core", "gpll", CLK_IGNORE_UNUSED, -- RK2928_CLKGATE_CON(0), 6, GFLAGS), + GATE(0, "apll_core", "apll", CLK_IGNORE_UNUSED, + RK2928_CLKGATE_CON(0), 6, GFLAGS), + GATE(0, "gpll_core", "gpll", CLK_IGNORE_UNUSED, + RK2928_CLKGATE_CON(0), 6, GFLAGS), ++ GATE(0, "dpll_core", "dpll", CLK_IGNORE_UNUSED, ++ RK2928_CLKGATE_CON(0), 6, GFLAGS), COMPOSITE_NOMUX(0, "pclk_dbg", "armclk", CLK_IGNORE_UNUSED, RK2928_CLKSEL_CON(1), 0, 4, DFLAGS | CLK_DIVIDER_READ_ONLY, RK2928_CLKGATE_CON(4), 1, GFLAGS), -@@ -257,14 +245,9 @@ static struct rockchip_clk_branch rk3228_clk_branches[] __initdata = { +@@ -257,14 +251,9 @@ static struct rockchip_clk_branch rk3228_clk_branches[] __initdata = { RK2928_MISC_CON, 15, 1, MFLAGS), /* PD_BUS */ - GATE(0, "hdmiphy_aclk_cpu", "hdmiphy", CLK_IGNORE_UNUSED, -- RK2928_CLKGATE_CON(0), 1, GFLAGS), -- GATE(0, "gpll_aclk_cpu", "gpll", CLK_IGNORE_UNUSED, -- RK2928_CLKGATE_CON(0), 1, GFLAGS), -- GATE(0, "cpll_aclk_cpu", "cpll", CLK_IGNORE_UNUSED, + COMPOSITE(0, "aclk_cpu_src", mux_pll_src_3plls_p, 0, + RK2928_CLKSEL_CON(0), 13, 2, MFLAGS, 8, 5, DFLAGS, RK2928_CLKGATE_CON(0), 1, GFLAGS), +- GATE(0, "gpll_aclk_cpu", "gpll", CLK_IGNORE_UNUSED, +- RK2928_CLKGATE_CON(0), 1, GFLAGS), +- GATE(0, "cpll_aclk_cpu", "cpll", CLK_IGNORE_UNUSED, +- RK2928_CLKGATE_CON(0), 1, GFLAGS), - COMPOSITE_NOGATE(0, "aclk_cpu_src", mux_aclk_cpu_src_p, 0, - RK2928_CLKSEL_CON(0), 13, 2, MFLAGS, 8, 5, DFLAGS), GATE(ACLK_CPU, "aclk_cpu", "aclk_cpu_src", 0, RK2928_CLKGATE_CON(6), 0, GFLAGS), COMPOSITE_NOMUX(HCLK_CPU, "hclk_cpu", "aclk_cpu_src", 0, -@@ -337,14 +320,9 @@ static struct rockchip_clk_branch rk3228_clk_branches[] __initdata = { +@@ -337,14 +326,9 @@ static struct rockchip_clk_branch rk3228_clk_branches[] __initdata = { RK2928_CLKGATE_CON(3), 8, GFLAGS), /* PD_PERI */ - GATE(0, "cpll_peri", "cpll", CLK_IGNORE_UNUSED, +- RK2928_CLKGATE_CON(2), 0, GFLAGS), +- GATE(0, "gpll_peri", "gpll", CLK_IGNORE_UNUSED, + COMPOSITE(0, "aclk_peri_src", mux_pll_src_3plls_p, 0, + RK2928_CLKSEL_CON(10), 10, 2, MFLAGS, 0, 5, DFLAGS, RK2928_CLKGATE_CON(2), 0, GFLAGS), -- GATE(0, "gpll_peri", "gpll", CLK_IGNORE_UNUSED, -- RK2928_CLKGATE_CON(2), 0, GFLAGS), - GATE(0, "hdmiphy_peri", "hdmiphy", CLK_IGNORE_UNUSED, - RK2928_CLKGATE_CON(2), 0, GFLAGS), - COMPOSITE_NOGATE(0, "aclk_peri_src", mux_aclk_peri_src_p, 0, @@ -111,7 +112,7 @@ index c1ef00247e26..1f1909b50eb4 100644 COMPOSITE_NOMUX(PCLK_PERI, "pclk_peri", "aclk_peri_src", 0, RK2928_CLKSEL_CON(10), 12, 3, DFLAGS, RK2928_CLKGATE_CON(5), 2, GFLAGS), -@@ -402,12 +380,9 @@ static struct rockchip_clk_branch rk3228_clk_branches[] __initdata = { +@@ -402,12 +386,9 @@ static struct rockchip_clk_branch rk3228_clk_branches[] __initdata = { * Clock-Architecture Diagram 2 */ @@ -127,7 +128,7 @@ index c1ef00247e26..1f1909b50eb4 100644 RK2928_CLKSEL_CON(29), 0, 3, DFLAGS), DIV(0, "sclk_vop_pre", "sclk_vop_src", 0, -From 41f643b812d3f16f7e2790c2fd709e9d122745e9 Mon Sep 17 00:00:00 2001 +From d575c876e7f19e1699471d88edfe8d1874f6dd21 Mon Sep 17 00:00:00 2001 From: Finley Xiao Date: Sun, 18 Mar 2018 21:41:43 +0800 Subject: [PATCH] clk: rockchip: rk3228: Fix sclk_wifi div_width @@ -139,10 +140,10 @@ Signed-off-by: Finley Xiao 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/clk/rockchip/clk-rk3228.c b/drivers/clk/rockchip/clk-rk3228.c -index 1f1909b50eb4..630041b2e005 100644 +index 6da33172c6ba..d59e619425b6 100644 --- a/drivers/clk/rockchip/clk-rk3228.c +++ b/drivers/clk/rockchip/clk-rk3228.c -@@ -357,7 +357,7 @@ static struct rockchip_clk_branch rk3228_clk_branches[] __initdata = { +@@ -363,7 +363,7 @@ static struct rockchip_clk_branch rk3228_clk_branches[] __initdata = { RK2928_CLKGATE_CON(10), 12, GFLAGS), COMPOSITE(SCLK_WIFI, "sclk_wifi", mux_pll_src_cpll_gpll_usb480m_p, 0, @@ -152,7 +153,7 @@ index 1f1909b50eb4..630041b2e005 100644 COMPOSITE(SCLK_SDMMC, "sclk_sdmmc", mux_mmc_src_p, 0, -From a07ecf7850119b84778c2443c71322795f3bbd12 Mon Sep 17 00:00:00 2001 +From 13db1588f0807f2d0569a45b93d6597280e105f6 Mon Sep 17 00:00:00 2001 From: Chen Lei Date: Tue, 25 Dec 2018 18:29:04 +0800 Subject: [PATCH] clk: rockchip: rk322x: fix wrong mmc phase shift for rk3228 @@ -167,10 +168,10 @@ Signed-off-by: Chen Lei 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/clk/rockchip/clk-rk3228.c b/drivers/clk/rockchip/clk-rk3228.c -index 630041b2e005..64de0759e0ed 100644 +index d59e619425b6..9c5ad7c71143 100644 --- a/drivers/clk/rockchip/clk-rk3228.c +++ b/drivers/clk/rockchip/clk-rk3228.c -@@ -614,13 +614,13 @@ static struct rockchip_clk_branch rk3228_clk_branches[] __initdata = { +@@ -620,13 +620,13 @@ static struct rockchip_clk_branch rk3228_clk_branches[] __initdata = { /* PD_MMC */ MMC(SCLK_SDMMC_DRV, "sdmmc_drv", "sclk_sdmmc", RK3228_SDMMC_CON0, 1), @@ -188,248 +189,41 @@ index 630041b2e005..64de0759e0ed 100644 static const char *const rk3228_critical_clocks[] __initconst = { -From 4f9a8b2a8cb0d695317922204d6ed7aa0d718084 Mon Sep 17 00:00:00 2001 -From: Finley Xiao -Date: Mon, 5 Feb 2018 10:04:15 +0800 -Subject: [PATCH] clk: rockchip: rk3228: Fix armclk parent - -Change-Id: I09830d96b37cca600f1782b9013b25e043467f97 -Signed-off-by: Finley Xiao ---- - drivers/clk/rockchip/clk-rk3228.c | 8 +++++++- - 1 file changed, 7 insertions(+), 1 deletion(-) - -diff --git a/drivers/clk/rockchip/clk-rk3228.c b/drivers/clk/rockchip/clk-rk3228.c -index 64de0759e0ed..17dfa40b12d5 100644 ---- a/drivers/clk/rockchip/clk-rk3228.c -+++ b/drivers/clk/rockchip/clk-rk3228.c -@@ -135,7 +135,7 @@ static const struct rockchip_cpuclk_reg_data rk3228_cpuclk_data = { - PNAME(mux_pll_p) = { "clk_24m", "xin24m" }; - - PNAME(mux_ddrphy_p) = { "dpll", "gpll", "apll" }; --PNAME(mux_armclk_p) = { "apll", "gpll", "dpll" }; -+PNAME(mux_armclk_p) = { "apll_core", "gpll_core", "dpll_core" }; - PNAME(mux_usb480m_phy_p) = { "usb480m_phy0", "usb480m_phy1" }; - PNAME(mux_usb480m_p) = { "usb480m_phy", "xin24m" }; - PNAME(mux_hdmiphy_p) = { "hdmiphy_phy", "xin24m" }; -@@ -229,6 +229,12 @@ static struct rockchip_clk_branch rk3228_clk_branches[] __initdata = { - RK2928_CLKGATE_CON(7), 0, GFLAGS), - - /* PD_CORE */ -+ GATE(0, "apll_core", "apll", CLK_IGNORE_UNUSED, -+ PX30_CLKGATE_CON(0), 6, GFLAGS), -+ GATE(0, "gpll_core", "gpll", CLK_IGNORE_UNUSED, -+ PX30_CLKGATE_CON(0), 6, GFLAGS), -+ GATE(0, "dpll_core", "dpll", CLK_IGNORE_UNUSED, -+ PX30_CLKGATE_CON(0), 6, GFLAGS), - COMPOSITE_NOMUX(0, "pclk_dbg", "armclk", CLK_IGNORE_UNUSED, - RK2928_CLKSEL_CON(1), 0, 4, DFLAGS | CLK_DIVIDER_READ_ONLY, - RK2928_CLKGATE_CON(4), 1, GFLAGS), - -From 522349f18db37193b1748631c229ccbf5a2380c1 Mon Sep 17 00:00:00 2001 -From: Finley Xiao -Date: Sun, 18 Mar 2018 21:42:22 +0800 -Subject: [PATCH] clk: rockchip: rk3228: remove the flag ROCKCHIP_PLL_SYNC_RATE - for GPLL - -To slove the display shaking, when uboot logo display to kernel show. - -Change-Id: Ifc97f72df27b4e8dbcd34ab8ed65ac027fd424d1 -Signed-off-by: Finley Xiao ---- - 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 17dfa40b12d5..3b18460d086b 100644 ---- a/drivers/clk/rockchip/clk-rk3228.c -+++ b/drivers/clk/rockchip/clk-rk3228.c -@@ -174,7 +174,7 @@ static struct rockchip_pll_clock rk3228_pll_clks[] __initdata = { - [cpll] = PLL(pll_rk3036, PLL_CPLL, "cpll", mux_pll_p, 0, RK2928_PLL_CON(6), - RK2928_MODE_CON, 8, 8, 0, NULL), - [gpll] = PLL(pll_rk3036, PLL_GPLL, "gpll", mux_pll_p, 0, RK2928_PLL_CON(9), -- RK2928_MODE_CON, 12, 9, ROCKCHIP_PLL_SYNC_RATE, rk3228_pll_rates), -+ RK2928_MODE_CON, 12, 9, 0, rk3228_pll_rates), - }; - - #define MFLAGS CLK_MUX_HIWORD_MASK - -From e965e7133455d753738ef732a4da0f196ff09495 Mon Sep 17 00:00:00 2001 -From: Elaine Zhang -Date: Tue, 25 Dec 2018 14:58:30 +0800 -Subject: [PATCH] clk: rockchip: rk322x: fix up the gate con description error - -Change-Id: I439314c590a7144fab6e33d1fb4f325530669842 -Signed-off-by: Elaine Zhang ---- - drivers/clk/rockchip/clk-rk3228.c | 6 +++--- - 1 file changed, 3 insertions(+), 3 deletions(-) - -diff --git a/drivers/clk/rockchip/clk-rk3228.c b/drivers/clk/rockchip/clk-rk3228.c -index 3b18460d086b..bc3996733afe 100644 ---- a/drivers/clk/rockchip/clk-rk3228.c -+++ b/drivers/clk/rockchip/clk-rk3228.c -@@ -230,11 +230,11 @@ static struct rockchip_clk_branch rk3228_clk_branches[] __initdata = { - - /* PD_CORE */ - GATE(0, "apll_core", "apll", CLK_IGNORE_UNUSED, -- PX30_CLKGATE_CON(0), 6, GFLAGS), -+ RK2928_CLKGATE_CON(0), 6, GFLAGS), - GATE(0, "gpll_core", "gpll", CLK_IGNORE_UNUSED, -- PX30_CLKGATE_CON(0), 6, GFLAGS), -+ RK2928_CLKGATE_CON(0), 6, GFLAGS), - GATE(0, "dpll_core", "dpll", CLK_IGNORE_UNUSED, -- PX30_CLKGATE_CON(0), 6, GFLAGS), -+ RK2928_CLKGATE_CON(0), 6, GFLAGS), - COMPOSITE_NOMUX(0, "pclk_dbg", "armclk", CLK_IGNORE_UNUSED, - RK2928_CLKSEL_CON(1), 0, 4, DFLAGS | CLK_DIVIDER_READ_ONLY, - RK2928_CLKGATE_CON(4), 1, GFLAGS), - -From 557f7fcc53e123be9204b49383f98eacd7855d41 Mon Sep 17 00:00:00 2001 +From 8b9b8802556c4f7ce09699a4a85e19143de43c44 Mon Sep 17 00:00:00 2001 From: Alex Bee -Date: Sun, 16 Aug 2020 16:52:03 +0200 -Subject: [PATCH] clk: rockchip: add CLOCK_IGNORE_UNUSED to serval RK3228 clks +Date: Mon, 14 Dec 2020 21:05:15 +0100 +Subject: [PATCH] clk: rockchip: add *_vio_h2p to RK3228's critical clocks -Some clocks need the CLOCK_IGNORE_UNUSED flag in order to be prevented from being -disabled at boot time and to get respective devices working. -Has been taken from vendor kernel. +These are required in order to read the HDMI edid and must not +get disabled in order to successfully do so. + +Signed-off-by: Alex Bee --- - drivers/clk/rockchip/clk-rk3228.c | 58 +++++++++++++++---------------- - 1 file changed, 29 insertions(+), 29 deletions(-) + drivers/clk/rockchip/clk-rk3228.c | 2 ++ + 1 file changed, 2 insertions(+) diff --git a/drivers/clk/rockchip/clk-rk3228.c b/drivers/clk/rockchip/clk-rk3228.c -index bc3996733afe..bfcb64e90d00 100644 +index 9c5ad7c71143..4b2aca6b1f11 100644 --- a/drivers/clk/rockchip/clk-rk3228.c +++ b/drivers/clk/rockchip/clk-rk3228.c -@@ -514,12 +514,12 @@ static struct rockchip_clk_branch rk3228_clk_branches[] __initdata = { - - /* PD_VOP */ - GATE(ACLK_RGA, "aclk_rga", "aclk_rga_pre", 0, RK2928_CLKGATE_CON(13), 0, GFLAGS), -- GATE(0, "aclk_rga_noc", "aclk_rga_pre", 0, RK2928_CLKGATE_CON(13), 11, GFLAGS), -+ GATE(0, "aclk_rga_noc", "aclk_rga_pre", CLK_IGNORE_UNUSED, RK2928_CLKGATE_CON(13), 11, GFLAGS), - GATE(ACLK_IEP, "aclk_iep", "aclk_iep_pre", 0, RK2928_CLKGATE_CON(13), 2, GFLAGS), -- GATE(0, "aclk_iep_noc", "aclk_iep_pre", 0, RK2928_CLKGATE_CON(13), 9, GFLAGS), -+ GATE(0, "aclk_iep_noc", "aclk_iep_pre", CLK_IGNORE_UNUSED, RK2928_CLKGATE_CON(13), 9, GFLAGS), - - GATE(ACLK_VOP, "aclk_vop", "aclk_vop_pre", 0, RK2928_CLKGATE_CON(13), 5, GFLAGS), -- GATE(0, "aclk_vop_noc", "aclk_vop_pre", 0, RK2928_CLKGATE_CON(13), 12, GFLAGS), -+ GATE(0, "aclk_vop_noc", "aclk_vop_pre", CLK_IGNORE_UNUSED, RK2928_CLKGATE_CON(13), 12, GFLAGS), - - GATE(ACLK_HDCP, "aclk_hdcp", "aclk_hdcp_pre", 0, RK2928_CLKGATE_CON(14), 10, GFLAGS), - GATE(0, "aclk_hdcp_noc", "aclk_hdcp_pre", 0, RK2928_CLKGATE_CON(13), 10, GFLAGS), -@@ -527,13 +527,13 @@ static struct rockchip_clk_branch rk3228_clk_branches[] __initdata = { - GATE(HCLK_RGA, "hclk_rga", "hclk_vio_pre", 0, RK2928_CLKGATE_CON(13), 1, GFLAGS), - GATE(HCLK_IEP, "hclk_iep", "hclk_vio_pre", 0, RK2928_CLKGATE_CON(13), 3, GFLAGS), - GATE(HCLK_VOP, "hclk_vop", "hclk_vio_pre", 0, RK2928_CLKGATE_CON(13), 6, GFLAGS), -- GATE(0, "hclk_vio_ahb_arbi", "hclk_vio_pre", 0, RK2928_CLKGATE_CON(13), 7, GFLAGS), -- GATE(0, "hclk_vio_noc", "hclk_vio_pre", 0, RK2928_CLKGATE_CON(13), 8, GFLAGS), -- GATE(0, "hclk_vop_noc", "hclk_vio_pre", 0, RK2928_CLKGATE_CON(13), 13, GFLAGS), -- GATE(HCLK_VIO_H2P, "hclk_vio_h2p", "hclk_vio_pre", 0, RK2928_CLKGATE_CON(14), 7, GFLAGS), -+ GATE(0, "hclk_vio_ahb_arbi", "hclk_vio_pre", CLK_IGNORE_UNUSED, RK2928_CLKGATE_CON(13), 7, GFLAGS), -+ GATE(0, "hclk_vio_noc", "hclk_vio_pre", CLK_IGNORE_UNUSED, RK2928_CLKGATE_CON(13), 8, GFLAGS), -+ GATE(0, "hclk_vop_noc", "hclk_vio_pre", CLK_IGNORE_UNUSED, RK2928_CLKGATE_CON(13), 13, GFLAGS), -+ GATE(HCLK_VIO_H2P, "hclk_vio_h2p", "hclk_vio_pre", CLK_IGNORE_UNUSED, RK2928_CLKGATE_CON(14), 7, GFLAGS), - GATE(HCLK_HDCP_MMU, "hclk_hdcp_mmu", "hclk_vio_pre", 0, RK2928_CLKGATE_CON(14), 12, GFLAGS), - GATE(PCLK_HDMI_CTRL, "pclk_hdmi_ctrl", "hclk_vio_pre", 0, RK2928_CLKGATE_CON(14), 6, GFLAGS), -- GATE(PCLK_VIO_H2P, "pclk_vio_h2p", "hclk_vio_pre", 0, RK2928_CLKGATE_CON(14), 8, GFLAGS), -+ GATE(PCLK_VIO_H2P, "pclk_vio_h2p", "hclk_vio_pre", CLK_IGNORE_UNUSED, RK2928_CLKGATE_CON(14), 8, GFLAGS), - GATE(PCLK_HDCP, "pclk_hdcp", "hclk_vio_pre", 0, RK2928_CLKGATE_CON(14), 11, GFLAGS), - - /* PD_PERI */ -@@ -545,13 +545,13 @@ static struct rockchip_clk_branch rk3228_clk_branches[] __initdata = { - GATE(HCLK_EMMC, "hclk_emmc", "hclk_peri", 0, RK2928_CLKGATE_CON(11), 2, GFLAGS), - GATE(HCLK_NANDC, "hclk_nandc", "hclk_peri", 0, RK2928_CLKGATE_CON(11), 3, GFLAGS), - GATE(HCLK_HOST0, "hclk_host0", "hclk_peri", 0, RK2928_CLKGATE_CON(11), 6, GFLAGS), -- GATE(0, "hclk_host0_arb", "hclk_peri", 0, RK2928_CLKGATE_CON(11), 7, GFLAGS), -+ GATE(0, "hclk_host0_arb", "hclk_peri", CLK_IGNORE_UNUSED, RK2928_CLKGATE_CON(11), 7, GFLAGS), - GATE(HCLK_HOST1, "hclk_host1", "hclk_peri", 0, RK2928_CLKGATE_CON(11), 8, GFLAGS), -- GATE(0, "hclk_host1_arb", "hclk_peri", 0, RK2928_CLKGATE_CON(11), 9, GFLAGS), -+ GATE(0, "hclk_host1_arb", "hclk_peri", CLK_IGNORE_UNUSED, RK2928_CLKGATE_CON(11), 9, GFLAGS), - GATE(HCLK_HOST2, "hclk_host2", "hclk_peri", 0, RK2928_CLKGATE_CON(11), 10, GFLAGS), - GATE(HCLK_OTG, "hclk_otg", "hclk_peri", 0, RK2928_CLKGATE_CON(11), 12, GFLAGS), -- GATE(0, "hclk_otg_pmu", "hclk_peri", 0, RK2928_CLKGATE_CON(11), 13, GFLAGS), -- GATE(0, "hclk_host2_arb", "hclk_peri", 0, RK2928_CLKGATE_CON(11), 14, GFLAGS), -+ GATE(0, "hclk_otg_pmu", "hclk_peri", CLK_IGNORE_UNUSED, RK2928_CLKGATE_CON(11), 13, GFLAGS), -+ GATE(0, "hclk_host2_arb", "hclk_peri", CLK_IGNORE_UNUSED, RK2928_CLKGATE_CON(11), 14, GFLAGS), - GATE(0, "hclk_peri_noc", "hclk_peri", CLK_IGNORE_UNUSED, RK2928_CLKGATE_CON(12), 1, GFLAGS), - - GATE(PCLK_GMAC, "pclk_gmac", "pclk_peri", 0, RK2928_CLKGATE_CON(11), 5, GFLAGS), -@@ -559,15 +559,15 @@ static struct rockchip_clk_branch rk3228_clk_branches[] __initdata = { - - /* PD_GPU */ - GATE(ACLK_GPU, "aclk_gpu", "aclk_gpu_pre", 0, RK2928_CLKGATE_CON(7), 14, GFLAGS), -- GATE(0, "aclk_gpu_noc", "aclk_gpu_pre", 0, RK2928_CLKGATE_CON(7), 15, GFLAGS), -+ GATE(0, "aclk_gpu_noc", "aclk_gpu_pre", CLK_IGNORE_UNUSED, RK2928_CLKGATE_CON(7), 15, GFLAGS), - - /* PD_BUS */ -- GATE(0, "sclk_initmem_mbist", "aclk_cpu", 0, RK2928_CLKGATE_CON(8), 1, GFLAGS), -- GATE(0, "aclk_initmem", "aclk_cpu", 0, RK2928_CLKGATE_CON(8), 0, GFLAGS), -+ GATE(0, "sclk_initmem_mbist", "aclk_cpu", CLK_IGNORE_UNUSED, RK2928_CLKGATE_CON(8), 1, GFLAGS), -+ GATE(0, "aclk_initmem", "aclk_cpu", CLK_IGNORE_UNUSED, RK2928_CLKGATE_CON(8), 0, GFLAGS), - GATE(ACLK_DMAC, "aclk_dmac_bus", "aclk_cpu", 0, RK2928_CLKGATE_CON(8), 2, GFLAGS), - GATE(0, "aclk_bus_noc", "aclk_cpu", CLK_IGNORE_UNUSED, RK2928_CLKGATE_CON(10), 1, GFLAGS), - -- GATE(0, "hclk_rom", "hclk_cpu", 0, RK2928_CLKGATE_CON(8), 3, GFLAGS), -+ GATE(0, "hclk_rom", "hclk_cpu", CLK_IGNORE_UNUSED, RK2928_CLKGATE_CON(8), 3, GFLAGS), - GATE(HCLK_I2S0_8CH, "hclk_i2s0_8ch", "hclk_cpu", 0, RK2928_CLKGATE_CON(8), 7, GFLAGS), - GATE(HCLK_I2S1_8CH, "hclk_i2s1_8ch", "hclk_cpu", 0, RK2928_CLKGATE_CON(8), 8, GFLAGS), - GATE(HCLK_I2S2_2CH, "hclk_i2s2_2ch", "hclk_cpu", 0, RK2928_CLKGATE_CON(8), 9, GFLAGS), -@@ -576,9 +576,9 @@ static struct rockchip_clk_branch rk3228_clk_branches[] __initdata = { - GATE(HCLK_M_CRYPTO, "hclk_crypto_mst", "hclk_cpu", 0, RK2928_CLKGATE_CON(8), 11, GFLAGS), - GATE(HCLK_S_CRYPTO, "hclk_crypto_slv", "hclk_cpu", 0, RK2928_CLKGATE_CON(8), 12, GFLAGS), - -- GATE(0, "pclk_ddrupctl", "pclk_ddr_pre", 0, RK2928_CLKGATE_CON(8), 4, GFLAGS), -- GATE(0, "pclk_ddrmon", "pclk_ddr_pre", 0, RK2928_CLKGATE_CON(8), 6, GFLAGS), -- GATE(0, "pclk_msch_noc", "pclk_ddr_pre", 0, RK2928_CLKGATE_CON(10), 2, GFLAGS), -+ GATE(0, "pclk_ddrupctl", "pclk_ddr_pre", CLK_IGNORE_UNUSED, RK2928_CLKGATE_CON(8), 4, GFLAGS), -+ GATE(0, "pclk_ddrmon", "pclk_ddr_pre", CLK_IGNORE_UNUSED, RK2928_CLKGATE_CON(8), 6, GFLAGS), -+ GATE(0, "pclk_msch_noc", "pclk_ddr_pre", CLK_IGNORE_UNUSED, RK2928_CLKGATE_CON(10), 2, GFLAGS), - - GATE(PCLK_EFUSE_1024, "pclk_efuse_1024", "pclk_cpu", 0, RK2928_CLKGATE_CON(8), 13, GFLAGS), - GATE(PCLK_EFUSE_256, "pclk_efuse_256", "pclk_cpu", 0, RK2928_CLKGATE_CON(8), 14, GFLAGS), -@@ -587,7 +587,7 @@ static struct rockchip_clk_branch rk3228_clk_branches[] __initdata = { - GATE(PCLK_I2C2, "pclk_i2c2", "pclk_cpu", 0, RK2928_CLKGATE_CON(9), 1, GFLAGS), - GATE(PCLK_I2C3, "pclk_i2c3", "pclk_cpu", 0, RK2928_CLKGATE_CON(9), 2, GFLAGS), - GATE(PCLK_TIMER, "pclk_timer0", "pclk_cpu", 0, RK2928_CLKGATE_CON(9), 4, GFLAGS), -- GATE(0, "pclk_stimer", "pclk_cpu", 0, RK2928_CLKGATE_CON(9), 5, GFLAGS), -+ GATE(0, "pclk_stimer", "pclk_cpu", CLK_IGNORE_UNUSED, RK2928_CLKGATE_CON(9), 5, GFLAGS), - GATE(PCLK_SPI0, "pclk_spi0", "pclk_cpu", 0, RK2928_CLKGATE_CON(9), 6, GFLAGS), - GATE(PCLK_PWM, "pclk_rk_pwm", "pclk_cpu", 0, RK2928_CLKGATE_CON(9), 7, GFLAGS), - GATE(PCLK_GPIO0, "pclk_gpio0", "pclk_cpu", 0, RK2928_CLKGATE_CON(9), 8, GFLAGS), -@@ -601,22 +601,22 @@ static struct rockchip_clk_branch rk3228_clk_branches[] __initdata = { - GATE(PCLK_GRF, "pclk_grf", "pclk_cpu", CLK_IGNORE_UNUSED, RK2928_CLKGATE_CON(10), 0, GFLAGS), - GATE(0, "pclk_cru", "pclk_cpu", CLK_IGNORE_UNUSED, RK2928_CLKGATE_CON(10), 1, GFLAGS), - GATE(0, "pclk_sgrf", "pclk_cpu", CLK_IGNORE_UNUSED, RK2928_CLKGATE_CON(10), 2, GFLAGS), -- GATE(0, "pclk_sim", "pclk_cpu", 0, RK2928_CLKGATE_CON(10), 3, GFLAGS), -+ GATE(0, "pclk_sim", "pclk_cpu", CLK_IGNORE_UNUSED, RK2928_CLKGATE_CON(10), 3, GFLAGS), - -- GATE(0, "pclk_ddrphy", "pclk_phy_pre", 0, RK2928_CLKGATE_CON(10), 3, GFLAGS), -- GATE(0, "pclk_acodecphy", "pclk_phy_pre", 0, RK2928_CLKGATE_CON(10), 5, GFLAGS), -+ GATE(0, "pclk_ddrphy", "pclk_phy_pre", CLK_IGNORE_UNUSED, RK2928_CLKGATE_CON(10), 3, GFLAGS), -+ GATE(0, "pclk_acodecphy", "pclk_phy_pre", CLK_IGNORE_UNUSED, RK2928_CLKGATE_CON(10), 5, GFLAGS), - GATE(PCLK_HDMI_PHY, "pclk_hdmiphy", "pclk_phy_pre", 0, RK2928_CLKGATE_CON(10), 7, GFLAGS), -- GATE(0, "pclk_vdacphy", "pclk_phy_pre", 0, RK2928_CLKGATE_CON(10), 8, GFLAGS), -- GATE(0, "pclk_phy_noc", "pclk_phy_pre", 0, RK2928_CLKGATE_CON(10), 9, GFLAGS), -+ GATE(0, "pclk_vdacphy", "pclk_phy_pre", CLK_IGNORE_UNUSED, RK2928_CLKGATE_CON(10), 8, GFLAGS), -+ GATE(0, "pclk_phy_noc", "pclk_phy_pre", CLK_IGNORE_UNUSED, RK2928_CLKGATE_CON(10), 9, GFLAGS), - - GATE(ACLK_VPU, "aclk_vpu", "aclk_vpu_pre", 0, RK2928_CLKGATE_CON(15), 0, GFLAGS), -- GATE(0, "aclk_vpu_noc", "aclk_vpu_pre", 0, RK2928_CLKGATE_CON(15), 4, GFLAGS), -+ GATE(0, "aclk_vpu_noc", "aclk_vpu_pre", CLK_IGNORE_UNUSED, RK2928_CLKGATE_CON(15), 4, GFLAGS), - GATE(ACLK_RKVDEC, "aclk_rkvdec", "aclk_rkvdec_pre", 0, RK2928_CLKGATE_CON(15), 2, GFLAGS), -- GATE(0, "aclk_rkvdec_noc", "aclk_rkvdec_pre", 0, RK2928_CLKGATE_CON(15), 6, GFLAGS), -+ GATE(0, "aclk_rkvdec_noc", "aclk_rkvdec_pre", CLK_IGNORE_UNUSED, RK2928_CLKGATE_CON(15), 6, GFLAGS), - GATE(HCLK_VPU, "hclk_vpu", "hclk_vpu_pre", 0, RK2928_CLKGATE_CON(15), 1, GFLAGS), -- GATE(0, "hclk_vpu_noc", "hclk_vpu_pre", 0, RK2928_CLKGATE_CON(15), 5, GFLAGS), -+ GATE(0, "hclk_vpu_noc", "hclk_vpu_pre", CLK_IGNORE_UNUSED, RK2928_CLKGATE_CON(15), 5, GFLAGS), - GATE(HCLK_RKVDEC, "hclk_rkvdec", "hclk_rkvdec_pre", 0, RK2928_CLKGATE_CON(15), 3, GFLAGS), -- GATE(0, "hclk_rkvdec_noc", "hclk_rkvdec_pre", 0, RK2928_CLKGATE_CON(15), 7, GFLAGS), -+ GATE(0, "hclk_rkvdec_noc", "hclk_rkvdec_pre", CLK_IGNORE_UNUSED, RK2928_CLKGATE_CON(15), 7, GFLAGS), - - /* PD_MMC */ - MMC(SCLK_SDMMC_DRV, "sdmmc_drv", "sclk_sdmmc", RK3228_SDMMC_CON0, 1), +@@ -641,6 +641,7 @@ static const char *const rk3228_critical_clocks[] __initconst = { + "aclk_vop_noc", + "aclk_hdcp_noc", + "hclk_vio_ahb_arbi", ++ "hclk_vio_h2p", + "hclk_vio_noc", + "hclk_vop_noc", + "hclk_host0_arb", +@@ -658,6 +659,7 @@ static const char *const rk3228_critical_clocks[] __initconst = { + "pclk_ddrphy", + "pclk_acodecphy", + "pclk_phy_noc", ++ "pclk_vio_h2p", + "aclk_vpu_noc", + "aclk_rkvdec_noc", + "hclk_vpu_noc", -From 2e0ab4e4f4319964f317eae5a6e25d2fccff3132 Mon Sep 17 00:00:00 2001 +From 3fc147d54b06e6451775465e35de17a6126377c2 Mon Sep 17 00:00:00 2001 From: Alex Bee Date: Sun, 16 Aug 2020 17:07:35 +0200 Subject: [PATCH] clk: rockchip add aclk_rkvdec and hclk_rkvdec to RK3228 @@ -442,11 +236,11 @@ to RK3228 critical clocks 1 file changed, 2 insertions(+) diff --git a/drivers/clk/rockchip/clk-rk3228.c b/drivers/clk/rockchip/clk-rk3228.c -index bfcb64e90d00..6c39ecd3db7e 100644 +index 4b2aca6b1f11..2ac006e99c03 100644 --- a/drivers/clk/rockchip/clk-rk3228.c +++ b/drivers/clk/rockchip/clk-rk3228.c -@@ -660,8 +660,10 @@ static const char *const rk3228_critical_clocks[] __initconst = { - "pclk_phy_noc", +@@ -662,8 +662,10 @@ static const char *const rk3228_critical_clocks[] __initconst = { + "pclk_vio_h2p", "aclk_vpu_noc", "aclk_rkvdec_noc", + "aclk_rkvdec", @@ -457,7 +251,7 @@ index bfcb64e90d00..6c39ecd3db7e 100644 static void __init rk3228_clk_init(struct device_node *np) -From 4ff8835efc210dc2557ec3ccbbf46af011d769c9 Mon Sep 17 00:00:00 2001 +From 8384abedb84b4f9c8648a92108de94b4b8d188a6 Mon Sep 17 00:00:00 2001 From: Alex Bee Date: Fri, 24 Apr 2020 11:42:58 +0200 Subject: [PATCH] soc: rockchip: Support powerdomains which don't need / @@ -538,46 +332,7 @@ index 54eb6cfc5d5b..c6b33f7c43df 100644 } -From 2293fee19de0f1cda113716d76ec2ea49682de43 Mon Sep 17 00:00:00 2001 -From: Alex Bee -Date: Fri, 24 Apr 2020 13:01:07 +0200 -Subject: [PATCH] sound: soc: rockchip: use rouned rate for i2s - ---- - sound/soc/rockchip/rockchip_i2s.c | 9 +++++++-- - 1 file changed, 7 insertions(+), 2 deletions(-) - -diff --git a/sound/soc/rockchip/rockchip_i2s.c b/sound/soc/rockchip/rockchip_i2s.c -index 593299675b8c..3157793ced90 100644 ---- a/sound/soc/rockchip/rockchip_i2s.c -+++ b/sound/soc/rockchip/rockchip_i2s.c -@@ -279,10 +279,13 @@ 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 == 0 || mclk_rate % bclk_rate) -+ if (bclk_rate == 0) { -+ dev_err(i2s->dev, "invalid bclk_rate: %d\n", -+ bclk_rate); - return -EINVAL; -+ } - -- div_bclk = mclk_rate / bclk_rate; -+ div_bclk = DIV_ROUND_CLOSEST(mclk_rate, bclk_rate); - div_lrck = bclk_rate / params_rate(params); - regmap_update_bits(i2s->regmap, I2S_CKR, - I2S_CKR_MDIV_MASK, -@@ -312,6 +315,8 @@ static int rockchip_i2s_hw_params(struct snd_pcm_substream *substream, - val |= I2S_TXCR_VDW(32); - break; - default: -+ dev_err(i2s->dev, "invalid format: %d\n", -+ params_format(params)); - return -EINVAL; - } - - -From 48d112b64ef3eca1e86dc263d89c1606d90a3428 Mon Sep 17 00:00:00 2001 +From 14c607b588c49705ac0486d63590876089b41a20 Mon Sep 17 00:00:00 2001 From: Alex Bee Date: Fri, 24 Apr 2020 09:08:44 +0200 Subject: [PATCH] phy: rockchip: hdmi: readout hdmi phy flag for RK3228 HDMI @@ -615,7 +370,7 @@ index 48e6e8d44a1a..a5f1d1a004d4 100644 status = "disabled"; }; diff --git a/drivers/phy/rockchip/phy-rockchip-inno-hdmi.c b/drivers/phy/rockchip/phy-rockchip-inno-hdmi.c -index 9ca20c947283..b1a9ff0131eb 100644 +index bb8bdf5e3301..0c7a97352714 100644 --- a/drivers/phy/rockchip/phy-rockchip-inno-hdmi.c +++ b/drivers/phy/rockchip/phy-rockchip-inno-hdmi.c @@ -237,6 +237,9 @@ struct inno_hdmi_phy { @@ -628,7 +383,7 @@ index 9ca20c947283..b1a9ff0131eb 100644 /* platform data */ const struct inno_hdmi_phy_drv_data *plat_data; int chip_version; -@@ -322,6 +325,7 @@ static const struct pre_pll_config pre_pll_cfg_table[] = { +@@ -347,6 +350,7 @@ static const struct pre_pll_config pre_pll_cfg_table[] = { static const struct post_pll_config post_pll_cfg_table[] = { {33750000, 1, 40, 8, 1}, {33750000, 1, 80, 8, 2}, @@ -636,7 +391,7 @@ index 9ca20c947283..b1a9ff0131eb 100644 {74250000, 1, 40, 8, 1}, {74250000, 18, 80, 8, 2}, {148500000, 2, 40, 4, 3}, -@@ -472,8 +476,11 @@ static int inno_hdmi_phy_power_on(struct phy *phy) +@@ -497,8 +501,11 @@ static int inno_hdmi_phy_power_on(struct phy *phy) return -EINVAL; for (; cfg->tmdsclock != 0; cfg++) @@ -650,7 +405,7 @@ index 9ca20c947283..b1a9ff0131eb 100644 break; for (; phy_cfg->tmdsclock != 0; phy_cfg++) -@@ -873,6 +880,10 @@ static int inno_hdmi_phy_clk_register(struct inno_hdmi_phy *inno) +@@ -909,6 +916,10 @@ static int inno_hdmi_phy_clk_register(struct inno_hdmi_phy *inno) static int inno_hdmi_phy_rk3228_init(struct inno_hdmi_phy *inno) { @@ -661,7 +416,7 @@ index 9ca20c947283..b1a9ff0131eb 100644 /* * Use phy internal register control * rxsense/poweron/pllpd/pdataen signal. -@@ -887,7 +898,28 @@ static int inno_hdmi_phy_rk3228_init(struct inno_hdmi_phy *inno) +@@ -923,7 +934,28 @@ static int inno_hdmi_phy_rk3228_init(struct inno_hdmi_phy *inno) inno_update_bits(inno, 0xaa, RK3228_POST_PLL_CTRL_MANUAL, RK3228_POST_PLL_CTRL_MANUAL); @@ -690,7 +445,7 @@ index 9ca20c947283..b1a9ff0131eb 100644 return 0; } -@@ -987,6 +1019,8 @@ static int inno_hdmi_phy_rk3328_init(struct inno_hdmi_phy *inno) +@@ -1023,6 +1055,8 @@ static int inno_hdmi_phy_rk3328_init(struct inno_hdmi_phy *inno) /* try to read the chip-version */ inno->chip_version = 1; @@ -700,7 +455,7 @@ index 9ca20c947283..b1a9ff0131eb 100644 if (IS_ERR(cell)) { if (PTR_ERR(cell) == -EPROBE_DEFER) -From cfc0aaf1cb5438ea48643e9e93ef08c3cec2005d Mon Sep 17 00:00:00 2001 +From 01d16d33ee32f2e2de85cbc8a0a399527c2121ad Mon Sep 17 00:00:00 2001 From: Alex Bee Date: Tue, 26 May 2020 14:41:39 +0200 Subject: [PATCH] usb: dwc2: QUIRKS: rockchip host only controller needs longer @@ -724,27 +479,27 @@ index fec17a2d2447..eb55c64f63be 100644 break; case USB_DR_MODE_PERIPHERAL: -From b1f2a3015eca386adb50aa52fa2f03737306ed3c Mon Sep 17 00:00:00 2001 +From ddbce05adbd8870b928b73d2f00c44f1044c1b25 Mon Sep 17 00:00:00 2001 From: Alex Bee Date: Sun, 16 Aug 2020 17:35:43 +0200 -Subject: [PATCH] nvmem: rockchip-efuse: fix RK3188 efuse read +Subject: [PATCH] nvmem: rockchip-efuse: fix RK3066/RK3188 efuse read -In order to read from RK3188s efuse, the logic is slightly different from whats -done currently for RK3288 and also used for this SoC. +In order to read from RK3066/RK3188 efuse, the logic is slightly different from +whats done currently for RK3288 and also used for this SoC. Logic, register mask and udelays have been taken from vendor kernel. --- - drivers/nvmem/rockchip-efuse.c | 49 +++++++++++++++++++++++++++++++++- - 1 file changed, 48 insertions(+), 1 deletion(-) + drivers/nvmem/rockchip-efuse.c | 51 ++++++++++++++++++++++++++++++++-- + 1 file changed, 49 insertions(+), 2 deletions(-) diff --git a/drivers/nvmem/rockchip-efuse.c b/drivers/nvmem/rockchip-efuse.c -index e4579de5d014..9afd71edf503 100644 +index e4579de5d014..424da17d6f84 100644 --- a/drivers/nvmem/rockchip-efuse.c +++ b/drivers/nvmem/rockchip-efuse.c @@ -17,6 +17,8 @@ #include #include -+#define RK3188_A_MASK 0xff ++#define RK3066_A_MASK 0xff + #define RK3288_A_SHIFT 6 #define RK3288_A_MASK 0x3ff @@ -753,7 +508,7 @@ index e4579de5d014..9afd71edf503 100644 struct clk *clk; }; -+static int rockchip_rk3188_efuse_read(void *context, unsigned int offset, ++static int rockchip_rk3066_efuse_read(void *context, unsigned int offset, + void *val, size_t bytes) +{ + struct rockchip_efuse_chip *efuse = context; @@ -772,10 +527,10 @@ index e4579de5d014..9afd71edf503 100644 + + while (bytes--) { + writel(readl(efuse->base + REG_EFUSE_CTRL) & -+ (~(RK3188_A_MASK << RK3288_A_SHIFT)), ++ (~(RK3066_A_MASK << RK3288_A_SHIFT)), + efuse->base + REG_EFUSE_CTRL); + writel(readl(efuse->base + REG_EFUSE_CTRL) | -+ ((offset++ & RK3188_A_MASK) << RK3288_A_SHIFT), ++ ((offset++ & RK3066_A_MASK) << RK3288_A_SHIFT), + efuse->base + REG_EFUSE_CTRL); + udelay(2); + writel(readl(efuse->base + REG_EFUSE_CTRL) | @@ -801,28 +556,47 @@ index e4579de5d014..9afd71edf503 100644 static int rockchip_rk3288_efuse_read(void *context, unsigned int offset, void *val, size_t bytes) { -@@ -222,7 +269,7 @@ static const struct of_device_id rockchip_efuse_match[] = { +@@ -218,11 +265,11 @@ static const struct of_device_id rockchip_efuse_match[] = { + }, + { + .compatible = "rockchip,rk3066a-efuse", +- .data = (void *)&rockchip_rk3288_efuse_read, ++ .data = (void *)&rockchip_rk3066_efuse_read, }, { .compatible = "rockchip,rk3188-efuse", - .data = (void *)&rockchip_rk3288_efuse_read, -+ .data = (void *)&rockchip_rk3188_efuse_read, ++ .data = (void *)&rockchip_rk3066_efuse_read, }, { .compatible = "rockchip,rk3228-efuse", -From 6cce60ef243c2be51d5a5ba66b15992110d9c9b4 Mon Sep 17 00:00:00 2001 +From 37dda5c7dbdd36fbb92abb4a4b2505150714361b Mon Sep 17 00:00:00 2001 From: Alex Bee Date: Sun, 16 Aug 2020 17:43:08 +0200 -Subject: [PATCH] ARM: dts: rockchip: fix RK3188 efuse register width +Subject: [PATCH] ARM: dts: rockchip: fix RK3066/RK3188 efuse register width -As with most Rockchip SoCs the RK3188s non-secure efuse contains 32 bytes of data. +As with most Rockchip SoCs the RK3066/RK3188 non-secure efuse contains 32 bytes of data. This adapts the register width, so that we don't get repeated data when reading out the values from it. --- - arch/arm/boot/dts/rk3188.dtsi | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) + arch/arm/boot/dts/rk3066a.dtsi | 2 +- + arch/arm/boot/dts/rk3188.dtsi | 2 +- + 2 files changed, 2 insertions(+), 2 deletions(-) +diff --git a/arch/arm/boot/dts/rk3066a.dtsi b/arch/arm/boot/dts/rk3066a.dtsi +index f91ce30549c2..6feeaf90a40c 100644 +--- a/arch/arm/boot/dts/rk3066a.dtsi ++++ b/arch/arm/boot/dts/rk3066a.dtsi +@@ -244,7 +244,7 @@ timer@2000e000 { + + efuse: efuse@20010000 { + compatible = "rockchip,rk3066a-efuse"; +- reg = <0x20010000 0x4000>; ++ reg = <0x20010000 0x20>; + #address-cells = <1>; + #size-cells = <1>; + clocks = <&cru PCLK_EFUSE>; diff --git a/arch/arm/boot/dts/rk3188.dtsi b/arch/arm/boot/dts/rk3188.dtsi index 2298a8d840ba..9e0806cd6f46 100644 --- a/arch/arm/boot/dts/rk3188.dtsi @@ -837,7 +611,7 @@ index 2298a8d840ba..9e0806cd6f46 100644 #size-cells = <1>; clocks = <&cru PCLK_EFUSE>; -From 6b24a1746ccbd902f241da4e854aa824a07bdaea Mon Sep 17 00:00:00 2001 +From 713a88dec72631a71bf736e120236f60d06f3989 Mon Sep 17 00:00:00 2001 From: Alex Bee Date: Sun, 16 Aug 2020 18:51:38 +0200 Subject: [PATCH] ARM: dts: rockchip add operating-points, power-domain for @@ -896,7 +670,7 @@ index a5f1d1a004d4..dedf84af9e51 100644 vpu_mmu: iommu@20020800 { -From c6d9b2d7dfff71d52caef22363ff51fc58012a31 Mon Sep 17 00:00:00 2001 +From 4526da0caf4ecc56cc6e6b8602715dbe839c3eac Mon Sep 17 00:00:00 2001 From: Alex Bee Date: Sun, 16 Aug 2020 19:44:42 +0200 Subject: [PATCH] ARM: dts: rockchip: add ethernet0 alias @@ -920,7 +694,7 @@ index dedf84af9e51..3c20ee3a7837 100644 serial1 = &uart1; serial2 = &uart2; -From 9224ab008c39f468393592da25bebbdce77718de Mon Sep 17 00:00:00 2001 +From 3d6864134434144078395786338b194704a5a41a Mon Sep 17 00:00:00 2001 From: Alex Bee Date: Sun, 16 Aug 2020 20:00:01 +0200 Subject: [PATCH] ARM: dts: rockchip: add hdmi simple-audio-card for RK322x @@ -992,7 +766,7 @@ index 3c20ee3a7837..d10ca04c20d6 100644 ports { -From ba86a4da4008564a6582e4fb1616c1a6b9ae07dd Mon Sep 17 00:00:00 2001 +From f917eada6b9f431a797e3bfab7cd06dbd9dfe981 Mon Sep 17 00:00:00 2001 From: Alex Bee Date: Sun, 16 Aug 2020 21:16:11 +0200 Subject: [PATCH] ARM: dts: rockchip: add uart1-1 pins for RK322x @@ -1048,7 +822,7 @@ index d10ca04c20d6..f675551391c3 100644 uart2 { -From f638085cfc9294bb2a559f1291a152ffc390bacc Mon Sep 17 00:00:00 2001 +From cbbb85e00a2b19c1e3e9e4d6591c481718e5fb42 Mon Sep 17 00:00:00 2001 From: Alex Bee Date: Sun, 16 Aug 2020 21:58:56 +0200 Subject: [PATCH] ARM: dts: rockchip: align mmc* node properties with driver @@ -1123,7 +897,7 @@ index f675551391c3..8e7a866e39e5 100644 sdio { -From aeced72476c71694b6534885aef5e309cfa9c248 Mon Sep 17 00:00:00 2001 +From fa003a22751b4c44aa59f296fbfa1e6ca7a98ea9 Mon Sep 17 00:00:00 2001 From: Jeffy Chen Date: Wed, 8 Jun 2016 14:05:42 +0800 Subject: [PATCH] clk: rockchip: rk3036: add ACLK_VCODEC @@ -1148,7 +922,7 @@ index 80876c8f8c9d..562202b80dd2 100644 RK2928_CLKGATE_CON(3), 11, GFLAGS), FACTOR_GATE(HCLK_VCODEC, "hclk_vcodec", "aclk_vcodec", 0, 1, 4, -From 925d3970cf83b7653777cdf5ae1a7e8f6fe5357c Mon Sep 17 00:00:00 2001 +From 6d4d08d01a1aae98c970a25c71a5f44a1aa45535 Mon Sep 17 00:00:00 2001 From: Randy Li Date: Fri, 20 Oct 2017 14:38:09 +0800 Subject: [PATCH] clk: rockchip: rk3036: export the hevc core clock @@ -1188,7 +962,7 @@ index 35a5a01f9697..cd231f57278d 100644 /* pclk gates */ #define PCLK_GPIO0 320 -From b60b66c0aaf033e7bd4c0bb8ede4a1fc6d6fc790 Mon Sep 17 00:00:00 2001 +From 5dfa1b7621086342d99d5b07cbeafaa1ead1cf30 Mon Sep 17 00:00:00 2001 From: Caesar Wang Date: Mon, 13 Nov 2017 09:28:12 +0800 Subject: [PATCH] clk: rockchip: export SCLK_I2S_PRE and SCLK_I2S_FRAC of i2s @@ -1237,7 +1011,7 @@ index cd231f57278d..4c7ff6141a67 100644 #define SCLK_MACREF 152 #define SCLK_MACPLL 153 -From 9459d8f0a0fd926cadfa6b552cbd8556325c3c35 Mon Sep 17 00:00:00 2001 +From 875febe15912c3e5fa3a2ca7f1bc27b7fd6a8210 Mon Sep 17 00:00:00 2001 From: Caesar Wang Date: Fri, 17 Nov 2017 14:49:16 +0800 Subject: [PATCH] clk: rockchip: protect the armclk for rk3036 @@ -1283,7 +1057,7 @@ index 08aaab381783..ebf2ec466b1e 100644 ROCKCHIP_SOFTRST_HIWORD_MASK); -From c696684fbb0ff023db9760c037fc1eb7e6fd9b01 Mon Sep 17 00:00:00 2001 +From 84c4e34b5a7ace8541744bcc5ee4e2ec38906e0e Mon Sep 17 00:00:00 2001 From: Finley Xiao Date: Mon, 13 Nov 2017 15:32:25 +0800 Subject: [PATCH] clk: rockchip: rk3036: leave apll for core, mac and lcdc only @@ -1418,7 +1192,7 @@ index ebf2ec466b1e..6e338e1970e9 100644 MUX(SCLK_MACREF, "mac_clk_ref", mux_mac_p, CLK_SET_RATE_PARENT, RK2928_CLKSEL_CON(21), 3, 1, MFLAGS), -From 46dfb6b7de3b0b169c9e17939b2c3de3600afbc6 Mon Sep 17 00:00:00 2001 +From f640e49f0aedb074762a77583004c383441a5d10 Mon Sep 17 00:00:00 2001 From: Randy Li Date: Fri, 20 Apr 2018 10:43:46 +0800 Subject: [PATCH] clk: rockchip: rk3036: export the sfc clocks @@ -1459,7 +1233,7 @@ index 4c7ff6141a67..72ba1952071d 100644 #define HCLK_SDIO 457 #define HCLK_EMMC 459 -From 80836af96f3775b9d84fdbb519838ea772e15626 Mon Sep 17 00:00:00 2001 +From 7264936f6dbfff1a6768d7cc119424f0ae52faa0 Mon Sep 17 00:00:00 2001 From: Elaine Zhang Date: Mon, 1 Jun 2020 15:36:35 +0800 Subject: [PATCH] clk: rockchip: rk3036: fix up the sclk_sfc parent error @@ -1492,7 +1266,7 @@ index 01178e05a926..6194df20574a 100644 RK2928_CLKGATE_CON(10), 5, GFLAGS), -From d8bb8772b6a648277040e96cba7ab28c720b0ec0 Mon Sep 17 00:00:00 2001 +From dd6750945d222d87447f0b8c61e1a321e94480bf Mon Sep 17 00:00:00 2001 From: Alex Bee Date: Sun, 16 Aug 2020 22:41:29 +0200 Subject: [PATCH] clk: rockchip: export PCLK_EFUSE for RK3036 @@ -1529,7 +1303,7 @@ index 72ba1952071d..febab04521a2 100644 /* hclk gates */ #define HCLK_OTG0 449 -From 8e2eadf8500e81f7434fcfcfc2294a71cfe372e6 Mon Sep 17 00:00:00 2001 +From 1a1fbf7a2883065bb8056174613ae2a430d454cb Mon Sep 17 00:00:00 2001 From: Alex Bee Date: Sun, 16 Aug 2020 22:43:41 +0200 Subject: [PATCH] ARM: dts: rockchip: add RK3036 efuse node @@ -1542,7 +1316,7 @@ to bindings document. 2 files changed, 8 insertions(+) diff --git a/Documentation/devicetree/bindings/nvmem/rockchip-efuse.yaml b/Documentation/devicetree/bindings/nvmem/rockchip-efuse.yaml -index 3ae00b0b23bc..c3fdabcb1e0a 100644 +index 104dd508565e..8dd059e63295 100644 --- a/Documentation/devicetree/bindings/nvmem/rockchip-efuse.yaml +++ b/Documentation/devicetree/bindings/nvmem/rockchip-efuse.yaml @@ -15,6 +15,7 @@ allOf: @@ -1570,7 +1344,7 @@ index dda5a1f79aca..838040b08967 100644 + }; }; -From 862e71262367000d13a2cfd38235b868a887902e Mon Sep 17 00:00:00 2001 +From 8555a8482e57b992284efaa6065832aebf1a9aaf Mon Sep 17 00:00:00 2001 From: Alex Bee Date: Sun, 16 Aug 2020 23:02:00 +0200 Subject: [PATCH] ARM: dts: add opp-table for RK3188s GPU @@ -1629,7 +1403,7 @@ index 9e0806cd6f46..e2edea308556 100644 }; -From 260d98880a8a31abe94b997db7189cb71af149f1 Mon Sep 17 00:00:00 2001 +From 86ae340dabdfbc27ebdb1b43b96d59999dfa4f5a Mon Sep 17 00:00:00 2001 From: Alex Bee Date: Sun, 16 Aug 2020 23:12:25 +0200 Subject: [PATCH] ARM: dts: rk322x: add crypto node @@ -1665,7 +1439,7 @@ index 8e7a866e39e5..217ee6568f9e 100644 compatible = "rockchip,rk3228-i2s", "rockchip,rk3066-i2s"; reg = <0x100b0000 0x4000>; -From 8c9b7d2181bdc18bf69fe0f48308fb3294f8c6d4 Mon Sep 17 00:00:00 2001 +From 17648b3f3533fa800cec162a8278611b2695413c Mon Sep 17 00:00:00 2001 From: Alex Bee Date: Thu, 15 Oct 2020 23:37:37 +0200 Subject: [PATCH] ARM: dts: add rk3228 power-domain node @@ -1833,3 +1607,956 @@ index 217ee6568f9e..4bc631881c05 100644 gic: interrupt-controller@32010000 { compatible = "arm,gic-400"; interrupt-controller; + +From 3cb47d552ab5397051980b8c6bcca78bbd2c1897 Mon Sep 17 00:00:00 2001 +From: Alex Bee +Date: Thu, 15 Oct 2020 18:22:12 +0200 +Subject: [PATCH] ARM: dts: add rk3036 power-domain node + +Signed-off-by: Alex Bee +--- + arch/arm/boot/dts/rk3036.dtsi | 53 +++++++++++++++++++++++++++++++++++ + 1 file changed, 53 insertions(+) + +diff --git a/arch/arm/boot/dts/rk3036.dtsi b/arch/arm/boot/dts/rk3036.dtsi +index 838040b08967..d7668a437c70 100644 +--- a/arch/arm/boot/dts/rk3036.dtsi ++++ b/arch/arm/boot/dts/rk3036.dtsi +@@ -6,6 +6,7 @@ + #include + #include + #include ++#include + + / { + #address-cells = <1>; +@@ -130,6 +131,7 @@ gpu: gpu@10090000 { + assigned-clock-rates = <100000000>; + clocks = <&cru SCLK_GPU>, <&cru SCLK_GPU>; + clock-names = "bus", "core"; ++ power-domains = <&power RK3036_PD_GPU>; + resets = <&cru SRST_GPU>; + status = "disabled"; + }; +@@ -140,6 +142,7 @@ vop: vop@10118000 { + interrupts = ; + clocks = <&cru ACLK_LCDC>, <&cru SCLK_LCDC>, <&cru HCLK_LCDC>; + clock-names = "aclk_vop", "dclk_vop", "hclk_vop"; ++ power-domains = <&power RK3036_PD_VIO>; + resets = <&cru SRST_LCDC1_A>, <&cru SRST_LCDC1_H>, <&cru SRST_LCDC1_D>; + reset-names = "axi", "ahb", "dclk"; + iommus = <&vop_mmu>; +@@ -162,10 +165,31 @@ vop_mmu: iommu@10118300 { + interrupt-names = "vop_mmu"; + clocks = <&cru ACLK_LCDC>, <&cru HCLK_LCDC>; + clock-names = "aclk", "iface"; ++ power-domains = <&power RK3036_PD_VIO>; + #iommu-cells = <0>; + status = "disabled"; + }; + ++ qos_gpu: qos@1012d000 { ++ compatible = "syscon"; ++ reg = <0x1012d000 0x20>; ++ }; ++ ++ qos_vpu: qos@1012e000 { ++ compatible = "syscon"; ++ reg = <0x1012e000 0x20>; ++ }; ++ ++ qos_hevc: qos@1012e080 { ++ compatible = "syscon"; ++ reg = <0x1012e080 0x20>; ++ }; ++ ++ qos_vio: qos@1012f000 { ++ compatible = "syscon"; ++ reg = <0x1012f000 0x20>; ++ }; ++ + gic: interrupt-controller@10139000 { + compatible = "arm,gic-400"; + interrupt-controller; +@@ -329,6 +353,35 @@ reboot-mode { + mode-bootloader = ; + mode-loader = ; + }; ++ ++ power: power-controller { ++ compatible = "rockchip,rk3036-power-controller"; ++ #power-domain-cells = <1>; ++ #address-cells = <1>; ++ #size-cells = <0>; ++ ++ pd_vio@RK3036_PD_VIO { ++ reg = ; ++ clocks = <&cru ACLK_LCDC>, ++ <&cru HCLK_LCDC>; ++ pm_qos = <&qos_vio>; ++ ++ }; ++ pd_gpu@RK3036_PD_GPU { ++ reg = ; ++ clocks = <&cru SCLK_GPU>; ++ pm_qos = <&qos_gpu>; ++ }; ++ pd_vpu@RK3036_PD_VPU { ++ reg = ; ++ clocks = <&cru ACLK_VCODEC>, ++ <&cru HCLK_VCODEC>, ++ <&cru ACLK_HEVC>; ++ pm_qos = <&qos_vpu>, ++ <&qos_hevc>; ++ }; ++ ++ }; + }; + + acodec: acodec-ana@20030000 { + +From 3718b8fa5ac8cf5935f1bf21faeb0b7aad9f0f44 Mon Sep 17 00:00:00 2001 +From: Alex Bee +Date: Fri, 16 Oct 2020 12:02:55 +0200 +Subject: [PATCH] ARM: dts: add SPDIF node for RK3066a + +While at that: fix interrupt number of RK3188's spdif + +Signed-off-by: Alex Bee +--- + arch/arm/boot/dts/rk3066a.dtsi | 20 ++++++++++++++++++++ + arch/arm/boot/dts/rk3188.dtsi | 2 +- + 2 files changed, 21 insertions(+), 1 deletion(-) + +diff --git a/arch/arm/boot/dts/rk3066a.dtsi b/arch/arm/boot/dts/rk3066a.dtsi +index 6feeaf90a40c..b8a9674bbbe4 100644 +--- a/arch/arm/boot/dts/rk3066a.dtsi ++++ b/arch/arm/boot/dts/rk3066a.dtsi +@@ -217,6 +217,20 @@ i2s2: i2s@1011c000 { + status = "disabled"; + }; + ++ spdif: sound@1011e000 { ++ compatible = "rockchip,rk3066-spdif"; ++ reg = <0x1011e000 0x2000>; ++ #sound-dai-cells = <0>; ++ clocks = <&cru SCLK_SPDIF>, <&cru HCLK_SPDIF>; ++ clock-names = "mclk", "hclk"; ++ dmas = <&dmac1_s 8>; ++ dma-names = "tx"; ++ interrupts = ; ++ pinctrl-names = "default"; ++ pinctrl-0 = <&spdif_tx>; ++ status = "disabled"; ++ }; ++ + cru: clock-controller@20000000 { + compatible = "rockchip,rk3066a-cru"; + reg = <0x20000000 0x1000>; +@@ -509,6 +523,12 @@ pwm3_out: pwm3-out { + }; + }; + ++ spdif { ++ spdif_tx: spdif-tx { ++ rockchip,pins = <1 RK_PB6 1 &pcfg_pull_none>; ++ }; ++ }; ++ + spi0 { + spi0_clk: spi0-clk { + rockchip,pins = <1 RK_PA5 2 &pcfg_pull_default>; +diff --git a/arch/arm/boot/dts/rk3188.dtsi b/arch/arm/boot/dts/rk3188.dtsi +index e2edea308556..79742ea997eb 100644 +--- a/arch/arm/boot/dts/rk3188.dtsi ++++ b/arch/arm/boot/dts/rk3188.dtsi +@@ -215,7 +215,7 @@ spdif: sound@1011e000 { + clock-names = "mclk", "hclk"; + dmas = <&dmac1_s 8>; + dma-names = "tx"; +- interrupts = ; ++ interrupts = ; + pinctrl-names = "default"; + pinctrl-0 = <&spdif_tx>; + status = "disabled"; + +From 07c24c6999c89701ed8ffd9d999d458445b2bfc4 Mon Sep 17 00:00:00 2001 +From: Alex Bee +Date: Fri, 16 Oct 2020 13:21:15 +0200 +Subject: [PATCH] ARM: dts: rockchip: disable arm-global-timer for rk3066a + +Commit 500d0aa918a2 ("ARM: dts: rockchip: disable arm-global-timer for rk3188") +disabled the A9 global timer for RK3188. +This has to be done for RK3066a as well for the very same reasons in particular +to prefer rockchip timer over the global timer, which provides a more reliable +timer source. + +Signed-off-by: Alex Bee +--- + arch/arm/boot/dts/rk3066a.dtsi | 4 ++++ + 1 file changed, 4 insertions(+) + +diff --git a/arch/arm/boot/dts/rk3066a.dtsi b/arch/arm/boot/dts/rk3066a.dtsi +index b8a9674bbbe4..82d005c68735 100644 +--- a/arch/arm/boot/dts/rk3066a.dtsi ++++ b/arch/arm/boot/dts/rk3066a.dtsi +@@ -714,6 +714,10 @@ i2s2_bus: i2s2-bus { + }; + }; + ++&global_timer { ++ status = "disabled"; ++}; ++ + &gpu { + compatible = "rockchip,rk3066-mali", "arm,mali-400"; + interrupts = , + +From 65712b2c67cc6aa39daccda1c5b415a5e908a80b Mon Sep 17 00:00:00 2001 +From: Alex Bee +Date: Sat, 17 Oct 2020 16:24:02 +0200 +Subject: [PATCH] ARM: dts: move RK3066a's cpu opp-table to operating-points-v2 + +Also: add core resets to cpu nodes + +Signed-off-by: Alex Bee +--- + arch/arm/boot/dts/rk3066a.dtsi | 51 ++++++++++++++++++++++++++-------- + 1 file changed, 40 insertions(+), 11 deletions(-) + +diff --git a/arch/arm/boot/dts/rk3066a.dtsi b/arch/arm/boot/dts/rk3066a.dtsi +index 82d005c68735..9279cd5405f7 100644 +--- a/arch/arm/boot/dts/rk3066a.dtsi ++++ b/arch/arm/boot/dts/rk3066a.dtsi +@@ -23,24 +23,53 @@ cpu0: cpu@0 { + compatible = "arm,cortex-a9"; + next-level-cache = <&L2>; + reg = <0x0>; +- operating-points = < +- /* kHz uV */ +- 1416000 1300000 +- 1200000 1175000 +- 1008000 1125000 +- 816000 1125000 +- 600000 1100000 +- 504000 1100000 +- 312000 1075000 +- >; +- clock-latency = <40000>; + clocks = <&cru ARMCLK>; ++ operating-points-v2 = <&cpu0_opp_table>; ++ resets = <&cru SRST_CORE0>; + }; + cpu1: cpu@1 { + device_type = "cpu"; + compatible = "arm,cortex-a9"; + next-level-cache = <&L2>; + reg = <0x1>; ++ operating-points-v2 = <&cpu0_opp_table>; ++ resets = <&cru SRST_CORE1>; ++ }; ++ }; ++ ++ cpu0_opp_table: opp_table0 { ++ compatible = "operating-points-v2"; ++ opp-shared; ++ ++ opp-312000000 { ++ opp-hz = /bits/ 64 <312000000>; ++ opp-microvolt = <1075000>; ++ clock-latency-ns = <40000>; ++ }; ++ opp-504000000 { ++ opp-hz = /bits/ 64 <504000000>; ++ opp-microvolt = <1100000>; ++ }; ++ opp-600000000 { ++ opp-hz = /bits/ 64 <600000000>; ++ opp-microvolt = <1100000>; ++ opp-suspend; ++ }; ++ opp-816000000 { ++ opp-hz = /bits/ 64 <816000000>; ++ opp-microvolt = <1125000>; ++ }; ++ opp-1008000000 { ++ opp-hz = /bits/ 64 <1008000000>; ++ opp-microvolt = <1125000>; ++ }; ++ opp-1200000000 { ++ opp-hz = /bits/ 64 <1200000000>; ++ opp-microvolt = <1175000>; ++ }; ++ opp-1416000000 { ++ opp-hz = /bits/ 64 <1416000000>; ++ opp-microvolt = <1300000>; + }; + }; + + +From 1fd7bfba9941a2ffee7c29a9f800aeaffd2fe8d8 Mon Sep 17 00:00:00 2001 +From: Alex Bee +Date: Sat, 17 Oct 2020 16:44:11 +0200 +Subject: [PATCH] ARM: dts: add gpu opp-table for RK3066a + +Signed-off-by: Alex Bee +--- + arch/arm/boot/dts/rk3066a.dtsi | 15 +++++++++++++++ + 1 file changed, 15 insertions(+) + +diff --git a/arch/arm/boot/dts/rk3066a.dtsi b/arch/arm/boot/dts/rk3066a.dtsi +index 9279cd5405f7..088cb5e2ef79 100644 +--- a/arch/arm/boot/dts/rk3066a.dtsi ++++ b/arch/arm/boot/dts/rk3066a.dtsi +@@ -94,6 +94,19 @@ simple-audio-card,cpu { + }; + }; + ++ gpu_opp_table: opp-table2 { ++ compatible = "operating-points-v2"; ++ ++ opp-266000000 { ++ opp-hz = /bits/ 64 <266000000>; ++ opp-microvolt = <1050000>; ++ }; ++ opp-400000000 { ++ opp-hz = /bits/ 64 <400000000>; ++ opp-microvolt = <1275000>; ++ }; ++ }; ++ + sram: sram@10080000 { + compatible = "mmio-sram"; + reg = <0x10080000 0x10000>; +@@ -769,7 +782,9 @@ &gpu { + "ppmmu2", + "pp3", + "ppmmu3"; ++ assigned-clock-rates = <266000000>; + power-domains = <&power RK3066_PD_GPU>; ++ operating-points-v2 = <&gpu_opp_table>; + }; + + &i2c0 { + +From f0004dc7f3ed7231f3b7e8263358cc5508495506 Mon Sep 17 00:00:00 2001 +From: Alex Bee +Date: Sat, 17 Oct 2020 16:55:12 +0200 +Subject: [PATCH] ARM: dts: add thermal sensor for RK3066 + +TSADC from RK3066a is different from other RK SoCs. Its driver +is more like an SARADC driver which has 2 iio-channels. The first is +connected to the internal thermal, while the second could be connected +to an external. +The values can be converted by defining a temperature-voltage-mapping +using the "generic-adc-thermal" driver/node. +Also add corresponding thermal zones for CPU/GPU. + +Signed-off-by: Alex Bee +--- + arch/arm/boot/dts/rk3066a.dtsi | 71 +++++++++++++++++++++++++++++++++- + 1 file changed, 70 insertions(+), 1 deletion(-) + +diff --git a/arch/arm/boot/dts/rk3066a.dtsi b/arch/arm/boot/dts/rk3066a.dtsi +index 088cb5e2ef79..84d7053d91f8 100644 +--- a/arch/arm/boot/dts/rk3066a.dtsi ++++ b/arch/arm/boot/dts/rk3066a.dtsi +@@ -8,6 +8,7 @@ + #include + #include + #include ++#include + #include "rk3xxx.dtsi" + + / { +@@ -26,6 +27,7 @@ cpu0: cpu@0 { + clocks = <&cru ARMCLK>; + operating-points-v2 = <&cpu0_opp_table>; + resets = <&cru SRST_CORE0>; ++ #cooling-cells = <2>; + }; + cpu1: cpu@1 { + device_type = "cpu"; +@@ -34,6 +36,7 @@ cpu1: cpu@1 { + reg = <0x1>; + operating-points-v2 = <&cpu0_opp_table>; + resets = <&cru SRST_CORE1>; ++ #cooling-cells = <2>; + }; + }; + +@@ -107,6 +110,72 @@ opp-400000000 { + }; + }; + ++ thermal-zones { ++ cpu_thermal: cpu-thermal { ++ polling-delay-passive = <100>; ++ polling-delay = <5000>; ++ thermal-sensors = <&thermal_int>; ++ ++ trips { ++ cpu_alert0: cpu_alert0 { ++ temperature = <70000>; ++ hysteresis = <2000>; ++ type = "passive"; ++ }; ++ cpu_alert1: cpu_alert1 { ++ temperature = <75000>; ++ hysteresis = <2000>; ++ type = "passive"; ++ }; ++ cpu_crit: cpu_crit { ++ temperature = <90000>; ++ hysteresis = <2000>; ++ type = "critical"; ++ }; ++ }; ++ ++ cooling-maps { ++ map0 { ++ trip = <&cpu_alert0>; ++ cooling-device = ++ <&cpu0 THERMAL_NO_LIMIT 6>, ++ <&cpu1 THERMAL_NO_LIMIT 6>; ++ }; ++ map1 { ++ trip = <&cpu_alert1>; ++ cooling-device = ++ <&cpu0 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>, ++ <&cpu1 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>; ++ }; ++ map2 { ++ trip = <&cpu_alert1>; ++ cooling-device = ++ <&gpu THERMAL_NO_LIMIT THERMAL_NO_LIMIT>; ++ }; ++ }; ++ }; ++ }; ++ ++ thermal_int: thermal-int { ++ compatible = "generic-adc-thermal"; ++ #thermal-sensor-cells = <0>; ++ io-channels = <&tsadc 0>; ++ io-channel-names = "sensor-channel"; ++ temperature-lookup-table = < (-40000) 2319 ++ 25000 2244 ++ 30000 2238 ++ 45000 2218 ++ 125000 2088>; ++ }; ++ ++ thermal_ext: thermal-ext { ++ compatible = "generic-adc-thermal"; ++ #thermal-sensor-cells = <0>; ++ io-channels = <&tsadc 1>; ++ io-channel-names = "sensor-channel"; ++ status = "disabled"; ++ }; ++ + sram: sram@10080000 { + compatible = "mmio-sram"; + reg = <0x10080000 0x10000>; +@@ -336,7 +405,6 @@ tsadc: tsadc@20060000 { + #io-channel-cells = <1>; + resets = <&cru SRST_TSADC>; + reset-names = "saradc-apb"; +- status = "disabled"; + }; + + usbphy: phy { +@@ -785,6 +853,7 @@ &gpu { + assigned-clock-rates = <266000000>; + power-domains = <&power RK3066_PD_GPU>; + operating-points-v2 = <&gpu_opp_table>; ++ #cooling-cells = <2>; + }; + + &i2c0 { + +From 37b6b0a447db0296e3f1a8ab9127b49053a803e7 Mon Sep 17 00:00:00 2001 +From: Alex Bee +Date: Sat, 17 Oct 2020 20:51:33 +0200 +Subject: [PATCH] clk: rockchip: add missing rk3066 cpu clk rate + +Signed-off-by: Alex Bee +--- + drivers/clk/rockchip/clk-rk3188.c | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/drivers/clk/rockchip/clk-rk3188.c b/drivers/clk/rockchip/clk-rk3188.c +index 78c3d0c80edf..a2f7ece161ec 100644 +--- a/drivers/clk/rockchip/clk-rk3188.c ++++ b/drivers/clk/rockchip/clk-rk3188.c +@@ -139,6 +139,7 @@ static struct rockchip_pll_rate_table rk3188_pll_rates[] = { + } + + static struct rockchip_cpuclk_rate_table rk3066_cpuclk_rates[] __initdata = { ++ RK3066_CPUCLK_RATE(1608000000, 2, 3, 1, 2, 1), + RK3066_CPUCLK_RATE(1416000000, 2, 3, 1, 2, 1), + RK3066_CPUCLK_RATE(1200000000, 2, 3, 1, 2, 1), + RK3066_CPUCLK_RATE(1008000000, 2, 2, 1, 2, 1), + +From 229f0fb68b80565dd1d85872afa65720e3b6ab63 Mon Sep 17 00:00:00 2001 +From: Alex Bee +Date: Sat, 17 Oct 2020 20:52:04 +0200 +Subject: [PATCH] ARM: dts: RK3066a add missing cpu freq + +This adds the previously added cpufreq to DT. It is disabled by +default, since it needs also the logic voltage to increased and +has therefore to be enabled in board level DT where both logic +and arm regulators are available. + +Signed-off-by: Alex Bee +--- + arch/arm/boot/dts/rk3066a.dtsi | 5 +++++ + 1 file changed, 5 insertions(+) + +diff --git a/arch/arm/boot/dts/rk3066a.dtsi b/arch/arm/boot/dts/rk3066a.dtsi +index 84d7053d91f8..f71529e6949f 100644 +--- a/arch/arm/boot/dts/rk3066a.dtsi ++++ b/arch/arm/boot/dts/rk3066a.dtsi +@@ -74,6 +74,11 @@ opp-1416000000 { + opp-hz = /bits/ 64 <1416000000>; + opp-microvolt = <1300000>; + }; ++ opp-1608000000 { ++ opp-hz = /bits/ 64 <1608000000>; ++ opp-microvolt = <1400000>; ++ status = "disabled"; ++ }; + }; + + display-subsystem { + +From cdd942ba744ff0a9705529776c881f57af0ec96b Mon Sep 17 00:00:00 2001 +From: Alex Bee +Date: Mon, 30 Nov 2020 23:54:22 +0100 +Subject: [PATCH] net: arc_emac: fix dma_map* / dma_unmap_* devices + +Commit 4e57482e8440 ("dma-direct: Fix potential NULL pointer dereference") +started checking for the existence of dev->dma_mask in dma_map_page_attrs, +which seems reasonable. +However from this commit on emac driver's dma mapping failed. During code +review it turned out, that all dma_map_* dma_unmap_* calls are using the +net-dev (which obviously doesn't have dma_mask attribute). On the other +hand in arc_emac_probe its parent (the actual emac device) is used for +dmam_alloc_coherent. +To fix this the net-dev's parent has to be used dma_map* / dma_unmap_* +calls as well. + +Signed-off-by: Alex Bee +--- + drivers/net/ethernet/arc/emac_main.c | 20 ++++++++++---------- + 1 file changed, 10 insertions(+), 10 deletions(-) + +diff --git a/drivers/net/ethernet/arc/emac_main.c b/drivers/net/ethernet/arc/emac_main.c +index b56a9e2aecd9..03e3ba81bebd 100644 +--- a/drivers/net/ethernet/arc/emac_main.c ++++ b/drivers/net/ethernet/arc/emac_main.c +@@ -140,7 +140,7 @@ static void arc_emac_tx_clean(struct net_device *ndev) + stats->tx_bytes += skb->len; + } + +- dma_unmap_single(&ndev->dev, dma_unmap_addr(tx_buff, addr), ++ dma_unmap_single(ndev->dev.parent, dma_unmap_addr(tx_buff, addr), + dma_unmap_len(tx_buff, len), DMA_TO_DEVICE); + + /* return the sk_buff to system */ +@@ -223,9 +223,9 @@ static int arc_emac_rx(struct net_device *ndev, int budget) + continue; + } + +- addr = dma_map_single(&ndev->dev, (void *)skb->data, ++ addr = dma_map_single(ndev->dev.parent, (void *)skb->data, + EMAC_BUFFER_SIZE, DMA_FROM_DEVICE); +- if (dma_mapping_error(&ndev->dev, addr)) { ++ if (dma_mapping_error(ndev->dev.parent, addr)) { + if (net_ratelimit()) + netdev_err(ndev, "cannot map dma buffer\n"); + dev_kfree_skb(skb); +@@ -237,7 +237,7 @@ static int arc_emac_rx(struct net_device *ndev, int budget) + } + + /* unmap previosly mapped skb */ +- dma_unmap_single(&ndev->dev, dma_unmap_addr(rx_buff, addr), ++ dma_unmap_single(ndev->dev.parent, dma_unmap_addr(rx_buff, addr), + dma_unmap_len(rx_buff, len), DMA_FROM_DEVICE); + + pktlen = info & LEN_MASK; +@@ -445,9 +445,9 @@ static int arc_emac_open(struct net_device *ndev) + if (unlikely(!rx_buff->skb)) + return -ENOMEM; + +- addr = dma_map_single(&ndev->dev, (void *)rx_buff->skb->data, ++ addr = dma_map_single(ndev->dev.parent, (void *)rx_buff->skb->data, + EMAC_BUFFER_SIZE, DMA_FROM_DEVICE); +- if (dma_mapping_error(&ndev->dev, addr)) { ++ if (dma_mapping_error(ndev->dev.parent, addr)) { + netdev_err(ndev, "cannot dma map\n"); + dev_kfree_skb(rx_buff->skb); + return -ENOMEM; +@@ -555,7 +555,7 @@ static void arc_free_tx_queue(struct net_device *ndev) + struct buffer_state *tx_buff = &priv->tx_buff[i]; + + if (tx_buff->skb) { +- dma_unmap_single(&ndev->dev, ++ dma_unmap_single(ndev->dev.parent, + dma_unmap_addr(tx_buff, addr), + dma_unmap_len(tx_buff, len), + DMA_TO_DEVICE); +@@ -586,7 +586,7 @@ static void arc_free_rx_queue(struct net_device *ndev) + struct buffer_state *rx_buff = &priv->rx_buff[i]; + + if (rx_buff->skb) { +- dma_unmap_single(&ndev->dev, ++ dma_unmap_single(ndev->dev.parent, + dma_unmap_addr(rx_buff, addr), + dma_unmap_len(rx_buff, len), + DMA_FROM_DEVICE); +@@ -692,10 +692,10 @@ static netdev_tx_t arc_emac_tx(struct sk_buff *skb, struct net_device *ndev) + return NETDEV_TX_BUSY; + } + +- addr = dma_map_single(&ndev->dev, (void *)skb->data, len, ++ addr = dma_map_single(ndev->dev.parent, (void *)skb->data, len, + DMA_TO_DEVICE); + +- if (unlikely(dma_mapping_error(&ndev->dev, addr))) { ++ if (unlikely(dma_mapping_error(ndev->dev.parent, addr))) { + stats->tx_dropped++; + stats->tx_errors++; + dev_kfree_skb_any(skb); + +From 04217d19aac7197c97ce132a5f53d21d018de4dd Mon Sep 17 00:00:00 2001 +From: Alex Bee +Date: Tue, 1 Dec 2020 01:03:37 +0100 +Subject: [PATCH] net: arc_emac: Add phy fixup for RTL8201F + +As stated in RTL8201F's datasheet the powersave functionality +has to be disabled in case the PHY's clock is used as clock +input for the mac interface. (which is the default) +Currently the mac interface is "hanging" for a couple of +seconds whenever there was no TX for some time. +Also EEE capabilities of this phy have to be disabled, +otherwise constant link up / link down events are triggered +when there is no traffic and emac will hang is this case +as well. + +Signed-off-by: Alex Bee +--- + drivers/net/ethernet/arc/emac.h | 14 +++++++ + drivers/net/ethernet/arc/emac_main.c | 61 ++++++++++++++++++++++++++++ + 2 files changed, 75 insertions(+) + +diff --git a/drivers/net/ethernet/arc/emac.h b/drivers/net/ethernet/arc/emac.h +index d820ae03a966..0ac87288b97d 100644 +--- a/drivers/net/ethernet/arc/emac.h ++++ b/drivers/net/ethernet/arc/emac.h +@@ -91,6 +91,20 @@ struct arc_emac_bd { + #define RX_RING_SZ (RX_BD_NUM * sizeof(struct arc_emac_bd)) + #define TX_RING_SZ (TX_BD_NUM * sizeof(struct arc_emac_bd)) + ++/* PHY fixups */ ++#define RTL_8201F_PHY_ID 0x001cc816 ++ ++#define RTL_8201F_PG_SELECT_REG 0x1f ++#define RTL_8201F_PG4_EEE_REG 0x10 ++#define RTL_8201F_PG4_EEE_RX_QUIET_EN BIT(8) ++#define RTL_8201F_PG4_EEE_TX_QUIET_EN BIT(9) ++#define RTL_8201F_PG4_EEE_NWAY_EN BIT(12) ++#define RTL_8201F_PG4_EEE_10M_CAP BIT(13) ++#define RTL_8201F_PG7_RMSR_REG 0x10 ++#define RTL_8201F_PG7_RMSR_CLK_DIR_IN BIT(12) ++#define RTL_8201F_PG0_PSMR_REG 0x18 ++#define RTL_8201F_PG0_PSMR_PWRSVE_EN BIT(15) ++ + /** + * struct buffer_state - Stores Rx/Tx buffer state. + * @sk_buff: Pointer to socket buffer. +diff --git a/drivers/net/ethernet/arc/emac_main.c b/drivers/net/ethernet/arc/emac_main.c +index 03e3ba81bebd..68089df758fa 100644 +--- a/drivers/net/ethernet/arc/emac_main.c ++++ b/drivers/net/ethernet/arc/emac_main.c +@@ -850,6 +850,62 @@ static const struct net_device_ops arc_emac_netdev_ops = { + #endif + }; + ++/** ++ * arc_emac_rtl8201f_phy_fixup ++ * @phydev: Pointer to phy_device structure. ++ * ++ * This function registers a fixup in case RTL8201F's phy ++ * clockout is used as reference for the mac interface ++ * and disable EEE, since emac can't handle it ++ */ ++static int arc_emac_rtl8201f_phy_fixup(struct phy_device *phydev) ++{ ++ unsigned int reg, curr_pg; ++ int err = 0; ++ ++ curr_pg = phy_read(phydev, RTL_8201F_PG_SELECT_REG); ++ err = phy_write(phydev, RTL_8201F_PG_SELECT_REG, 4); ++ if (err) ++ goto out_err; ++ mdelay(10); ++ ++ /* disable EEE */ ++ reg = phy_read(phydev, RTL_8201F_PG4_EEE_REG); ++ reg &= ~RTL_8201F_PG4_EEE_RX_QUIET_EN & ++ ~RTL_8201F_PG4_EEE_TX_QUIET_EN & ++ ~RTL_8201F_PG4_EEE_NWAY_EN & ++ ~RTL_8201F_PG4_EEE_10M_CAP; ++ err = phy_write(phydev, RTL_8201F_PG4_EEE_REG, reg); ++ if (err) ++ goto out_err; ++ ++ if (phydev->interface == PHY_INTERFACE_MODE_RMII) { ++ err = phy_write(phydev, RTL_8201F_PG_SELECT_REG, 7); ++ if (err) ++ goto out_err; ++ mdelay(10); ++ ++ reg = phy_read(phydev, RTL_8201F_PG7_RMSR_REG); ++ err = phy_write(phydev, RTL_8201F_PG_SELECT_REG, 0); ++ if (err) ++ goto out_err; ++ mdelay(10); ++ ++ if (!(reg & RTL_8201F_PG7_RMSR_CLK_DIR_IN)) { ++ /* disable powersave if phy's clock output is used */ ++ reg = phy_read(phydev, RTL_8201F_PG0_PSMR_REG); ++ reg &= ~RTL_8201F_PG0_PSMR_PWRSVE_EN & 0xffff; ++ err = phy_write(phydev, RTL_8201F_PG0_PSMR_REG, reg); ++ } ++ } ++ ++out_err: ++ phy_write(phydev, RTL_8201F_PG_SELECT_REG, curr_pg); ++ mdelay(10); ++ ++ return err; ++}; ++ + int arc_emac_probe(struct net_device *ndev, int interface) + { + struct device *dev = ndev->dev.parent; +@@ -974,6 +1030,11 @@ int arc_emac_probe(struct net_device *ndev, int interface) + goto out_clken; + } + ++ err = phy_register_fixup_for_uid(RTL_8201F_PHY_ID, 0xfffff0, ++ arc_emac_rtl8201f_phy_fixup); ++ if (err) ++ dev_warn(dev, "Cannot register PHY board fixup.\n"); ++ + phydev = of_phy_connect(ndev, phy_node, arc_emac_adjust_link, 0, + interface); + if (!phydev) { + +From b9de203365b74ee111d977424ed3fe8d325cc39b Mon Sep 17 00:00:00 2001 +From: Alex Bee +Date: Mon, 30 Nov 2020 21:12:12 +0100 +Subject: [PATCH] ARM: dts: rk3xx add L2 properties + +As per vendor source, these properties have to be set. It has been +oberserved without them, cpu(s) might hang on boot process. + +Signed-off-by: Alex Bee +--- + arch/arm/boot/dts/rk3xxx.dtsi | 2 ++ + 1 file changed, 2 insertions(+) + +diff --git a/arch/arm/boot/dts/rk3xxx.dtsi b/arch/arm/boot/dts/rk3xxx.dtsi +index 97415180d5bb..d04391e8ee7c 100644 +--- a/arch/arm/boot/dts/rk3xxx.dtsi ++++ b/arch/arm/boot/dts/rk3xxx.dtsi +@@ -99,6 +99,8 @@ L2: cache-controller@10138000 { + reg = <0x10138000 0x1000>; + cache-unified; + cache-level = <2>; ++ prefetch-data = <1>; ++ prefetch-instr = <1>; + }; + + scu@1013c000 { + +From 11ffa728158fba63164295371cbdfc61af81ff3e Mon Sep 17 00:00:00 2001 +From: Alex Bee +Date: Mon, 10 Feb 2020 16:34:04 +0100 +Subject: [PATCH] ARM64: dts: rk3328 add mmc resets + +Signed-off-by: Alex Bee +--- + arch/arm64/boot/dts/rockchip/rk3328.dtsi | 6 ++++++ + 1 file changed, 6 insertions(+) + +diff --git a/arch/arm64/boot/dts/rockchip/rk3328.dtsi b/arch/arm64/boot/dts/rockchip/rk3328.dtsi +index db0d5c8e5f96..d89c3ada8bb5 100644 +--- a/arch/arm64/boot/dts/rockchip/rk3328.dtsi ++++ b/arch/arm64/boot/dts/rockchip/rk3328.dtsi +@@ -862,6 +862,8 @@ sdmmc: mmc@ff500000 { + clock-names = "biu", "ciu", "ciu-drive", "ciu-sample"; + fifo-depth = <0x100>; + max-frequency = <150000000>; ++ resets = <&cru SRST_MMC0>; ++ reset-names = "reset"; + status = "disabled"; + }; + +@@ -874,6 +876,8 @@ sdio: mmc@ff510000 { + clock-names = "biu", "ciu", "ciu-drive", "ciu-sample"; + fifo-depth = <0x100>; + max-frequency = <150000000>; ++ resets = <&cru SRST_SDIO>; ++ reset-names = "reset"; + status = "disabled"; + }; + +@@ -886,6 +890,8 @@ emmc: mmc@ff520000 { + clock-names = "biu", "ciu", "ciu-drive", "ciu-sample"; + fifo-depth = <0x100>; + max-frequency = <150000000>; ++ resets = <&cru SRST_EMMC>; ++ reset-names = "reset"; + status = "disabled"; + }; + + +From c5b9dbf8be5f1b43ba1de09c01d22211cda2bca1 Mon Sep 17 00:00:00 2001 +From: Alex Bee +Date: Mon, 10 Feb 2020 19:22:41 +0100 +Subject: [PATCH] ARM64: dts: rk3328 add sdmmc ext node + +Signed-off-by: Alex Bee +--- + arch/arm64/boot/dts/rockchip/rk3328.dtsi | 14 ++++++++++++++ + 1 file changed, 14 insertions(+) + +diff --git a/arch/arm64/boot/dts/rockchip/rk3328.dtsi b/arch/arm64/boot/dts/rockchip/rk3328.dtsi +index d89c3ada8bb5..17c556183807 100644 +--- a/arch/arm64/boot/dts/rockchip/rk3328.dtsi ++++ b/arch/arm64/boot/dts/rockchip/rk3328.dtsi +@@ -989,6 +989,20 @@ usb_host0_ohci: usb@ff5d0000 { + status = "disabled"; + }; + ++ sdmmc_ext: dwmmc@ff5f0000 { ++ compatible = "rockchip,rk3328-dw-mshc", "rockchip,rk3288-dw-mshc"; ++ reg = <0x0 0xff5f0000 0x0 0x4000>; ++ interrupts = ; ++ clocks = <&cru HCLK_SDMMC_EXT>, <&cru SCLK_SDMMC_EXT>, ++ <&cru SCLK_SDMMC_EXT_DRV>, <&cru SCLK_SDMMC_EXT_SAMPLE>; ++ clock-names = "biu", "ciu", "ciu-drive", "ciu-sample"; ++ fifo-depth = <0x100>; ++ max-frequency = <150000000>; ++ resets = <&cru SRST_SDMMCEXT>; ++ reset-names = "reset"; ++ status = "disabled"; ++ }; ++ + gic: interrupt-controller@ff811000 { + compatible = "arm,gic-400"; + #interrupt-cells = <3>; + +From 9bb697a154bc838094e2dda77d345cfd09c80bde Mon Sep 17 00:00:00 2001 +From: Alex Bee +Date: Mon, 10 Feb 2020 19:24:54 +0100 +Subject: [PATCH] ARM64: dts: rk3328 add gpu powerdomain + +Signed-off-by: Alex Bee +--- + arch/arm64/boot/dts/rockchip/rk3328.dtsi | 5 +++++ + 1 file changed, 5 insertions(+) + +diff --git a/arch/arm64/boot/dts/rockchip/rk3328.dtsi b/arch/arm64/boot/dts/rockchip/rk3328.dtsi +index 17c556183807..656379a8e6cd 100644 +--- a/arch/arm64/boot/dts/rockchip/rk3328.dtsi ++++ b/arch/arm64/boot/dts/rockchip/rk3328.dtsi +@@ -318,6 +318,10 @@ power: power-controller { + #address-cells = <1>; + #size-cells = <0>; + ++ pd_gpu@RK3328_PD_GPU { ++ reg = ; ++ clocks = <&cru ACLK_GPU>; ++ }; + pd_hevc@RK3328_PD_HEVC { + reg = ; + }; +@@ -620,6 +624,7 @@ gpu: gpu@ff300000 { + "ppmmu1"; + clocks = <&cru ACLK_GPU>, <&cru ACLK_GPU>; + clock-names = "bus", "core"; ++ power-domains = <&power RK3328_PD_GPU>; + resets = <&cru SRST_GPU_A>; + }; + + +From a57c0fc274e83a2c40b31e66bcd009b9508d3f3c Mon Sep 17 00:00:00 2001 +From: Alex Bee +Date: Tue, 11 Feb 2020 16:11:22 +0100 +Subject: [PATCH] ARM64: dts: rk3328 adjust clock settings + +Signed-off-by: Alex Bee +--- + arch/arm64/boot/dts/rockchip/rk3328.dtsi | 24 +++++++++++++++++++----- + 1 file changed, 19 insertions(+), 5 deletions(-) + +diff --git a/arch/arm64/boot/dts/rockchip/rk3328.dtsi b/arch/arm64/boot/dts/rockchip/rk3328.dtsi +index 656379a8e6cd..abe7f1573825 100644 +--- a/arch/arm64/boot/dts/rockchip/rk3328.dtsi ++++ b/arch/arm64/boot/dts/rockchip/rk3328.dtsi +@@ -786,8 +786,7 @@ cru: clock-controller@ff440000 { + <&cru SCLK_RTC32K>, <&cru SCLK_UART0>, + <&cru SCLK_UART1>, <&cru SCLK_UART2>, + <&cru ACLK_BUS_PRE>, <&cru ACLK_PERI_PRE>, +- <&cru ACLK_VIO_PRE>, <&cru ACLK_RGA_PRE>, +- <&cru ACLK_VOP_PRE>, <&cru ACLK_RKVDEC_PRE>, ++ <&cru ACLK_RGA_PRE>, <&cru ACLK_RKVDEC_PRE>, + <&cru ACLK_RKVENC>, <&cru ACLK_VPU_PRE>, + <&cru SCLK_VDEC_CABAC>, <&cru SCLK_VDEC_CORE>, + <&cru SCLK_VENC_CORE>, <&cru SCLK_VENC_DSP>, +@@ -797,7 +796,15 @@ cru: clock-controller@ff440000 { + <&cru ACLK_BUS_PRE>, <&cru HCLK_BUS_PRE>, + <&cru PCLK_BUS_PRE>, <&cru ACLK_PERI_PRE>, + <&cru HCLK_PERI>, <&cru PCLK_PERI>, +- <&cru SCLK_RTC32K>; ++ <&cru ACLK_VIO_PRE>, <&cru HCLK_VIO_PRE>, ++ <&cru ACLK_RGA_PRE>, <&cru SCLK_RGA>, ++ <&cru ACLK_VOP_PRE>, <&cru ACLK_RKVDEC_PRE>, ++ <&cru ACLK_RKVENC>, <&cru ACLK_VPU_PRE>, ++ <&cru SCLK_VDEC_CABAC>, <&cru SCLK_VDEC_CORE>, ++ <&cru SCLK_VENC_CORE>, <&cru SCLK_VENC_DSP>, ++ <&cru SCLK_EFUSE>, <&cru PCLK_DDR>, ++ <&cru ACLK_GMAC>, <&cru PCLK_GMAC>, ++ <&cru SCLK_RTC32K>, <&cru SCLK_USB3OTG_SUSPEND>; + assigned-clock-parents = + <&cru HDMIPHY>, <&cru PLL_APLL>, + <&cru PLL_GPLL>, <&xin24m>, +@@ -808,7 +815,6 @@ cru: clock-controller@ff440000 { + <24000000>, <24000000>, + <15000000>, <15000000>, + <100000000>, <100000000>, +- <100000000>, <100000000>, + <50000000>, <100000000>, + <100000000>, <100000000>, + <50000000>, <50000000>, +@@ -818,7 +824,15 @@ cru: clock-controller@ff440000 { + <150000000>, <75000000>, + <75000000>, <150000000>, + <75000000>, <75000000>, +- <32768>; ++ <300000000>, <100000000>, ++ <300000000>, <200000000>, ++ <400000000>, <500000000>, ++ <200000000>, <300000000>, ++ <300000000>, <250000000>, ++ <200000000>, <100000000>, ++ <24000000>, <100000000>, ++ <150000000>, <50000000>, ++ <32768>, <32768>; + }; + + usb2phy_grf: syscon@ff450000 { diff --git a/patch/kernel/rk322x-current/01-linux-1002-rockchip-drm-wip.patch b/patch/kernel/rk322x-current/01-linux-1001-drm-wip.patch similarity index 65% rename from patch/kernel/rk322x-current/01-linux-1002-rockchip-drm-wip.patch rename to patch/kernel/rk322x-current/01-linux-1001-drm-wip.patch index ec4a02706..957f36ad6 100644 --- a/patch/kernel/rk322x-current/01-linux-1002-rockchip-drm-wip.patch +++ b/patch/kernel/rk322x-current/01-linux-1001-drm-wip.patch @@ -1,367 +1,4 @@ -From dd7efcfd32481cecf647067cedd23c1d799daead Mon Sep 17 00:00:00 2001 -From: Jonas Karlman -Date: Wed, 8 Jan 2020 21:07:47 +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 b1a9ff0131eb..f784408926d6 100644 ---- a/drivers/phy/rockchip/phy-rockchip-inno-hdmi.c -+++ b/drivers/phy/rockchip/phy-rockchip-inno-hdmi.c -@@ -797,8 +797,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 3b35058e573c01959e413e4899f3c6a6be8058da Mon Sep 17 00:00:00 2001 -From: Zheng Yang -Date: Wed, 8 Jan 2020 21:07:48 +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 f784408926d6..4f000942c824 100644 ---- a/drivers/phy/rockchip/phy-rockchip-inno-hdmi.c -+++ b/drivers/phy/rockchip/phy-rockchip-inno-hdmi.c -@@ -752,10 +752,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 893babbe917db2895ead295b8897c74f40396afe Mon Sep 17 00:00:00 2001 -From: Jonas Karlman -Date: Wed, 8 Jan 2020 21:07:48 +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 4f000942c824..05a5362c1f73 100644 ---- a/drivers/phy/rockchip/phy-rockchip-inno-hdmi.c -+++ b/drivers/phy/rockchip/phy-rockchip-inno-hdmi.c -@@ -721,7 +721,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; - -@@ -744,9 +744,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 8674a04f14c6bb56b84dcf934f4f921c213e62e5 Mon Sep 17 00:00:00 2001 -From: Jonas Karlman -Date: Wed, 8 Jan 2020 21:07:48 +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 05a5362c1f73..5e07346af27c 100644 ---- a/drivers/phy/rockchip/phy-rockchip-inno-hdmi.c -+++ b/drivers/phy/rockchip/phy-rockchip-inno-hdmi.c -@@ -1054,9 +1054,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; -@@ -1064,7 +1065,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 e6e89b9198928abb1fc417985cce8000b2e55839 Mon Sep 17 00:00:00 2001 -From: Huicong Xu -Date: Wed, 8 Jan 2020 21:07:49 +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 5e07346af27c..29e9a1c1e76b 100644 ---- a/drivers/phy/rockchip/phy-rockchip-inno-hdmi.c -+++ b/drivers/phy/rockchip/phy-rockchip-inno-hdmi.c -@@ -248,6 +248,7 @@ struct inno_hdmi_phy { - struct clk_hw hw; - struct clk *phyclk; - unsigned long pixclock; -+ unsigned long tmdsclock; - }; - - struct pre_pll_config { -@@ -492,6 +493,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; -@@ -516,6 +519,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; -@@ -635,6 +640,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); -@@ -677,6 +685,7 @@ static int inno_hdmi_phy_rk3228_clk_set_rate(struct clk_hw *hw, - } - - inno->pixclock = rate; -+ inno->tmdsclock = tmdsclock; - - return 0; - } -@@ -788,6 +797,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); -@@ -827,6 +839,7 @@ static int inno_hdmi_phy_rk3328_clk_set_rate(struct clk_hw *hw, - } - - inno->pixclock = rate; -+ inno->tmdsclock = tmdsclock; - - return 0; - } - -From 43a9498fb30c743d2afe70b9d39f561910ddcb5b Mon Sep 17 00:00:00 2001 -From: Algea Cao -Date: Wed, 8 Jan 2020 21:07:53 +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 29e9a1c1e76b..0c7a97352714 100644 ---- a/drivers/phy/rockchip/phy-rockchip-inno-hdmi.c -+++ b/drivers/phy/rockchip/phy-rockchip-inno-hdmi.c -@@ -294,32 +294,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 d9dca0f6a52f6d013240398187c4460600abcdf4 Mon Sep 17 00:00:00 2001 +From 0af28d066edbb4297d5140ff4c93db7b0bc0b182 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 @@ -424,7 +61,7 @@ index c80f7d9fd13f..6cbdb4672a4b 100644 .atomic_check = vop_crtc_atomic_check, .atomic_begin = vop_crtc_atomic_begin, -From b6030ac943d755d31b69c658f498999875a0a46d Mon Sep 17 00:00:00 2001 +From 35e601dd9730b541bde93ec5cd5320b2c14a84fa Mon Sep 17 00:00:00 2001 From: Jonas Karlman Date: Mon, 20 Jul 2020 11:46:16 +0000 Subject: [PATCH] WIP: drm/rockchip: vop: max_output @@ -543,36 +180,7 @@ index 80053d91a301..57c36e9207c1 100644 .common = &rk3328_common, .modeset = &rk3328_modeset, -From 7c8b58413c38c263e4a9103281a214cb3a2db69c 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 bbdb19a3e85d..6547e2b4b617 100644 ---- a/arch/arm64/boot/dts/rockchip/rk3328.dtsi -+++ b/arch/arm64/boot/dts/rockchip/rk3328.dtsi -@@ -802,8 +802,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>, - -From b6d211f4b212569724efed3c9eaaf06615268d61 Mon Sep 17 00:00:00 2001 +From 61b85ebc7d075446c5f8a57607eb1fc87b16e2a8 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 @@ -598,7 +206,7 @@ index 23de359a1dec..cdf953850873 100644 } -From 1efdc8bf4ab51829d5b086f6bc45e7f02da1170c Mon Sep 17 00:00:00 2001 +From a1675f5032286c3f2e939a7392361fc15099c0b7 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 @@ -652,7 +260,7 @@ index cdf953850873..4652c0e0dcd6 100644 { ~0UL, 0x0000, 0x0000, 0x0000} }; -From d010c041afc48d4592625e23082aa31871042847 Mon Sep 17 00:00:00 2001 +From 15a5f1ae8e0f570e81affb35b9b4aa4c0f485614 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 @@ -678,7 +286,7 @@ index 4652c0e0dcd6..10c3dc521cbd 100644 }; -From c4e637b2fc48c3bdb6f1ff8d5a5883e21587f051 Mon Sep 17 00:00:00 2001 +From 43ac4790ecf27cf8db51e68298c541224af046a6 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 @@ -723,7 +331,7 @@ index 10c3dc521cbd..cc7675638e4f 100644 } }; -From 2b9a23ae36142d8d4d9fcce63a90b9c8329ad187 Mon Sep 17 00:00:00 2001 +From 7604ef86c3d010fbfa61cf030b055b3860a53682 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 @@ -908,7 +516,7 @@ index cc7675638e4f..c4c158106ca4 100644 } }; -From fd940089282dffc01cc7b45a5aef11acd59a4f9f Mon Sep 17 00:00:00 2001 +From 119aca9dc20be1639fe8146237d2821695a2bc6b 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 @@ -955,7 +563,7 @@ index c4c158106ca4..b62d8f4fc9a8 100644 static void dw_hdmi_rockchip_encoder_disable(struct drm_encoder *encoder) -From c2ac79d4d979bc7cdee94bc4ecad5946b31d2caf Mon Sep 17 00:00:00 2001 +From 9f31d6e1e2951eeaa979e1f9eb4b04cb64a4daf8 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 @@ -979,7 +587,7 @@ index b62d8f4fc9a8..6f7641fbe6cc 100644 static void dw_hdmi_rockchip_encoder_disable(struct drm_encoder *encoder) -From f7e97888e1b955bee4e7fc778b9434c3c3aeaa1c Mon Sep 17 00:00:00 2001 +From bea1222407f1eb9d6af776d98eae5bd0f3544134 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 @@ -1018,7 +626,7 @@ index 6f7641fbe6cc..cc20a83fa9b8 100644 .phy_ops = &rk3328_hdmi_phy_ops, .phy_name = "inno_dw_hdmi_phy2", -From db3a0bad2ab53b12c7dbeec032cb8f3d7ef0563d Mon Sep 17 00:00:00 2001 +From 0bd355e25df8c93481ea6995bec7f452da97d5bf 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 @@ -1029,7 +637,7 @@ Signed-off-by: Jonas Karlman 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/clk/rockchip/clk-rk3228.c b/drivers/clk/rockchip/clk-rk3228.c -index 6c39ecd3db7e..0c422e4bb213 100644 +index 2ac006e99c03..1f9176a5cc07 100644 --- a/drivers/clk/rockchip/clk-rk3228.c +++ b/drivers/clk/rockchip/clk-rk3228.c @@ -393,7 +393,7 @@ static struct rockchip_clk_branch rk3228_clk_branches[] __initdata = { @@ -1042,7 +650,7 @@ index 6c39ecd3db7e..0c422e4bb213 100644 FACTOR(0, "xin12m", "xin24m", 0, 1, 2), -From d25ae20e096caca3783c95d14586a4357fa83449 Mon Sep 17 00:00:00 2001 +From 957c41ed6b5a182b12880b6f16f6e17d034bf483 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 @@ -1093,7 +701,7 @@ index 15c8f1dcba9a..460b19d65ef3 100644 RK3288_CLKGATE_CON(3), 1, GFLAGS), COMPOSITE(DCLK_VOP1, "dclk_vop1", mux_pll_src_cpll_gpll_npll_p, 0, -From f971cfab78a201e0e4c3413a69b3ab1467ca6e3e Mon Sep 17 00:00:00 2001 +From 0f7295f13d592ba60dee79a0cc23302ed2febffa 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 @@ -1148,7 +756,7 @@ index 460b19d65ef3..b973c6b0315b 100644 static struct clk_div_table div_hclk_cpu_t[] = { -From 611c4656dadc68be76767b04c27266c183748090 Mon Sep 17 00:00:00 2001 +From e9d9694635e5cd9a84779e045c670239fc255606 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 @@ -1200,7 +808,7 @@ index b973c6b0315b..9192b89c2550 100644 }; -From 1e71e8f100f877a3fb04a63c437869732bab5974 Mon Sep 17 00:00:00 2001 +From 2e18be0e366e9afcfe7dcdb69c3c90cce472bfa0 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 @@ -1291,7 +899,7 @@ index 3682d5675cf7..0934145c09ad 100644 RK3399_CLKGATE_CON(10), 12, GFLAGS), -From aafa27ca194b5601de77c56773aa69c2e2db0051 Mon Sep 17 00:00:00 2001 +From b2d23eae37a78a425144a21eb8bfbedc03edc754 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 @@ -1329,10 +937,10 @@ index a376dea3bb1b..9757976d6e8a 100644 }; }; diff --git a/arch/arm64/boot/dts/rockchip/rk3399.dtsi b/arch/arm64/boot/dts/rockchip/rk3399.dtsi -index ada724b12f01..8973bf68d652 100644 +index f5dee5f447bb..3e44bf8eac5c 100644 --- a/arch/arm64/boot/dts/rockchip/rk3399.dtsi +++ b/arch/arm64/boot/dts/rockchip/rk3399.dtsi -@@ -1637,11 +1637,6 @@ vopl_out_edp: endpoint@1 { +@@ -1640,11 +1640,6 @@ vopl_out_edp: endpoint@1 { remote-endpoint = <&edp_in_vopl>; }; @@ -1344,7 +952,7 @@ index ada724b12f01..8973bf68d652 100644 vopl_out_mipi1: endpoint@3 { reg = <3>; remote-endpoint = <&mipi1_in_vopl>; -@@ -1787,10 +1782,6 @@ hdmi_in_vopb: endpoint@0 { +@@ -1816,10 +1811,6 @@ hdmi_in_vopb: endpoint@0 { reg = <0>; remote-endpoint = <&vopb_out_hdmi>; }; @@ -1356,232 +964,7 @@ index ada724b12f01..8973bf68d652 100644 }; }; -From 667178b6aeeeca36baf3f739902e5888efce6705 Mon Sep 17 00:00:00 2001 -From: Jonas Karlman -Date: Tue, 26 Feb 2019 20:45:14 +0000 -Subject: [PATCH] WIP: dw-hdmi-cec: sleep 100ms on error - -Signed-off-by: Jonas Karlman ---- - drivers/gpu/drm/bridge/synopsys/dw-hdmi-cec.c | 19 +++++++++++++++++-- - 1 file changed, 17 insertions(+), 2 deletions(-) - -diff --git a/drivers/gpu/drm/bridge/synopsys/dw-hdmi-cec.c b/drivers/gpu/drm/bridge/synopsys/dw-hdmi-cec.c -index 70ab4fbdc23e..f6a85f73b90d 100644 ---- a/drivers/gpu/drm/bridge/synopsys/dw-hdmi-cec.c -+++ b/drivers/gpu/drm/bridge/synopsys/dw-hdmi-cec.c -@@ -4,6 +4,7 @@ - * - * Copyright (C) 2015-2017 Russell King. - */ -+#include - #include - #include - #include -@@ -129,8 +130,16 @@ static irqreturn_t dw_hdmi_cec_hardirq(int irq, void *data) - - dw_hdmi_write(cec, stat, HDMI_IH_CEC_STAT0); - -- if (stat & CEC_STAT_ERROR_INIT) { -- cec->tx_status = CEC_TX_STATUS_ERROR; -+ /* -+ * Status with both done and error_initiator bits have been seen -+ * on Rockchip RK3328 devices, transmit attempt seems to have failed -+ * when this happens, report as low drive and block cec-framework -+ * 100ms before core retransmits the failed message, this seems to -+ * mitigate the issue with failed transmit attempts. -+ */ -+ if ((stat & (CEC_STAT_DONE|CEC_STAT_ERROR_INIT)) == (CEC_STAT_DONE|CEC_STAT_ERROR_INIT)) { -+ pr_info("dw_hdmi_cec_hardirq: stat=%02x LOW_DRIVE\n", stat); -+ cec->tx_status = CEC_TX_STATUS_LOW_DRIVE; - cec->tx_done = true; - ret = IRQ_WAKE_THREAD; - } else if (stat & CEC_STAT_DONE) { -@@ -141,6 +150,10 @@ static irqreturn_t dw_hdmi_cec_hardirq(int irq, void *data) - cec->tx_status = CEC_TX_STATUS_NACK; - cec->tx_done = true; - ret = IRQ_WAKE_THREAD; -+ } else if (stat & CEC_STAT_ERROR_INIT) { -+ cec->tx_status = CEC_TX_STATUS_ERROR; -+ cec->tx_done = true; -+ ret = IRQ_WAKE_THREAD; - } - - if (stat & CEC_STAT_EOM) { -@@ -173,6 +186,8 @@ static irqreturn_t dw_hdmi_cec_thread(int irq, void *data) - - if (cec->tx_done) { - cec->tx_done = false; -+ if (cec->tx_status == CEC_TX_STATUS_LOW_DRIVE) -+ msleep(100); - cec_transmit_attempt_done(adap, cec->tx_status); - } - if (cec->rx_done) { - -From 2642ca152420726d73313a469423e6447df393a6 Mon Sep 17 00:00:00 2001 -From: Jonas Karlman -Date: Sat, 18 Jul 2020 20:54:38 +0000 -Subject: [PATCH] asdf - ---- - drivers/gpu/drm/bridge/synopsys/dw-hdmi-cec.c | 36 +++++++++++++++---- - drivers/media/cec/core/cec-adap.c | 2 +- - 2 files changed, 30 insertions(+), 8 deletions(-) - -diff --git a/drivers/gpu/drm/bridge/synopsys/dw-hdmi-cec.c b/drivers/gpu/drm/bridge/synopsys/dw-hdmi-cec.c -index f6a85f73b90d..e6953219beee 100644 ---- a/drivers/gpu/drm/bridge/synopsys/dw-hdmi-cec.c -+++ b/drivers/gpu/drm/bridge/synopsys/dw-hdmi-cec.c -@@ -58,6 +58,7 @@ struct dw_hdmi_cec { - u32 addresses; - struct cec_adapter *adap; - struct cec_msg rx_msg; -+ unsigned int tx_attempts; - unsigned int tx_status; - bool tx_done; - bool rx_done; -@@ -96,6 +97,8 @@ static int dw_hdmi_cec_transmit(struct cec_adapter *adap, u8 attempts, - struct dw_hdmi_cec *cec = cec_get_drvdata(adap); - unsigned int i, ctrl; - -+ pr_info("%s: attempts=%u signal_free_time=%u msg=%*ph (sequence: %u)\n", __func__, attempts, signal_free_time, msg->len, msg->msg, msg->sequence); -+ - switch (signal_free_time) { - case CEC_SIGNAL_FREE_TIME_RETRY: - ctrl = CEC_CTRL_RETRY; -@@ -131,26 +134,35 @@ static irqreturn_t dw_hdmi_cec_hardirq(int irq, void *data) - dw_hdmi_write(cec, stat, HDMI_IH_CEC_STAT0); - - /* -- * Status with both done and error_initiator bits have been seen -- * on Rockchip RK3328 devices, transmit attempt seems to have failed -- * when this happens, report as low drive and block cec-framework -+ * Status with both done and error_initiator bits have been observed -+ * on Rockchip RK3328/RK3399 devices, transmit attempt seems to have -+ * failed when this happens, report as low drive and block cec-framework - * 100ms before core retransmits the failed message, this seems to - * mitigate the issue with failed transmit attempts. - */ - if ((stat & (CEC_STAT_DONE|CEC_STAT_ERROR_INIT)) == (CEC_STAT_DONE|CEC_STAT_ERROR_INIT)) { -- pr_info("dw_hdmi_cec_hardirq: stat=%02x LOW_DRIVE\n", stat); -+ if (!cec->tx_attempts) -+ cec->tx_attempts = 2; - cec->tx_status = CEC_TX_STATUS_LOW_DRIVE; - cec->tx_done = true; - ret = IRQ_WAKE_THREAD; -+ } else if (stat & CEC_STAT_ARBLOST) { -+ cec->tx_attempts = 0; -+ cec->tx_status = CEC_TX_STATUS_ARB_LOST; -+ cec->tx_done = true; -+ ret = IRQ_WAKE_THREAD; - } else if (stat & CEC_STAT_DONE) { -+ cec->tx_attempts = 0; - cec->tx_status = CEC_TX_STATUS_OK; - cec->tx_done = true; - ret = IRQ_WAKE_THREAD; - } else if (stat & CEC_STAT_NACK) { -+ cec->tx_attempts = 0; - cec->tx_status = CEC_TX_STATUS_NACK; - cec->tx_done = true; - ret = IRQ_WAKE_THREAD; - } else if (stat & CEC_STAT_ERROR_INIT) { -+ cec->tx_attempts = 0; - cec->tx_status = CEC_TX_STATUS_ERROR; - cec->tx_done = true; - ret = IRQ_WAKE_THREAD; -@@ -176,6 +188,8 @@ static irqreturn_t dw_hdmi_cec_hardirq(int irq, void *data) - ret = IRQ_WAKE_THREAD; - } - -+ pr_info("%s: stat=%x ret=%x tx_done=%d rx_done=%d tx_status=%u tx_attempts=%u\n", __func__, stat, ret, cec->tx_done, cec->rx_done, cec->tx_status, cec->tx_attempts); -+ - return ret; - } - -@@ -184,11 +198,19 @@ static irqreturn_t dw_hdmi_cec_thread(int irq, void *data) - struct cec_adapter *adap = data; - struct dw_hdmi_cec *cec = cec_get_drvdata(adap); - -+ //pr_info("%s: tx_done=%d rx_done=%d tx_status=%u tx_attempts=%u\n", __func__, cec->tx_done, cec->rx_done, cec->tx_status, cec->tx_attempts); -+ - if (cec->tx_done) { - cec->tx_done = false; - if (cec->tx_status == CEC_TX_STATUS_LOW_DRIVE) - msleep(100); -- cec_transmit_attempt_done(adap, cec->tx_status); -+ if (cec->tx_attempts > 1) { -+ cec->tx_attempts--; -+ dw_hdmi_write(cec, CEC_CTRL_RETRY | CEC_CTRL_START, HDMI_CEC_CTRL); -+ } else { -+ cec->tx_attempts = 0; -+ cec_transmit_attempt_done(adap, cec->tx_status); -+ } - } - if (cec->rx_done) { - cec->rx_done = false; -@@ -219,8 +241,8 @@ static int dw_hdmi_cec_enable(struct cec_adapter *adap, bool enable) - - cec->ops->enable(cec->hdmi); - -- irqs = CEC_STAT_ERROR_INIT | CEC_STAT_NACK | CEC_STAT_EOM | -- CEC_STAT_DONE; -+ irqs = CEC_STAT_ERROR_INIT | CEC_STAT_ARBLOST | CEC_STAT_NACK | -+ CEC_STAT_EOM | CEC_STAT_DONE; - dw_hdmi_write(cec, irqs, HDMI_CEC_POLARITY); - dw_hdmi_write(cec, ~irqs, HDMI_CEC_MASK); - dw_hdmi_write(cec, ~irqs, HDMI_IH_MUTE_CEC_STAT0); -diff --git a/drivers/media/cec/core/cec-adap.c b/drivers/media/cec/core/cec-adap.c -index 926d65db6d3e..7b17539f656c 100644 ---- a/drivers/media/cec/core/cec-adap.c -+++ b/drivers/media/cec/core/cec-adap.c -@@ -599,7 +599,6 @@ void cec_transmit_done_ts(struct cec_adapter *adap, u8 status, - unsigned int attempts_made = arb_lost_cnt + nack_cnt + - low_drive_cnt + error_cnt; - -- dprintk(2, "%s: status 0x%02x\n", __func__, status); - if (attempts_made < 1) - attempts_made = 1; - -@@ -620,6 +619,7 @@ void cec_transmit_done_ts(struct cec_adapter *adap, u8 status, - adap->transmit_in_progress = false; - - msg = &data->msg; -+ dprintk(2, "%s: %*ph (sequence: %u, attempts: %d, status: %02x)\n", __func__, msg->len, msg->msg, msg->sequence, attempts_made, status); - - /* Drivers must fill in the status! */ - WARN_ON(status == 0); - -From 2acbc9339a2fe44e1c7d5b2b97d2a09ba16c96fb Mon Sep 17 00:00:00 2001 -From: Jonas Karlman -Date: Mon, 20 Jul 2020 11:44:01 +0000 -Subject: [PATCH] cec dprintk revert - ---- - drivers/media/cec/core/cec-adap.c | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/drivers/media/cec/core/cec-adap.c b/drivers/media/cec/core/cec-adap.c -index 7b17539f656c..926d65db6d3e 100644 ---- a/drivers/media/cec/core/cec-adap.c -+++ b/drivers/media/cec/core/cec-adap.c -@@ -599,6 +599,7 @@ void cec_transmit_done_ts(struct cec_adapter *adap, u8 status, - unsigned int attempts_made = arb_lost_cnt + nack_cnt + - low_drive_cnt + error_cnt; - -+ dprintk(2, "%s: status 0x%02x\n", __func__, status); - if (attempts_made < 1) - attempts_made = 1; - -@@ -619,7 +620,6 @@ void cec_transmit_done_ts(struct cec_adapter *adap, u8 status, - adap->transmit_in_progress = false; - - msg = &data->msg; -- dprintk(2, "%s: %*ph (sequence: %u, attempts: %d, status: %02x)\n", __func__, msg->len, msg->msg, msg->sequence, attempts_made, status); - - /* Drivers must fill in the status! */ - WARN_ON(status == 0); - -From 0e1dc6a91a725e1d3417f693f620a77e29a222ad Mon Sep 17 00:00:00 2001 +From c94f4e569387f6874b2c96a3db684751529fb6b6 Mon Sep 17 00:00:00 2001 From: Jonas Karlman Date: Mon, 20 Jul 2020 12:33:01 +0000 Subject: [PATCH] Revert "fixup! WIP: drm/rockchip: vop: max_output" @@ -1616,7 +999,7 @@ index 106b38ea12df..138f449924f8 100644 * Clock craziness. * -From 0b9759fa2630678c7e12f1b922ff866f53df90d1 Mon Sep 17 00:00:00 2001 +From 8af324175e002a9ee48be8618dce51ffc348a409 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 @@ -1644,7 +1027,7 @@ index 138f449924f8..0a25de483515 100644 return NULL; -From dbf463be2403be5cd1e538fce49d85f7e26d4b3e Mon Sep 17 00:00:00 2001 +From cf2f0b3497dd7094b96d0f61d71e07927aae3e0c Mon Sep 17 00:00:00 2001 From: Jonas Karlman Date: Mon, 20 Jul 2020 15:15:50 +0000 Subject: [PATCH] WIP: drm/rockchip: vop: filter interlaced modes @@ -1668,7 +1051,7 @@ index 0a25de483515..5ab1412173a7 100644 if (rounded_rate < 0) return MODE_NOCLOCK; -From c846700ec7fdd8b7982f523bbfe867db3d08711b Mon Sep 17 00:00:00 2001 +From 1400714403b22c227d281c8fc5a3c07cc6312740 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 @@ -1899,7 +1282,7 @@ index cc20a83fa9b8..745fd1c13cef 100644 } -From a1b98d86294a9320fe154aa11e104dea6becee4a Mon Sep 17 00:00:00 2001 +From ea791312a81f11f719a019e30c7736e7ab314739 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 @@ -1913,7 +1296,7 @@ Signed-off-by: Jonas Karlman 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 748df1cacd2b..c25d5ac7bb07 100644 +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 { @@ -1977,7 +1360,7 @@ index ea34ca146b82..4f61ede6486d 100644 struct dw_hdmi *dw_hdmi_probe(struct platform_device *pdev, -From 1f152929c7bb18b6349fffbc06a003007e5e3783 Mon Sep 17 00:00:00 2001 +From 0ea5bddefeeecd75d9dbee409ad8a8fddff6d378 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 @@ -1990,7 +1373,7 @@ Signed-off-by: Jonas Karlman 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 c25d5ac7bb07..bcdd823907c2 100644 +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, @@ -2037,7 +1420,7 @@ index c25d5ac7bb07..bcdd823907c2 100644 dw_hdmi_phy_i2c_write(hdmi, 0, HDMI_3D_TX_PHY_PLLPHBYCTRL); -From 9c5117c0b3a6d5a128c6ce2102f8e81676752978 Mon Sep 17 00:00:00 2001 +From 153e20ab5fd968cb5aff1e0cd7191d1ca1a6744e 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 @@ -2049,7 +1432,7 @@ Signed-off-by: Jonas Karlman 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 bcdd823907c2..f5d048adf649 100644 +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, @@ -2076,7 +1459,7 @@ index 4f61ede6486d..0ebe01835d2a 100644 const struct dw_hdmi_phy_config *phy_config; int (*configure_phy)(struct dw_hdmi *hdmi, void *data, -From dadb0b7e99a25a71a8b9e41d6cb154cb2ddf856e Mon Sep 17 00:00:00 2001 +From 21174838c2d39a88ea46dbf64ced1ac133f32e7c 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 @@ -2117,77 +1500,7 @@ index 745fd1c13cef..9784111ea746 100644 encoder = &hdmi->encoder; -From 0f936ce17398a9cee1be5027cf86b44430fcd23e 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: rk3399: add mpll_cfg_420 - -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 9784111ea746..e7fbeb9132fb 100644 ---- a/drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c -+++ b/drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c -@@ -166,6 +166,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 */ - { -@@ -481,6 +521,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 240069c903db02016afcbacbde7a292d651eeb36 Mon Sep 17 00:00:00 2001 +From fbf69694a8f832cfa942f16a4bd8a630aa8f0f3f 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 @@ -2198,7 +1511,7 @@ Subject: [PATCH] WIP: drm/bridge: dw-hdmi: limit mode and bus format to 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 f5d048adf649..26c64cf2d00a 100644 +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, @@ -2256,7 +1569,7 @@ index f5d048adf649..26c64cf2d00a 100644 dev_dbg(hdmi->dev, "final tmdsclock = %d\n", vmode->mtmdsclock); /* Set up HDMI_FC_INVIDCONF */ -@@ -2550,8 +2547,21 @@ static int dw_hdmi_connector_create(struct dw_hdmi *hdmi) +@@ -2544,8 +2541,21 @@ static int dw_hdmi_connector_create(struct dw_hdmi *hdmi) * - MEDIA_BUS_FMT_RGB888_1X24, */ @@ -2280,7 +1593,7 @@ index f5d048adf649..26c64cf2d00a 100644 static u32 *dw_hdmi_bridge_atomic_get_output_bus_fmts(struct drm_bridge *bridge, struct drm_bridge_state *bridge_state, -@@ -2563,8 +2573,6 @@ static u32 *dw_hdmi_bridge_atomic_get_output_bus_fmts(struct drm_bridge *bridge, +@@ -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; @@ -2289,7 +1602,7 @@ index f5d048adf649..26c64cf2d00a 100644 u32 *output_fmts; unsigned int i = 0; -@@ -2587,29 +2595,33 @@ static u32 *dw_hdmi_bridge_atomic_get_output_bus_fmts(struct drm_bridge *bridge, +@@ -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 */ @@ -2331,7 +1644,7 @@ index f5d048adf649..26c64cf2d00a 100644 } /* -@@ -2618,40 +2630,51 @@ static u32 *dw_hdmi_bridge_atomic_get_output_bus_fmts(struct drm_bridge *bridge, +@@ -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) { @@ -2394,7 +1707,7 @@ index f5d048adf649..26c64cf2d00a 100644 *num_output_fmts = i; -@@ -2831,11 +2854,20 @@ dw_hdmi_bridge_mode_valid(struct drm_bridge *bridge, +@@ -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; @@ -2416,7 +1729,7 @@ index f5d048adf649..26c64cf2d00a 100644 mode_status = pdata->mode_valid(hdmi, pdata->priv_data, info, mode); -From 636c91cfca72fb0c6b8c5e8084867d74491b5dfa Mon Sep 17 00:00:00 2001 +From 6e9f31fe455b92a19f12c4bae9c9f4b00efde58e 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 @@ -2427,7 +1740,7 @@ Subject: [PATCH] WIP: drm/rockchip: dw_hdmi: add 10-bit rgb bus format 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 e7fbeb9132fb..cd87ee8a65c3 100644 +index 9784111ea746..ddff1582b271 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 { @@ -2438,7 +1751,7 @@ index e7fbeb9132fb..cd87ee8a65c3 100644 static const struct dw_hdmi_mpll_config rockchip_mpll_cfg[] = { { -@@ -282,6 +283,11 @@ dw_hdmi_rockchip_bridge_mode_set(struct drm_bridge *bridge, +@@ -242,6 +243,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); @@ -2450,7 +1763,7 @@ index e7fbeb9132fb..cd87ee8a65c3 100644 clk_set_rate(hdmi->vpll_clk, adjusted_mode->clock * 1000); } -@@ -320,6 +326,7 @@ static void dw_hdmi_rockchip_bridge_enable(struct drm_bridge *bridge) +@@ -280,6 +286,7 @@ static void dw_hdmi_rockchip_bridge_enable(struct drm_bridge *bridge) static bool is_rgb(u32 format) { switch (format) { @@ -2458,7 +1771,7 @@ index e7fbeb9132fb..cd87ee8a65c3 100644 case MEDIA_BUS_FMT_RGB888_1X24: return true; default: -@@ -327,6 +334,16 @@ static bool is_rgb(u32 format) +@@ -287,6 +294,16 @@ static bool is_rgb(u32 format) } } @@ -2475,7 +1788,7 @@ index e7fbeb9132fb..cd87ee8a65c3 100644 static int dw_hdmi_rockchip_bridge_atomic_check(struct drm_bridge *bridge, struct drm_bridge_state *bridge_state, -@@ -334,9 +351,24 @@ dw_hdmi_rockchip_bridge_atomic_check(struct drm_bridge *bridge, +@@ -294,9 +311,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); @@ -2500,7 +1813,7 @@ index e7fbeb9132fb..cd87ee8a65c3 100644 return 0; } -@@ -348,10 +380,19 @@ static u32 *dw_hdmi_rockchip_get_input_bus_fmts(struct drm_bridge *bridge, +@@ -308,10 +340,19 @@ static u32 *dw_hdmi_rockchip_get_input_bus_fmts(struct drm_bridge *bridge, u32 output_fmt, unsigned int *num_input_fmts) { @@ -2534,7 +1847,7 @@ index e33c2dcd0d4b..03944e08b6c7 100644 #define to_rockchip_crtc_state(s) \ container_of(s, struct rockchip_crtc_state, base) -From ff80104f4a32e591e12358432a85aabc5b436b63 Mon Sep 17 00:00:00 2001 +From 83871fb221f71065f78cff3c8019f8684481a155 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 @@ -2545,7 +1858,7 @@ Signed-off-by: Jonas Karlman 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 26c64cf2d00a..ffb72e6874c8 100644 +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, @@ -2565,7 +1878,7 @@ index 26c64cf2d00a..ffb72e6874c8 100644 /* * The Designware IP uses a different byte format from standard * AVI info frames, though generally the bits are in the correct -@@ -2437,7 +2440,8 @@ static int dw_hdmi_connector_atomic_check(struct drm_connector *connector, +@@ -2431,7 +2434,8 @@ static int dw_hdmi_connector_atomic_check(struct drm_connector *connector, if (!crtc) return 0; @@ -2575,7 +1888,7 @@ index 26c64cf2d00a..ffb72e6874c8 100644 crtc_state = drm_atomic_get_crtc_state(state, crtc); if (IS_ERR(crtc_state)) return PTR_ERR(crtc_state); -@@ -2505,6 +2509,8 @@ static int dw_hdmi_connector_create(struct dw_hdmi *hdmi) +@@ -2499,6 +2503,8 @@ static int dw_hdmi_connector_create(struct dw_hdmi *hdmi) drm_connector_attach_max_bpc_property(connector, 8, 16); @@ -2585,7 +1898,7 @@ index 26c64cf2d00a..ffb72e6874c8 100644 drm_object_attach_property(&connector->base, connector->dev->mode_config.hdr_output_metadata_property, 0); -From 9d3f655dae4e7d01ed64783958c228ab031b723c Mon Sep 17 00:00:00 2001 +From 553cc49748b8f0d074735f18cd45f050fca567e7 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 @@ -2598,7 +1911,7 @@ Subject: [PATCH] WIP: drm/rockchip: add yuv444 support 4 files changed, 78 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c b/drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c -index cd87ee8a65c3..436a9223e5e4 100644 +index ddff1582b271..eea8e1491204 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 { @@ -2609,7 +1922,7 @@ index cd87ee8a65c3..436a9223e5e4 100644 }; struct rockchip_hdmi { -@@ -334,10 +335,22 @@ static bool is_rgb(u32 format) +@@ -294,10 +295,22 @@ static bool is_rgb(u32 format) } } @@ -2632,7 +1945,7 @@ index cd87ee8a65c3..436a9223e5e4 100644 return true; default: return false; -@@ -354,12 +367,22 @@ dw_hdmi_rockchip_bridge_atomic_check(struct drm_bridge *bridge, +@@ -314,12 +327,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; @@ -2655,7 +1968,7 @@ index cd87ee8a65c3..436a9223e5e4 100644 s->bus_width = is_10bit(format) ? 10 : 8; old_crtc_state = drm_atomic_get_old_crtc_state(state, conn_state->crtc); -@@ -393,7 +416,10 @@ static u32 *dw_hdmi_rockchip_get_input_bus_fmts(struct drm_bridge *bridge, +@@ -353,7 +376,10 @@ static u32 *dw_hdmi_rockchip_get_input_bus_fmts(struct drm_bridge *bridge, if (!has_10bit && is_10bit(output_fmt)) return NULL; @@ -2667,7 +1980,7 @@ index cd87ee8a65c3..436a9223e5e4 100644 return NULL; input_fmt = kzalloc(sizeof(*input_fmt), GFP_KERNEL); -@@ -542,6 +568,7 @@ static const struct dw_hdmi_phy_ops rk3328_hdmi_phy_ops = { +@@ -502,6 +528,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, @@ -2675,7 +1988,7 @@ index cd87ee8a65c3..436a9223e5e4 100644 }; static const struct dw_hdmi_plat_data rk3328_hdmi_drv_data = { -@@ -557,6 +584,7 @@ static struct rockchip_hdmi_chip_data rk3399_chip_data = { +@@ -517,6 +544,7 @@ static struct rockchip_hdmi_chip_data rk3399_chip_data = { .lcdsel_grf_reg = RK3399_GRF_SOC_CON20, .lcdsel_big = HIWORD_UPDATE(0, RK3399_HDMI_LCDC_SEL), .lcdsel_lit = HIWORD_UPDATE(RK3399_HDMI_LCDC_SEL, RK3399_HDMI_LCDC_SEL), @@ -2805,7 +2118,7 @@ index 57c36e9207c1..800b9341dd42 100644 static const struct vop_intr rk3328_vop_intr = { -From 32b8598b1300eb3efd9e01b7afe0b6ca86b15123 Mon Sep 17 00:00:00 2001 +From 6127108151898a2c69fb50749d7e647ac35cf8aa 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 @@ -2818,10 +2131,10 @@ Subject: [PATCH] WIP: drm/rockchip: add yuv420 support 4 files changed, 48 insertions(+), 5 deletions(-) diff --git a/drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c b/drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c -index 436a9223e5e4..1abc46a023a4 100644 +index eea8e1491204..c25ebe31b98d 100644 --- a/drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c +++ b/drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c -@@ -346,9 +346,21 @@ static bool is_yuv444(u32 format) +@@ -306,9 +306,21 @@ static bool is_yuv444(u32 format) } } @@ -2843,7 +2156,7 @@ index 436a9223e5e4..1abc46a023a4 100644 case MEDIA_BUS_FMT_RGB101010_1X30: case MEDIA_BUS_FMT_YUV10_1X30: return true; -@@ -385,6 +397,11 @@ dw_hdmi_rockchip_bridge_atomic_check(struct drm_bridge *bridge, +@@ -345,6 +357,11 @@ dw_hdmi_rockchip_bridge_atomic_check(struct drm_bridge *bridge, s->bus_width = is_10bit(format) ? 10 : 8; @@ -2855,7 +2168,7 @@ index 436a9223e5e4..1abc46a023a4 100644 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); -@@ -405,6 +422,7 @@ static u32 *dw_hdmi_rockchip_get_input_bus_fmts(struct drm_bridge *bridge, +@@ -365,6 +382,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; @@ -2863,7 +2176,7 @@ index 436a9223e5e4..1abc46a023a4 100644 u32 *input_fmt; bool has_10bit = true; -@@ -419,6 +437,9 @@ static u32 *dw_hdmi_rockchip_get_input_bus_fmts(struct drm_bridge *bridge, +@@ -379,6 +397,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; @@ -2873,7 +2186,7 @@ index 436a9223e5e4..1abc46a023a4 100644 } else if (!is_rgb(output_fmt)) return NULL; -@@ -578,6 +599,7 @@ static const struct dw_hdmi_plat_data rk3328_hdmi_drv_data = { +@@ -538,6 +559,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, @@ -2881,7 +2194,7 @@ index 436a9223e5e4..1abc46a023a4 100644 }; static struct rockchip_hdmi_chip_data rk3399_chip_data = { -@@ -595,6 +617,7 @@ static const struct dw_hdmi_plat_data rk3399_hdmi_drv_data = { +@@ -554,6 +576,7 @@ static const struct dw_hdmi_plat_data rk3399_hdmi_drv_data = { .phy_config = rockchip_phy_config, .phy_data = &rk3399_chip_data, .use_drm_infoframe = true, @@ -2982,7 +2295,7 @@ index 800b9341dd42..dd4546f9f410 100644 .dsp_out_yuv = VOP_REG(RK3328_POST_SCL_CTRL, 0x1, 2), .dsp_background = VOP_REG(RK3328_DSP_BG, 0xffffffff, 0), -From bf070727c435df4b370aa6e7fdf0ecba2fd6985c Mon Sep 17 00:00:00 2001 +From c70da56116a103e5f6bd154b7819217410a9c4f7 Mon Sep 17 00:00:00 2001 From: Jonas Karlman Date: Sun, 7 Jun 2020 20:25:25 +0000 Subject: [PATCH] drm: drm_fourcc: add NV20 and NV30 YUV formats @@ -3039,7 +2352,7 @@ index 82f327801267..d8e6159213dc 100644 /* * 2 plane YCbCr MSB aligned -From f4c0d6f87d4231a92f4337ba8d1b0913eacb963e Mon Sep 17 00:00:00 2001 +From b41c8312d8bcd440bc42a799dd09b4acd9d4eca2 Mon Sep 17 00:00:00 2001 From: Jonas Karlman Date: Sun, 7 Jun 2020 20:25:26 +0000 Subject: [PATCH] drm: rockchip: add NV15, NV20 and NV30 support @@ -3215,11 +2528,11 @@ index dd4546f9f410..7d5191421ddf 100644 .y_mir_en = VOP_REG(RK3288_WIN0_CTRL0, 0x1, 22), .act_info = VOP_REG(RK3288_WIN0_ACT_INFO, 0x1fff1fff, 0), -From e6aab013424e8e5a033f2da27757735f2a31c24e Mon Sep 17 00:00:00 2001 +From 478dd53361097d99541d777ce0f7fec7a79b7fa8 Mon Sep 17 00:00:00 2001 From: Alex Bee Date: Sat, 15 Aug 2020 21:11:08 +0200 -Subject: [PATCH] drm/rockchip: rk3368's vop does not support 10-bit formats - - neither as input nor as output +Subject: [PATCH] !fixup drm/rockchip: rk3368's vop does not support 10-bit + formats --- drivers/gpu/drm/rockchip/rockchip_vop_reg.c | 4 ++-- @@ -3241,7 +2554,7 @@ index 7d5191421ddf..20c3e6248ec7 100644 .enable = VOP_REG(RK3368_WIN0_CTRL0, 0x1, 0), .format = VOP_REG(RK3368_WIN0_CTRL0, 0x7, 1), -From e3b1ffdb8a4620cb05ad1a2fb3ca6c398bf6470f Mon Sep 17 00:00:00 2001 +From 1f05ca5dfe7bd1553d32be9f450614b545be0912 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 @@ -3252,10 +2565,10 @@ Subject: [PATCH] drm/rockchip: enable ycbcr_420_allowed and ycbcr_444_allowed 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 1abc46a023a4..64a79b33ff18 100644 +index c25ebe31b98d..5562326e4bce 100644 --- a/drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c +++ b/drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c -@@ -555,6 +555,7 @@ static const struct dw_hdmi_phy_ops rk3228_hdmi_phy_ops = { +@@ -515,6 +515,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, @@ -3263,7 +2576,7 @@ index 1abc46a023a4..64a79b33ff18 100644 }; static const struct dw_hdmi_plat_data rk3228_hdmi_drv_data = { -@@ -563,6 +564,7 @@ static const struct dw_hdmi_plat_data rk3228_hdmi_drv_data = { +@@ -523,6 +524,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, @@ -3272,7 +2585,7 @@ index 1abc46a023a4..64a79b33ff18 100644 static struct rockchip_hdmi_chip_data rk3288_chip_data = { -From 8bdc71e93099e4a8e3fd8791832a83dfe485cd99 Mon Sep 17 00:00:00 2001 +From 4273e39fec795fe18f83414655d30b0b9c5420d9 Mon Sep 17 00:00:00 2001 From: Alex Bee Date: Wed, 22 Jul 2020 20:13:28 +0200 Subject: [PATCH] drm: rockchip: add scaling for RK3036 win1 @@ -3320,27 +2633,31 @@ index 20c3e6248ec7..93a00b6ac295 100644 .nformats = ARRAY_SIZE(formats_win_lite), .format_modifiers = format_modifiers_win_lite, -From e2153eb92daad4a2e35b86096cbfe5f3ec4dc5ed Mon Sep 17 00:00:00 2001 +From a05d484d84e54a59c7846d2b409dda1e7355e3de Mon Sep 17 00:00:00 2001 From: Alex Bee Date: Wed, 22 Jul 2020 20:13:29 +0200 Subject: [PATCH] drm: rockchip: add missing registers for RK3188 Add dither_up, dsp_lut_en and data_blank registers to enable their respective functionality for RK3188's VOP. +While at that also fix .dsp_blank register which is (only) set though +BIT24 (same as RK3066) Signed-off-by: Alex Bee --- - drivers/gpu/drm/rockchip/rockchip_vop_reg.c | 3 +++ - 1 file changed, 3 insertions(+) + drivers/gpu/drm/rockchip/rockchip_vop_reg.c | 5 ++++- + 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/rockchip/rockchip_vop_reg.c b/drivers/gpu/drm/rockchip/rockchip_vop_reg.c -index 93a00b6ac295..2638d084f9ce 100644 +index 93a00b6ac295..f8a898c5bb62 100644 --- a/drivers/gpu/drm/rockchip/rockchip_vop_reg.c +++ b/drivers/gpu/drm/rockchip/rockchip_vop_reg.c -@@ -529,6 +529,9 @@ static const struct vop_common rk3188_common = { +@@ -528,7 +528,10 @@ static const struct vop_common rk3188_common = { + .dither_down_sel = VOP_REG(RK3188_DSP_CTRL0, 0x1, 27), .dither_down_en = VOP_REG(RK3188_DSP_CTRL0, 0x1, 11), .dither_down_mode = VOP_REG(RK3188_DSP_CTRL0, 0x1, 10), - .dsp_blank = VOP_REG(RK3188_DSP_CTRL1, 0x3, 24), +- .dsp_blank = VOP_REG(RK3188_DSP_CTRL1, 0x3, 24), ++ .dsp_blank = VOP_REG(RK3188_DSP_CTRL1, 0x1, 24), + .dither_up = VOP_REG(RK3188_DSP_CTRL0, 0x1, 9), + .dsp_lut_en = VOP_REG(RK3188_SYS_CTRL, 0x1, 28), + .data_blank = VOP_REG(RK3188_DSP_CTRL1, 0x1, 25), @@ -3348,7 +2665,76 @@ index 93a00b6ac295..2638d084f9ce 100644 static const struct vop_win_data rk3188_vop_win_data[] = { -From c0e58f92ce8d4a6d792fb3e49ec2c1e46039ae76 Mon Sep 17 00:00:00 2001 +From 6dd7876510c6a23e6d6b1243c730d73e6acb1137 Mon Sep 17 00:00:00 2001 +From: Alex Bee +Date: Wed, 22 Jul 2020 20:44:12 +0200 +Subject: [PATCH] drm: rockchip: add missing registers for RK3066 + +Add dither_up, dsp_lut_en and data_blank registers to enable their +respective functionality for RK3066's VOP. +While at that also fix .rb_swap and .format registers for all windows, +which have to be set though RK3066_SYS_CTRL1. Also remove .scl from +win1: Scaling is only supported on the primary plane. + +Signed-off-by: Alex Bee +--- + drivers/gpu/drm/rockchip/rockchip_vop_reg.c | 16 +++++++++------- + 1 file changed, 9 insertions(+), 7 deletions(-) + +diff --git a/drivers/gpu/drm/rockchip/rockchip_vop_reg.c b/drivers/gpu/drm/rockchip/rockchip_vop_reg.c +index f8a898c5bb62..77f8b49a4d17 100644 +--- a/drivers/gpu/drm/rockchip/rockchip_vop_reg.c ++++ b/drivers/gpu/drm/rockchip/rockchip_vop_reg.c +@@ -372,8 +372,8 @@ static const struct vop_win_phy rk3066_win0_data = { + .nformats = ARRAY_SIZE(formats_win_full), + .format_modifiers = format_modifiers_win_full, + .enable = VOP_REG(RK3066_SYS_CTRL1, 0x1, 0), +- .format = VOP_REG(RK3066_SYS_CTRL0, 0x7, 4), +- .rb_swap = VOP_REG(RK3066_SYS_CTRL0, 0x1, 19), ++ .format = VOP_REG(RK3066_SYS_CTRL1, 0x7, 4), ++ .rb_swap = VOP_REG(RK3066_SYS_CTRL1, 0x1, 19), + .act_info = VOP_REG(RK3066_WIN0_ACT_INFO, 0x1fff1fff, 0), + .dsp_info = VOP_REG(RK3066_WIN0_DSP_INFO, 0x0fff0fff, 0), + .dsp_st = VOP_REG(RK3066_WIN0_DSP_ST, 0x1fff1fff, 0), +@@ -384,13 +384,12 @@ static const struct vop_win_phy rk3066_win0_data = { + }; + + static const struct vop_win_phy rk3066_win1_data = { +- .scl = &rk3066_win_scl, + .data_formats = formats_win_full, + .nformats = ARRAY_SIZE(formats_win_full), + .format_modifiers = format_modifiers_win_full, + .enable = VOP_REG(RK3066_SYS_CTRL1, 0x1, 1), +- .format = VOP_REG(RK3066_SYS_CTRL0, 0x7, 7), +- .rb_swap = VOP_REG(RK3066_SYS_CTRL0, 0x1, 23), ++ .format = VOP_REG(RK3066_SYS_CTRL1, 0x7, 7), ++ .rb_swap = VOP_REG(RK3066_SYS_CTRL1, 0x1, 23), + .act_info = VOP_REG(RK3066_WIN1_ACT_INFO, 0x1fff1fff, 0), + .dsp_info = VOP_REG(RK3066_WIN1_DSP_INFO, 0x0fff0fff, 0), + .dsp_st = VOP_REG(RK3066_WIN1_DSP_ST, 0x1fff1fff, 0), +@@ -405,8 +404,8 @@ static const struct vop_win_phy rk3066_win2_data = { + .nformats = ARRAY_SIZE(formats_win_lite), + .format_modifiers = format_modifiers_win_lite, + .enable = VOP_REG(RK3066_SYS_CTRL1, 0x1, 2), +- .format = VOP_REG(RK3066_SYS_CTRL0, 0x7, 10), +- .rb_swap = VOP_REG(RK3066_SYS_CTRL0, 0x1, 27), ++ .format = VOP_REG(RK3066_SYS_CTRL1, 0x7, 10), ++ .rb_swap = VOP_REG(RK3066_SYS_CTRL1, 0x1, 27), + .dsp_info = VOP_REG(RK3066_WIN2_DSP_INFO, 0x0fff0fff, 0), + .dsp_st = VOP_REG(RK3066_WIN2_DSP_ST, 0x1fff1fff, 0), + .yrgb_mst = VOP_REG(RK3066_WIN2_MST, 0xffffffff, 0), +@@ -431,6 +430,9 @@ static const struct vop_common rk3066_common = { + .dither_down_en = VOP_REG(RK3066_DSP_CTRL0, 0x1, 11), + .dither_down_mode = VOP_REG(RK3066_DSP_CTRL0, 0x1, 10), + .dsp_blank = VOP_REG(RK3066_DSP_CTRL1, 0x1, 24), ++ .dither_up = VOP_REG(RK3066_DSP_CTRL0, 0x1, 9), ++ .dsp_lut_en = VOP_REG(RK3066_SYS_CTRL1, 0x1, 31), ++ .data_blank = VOP_REG(RK3066_DSP_CTRL1, 0x1, 25), + }; + + static const struct vop_win_data rk3066_vop_win_data[] = { + +From 08b0db205ddef2853dd75c0691d7d6d6f94c611b Mon Sep 17 00:00:00 2001 From: Alex Bee Date: Wed, 22 Jul 2020 20:13:30 +0200 Subject: [PATCH] drm: rockchip: add alpha support for RK3036, RK3066, RK3126 @@ -3370,7 +2756,7 @@ Signed-off-by: Alex Bee 2 files changed, 22 insertions(+) diff --git a/drivers/gpu/drm/rockchip/rockchip_vop_reg.c b/drivers/gpu/drm/rockchip/rockchip_vop_reg.c -index 2638d084f9ce..e1db4e57c51a 100644 +index 77f8b49a4d17..27a04c5bc2fd 100644 --- a/drivers/gpu/drm/rockchip/rockchip_vop_reg.c +++ b/drivers/gpu/drm/rockchip/rockchip_vop_reg.c @@ -121,6 +121,9 @@ static const struct vop_win_phy rk3036_win0_data = { @@ -3412,7 +2798,7 @@ index 2638d084f9ce..e1db4e57c51a 100644 }; static const struct vop_win_phy rk3066_win1_data = { -@@ -398,6 +409,8 @@ static const struct vop_win_phy rk3066_win1_data = { +@@ -397,6 +408,8 @@ static const struct vop_win_phy rk3066_win1_data = { .uv_mst = VOP_REG(RK3066_WIN1_CBR_MST, 0xffffffff, 0), .yrgb_vir = VOP_REG(RK3066_WIN1_VIR, 0xffff, 0), .uv_vir = VOP_REG(RK3066_WIN1_VIR, 0x1fff, 16), @@ -3421,7 +2807,7 @@ index 2638d084f9ce..e1db4e57c51a 100644 }; static const struct vop_win_phy rk3066_win2_data = { -@@ -411,6 +424,8 @@ static const struct vop_win_phy rk3066_win2_data = { +@@ -410,6 +423,8 @@ static const struct vop_win_phy rk3066_win2_data = { .dsp_st = VOP_REG(RK3066_WIN2_DSP_ST, 0x1fff1fff, 0), .yrgb_mst = VOP_REG(RK3066_WIN2_MST, 0xffffffff, 0), .yrgb_vir = VOP_REG(RK3066_WIN2_VIR, 0xffff, 0), @@ -3430,7 +2816,7 @@ index 2638d084f9ce..e1db4e57c51a 100644 }; static const struct vop_modeset rk3066_modeset = { -@@ -493,6 +508,9 @@ static const struct vop_win_phy rk3188_win0_data = { +@@ -495,6 +510,9 @@ static const struct vop_win_phy rk3188_win0_data = { .yrgb_mst = VOP_REG(RK3188_WIN0_YRGB_MST0, 0xffffffff, 0), .uv_mst = VOP_REG(RK3188_WIN0_CBR_MST0, 0xffffffff, 0), .yrgb_vir = VOP_REG(RK3188_WIN_VIR, 0x1fff, 0), @@ -3440,7 +2826,7 @@ index 2638d084f9ce..e1db4e57c51a 100644 }; static const struct vop_win_phy rk3188_win1_data = { -@@ -507,6 +525,9 @@ static const struct vop_win_phy rk3188_win1_data = { +@@ -509,6 +527,9 @@ static const struct vop_win_phy rk3188_win1_data = { .dsp_st = VOP_REG(RK3188_WIN1_DSP_ST, 0x0fff0fff, 0), .yrgb_mst = VOP_REG(RK3188_WIN1_MST, 0xffffffff, 0), .yrgb_vir = VOP_REG(RK3188_WIN_VIR, 0x1fff, 16), @@ -3463,7 +2849,7 @@ index 6e9fa5815d4d..0b3cd65ba5c1 100644 #define RK3188_WIN0_CBR_MST0 0x24 #define RK3188_WIN0_YRGB_MST1 0x28 -From 03532318ac2db5df4e83226628cb80399466bcd1 Mon Sep 17 00:00:00 2001 +From 9fb777928ddfedc0412fa79b320814c06b7195cf Mon Sep 17 00:00:00 2001 From: Alex Bee Date: Wed, 22 Jul 2020 20:13:31 +0200 Subject: [PATCH] drm: rockchip: set alpha_en to 0 if it is not used @@ -3491,7 +2877,7 @@ index 413534cf1a93..9b1cc0f413fc 100644 VOP_WIN_SET(vop, win, enable, 1); -From 5447465aa564564d938209b4c5a2675f8d744354 Mon Sep 17 00:00:00 2001 +From 9be348c6cade7e709be7347d336c7638bf603b46 Mon Sep 17 00:00:00 2001 From: Alex Bee Date: Sat, 15 Aug 2020 23:38:05 +0200 Subject: [PATCH] rockchip/drm: add dsp_data_swap register for RK3188 @@ -3501,10 +2887,10 @@ Subject: [PATCH] rockchip/drm: add dsp_data_swap register for RK3188 1 file changed, 1 insertion(+) diff --git a/drivers/gpu/drm/rockchip/rockchip_vop_reg.c b/drivers/gpu/drm/rockchip/rockchip_vop_reg.c -index e1db4e57c51a..e10cb2d33951 100644 +index 27a04c5bc2fd..b47f036d4a2c 100644 --- a/drivers/gpu/drm/rockchip/rockchip_vop_reg.c +++ b/drivers/gpu/drm/rockchip/rockchip_vop_reg.c -@@ -553,6 +553,7 @@ static const struct vop_common rk3188_common = { +@@ -555,6 +555,7 @@ static const struct vop_common rk3188_common = { .dither_up = VOP_REG(RK3188_DSP_CTRL0, 0x1, 9), .dsp_lut_en = VOP_REG(RK3188_SYS_CTRL, 0x1, 28), .data_blank = VOP_REG(RK3188_DSP_CTRL1, 0x1, 25), @@ -3513,7 +2899,30 @@ index e1db4e57c51a..e10cb2d33951 100644 static const struct vop_win_data rk3188_vop_win_data[] = { -From ee7a494712813333d714ff7360dae7e91d8ebdc3 Mon Sep 17 00:00:00 2001 +From 195b202dbc5abe9c65e029826a7f3e2a2d71067a Mon Sep 17 00:00:00 2001 +From: Alex Bee +Date: Wed, 22 Jul 2020 20:22:02 +0200 +Subject: [PATCH] rockchip/drm: add dsp_data_swap register for RK3066 + +Signed-off-by: Alex Bee +--- + drivers/gpu/drm/rockchip/rockchip_vop_reg.c | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/drivers/gpu/drm/rockchip/rockchip_vop_reg.c b/drivers/gpu/drm/rockchip/rockchip_vop_reg.c +index b47f036d4a2c..ae4a27704ad6 100644 +--- a/drivers/gpu/drm/rockchip/rockchip_vop_reg.c ++++ b/drivers/gpu/drm/rockchip/rockchip_vop_reg.c +@@ -448,6 +448,7 @@ static const struct vop_common rk3066_common = { + .dither_up = VOP_REG(RK3066_DSP_CTRL0, 0x1, 9), + .dsp_lut_en = VOP_REG(RK3066_SYS_CTRL1, 0x1, 31), + .data_blank = VOP_REG(RK3066_DSP_CTRL1, 0x1, 25), ++ .dsp_data_swap = VOP_REG(RK3066_DSP_CTRL1, 0x1f, 26), + }; + + static const struct vop_win_data rk3066_vop_win_data[] = { + +From 526739e44d5b0936db93bb92d2a98835723502c3 Mon Sep 17 00:00:00 2001 From: Alex Bee Date: Sun, 16 Aug 2020 00:55:19 +0200 Subject: [PATCH] drm/rockchip: inno hdmi - add audio support - add required @@ -3551,10 +2960,10 @@ index cec21714f0e0..b022c931e186 100644 pinctrl-0 = <&hdmi_ctl>; diff --git a/arch/arm/boot/dts/rk3036.dtsi b/arch/arm/boot/dts/rk3036.dtsi -index 838040b08967..4ffe72ab5f63 100644 +index d7668a437c70..a86e1dc7fb5b 100644 --- a/arch/arm/boot/dts/rk3036.dtsi +++ b/arch/arm/boot/dts/rk3036.dtsi -@@ -344,11 +344,14 @@ hdmi: hdmi@20034000 { +@@ -397,11 +397,14 @@ hdmi: hdmi@20034000 { compatible = "rockchip,rk3036-inno-hdmi"; reg = <0x20034000 0x4000>; interrupts = ; @@ -3571,7 +2980,7 @@ index 838040b08967..4ffe72ab5f63 100644 status = "disabled"; hdmi_in: port { -@@ -361,6 +364,23 @@ hdmi_in_vop: endpoint@0 { +@@ -414,6 +417,23 @@ hdmi_in_vop: endpoint@0 { }; }; @@ -4028,1245 +3437,7 @@ index 93245b55f967..b722afc4e41f 100644 #define HDMI_VIDEO_TIMING_CTL 0x08 -From 36a713bfb58368d37e19926d79709971183d86c8 Mon Sep 17 00:00:00 2001 -From: Phong LE -Date: Wed, 11 Mar 2020 13:51:33 +0100 -Subject: [PATCH] dt-bindings: display: bridge: add it66121 bindings - -Add the ITE bridge HDMI it66121 bindings. - -Signed-off-by: Phong LE ---- - .../bindings/display/bridge/ite,it66121.yaml | 98 +++++++++++++++++++ - 1 file changed, 98 insertions(+) - create mode 100644 Documentation/devicetree/bindings/display/bridge/ite,it66121.yaml - -diff --git a/Documentation/devicetree/bindings/display/bridge/ite,it66121.yaml b/Documentation/devicetree/bindings/display/bridge/ite,it66121.yaml -new file mode 100644 -index 000000000000..1717e880d130 ---- /dev/null -+++ b/Documentation/devicetree/bindings/display/bridge/ite,it66121.yaml -@@ -0,0 +1,98 @@ -+# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause) -+%YAML 1.2 -+--- -+$id: http://devicetree.org/schemas/display/bridge/ite,it66121.yaml# -+$schema: http://devicetree.org/meta-schemas/core.yaml# -+ -+title: ITE it66121 HDMI bridge Device Tree Bindings -+ -+maintainers: -+ - Phong LE -+ - Neil Armstrong -+ -+description: | -+ The IT66121 is a high-performance and low-power single channel HDMI -+ transmitter, fully compliant with HDMI 1.3a, HDCP 1.2 and backward compatible -+ to DVI 1.0 specifications. -+ -+properties: -+ compatible: -+ const: ite,it66121 -+ -+ reg: -+ maxItems: 1 -+ description: base I2C address of the device -+ -+ reset-gpios: -+ maxItems: 1 -+ description: GPIO connected to active low reset -+ -+ vrf12-supply: -+ maxItems: 1 -+ description: Regulator for 1.2V analog core power. -+ -+ vcn33-supply: -+ maxItems: 1 -+ description: Regulator for 3.3V digital core power. -+ -+ vcn18-supply: -+ maxItems: 1 -+ description: Regulator for 1.8V IO core power. -+ -+ interrupts: -+ maxItems: 1 -+ -+ pclk-dual-edge: -+ maxItems: 1 -+ description: enable pclk dual edge mode. -+ -+ port: -+ type: object -+ -+ properties: -+ endpoint: -+ type: object -+ description: | -+ Input endpoints of the bridge. -+ -+ required: -+ - endpoint -+ -+required: -+ - compatible -+ - reg -+ - reset-gpios -+ - vrf12-supply -+ - vcn33-supply -+ - vcn18-supply -+ - interrupts -+ - port -+ -+additionalProperties: false -+ -+examples: -+ - | -+ i2c6 { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ -+ it66121hdmitx: it66121hdmitx@4c { -+ compatible = "ite,it66121"; -+ pinctrl-names = "default"; -+ pinctrl-0 = <&ite_pins_default>; -+ vcn33-supply = <&mt6358_vcn33_wifi_reg>; -+ vcn18-supply = <&mt6358_vcn18_reg>; -+ vrf12-supply = <&mt6358_vrf12_reg>; -+ reset-gpios = <&pio 160 1 /* GPIO_ACTIVE_LOW */>; -+ interrupt-parent = <&pio>; -+ interrupts = <4 8 /* IRQ_TYPE_LEVEL_LOW */>; -+ reg = <0x4c>; -+ pclk-dual-edge; -+ -+ port { -+ it66121_in: endpoint { -+ remote-endpoint = <&display_out>; -+ }; -+ }; -+ }; -+ }; - -From 55408304bc6a2c5e546743701e589f2ece3f3877 Mon Sep 17 00:00:00 2001 -From: Phong LE -Date: Wed, 11 Mar 2020 13:51:34 +0100 -Subject: [PATCH] drm: bridge: add it66121 driver - -This commit is a simple driver for bridge HMDI it66121. -The input format is RBG and there is no color conversion. -Audio, HDCP and CEC are not supported yet. - -Signed-off-by: Phong LE ---- - drivers/gpu/drm/bridge/Kconfig | 8 + - drivers/gpu/drm/bridge/Makefile | 1 + - drivers/gpu/drm/bridge/ite-it66121.c | 997 +++++++++++++++++++++++++++ - 3 files changed, 1006 insertions(+) - create mode 100644 drivers/gpu/drm/bridge/ite-it66121.c - -diff --git a/drivers/gpu/drm/bridge/Kconfig b/drivers/gpu/drm/bridge/Kconfig -index 43271c21d3fc..204246d65f44 100644 ---- a/drivers/gpu/drm/bridge/Kconfig -+++ b/drivers/gpu/drm/bridge/Kconfig -@@ -48,6 +48,14 @@ config DRM_DISPLAY_CONNECTOR - on ARM-based platforms. Saying Y here when this driver is not needed - will not cause any issue. - -+config DRM_ITE_IT66121 -+ tristate "ITE IT66121 HDMI bridge" -+ depends on OF -+ select DRM_KMS_HELPER -+ select REGMAP_I2C -+ help -+ Support for ITE IT66121 HDMI bridge. -+ - config DRM_LVDS_CODEC - tristate "Transparent LVDS encoders and decoders support" - depends on OF -diff --git a/drivers/gpu/drm/bridge/Makefile b/drivers/gpu/drm/bridge/Makefile -index d63d4b7e4347..ffa91a5a6bda 100644 ---- a/drivers/gpu/drm/bridge/Makefile -+++ b/drivers/gpu/drm/bridge/Makefile -@@ -2,6 +2,7 @@ - obj-$(CONFIG_DRM_CDNS_DSI) += cdns-dsi.o - obj-$(CONFIG_DRM_CHRONTEL_CH7033) += chrontel-ch7033.o - obj-$(CONFIG_DRM_DISPLAY_CONNECTOR) += display-connector.o -+obj-$(CONFIG_DRM_ITE_IT66121) += ite-it66121.o - obj-$(CONFIG_DRM_LVDS_CODEC) += lvds-codec.o - obj-$(CONFIG_DRM_MEGACHIPS_STDPXXXX_GE_B850V3_FW) += megachips-stdpxxxx-ge-b850v3-fw.o - obj-$(CONFIG_DRM_NXP_PTN3460) += nxp-ptn3460.o -diff --git a/drivers/gpu/drm/bridge/ite-it66121.c b/drivers/gpu/drm/bridge/ite-it66121.c -new file mode 100644 -index 000000000000..7e1a90319a6a ---- /dev/null -+++ b/drivers/gpu/drm/bridge/ite-it66121.c -@@ -0,0 +1,997 @@ -+// SPDX-License-Identifier: GPL-2.0-only -+/* -+ * Copyright (C) 2020 BayLibre, SAS -+ * Author: Phong LE -+ * Copyright (C) 2018-2019, Artem Mygaiev -+ * Copyright (C) 2017, Fresco Logic, Incorporated. -+ * -+ */ -+ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+ -+#define IT66121_MASTER_SEL_REG 0x10 -+#define IT66121_MASTER_SEL_HOST BIT(0) -+ -+#define IT66121_AFE_DRV_REG 0x61 -+#define IT66121_AFE_DRV_RST BIT(4) -+#define IT66121_AFE_DRV_PWD BIT(5) -+ -+#define IT66121_INPUT_MODE_REG 0x70 -+#define IT66121_INPUT_MODE_RGB (0 << 6) -+#define IT66121_INPUT_MODE_YUV422 BIT(6) -+#define IT66121_INPUT_MODE_YUV444 (2 << 6) -+#define IT66121_INPUT_MODE_CCIR656 BIT(4) -+#define IT66121_INPUT_MODE_SYNCEMB BIT(3) -+#define IT66121_INPUT_MODE_DDR BIT(2) -+ -+#define IT66121_INPUT_CSC_REG 0x72 -+#define IT66121_INPUT_CSC_ENDITHER BIT(7) -+#define IT66121_INPUT_CSC_ENUDFILTER BIT(6) -+#define IT66121_INPUT_CSC_DNFREE_GO BIT(5) -+#define IT66121_INPUT_CSC_RGB_TO_YUV 0x02 -+#define IT66121_INPUT_CSC_YUV_TO_RGB 0x03 -+#define IT66121_INPUT_CSC_NO_CONV 0x00 -+ -+#define IT66121_AFE_XP_REG 0x62 -+#define IT66121_AFE_XP_GAINBIT BIT(7) -+#define IT66121_AFE_XP_PWDPLL BIT(6) -+#define IT66121_AFE_XP_ENI BIT(5) -+#define IT66121_AFE_XP_ENO BIT(4) -+#define IT66121_AFE_XP_RESETB BIT(3) -+#define IT66121_AFE_XP_PWDI BIT(2) -+ -+#define IT66121_AFE_IP_REG 0x64 -+#define IT66121_AFE_IP_GAINBIT BIT(7) -+#define IT66121_AFE_IP_PWDPLL BIT(6) -+#define IT66121_AFE_IP_CKSEL_05 (0 << 4) -+#define IT66121_AFE_IP_CKSEL_1 BIT(4) -+#define IT66121_AFE_IP_CKSEL_2 (2 << 4) -+#define IT66121_AFE_IP_CKSEL_2OR4 (3 << 4) -+#define IT66121_AFE_IP_ER0 BIT(3) -+#define IT66121_AFE_IP_RESETB BIT(2) -+#define IT66121_AFE_IP_ENC BIT(1) -+#define IT66121_AFE_IP_EC1 BIT(0) -+ -+#define IT66121_AFE_XP_EC1_REG 0x68 -+#define IT66121_AFE_XP_EC1_LOWCLK BIT(4) -+ -+#define IT66121_SW_RST_REG 0x04 -+#define IT66121_SW_RST_REF BIT(5) -+#define IT66121_SW_RST_AREF BIT(4) -+#define IT66121_SW_RST_VID BIT(3) -+#define IT66121_SW_RST_AUD BIT(2) -+#define IT66121_SW_RST_HDCP BIT(0) -+ -+#define IT66121_DDC_COMMAND_REG 0x15 -+#define IT66121_DDC_COMMAND_BURST_READ 0x0 -+#define IT66121_DDC_COMMAND_EDID_READ 0x3 -+#define IT66121_DDC_COMMAND_FIFO_CLR 0x9 -+#define IT66121_DDC_COMMAND_SCL_PULSE 0xA -+#define IT66121_DDC_COMMAND_ABORT 0xF -+ -+#define IT66121_HDCP_REG 0x20 -+#define IT66121_HDCP_CPDESIRED BIT(0) -+#define IT66121_HDCP_EN1P1FEAT BIT(1) -+ -+#define IT66121_INT_STATUS1_REG 0x06 -+#define IT66121_INT_STATUS1_AUD_OVF BIT(7) -+#define IT66121_INT_STATUS1_DDC_NOACK BIT(5) -+#define IT66121_INT_STATUS1_DDC_FIFOERR BIT(4) -+#define IT66121_INT_STATUS1_DDC_BUSHANG BIT(2) -+#define IT66121_INT_STATUS1_RX_SENS_STATUS BIT(1) -+#define IT66121_INT_STATUS1_HPD_STATUS BIT(0) -+ -+#define IT66121_DDC_HEADER_REG 0x11 -+#define IT66121_DDC_HEADER_HDCP 0x74 -+#define IT66121_DDC_HEADER_EDID 0xA0 -+ -+#define IT66121_DDC_OFFSET_REG 0x12 -+#define IT66121_DDC_BYTE_REG 0x13 -+#define IT66121_DDC_SEGMENT_REG 0x14 -+#define IT66121_DDC_RD_FIFO_REG 0x17 -+ -+#define IT66121_CLK_BANK_REG 0x0F -+#define IT66121_CLK_BANK_PWROFF_RCLK BIT(6) -+#define IT66121_CLK_BANK_PWROFF_ACLK BIT(5) -+#define IT66121_CLK_BANK_PWROFF_TXCLK BIT(4) -+#define IT66121_CLK_BANK_PWROFF_CRCLK BIT(3) -+#define IT66121_CLK_BANK_0 0 -+#define IT66121_CLK_BANK_1 1 -+ -+#define IT66121_INT_REG 0x05 -+#define IT66121_INT_ACTIVE_HIGH BIT(7) -+#define IT66121_INT_OPEN_DRAIN BIT(6) -+#define IT66121_INT_TX_CLK_OFF BIT(0) -+ -+#define IT66121_INT_MASK1_REG 0x09 -+#define IT66121_INT_MASK1_AUD_OVF BIT(7) -+#define IT66121_INT_MASK1_DDC_NOACK BIT(5) -+#define IT66121_INT_MASK1_DDC_FIFOERR BIT(4) -+#define IT66121_INT_MASK1_DDC_BUSHANG BIT(2) -+#define IT66121_INT_MASK1_RX_SENS BIT(1) -+#define IT66121_INT_MASK1_HPD BIT(0) -+ -+#define IT66121_INT_CLR1_REG 0x0C -+#define IT66121_INT_CLR1_PKTACP BIT(7) -+#define IT66121_INT_CLR1_PKTNULL BIT(6) -+#define IT66121_INT_CLR1_PKTGEN BIT(5) -+#define IT66121_INT_CLR1_KSVLISTCHK BIT(4) -+#define IT66121_INT_CLR1_AUTHDONE BIT(3) -+#define IT66121_INT_CLR1_AUTHFAIL BIT(2) -+#define IT66121_INT_CLR1_RX_SENS BIT(1) -+#define IT66121_INT_CLR1_HPD BIT(0) -+ -+#define IT66121_AV_MUTE_REG 0xC1 -+#define IT66121_AV_MUTE_ON BIT(0) -+#define IT66121_AV_MUTE_BLUESCR BIT(1) -+ -+#define IT66121_PKT_GEN_CTRL_REG 0xC6 -+#define IT66121_PKT_GEN_CTRL_ON BIT(0) -+#define IT66121_PKT_GEN_CTRL_RPT BIT(1) -+ -+#define IT66121_AVIINFO_DB1_REG 0x158 -+#define IT66121_AVIINFO_DB2_REG 0x159 -+#define IT66121_AVIINFO_DB3_REG 0x15A -+#define IT66121_AVIINFO_DB4_REG 0x15B -+#define IT66121_AVIINFO_DB5_REG 0x15C -+#define IT66121_AVIINFO_CSUM_REG 0x15D -+#define IT66121_AVIINFO_DB6_REG 0x15E -+#define IT66121_AVIINFO_DB7_REG 0x15F -+#define IT66121_AVIINFO_DB8_REG 0x160 -+#define IT66121_AVIINFO_DB9_REG 0x161 -+#define IT66121_AVIINFO_DB10_REG 0x162 -+#define IT66121_AVIINFO_DB11_REG 0x163 -+#define IT66121_AVIINFO_DB12_REG 0x164 -+#define IT66121_AVIINFO_DB13_REG 0x165 -+ -+#define IT66121_AVI_INFO_PKT_REG 0xCD -+#define IT66121_AVI_INFO_PKT_ON BIT(0) -+#define IT66121_AVI_INFO_PKT_RPT BIT(1) -+ -+#define IT66121_HDMI_MODE_REG 0xC0 -+#define IT66121_HDMI_MODE_HDMI BIT(0) -+ -+#define IT66121_SYS_STATUS_REG 0x0E -+#define IT66121_SYS_STATUS_ACTIVE_IRQ BIT(7) -+#define IT66121_SYS_STATUS_HPDETECT BIT(6) -+#define IT66121_SYS_STATUS_SENDECTECT BIT(5) -+#define IT66121_SYS_STATUS_VID_STABLE BIT(4) -+#define IT66121_SYS_STATUS_AUD_CTS_CLR BIT(1) -+#define IT66121_SYS_STATUS_CLEAR_IRQ BIT(0) -+ -+#define IT66121_DDC_STATUS_REG 0x16 -+#define IT66121_DDC_STATUS_TX_DONE BIT(7) -+#define IT66121_DDC_STATUS_ACTIVE BIT(6) -+#define IT66121_DDC_STATUS_NOACK BIT(5) -+#define IT66121_DDC_STATUS_WAIT_BUS BIT(4) -+#define IT66121_DDC_STATUS_ARBI_LOSE BIT(3) -+#define IT66121_DDC_STATUS_FIFO_FULL BIT(2) -+#define IT66121_DDC_STATUS_FIFO_EMPTY BIT(1) -+#define IT66121_DDC_STATUS_FIFO_VALID BIT(0) -+ -+#define IT66121_VENDOR_ID0 0x54 -+#define IT66121_VENDOR_ID1 0x49 -+#define IT66121_DEVICE_ID0 0x12 -+#define IT66121_DEVICE_ID1 0x06 -+#define IT66121_DEVICE_MASK 0x0F -+#define IT66121_EDID_SLEEP 20000 -+#define IT66121_EDID_TIMEOUT 200000 -+#define IT66121_EDID_FIFO_SIZE 32 -+#define IT66121_AFE_CLK_HIGH 80000 -+ -+struct it66121_conf { -+ unsigned int input_mode_reg; -+ unsigned int input_conversion_reg; -+}; -+ -+struct it66121_ctx { -+ struct regmap *regmap; -+ struct drm_bridge bridge; -+ struct drm_connector connector; -+ struct device *dev; -+ struct gpio_desc *gpio_reset; -+ struct i2c_client *client; -+ struct regulator_bulk_data supplies[3]; -+ bool dual_edge; -+ const struct it66121_conf *conf; -+ struct mutex lock; /* Protects fields below and device registers */ -+ struct edid *edid; -+ struct hdmi_avi_infoframe hdmi_avi_infoframe; -+}; -+ -+static const struct regmap_range_cfg it66121_regmap_banks[] = { -+ { -+ .name = "it66121", -+ .range_min = 0x00, -+ .range_max = 0x1FF, -+ .selector_reg = IT66121_CLK_BANK_REG, -+ .selector_mask = 0x1, -+ .selector_shift = 0, -+ .window_start = 0x00, -+ .window_len = 0x130, -+ }, -+}; -+ -+static const struct regmap_config it66121_regmap_config = { -+ .val_bits = 8, -+ .reg_bits = 8, -+ .max_register = 0x1FF, -+ .ranges = it66121_regmap_banks, -+ .num_ranges = ARRAY_SIZE(it66121_regmap_banks), -+}; -+ -+static const struct it66121_conf it66121_conf_simple = { -+ .input_mode_reg = IT66121_INPUT_MODE_RGB | IT66121_INPUT_MODE_DDR, -+ .input_conversion_reg = IT66121_INPUT_CSC_NO_CONV, -+}; -+ -+static void it66121_hw_reset(struct it66121_ctx *ctx) -+{ -+ gpiod_set_value(ctx->gpio_reset, 1); -+ msleep(20); -+ gpiod_set_value(ctx->gpio_reset, 0); -+} -+ -+static int ite66121_power_on(struct it66121_ctx *ctx) -+{ -+ return regulator_bulk_enable(ARRAY_SIZE(ctx->supplies), ctx->supplies); -+} -+ -+static int ite66121_power_off(struct it66121_ctx *ctx) -+{ -+ return regulator_bulk_disable(ARRAY_SIZE(ctx->supplies), ctx->supplies); -+} -+ -+static int it66121_preamble_ddc(struct it66121_ctx *ctx) -+{ -+ return regmap_write(ctx->regmap, IT66121_MASTER_SEL_REG, -+ IT66121_MASTER_SEL_HOST); -+} -+ -+static int it66121_fire_afe(struct it66121_ctx *ctx) -+{ -+ return regmap_write(ctx->regmap, IT66121_AFE_DRV_REG, 0); -+} -+ -+static int it66121_configure_input(struct it66121_ctx *ctx) -+{ -+ int ret; -+ -+ ret = regmap_write(ctx->regmap, IT66121_INPUT_MODE_REG, -+ ctx->conf->input_mode_reg); -+ if (ret) -+ return ret; -+ -+ return regmap_write(ctx->regmap, IT66121_INPUT_CSC_REG, -+ ctx->conf->input_conversion_reg); -+} -+ -+/** -+ * it66121_configure_afe() - Configure the analog front end -+ * @ctx: it66121_ctx object -+ * -+ * RETURNS: -+ * zero if success, a negative error code otherwise. -+ */ -+static int it66121_configure_afe(struct it66121_ctx *ctx, -+ const struct drm_display_mode *mode) -+{ -+ int ret; -+ -+ ret = regmap_write(ctx->regmap, IT66121_AFE_DRV_REG, -+ IT66121_AFE_DRV_RST); -+ if (ret) -+ return ret; -+ -+ if (mode->clock > IT66121_AFE_CLK_HIGH) { -+ ret = regmap_write_bits(ctx->regmap, IT66121_AFE_XP_REG, -+ IT66121_AFE_XP_GAINBIT | -+ IT66121_AFE_XP_ENO, -+ IT66121_AFE_XP_GAINBIT); -+ if (ret) -+ return ret; -+ -+ ret = regmap_write_bits(ctx->regmap, IT66121_AFE_IP_REG, -+ IT66121_AFE_IP_GAINBIT | -+ IT66121_AFE_IP_ER0 | -+ IT66121_AFE_IP_EC1, -+ IT66121_AFE_IP_GAINBIT); -+ if (ret) -+ return ret; -+ -+ ret = regmap_write_bits(ctx->regmap, IT66121_AFE_XP_EC1_REG, -+ IT66121_AFE_XP_EC1_LOWCLK, 0x80); -+ if (ret) -+ return ret; -+ } else { -+ ret = regmap_write_bits(ctx->regmap, IT66121_AFE_XP_REG, -+ IT66121_AFE_XP_GAINBIT | -+ IT66121_AFE_XP_ENO, -+ IT66121_AFE_XP_ENO); -+ if (ret) -+ return ret; -+ -+ ret = regmap_write_bits(ctx->regmap, IT66121_AFE_IP_REG, -+ IT66121_AFE_IP_GAINBIT | -+ IT66121_AFE_IP_ER0 | -+ IT66121_AFE_IP_EC1, IT66121_AFE_IP_ER0 | -+ IT66121_AFE_IP_EC1); -+ if (ret) -+ return ret; -+ -+ ret = regmap_write_bits(ctx->regmap, IT66121_AFE_XP_EC1_REG, -+ IT66121_AFE_XP_EC1_LOWCLK, -+ IT66121_AFE_XP_EC1_LOWCLK); -+ if (ret) -+ return ret; -+ } -+ -+ /* Clear reset flags */ -+ ret = regmap_write_bits(ctx->regmap, IT66121_SW_RST_REG, -+ IT66121_SW_RST_REF | IT66121_SW_RST_VID, -+ ~(IT66121_SW_RST_REF | IT66121_SW_RST_VID) & -+ 0xFF); -+ if (ret) -+ return ret; -+ -+ return it66121_fire_afe(ctx); -+} -+ -+static inline int it66121_wait_ddc_ready(struct it66121_ctx *ctx) -+{ -+ int ret, val; -+ -+ ret = regmap_read_poll_timeout(ctx->regmap, IT66121_DDC_STATUS_REG, -+ val, true, -+ IT66121_EDID_SLEEP, -+ IT66121_EDID_TIMEOUT); -+ if (ret) -+ return ret; -+ -+ if (val & (IT66121_DDC_STATUS_NOACK | IT66121_DDC_STATUS_WAIT_BUS | -+ IT66121_DDC_STATUS_ARBI_LOSE)) -+ return -EAGAIN; -+ -+ return 0; -+} -+ -+static int it66121_clear_ddc_fifo(struct it66121_ctx *ctx) -+{ -+ int ret; -+ -+ ret = it66121_preamble_ddc(ctx); -+ if (ret) -+ return ret; -+ -+ return regmap_write(ctx->regmap, IT66121_DDC_COMMAND_REG, -+ IT66121_DDC_COMMAND_FIFO_CLR); -+} -+ -+static int it66121_abort_ddc_ops(struct it66121_ctx *ctx) -+{ -+ int ret; -+ unsigned int swreset, cpdesire; -+ -+ ret = regmap_read(ctx->regmap, IT66121_SW_RST_REG, &swreset); -+ if (ret) -+ return ret; -+ -+ ret = regmap_read(ctx->regmap, IT66121_HDCP_REG, &cpdesire); -+ if (ret) -+ return ret; -+ -+ ret = regmap_write(ctx->regmap, IT66121_HDCP_REG, -+ cpdesire & (~IT66121_HDCP_CPDESIRED & 0xFF)); -+ if (ret) -+ return ret; -+ -+ ret = regmap_write(ctx->regmap, IT66121_SW_RST_REG, -+ swreset | IT66121_SW_RST_HDCP); -+ if (ret) -+ return ret; -+ -+ ret = it66121_preamble_ddc(ctx); -+ if (ret) -+ return ret; -+ -+ ret = regmap_write(ctx->regmap, IT66121_DDC_COMMAND_REG, -+ IT66121_DDC_COMMAND_ABORT); -+ if (ret) -+ return ret; -+ -+ return it66121_wait_ddc_ready(ctx); -+} -+ -+static int it66121_get_edid_block(void *context, u8 *buf, -+ unsigned int block, size_t len) -+{ -+ struct it66121_ctx *ctx = context; -+ unsigned int val; -+ int remain = len; -+ int offset = 0; -+ int ret, cnt; -+ -+ offset = (block % 2) * len; -+ block = block / 2; -+ -+ ret = regmap_read(ctx->regmap, IT66121_INT_STATUS1_REG, &val); -+ if (ret) -+ return ret; -+ -+ if (val & IT66121_INT_STATUS1_DDC_BUSHANG) { -+ ret = it66121_abort_ddc_ops(ctx); -+ if (ret) -+ return ret; -+ } -+ -+ ret = it66121_clear_ddc_fifo(ctx); -+ if (ret) -+ return ret; -+ -+ while (remain > 0) { -+ cnt = (remain > IT66121_EDID_FIFO_SIZE) ? -+ IT66121_EDID_FIFO_SIZE : remain; -+ ret = it66121_preamble_ddc(ctx); -+ if (ret) -+ return ret; -+ -+ ret = regmap_write(ctx->regmap, IT66121_DDC_COMMAND_REG, -+ IT66121_DDC_COMMAND_FIFO_CLR); -+ if (ret) -+ return ret; -+ -+ ret = it66121_wait_ddc_ready(ctx); -+ if (ret) -+ return ret; -+ -+ ret = regmap_read(ctx->regmap, IT66121_INT_STATUS1_REG, &val); -+ if (ret) -+ return ret; -+ -+ if (val & IT66121_INT_STATUS1_DDC_BUSHANG) { -+ ret = it66121_abort_ddc_ops(ctx); -+ if (ret) -+ return ret; -+ } -+ -+ ret = it66121_preamble_ddc(ctx); -+ if (ret) -+ return ret; -+ -+ ret = regmap_write(ctx->regmap, IT66121_DDC_HEADER_REG, -+ IT66121_DDC_HEADER_EDID); -+ if (ret) -+ return ret; -+ -+ ret = regmap_write(ctx->regmap, IT66121_DDC_OFFSET_REG, offset); -+ if (ret) -+ return ret; -+ -+ ret = regmap_write(ctx->regmap, IT66121_DDC_BYTE_REG, cnt); -+ if (ret) -+ return ret; -+ -+ ret = regmap_write(ctx->regmap, IT66121_DDC_SEGMENT_REG, block); -+ if (ret) -+ return ret; -+ -+ ret = regmap_write(ctx->regmap, IT66121_DDC_COMMAND_REG, -+ IT66121_DDC_COMMAND_EDID_READ); -+ if (ret) -+ return ret; -+ -+ offset += cnt; -+ remain -= cnt; -+ msleep(20); -+ -+ ret = it66121_wait_ddc_ready(ctx); -+ if (ret) -+ return ret; -+ -+ do { -+ ret = regmap_read(ctx->regmap, -+ IT66121_DDC_RD_FIFO_REG, &val); -+ if (ret) -+ return ret; -+ *(buf++) = val; -+ cnt--; -+ } while (cnt > 0); -+ } -+ -+ return 0; -+} -+ -+static int it66121_connector_get_modes(struct drm_connector *connector) -+{ -+ int ret, num_modes = 0; -+ struct it66121_ctx *ctx = container_of(connector, struct it66121_ctx, -+ connector); -+ -+ if (ctx->edid) -+ return drm_add_edid_modes(connector, ctx->edid); -+ -+ mutex_lock(&ctx->lock); -+ -+ ctx->edid = drm_do_get_edid(connector, it66121_get_edid_block, ctx); -+ if (!ctx->edid) { -+ DRM_ERROR("Failed to read EDID\n"); -+ goto unlock; -+ } -+ -+ ret = drm_connector_update_edid_property(connector, -+ ctx->edid); -+ if (ret) { -+ DRM_ERROR("Failed to update EDID property: %d\n", ret); -+ goto unlock; -+ } -+ -+ num_modes = drm_add_edid_modes(connector, ctx->edid); -+ -+unlock: -+ mutex_unlock(&ctx->lock); -+ -+ return num_modes; -+} -+ -+static bool it66121_is_hpd_detect(struct it66121_ctx *ctx) -+{ -+ int val; -+ -+ if (regmap_read(ctx->regmap, IT66121_SYS_STATUS_REG, &val)) -+ return false; -+ -+ return (val & IT66121_SYS_STATUS_HPDETECT); -+} -+ -+static int it66121_connector_detect_ctx(struct drm_connector *connector, -+ struct drm_modeset_acquire_ctx *c, -+ bool force) -+{ -+ struct it66121_ctx *ctx = container_of(connector, struct it66121_ctx, -+ connector); -+ -+ return (it66121_is_hpd_detect(ctx)) ? -+ connector_status_connected : connector_status_disconnected; -+} -+ -+static enum drm_mode_status -+it66121_connector_mode_valid(struct drm_connector *connector, -+ struct drm_display_mode *mode) -+{ -+ unsigned long max_clock; -+ struct it66121_ctx *ctx = container_of(connector, struct it66121_ctx, -+ connector); -+ -+ max_clock = ctx->dual_edge ? 74250 : 148500; -+ -+ if (mode->clock > max_clock) -+ return MODE_CLOCK_HIGH; -+ -+ if (mode->clock < 25000) -+ return MODE_CLOCK_LOW; -+ -+ return MODE_OK; -+} -+ -+static struct drm_connector_helper_funcs it66121_connector_helper_funcs = { -+ .get_modes = it66121_connector_get_modes, -+ .detect_ctx = it66121_connector_detect_ctx, -+ .mode_valid = it66121_connector_mode_valid, -+}; -+ -+static const struct drm_connector_funcs it66121_connector_funcs = { -+ .reset = drm_atomic_helper_connector_reset, -+ .fill_modes = drm_helper_probe_single_connector_modes, -+ .destroy = drm_connector_cleanup, -+ .atomic_duplicate_state = drm_atomic_helper_connector_duplicate_state, -+ .atomic_destroy_state = drm_atomic_helper_connector_destroy_state, -+}; -+ -+static int it66121_bridge_attach(struct drm_bridge *bridge, -+ enum drm_bridge_attach_flags flags) -+{ -+ int ret; -+ struct it66121_ctx *ctx = container_of(bridge, struct it66121_ctx, -+ bridge); -+ -+ if (flags & DRM_BRIDGE_ATTACH_NO_CONNECTOR) { -+ DRM_ERROR("Fix bridge driver to make connector optional!"); -+ return -EINVAL; -+ } -+ -+ if (!bridge->encoder) { -+ DRM_ERROR("Parent encoder object not found"); -+ return -ENODEV; -+ } -+ -+ ret = regmap_write_bits(ctx->regmap, IT66121_CLK_BANK_REG, -+ IT66121_CLK_BANK_PWROFF_RCLK, 0); -+ if (ret) -+ return ret; -+ -+ ret = regmap_write_bits(ctx->regmap, IT66121_INT_REG, -+ IT66121_INT_TX_CLK_OFF, 0); -+ if (ret) -+ return ret; -+ -+ ret = regmap_write_bits(ctx->regmap, IT66121_AFE_DRV_REG, -+ IT66121_AFE_DRV_PWD, 0); -+ if (ret) -+ return ret; -+ -+ ret = regmap_write_bits(ctx->regmap, IT66121_AFE_XP_REG, -+ IT66121_AFE_XP_PWDI | IT66121_AFE_XP_PWDPLL, 0); -+ if (ret) -+ return ret; -+ -+ ret = regmap_write_bits(ctx->regmap, IT66121_AFE_IP_REG, -+ IT66121_AFE_IP_PWDPLL, 0); -+ if (ret) -+ return ret; -+ -+ ret = regmap_write_bits(ctx->regmap, IT66121_AFE_DRV_REG, -+ IT66121_AFE_DRV_RST, 0); -+ if (ret) -+ return ret; -+ -+ ret = regmap_write_bits(ctx->regmap, IT66121_AFE_XP_REG, -+ IT66121_AFE_XP_RESETB, IT66121_AFE_XP_RESETB); -+ if (ret) -+ return ret; -+ -+ ret = regmap_write_bits(ctx->regmap, IT66121_AFE_IP_REG, -+ IT66121_AFE_IP_RESETB, IT66121_AFE_IP_RESETB); -+ if (ret) -+ return ret; -+ -+ ret = regmap_write_bits(ctx->regmap, IT66121_SW_RST_REG, -+ IT66121_SW_RST_REF, -+ IT66121_SW_RST_REF); -+ if (ret) -+ return ret; -+ -+ msleep(50); -+ -+ ret = drm_connector_init(bridge->dev, &ctx->connector, -+ &it66121_connector_funcs, -+ DRM_MODE_CONNECTOR_HDMIA); -+ if (ret) -+ return ret; -+ -+ ctx->connector.polled = DRM_CONNECTOR_POLL_HPD; -+ drm_connector_helper_add(&ctx->connector, -+ &it66121_connector_helper_funcs); -+ -+ ret = drm_connector_attach_encoder(&ctx->connector, bridge->encoder); -+ if (ret) -+ return ret; -+ -+ ret = drm_connector_register(&ctx->connector); -+ if (ret) -+ return ret; -+ -+ /* Start interrupts */ -+ return regmap_write_bits(ctx->regmap, IT66121_INT_MASK1_REG, -+ IT66121_INT_MASK1_DDC_NOACK | -+ IT66121_INT_MASK1_HPD | -+ IT66121_INT_MASK1_DDC_FIFOERR | -+ IT66121_INT_MASK1_DDC_BUSHANG, -+ ~(IT66121_INT_MASK1_DDC_NOACK | -+ IT66121_INT_MASK1_HPD | -+ IT66121_INT_MASK1_DDC_FIFOERR | -+ IT66121_INT_MASK1_DDC_BUSHANG) & 0xFF); -+} -+ -+static int it66121_set_mute(struct it66121_ctx *ctx, bool mute) -+{ -+ int ret; -+ unsigned int val; -+ -+ val = mute ? IT66121_AV_MUTE_ON : (~IT66121_AV_MUTE_ON & 0xFF); -+ ret = regmap_write_bits(ctx->regmap, IT66121_AV_MUTE_REG, -+ IT66121_AV_MUTE_ON, val); -+ if (ret) -+ return ret; -+ -+ return regmap_write(ctx->regmap, IT66121_PKT_GEN_CTRL_REG, -+ IT66121_PKT_GEN_CTRL_ON | -+ IT66121_PKT_GEN_CTRL_RPT); -+} -+ -+static void it66121_bridge_enable(struct drm_bridge *bridge) -+{ -+ struct it66121_ctx *ctx = container_of(bridge, struct it66121_ctx, -+ bridge); -+ -+ it66121_set_mute(ctx, false); -+} -+ -+static void it66121_bridge_disable(struct drm_bridge *bridge) -+{ -+ struct it66121_ctx *ctx = container_of(bridge, struct it66121_ctx, -+ bridge); -+ -+ it66121_set_mute(ctx, true); -+} -+ -+static -+void it66121_bridge_mode_set(struct drm_bridge *bridge, -+ const struct drm_display_mode *mode, -+ const struct drm_display_mode *adjusted_mode) -+{ -+ int ret, i; -+ u8 buf[HDMI_INFOFRAME_SIZE(AVI)]; -+ struct it66121_ctx *ctx = container_of(bridge, struct it66121_ctx, -+ bridge); -+ const u16 aviinfo_reg[HDMI_AVI_INFOFRAME_SIZE] = { -+ IT66121_AVIINFO_DB1_REG, -+ IT66121_AVIINFO_DB2_REG, -+ IT66121_AVIINFO_DB3_REG, -+ IT66121_AVIINFO_DB4_REG, -+ IT66121_AVIINFO_DB5_REG, -+ IT66121_AVIINFO_DB6_REG, -+ IT66121_AVIINFO_DB7_REG, -+ IT66121_AVIINFO_DB8_REG, -+ IT66121_AVIINFO_DB9_REG, -+ IT66121_AVIINFO_DB10_REG, -+ IT66121_AVIINFO_DB11_REG, -+ IT66121_AVIINFO_DB12_REG, -+ IT66121_AVIINFO_DB13_REG -+ }; -+ -+ mutex_lock(&ctx->lock); -+ -+ hdmi_avi_infoframe_init(&ctx->hdmi_avi_infoframe); -+ -+ ret = drm_hdmi_avi_infoframe_from_display_mode(&ctx->hdmi_avi_infoframe, -+ &ctx->connector, -+ adjusted_mode); -+ if (ret) { -+ DRM_ERROR("Failed to setup AVI infoframe: %d\n", ret); -+ goto unlock; -+ } -+ -+ ret = hdmi_avi_infoframe_pack(&ctx->hdmi_avi_infoframe, buf, -+ sizeof(buf)); -+ if (ret < 0) { -+ DRM_ERROR("Failed to pack infoframe: %d\n", ret); -+ goto unlock; -+ } -+ -+ /* Write new AVI infoframe packet */ -+ for (i = 0; i < HDMI_AVI_INFOFRAME_SIZE; i++) { -+ if (regmap_write(ctx->regmap, aviinfo_reg[i], -+ buf[i + HDMI_INFOFRAME_HEADER_SIZE])) -+ goto unlock; -+ } -+ if (regmap_write(ctx->regmap, IT66121_AVIINFO_CSUM_REG, buf[3])) -+ goto unlock; -+ -+ /* Enable AVI infoframe */ -+ if (regmap_write(ctx->regmap, IT66121_AVI_INFO_PKT_REG, -+ IT66121_AVI_INFO_PKT_ON | -+ IT66121_AVI_INFO_PKT_RPT)) -+ goto unlock; -+ -+ /* Set TX mode to HDMI */ -+ if (regmap_write(ctx->regmap, IT66121_HDMI_MODE_REG, -+ IT66121_HDMI_MODE_HDMI)) -+ goto unlock; -+ -+ if (regmap_write_bits(ctx->regmap, IT66121_CLK_BANK_REG, -+ IT66121_CLK_BANK_PWROFF_TXCLK, -+ IT66121_CLK_BANK_PWROFF_TXCLK)) -+ goto unlock; -+ -+ if (it66121_configure_input(ctx)) -+ goto unlock; -+ -+ if (it66121_configure_afe(ctx, adjusted_mode)) -+ goto unlock; -+ -+ regmap_write_bits(ctx->regmap, IT66121_CLK_BANK_REG, -+ IT66121_CLK_BANK_PWROFF_TXCLK, -+ ~IT66121_CLK_BANK_PWROFF_TXCLK & 0xFF); -+ -+unlock: -+ mutex_unlock(&ctx->lock); -+} -+ -+static const struct drm_bridge_funcs it66121_bridge_funcs = { -+ .attach = it66121_bridge_attach, -+ .enable = it66121_bridge_enable, -+ .disable = it66121_bridge_disable, -+ .mode_set = it66121_bridge_mode_set, -+}; -+ -+static irqreturn_t it66121_irq_threaded_handler(int irq, void *dev_id) -+{ -+ int ret; -+ unsigned int val; -+ struct it66121_ctx *ctx = dev_id; -+ struct device *dev = ctx->dev; -+ bool event = false; -+ -+ mutex_lock(&ctx->lock); -+ -+ ret = regmap_read(ctx->regmap, IT66121_SYS_STATUS_REG, &val); -+ if (ret) -+ goto unlock; -+ -+ if (val & IT66121_SYS_STATUS_ACTIVE_IRQ) { -+ ret = regmap_read(ctx->regmap, IT66121_INT_STATUS1_REG, &val); -+ if (ret) { -+ dev_err(dev, "Cannot read STATUS1_REG %d\n", ret); -+ } else { -+ if (val & IT66121_INT_STATUS1_DDC_FIFOERR) -+ it66121_clear_ddc_fifo(ctx); -+ if (val & (IT66121_INT_STATUS1_DDC_BUSHANG | -+ IT66121_INT_STATUS1_DDC_NOACK)) -+ it66121_abort_ddc_ops(ctx); -+ if (val & IT66121_INT_STATUS1_HPD_STATUS) { -+ regmap_write_bits(ctx->regmap, -+ IT66121_INT_CLR1_REG, -+ IT66121_INT_CLR1_HPD, -+ IT66121_INT_CLR1_HPD); -+ -+ if (!it66121_is_hpd_detect(ctx)) { -+ kfree(ctx->edid); -+ ctx->edid = NULL; -+ } -+ event = true; -+ } -+ } -+ -+ regmap_write_bits(ctx->regmap, IT66121_SYS_STATUS_REG, -+ IT66121_SYS_STATUS_CLEAR_IRQ, -+ IT66121_SYS_STATUS_CLEAR_IRQ); -+ } -+ -+unlock: -+ mutex_unlock(&ctx->lock); -+ -+ if (event) -+ drm_helper_hpd_irq_event(ctx->bridge.dev); -+ -+ return IRQ_HANDLED; -+} -+ -+static int it66121_probe(struct i2c_client *client, -+ const struct i2c_device_id *id) -+{ -+ u8 ids[4]; -+ int i, ret; -+ struct it66121_ctx *ctx; -+ struct device *dev = &client->dev; -+ -+ if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C)) { -+ dev_err(dev, "I2C check functionality failed.\n"); -+ return -ENXIO; -+ } -+ -+ ctx = devm_kzalloc(dev, sizeof(*ctx), GFP_KERNEL); -+ if (!ctx) -+ return -ENOMEM; -+ -+ ctx->dev = dev; -+ ctx->client = client; -+ i2c_set_clientdata(client, ctx); -+ mutex_init(&ctx->lock); -+ ctx->conf = (struct it66121_conf *)of_device_get_match_data(dev); -+ if (!ctx->conf) -+ return -ENODEV; -+ -+ ctx->supplies[0].supply = "vcn33"; -+ ctx->supplies[1].supply = "vcn18"; -+ ctx->supplies[2].supply = "vrf12"; -+ ret = devm_regulator_bulk_get(ctx->dev, 3, ctx->supplies); -+ if (ret) { -+ dev_err(ctx->dev, "regulator_bulk failed\n"); -+ return ret; -+ } -+ -+ ctx->dual_edge = of_property_read_bool(dev->of_node, "pclk-dual-edge"); -+ -+ ret = ite66121_power_on(ctx); -+ if (ret) -+ return ret; -+ -+ it66121_hw_reset(ctx); -+ -+ ctx->regmap = devm_regmap_init_i2c(client, &it66121_regmap_config); -+ if (IS_ERR(ctx->regmap)) { -+ ite66121_power_off(ctx); -+ return PTR_ERR(ctx); -+ } -+ -+ for (i = 0; i < 4; i++) { -+ regmap_read(ctx->regmap, i, &ret); -+ ids[i] = ret; -+ } -+ -+ if (ids[0] != IT66121_VENDOR_ID0 || -+ ids[1] != IT66121_VENDOR_ID1 || -+ ids[2] != IT66121_DEVICE_ID0 || -+ ((ids[3] & IT66121_DEVICE_MASK) != IT66121_DEVICE_ID1)) { -+ ite66121_power_off(ctx); -+ return -ENODEV; -+ } -+ -+ ctx->bridge.funcs = &it66121_bridge_funcs; -+ ctx->bridge.of_node = dev->of_node; -+ -+ ret = devm_request_threaded_irq(dev, client->irq, NULL, -+ it66121_irq_threaded_handler, -+ IRQF_SHARED | IRQF_TRIGGER_LOW | -+ IRQF_ONESHOT, -+ dev_name(dev), -+ ctx); -+ if (ret < 0) { -+ dev_err(dev, "Failed to request irq %d:%d\n", client->irq, ret); -+ ite66121_power_off(ctx); -+ return ret; -+ } -+ -+ drm_bridge_add(&ctx->bridge); -+ -+ return 0; -+} -+ -+static int it66121_remove(struct i2c_client *client) -+{ -+ struct it66121_ctx *ctx = i2c_get_clientdata(client); -+ -+ ite66121_power_off(ctx); -+ drm_bridge_remove(&ctx->bridge); -+ kfree(ctx->edid); -+ mutex_destroy(&ctx->lock); -+ -+ return 0; -+} -+ -+static const struct of_device_id it66121_dt_match[] = { -+ { .compatible = "ite,it66121", -+ .data = &it66121_conf_simple, -+ }, -+ { }, -+}; -+MODULE_DEVICE_TABLE(of, it66121_dt_match); -+ -+static const struct i2c_device_id it66121_id[] = { -+ { "it66121", 0 }, -+ { }, -+}; -+MODULE_DEVICE_TABLE(i2c, it66121_id); -+ -+static struct i2c_driver it66121_driver = { -+ .driver = { -+ .name = "it66121", -+ .of_match_table = it66121_dt_match, -+ }, -+ .probe = it66121_probe, -+ .remove = it66121_remove, -+ .id_table = it66121_id, -+}; -+ -+module_i2c_driver(it66121_driver); -+ -+MODULE_AUTHOR("Phong LE"); -+MODULE_DESCRIPTION("IT66121 HDMI transmitter driver"); -+MODULE_LICENSE("GPL v2"); - -From 16bbf295dbfda3cf315c62bbf42cd5e6a0796e45 Mon Sep 17 00:00:00 2001 -From: Phong LE -Date: Wed, 11 Mar 2020 13:51:35 +0100 -Subject: [PATCH] MAINTAINERS: add it66121 HDMI bridge driver entry - -Add Neil Armstrong and myself as maintainers - -Signed-off-by: Phong LE ---- - MAINTAINERS | 8 ++++++++ - 1 file changed, 8 insertions(+) - -diff --git a/MAINTAINERS b/MAINTAINERS -index 0a14444b5f65..587c013211ae 100644 ---- a/MAINTAINERS -+++ b/MAINTAINERS -@@ -9309,6 +9309,14 @@ Q: http://patchwork.linuxtv.org/project/linux-media/list/ - T: git git://linuxtv.org/anttip/media_tree.git - F: drivers/media/tuners/it913x* - -+ITE IT66121 HDMI BRIDGE DRIVER -+M: Phong LE -+M: Neil Armstrong -+S: Maintained -+F: drivers/gpu/drm/bridge/ite-it66121.c -+T: git git://anongit.freedesktop.org/drm/drm-misc -+F: Documentation/devicetree/bindings/display/bridge/ite,it66121.yaml -+ - IVTV VIDEO4LINUX DRIVER - M: Andy Walls - L: linux-media@vger.kernel.org - -From 687354cbf754607f5a6746a85289ff1096cf0242 Mon Sep 17 00:00:00 2001 -From: Alex Bee -Date: Tue, 26 May 2020 13:48:12 +0200 -Subject: [PATCH] drm: bridge: it66121: add IT66121FN variant - ---- - drivers/gpu/drm/bridge/ite-it66121.c | 8 ++++++++ - 1 file changed, 8 insertions(+) - -diff --git a/drivers/gpu/drm/bridge/ite-it66121.c b/drivers/gpu/drm/bridge/ite-it66121.c -index 7e1a90319a6a..68f7e50fdddd 100644 ---- a/drivers/gpu/drm/bridge/ite-it66121.c -+++ b/drivers/gpu/drm/bridge/ite-it66121.c -@@ -242,6 +242,11 @@ static const struct it66121_conf it66121_conf_simple = { - .input_conversion_reg = IT66121_INPUT_CSC_NO_CONV, - }; - -+static const struct it66121_conf it66121fn_conf_simple = { -+ .input_mode_reg = IT66121_INPUT_MODE_RGB, -+ .input_conversion_reg = IT66121_INPUT_CSC_NO_CONV, -+}; -+ - static void it66121_hw_reset(struct it66121_ctx *ctx) - { - gpiod_set_value(ctx->gpio_reset, 1); -@@ -970,6 +975,9 @@ static const struct of_device_id it66121_dt_match[] = { - { .compatible = "ite,it66121", - .data = &it66121_conf_simple, - }, -+ { .compatible = "ite,it66121fn", -+ .data = &it66121fn_conf_simple, -+ }, - { }, - }; - MODULE_DEVICE_TABLE(of, it66121_dt_match); - -From 2877f7c88109d3f0573073ca5183c8baef437c9d Mon Sep 17 00:00:00 2001 +From a8d962000848a237f8e8f0de8395d4e7df2a7197 Mon Sep 17 00:00:00 2001 From: Alex Bee Date: Sun, 16 Aug 2020 23:40:24 +0200 Subject: [PATCH] WIP: ARM: dts: rockchip add vpll clock to RK322Xs hdmi node @@ -5291,48 +3462,7 @@ index 4bc631881c05..f98a945c68d3 100644 pinctrl-0 = <&hdmii2c_xfer &hdmi_hpd &hdmi_cec>; resets = <&cru SRST_HDMI_P>; -From d1df7c9067139e04b9e0f6c11e5b1b88d4a6a07c Mon Sep 17 00:00:00 2001 -From: Alex Bee -Date: Tue, 18 Aug 2020 11:19:53 +0200 -Subject: [PATCH] drm/bridge: !cleanup: remove pr_infos - ---- - drivers/gpu/drm/bridge/synopsys/dw-hdmi-cec.c | 6 ------ - 1 file changed, 6 deletions(-) - -diff --git a/drivers/gpu/drm/bridge/synopsys/dw-hdmi-cec.c b/drivers/gpu/drm/bridge/synopsys/dw-hdmi-cec.c -index e6953219beee..2cfd5b418c05 100644 ---- a/drivers/gpu/drm/bridge/synopsys/dw-hdmi-cec.c -+++ b/drivers/gpu/drm/bridge/synopsys/dw-hdmi-cec.c -@@ -97,8 +97,6 @@ static int dw_hdmi_cec_transmit(struct cec_adapter *adap, u8 attempts, - struct dw_hdmi_cec *cec = cec_get_drvdata(adap); - unsigned int i, ctrl; - -- pr_info("%s: attempts=%u signal_free_time=%u msg=%*ph (sequence: %u)\n", __func__, attempts, signal_free_time, msg->len, msg->msg, msg->sequence); -- - switch (signal_free_time) { - case CEC_SIGNAL_FREE_TIME_RETRY: - ctrl = CEC_CTRL_RETRY; -@@ -188,8 +186,6 @@ static irqreturn_t dw_hdmi_cec_hardirq(int irq, void *data) - ret = IRQ_WAKE_THREAD; - } - -- pr_info("%s: stat=%x ret=%x tx_done=%d rx_done=%d tx_status=%u tx_attempts=%u\n", __func__, stat, ret, cec->tx_done, cec->rx_done, cec->tx_status, cec->tx_attempts); -- - return ret; - } - -@@ -198,8 +194,6 @@ static irqreturn_t dw_hdmi_cec_thread(int irq, void *data) - struct cec_adapter *adap = data; - struct dw_hdmi_cec *cec = cec_get_drvdata(adap); - -- //pr_info("%s: tx_done=%d rx_done=%d tx_status=%u tx_attempts=%u\n", __func__, cec->tx_done, cec->rx_done, cec->tx_status, cec->tx_attempts); -- - if (cec->tx_done) { - cec->tx_done = false; - if (cec->tx_status == CEC_TX_STATUS_LOW_DRIVE) - -From b145995aa4a89abae1799b469297fef1857d62b3 Mon Sep 17 00:00:00 2001 +From 30c781872a7b883b18193fa5aed75c312b06f4ab 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 @@ -5387,3 +3517,1188 @@ index 9b1cc0f413fc..a34ff7593e1f 100644 VOP_WIN_SET(vop, win, uv_mst, dma_addr); for (i = 0; i < NUM_YUV2YUV_COEFFICIENTS; i++) { + +From b26ffb40570c456d0f84a3fa7886e2120c0397c2 Mon Sep 17 00:00:00 2001 +From: Alex Bee +Date: Tue, 26 May 2020 13:48:12 +0200 +Subject: [PATCH] drm: bridge: it66121: add IT66121FN variant + +--- + drivers/gpu/drm/bridge/ite-it66121.c | 8 ++++++++ + 1 file changed, 8 insertions(+) + +diff --git a/drivers/gpu/drm/bridge/ite-it66121.c b/drivers/gpu/drm/bridge/ite-it66121.c +index 7e1a90319a6a..68f7e50fdddd 100644 +--- a/drivers/gpu/drm/bridge/ite-it66121.c ++++ b/drivers/gpu/drm/bridge/ite-it66121.c +@@ -242,6 +242,11 @@ static const struct it66121_conf it66121_conf_simple = { + .input_conversion_reg = IT66121_INPUT_CSC_NO_CONV, + }; + ++static const struct it66121_conf it66121fn_conf_simple = { ++ .input_mode_reg = IT66121_INPUT_MODE_RGB, ++ .input_conversion_reg = IT66121_INPUT_CSC_NO_CONV, ++}; ++ + static void it66121_hw_reset(struct it66121_ctx *ctx) + { + gpiod_set_value(ctx->gpio_reset, 1); +@@ -970,6 +975,9 @@ static const struct of_device_id it66121_dt_match[] = { + { .compatible = "ite,it66121", + .data = &it66121_conf_simple, + }, ++ { .compatible = "ite,it66121fn", ++ .data = &it66121fn_conf_simple, ++ }, + { }, + }; + MODULE_DEVICE_TABLE(of, it66121_dt_match); + +From a52fbdfbb0bccb1202beb25b58bdc29517c178d2 Mon Sep 17 00:00:00 2001 +From: Alex Bee +Date: Tue, 18 Aug 2020 23:15:45 +0200 +Subject: [PATCH] HACK: drm/rockchip: return false in ... if no platform device + is found + +This check will perfectly fail for bridges which are connected via i2c +and are therefore no platform devices. +TODO: look for a smarter solution + +Signed-off-by: Alex Bee +--- + drivers/gpu/drm/rockchip/rockchip_drm_drv.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_drv.c b/drivers/gpu/drm/rockchip/rockchip_drm_drv.c +index b7654f5e4225..44ec8003e2a4 100644 +--- a/drivers/gpu/drm/rockchip/rockchip_drm_drv.c ++++ b/drivers/gpu/drm/rockchip/rockchip_drm_drv.c +@@ -274,7 +274,7 @@ int rockchip_drm_endpoint_is_subdriver(struct device_node *ep) + pdev = of_find_device_by_node(node); + of_node_put(node); + if (!pdev) +- return -ENODEV; ++ return false; + + /* + * All rockchip subdrivers have probed at this point, so + +From 1fca49c650ba0441613da75e43323afb5525c8de Mon Sep 17 00:00:00 2001 +From: Alex Bee +Date: Tue, 18 Aug 2020 14:22:32 +0200 +Subject: [PATCH] drm/bridge: it66121 fix regmap config + +registers 0x00~0x2f don't need/must not have a selector +also: fix regmap range +--- + drivers/gpu/drm/bridge/ite-it66121.c | 12 ++++++------ + 1 file changed, 6 insertions(+), 6 deletions(-) + +diff --git a/drivers/gpu/drm/bridge/ite-it66121.c b/drivers/gpu/drm/bridge/ite-it66121.c +index 68f7e50fdddd..90f0881818d6 100644 +--- a/drivers/gpu/drm/bridge/ite-it66121.c ++++ b/drivers/gpu/drm/bridge/ite-it66121.c +@@ -218,21 +218,21 @@ struct it66121_ctx { + + static const struct regmap_range_cfg it66121_regmap_banks[] = { + { +- .name = "it66121", +- .range_min = 0x00, +- .range_max = 0x1FF, ++ .name = "it66121-banks", ++ .range_min = 0x30, ++ .range_max = 0x1bf, + .selector_reg = IT66121_CLK_BANK_REG, + .selector_mask = 0x1, + .selector_shift = 0, +- .window_start = 0x00, +- .window_len = 0x130, ++ .window_start = 0x30, ++ .window_len = 0xcf, + }, + }; + + static const struct regmap_config it66121_regmap_config = { + .val_bits = 8, + .reg_bits = 8, +- .max_register = 0x1FF, ++ .max_register = 0x1bf, + .ranges = it66121_regmap_banks, + .num_ranges = ARRAY_SIZE(it66121_regmap_banks), + }; + +From 525f46ff24e5db028d341d04d1aede0cfc672c39 Mon Sep 17 00:00:00 2001 +From: Alex Bee +Date: Tue, 18 Aug 2020 17:29:54 +0200 +Subject: [PATCH] drm/bridge: it66121 add detection message + +--- + drivers/gpu/drm/bridge/ite-it66121.c | 5 ++++- + 1 file changed, 4 insertions(+), 1 deletion(-) + +diff --git a/drivers/gpu/drm/bridge/ite-it66121.c b/drivers/gpu/drm/bridge/ite-it66121.c +index 90f0881818d6..650dd2f063cc 100644 +--- a/drivers/gpu/drm/bridge/ite-it66121.c ++++ b/drivers/gpu/drm/bridge/ite-it66121.c +@@ -936,8 +936,11 @@ static int it66121_probe(struct i2c_client *client, + ids[2] != IT66121_DEVICE_ID0 || + ((ids[3] & IT66121_DEVICE_MASK) != IT66121_DEVICE_ID1)) { + ite66121_power_off(ctx); ++ DRM_INFO("HDMITX it66121 could not be indentified.\n"); + return -ENODEV; +- } ++ } else ++ DRM_INFO("HDMITX it66121 rev %d succsessfully indentified.\n", ++ ids[3] >> 4); + + ctx->bridge.funcs = &it66121_bridge_funcs; + ctx->bridge.of_node = dev->of_node; + +From ff31ba7e3c18672f7fa3ac17f9399301cc55cacb Mon Sep 17 00:00:00 2001 +From: Alex Bee +Date: Tue, 18 Aug 2020 22:28:21 +0200 +Subject: [PATCH] drm/bridge it66121 add AFE_XP_PLL_CTRL settings + +Add IT66121_AFE_XP_PLL_CTRL settings, it's unknown what they actualy +mean, since there is no documentation about it. Values have been taken +from vendor driver and it helps stablize signal at 1080p modes. + +Signed-off-by: Alex Bee +--- + drivers/gpu/drm/bridge/ite-it66121.c | 18 ++++++++++++++++++ + 1 file changed, 18 insertions(+) + +diff --git a/drivers/gpu/drm/bridge/ite-it66121.c b/drivers/gpu/drm/bridge/ite-it66121.c +index 650dd2f063cc..bc6ca85e5ee1 100644 +--- a/drivers/gpu/drm/bridge/ite-it66121.c ++++ b/drivers/gpu/drm/bridge/ite-it66121.c +@@ -72,6 +72,10 @@ + #define IT66121_AFE_XP_EC1_REG 0x68 + #define IT66121_AFE_XP_EC1_LOWCLK BIT(4) + ++#define IT66121_AFE_XP_PLL_CTRL 0x6a ++#define IT66121_AFE_XP_PLL_HIGH_CLK_MASK (BIT(4) | BIT(5) | \ ++ BIT(6)) ++ + #define IT66121_SW_RST_REG 0x04 + #define IT66121_SW_RST_REF BIT(5) + #define IT66121_SW_RST_AREF BIT(4) +@@ -325,6 +329,13 @@ static int it66121_configure_afe(struct it66121_ctx *ctx, + IT66121_AFE_XP_EC1_LOWCLK, 0x80); + if (ret) + return ret; ++ ++ ret = regmap_write_bits(ctx->regmap, IT66121_AFE_XP_PLL_CTRL, ++ IT66121_AFE_XP_PLL_HIGH_CLK_MASK, ++ IT66121_AFE_XP_PLL_HIGH_CLK_MASK); ++ if (ret) ++ return ret; ++ + } else { + ret = regmap_write_bits(ctx->regmap, IT66121_AFE_XP_REG, + IT66121_AFE_XP_GAINBIT | +@@ -346,6 +357,13 @@ static int it66121_configure_afe(struct it66121_ctx *ctx, + IT66121_AFE_XP_EC1_LOWCLK); + if (ret) + return ret; ++ ++ ++ ret = regmap_write_bits(ctx->regmap, IT66121_AFE_XP_PLL_CTRL, ++ IT66121_AFE_XP_PLL_HIGH_CLK_MASK, ++ ~(IT66121_AFE_XP_PLL_HIGH_CLK_MASK) & 0xff); ++ if (ret) ++ return ret; + } + + /* Clear reset flags */ + +From 2a962b60c92993e1a1c82e74a403b33641d1cfbd Mon Sep 17 00:00:00 2001 +From: Alex Bee +Date: Wed, 19 Aug 2020 19:02:02 +0200 +Subject: [PATCH] drm/bridge it66121 fire_afe if IT66121_SYS_STATUS_VID_STABLE + +There is an interrupt if video is stable - we should fire afe after that +arrived. + +Signed-off-by: Alex Bee +--- + drivers/gpu/drm/bridge/ite-it66121.c | 101 ++++++++++++++++++++++----- + 1 file changed, 83 insertions(+), 18 deletions(-) + +diff --git a/drivers/gpu/drm/bridge/ite-it66121.c b/drivers/gpu/drm/bridge/ite-it66121.c +index bc6ca85e5ee1..81d1f53d50f5 100644 +--- a/drivers/gpu/drm/bridge/ite-it66121.c ++++ b/drivers/gpu/drm/bridge/ite-it66121.c +@@ -95,12 +95,30 @@ + #define IT66121_HDCP_EN1P1FEAT BIT(1) + + #define IT66121_INT_STATUS1_REG 0x06 +-#define IT66121_INT_STATUS1_AUD_OVF BIT(7) +-#define IT66121_INT_STATUS1_DDC_NOACK BIT(5) +-#define IT66121_INT_STATUS1_DDC_FIFOERR BIT(4) +-#define IT66121_INT_STATUS1_DDC_BUSHANG BIT(2) +-#define IT66121_INT_STATUS1_RX_SENS_STATUS BIT(1) +-#define IT66121_INT_STATUS1_HPD_STATUS BIT(0) ++#define IT66121_INT_STATUS1_AUD_OVF BIT(7) ++#define IT66121_INT_STATUS1_DDC_NOACK BIT(5) ++#define IT66121_INT_STATUS1_DDC_FIFOERR BIT(4) ++#define IT66121_INT_STATUS1_DDC_BUSHANG BIT(2) ++#define IT66121_INT_STATUS1_RX_SENS_STATUS BIT(1) ++#define IT66121_INT_STATUS1_HPD_STATUS BIT(0) ++ ++#define IT66121_INT_STATUS2_REG 0x07 ++#define IT66121_INT_STATUS2_PKT_3D BIT(7) ++#define IT66121_INT_STATUS2_VID_UNSTABLE BIT(6) ++#define IT66121_INT_STATUS2_PKT_ACP BIT(5) ++#define IT66121_INT_STATUS2_PKT_NULL BIT(4) ++#define IT66121_INT_STATUS2_PKT_GEN BIT(3) ++#define IT66121_INT_STATUS2_CHK_KSV_LIST BIT(2) ++#define IT66121_INT_STATUS2_AUTH_DONE BIT(1) ++#define IT66121_INT_STATUS2_AUTH_FAIL BIT(0) ++ ++#define IT66121_INT_STATUS3_REG 0x08 ++#define IT66121_INT_STATUS3_AUD_CTS BIT(6) ++#define IT66121_INT_STATUS3_VSYNC BIT(5) ++#define IT66121_INT_STATUS3_VID_STABLE BIT(4) ++#define IT66121_INT_STATUS2_PKT_MPEG BIT(3) ++#define IT66121_INT_STATUS3_PKT_AUD BIT(1) ++#define IT66121_INT_STATUS3_PKT_AVI BIT(0) + + #define IT66121_DDC_HEADER_REG 0x11 + #define IT66121_DDC_HEADER_HDCP 0x74 +@@ -132,16 +150,43 @@ + #define IT66121_INT_MASK1_RX_SENS BIT(1) + #define IT66121_INT_MASK1_HPD BIT(0) + ++#define IT66121_INT_MASK2_REG 0x0a ++#define IT66121_INT_MASK2_PKT_AVI BIT(7) ++#define IT66121_INT_MASK2_VID_UNSTABLE BIT(6) ++#define IT66121_INT_MASK2_PKT_ACP BIT(5) ++#define IT66121_INT_MASK2_PKT_NULL BIT(4) ++#define IT66121_INT_MASK2_PKT_GEN BIT(3) ++#define IT66121_INT_MASK2_CHK_KSV_LIST BIT(2) ++#define IT66121_INT_MASK2_AUTH_DONE BIT(1) ++#define IT66121_INT_MASK2_AUTH_FAIL BIT(0) ++ ++#define IT66121_INT_MASK3_REG 0x0b ++#define IT66121_INT_MASK3_PKT_3D BIT(6) ++#define IT66121_INT_MASK3_AUD_CTS BIT(5) ++#define IT66121_INT_MASK3_VSYNC BIT(4) ++#define IT66121_INT_MASK3_VID_STABLE BIT(3) ++#define IT66121_INT_MASK3_PKT_MPEG BIT(2) ++#define IT66121_INT_MASK3_PKT_AUD BIT(0) ++ + #define IT66121_INT_CLR1_REG 0x0C +-#define IT66121_INT_CLR1_PKTACP BIT(7) +-#define IT66121_INT_CLR1_PKTNULL BIT(6) +-#define IT66121_INT_CLR1_PKTGEN BIT(5) +-#define IT66121_INT_CLR1_KSVLISTCHK BIT(4) +-#define IT66121_INT_CLR1_AUTHDONE BIT(3) +-#define IT66121_INT_CLR1_AUTHFAIL BIT(2) ++#define IT66121_INT_CLR1_PKT_ACP BIT(7) ++#define IT66121_INT_CLR1_PKT_NULL BIT(6) ++#define IT66121_INT_CLR1_PKT_GEN BIT(5) ++#define IT66121_INT_CLR1_CHK_KSV_LIST BIT(4) ++#define IT66121_INT_CLR1_AUTH_DONE BIT(3) ++#define IT66121_INT_CLR1_AUTH_FAIL BIT(2) + #define IT66121_INT_CLR1_RX_SENS BIT(1) + #define IT66121_INT_CLR1_HPD BIT(0) + ++#define IT66121_INT_CLR2_REG 0x0d ++#define IT66121_INT_CLR2_VSYNC BIT(7) ++#define IT66121_INT_CLR2_VID_STABLE BIT(6) ++#define IT66121_INT_CLR2_PKT_MPEG BIT(5) ++#define IT66121_INT_CLR2_PKT_AUD BIT(3) ++#define IT66121_INT_CLR2_PKT_AVI BIT(2) ++#define IT66121_INT_CLR2_PKT_3D BIT(1) ++#define IT66121_INT_CLR2_VID_UNSTABLE BIT(0) ++ + #define IT66121_AV_MUTE_REG 0xC1 + #define IT66121_AV_MUTE_ON BIT(0) + #define IT66121_AV_MUTE_BLUESCR BIT(1) +@@ -371,10 +416,9 @@ static int it66121_configure_afe(struct it66121_ctx *ctx, + IT66121_SW_RST_REF | IT66121_SW_RST_VID, + ~(IT66121_SW_RST_REF | IT66121_SW_RST_VID) & + 0xFF); +- if (ret) +- return ret; + +- return it66121_fire_afe(ctx); ++ return ret; ++ + } + + static inline int it66121_wait_ddc_ready(struct it66121_ctx *ctx) +@@ -711,6 +755,12 @@ static int it66121_bridge_attach(struct drm_bridge *bridge, + return ret; + + /* Start interrupts */ ++ ret = regmap_write_bits(ctx->regmap, IT66121_INT_MASK3_REG, ++ IT66121_INT_MASK3_VID_STABLE, ++ ~(IT66121_INT_MASK3_VID_STABLE) & 0xff); ++ if (ret) ++ return ret; ++ + return regmap_write_bits(ctx->regmap, IT66121_INT_MASK1_REG, + IT66121_INT_MASK1_DDC_NOACK | + IT66121_INT_MASK1_HPD | +@@ -847,18 +897,18 @@ static const struct drm_bridge_funcs it66121_bridge_funcs = { + static irqreturn_t it66121_irq_threaded_handler(int irq, void *dev_id) + { + int ret; +- unsigned int val; ++ unsigned int val, sys_status; + struct it66121_ctx *ctx = dev_id; + struct device *dev = ctx->dev; + bool event = false; + + mutex_lock(&ctx->lock); + +- ret = regmap_read(ctx->regmap, IT66121_SYS_STATUS_REG, &val); ++ ret = regmap_read(ctx->regmap, IT66121_SYS_STATUS_REG, &sys_status); + if (ret) + goto unlock; + +- if (val & IT66121_SYS_STATUS_ACTIVE_IRQ) { ++ if (sys_status & IT66121_SYS_STATUS_ACTIVE_IRQ) { + ret = regmap_read(ctx->regmap, IT66121_INT_STATUS1_REG, &val); + if (ret) { + dev_err(dev, "Cannot read STATUS1_REG %d\n", ret); +@@ -882,6 +932,21 @@ static irqreturn_t it66121_irq_threaded_handler(int irq, void *dev_id) + } + } + ++ ret = regmap_read(ctx->regmap, IT66121_INT_STATUS3_REG, &val); ++ if (ret) { ++ dev_err(dev, "Cannot read STATUS3_REG %d\n", ret); ++ } else if (val) { ++ if (val & IT66121_INT_STATUS3_VID_STABLE) { ++ if (sys_status & IT66121_SYS_STATUS_VID_STABLE) ++ it66121_fire_afe(ctx); ++ ++ regmap_write_bits(ctx->regmap, ++ IT66121_INT_CLR2_REG, ++ IT66121_INT_CLR2_VID_STABLE, ++ IT66121_INT_CLR2_VID_STABLE); ++ } ++ } ++ + regmap_write_bits(ctx->regmap, IT66121_SYS_STATUS_REG, + IT66121_SYS_STATUS_CLEAR_IRQ, + IT66121_SYS_STATUS_CLEAR_IRQ); + +From 2ec0caed703ceb5aad46c162c1f3fde4789fd635 Mon Sep 17 00:00:00 2001 +From: Alex Bee +Date: Tue, 18 Aug 2020 22:44:12 +0200 +Subject: [PATCH] drm/bridge it66121: add I2S sound support + +Add sound support for it66121 - todos: + - TODOs + - refactor some huge functions + - smarter error handling (whole driver) + +Signed-off-by: Alex Bee +--- + drivers/gpu/drm/bridge/Kconfig | 1 + + drivers/gpu/drm/bridge/ite-it66121.c | 685 +++++++++++++++++++++++++++ + 2 files changed, 686 insertions(+) + +diff --git a/drivers/gpu/drm/bridge/Kconfig b/drivers/gpu/drm/bridge/Kconfig +index 6fe281070602..fd026f7cb4ba 100644 +--- a/drivers/gpu/drm/bridge/Kconfig ++++ b/drivers/gpu/drm/bridge/Kconfig +@@ -64,6 +64,7 @@ config DRM_LONTIUM_LT9611 + config DRM_ITE_IT66121 + tristate "ITE IT66121 HDMI bridge" + depends on OF ++ select SND_SOC_HDMI_CODEC if SND_SOC + select DRM_KMS_HELPER + select REGMAP_I2C + help +diff --git a/drivers/gpu/drm/bridge/ite-it66121.c b/drivers/gpu/drm/bridge/ite-it66121.c +index 81d1f53d50f5..98f3d68fe01f 100644 +--- a/drivers/gpu/drm/bridge/ite-it66121.c ++++ b/drivers/gpu/drm/bridge/ite-it66121.c +@@ -1,5 +1,6 @@ + // SPDX-License-Identifier: GPL-2.0-only + /* ++ * Copyright (C) 2020 Alex Bee + * Copyright (C) 2020 BayLibre, SAS + * Author: Phong LE + * Copyright (C) 2018-2019, Artem Mygaiev +@@ -26,6 +27,9 @@ + #include + #include + ++#include ++#include ++ + #define IT66121_MASTER_SEL_REG 0x10 + #define IT66121_MASTER_SEL_HOST BIT(0) + +@@ -245,11 +249,149 @@ + #define IT66121_EDID_FIFO_SIZE 32 + #define IT66121_AFE_CLK_HIGH 80000 + ++#define IT66121_AUD_CLK_CTRL_REG 0x58 ++#define IT66121_AUD_AUT_IP_CLK BIT(0) ++#define IT66121_AUD_AUT_OVR_SMPL_CLK BIT(4) ++#define IT66121_AUD_EXT_MCLK_128FS (0 << 2) ++#define IT66121_AUD_EXT_MCLK_256FS BIT(2) ++#define IT66121_AUD_EXT_MCLK_512FS (2 << 2) ++#define IT66121_AUD_EXT_MCLK_1024FS (3 << 2) ++ ++#define IT66121_AUD_INFO_REG_SZ 5 ++#define IT66121_AUD_INFO_DB1_REG 0x168 ++#define IT66121_AUD_INFO_DB2_REG 0x169 ++#define IT66121_AUD_INFO_DB3_REG 0x16a ++#define IT66121_AUD_INFO_DB4_REG 0x16b ++#define IT66121_AUD_INFO_DB5_REG 0x16c ++#define IT66121_AUD_INFO_CSUM_REG 0x16d ++ ++#define IT66121_AUD_INFO_PKT_REG 0xce ++#define IT66121_AUD_INFO_PKT_ON BIT(0) ++#define IT66121_AUD_INFO_PKT_RPT BIT(1) ++ ++#define IT66121_AUD_PKT_N1_REG 0x133 ++#define IT66121_AUD_PKT_N2_REG 0x134 ++#define IT66121_AUD_PKT_N3_REG 0x135 ++ ++#define IT66121_AUD_PKT_CTS_MODE_REG 0xc5 ++#define IT66121_AUD_PKT_CTS_MODE_USER BIT(1) ++#define IT66121_AUD_PKT_CTS_MODE_AUTO_VAL 0 ++#define IT66121_AUD_PKT_CTS1_REG 0x130 ++#define IT66121_AUD_PKT_CTS2_REG 0x131 ++#define IT66121_AUD_PKT_CTS3_REG 0x132 ++#define IT66121_AUD_PKT_AUTO_CNT_CTS1_REG 0x135 ++#define IT66121_AUD_PKT_AUTO_CNT_CTS2_REG 0x136 ++#define IT66121_AUD_PKT_AUTO_CNT_CTS3_REG 0x137 ++ ++#define IT66121_AUD_CHST_MODE_REG 0x191 ++#define IT66121_AUD_CHST_MODE_NLPCM BIT(1) ++#define IT66121_AUD_CHST_CAT_REG 0x192 ++#define IT66121_AUD_CHST_SRCNUM_REG 0x193 ++#define IT66121_AUD_CHST_CHTNUM_REG 0x194 ++#define IT66121_AUD_CHST_CA_FS_REG 0x198 ++#define IT66121_AUD_CHST_OFS_WL_REG 0x199 ++ ++#define IT66121_AUD_CTRL0_REG 0xe0 ++#define IT66121_AUD_SWL_16BIT (0 << 6) ++#define IT66121_AUD_SWL_18BIT BIT(6) ++#define IT66121_AUD_SWL_20BIT (2 << 6) ++#define IT66121_AUD_SWL_24BIT (3 << 6) ++#define IT66121_AUD_SWL_MASK IT66121_AUD_SWL_24BIT ++#define IT66121_AUD_SPDIFTC BIT(5) ++#define IT66121_AUD_SPDIF BIT(4) ++#define IT66121_AUD_I2S (0 << 4) ++#define IT66121_AUD_TYPE_MASK IT66121_AUD_SPDIF ++#define IT66121_AUD_EN_I2S3 BIT(3) ++#define IT66121_AUD_EN_I2S2 BIT(2) ++#define IT66121_AUD_EN_I2S1 BIT(1) ++#define IT66121_AUD_EN_I2S0 BIT(0) ++#define IT66121_AUD_EN_I2S_MASK 0x0f ++#define IT66121_AUD_EN_SPDIF 1 ++ ++#define IT66121_AUD_CTRL1_REG 0xe1 ++#define IT66121_AUD_FMT_STD_I2S (0 << 0) ++#define IT66121_AUD_FMT_32BIT_I2S BIT(0) ++#define IT66121_AUD_FMT_LEFT_JUSTIFY (0 << 1) ++#define IT66121_AUD_FMT_RIGHT_JUSTIFY BIT(1) ++#define IT66121_AUD_FMT_DELAY_1T_TO_WS (0 << 2) ++#define IT66121_AUD_FMT_NO_DELAY_TO_WS BIT(2) ++#define IT66121_AUD_FMT_WS0_LEFT (0 << 3) ++#define IT66121_AUD_FMT_WS0_RIGHT BIT(3) ++#define IT66121_AUD_FMT_MSB_SHIFT_FIRST (0 << 4) ++#define IT66121_AUD_FMT_LSB_SHIFT_FIRST BIT(4) ++#define IT66121_AUD_FMT_RISE_EDGE_SAMPLE_WS (0 << 5) ++#define IT66121_AUD_FMT_FALL_EDGE_SAMPLE_WS BIT(5) ++#define IT66121_AUD_FMT_FULLPKT BIT(6) ++ ++#define IT66121_AUD_FIFOMAP_REG 0xe2 ++#define IT66121_AUD_FIFO3_SEL 6 ++#define IT66121_AUD_FIFO2_SEL 4 ++#define IT66121_AUD_FIFO1_SEL 2 ++#define IT66121_AUD_FIFO0_SEL 0 ++#define IT66121_AUD_FIFO_SELSRC3 3 ++#define IT66121_AUD_FIFO_SELSRC2 2 ++#define IT66121_AUD_FIFO_SELSRC1 1 ++#define IT66121_AUD_FIFO_SELSRC0 0 ++#define IT66121_AUD_FIFOMAP_DEFAULT (IT66121_AUD_FIFO_SELSRC0 \ ++ << IT66121_AUD_FIFO0_SEL | \ ++ IT66121_AUD_FIFO_SELSRC1 \ ++ << IT66121_AUD_FIFO1_SEL | \ ++ IT66121_AUD_FIFO_SELSRC2 \ ++ << IT66121_AUD_FIFO2_SEL | \ ++ IT66121_AUD_FIFO_SELSRC3 \ ++ << IT66121_AUD_FIFO3_SEL) ++ ++#define IT66121_AUD_CTRL3_REG 0xe3 ++#define IT66121_AUD_MULCH BIT(7) ++#define IT66121_AUD_ZERO_CTS BIT(6) ++#define IT66121_AUD_CHSTSEL BIT(4) ++#define IT66121_AUD_S3RLCHG BIT(3) ++#define IT66121_AUD_S2RLCHG BIT(2) ++#define IT66121_AUD_S1RLCHG BIT(1) ++#define IT66121_AUD_S0RLCHG BIT(0) ++#define IT66121_AUD_SRLCHG_MASK 0x0f ++#define IT66121_AUD_SRLCHG_DEFAULT ((~IT66121_AUD_S0RLCHG & \ ++ ~IT66121_AUD_S1RLCHG & \ ++ ~IT66121_AUD_S2RLCHG & \ ++ ~IT66121_AUD_S3RLCHG) & \ ++ IT66121_AUD_SRLCHG_MASK) ++ ++#define IT66121_AUD_SRC_VALID_FLAT_REG 0xe4 ++#define IT66121_AUD_SPXFLAT_SRC3 BIT(7) ++#define IT66121_AUD_SPXFLAT_SRC2 BIT(6) ++#define IT66121_AUD_SPXFLAT_SRC1 BIT(5) ++#define IT66121_AUD_SPXFLAT_SRC0 BIT(4) ++#define IT66121_AUD_SPXFLAT_MASK 0xf0 ++#define IT66121_AUD_SPXFLAT_SRC_ALL (IT66121_AUD_SPXFLAT_SRC0 | \ ++ IT66121_AUD_SPXFLAT_SRC1 | \ ++ IT66121_AUD_SPXFLAT_SRC2 | \ ++ IT66121_AUD_SPXFLAT_SRC3) ++#define IT66121_AUD_ERR2FLAT BIT(3) ++#define IT66121_AUD_S3VALID BIT(2) ++#define IT66121_AUD_S2VALID BIT(1) ++#define IT66121_AUD_S1VALID BIT(0) ++ ++#define IT66121_AUD_HDAUDIO_REG 0xe5 ++#define IT66121_AUD_HBR BIT(3) ++#define IT66121_AUD_DSD BIT(1) ++ + struct it66121_conf { + unsigned int input_mode_reg; + unsigned int input_conversion_reg; + }; + ++struct it66121_audio { ++ struct platform_device *pdev; ++ unsigned int sources; ++ unsigned int n; ++ unsigned int cts; ++ unsigned int format; ++ unsigned int sample_wl; ++ bool is_hbr; ++ struct hdmi_audio_infoframe audio_infoframe; ++ struct snd_aes_iec958 aes_iec958; ++}; ++ + struct it66121_ctx { + struct regmap *regmap; + struct drm_bridge bridge; +@@ -260,6 +402,8 @@ struct it66121_ctx { + struct regulator_bulk_data supplies[3]; + bool dual_edge; + const struct it66121_conf *conf; ++ bool sink_has_audio; ++ struct it66121_audio audio; + struct mutex lock; /* Protects fields below and device registers */ + struct edid *edid; + struct hdmi_avi_infoframe hdmi_avi_infoframe; +@@ -610,6 +754,7 @@ static int it66121_connector_get_modes(struct drm_connector *connector) + } + + num_modes = drm_add_edid_modes(connector, ctx->edid); ++ ctx->sink_has_audio = drm_detect_monitor_audio(ctx->edid); + + unlock: + mutex_unlock(&ctx->lock); +@@ -894,6 +1039,536 @@ static const struct drm_bridge_funcs it66121_bridge_funcs = { + .mode_set = it66121_bridge_mode_set, + }; + ++/* Audio related functions */ ++ ++static int it66121_audio_reset_fifo(struct it66121_ctx *ctx) ++{ ++ int ret; ++ ++ ret = regmap_write_bits(ctx->regmap, IT66121_SW_RST_REG, ++ IT66121_SW_RST_AUD, ++ IT66121_SW_RST_AUD); ++ if (ret) ++ return ret; ++ ++ usleep_range(2000, 4000); ++ ++ return regmap_write_bits(ctx->regmap, IT66121_SW_RST_REG, ++ IT66121_SW_RST_AUD, ++ ~(IT66121_SW_RST_AUD) & 0xff); ++} ++ ++static int it66121_audio_set_infoframe(struct it66121_ctx *ctx) ++{ ++ int i, ret; ++ u8 infoframe_buf[HDMI_INFOFRAME_SIZE(AUDIO)]; ++ ++ const u16 audioinfo_reg[IT66121_AUD_INFO_REG_SZ] = { ++ IT66121_AUD_INFO_DB1_REG, ++ IT66121_AUD_INFO_DB2_REG, ++ IT66121_AUD_INFO_DB3_REG, ++ IT66121_AUD_INFO_DB4_REG, ++ IT66121_AUD_INFO_DB5_REG ++ }; ++ ++ ret = hdmi_audio_infoframe_pack(&ctx->audio.audio_infoframe, infoframe_buf, ++ sizeof(infoframe_buf)); ++ if (ret < 0) { ++ dev_err(ctx->dev, "%s: failed to pack audio infoframe: %d\n", ++ __func__, ret); ++ return ret; ++ } ++ ++ for (i = 0; i < IT66121_AUD_INFO_REG_SZ; i++) { ++ ret = regmap_write(ctx->regmap, audioinfo_reg[i], ++ infoframe_buf[i + HDMI_INFOFRAME_HEADER_SIZE]); ++ if (ret) ++ return ret; ++ } ++ ++ /* ++ * TODO: linux defines 10 bytes; currently only 5 are filled ++ * if that ever changes checksum will differ since ++ * it66121 takes max 5 bytes -> calc checksum here???? ++ */ ++ ret = regmap_write(ctx->regmap, IT66121_AUD_INFO_CSUM_REG, infoframe_buf[3]); ++ ++ if (ret) ++ return ret; ++ ++ return regmap_write(ctx->regmap, IT66121_AUD_INFO_PKT_REG, ++ IT66121_AUD_INFO_PKT_ON | IT66121_AUD_INFO_PKT_RPT); ++} ++ ++static int it66121_audio_set_cts_n(struct it66121_ctx *ctx) ++{ ++ int ret; ++ ++ ret = regmap_write(ctx->regmap, IT66121_AUD_PKT_N1_REG, ++ ctx->audio.n & 0xff); ++ if (ret) ++ return ret; ++ ret = regmap_write(ctx->regmap, IT66121_AUD_PKT_N2_REG, ++ (ctx->audio.n >> 8) & 0xff); ++ if (ret) ++ return ret; ++ ++ ret = regmap_write(ctx->regmap, IT66121_AUD_PKT_N3_REG, ++ (ctx->audio.n >> 16) & 0xf); ++ if (ret) ++ return ret; ++ ++ ret = regmap_write(ctx->regmap, IT66121_AUD_PKT_CTS1_REG, ++ ctx->audio.cts & 0xff); ++ if (ret) ++ return ret; ++ ++ ret = regmap_write(ctx->regmap, IT66121_AUD_PKT_CTS2_REG, ++ (ctx->audio.cts >> 8) & 0xff); ++ if (ret) ++ return ret; ++ ++ ret = regmap_write(ctx->regmap, IT66121_AUD_PKT_CTS3_REG, ++ (ctx->audio.cts >> 16) & 0xf); ++ if (ret) ++ return ret; ++ ++ /* ++ * magic values ("password") have to be written to ++ * f8 register to enable writing to IT66121_AUD_PKT_CTS_MODE_REG ++ */ ++ ++ ret = regmap_write(ctx->regmap, 0xf8, 0xc3); ++ if (ret) ++ return ret; ++ ++ ret = regmap_write(ctx->regmap, 0xf8, 0xa5); ++ if (ret) ++ return ret; ++ ++ ret = regmap_write_bits(ctx->regmap, ++ IT66121_AUD_PKT_CTS_MODE_REG, ++ IT66121_AUD_PKT_CTS_MODE_USER, ++ ctx->audio.cts == IT66121_AUD_PKT_CTS_MODE_AUTO_VAL ++ ? ~IT66121_AUD_PKT_CTS_MODE_USER & 0xff ++ : IT66121_AUD_PKT_CTS_MODE_USER); ++ if (ret) ++ return ret; ++ ++ /* ++ * disabling write to IT66121_AUD_PKT_CTS_MODE_REG ++ * again by overwriting perviously set "password" ++ */ ++ return regmap_write(ctx->regmap, 0xf8, 0xff); ++} ++ ++static int it66121_audio_set_channel_status(struct it66121_ctx *ctx) ++{ ++ int ret; ++ unsigned int val; ++ ++ /* TODO: check: always use NLPCM - would to cover LPCM also?*/ ++ val = IT66121_AUD_CHST_MODE_NLPCM; ++ val |= ctx->audio.aes_iec958.status[0] & IEC958_AES0_CON_NOT_COPYRIGHT ++ ? BIT(3) ++ : (0 << 3); ++ val |= (ctx->audio.aes_iec958.status[0] & IEC958_AES0_CON_EMPHASIS) << 4; ++ ret = regmap_write(ctx->regmap, ++ IT66121_AUD_CHST_MODE_REG, ++ val); ++ if (ret) ++ return ret; ++ ++ ret = regmap_write(ctx->regmap, ++ IT66121_AUD_CHST_CAT_REG, ++ ctx->audio.aes_iec958.status[1]); ++ if (ret) ++ return ret; ++ ++ ret = regmap_write(ctx->regmap, ++ IT66121_AUD_CHST_SRCNUM_REG, ++ ctx->audio.aes_iec958.status[2] & ++ IEC958_AES2_CON_SOURCE); ++ if (ret) ++ return ret; ++ ++ ret = regmap_write(ctx->regmap, ++ IT66121_AUD_CHST_CHTNUM_REG, ++ ((ctx->audio.aes_iec958.status[2] & ++ IEC958_AES2_CON_CHANNEL) >> 4)); ++ if (ret) ++ return ret; ++ ++ ret = regmap_write(ctx->regmap, ++ IT66121_AUD_CHST_CA_FS_REG, ++ (ctx->audio.aes_iec958.status[3] & ++ IEC958_AES3_CON_CLOCK) << 2 | ++ (ctx->audio.aes_iec958.status[3] & ++ IEC958_AES3_CON_FS)); ++ if (ret) ++ return ret; ++ ++ return regmap_write(ctx->regmap, ++ IT66121_AUD_CHST_OFS_WL_REG, ++ ctx->audio.aes_iec958.status[4]); ++} ++ ++static int it66121_audio_mute(struct it66121_ctx *ctx, bool enable) ++{ ++ return regmap_write_bits(ctx->regmap, IT66121_AUD_CTRL0_REG, ++ IT66121_AUD_EN_I2S_MASK, ++ enable ? 0x0 : ctx->audio.sources); ++} ++ ++static int it66121_audio_set_controls(struct it66121_ctx *ctx) ++{ ++ int ret; ++ ++ ret = regmap_write_bits(ctx->regmap, IT66121_AUD_CTRL0_REG, ++ IT66121_AUD_TYPE_MASK | IT66121_AUD_SWL_MASK, ++ IT66121_AUD_I2S | ctx->audio.sample_wl); ++ ++ if (ret) ++ return ret; ++ ++ ret = regmap_write(ctx->regmap, IT66121_AUD_CTRL1_REG, ++ ctx->audio.format); ++ if (ret) ++ return ret; ++ ++ /* default fifo mapping: fifo0 => source0, fifo1 => source1, ... */ ++ ret = regmap_write(ctx->regmap, IT66121_AUD_FIFOMAP_REG, ++ IT66121_AUD_FIFOMAP_DEFAULT); ++ if (ret) ++ return ret; ++ ++ /* Do not swap R/L for any source */ ++ ret = regmap_write_bits(ctx->regmap, IT66121_AUD_CTRL3_REG, ++ IT66121_AUD_SRLCHG_MASK, ++ IT66121_AUD_SRLCHG_DEFAULT); ++ if (ret) ++ return ret; ++ ++ /* "unflat" all sources */ ++ ret = regmap_write_bits(ctx->regmap, ++ IT66121_AUD_SRC_VALID_FLAT_REG, ++ IT66121_AUD_SPXFLAT_MASK, ++ ~IT66121_AUD_SPXFLAT_SRC_ALL & 0xff); ++ if (ret) ++ return ret; ++ ++ /* TODO: check if we really support HBR audio yet */ ++ return regmap_write_bits(ctx->regmap, IT66121_AUD_HDAUDIO_REG, ++ IT66121_AUD_HBR, ++ ctx->audio.is_hbr ++ ? IT66121_AUD_HBR ++ : ~IT66121_AUD_HBR & 0xff); ++} ++ ++static int it66121_audio_hw_params(struct device *dev, void *data, ++ struct hdmi_codec_daifmt *daifmt, ++ struct hdmi_codec_params *params) ++{ ++ int ret; ++ unsigned int sources = 0; ++ ++ struct it66121_ctx *ctx = dev_get_drvdata(dev); ++ ++ if (!ctx->sink_has_audio) { ++ dev_err(ctx->dev, "%s: sink has no audio", __func__); ++ return -EINVAL; ++ } ++ ++ /* for now i2s only */ ++ if (daifmt->bit_clk_master | daifmt->frame_clk_master) { ++ dev_err(ctx->dev, ++ "%s: only clk_master and frame_clk_master formats are supported\n", ++ __func__); ++ return -EINVAL; ++ } ++ ++ /* TODO: move all these switches in functions ? */ ++ switch (daifmt->fmt) { ++ case HDMI_I2S: ++ ctx->audio.format = IT66121_AUD_FMT_32BIT_I2S; ++ break; ++ case HDMI_RIGHT_J: ++ ctx->audio.format = IT66121_AUD_FMT_RIGHT_JUSTIFY; ++ break; ++ case HDMI_LEFT_J: ++ ctx->audio.format = IT66121_AUD_FMT_LEFT_JUSTIFY; ++ break; ++ default: ++ dev_err(ctx->dev, "%s: unsupported daiformat: %u\n", ++ __func__, daifmt->fmt); ++ return -EINVAL; ++ } ++ ++ switch (params->channels) { ++ case 7 ... 8: ++ ctx->audio.sources |= IT66121_AUD_EN_I2S3; ++ sources++; ++ fallthrough; ++ case 5 ... 6: ++ ctx->audio.sources |= IT66121_AUD_EN_I2S2; ++ sources++; ++ fallthrough; ++ case 3 ... 4: ++ ctx->audio.sources |= IT66121_AUD_EN_I2S1; ++ sources++; ++ fallthrough; ++ case 1 ... 2: ++ ctx->audio.sources |= IT66121_AUD_EN_I2S0; ++ sources++; ++ break; ++ default: ++ dev_err(ctx->dev, "%s: unsupported channel count: %d\n", ++ __func__, params->channels); ++ return -EINVAL; ++ } ++ ++ switch (params->sample_width) { ++ case 16: ++ ctx->audio.sample_wl = IT66121_AUD_SWL_16BIT; ++ break; ++ case 18: ++ ctx->audio.sample_wl = IT66121_AUD_SWL_18BIT; ++ break; ++ case 20: ++ ctx->audio.sample_wl = IT66121_AUD_SWL_20BIT; ++ break; ++ case 24: ++ case 32: ++ /* assume 24 bit wordlength for 32 bit width */ ++ ctx->audio.sample_wl = IT66121_AUD_SWL_24BIT; ++ break; ++ default: ++ dev_err(ctx->dev, "%s: unsupported sample width: %d\n", ++ __func__, params->channels); ++ return -EINVAL; ++ } ++ ++ switch (params->sample_rate) { ++ case 32000: ++ case 48000: ++ case 96000: ++ case 192000: ++ ctx->audio.n = 128 * params->sample_rate / 1000; ++ ctx->audio.is_hbr = false; ++ break; ++ case 44100: ++ case 88200: ++ case 176400: ++ ctx->audio.n = 128 * params->sample_rate / 900; ++ ctx->audio.is_hbr = false; ++ break; ++ case 768000: ++ ctx->audio.n = 24576; ++ ctx->audio.is_hbr = true; ++ break; ++ default: ++ dev_err(ctx->dev, "%s: unsupported sample_rate: %d\n", ++ __func__, params->sample_rate); ++ return -EINVAL; ++ } ++ ++ /* not all bits are correctly filled in snd_aes_iec958 - fill them here */ ++ if ((params->iec.status[2] & IEC958_AES2_CON_SOURCE) == IEC958_AES2_CON_SOURCE_UNSPEC) ++ params->iec.status[2] |= sources; ++ ++ if ((params->iec.status[2] & IEC958_AES2_CON_CHANNEL) == IEC958_AES2_CON_CHANNEL_UNSPEC) ++ params->iec.status[2] |= params->channels << 4; ++ ++ /* OFs is 1-complement of Fs */ ++ if ((params->iec.status[4] & IEC958_AES4_CON_ORIGFS) == IEC958_AES4_CON_ORIGFS_NOTID && ++ (params->iec.status[3] & IEC958_AES3_CON_FS) != IEC958_AES3_CON_FS_NOTID) ++ params->iec.status[4] |= (~(params->iec.status[3] & IEC958_AES3_CON_FS) & 0xf) << 4; ++ ++ ctx->audio.format |= IT66121_AUD_FMT_FULLPKT; ++ ctx->audio.cts = IT66121_AUD_PKT_CTS_MODE_AUTO_VAL; ++ ctx->audio.audio_infoframe = params->cea; ++ ctx->audio.aes_iec958 = params->iec; ++ ++ ret = it66121_audio_reset_fifo(ctx); ++ if (ret) ++ return ret; ++ ++ ret = it66121_audio_set_infoframe(ctx); ++ if (ret) { ++ dev_err(ctx->dev, ++ "%s: failed to assemble/enable audio infoframe: %d\n", ++ __func__, ret); ++ /* TODO: Really fail here? */ ++ return ret; ++ } ++ ++ ret = it66121_audio_set_cts_n(ctx); ++ if (ret) { ++ dev_err(ctx->dev, ++ "%s: failed to write cts/n values: %d\n", ++ __func__, ret); ++ return ret; ++ } ++ ++ ret = it66121_audio_set_channel_status(ctx); ++ if (ret) { ++ dev_err(ctx->dev, ++ "%s: failed to write channel_status %d\n", ++ __func__, ret); ++ return ret; ++ } ++ ++ ret = it66121_audio_set_controls(ctx); ++ if (ret) { ++ dev_err(ctx->dev, ++ "%s: failed to write audio controls %d\n", ++ __func__, ret); ++ return ret; ++ } ++ ++ return ret; ++} ++ ++static void it66121_audio_shutdown(struct device *dev, void *data) ++{ ++ struct it66121_ctx *ctx = dev_get_drvdata(dev); ++ ++ regmap_write_bits(ctx->regmap, IT66121_SW_RST_REG, ++ IT66121_SW_RST_AUD | IT66121_SW_RST_AREF, ++ IT66121_SW_RST_AUD | IT66121_SW_RST_AREF); ++ ++ regmap_write(ctx->regmap, IT66121_AUD_CLK_CTRL_REG, 0x0); ++ ++ regmap_write_bits(ctx->regmap, IT66121_INT_MASK1_REG, ++ IT66121_INT_MASK1_AUD_OVF, ++ IT66121_INT_MASK1_AUD_OVF); ++ ++ regmap_write_bits(ctx->regmap, IT66121_CLK_BANK_REG, ++ IT66121_CLK_BANK_PWROFF_ACLK, ++ IT66121_CLK_BANK_PWROFF_ACLK); ++ ++ regmap_write_bits(ctx->regmap, IT66121_SW_RST_REG, ++ IT66121_SW_RST_AUD | IT66121_SW_RST_AREF, ++ ~(IT66121_SW_RST_AUD | IT66121_SW_RST_AREF) & 0xff); ++} ++ ++static int it66121_audio_startup(struct device *dev, void *data) ++{ ++ int ret; ++ ++ struct it66121_ctx *ctx = dev_get_drvdata(dev); ++ ++ ret = regmap_write_bits(ctx->regmap, IT66121_SW_RST_REG, ++ IT66121_SW_RST_AUD | IT66121_SW_RST_AREF, ++ IT66121_SW_RST_AUD | IT66121_SW_RST_AREF); ++ if (ret) ++ return ret; ++ /* TODO: check how to determine Fs at runtime -> only for spdif???*/ ++ ret = regmap_write(ctx->regmap, IT66121_AUD_CLK_CTRL_REG, ++ IT66121_AUD_AUT_OVR_SMPL_CLK | ++ IT66121_AUD_EXT_MCLK_256FS); ++ if (ret) ++ return ret; ++ ++ ret = regmap_write_bits(ctx->regmap, IT66121_CLK_BANK_REG, ++ IT66121_CLK_BANK_PWROFF_ACLK, ++ ~IT66121_CLK_BANK_PWROFF_ACLK & 0xff); ++ if (ret) ++ return ret; ++ ++ ret = regmap_write_bits(ctx->regmap, IT66121_INT_MASK1_REG, ++ IT66121_INT_MASK1_AUD_OVF, ++ ~IT66121_INT_MASK1_AUD_OVF & 0xff); ++ if (ret) ++ return ret; ++ ++ return regmap_write_bits(ctx->regmap, IT66121_SW_RST_REG, ++ IT66121_SW_RST_AUD | IT66121_SW_RST_AREF, ++ ~(IT66121_SW_RST_AUD | IT66121_SW_RST_AREF) & 0xff); ++} ++ ++int it66121_audio_mute_stream(struct device *dev, void *data, bool enable, ++ int direction) ++{ ++ struct it66121_ctx *ctx = dev_get_drvdata(dev); ++ ++ return it66121_audio_mute(ctx, enable); ++} ++ ++static int it66121_audio_get_dai_id(struct snd_soc_component *component, ++ struct device_node *endpoint) ++{ ++ struct of_endpoint of_ep; ++ int ret; ++ ++ ret = of_graph_parse_endpoint(endpoint, &of_ep); ++ if (ret < 0) ++ return ret; ++ ++ /* ++ * HDMI sound should be located as reg = <2> ++ * Then, it is sound port 0 ++ */ ++ if (of_ep.port == 2) ++ return 0; ++ ++ return -EINVAL; ++} ++ ++static int it66121_audio_get_eld(struct device *dev, void *data, ++ u8 *buf, size_t len) ++{ ++ struct it66121_ctx *ctx = dev_get_drvdata(dev); ++ ++ memcpy(buf, ctx->connector.eld, ++ min(sizeof(ctx->connector.eld), len)); ++ ++ return 0; ++} ++ ++static const struct hdmi_codec_ops it66121_audio_codec_ops = { ++ .audio_shutdown = it66121_audio_shutdown, ++ .audio_startup = it66121_audio_startup, ++ .mute_stream = it66121_audio_mute_stream, ++ .no_capture_mute = 1, ++ .hw_params = it66121_audio_hw_params, ++ .get_eld = it66121_audio_get_eld, ++ .get_dai_id = it66121_audio_get_dai_id, ++}; ++ ++static const struct hdmi_codec_pdata codec_data = { ++ .ops = &it66121_audio_codec_ops, ++ .i2s = 1, /* Only i2s support for now. */ ++ .spdif = 0, ++ .max_i2s_channels = 8, ++}; ++ ++static int it66121_audio_codec_init(struct it66121_ctx *it66121, ++ struct device *dev) ++{ ++ struct it66121_ctx *ctx = dev_get_drvdata(dev); ++ ++ ctx->audio.pdev = platform_device_register_data( ++ dev, HDMI_CODEC_DRV_NAME, PLATFORM_DEVID_AUTO, ++ &codec_data, sizeof(codec_data)); ++ ++ if (IS_ERR(ctx->audio.pdev)) ++ return PTR_ERR(ctx->audio.pdev); ++ ++ DRM_INFO("%s has been bound to to HDMITX it66121\n", ++ HDMI_CODEC_DRV_NAME); ++ ++ return 0; ++} ++ ++static void it66121_audio_codec_exit(struct it66121_ctx *ctx) ++{ ++ if (ctx->audio.pdev) { ++ platform_device_unregister(ctx->audio.pdev); ++ ctx->audio.pdev = NULL; ++ } ++} ++ + static irqreturn_t it66121_irq_threaded_handler(int irq, void *dev_id) + { + int ret; +@@ -930,6 +1605,8 @@ static irqreturn_t it66121_irq_threaded_handler(int irq, void *dev_id) + } + event = true; + } ++ if (val & IT66121_INT_STATUS1_AUD_OVF) ++ it66121_audio_reset_fifo(ctx); + } + + ret = regmap_read(ctx->regmap, IT66121_INT_STATUS3_REG, &val); +@@ -1042,6 +1719,12 @@ static int it66121_probe(struct i2c_client *client, + + drm_bridge_add(&ctx->bridge); + ++ ret = it66121_audio_codec_init(ctx, dev); ++ if (ret) { ++ dev_err(dev, "Failed to initialize audio codec %d\n", ret); ++ return ret; ++ } ++ + return 0; + } + +@@ -1049,6 +1732,7 @@ static int it66121_remove(struct i2c_client *client) + { + struct it66121_ctx *ctx = i2c_get_clientdata(client); + ++ it66121_audio_codec_exit(ctx); + ite66121_power_off(ctx); + drm_bridge_remove(&ctx->bridge); + kfree(ctx->edid); +@@ -1086,6 +1770,7 @@ static struct i2c_driver it66121_driver = { + + module_i2c_driver(it66121_driver); + ++MODULE_AUTHOR("Alex Bee"); + MODULE_AUTHOR("Phong LE"); + MODULE_DESCRIPTION("IT66121 HDMI transmitter driver"); + MODULE_LICENSE("GPL v2"); + +From a6545c717b35bb1e53f8df75093e7582d1b75635 Mon Sep 17 00:00:00 2001 +From: Alex Bee +Date: Tue, 18 Aug 2020 22:46:01 +0200 +Subject: [PATCH] drm/bridge: it66121: increase reset time + +Signed-off-by: Alex Bee +--- + drivers/gpu/drm/bridge/ite-it66121.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/drivers/gpu/drm/bridge/ite-it66121.c b/drivers/gpu/drm/bridge/ite-it66121.c +index 98f3d68fe01f..a01d2e46bb0c 100644 +--- a/drivers/gpu/drm/bridge/ite-it66121.c ++++ b/drivers/gpu/drm/bridge/ite-it66121.c +@@ -443,7 +443,7 @@ static const struct it66121_conf it66121fn_conf_simple = { + static void it66121_hw_reset(struct it66121_ctx *ctx) + { + gpiod_set_value(ctx->gpio_reset, 1); +- msleep(20); ++ msleep(50); + gpiod_set_value(ctx->gpio_reset, 0); + } + diff --git a/patch/kernel/rk322x-current/01-linux-1004-rockchip-v4l-wip.patch b/patch/kernel/rk322x-current/01-linux-1002-v4l-wip.patch similarity index 80% rename from patch/kernel/rk322x-current/01-linux-1004-rockchip-v4l-wip.patch rename to patch/kernel/rk322x-current/01-linux-1002-v4l-wip.patch index 2c4aa8fde..9c3088c73 100644 --- a/patch/kernel/rk322x-current/01-linux-1004-rockchip-v4l-wip.patch +++ b/patch/kernel/rk322x-current/01-linux-1002-v4l-wip.patch @@ -1,4 +1,4 @@ -From 52739ec560f2b0da10b5cbb3d29110753187668d Mon Sep 17 00:00:00 2001 +From 322d662f2a0a2b807da3978eedc234b93dbf53c2 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 @@ -34,7 +34,7 @@ index 1013d1aba59a..f3d788f90fed 100644 rkvdec_job_finish(ctx, VB2_BUF_STATE_ERROR); } -From abcc2dcb7325228fb91f13742c01d141ca53027d Mon Sep 17 00:00:00 2001 +From 819ed8a7ae45790f45ee62a769d7f50092b7d2e4 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 @@ -62,7 +62,7 @@ index f3d788f90fed..e1eec79fe9a2 100644 } -From 98a4ee0b1b176240b42d186af3192321ed429067 Mon Sep 17 00:00:00 2001 +From f2a417e4106f6a07116d74a99194c89cfa8858f1 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 @@ -120,7 +120,7 @@ index c115cd362a7f..d9a2fd9386e2 100644 if (idx >= ARRAY_SIZE(dec_params->dpb)) continue; -From e79774548eb7ecc1727c0234aae3d25bc70fc98a Mon Sep 17 00:00:00 2001 +From 918eabd2461d3394689c85d0b0df3711392eb699 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 @@ -237,7 +237,7 @@ index d9a2fd9386e2..d4f27ef7addd 100644 writel_relaxed(reg, rkvdec->regs + RKVDEC_REG_CUR_POC0); -From f66aee32b4c1257d74020833f2194d42e3d0a8cf Mon Sep 17 00:00:00 2001 +From 7b7488414b5d1c23b39bb9b9de376e28c287661d 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 @@ -253,10 +253,10 @@ Signed-off-by: Jernej Skrabec 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 d29aed416fda..ad21d33c35b8 100644 +index 456488f2b5ca..81529b1d8d69 100644 --- a/Documentation/userspace-api/media/v4l/ext-ctrls-codec.rst +++ b/Documentation/userspace-api/media/v4l/ext-ctrls-codec.rst -@@ -4777,6 +4777,47 @@ enum v4l2_mpeg_video_hevc_size_of_length_field - +@@ -4866,6 +4866,47 @@ enum v4l2_mpeg_video_hevc_size_of_length_field - - ``padding[6]`` - Applications and drivers must set this to zero. @@ -305,10 +305,10 @@ index d29aed416fda..ad21d33c35b8 100644 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 3828bb79225d..a77560204c21 100644 +index d585909bc4e2..f817c643761b 100644 --- a/Documentation/userspace-api/media/v4l/pixfmt-compressed.rst +++ b/Documentation/userspace-api/media/v4l/pixfmt-compressed.rst -@@ -207,6 +207,7 @@ Compressed Formats +@@ -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`` @@ -317,10 +317,10 @@ index 3828bb79225d..a77560204c21 100644 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 3948bee0f5e1..87f16a13c598 100644 +index a88e962ac8a1..4267ba536013 100644 --- a/drivers/media/v4l2-core/v4l2-ctrls.c +++ b/drivers/media/v4l2-core/v4l2-ctrls.c -@@ -995,6 +995,7 @@ const char *v4l2_ctrl_get_name(u32 id) +@@ -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"; @@ -328,7 +328,7 @@ index 3948bee0f5e1..87f16a13c598 100644 case V4L2_CID_MPEG_VIDEO_HEVC_DECODE_MODE: return "HEVC Decode Mode"; case V4L2_CID_MPEG_VIDEO_HEVC_START_CODE: return "HEVC Start Code"; -@@ -1442,6 +1443,9 @@ void v4l2_ctrl_fill(u32 id, const char **name, enum v4l2_ctrl_type *type, +@@ -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; @@ -338,7 +338,7 @@ index 3948bee0f5e1..87f16a13c598 100644 case V4L2_CID_UNIT_CELL_SIZE: *type = V4L2_CTRL_TYPE_AREA; *flags |= V4L2_CTRL_FLAG_READ_ONLY; -@@ -2134,6 +2138,9 @@ static int std_validate_compound(const struct v4l2_ctrl *ctrl, u32 idx, +@@ -2167,6 +2171,9 @@ static int std_validate_compound(const struct v4l2_ctrl *ctrl, u32 idx, zero_padding(*p_hevc_slice_params); break; @@ -348,7 +348,7 @@ index 3948bee0f5e1..87f16a13c598 100644 case V4L2_CTRL_TYPE_AREA: area = p; if (!area->width || !area->height) -@@ -2832,6 +2839,9 @@ static struct v4l2_ctrl *v4l2_ctrl_new(struct v4l2_ctrl_handler *hdl, +@@ -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; @@ -393,7 +393,7 @@ index 1009cf0891cc..1592e52c3614 100644 + #endif -From ec77cb8b66ce6f703dc35e21966dc19e0bb2be65 Mon Sep 17 00:00:00 2001 +From 39fccad1853d319b5d6de0352b6106f5a2f9e7eb 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 @@ -410,10 +410,10 @@ Signed-off-by: Jernej Skrabec 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 ad21d33c35b8..352aee152c58 100644 +index 81529b1d8d69..817773791888 100644 --- a/Documentation/userspace-api/media/v4l/ext-ctrls-codec.rst +++ b/Documentation/userspace-api/media/v4l/ext-ctrls-codec.rst -@@ -4572,6 +4572,9 @@ enum v4l2_mpeg_video_hevc_size_of_length_field - +@@ -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. @@ -423,7 +423,7 @@ index ad21d33c35b8..352aee152c58 100644 * - __u8 - ``nal_unit_type`` - -@@ -4649,7 +4652,7 @@ enum v4l2_mpeg_video_hevc_size_of_length_field - +@@ -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 @@ -456,7 +456,7 @@ index 1592e52c3614..3e2e32098312 100644 /* 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 47bd09e7ebe0b20e61dc2cd7ca3e4d341c464835 Mon Sep 17 00:00:00 2001 +From 393a4406b1b88ebb97b04586f27b0334136aede1 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 @@ -526,7 +526,7 @@ index 3e2e32098312..3cc3b47e1417 100644 /* 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 0b054c01bca7026d690df47e6f4dadf72aef290c Mon Sep 17 00:00:00 2001 +From 6b50e1d090acfd964a80c3821d4cac909b38693c 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 @@ -569,7 +569,7 @@ index 3cc3b47e1417..b33e1a8141e1 100644 /* 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 f882ac311e8d1a4e6dea67f36433c983d35ea538 Mon Sep 17 00:00:00 2001 +From b34391e007c6f8bd42396d954d270457a50ac84c 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 @@ -3237,7 +3237,7 @@ index 5f66f07acac5..d5600c6a4c17 100644 #endif /* RKVDEC_H_ */ -From 9782bedbf0833baae6ca1b4337ba6b5c1ddfada7 Mon Sep 17 00:00:00 2001 +From a9609c4fd9f76a35c3f84e32002a26ff857940f8 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 @@ -3325,7 +3325,7 @@ index 880a70c9291e..5eec0ed710b2 100644 { .mandatory = true, -From c7d4379420bf34c72971b78b4a75ae0a66f57055 Mon Sep 17 00:00:00 2001 +From b0827a52d53f0f561e658eb77ed446738d5e12ea 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 @@ -3526,7 +3526,7 @@ index 219283a06f52..7e35140a4f22 100644 /** -From a15f6763e792feefb3a70538f3ac6aa52ad39152 Mon Sep 17 00:00:00 2001 +From 9d86dd7c5559c7f2e1cf8f7bcab79720aeb09703 Mon Sep 17 00:00:00 2001 From: Randy Li Date: Sun, 6 Jan 2019 01:48:37 +0800 Subject: [PATCH] soc: rockchip: power-domain: export idle request @@ -3627,7 +3627,7 @@ index 000000000000..690db6118636 + +#endif -From 5603fb7ddc0471490e5d6716679117caa9eb1390 Mon Sep 17 00:00:00 2001 +From e34147ff2737bf9ba728c42c7968f10574e127ca Mon Sep 17 00:00:00 2001 From: Alex Bee Date: Wed, 20 May 2020 17:04:47 +0200 Subject: [PATCH] media: rkvdec: implement reset controls @@ -3851,7 +3851,7 @@ index d5600c6a4c17..975fe4b5dd68 100644 struct rkvdec_ctx { -From b8a61079d634dc75731041da6240ef34b6f88af1 Mon Sep 17 00:00:00 2001 +From 6261fb0dde9dfddc3cfed72c8445946993314ff6 Mon Sep 17 00:00:00 2001 From: Alex Bee Date: Tue, 18 Aug 2020 11:38:04 +0200 Subject: [PATCH] WIP: arm64: dts: add resets to vdec for RK3399 @@ -3861,10 +3861,10 @@ Subject: [PATCH] WIP: arm64: dts: add resets to vdec for RK3399 1 file changed, 5 insertions(+) diff --git a/arch/arm64/boot/dts/rockchip/rk3399.dtsi b/arch/arm64/boot/dts/rockchip/rk3399.dtsi -index 8973bf68d652..89429d252b87 100644 +index 3e44bf8eac5c..81b4b8714e3f 100644 --- a/arch/arm64/boot/dts/rockchip/rk3399.dtsi +++ b/arch/arm64/boot/dts/rockchip/rk3399.dtsi -@@ -1281,6 +1281,11 @@ vdec: video-codec@ff660000 { +@@ -1284,6 +1284,11 @@ vdec: video-codec@ff660000 { clock-names = "axi", "ahb", "cabac", "core"; iommus = <&vdec_mmu>; power-domains = <&power RK3399_PD_VDU>; @@ -3877,7 +3877,7 @@ index 8973bf68d652..89429d252b87 100644 vdec_mmu: iommu@ff660480 { -From 853f09fc211b97373ce663b59cb9eef1199a851a Mon Sep 17 00:00:00 2001 +From c2a32797230aece341856e09b0139cf3d259e07b Mon Sep 17 00:00:00 2001 From: Alex Bee Date: Fri, 24 Apr 2020 12:36:13 +0200 Subject: [PATCH] media: hantro: add Rockchip RK3228 @@ -3903,7 +3903,7 @@ index c81dbc3e8960..ddbda080950e 100644 - rockchip,rk3328-vpu - rockchip,rk3399-vpu -From 60bd8c1e3ef18e25d15bb484eba13b8b44d02384 Mon Sep 17 00:00:00 2001 +From 86ac3c31aadac54e5c4a941ae25147b8e1045676 Mon Sep 17 00:00:00 2001 From: Alex Bee Date: Fri, 24 Apr 2020 12:38:24 +0200 Subject: [PATCH] ARM: dts: rockchip: add vpu node for RK322x @@ -3949,7 +3949,7 @@ index f98a945c68d3..b233baeb20ef 100644 vdec_mmu: iommu@20030480 { -From d3d7be9f48a07afb8e6429524851cad087d71976 Mon Sep 17 00:00:00 2001 +From 2542e122786d27dfcf4bf2a60b2d91a4ae3a48dd Mon Sep 17 00:00:00 2001 From: Alex Bee Date: Tue, 26 May 2020 14:11:57 +0200 Subject: [PATCH] media: hantro: add support for RK3188 @@ -4195,7 +4195,7 @@ index 7b299ee3e93d..1ac00695a864 100644 .enc_offset = 0x0, .enc_fmts = rk3288_vpu_enc_fmts, -From e59060a8da2f3b18292bede54f9bff191831bf63 Mon Sep 17 00:00:00 2001 +From d99de1ed4674749d5c52b0acd9e22e04a08cf28b Mon Sep 17 00:00:00 2001 From: Alex Bee Date: Tue, 26 May 2020 14:12:35 +0200 Subject: [PATCH] ARM: dts: rockchip: add vpu node for RK3188 @@ -4206,7 +4206,7 @@ Add VPU node to RK3188s dtsi. 1 file changed, 13 insertions(+) diff --git a/arch/arm/boot/dts/rk3188.dtsi b/arch/arm/boot/dts/rk3188.dtsi -index e2edea308556..b9128109cf72 100644 +index 79742ea997eb..74bb2525715c 100644 --- a/arch/arm/boot/dts/rk3188.dtsi +++ b/arch/arm/boot/dts/rk3188.dtsi @@ -141,6 +141,19 @@ smp-sram@0 { @@ -4230,7 +4230,7 @@ index e2edea308556..b9128109cf72 100644 compatible = "rockchip,rk3188-vop"; reg = <0x1010c000 0x1000>; -From 99b46ed456e8aa98a68996eb17ce028619f709f0 Mon Sep 17 00:00:00 2001 +From 0c4979901a6b29b3033b0c961d33cb8be9f7d46b Mon Sep 17 00:00:00 2001 From: Alex Bee Date: Tue, 26 May 2020 17:24:12 +0200 Subject: [PATCH] media: hantro: add support for Rockchip RK3036 @@ -4323,7 +4323,7 @@ index 1ac00695a864..b5887fdae250 100644 .enc_offset = 0x0, .enc_fmts = rk3288_vpu_enc_fmts, -From 966bf162f18826fc83779148a9b2cca5c578988f Mon Sep 17 00:00:00 2001 +From 3d1b0b0c9d0188fa39b42e24bf973bb051c032b1 Mon Sep 17 00:00:00 2001 From: Alex Bee Date: Tue, 26 May 2020 17:42:55 +0200 Subject: [PATCH] ARM: dts: rockchip: add vpu node for RK3036 @@ -4331,35 +4331,14 @@ Subject: [PATCH] ARM: dts: rockchip: add vpu node for RK3036 This adds VPU node to RK3036. While at it also add the required mmu, power-domain controller and qos node to make the VPU work on this SoC. --- - .../bindings/media/rockchip-vpu.yaml | 1 + - arch/arm/boot/dts/rk3036.dtsi | 44 +++++++++++++++++++ - 2 files changed, 45 insertions(+) + arch/arm/boot/dts/rk3036.dtsi | 23 +++++++++++++++++++++++ + 1 file changed, 23 insertions(+) -diff --git a/Documentation/devicetree/bindings/media/rockchip-vpu.yaml b/Documentation/devicetree/bindings/media/rockchip-vpu.yaml -index 1f0b3685fa85..24aa60a6226d 100644 ---- a/Documentation/devicetree/bindings/media/rockchip-vpu.yaml -+++ b/Documentation/devicetree/bindings/media/rockchip-vpu.yaml -@@ -16,6 +16,7 @@ description: - properties: - compatible: - enum: -+ - rockchip,rk3036-vpu - - rockchip,rk3188-vpu - - rockchip,rk3228-vpu - - rockchip,rk3288-vpu diff --git a/arch/arm/boot/dts/rk3036.dtsi b/arch/arm/boot/dts/rk3036.dtsi -index 4ffe72ab5f63..6700a17a6446 100644 +index a86e1dc7fb5b..ef8ceed78f73 100644 --- a/arch/arm/boot/dts/rk3036.dtsi +++ b/arch/arm/boot/dts/rk3036.dtsi -@@ -6,6 +6,7 @@ - #include - #include - #include -+#include - - / { - #address-cells = <1>; -@@ -134,6 +135,29 @@ gpu: gpu@10090000 { +@@ -136,6 +136,29 @@ gpu: gpu@10090000 { status = "disabled"; }; @@ -4389,64 +4368,31 @@ index 4ffe72ab5f63..6700a17a6446 100644 vop: vop@10118000 { compatible = "rockchip,rk3036-vop"; reg = <0x10118000 0x19c>; -@@ -166,6 +190,11 @@ vop_mmu: iommu@10118300 { - status = "disabled"; - }; - -+ qos_vpu: qos@1012e000 { -+ compatible = "syscon"; -+ reg = <0x1012e000 0x20>; -+ }; -+ - gic: interrupt-controller@10139000 { - compatible = "arm,gic-400"; - interrupt-controller; -@@ -329,6 +358,21 @@ reboot-mode { - mode-bootloader = ; - mode-loader = ; - }; -+ -+ power: power-controller { -+ compatible = "rockchip,rk3036-power-controller"; -+ #power-domain-cells = <1>; -+ #address-cells = <1>; -+ #size-cells = <0>; -+ -+ pd_vpu@RK3036_PD_VPU { -+ reg = ; -+ clocks = <&cru ACLK_VCODEC>, -+ <&cru HCLK_VCODEC>; -+ pm_qos = <&qos_vpu>; -+ }; -+ -+ }; - }; - - acodec: acodec-ana@20030000 { -From 10d7d4b4c5b6d6a6317d8cdeeca00a465cb9092c Mon Sep 17 00:00:00 2001 +From 996f741a44faecc4b9485ee0b8258b3e3441474e Mon Sep 17 00:00:00 2001 From: Alex Bee Date: Tue, 26 May 2020 17:54:22 +0200 Subject: [PATCH] media: hantro: adapt Kconfig help text -Since help text line would get very long if all supported SoCs are mentioned -I shortend it to "Rockchip SoCs" +Add RK3036, RK3066, RK3188 and RK322x to Kconfig help +text --- - drivers/staging/media/hantro/Kconfig | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) + drivers/staging/media/hantro/Kconfig | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/drivers/staging/media/hantro/Kconfig b/drivers/staging/media/hantro/Kconfig -index 5b6cf9f62b1a..d33f1ddbc9c9 100644 +index 5b6cf9f62b1a..ef8bd5067be8 100644 --- a/drivers/staging/media/hantro/Kconfig +++ b/drivers/staging/media/hantro/Kconfig -@@ -30,4 +30,4 @@ config VIDEO_HANTRO_ROCKCHIP +@@ -30,4 +30,5 @@ config VIDEO_HANTRO_ROCKCHIP depends on ARCH_ROCKCHIP || COMPILE_TEST default y help - Enable support for RK3288, RK3328, and RK3399 SoCs. -+ Enable support for Rockchip SoCs. ++ Enable support for RK3036, RK3066, RK3188, RK322x ++ RK3288, RK3328 and RK3399 SoCs. -From 2a2d8ee9133194cf6251ee7b50033b2382a45daa Mon Sep 17 00:00:00 2001 +From 839059f221d04ef0a6c7e03bcade1e50148d06cd Mon Sep 17 00:00:00 2001 From: Alex Bee Date: Sat, 23 May 2020 14:22:54 +0200 Subject: [PATCH] ARM: dts: rockchip: add vdec node for RK322x @@ -4504,10 +4450,72 @@ index b233baeb20ef..de5727e0bc94 100644 vop: vop@20050000 { -From b58b02c888f17ef8315549c498b9833b05315106 Mon Sep 17 00:00:00 2001 +From 7123c3d575df39ea102be56374fbc82a02d59ff2 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 +--- + arch/arm64/boot/dts/rockchip/rk3328.dtsi | 26 +++++++++++++++++++++++- + 1 file changed, 25 insertions(+), 1 deletion(-) + +diff --git a/arch/arm64/boot/dts/rockchip/rk3328.dtsi b/arch/arm64/boot/dts/rockchip/rk3328.dtsi +index abe7f1573825..9a7a5c1adaa8 100644 +--- a/arch/arm64/boot/dts/rockchip/rk3328.dtsi ++++ b/arch/arm64/boot/dts/rockchip/rk3328.dtsi +@@ -327,6 +327,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 = ; +@@ -672,6 +676,26 @@ vpu_mmu: iommu@ff350800 { + power-domains = <&power RK3328_PD_VPU>; + }; + ++ rkvdec: video-codec@ff360000 { ++ compatible = "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>; ++ resets = <&cru SRST_VDEC_H>, <&cru SRST_VDEC_A>, ++ <&cru SRST_VDEC_CORE>, <&cru SRST_VDEC_CABAC>, ++ <&cru SRST_VDEC_NIU_A>, <&cru SRST_VDEC_NIU_H>; ++ reset-names = "video_h", "video_a", ++ "video_core", "video_cabac", ++ "niu_a", "niu_h"; ++ } ++ + rkvdec_mmu: iommu@ff360480 { + compatible = "rockchip,iommu"; + reg = <0x0 0xff360480 0x0 0x40>, <0x0 0xff3604c0 0x0 0x40>; +@@ -680,7 +704,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 e6885f7f00a88d6b7c7938b77874e466e48ba9d9 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.10 uapi changes +Subject: [PATCH] media: hantro: adapt to match 5.11 H.264 uapi changes Signed-off-by: Alex Bee --- @@ -4532,10 +4540,10 @@ index bc2af450a94c..7bdefcc2fc77 100644 if (dpb[i / 2].flags & V4L2_H264_DPB_ENTRY_FLAG_LONG_TERM) -From ecbe4dd54f235973dc484bd91d75ea59a92bef2c Mon Sep 17 00:00:00 2001 +From 133d19f65874d3a3c7302ea7e2c1423e4b574545 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.10 uapi changes +Subject: [PATCH] media: rkvdec: adapt to match 5.11 H.264 uapi changes Signed-off-by: Alex Bee --- @@ -4577,3 +4585,2022 @@ index d4f27ef7addd..627cd4efabef 100644 (dpb[idx].flags & flags) == long_term) { set_ps_field(hw_rps, DPB_INFO(i, j), idx | (1 << 4)); + +From 44db6f132cfe12d3042e521d55d01e71b3b68f92 Mon Sep 17 00:00:00 2001 +From: Alex Bee +Date: Thu, 23 Jul 2020 17:25:12 +0200 +Subject: [PATCH] ARM: dts: add vpu node for RK3066 + +Signed-off-by: Alex Bee +--- + arch/arm/boot/dts/rk3066a.dtsi | 13 +++++++++++++ + 1 file changed, 13 insertions(+) + +diff --git a/arch/arm/boot/dts/rk3066a.dtsi b/arch/arm/boot/dts/rk3066a.dtsi +index f71529e6949f..d9984d0f8f23 100644 +--- a/arch/arm/boot/dts/rk3066a.dtsi ++++ b/arch/arm/boot/dts/rk3066a.dtsi +@@ -194,6 +194,19 @@ smp-sram@0 { + }; + }; + ++ vpu: video-codec@10104000 { ++ compatible = "rockchip,rk3188-vpu"; ++ reg = <0x10104000 0x800>; ++ interrupts = , ++ ; ++ interrupt-names = "vepu", "vdpu"; ++ clocks = <&cru ACLK_VDPU>, <&cru HCLK_VDPU>, ++ <&cru ACLK_VEPU>, <&cru HCLK_VEPU>; ++ clock-names = "aclk_vdpu", "hclk_vdpu", ++ "aclk_vepu", "hclk_vepu"; ++ power-domains = <&power RK3066_PD_VIDEO>; ++ }; ++ + vop0: vop@1010c000 { + compatible = "rockchip,rk3066-vop"; + reg = <0x1010c000 0x19c>; + +From 4b90b0c9d234efda1e91a2a4ffb8fd01882225ea Mon Sep 17 00:00:00 2001 +From: Alex Bee +Date: Sun, 11 Oct 2020 17:03:12 +0200 +Subject: [PATCH] dt-bindings: media: Add Rockchip IEP binding + +* Add some meaningful message here * + +Signed-off-by: Alex Bee +--- + .../bindings/media/rockchip-iep.yaml | 88 +++++++++++++++++++ + 1 file changed, 88 insertions(+) + create mode 100644 Documentation/devicetree/bindings/media/rockchip-iep.yaml + +diff --git a/Documentation/devicetree/bindings/media/rockchip-iep.yaml b/Documentation/devicetree/bindings/media/rockchip-iep.yaml +new file mode 100644 +index 000000000000..0be78de932db +--- /dev/null ++++ b/Documentation/devicetree/bindings/media/rockchip-iep.yaml +@@ -0,0 +1,88 @@ ++# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause) ++%YAML 1.2 ++--- ++$id: http://devicetree.org/schemas/media/rockchip-iep.yaml# ++$schema: http://devicetree.org/meta-schemas/core.yaml# ++ ++title: Rockchip Image Enhancement Processor (IEP) ++ ++description: ++ Rockchip IEP supports various image enhancement operations for YUV and RGB domains. ++ Deinterlacing, spatial and temporal sampling noise reduction are supported by the ++ YUV block. Gamma adjustment, edge enhancement, detail enhancement are supported in ++ the RGB block. Brightness, Saturation, Contrast, Hue adjustment is supported for ++ both domains. Furthermore it supports converting RGB to YUV / YUV to RGB. ++ ++maintainers: ++ - Heiko Stuebner ++ ++properties: ++ compatible: ++ oneOf: ++ - const: rockchip,rk3228-iep ++ - items: ++ - enum: ++ - rockchip,rk3288-iep ++ - rockchip,rk3328-iep ++ - rockchip,rk3368-iep ++ - rockchip,rk3399-iep ++ - const: rockchip,rk3228-iep ++ ++ reg: ++ maxItems: 1 ++ ++ interrupts: ++ maxItems: 1 ++ ++ clocks: ++ maxItems: 2 ++ ++ clock-names: ++ items: ++ - const: axi ++ - const: ahb ++ ++ power-domains: ++ maxItems: 1 ++ ++ iommus: ++ maxItems: 1 ++ ++ resets: ++ maxItems: 2 ++ ++ reset-names: ++ items: ++ - const: axi ++ - const: ahb ++ ++required: ++ - compatible ++ - reg ++ - interrupts ++ - clocks ++ - clock-names ++ - resets ++ - reset-names ++ ++additionalProperties: false ++ ++examples: ++ - | ++ #include ++ #include ++ #include ++ iep: iep@20070000 { ++ compatible = "rockchip,rk3228-iep"; ++ reg = <0x20070000 0x800>; ++ interrupts = ; ++ interrupt-names = "iep"; ++ clocks = <&cru ACLK_IEP>, ++ <&cru HCLK_IEP>; ++ clock-names = "axi", "ahb"; ++ resets = <&cru SRST_IEP_A>, ++ <&cru SRST_IEP_H>; ++ reset-names = "axi", "ahb"; ++ power-domains = <&power RK3228_PD_VIO>; ++ iommus = <&iep_mmu>; ++ }; + +From 76673c3abd13bcdb53915d9c0e909d287a13b41d Mon Sep 17 00:00:00 2001 +From: Alex Bee +Date: Sun, 11 Oct 2020 21:24:10 +0200 +Subject: [PATCH] media: rockchip: Add Rockchip IEP driver + +* Add some meaningful message here * + +Signed-off-by: Alex Bee +--- + drivers/media/platform/Kconfig | 14 + + drivers/media/platform/Makefile | 1 + + drivers/media/platform/rockchip/iep/Makefile | 5 + + .../media/platform/rockchip/iep/iep-regs.h | 291 +++++ + drivers/media/platform/rockchip/iep/iep.c | 1121 +++++++++++++++++ + drivers/media/platform/rockchip/iep/iep.h | 114 ++ + 6 files changed, 1546 insertions(+) + create mode 100644 drivers/media/platform/rockchip/iep/Makefile + create mode 100644 drivers/media/platform/rockchip/iep/iep-regs.h + create mode 100644 drivers/media/platform/rockchip/iep/iep.c + create mode 100644 drivers/media/platform/rockchip/iep/iep.h + +diff --git a/drivers/media/platform/Kconfig b/drivers/media/platform/Kconfig +index 7e152bbb4fa6..eee78b20c791 100644 +--- a/drivers/media/platform/Kconfig ++++ b/drivers/media/platform/Kconfig +@@ -462,6 +462,20 @@ config VIDEO_RENESAS_VSP1 + To compile this driver as a module, choose M here: the module + will be called vsp1. + ++config VIDEO_ROCKCHIP_IEP ++ tristate "Rockchip Image Enhancement Processor" ++ depends on VIDEO_DEV && VIDEO_V4L2 ++ depends on ARCH_ROCKCHIP || COMPILE_TEST ++ select VIDEOBUF2_DMA_CONTIG ++ select V4L2_MEM2MEM_DEV ++ help ++ This is a v4l2 driver for Rockchip Image Enhancement Processor (IEP) ++ found in most Rockchip RK3xxx SoCs. ++ Rockchip IEP supports various enhancement operations for RGB and YUV ++ images. The driver currently implements YUV deinterlacing only. ++ To compile this driver as a module, choose M here: the module ++ will be called rockchip-iep ++ + config VIDEO_ROCKCHIP_RGA + tristate "Rockchip Raster 2d Graphic Acceleration Unit" + depends on VIDEO_DEV && VIDEO_V4L2 +diff --git a/drivers/media/platform/Makefile b/drivers/media/platform/Makefile +index 62b6cdc8c730..f99a873818d5 100644 +--- a/drivers/media/platform/Makefile ++++ b/drivers/media/platform/Makefile +@@ -52,6 +52,7 @@ obj-$(CONFIG_VIDEO_RENESAS_FDP1) += rcar_fdp1.o + obj-$(CONFIG_VIDEO_RENESAS_JPU) += rcar_jpu.o + obj-$(CONFIG_VIDEO_RENESAS_VSP1) += vsp1/ + ++obj-$(CONFIG_VIDEO_ROCKCHIP_IEP) += rockchip/iep/ + obj-$(CONFIG_VIDEO_ROCKCHIP_RGA) += rockchip/rga/ + + obj-y += omap/ +diff --git a/drivers/media/platform/rockchip/iep/Makefile b/drivers/media/platform/rockchip/iep/Makefile +new file mode 100644 +index 000000000000..5c89b3277469 +--- /dev/null ++++ b/drivers/media/platform/rockchip/iep/Makefile +@@ -0,0 +1,5 @@ ++# SPDX-License-Identifier: GPL-2.0-only ++ ++rockchip-iep-objs := iep.o ++ ++obj-$(CONFIG_VIDEO_ROCKCHIP_IEP) += rockchip-iep.o +diff --git a/drivers/media/platform/rockchip/iep/iep-regs.h b/drivers/media/platform/rockchip/iep/iep-regs.h +new file mode 100644 +index 000000000000..a68685ef3604 +--- /dev/null ++++ b/drivers/media/platform/rockchip/iep/iep-regs.h +@@ -0,0 +1,291 @@ ++/* SPDX-License-Identifier: GPL-2.0-only */ ++/* ++ * Rockchip Image Enhancement Processor (IEP) driver ++ * ++ * Copyright (C) 2020 Alex Bee ++ * ++ */ ++ ++#ifndef __IEP_REGS_H__ ++#define __IEP_REGS_H__ ++ ++/* IEP Registers addresses */ ++#define IEP_CONFIG0 0x000 /* Configuration register0 */ ++#define IEP_VOP_DIRECT_PATH BIT(0) ++#define IEP_DEIN_HIGH_FREQ_SHFT 1 ++#define IEP_DEIN_HIGH_FREQ_MASK (0x7f << IEP_DEIN_HIGH_FREQ_SHFT) ++#define IEP_DEIN_MODE_SHFT 8 ++#define IEP_DEIN_MODE_MASK (7 << IEP_DEIN_MODE_SHFT) ++#define IEP_DEIN_HIGH_FREQ_EN BIT(11) ++#define IEP_DEIN_EDGE_INTPOL_EN BIT(12) ++#define IEP_YUV_DENOISE_EN BIT(13) ++#define IEP_YUV_ENHNC_EN BIT(14) ++#define IEP_DEIN_EDGE_INTPOL_SMTH_EN BIT(15) ++#define IEP_RGB_CLR_ENHNC_EN BIT(16) ++#define IEP_RGB_CNTRST_ENHNC_EN BIT(17) ++#define IEP_RGB_ENHNC_MODE_BYPASS (0 << 18) ++#define IEP_RGB_ENHNC_MODE_DNS BIT(18) ++#define IEP_RGB_ENHNC_MODE_DTL (2 << 18) ++#define IEP_RGB_ENHNC_MODE_EDG (3 << 18) ++#define IEP_RGB_ENHNC_MODE_MASK (3 << 18) ++#define IEP_RGB_CNTRST_ENHNC_DDE_FRST BIT(20) ++#define IEP_DEIN_EDGE_INTPOL_RADIUS_SHFT 21 ++#define IEP_DEIN_EDGE_INTPOL_RADIUS_MASK (3 << IEP_DEIN_EDGE_INTPOL_RADIUS_SHFT) ++#define IEP_DEIN_EDGE_INTPOL_SELECT BIT(23) ++ ++#define IEP_CONFIG1 0x004 /* Configuration register1 */ ++#define IEP_SRC_FMT_SHFT 0 ++#define IEP_SRC_FMT_MASK (3 << IEP_SRC_FMT_SHFT) ++#define IEP_SRC_RGB_SWP_SHFT 2 ++#define IEP_SRC_RGB_SWP_MASK (2 << IEP_SRC_RGB_SWP_SHFT) ++#define IEP_SRC_YUV_SWP_SHFT 4 ++#define IEP_SRC_YUV_SWP_MASK (3 << IEP_SRC_YUV_SWP_SHFT) ++#define IEP_DST_FMT_SHFT 8 ++#define IEP_DST_FMT_MASK (3 << IEP_DST_FMT_SHFT) ++#define IEP_DST_RGB_SWP_SHFT 10 ++#define IEP_DST_RGB_SWP_MASK (2 << IEP_DST_RGB_SWP_SHFT) ++#define IEP_DST_YUV_SWP_SHFT 12 ++#define IEP_DST_YUV_SWP_MASK (3 << IEP_DST_YUV_SWP_SHFT) ++#define IEP_DTH_UP_EN BIT(14) ++#define IEP_DTH_DWN_EN BIT(15) ++#define IEP_YUV2RGB_COE_BT601_1 (0 << 16) ++#define IEP_YUV2RGB_COE_BT601_F BIT(16) ++#define IEP_YUV2RGB_COE_BT709_1 (2 << 16) ++#define IEP_YUV2RGB_COE_BT709_F (3 << 16) ++#define IEP_YUV2RGB_COE_MASK (3 << 16) ++#define IEP_RGB2YUV_COE_BT601_1 (0 << 18) ++#define IEP_RGB2YUV_COE_BT601_F BIT(18) ++#define IEP_RGB2YUV_COE_BT709_1 (2 << 18) ++#define IEP_RGB2YUV_COE_BT709_F (3 << 18) ++#define IEP_RGB2YUV_COE_MASK (3 << 18) ++#define IEP_YUV2RGB_EN BIT(20) ++#define IEP_RGB2YUV_EN BIT(21) ++#define IEP_YUV2RGB_CLIP_EN BIT(22) ++#define IEP_RGB2YUV_CLIP_EN BIT(23) ++#define IEP_GLB_ALPHA_SHFT 24 ++#define IEP_GLB_ALPHA_MASK (0x7f << IEP_GLB_ALPHA_SHFT) ++ ++#define IEP_STATUS 0x008 /* Status register */ ++#define IEP_STATUS_YUV_DNS BIT(0) ++#define IEP_STATUS_SCL BIT(1) ++#define IEP_STATUS_DIL BIT(2) ++#define IEP_STATUS_DDE BIT(3) ++#define IEP_STATUS_DMA_WR_YUV BIT(4) ++#define IEP_STATUS_DMA_RE_YUV BIT(5) ++#define IEP_STATUS_DMA_WR_RGB BIT(6) ++#define IEP_STATUS_DMA_RE_RGB BIT(7) ++#define IEP_STATUS_VOP_DIRECT_PATH BIT(8) ++#define IEP_STATUS_DMA_IA_WR_YUV BIT(16) ++#define IEP_STATUS_DMA_IA_RE_YUV BIT(17) ++#define IEP_STATUS_DMA_IA_WR_RGB BIT(18) ++#define IEP_STATUS_DMA_IA_RE_RGB BIT(19) ++ ++#define IEP_INT 0x00c /* Interrupt register*/ ++#define IEP_INT_FRAME_DONE BIT(0) /* Frame process done interrupt */ ++#define IEP_INT_FRAME_DONE_EN BIT(8) /* Frame process done interrupt enable */ ++#define IEP_INT_FRAME_DONE_CLR BIT(16) /* Frame process done interrupt clear */ ++ ++#define IEP_FRM_START 0x010 /* Frame start */ ++#define IEP_SRST 0x014 /* Soft reset */ ++#define IEP_CONFIG_DONE 0x018 /* Configuration done */ ++#define IEP_FRM_CNT 0x01c /* Frame counter */ ++ ++#define IEP_VIR_IMG_WIDTH 0x020 /* Image virtual width */ ++#define IEP_IMG_SCL_FCT 0x024 /* Scaling factor */ ++#define IEP_SRC_IMG_SIZE 0x028 /* src image width/height */ ++#define IEP_DST_IMG_SIZE 0x02c /* dst image width/height */ ++#define IEP_DST_IMG_WIDTH_TILE0 0x030 /* dst image tile0 width */ ++#define IEP_DST_IMG_WIDTH_TILE1 0x034 /* dst image tile1 width */ ++#define IEP_DST_IMG_WIDTH_TILE2 0x038 /* dst image tile2 width */ ++#define IEP_DST_IMG_WIDTH_TILE3 0x03c /* dst image tile3 width */ ++ ++#define IEP_ENH_YUV_CNFG_0 0x040 /* Brightness, contrast, saturation adjustment */ ++#define IEP_YUV_BRIGHTNESS_SHFT 0 ++#define IEP_YUV_BRIGHTNESS_MASK (0x3f << IEP_YUV_BRIGHTNESS_SHFT) ++#define IEP_YUV_CONTRAST_SHFT 8 ++#define IEP_YUV_CONTRAST_MASK (0xff << IEP_YUV_CONTRAST_SHFT) ++#define IEP_YUV_SATURATION_SHFT 16 ++#define IEP_YUV_SATURATION_MASK (0x1ff << IEP_YUV_SATURATION_SHFT) ++ ++#define IEP_ENH_YUV_CNFG_1 0x044 /* Hue configuration */ ++#define IEP_YUV_COS_HUE_SHFT 0 ++#define IEP_YUV_COS_HUE_MASK (0xff << IEP_YUV_COS_HUE_SHFT) ++#define IEP_YUV_SIN_HUE_SHFT 8 ++#define IEP_YUV_SIN_HUE_MASK (0xff << IEP_YUV_SIN_HUE_SHFT) ++ ++#define IEP_ENH_YUV_CNFG_2 0x048 /* Color bar configuration */ ++#define IEP_YUV_COLOR_BAR_Y_SHFT 0 ++#define IEP_YUV_COLOR_BAR_Y_MASK (0xff << IEP_YUV_COLOR_BAR_Y_SHFT) ++#define IEP_YUV_COLOR_BAR_U_SHFT 8 ++#define IEP_YUV_COLOR_BAR_U_MASK (0xff << IEP_YUV_COLOR_BAR_U_SHFT) ++#define IEP_YUV_COLOR_BAR_V_SHFT 16 ++#define IEP_YUV_COLOR_BAR_V_MASK (0xff << IEP_YUV_COLOR_BAR_V_SHFT) ++#define IEP_YUV_VIDEO_MODE_SHFT 24 ++#define IEP_YUV_VIDEO_MODE_MASK (3 << IEP_YUV_VIDEO_MODE_SHFT) ++ ++#define IEP_ENH_RGB_CNFG 0x04c /* RGB enhancement configuration */ ++#define IEP_ENH_RGB_C_COE 0x050 /* RGB color enhancement coefficient */ ++ ++#define IEP_RAW_CONFIG0 0x058 /* Raw configuration register0 */ ++#define IEP_RAW_CONFIG1 0x05c /* Raw configuration register1 */ ++#define IEP_RAW_VIR_IMG_WIDTH 0x060 /* Raw image virtual width */ ++#define IEP_RAW_IMG_SCL_FCT 0x064 /* Raw scaling factor */ ++#define IEP_RAW_SRC_IMG_SIZE 0x068 /* Raw src image width/height */ ++#define IEP_RAW_DST_IMG_SIZE 0x06c /* Raw src image width/height */ ++#define IEP_RAW_ENH_YUV_CNFG_0 0x070 /* Raw brightness,contrast,saturation adjustment */ ++#define IEP_RAW_ENH_YUV_CNFG_1 0x074 /* Raw hue configuration */ ++#define IEP_RAW_ENH_YUV_CNFG_2 0x078 /* Raw color bar configuration */ ++#define IEP_RAW_ENH_RGB_CNFG 0x07c /* Raw RGB enhancement configuration */ ++ ++#define IEP_SRC_ADDR_Y_RGB 0x080 /* Start addr. of src image 0 (Y/RGB) */ ++#define IEP_SRC_ADDR_CBCR 0x084 /* Start addr. of src image 0 (Cb/Cr) */ ++#define IEP_SRC_ADDR_CR 0x088 /* Start addr. of src image 0 (Cr) */ ++#define IEP_SRC_ADDR_Y1 0x08c /* Start addr. of src image 1 (Y) */ ++#define IEP_SRC_ADDR_CBCR1 0x090 /* Start addr. of src image 1 (Cb/Cr) */ ++#define IEP_SRC_ADDR_CR1 0x094 /* Start addr. of src image 1 (Cr) */ ++#define IEP_SRC_ADDR_Y_ITEMP 0x098 /* Start addr. of src image(Y int part) */ ++#define IEP_SRC_ADDR_CBCR_ITEMP 0x09c /* Start addr. of src image(CBCR int part) */ ++#define IEP_SRC_ADDR_CR_ITEMP 0x0a0 /* Start addr. of src image(CR int part) */ ++#define IEP_SRC_ADDR_Y_FTEMP 0x0a4 /* Start addr. of src image(Y frac part) */ ++#define IEP_SRC_ADDR_CBCR_FTEMP 0x0a8 /* Start addr. of src image(CBCR frac part) */ ++#define IEP_SRC_ADDR_CR_FTEMP 0x0ac /* Start addr. of src image(CR frac part) */ ++ ++#define IEP_DST_ADDR_Y_RGB 0x0b0 /* Start addr. of dst image 0 (Y/RGB) */ ++#define IEP_DST_ADDR_CBCR 0x0b4 /* Start addr. of dst image 0 (Cb/Cr) */ ++#define IEP_DST_ADDR_CR 0x0b8 /* Start addr. of dst image 0 (Cr) */ ++#define IEP_DST_ADDR_Y1 0x0bc /* Start addr. of dst image 1 (Y) */ ++#define IEP_DST_ADDR_CBCR1 0x0c0 /* Start addr. of dst image 1 (Cb/Cr) */ ++#define IEP_DST_ADDR_CR1 0x0c4 /* Start addr. of dst image 1 (Cr) */ ++#define IEP_DST_ADDR_Y_ITEMP 0x0c8 /* Start addr. of dst image(Y int part) */ ++#define IEP_DST_ADDR_CBCR_ITEMP 0x0cc /* Start addr. of dst image(CBCR int part)*/ ++#define IEP_DST_ADDR_CR_ITEMP 0x0d0 /* Start addr. of dst image(CR int part) */ ++#define IEP_DST_ADDR_Y_FTEMP 0x0d4 /* Start addr. of dst image(Y frac part) */ ++#define IEP_DST_ADDR_CBCR_FTEMP 0x0d8 /* Start addr. of dst image(CBCR frac part) */ ++#define IEP_DST_ADDR_CR_FTEMP 0x0dc /* Start addr. of dst image(CR frac part)*/ ++ ++#define IEP_DEIN_MTN_TAB0 0x0e0 /* Deinterlace motion table0 */ ++#define IEP_DEIN_MTN_TAB1 0x0e4 /* Deinterlace motion table1 */ ++#define IEP_DEIN_MTN_TAB2 0x0e8 /* Deinterlace motion table2 */ ++#define IEP_DEIN_MTN_TAB3 0x0ec /* Deinterlace motion table3 */ ++#define IEP_DEIN_MTN_TAB4 0x0f0 /* Deinterlace motion table4 */ ++#define IEP_DEIN_MTN_TAB5 0x0f4 /* Deinterlace motion table5 */ ++#define IEP_DEIN_MTN_TAB6 0x0f8 /* Deinterlace motion table6 */ ++#define IEP_DEIN_MTN_TAB7 0x0fc /* Deinterlace motion table7 */ ++ ++#define IEP_ENH_CG_TAB 0x100 /* Contrast and gamma enhancement table */ ++#define IEP_ENH_DDE_COE0 0x400 /* Denoise,detail and edge enhancement coefficient */ ++#define IEP_ENH_DDE_COE1 0x500 /* Denoise,detail and edge enhancement coefficient1 */ ++ ++#define IEP_INT_MASK (IEP_INT_FRAME_DONE) ++ ++/* IEP colorformats */ ++#define IEP_COLOR_FMT_XRGB 0U ++#define IEP_COLOR_FMT_RGB565 1U ++#define IEP_COLOR_FMT_YUV422 2U ++#define IEP_COLOR_FMT_YUV420 3U ++ ++/* IEP YUV color swaps */ ++#define IEP_YUV_SWP_SP_UV 0U ++#define IEP_YUV_SWP_SP_VU 1U ++#define IEP_YUV_SWP_P 2U ++ ++/* IEP XRGB color swaps */ ++#define XRGB_SWP_XRGB 0U ++#define XRGB_SWP_XBGR 1U ++#define XRGB_SWP_BGRX 2U ++ ++/* IEP RGB565 color swaps */ ++#define RGB565_SWP_RGB 0U ++#define RGB565_SWP_BGR 1U ++ ++#define FMT_IS_YUV(fmt) (fmt == IEP_COLOR_FMT_XRGB || fmt == IEP_COLOR_FMT_RGB565 ? 0 : 1) ++ ++#define IEP_IMG_SIZE(w, h) (((w - 1) & 0x1fff) << 0 | \ ++ ((h - 1) & 0x1fff) << 16) ++ ++#define IEP_VIR_WIDTH(src_w, dst_w) (((src_w / 4) & 0x1fff) << 0 | \ ++ ((dst_w / 4) & 0x1fff) << 16) ++ ++#define IEP_Y_STRIDE(w, h) (w * h) ++#define IEP_UV_STRIDE(w, h, fac) (w * h + w * h / fac) ++ ++#define IEP_SRC_FMT_SWP_MASK(f) (FMT_IS_YUV(f) ? IEP_SRC_YUV_SWP_MASK : IEP_SRC_RGB_SWP_MASK) ++#define IEP_DST_FMT_SWP_MASK(f) (FMT_IS_YUV(f) ? IEP_DST_YUV_SWP_MASK : IEP_DST_RGB_SWP_MASK) ++ ++#define IEP_SRC_FMT(f, swp) (f << IEP_SRC_FMT_SHFT | \ ++ (swp << (FMT_IS_YUV(f) ? IEP_SRC_YUV_SWP_SHFT : IEP_SRC_RGB_SWP_SHFT))) ++#define IEP_DST_FMT(f, swp) (f << IEP_DST_FMT_SHFT | \ ++ (swp << (FMT_IS_YUV(f) ? IEP_DST_YUV_SWP_SHFT : IEP_DST_RGB_SWP_SHFT))) ++ ++/* IEP DEINTERLACE MODES */ ++#define IEP_DEIN_MODE_YUV 0U ++#define IEP_DEIN_MODE_I4O2 1U ++#define IEP_DEIN_MODE_I4O1B 2U ++#define IEP_DEIN_MODE_I4O1T 3U ++#define IEP_DEIN_MODE_I2O1B 4U ++#define IEP_DEIN_MODE_I2O1T 5U ++#define IEP_DEIN_MODE_BYPASS 6U ++ ++#define IEP_DEIN_IN_FIELDS_2 2U ++#define IEP_DEIN_IN_FIELDS_4 4U ++ ++#define IEP_DEIN_OUT_FRAMES_1 1U ++#define IEP_DEIN_OUT_FRAMES_2 2U ++ ++/* values taken from BSP driver */ ++static const u32 default_dein_motion_tbl[][2] = { ++ { IEP_DEIN_MTN_TAB0, 0x40404040 }, ++ { IEP_DEIN_MTN_TAB1, 0x3c3e3f3f }, ++ { IEP_DEIN_MTN_TAB2, 0x3336393b }, ++ { IEP_DEIN_MTN_TAB3, 0x272a2d31 }, ++ { IEP_DEIN_MTN_TAB4, 0x181c2023 }, ++ { IEP_DEIN_MTN_TAB5, 0x0c0e1215 }, ++ { IEP_DEIN_MTN_TAB6, 0x03040609 }, ++ { IEP_DEIN_MTN_TAB7, 0x00000001 }, ++ ++}; ++ ++#define IEP_DEIN_IN_IMG0_Y(bff) (bff ? IEP_SRC_ADDR_Y_RGB : IEP_SRC_ADDR_Y1) ++#define IEP_DEIN_IN_IMG0_CBCR(bff) (bff ? IEP_SRC_ADDR_CBCR : IEP_SRC_ADDR_CBCR1) ++#define IEP_DEIN_IN_IMG0_CR(bff) (bff ? IEP_SRC_ADDR_CR : IEP_SRC_ADDR_CR1) ++#define IEP_DEIN_IN_IMG1_Y(bff) (IEP_DEIN_IN_IMG0_Y(!bff)) ++#define IEP_DEIN_IN_IMG1_CBCR(bff) (IEP_DEIN_IN_IMG0_CBCR(!bff)) ++#define IEP_DEIN_IN_IMG1_CR(bff) (IEP_DEIN_IN_IMG0_CR(!bff)) ++ ++#define IEP_DEIN_OUT_IMG0_Y(bff) (bff ? IEP_DST_ADDR_Y1 : IEP_DST_ADDR_Y_RGB) ++#define IEP_DEIN_OUT_IMG0_CBCR(bff) (bff ? IEP_DST_ADDR_CBCR1 : IEP_DST_ADDR_CBCR) ++#define IEP_DEIN_OUT_IMG0_CR(bff) (bff ? IEP_DST_ADDR_CR1 : IEP_DST_ADDR_CR) ++#define IEP_DEIN_OUT_IMG1_Y(bff) (IEP_DEIN_OUT_IMG0_Y(!bff)) ++#define IEP_DEIN_OUT_IMG1_CBCR(bff) (IEP_DEIN_OUT_IMG0_CBCR(!bff)) ++#define IEP_DEIN_OUT_IMG1_CR(bff) (IEP_DEIN_OUT_IMG0_CR(!bff)) ++ ++#define IEP_DEIN_MODE(m) (m << IEP_DEIN_MODE_SHFT) ++ ++#define IEP_DEIN_IN_MODE_FIELDS(m) ((m == IEP_DEIN_MODE_I4O1T || m == IEP_DEIN_MODE_I4O1B \ ++ || m == IEP_DEIN_MODE_I4O2) \ ++ ? IEP_DEIN_IN_FIELDS_4 : IEP_DEIN_IN_FIELDS_2) ++ ++#define IEP_DEIN_OUT_MODE_FRAMES(m) (m == IEP_DEIN_MODE_I4O2 \ ++ ? IEP_DEIN_OUT_FRAMES_2 : IEP_DEIN_OUT_FRAMES_1) ++ ++#define IEP_DEIN_OUT_MODE_1FRM_TOP_FIELD(m) (m == IEP_DEIN_MODE_I4O1T || IEP_DEIN_MODE_I2O1T \ ++ ? 1 : 0) ++ ++#define IEP_DEIN_EDGE_INTPOL_RADIUS(r) (r << IEP_DEIN_EDGE_INTPOL_RADIUS_SHFT) ++ ++#define IEP_DEIN_HIGH_FREQ(f) (f << IEP_DEIN_HIGH_FREQ_SHFT) ++ ++/* YUV Enhance video modes */ ++#define VIDEO_MODE_BLACK_SCREEN 0U ++#define VIDEO_MODE_BLUE_SCREEN 1U ++#define VIDEO_MODE_COLOR_BARS 2U ++#define VIDEO_MODE_NORMAL_VIDEO 3U ++ ++#define YUV_VIDEO_MODE(m) ((m << IEP_YUV_VIDEO_MODE_SHFT) & IEP_YUV_VIDEO_MODE_MASK) ++#define YUV_BRIGHTNESS(v) ((v << IEP_YUV_BRIGHTNESS_SHFT) & IEP_YUV_BRIGHTNESS_MASK) ++#define YUV_CONTRAST(v) ((v << IEP_YUV_CONTRAST_SHFT) & IEP_YUV_CONTRAST_MASK) ++#define YUV_SATURATION(v) ((v << IEP_YUV_SATURATION_SHFT) & IEP_YUV_SATURATION_MASK) ++#define YUV_COS_HUE(v) ((v << IEP_YUV_COS_HUE_SHFT) & IEP_YUV_COS_HUE_MASK) ++#define YUV_SIN_HUE(v) ((v << IEP_YUV_SIN_HUE_SHFT) & IEP_YUV_SIN_HUE_MASK) ++ ++#endif +diff --git a/drivers/media/platform/rockchip/iep/iep.c b/drivers/media/platform/rockchip/iep/iep.c +new file mode 100644 +index 000000000000..93954e6c4c4d +--- /dev/null ++++ b/drivers/media/platform/rockchip/iep/iep.c +@@ -0,0 +1,1121 @@ ++// SPDX-License-Identifier: GPL-2.0-only ++/* ++ * Rockchip Image Enhancement Processor (IEP) driver ++ * ++ * Copyright (C) 2020 Alex Bee ++ * ++ */ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#include "iep-regs.h" ++#include "iep.h" ++ ++static struct iep_fmt formats[] = { ++ { ++ .fourcc = V4L2_PIX_FMT_NV12, ++ .color_swap = IEP_YUV_SWP_SP_UV, ++ .hw_format = IEP_COLOR_FMT_YUV420, ++ .depth = 12, ++ .uv_factor = 4, ++ }, ++ ++ { ++ .fourcc = V4L2_PIX_FMT_NV21, ++ .color_swap = IEP_YUV_SWP_SP_VU, ++ .hw_format = IEP_COLOR_FMT_YUV420, ++ .depth = 12, ++ .uv_factor = 4, ++ }, ++ { ++ .fourcc = V4L2_PIX_FMT_NV16, ++ .color_swap = IEP_YUV_SWP_SP_UV, ++ .hw_format = IEP_COLOR_FMT_YUV422, ++ .depth = 16, ++ .uv_factor = 2, ++ }, ++ { ++ .fourcc = V4L2_PIX_FMT_NV61, ++ .color_swap = IEP_YUV_SWP_SP_VU, ++ .hw_format = IEP_COLOR_FMT_YUV422, ++ .depth = 16, ++ .uv_factor = 2, ++ }, ++ { ++ .fourcc = V4L2_PIX_FMT_YUV420, ++ .color_swap = IEP_YUV_SWP_P, ++ .hw_format = IEP_COLOR_FMT_YUV420, ++ .depth = 12, ++ .uv_factor = 4, ++ }, ++ { ++ .fourcc = V4L2_PIX_FMT_YUV422P, ++ .color_swap = IEP_YUV_SWP_P, ++ .hw_format = IEP_COLOR_FMT_YUV422, ++ .depth = 16, ++ .uv_factor = 2, ++ }, ++}; ++ ++static struct iep_fmt *iep_fmt_find(struct v4l2_pix_format *pix_fmt) ++{ ++ unsigned int i; ++ ++ for (i = 0; i < ARRAY_SIZE(formats); i++) { ++ if (formats[i].fourcc == pix_fmt->pixelformat) ++ return &formats[i]; ++ } ++ ++ return NULL; ++} ++ ++static bool iep_check_pix_format(u32 pixelformat) ++{ ++ unsigned int i; ++ ++ for (i = 0; i < ARRAY_SIZE(formats); i++) ++ if (formats[i].fourcc == pixelformat) ++ return true; ++ ++ return false; ++} ++ ++static struct vb2_v4l2_buffer *iep_m2m_next_src_buf(struct iep_ctx *ctx) ++{ ++ struct vb2_v4l2_buffer *src_buf = v4l2_m2m_next_src_buf(ctx->fh.m2m_ctx); ++ ++ /* applcication has set a sequence: take it as start point */ ++ if (ctx->src_sequence == 0 && src_buf->sequence > 0) ++ ctx->src_sequence = src_buf->sequence; ++ ++ src_buf->sequence = ctx->src_sequence++; ++ ++ return src_buf; ++} ++ ++static struct vb2_v4l2_buffer *iep_m2m_next_dst_buf(struct iep_ctx *ctx) ++{ ++ struct vb2_v4l2_buffer *dst_buf = v4l2_m2m_next_dst_buf(ctx->fh.m2m_ctx); ++ ++ /* applcication has set a sequence: take it as start point */ ++ if (ctx->dst_sequence == 0 && dst_buf->sequence > 0) ++ ctx->dst_sequence = dst_buf->sequence; ++ ++ dst_buf->sequence = ctx->dst_sequence++; ++ ++ return dst_buf; ++} ++ ++static void iep_m2m_dst_bufs_done(struct iep_ctx *ctx, enum vb2_buffer_state state) ++{ ++ if (ctx->dst0_buf) { ++ v4l2_m2m_buf_done(ctx->dst0_buf, state); ++ ctx->dst_buffs_done++; ++ ctx->dst0_buf = NULL; ++ } ++ ++ if (ctx->dst1_buf) { ++ v4l2_m2m_buf_done(ctx->dst1_buf, state); ++ ctx->dst_buffs_done++; ++ ctx->dst1_buf = NULL; ++ } ++} ++ ++static void iep_setup_formats(struct iep_ctx *ctx) ++{ ++ /* setup src dimensions */ ++ iep_write(ctx->iep, IEP_SRC_IMG_SIZE, ++ IEP_IMG_SIZE(ctx->src_fmt.pix.width, ctx->src_fmt.pix.height)); ++ ++ /* setup dst dimensions */ ++ iep_write(ctx->iep, IEP_DST_IMG_SIZE, ++ IEP_IMG_SIZE(ctx->dst_fmt.pix.width, ctx->dst_fmt.pix.height)); ++ ++ /* setup virtual width */ ++ iep_write(ctx->iep, IEP_VIR_IMG_WIDTH, ++ IEP_VIR_WIDTH(ctx->src_fmt.pix.width, ctx->dst_fmt.pix.width)); ++ ++ /* setup src format */ ++ iep_shadow_mod(ctx->iep, IEP_CONFIG1, IEP_RAW_CONFIG1, ++ IEP_SRC_FMT_MASK | IEP_SRC_FMT_SWP_MASK(ctx->src_fmt.hw_fmt->hw_format), ++ IEP_SRC_FMT(ctx->src_fmt.hw_fmt->hw_format, ++ ctx->src_fmt.hw_fmt->color_swap)); ++ /* setup dst format */ ++ iep_shadow_mod(ctx->iep, IEP_CONFIG1, IEP_RAW_CONFIG1, ++ IEP_DST_FMT_MASK | IEP_DST_FMT_SWP_MASK(ctx->dst_fmt.hw_fmt->hw_format), ++ IEP_DST_FMT(ctx->dst_fmt.hw_fmt->hw_format, ++ ctx->dst_fmt.hw_fmt->color_swap)); ++ ++ ctx->fmt_changed = false; ++} ++ ++static void iep_dein_init(struct rockchip_iep *iep) ++{ ++ unsigned int i; ++ ++ /* values taken from BSP driver */ ++ iep_shadow_mod(iep, IEP_CONFIG0, IEP_RAW_CONFIG0, ++ (IEP_DEIN_EDGE_INTPOL_SMTH_EN | ++ IEP_DEIN_EDGE_INTPOL_RADIUS_MASK | ++ IEP_DEIN_HIGH_FREQ_EN | ++ IEP_DEIN_HIGH_FREQ_MASK), ++ (IEP_DEIN_EDGE_INTPOL_SMTH_EN | ++ IEP_DEIN_EDGE_INTPOL_RADIUS(3) | ++ IEP_DEIN_HIGH_FREQ_EN | ++ IEP_DEIN_HIGH_FREQ(64))); ++ ++ for (i = 0; i < ARRAY_SIZE(default_dein_motion_tbl); i++) ++ iep_write(iep, default_dein_motion_tbl[i][0], ++ default_dein_motion_tbl[i][1]); ++} ++ ++static void iep_init(struct rockchip_iep *iep) ++{ ++ iep_write(iep, IEP_CONFIG0, ++ IEP_DEIN_MODE(IEP_DEIN_MODE_BYPASS) // | ++ //IEP_YUV_ENHNC_EN ++ ); ++ ++ /* TODO: B/S/C/H works ++ * only in 1-frame-out modes ++ iep_write(iep, IEP_ENH_YUV_CNFG_0, ++ YUV_BRIGHTNESS(0) | ++ YUV_CONTRAST(128) | ++ YUV_SATURATION(128)); ++ ++ iep_write(iep, IEP_ENH_YUV_CNFG_1, ++ YUV_COS_HUE(255) | ++ YUV_SIN_HUE(255)); ++ ++ iep_write(iep, IEP_ENH_YUV_CNFG_2, ++ YUV_VIDEO_MODE(VIDEO_MODE_NORMAL_VIDEO)); ++ ++ */ ++ ++ /* reset frame counter */ ++ iep_write(iep, IEP_FRM_CNT, 0); ++} ++ ++static void iep_device_run(void *priv) ++{ ++ struct iep_ctx *ctx = priv; ++ struct rockchip_iep *iep = ctx->iep; ++ struct vb2_v4l2_buffer *src, *dst; ++ unsigned int dein_mode; ++ dma_addr_t addr; ++ ++ if (ctx->fmt_changed) ++ iep_setup_formats(ctx); ++ ++ if (ctx->prev_src_buf) ++ dein_mode = IEP_DEIN_MODE_I4O2; ++ else ++ dein_mode = ctx->field_bff ? IEP_DEIN_MODE_I2O1B : IEP_DEIN_MODE_I2O1T; ++ ++ iep_shadow_mod(iep, IEP_CONFIG0, IEP_RAW_CONFIG0, ++ IEP_DEIN_MODE_MASK, IEP_DEIN_MODE(dein_mode)); ++ ++ /* sync RAW_xxx registers with actual used */ ++ iep_write(iep, IEP_CONFIG_DONE, 1); ++ ++ /* setup src buff(s)/addresses */ ++ src = iep_m2m_next_src_buf(ctx); ++ addr = vb2_dma_contig_plane_dma_addr(&src->vb2_buf, 0); ++ ++ iep_write(iep, IEP_DEIN_IN_IMG0_Y(ctx->field_bff), addr); ++ ++ iep_write(iep, IEP_DEIN_IN_IMG0_CBCR(ctx->field_bff), ++ addr + ctx->src_fmt.y_stride); ++ ++ iep_write(iep, IEP_DEIN_IN_IMG0_CR(ctx->field_bff), ++ addr + ctx->src_fmt.uv_stride); ++ ++ if (IEP_DEIN_IN_MODE_FIELDS(dein_mode) == IEP_DEIN_IN_FIELDS_4) ++ addr = vb2_dma_contig_plane_dma_addr(&ctx->prev_src_buf->vb2_buf, 0); ++ ++ iep_write(iep, IEP_DEIN_IN_IMG1_Y(ctx->field_bff), addr); ++ ++ iep_write(iep, IEP_DEIN_IN_IMG1_CBCR(ctx->field_bff), ++ addr + ctx->src_fmt.y_stride); ++ ++ iep_write(iep, IEP_DEIN_IN_IMG1_CR(ctx->field_bff), ++ addr + ctx->src_fmt.uv_stride); ++ ++ /* setup dst buff(s)/addresses */ ++ dst = iep_m2m_next_dst_buf(ctx); ++ addr = vb2_dma_contig_plane_dma_addr(&dst->vb2_buf, 0); ++ ++ if (IEP_DEIN_OUT_MODE_FRAMES(dein_mode) == IEP_DEIN_OUT_FRAMES_2) { ++ v4l2_m2m_buf_copy_metadata(ctx->prev_src_buf, dst, true); ++ ++ iep_write(iep, IEP_DEIN_OUT_IMG0_Y(ctx->field_bff), addr); ++ ++ iep_write(iep, IEP_DEIN_OUT_IMG0_CBCR(ctx->field_bff), ++ addr + ctx->dst_fmt.y_stride); ++ ++ iep_write(iep, IEP_DEIN_OUT_IMG0_CR(ctx->field_bff), ++ addr + ctx->dst_fmt.uv_stride); ++ ++ ctx->dst0_buf = v4l2_m2m_dst_buf_remove(ctx->fh.m2m_ctx); ++ ++ dst = iep_m2m_next_dst_buf(ctx); ++ addr = vb2_dma_contig_plane_dma_addr(&dst->vb2_buf, 0); ++ } ++ ++ v4l2_m2m_buf_copy_metadata(src, dst, true); ++ ++ iep_write(iep, IEP_DEIN_OUT_IMG1_Y(ctx->field_bff), addr); ++ ++ iep_write(iep, IEP_DEIN_OUT_IMG1_CBCR(ctx->field_bff), ++ addr + ctx->dst_fmt.y_stride); ++ ++ iep_write(iep, IEP_DEIN_OUT_IMG1_CR(ctx->field_bff), ++ addr + ctx->dst_fmt.uv_stride); ++ ++ ctx->dst1_buf = v4l2_m2m_dst_buf_remove(ctx->fh.m2m_ctx); ++ ++ iep_mod(ctx->iep, IEP_INT, IEP_INT_FRAME_DONE_EN, ++ IEP_INT_FRAME_DONE_EN); ++ ++ /* start HW */ ++ iep_write(iep, IEP_FRM_START, 1); ++} ++ ++static int iep_job_ready(void *priv) ++{ ++ struct iep_ctx *ctx = priv; ++ ++ return v4l2_m2m_num_dst_bufs_ready(ctx->fh.m2m_ctx) >= 2 && ++ v4l2_m2m_num_src_bufs_ready(ctx->fh.m2m_ctx) >= 1; ++} ++ ++static void iep_job_abort(void *priv) ++{ ++ struct iep_ctx *ctx = priv; ++ ++ /* Will cancel the transaction in the next interrupt handler */ ++ ctx->job_abort = true; ++} ++ ++static const struct v4l2_m2m_ops iep_m2m_ops = { ++ .device_run = iep_device_run, ++ .job_ready = iep_job_ready, ++ .job_abort = iep_job_abort, ++}; ++ ++static int iep_queue_setup(struct vb2_queue *vq, unsigned int *nbuffers, ++ unsigned int *nplanes, unsigned int sizes[], ++ struct device *alloc_devs[]) ++{ ++ struct iep_ctx *ctx = vb2_get_drv_priv(vq); ++ struct v4l2_pix_format *pix_fmt; ++ ++ if (V4L2_TYPE_IS_OUTPUT(vq->type)) ++ pix_fmt = &ctx->src_fmt.pix; ++ else ++ pix_fmt = &ctx->dst_fmt.pix; ++ ++ if (*nplanes) { ++ if (sizes[0] < pix_fmt->sizeimage) ++ return -EINVAL; ++ } else { ++ sizes[0] = pix_fmt->sizeimage; ++ *nplanes = 1; ++ } ++ ++ return 0; ++} ++ ++static int iep_buf_prepare(struct vb2_buffer *vb) ++{ ++ struct vb2_queue *vq = vb->vb2_queue; ++ struct iep_ctx *ctx = vb2_get_drv_priv(vq); ++ struct v4l2_pix_format *pix_fmt; ++ ++ if (V4L2_TYPE_IS_OUTPUT(vq->type)) ++ pix_fmt = &ctx->src_fmt.pix; ++ else ++ pix_fmt = &ctx->dst_fmt.pix; ++ ++ if (vb2_plane_size(vb, 0) < pix_fmt->sizeimage) ++ return -EINVAL; ++ ++ /* set bytesused for capture buffers */ ++ if (!V4L2_TYPE_IS_OUTPUT(vq->type)) ++ vb2_set_plane_payload(vb, 0, pix_fmt->sizeimage); ++ ++ return 0; ++} ++ ++static void iep_buf_queue(struct vb2_buffer *vb) ++{ ++ struct vb2_v4l2_buffer *vbuf = to_vb2_v4l2_buffer(vb); ++ struct iep_ctx *ctx = vb2_get_drv_priv(vb->vb2_queue); ++ ++ v4l2_m2m_buf_queue(ctx->fh.m2m_ctx, vbuf); ++} ++ ++static void iep_queue_cleanup(struct vb2_queue *vq, u32 state) ++{ ++ struct iep_ctx *ctx = vb2_get_drv_priv(vq); ++ struct vb2_v4l2_buffer *vbuf; ++ ++ do { ++ if (V4L2_TYPE_IS_OUTPUT(vq->type)) ++ vbuf = v4l2_m2m_src_buf_remove(ctx->fh.m2m_ctx); ++ else ++ vbuf = v4l2_m2m_dst_buf_remove(ctx->fh.m2m_ctx); ++ ++ if (vbuf) ++ v4l2_m2m_buf_done(vbuf, state); ++ } while (vbuf); ++ ++ if (V4L2_TYPE_IS_OUTPUT(vq->type) && ctx->prev_src_buf) ++ v4l2_m2m_buf_done(ctx->prev_src_buf, state); ++ else ++ iep_m2m_dst_bufs_done(ctx, state); ++} ++ ++static int iep_start_streaming(struct vb2_queue *vq, unsigned int count) ++{ ++ struct iep_ctx *ctx = vb2_get_drv_priv(vq); ++ struct device *dev = ctx->iep->dev; ++ int ret; ++ ++ if (V4L2_TYPE_IS_OUTPUT(vq->type)) { ++ ret = pm_runtime_get_sync(dev); ++ if (ret < 0) { ++ dev_err(dev, "Failed to enable module\n"); ++ goto err_runtime_get; ++ } ++ ++ ctx->field_order_bff = ++ ctx->src_fmt.pix.field == V4L2_FIELD_INTERLACED_BT; ++ ctx->field_bff = ctx->field_order_bff; ++ ++ ctx->src_sequence = 0; ++ ctx->dst_sequence = 0; ++ ++ ctx->prev_src_buf = NULL; ++ ++ ctx->dst0_buf = NULL; ++ ctx->dst1_buf = NULL; ++ ctx->dst_buffs_done = 0; ++ ++ ctx->job_abort = false; ++ ++ iep_init(ctx->iep); ++ //if (ctx->src_fmt.pix.field != ctx->src_fmt.pix.field) ++ iep_dein_init(ctx->iep); ++ } ++ ++ return 0; ++ ++err_runtime_get: ++ iep_queue_cleanup(vq, VB2_BUF_STATE_QUEUED); ++ ++ return ret; ++} ++ ++static void iep_stop_streaming(struct vb2_queue *vq) ++{ ++ struct iep_ctx *ctx = vb2_get_drv_priv(vq); ++ ++ if (V4L2_TYPE_IS_OUTPUT(vq->type)) { ++ pm_runtime_mark_last_busy(ctx->iep->dev); ++ pm_runtime_put_autosuspend(ctx->iep->dev); ++ } ++ ++ iep_queue_cleanup(vq, VB2_BUF_STATE_ERROR); ++} ++ ++static const struct vb2_ops iep_qops = { ++ .queue_setup = iep_queue_setup, ++ .buf_prepare = iep_buf_prepare, ++ .buf_queue = iep_buf_queue, ++ .start_streaming = iep_start_streaming, ++ .stop_streaming = iep_stop_streaming, ++ .wait_prepare = vb2_ops_wait_prepare, ++ .wait_finish = vb2_ops_wait_finish, ++}; ++ ++static int iep_queue_init(void *priv, struct vb2_queue *src_vq, ++ struct vb2_queue *dst_vq) ++{ ++ struct iep_ctx *ctx = priv; ++ int ret; ++ ++ src_vq->type = V4L2_BUF_TYPE_VIDEO_OUTPUT; ++ src_vq->dma_attrs = DMA_ATTR_ALLOC_SINGLE_PAGES | ++ DMA_ATTR_NO_KERNEL_MAPPING; ++ src_vq->io_modes = VB2_MMAP | VB2_DMABUF; ++ src_vq->drv_priv = ctx; ++ src_vq->buf_struct_size = sizeof(struct v4l2_m2m_buffer); ++ src_vq->min_buffers_needed = 1; ++ src_vq->ops = &iep_qops; ++ src_vq->mem_ops = &vb2_dma_contig_memops; ++ src_vq->timestamp_flags = V4L2_BUF_FLAG_TIMESTAMP_COPY; ++ src_vq->lock = &ctx->iep->mutex; ++ src_vq->dev = ctx->iep->v4l2_dev.dev; ++ ++ ret = vb2_queue_init(src_vq); ++ if (ret) ++ return ret; ++ ++ dst_vq->dma_attrs = DMA_ATTR_ALLOC_SINGLE_PAGES | ++ DMA_ATTR_NO_KERNEL_MAPPING; ++ dst_vq->type = V4L2_BUF_TYPE_VIDEO_CAPTURE; ++ dst_vq->io_modes = VB2_MMAP | VB2_DMABUF; ++ dst_vq->drv_priv = ctx; ++ dst_vq->buf_struct_size = sizeof(struct v4l2_m2m_buffer); ++ dst_vq->min_buffers_needed = 2; ++ dst_vq->ops = &iep_qops; ++ dst_vq->mem_ops = &vb2_dma_contig_memops; ++ dst_vq->timestamp_flags = V4L2_BUF_FLAG_TIMESTAMP_COPY; ++ dst_vq->lock = &ctx->iep->mutex; ++ dst_vq->dev = ctx->iep->v4l2_dev.dev; ++ ++ ret = vb2_queue_init(dst_vq); ++ if (ret) ++ return ret; ++ ++ return 0; ++} ++ ++static void iep_prepare_format(struct v4l2_pix_format *pix_fmt) ++{ ++ unsigned int height = pix_fmt->height; ++ unsigned int width = pix_fmt->width; ++ unsigned int sizeimage, bytesperline; ++ ++ struct iep_fmt *hw_fmt = iep_fmt_find(pix_fmt); ++ ++ if (!hw_fmt) { ++ hw_fmt = &formats[0]; ++ pix_fmt->pixelformat = hw_fmt->fourcc; ++ } ++ ++ width = ALIGN(clamp(width, IEP_MIN_WIDTH, ++ IEP_MAX_WIDTH), 16); ++ height = ALIGN(clamp(height, IEP_MIN_HEIGHT, ++ IEP_MAX_HEIGHT), 16); ++ ++ bytesperline = FMT_IS_YUV(hw_fmt->hw_format) ++ ? width : (width * hw_fmt->depth) >> 3; ++ ++ sizeimage = height * (width * hw_fmt->depth) >> 3; ++ ++ pix_fmt->width = width; ++ pix_fmt->height = height; ++ pix_fmt->bytesperline = bytesperline; ++ pix_fmt->sizeimage = sizeimage; ++} ++ ++static int iep_open(struct file *file) ++{ ++ struct rockchip_iep *iep = video_drvdata(file); ++ struct iep_ctx *ctx = NULL; ++ ++ int ret; ++ ++ if (mutex_lock_interruptible(&iep->mutex)) ++ return -ERESTARTSYS; ++ ++ ctx = kzalloc(sizeof(*ctx), GFP_KERNEL); ++ if (!ctx) { ++ mutex_unlock(&iep->mutex); ++ return -ENOMEM; ++ } ++ ++ /* default output format */ ++ ctx->src_fmt.pix.pixelformat = formats[0].fourcc; ++ ctx->src_fmt.pix.field = V4L2_FIELD_INTERLACED; ++ ctx->src_fmt.pix.width = IEP_DEFAULT_WIDTH; ++ ctx->src_fmt.pix.height = IEP_DEFAULT_HEIGHT; ++ iep_prepare_format(&ctx->src_fmt.pix); ++ ctx->src_fmt.hw_fmt = &formats[0]; ++ ctx->dst_fmt.y_stride = IEP_Y_STRIDE(ctx->src_fmt.pix.width, ctx->src_fmt.pix.height); ++ ctx->dst_fmt.uv_stride = IEP_UV_STRIDE(ctx->src_fmt.pix.width, ctx->src_fmt.pix.height, ++ ctx->src_fmt.hw_fmt->uv_factor); ++ ++ /* default capture format */ ++ ctx->dst_fmt.pix.pixelformat = formats[0].fourcc; ++ ctx->dst_fmt.pix.field = V4L2_FIELD_NONE; ++ ctx->dst_fmt.pix.width = IEP_DEFAULT_WIDTH; ++ ctx->dst_fmt.pix.height = IEP_DEFAULT_HEIGHT; ++ iep_prepare_format(&ctx->dst_fmt.pix); ++ ctx->dst_fmt.hw_fmt = &formats[0]; ++ ctx->dst_fmt.y_stride = IEP_Y_STRIDE(ctx->dst_fmt.pix.width, ctx->dst_fmt.pix.height); ++ ctx->dst_fmt.uv_stride = IEP_UV_STRIDE(ctx->dst_fmt.pix.width, ctx->dst_fmt.pix.height, ++ ctx->dst_fmt.hw_fmt->uv_factor); ++ /* ensure fmts are written to HW */ ++ ctx->fmt_changed = true; ++ ++ v4l2_fh_init(&ctx->fh, video_devdata(file)); ++ file->private_data = &ctx->fh; ++ ctx->iep = iep; ++ ++ ctx->fh.m2m_ctx = v4l2_m2m_ctx_init(iep->m2m_dev, ctx, ++ &iep_queue_init); ++ ++ if (IS_ERR(ctx->fh.m2m_ctx)) { ++ ret = PTR_ERR(ctx->fh.m2m_ctx); ++ goto err_free; ++ } ++ ++ v4l2_fh_add(&ctx->fh); ++ ++ mutex_unlock(&iep->mutex); ++ ++ return 0; ++ ++err_free: ++ kfree(ctx); ++ mutex_unlock(&iep->mutex); ++ ++ return ret; ++} ++ ++static int iep_release(struct file *file) ++{ ++ struct rockchip_iep *iep = video_drvdata(file); ++ struct iep_ctx *ctx = container_of(file->private_data, ++ struct iep_ctx, fh); ++ ++ mutex_lock(&iep->mutex); ++ ++ v4l2_fh_del(&ctx->fh); ++ v4l2_fh_exit(&ctx->fh); ++ v4l2_m2m_ctx_release(ctx->fh.m2m_ctx); ++ kfree(ctx); ++ ++ mutex_unlock(&iep->mutex); ++ return 0; ++} ++ ++static const struct v4l2_file_operations iep_fops = { ++ .owner = THIS_MODULE, ++ .open = iep_open, ++ .release = iep_release, ++ .poll = v4l2_m2m_fop_poll, ++ .unlocked_ioctl = video_ioctl2, ++ .mmap = v4l2_m2m_fop_mmap, ++}; ++ ++static int iep_querycap(struct file *file, void *priv, ++ struct v4l2_capability *cap) ++{ ++ strscpy(cap->driver, IEP_NAME, sizeof(cap->driver)); ++ strscpy(cap->card, IEP_NAME, sizeof(cap->card)); ++ snprintf(cap->bus_info, sizeof(cap->bus_info), ++ "platform:%s", IEP_NAME); ++ ++ return 0; ++} ++ ++static int iep_enum_fmt(struct file *file, void *priv, ++ struct v4l2_fmtdesc *f) ++{ ++ struct iep_fmt *fmt; ++ ++ if (f->index < ARRAY_SIZE(formats)) { ++ fmt = &formats[f->index]; ++ f->pixelformat = fmt->fourcc; ++ ++ return 0; ++ } ++ ++ return -EINVAL; ++} ++ ++static int iep_enum_framesizes(struct file *file, void *priv, ++ struct v4l2_frmsizeenum *fsize) ++{ ++ if (fsize->index != 0) ++ return -EINVAL; ++ ++ if (!iep_check_pix_format(fsize->pixel_format)) ++ return -EINVAL; ++ ++ fsize->type = V4L2_FRMSIZE_TYPE_STEPWISE; ++ ++ fsize->stepwise.min_width = IEP_MIN_WIDTH; ++ fsize->stepwise.max_width = IEP_MAX_WIDTH; ++ fsize->stepwise.step_width = 16; ++ ++ fsize->stepwise.min_height = IEP_MIN_HEIGHT; ++ fsize->stepwise.max_height = IEP_MAX_HEIGHT; ++ fsize->stepwise.step_height = 16; ++ ++ return 0; ++} ++ ++static inline struct iep_ctx *iep_file2ctx(struct file *file) ++{ ++ return container_of(file->private_data, struct iep_ctx, fh); ++} ++ ++static int iep_g_fmt_vid_cap(struct file *file, void *priv, ++ struct v4l2_format *f) ++{ ++ struct iep_ctx *ctx = iep_file2ctx(file); ++ ++ f->fmt.pix = ctx->dst_fmt.pix; ++ ++ return 0; ++} ++ ++static int iep_g_fmt_vid_out(struct file *file, void *priv, ++ struct v4l2_format *f) ++{ ++ struct iep_ctx *ctx = iep_file2ctx(file); ++ ++ f->fmt.pix = ctx->src_fmt.pix; ++ ++ return 0; ++} ++ ++static int iep_try_fmt_vid_cap(struct file *file, void *priv, ++ struct v4l2_format *f) ++{ ++ f->fmt.pix.field = V4L2_FIELD_NONE; ++ iep_prepare_format(&f->fmt.pix); ++ ++ return 0; ++} ++ ++static int iep_try_fmt_vid_out(struct file *file, void *priv, ++ struct v4l2_format *f) ++{ ++ if (f->fmt.pix.field != V4L2_FIELD_INTERLACED_TB && ++ f->fmt.pix.field != V4L2_FIELD_INTERLACED_BT && ++ f->fmt.pix.field != V4L2_FIELD_INTERLACED) ++ f->fmt.pix.field = V4L2_FIELD_INTERLACED; ++ ++ iep_prepare_format(&f->fmt.pix); ++ ++ return 0; ++} ++ ++static int iep_s_fmt_vid_out(struct file *file, void *priv, ++ struct v4l2_format *f) ++{ ++ struct iep_ctx *ctx = iep_file2ctx(file); ++ struct vb2_queue *vq; ++ ++ int ret; ++ ++ ret = iep_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)) ++ return -EBUSY; ++ ++ ctx->src_fmt.pix = f->fmt.pix; ++ ctx->src_fmt.hw_fmt = iep_fmt_find(&f->fmt.pix); ++ ctx->src_fmt.y_stride = IEP_Y_STRIDE(f->fmt.pix.width, f->fmt.pix.height); ++ ctx->src_fmt.uv_stride = IEP_UV_STRIDE(f->fmt.pix.width, f->fmt.pix.height, ++ ctx->src_fmt.hw_fmt->uv_factor); ++ ++ /* Propagate colorspace information to capture. */ ++ ctx->dst_fmt.pix.colorspace = f->fmt.pix.colorspace; ++ ctx->dst_fmt.pix.xfer_func = f->fmt.pix.xfer_func; ++ ctx->dst_fmt.pix.ycbcr_enc = f->fmt.pix.ycbcr_enc; ++ ctx->dst_fmt.pix.quantization = f->fmt.pix.quantization; ++ ++ /* scaling is not supported */ ++ ctx->dst_fmt.pix.width = f->fmt.pix.width; ++ ctx->dst_fmt.pix.height = f->fmt.pix.height; ++ ctx->dst_fmt.y_stride = IEP_Y_STRIDE(f->fmt.pix.width, f->fmt.pix.height); ++ ctx->dst_fmt.uv_stride = IEP_UV_STRIDE(f->fmt.pix.width, f->fmt.pix.height, ++ ctx->dst_fmt.hw_fmt->uv_factor); ++ ++ ctx->fmt_changed = true; ++ ++ return 0; ++} ++ ++static int iep_s_fmt_vid_cap(struct file *file, void *priv, ++ struct v4l2_format *f) ++{ ++ struct iep_ctx *ctx = iep_file2ctx(file); ++ struct vb2_queue *vq; ++ int ret; ++ ++ ret = iep_try_fmt_vid_cap(file, priv, f); ++ if (ret) ++ return ret; ++ ++ vq = v4l2_m2m_get_vq(ctx->fh.m2m_ctx, f->type); ++ if (vb2_is_busy(vq)) ++ return -EBUSY; ++ ++ /* scaling is not supported */ ++ f->fmt.pix.width = ctx->src_fmt.pix.width; ++ f->fmt.pix.height = ctx->src_fmt.pix.height; ++ ++ ctx->dst_fmt.pix = f->fmt.pix; ++ ctx->dst_fmt.hw_fmt = iep_fmt_find(&f->fmt.pix); ++ ++ ctx->dst_fmt.y_stride = IEP_Y_STRIDE(f->fmt.pix.width, f->fmt.pix.height); ++ ctx->dst_fmt.uv_stride = IEP_UV_STRIDE(f->fmt.pix.width, f->fmt.pix.height, ++ ctx->dst_fmt.hw_fmt->uv_factor); ++ ++ ctx->fmt_changed = true; ++ ++ return 0; ++} ++ ++static const struct v4l2_ioctl_ops iep_ioctl_ops = { ++ .vidioc_querycap = iep_querycap, ++ ++ .vidioc_enum_framesizes = iep_enum_framesizes, ++ ++ .vidioc_enum_fmt_vid_cap = iep_enum_fmt, ++ .vidioc_g_fmt_vid_cap = iep_g_fmt_vid_cap, ++ .vidioc_try_fmt_vid_cap = iep_try_fmt_vid_cap, ++ .vidioc_s_fmt_vid_cap = iep_s_fmt_vid_cap, ++ ++ .vidioc_enum_fmt_vid_out = iep_enum_fmt, ++ .vidioc_g_fmt_vid_out = iep_g_fmt_vid_out, ++ .vidioc_try_fmt_vid_out = iep_try_fmt_vid_out, ++ .vidioc_s_fmt_vid_out = iep_s_fmt_vid_out, ++ ++ .vidioc_reqbufs = v4l2_m2m_ioctl_reqbufs, ++ .vidioc_querybuf = v4l2_m2m_ioctl_querybuf, ++ .vidioc_qbuf = v4l2_m2m_ioctl_qbuf, ++ .vidioc_dqbuf = v4l2_m2m_ioctl_dqbuf, ++ .vidioc_prepare_buf = v4l2_m2m_ioctl_prepare_buf, ++ .vidioc_create_bufs = v4l2_m2m_ioctl_create_bufs, ++ .vidioc_expbuf = v4l2_m2m_ioctl_expbuf, ++ ++ .vidioc_streamon = v4l2_m2m_ioctl_streamon, ++ .vidioc_streamoff = v4l2_m2m_ioctl_streamoff, ++}; ++ ++static const struct video_device iep_video_device = { ++ .name = IEP_NAME, ++ .vfl_dir = VFL_DIR_M2M, ++ .fops = &iep_fops, ++ .ioctl_ops = &iep_ioctl_ops, ++ .minor = -1, ++ .release = video_device_release_empty, ++ .device_caps = V4L2_CAP_VIDEO_M2M | V4L2_CAP_STREAMING, ++}; ++ ++static int iep_parse_dt(struct rockchip_iep *iep) ++{ ++ int ret = 0; ++ ++ iep->resets = devm_reset_control_array_get(iep->dev, false, true); ++ if (IS_ERR(iep->resets)) { ++ dev_err(iep->dev, "getting resets failed %ld\n", PTR_ERR(iep->resets)); ++ return PTR_ERR(iep->resets); ++ } ++ ++ iep->axi_clk = devm_clk_get(iep->dev, "axi"); ++ if (IS_ERR(iep->axi_clk)) { ++ dev_err(iep->dev, "failed to get aclk clock\n"); ++ return PTR_ERR(iep->axi_clk); ++ } ++ ++ iep->ahb_clk = devm_clk_get(iep->dev, "ahb"); ++ if (IS_ERR(iep->ahb_clk)) { ++ dev_err(iep->dev, "failed to get hclk clock\n"); ++ return PTR_ERR(iep->ahb_clk); ++ } ++ ++ ret = clk_set_rate(iep->axi_clk, 300000000); ++ ++ if (ret) ++ dev_err(iep->dev, "failed to set axi clock rate to 300 MHz\n"); ++ ++ return ret; ++} ++ ++static irqreturn_t iep_isr(int irq, void *prv) ++{ ++ struct rockchip_iep *iep = prv; ++ struct iep_ctx *ctx; ++ u32 val; ++ enum vb2_buffer_state state = VB2_BUF_STATE_DONE; ++ ++ ctx = v4l2_m2m_get_curr_priv(iep->m2m_dev); ++ if (!ctx) { ++ v4l2_err(&iep->v4l2_dev, ++ "Instance released before the end of transaction\n"); ++ return IRQ_NONE; ++ } ++ ++ /* ++ * The irq is shared with the iommu. If the runtime-pm state of the ++ * iep-device is disabled or the interrupt status doesn't match the ++ * expeceted mask the irq has been targeted to the iommu. ++ */ ++ ++ if (!pm_runtime_active(iep->dev) || ++ !(iep_read(iep, IEP_INT) & IEP_INT_MASK)) ++ return IRQ_NONE; ++ ++ /* disable interrupt - will be re-enabled at next iep_device_run */ ++ iep_mod(ctx->iep, IEP_INT, ++ IEP_INT_FRAME_DONE_EN, 0); ++ ++ iep_mod(iep, IEP_INT, IEP_INT_FRAME_DONE_CLR, ++ IEP_INT_FRAME_DONE_CLR); ++ ++ /* wait for all status regs to show "idle" */ ++ val = readl_poll_timeout(iep->regs + IEP_STATUS, val, ++ (val == 0), 100, IEP_TIMEOUT); ++ ++ if (val) { ++ dev_err(iep->dev, ++ "Failed to wait for job to finish: status: %u\n", val); ++ state = VB2_BUF_STATE_ERROR; ++ ctx->job_abort = true; ++ } ++ ++ iep_m2m_dst_bufs_done(ctx, state); ++ ++ ctx->field_bff = (ctx->dst_buffs_done % 2 == 0) ++ ? ctx->field_order_bff : !ctx->field_order_bff; ++ ++ if (ctx->dst_buffs_done == 2 || ctx->job_abort) { ++ if (ctx->prev_src_buf) ++ v4l2_m2m_buf_done(ctx->prev_src_buf, state); ++ ++ /* current src buff will be next prev */ ++ ctx->prev_src_buf = v4l2_m2m_src_buf_remove(ctx->fh.m2m_ctx); ++ ++ v4l2_m2m_job_finish(ctx->iep->m2m_dev, ctx->fh.m2m_ctx); ++ ctx->dst_buffs_done = 0; ++ ++ } else { ++ iep_device_run(ctx); ++ } ++ ++ return IRQ_HANDLED; ++} ++ ++static int iep_probe(struct platform_device *pdev) ++{ ++ struct rockchip_iep *iep; ++ struct video_device *vfd; ++ struct resource *res; ++ int ret = 0; ++ int irq; ++ ++ if (!pdev->dev.of_node) ++ return -ENODEV; ++ ++ iep = devm_kzalloc(&pdev->dev, sizeof(*iep), GFP_KERNEL); ++ if (!iep) ++ return -ENOMEM; ++ ++ platform_set_drvdata(pdev, iep); ++ iep->dev = &pdev->dev; ++ iep->vfd = iep_video_device; ++ ++ ret = iep_parse_dt(iep); ++ if (ret) ++ dev_err(&pdev->dev, "Unable to parse OF data\n"); ++ ++ res = platform_get_resource(pdev, IORESOURCE_MEM, 0); ++ ++ iep->regs = devm_ioremap_resource(iep->dev, res); ++ if (IS_ERR(iep->regs)) { ++ ret = PTR_ERR(iep->regs); ++ goto err_put_clk; ++ } ++ ++ ret = dma_set_coherent_mask(&pdev->dev, DMA_BIT_MASK(32)); ++ if (ret) { ++ dev_err(&pdev->dev, "Could not set DMA coherent mask.\n"); ++ goto err_put_clk; ++ } ++ ++ vb2_dma_contig_set_max_seg_size(&pdev->dev, DMA_BIT_MASK(32)); ++ ++ irq = platform_get_irq(pdev, 0); ++ if (irq < 0) { ++ ret = irq; ++ goto err_put_clk; ++ } ++ ++ /* IRQ is shared with IOMMU */ ++ ret = devm_request_irq(iep->dev, irq, iep_isr, IRQF_SHARED, ++ dev_name(iep->dev), iep); ++ if (ret < 0) { ++ dev_err(iep->dev, "failed to request irq\n"); ++ goto err_put_clk; ++ } ++ ++ mutex_init(&iep->mutex); ++ ++ ret = v4l2_device_register(&pdev->dev, &iep->v4l2_dev); ++ if (ret) { ++ dev_err(iep->dev, "Failed to register V4L2 device\n"); ++ ++ return ret; ++ } ++ ++ vfd = &iep->vfd; ++ vfd->lock = &iep->mutex; ++ vfd->v4l2_dev = &iep->v4l2_dev; ++ ++ snprintf(vfd->name, sizeof(vfd->name), "%s", ++ iep_video_device.name); ++ ++ video_set_drvdata(vfd, iep); ++ ++ ret = video_register_device(vfd, VFL_TYPE_VIDEO, 0); ++ if (ret) { ++ v4l2_err(&iep->v4l2_dev, "Failed to register video device\n"); ++ ++ goto err_v4l2; ++ } ++ ++ v4l2_info(&iep->v4l2_dev, ++ "Device %s registered as /dev/video%d\n", vfd->name, vfd->num); ++ ++ iep->m2m_dev = v4l2_m2m_init(&iep_m2m_ops); ++ if (IS_ERR(iep->m2m_dev)) { ++ v4l2_err(&iep->v4l2_dev, ++ "Failed to initialize V4L2 M2M device\n"); ++ ret = PTR_ERR(iep->m2m_dev); ++ ++ goto err_video; ++ } ++ ++ /* ++ * needs to be done here, doing it any later, i.e. after ++ * the clocks are enabled, will make the device no more ++ * working (HW bug?) ++ */ ++ reset_control_assert(iep->resets); ++ udelay(1); ++ reset_control_deassert(iep->resets); ++ udelay(1); ++ ++ pm_runtime_set_autosuspend_delay(iep->dev, 100); ++ pm_runtime_use_autosuspend(iep->dev); ++ pm_runtime_enable(iep->dev); ++ ++ return ret; ++ ++err_video: ++ video_unregister_device(&iep->vfd); ++err_v4l2: ++ v4l2_device_unregister(&iep->v4l2_dev); ++err_put_clk: ++ pm_runtime_dont_use_autosuspend(iep->dev); ++ pm_runtime_disable(iep->dev); ++ ++return ret; ++} ++ ++static int iep_remove(struct platform_device *pdev) ++{ ++ struct rockchip_iep *iep = platform_get_drvdata(pdev); ++ ++ pm_runtime_dont_use_autosuspend(iep->dev); ++ pm_runtime_disable(iep->dev); ++ ++ v4l2_m2m_release(iep->m2m_dev); ++ video_unregister_device(&iep->vfd); ++ v4l2_device_unregister(&iep->v4l2_dev); ++ ++ return 0; ++} ++ ++static int __maybe_unused iep_runtime_suspend(struct device *dev) ++{ ++ struct rockchip_iep *iep = dev_get_drvdata(dev); ++ ++ dev_info(iep->dev, "%s\n", __func__); ++ ++ clk_disable_unprepare(iep->ahb_clk); ++ clk_disable_unprepare(iep->axi_clk); ++ ++ return 0; ++} ++ ++static int __maybe_unused iep_runtime_resume(struct device *dev) ++{ ++ struct rockchip_iep *iep; ++ int ret = 0; ++ ++ iep = dev_get_drvdata(dev); ++ ++ dev_info(iep->dev, "%s\n", __func__); ++ ++ ret = clk_prepare_enable(iep->axi_clk); ++ if (ret) { ++ dev_err(iep->dev, "Cannot enable axi clock: %d\n", ret); ++ return ret; ++ } ++ ++ ret = clk_prepare_enable(iep->ahb_clk); ++ if (ret) { ++ dev_err(iep->dev, "Cannot enable ahb clock: %d\n", ret); ++ goto err_disable_axi_clk; ++ } ++ ++ return ret; ++ ++err_disable_axi_clk: ++ clk_disable_unprepare(iep->axi_clk); ++ return ret; ++} ++ ++static const struct dev_pm_ops iep_pm_ops = { ++ SET_SYSTEM_SLEEP_PM_OPS(pm_runtime_force_suspend, ++ pm_runtime_force_resume) ++ SET_RUNTIME_PM_OPS(iep_runtime_suspend, ++ iep_runtime_resume, NULL) ++}; ++ ++static const struct of_device_id rockchip_iep_match[] = { ++ { ++ .compatible = "rockchip,rk3228-iep", ++ }, ++ {}, ++}; ++ ++MODULE_DEVICE_TABLE(of, rockchip_iep_match); ++ ++static struct platform_driver iep_pdrv = { ++ .probe = iep_probe, ++ .remove = iep_remove, ++ .driver = { ++ .name = IEP_NAME, ++ .pm = &iep_pm_ops, ++ .of_match_table = rockchip_iep_match, ++ }, ++}; ++ ++module_platform_driver(iep_pdrv); ++ ++MODULE_AUTHOR("Alex Bee "); ++MODULE_DESCRIPTION("Rockchip Image Enhancement Processor"); ++MODULE_LICENSE("GPL v2"); +diff --git a/drivers/media/platform/rockchip/iep/iep.h b/drivers/media/platform/rockchip/iep/iep.h +new file mode 100644 +index 000000000000..6f525f23627b +--- /dev/null ++++ b/drivers/media/platform/rockchip/iep/iep.h +@@ -0,0 +1,114 @@ ++/* SPDX-License-Identifier: GPL-2.0-only */ ++/* ++ * Rockchip Image Enhancement Processor (IEP) driver ++ * ++ * Copyright (C) 2020 Alex Bee ++ * ++ */ ++#ifndef __IEP_H__ ++#define __IEP_H__ ++ ++#include ++#include ++#include ++#include ++ ++#define IEP_NAME "rockchip-iep" ++ ++/* Hardware limits */ ++#define IEP_MIN_WIDTH 320U ++#define IEP_MAX_WIDTH 1920U ++ ++#define IEP_MIN_HEIGHT 240U ++#define IEP_MAX_HEIGHT 1088U ++ ++/* Hardware defaults */ ++#define IEP_DEFAULT_WIDTH 320U ++#define IEP_DEFAULT_HEIGHT 240U ++ ++//ns ++#define IEP_TIMEOUT 250000 ++ ++struct iep_fmt { ++ u32 fourcc; ++ u8 depth; ++ u8 uv_factor; ++ u8 color_swap; ++ u8 hw_format; ++}; ++ ++struct iep_frm_fmt { ++ struct iep_fmt *hw_fmt; ++ struct v4l2_pix_format pix; ++ ++ unsigned int y_stride; ++ unsigned int uv_stride; ++}; ++ ++struct iep_ctx { ++ struct v4l2_fh fh; ++ struct rockchip_iep *iep; ++ ++ struct iep_frm_fmt src_fmt; ++ struct iep_frm_fmt dst_fmt; ++ ++ struct vb2_v4l2_buffer *prev_src_buf; ++ struct vb2_v4l2_buffer *dst0_buf; ++ struct vb2_v4l2_buffer *dst1_buf; ++ ++ u32 dst_sequence; ++ u32 src_sequence; ++ ++ /* bff = bottom field first */ ++ bool field_order_bff; ++ bool field_bff; ++ ++ unsigned int dst_buffs_done; ++ ++ bool fmt_changed; ++ bool job_abort; ++}; ++ ++struct rockchip_iep { ++ struct v4l2_device v4l2_dev; ++ struct v4l2_m2m_dev *m2m_dev; ++ struct video_device vfd; ++ ++ struct device *dev; ++ ++ void __iomem *regs; ++ ++ struct clk *axi_clk; ++ struct clk *ahb_clk; ++ ++ struct reset_control *resets; ++ ++ /* vfd lock */ ++ struct mutex mutex; ++}; ++ ++static inline void iep_write(struct rockchip_iep *iep, u32 reg, u32 value) ++{ ++ writel(value, iep->regs + reg); ++}; ++ ++static inline u32 iep_read(struct rockchip_iep *iep, u32 reg) ++{ ++ return readl(iep->regs + reg); ++}; ++ ++static inline void iep_shadow_mod(struct rockchip_iep *iep, u32 reg, ++ u32 shadow_reg, u32 mask, u32 val) ++{ ++ u32 temp = iep_read(iep, shadow_reg) & ~(mask); ++ ++ temp |= val & mask; ++ iep_write(iep, reg, temp); ++}; ++ ++static inline void iep_mod(struct rockchip_iep *iep, u32 reg, u32 mask, u32 val) ++{ ++ iep_shadow_mod(iep, reg, reg, mask, val); ++}; ++ ++#endif + +From e9d4e43dc5a6fbcdff3be92e4ec40c7bb787a897 Mon Sep 17 00:00:00 2001 +From: Alex Bee +Date: Sun, 11 Oct 2020 14:48:44 +0200 +Subject: [PATCH] ARM: dts: rockchip: Add IEP node for RK322x + +Signed-off-by: Alex Bee +--- + arch/arm/boot/dts/rk322x.dtsi | 19 +++++++++++++++++-- + 1 file changed, 17 insertions(+), 2 deletions(-) + +diff --git a/arch/arm/boot/dts/rk322x.dtsi b/arch/arm/boot/dts/rk322x.dtsi +index de5727e0bc94..a2012a44421d 100644 +--- a/arch/arm/boot/dts/rk322x.dtsi ++++ b/arch/arm/boot/dts/rk322x.dtsi +@@ -781,6 +781,21 @@ rga: rga@20060000 { + power-domains = <&power RK3228_PD_VIO>; + }; + ++ iep: iep@20070000 { ++ compatible = "rockchip,rk3228-iep"; ++ reg = <0x20070000 0x800>; ++ interrupts = ; ++ interrupt-names = "iep"; ++ clocks = <&cru ACLK_IEP>, ++ <&cru HCLK_IEP>; ++ clock-names = "axi", "ahb"; ++ resets = <&cru SRST_IEP_A>, ++ <&cru SRST_IEP_H>; ++ reset-names = "axi", "ahb"; ++ power-domains = <&power RK3228_PD_VIO>; ++ iommus = <&iep_mmu>; ++ }; ++ + iep_mmu: iommu@20070800 { + compatible = "rockchip,iommu"; + reg = <0x20070800 0x100>; +@@ -788,8 +803,8 @@ iep_mmu: iommu@20070800 { + interrupt-names = "iep_mmu"; + clocks = <&cru ACLK_IEP>, <&cru HCLK_IEP>; + clock-names = "aclk", "iface"; +- iommu-cells = <0>; +- status = "disabled"; ++ #iommu-cells = <0>; ++ power-domains = <&power RK3228_PD_VIO>; + }; + + hdmi: hdmi@200a0000 { + +From e01ddeae4d23380545603195f72054a604ef45f4 Mon Sep 17 00:00:00 2001 +From: Alex Bee +Date: Wed, 14 Oct 2020 20:22:38 +0200 +Subject: [PATCH] ARM64: dts: rockchip: Add IEP node for RK3328 + +while at that also add the iep mmu and powerdomain nodes + +Signed-off-by: Alex Bee +--- + arch/arm64/boot/dts/rockchip/rk3328.dtsi | 38 ++++++++++++++++++++++++ + 1 file changed, 38 insertions(+) + +diff --git a/arch/arm64/boot/dts/rockchip/rk3328.dtsi b/arch/arm64/boot/dts/rockchip/rk3328.dtsi +index 9a7a5c1adaa8..9fce8036df9b 100644 +--- a/arch/arm64/boot/dts/rockchip/rk3328.dtsi ++++ b/arch/arm64/boot/dts/rockchip/rk3328.dtsi +@@ -336,6 +336,12 @@ pd_vpu@RK3328_PD_VPU { + reg = ; + clocks = <&cru ACLK_VPU>, <&cru HCLK_VPU>; + }; ++ pd_vio@RK3328_PD_VIO { ++ reg = ; ++ clocks = <&cru ACLK_IEP>, ++ <&cru HCLK_IEP>; ++ pm_qos = <&qos_vio>; ++ }; + }; + + reboot-mode { +@@ -740,6 +746,33 @@ vop_mmu: iommu@ff373f00 { + status = "disabled"; + }; + ++ iep: iep@ff3a0000 { ++ compatible = "rockchip,rk3328-iep", "rockchip,rk3228-iep"; ++ reg = <0x0 0xff3a0000 0x0 0x800>; ++ interrupts = ; ++ interrupt-names = "iep"; ++ clocks = <&cru ACLK_IEP>, ++ <&cru HCLK_IEP>; ++ clock-names = "axi", "ahb"; ++ resets = <&cru SRST_IEP_A>, ++ <&cru SRST_IEP_H>; ++ reset-names = "axi", "ahb"; ++ power-domains = <&power RK3328_PD_VIO>; ++ iommus = <&iep_mmu>; ++ }; ++ ++ iep_mmu: iommu@ff3a0800 { ++ compatible = "rockchip,iommu"; ++ reg = <0x0 0xff3a0800 0x0 0x40>; ++ interrupts = ; ++ interrupt-names = "iep_mmu"; ++ clocks = <&cru ACLK_IEP>, ++ <&cru HCLK_IEP>; ++ clock-names = "aclk", "iface"; ++ power-domains = <&power RK3328_PD_VIO>; ++ #iommu-cells = <0>; ++ }; ++ + hdmi: hdmi@ff3c0000 { + compatible = "rockchip,rk3328-dw-hdmi"; + reg = <0x0 0xff3c0000 0x0 0x20000>; +@@ -1046,6 +1079,11 @@ sdmmc_ext: dwmmc@ff5f0000 { + status = "disabled"; + }; + ++ qos_vio: qos@ff760080 { ++ compatible = "syscon"; ++ reg = <0x0 0xff760080 0x0 0x20>; ++ }; ++ + gic: interrupt-controller@ff811000 { + compatible = "arm,gic-400"; + #interrupt-cells = <3>; + +From d2753e5742ac64bd8969b69ad74b1eb95f61e885 Mon Sep 17 00:00:00 2001 +From: Alex Bee +Date: Wed, 14 Oct 2020 20:43:12 +0200 +Subject: [PATCH] ARM64: dts: rockchip: Add IEP node for RK3399 + +Signed-off-by: Alex Bee +--- + arch/arm64/boot/dts/rockchip/rk3399.dtsi | 17 ++++++++++++++++- + 1 file changed, 16 insertions(+), 1 deletion(-) + +diff --git a/arch/arm64/boot/dts/rockchip/rk3399.dtsi b/arch/arm64/boot/dts/rockchip/rk3399.dtsi +index 81b4b8714e3f..910cc877e23f 100644 +--- a/arch/arm64/boot/dts/rockchip/rk3399.dtsi ++++ b/arch/arm64/boot/dts/rockchip/rk3399.dtsi +@@ -1302,6 +1302,21 @@ vdec_mmu: iommu@ff660480 { + #iommu-cells = <0>; + }; + ++ iep: iep@ff670000 { ++ compatible = "rockchip,rk3399-iep", "rockchip,rk3228-iep"; ++ reg = <0x0 0xff670000 0x0 0x800>; ++ interrupts = ; ++ interrupt-names = "iep"; ++ clocks = <&cru ACLK_IEP>, ++ <&cru HCLK_IEP>; ++ clock-names = "axi", "ahb"; ++ resets = <&cru SRST_A_IEP>, ++ <&cru SRST_H_IEP>; ++ reset-names = "axi", "ahb"; ++ power-domains = <&power RK3399_PD_IEP>; ++ iommus = <&iep_mmu>; ++ }; ++ + iep_mmu: iommu@ff670800 { + compatible = "rockchip,iommu"; + reg = <0x0 0xff670800 0x0 0x40>; +@@ -1309,8 +1324,8 @@ iep_mmu: iommu@ff670800 { + interrupt-names = "iep_mmu"; + clocks = <&cru ACLK_IEP>, <&cru HCLK_IEP>; + clock-names = "aclk", "iface"; ++ power-domains = <&power RK3399_PD_IEP>; + #iommu-cells = <0>; +- status = "disabled"; + }; + + rga: rga@ff680000 { + +From ce22eb2d667873d807131360f33980e5c7459f00 Mon Sep 17 00:00:00 2001 +From: Alex Bee +Date: Wed, 14 Oct 2020 20:51:04 +0200 +Subject: [PATCH] ARM64: dts: rockchip: Add IEP node for RK3368 + +Signed-off-by: Alex Bee +--- + arch/arm64/boot/dts/rockchip/rk3368.dtsi | 15 ++++++++++++++- + 1 file changed, 14 insertions(+), 1 deletion(-) + +diff --git a/arch/arm64/boot/dts/rockchip/rk3368.dtsi b/arch/arm64/boot/dts/rockchip/rk3368.dtsi +index 3746f23dc3df..9403135881e8 100644 +--- a/arch/arm64/boot/dts/rockchip/rk3368.dtsi ++++ b/arch/arm64/boot/dts/rockchip/rk3368.dtsi +@@ -714,6 +714,20 @@ i2s_8ch: i2s-8ch@ff898000 { + status = "disabled"; + }; + ++ iep: iep@ff900000 { ++ compatible = "rockchip,rk3368-iep", "rockchip,rk3228-iep"; ++ reg = <0x0 0xff900000 0x0 0x800>; ++ interrupts = ; ++ interrupt-names = "iep"; ++ clocks = <&cru ACLK_IEP>, ++ <&cru HCLK_IEP>; ++ clock-names = "axi", "ahb"; ++ resets = <&cru SRST_IEP_AXI>, ++ <&cru SRST_IEP_AHB>; ++ reset-names = "axi", "ahb"; ++ iommus = <&iep_mmu>; ++ }; ++ + iep_mmu: iommu@ff900800 { + compatible = "rockchip,iommu"; + reg = <0x0 0xff900800 0x0 0x100>; +@@ -722,7 +736,6 @@ iep_mmu: iommu@ff900800 { + clocks = <&cru ACLK_IEP>, <&cru HCLK_IEP>; + clock-names = "aclk", "iface"; + #iommu-cells = <0>; +- status = "disabled"; + }; + + isp_mmu: iommu@ff914000 { + +From 8a9cf089ef1310522371ada40d1aa6ff6ba41da5 Mon Sep 17 00:00:00 2001 +From: Alex Bee +Date: Wed, 14 Oct 2020 20:53:56 +0200 +Subject: [PATCH] ARM: dts: rockchip: Add IEP node for RK3288 + +Signed-off-by: Alex Bee +--- + arch/arm/boot/dts/rk3288.dtsi | 17 ++++++++++++++++- + 1 file changed, 16 insertions(+), 1 deletion(-) + +diff --git a/arch/arm/boot/dts/rk3288.dtsi b/arch/arm/boot/dts/rk3288.dtsi +index 9757976d6e8a..d7aa05d7dee7 100644 +--- a/arch/arm/boot/dts/rk3288.dtsi ++++ b/arch/arm/boot/dts/rk3288.dtsi +@@ -1002,6 +1002,21 @@ crypto: cypto-controller@ff8a0000 { + status = "okay"; + }; + ++ iep: iep@ff90000 { ++ compatible = "rockchip,rk3288-iep", "rockchip,rk3228-iep"; ++ reg = <0x0 0xff900000 0x0 0x800>; ++ interrupts = ; ++ interrupt-names = "iep"; ++ clocks = <&cru ACLK_IEP>, ++ <&cru HCLK_IEP>; ++ clock-names = "axi", "ahb"; ++ resets = <&cru SRST_IEP_AXI>, ++ <&cru SRST_IEP_AHB>; ++ reset-names = "axi", "ahb"; ++ power-domains = <&power RK3288_PD_VIO>; ++ iommus = <&iep_mmu>; ++ }; ++ + iep_mmu: iommu@ff900800 { + compatible = "rockchip,iommu"; + reg = <0x0 0xff900800 0x0 0x40>; +@@ -1009,8 +1024,8 @@ iep_mmu: iommu@ff900800 { + interrupt-names = "iep_mmu"; + clocks = <&cru ACLK_IEP>, <&cru HCLK_IEP>; + clock-names = "aclk", "iface"; ++ power-domains = <&power RK3288_PD_VIO>; + #iommu-cells = <0>; +- status = "disabled"; + }; + + isp_mmu: iommu@ff914000 { diff --git a/patch/kernel/rk322x-current/01-linux-9000-rk322x-boxes.patch b/patch/kernel/rk322x-current/01-linux-9000-rk322x-box-DTs.patch similarity index 94% rename from patch/kernel/rk322x-current/01-linux-9000-rk322x-boxes.patch rename to patch/kernel/rk322x-current/01-linux-9000-rk322x-box-DTs.patch index 8c346dfdd..a3a6d76a8 100644 --- a/patch/kernel/rk322x-current/01-linux-9000-rk322x-boxes.patch +++ b/patch/kernel/rk322x-current/01-linux-9000-rk322x-box-DTs.patch @@ -1,4 +1,4 @@ -From d9e3ab544074c0a780bce1b2a165f7b1147cb473 Mon Sep 17 00:00:00 2001 +From 0a4705dcfadb06b21b05b92cdd23a7cf61b27d85 Mon Sep 17 00:00:00 2001 From: Alex Bee Date: Sun, 16 Aug 2020 23:03:12 +0200 Subject: [PATCH] WIP: ARM: dts: add RK322x box device trees @@ -6,16 +6,16 @@ Subject: [PATCH] WIP: ARM: dts: add RK322x box device trees Signed-off-by: Alex Bee --- arch/arm/boot/dts/Makefile | 4 + - arch/arm/boot/dts/rk3228a-box-h96mini.dts | 115 ++++++++ + arch/arm/boot/dts/rk3228a-box-h96mini.dts | 115 +++++++++ arch/arm/boot/dts/rk3228a-box.dts | 47 ++++ arch/arm/boot/dts/rk3228a-box.dtsi | 12 + - arch/arm/boot/dts/rk3229-box-a95xr1.dts | 57 ++++ + arch/arm/boot/dts/rk3229-box-a95xr1.dts | 57 +++++ arch/arm/boot/dts/rk3229-box.dts | 50 ++++ arch/arm/boot/dts/rk3229-box.dtsi | 13 + arch/arm/boot/dts/rk3229-cpu-opp.dtsi | 50 ++++ - arch/arm/boot/dts/rk322x-box-dcdc.dtsi | 163 +++++++++++ - arch/arm/boot/dts/rk322x-box.dtsi | 316 ++++++++++++++++++++++ - 10 files changed, 827 insertions(+) + arch/arm/boot/dts/rk322x-box-dcdc.dtsi | 163 +++++++++++++ + arch/arm/boot/dts/rk322x-box.dtsi | 282 ++++++++++++++++++++++ + 10 files changed, 793 insertions(+) create mode 100644 arch/arm/boot/dts/rk3228a-box-h96mini.dts create mode 100644 arch/arm/boot/dts/rk3228a-box.dts create mode 100644 arch/arm/boot/dts/rk3228a-box.dtsi @@ -27,10 +27,10 @@ Signed-off-by: Alex Bee create mode 100644 arch/arm/boot/dts/rk322x-box.dtsi diff --git a/arch/arm/boot/dts/Makefile b/arch/arm/boot/dts/Makefile -index 4572db3fa5ae..76e3f8916e86 100644 +index ce66ffd5a1bb..4841972313e8 100644 --- a/arch/arm/boot/dts/Makefile +++ b/arch/arm/boot/dts/Makefile -@@ -969,7 +969,11 @@ dtb-$(CONFIG_ARCH_ROCKCHIP) += \ +@@ -981,7 +981,11 @@ dtb-$(CONFIG_ARCH_ROCKCHIP) += \ rk3188-bqedison2qc.dtb \ rk3188-px3-evb.dtb \ rk3188-radxarock.dtb \ @@ -599,10 +599,10 @@ index 000000000000..34273f3ff9ae +}; diff --git a/arch/arm/boot/dts/rk322x-box.dtsi b/arch/arm/boot/dts/rk322x-box.dtsi new file mode 100644 -index 000000000000..b65f99b08366 +index 000000000000..ef5fa28d8ee9 --- /dev/null +++ b/arch/arm/boot/dts/rk322x-box.dtsi -@@ -0,0 +1,316 @@ +@@ -0,0 +1,282 @@ +// SPDX-License-Identifier: (GPL-2.0+ OR MIT) + +/dts-v1/; @@ -653,17 +653,6 @@ index 000000000000..b65f99b08366 + reg = <0x60000000 0x40000000>; + }; + -+ reserved-memory { -+ #address-cells = <1>; -+ #size-cells = <1>; -+ ranges; -+ -+ trust_reserved: trust@68400000 { -+ reg = <0x68400000 0xe00000>; -+ no-map; -+ }; -+ }; -+ + sdio_pwrseq: sdio-pwrseq { + compatible = "mmc-pwrseq-simple"; + pinctrl-names = "default"; @@ -690,29 +679,6 @@ index 000000000000..b65f99b08366 + }; +}; + -+&cpu0_opp_table { -+ -+ opp-408000000 { -+ opp-microvolt = <950000 950000 1275000>; -+ }; -+ -+ opp-600000000 { -+ opp-microvolt = <975000 975000 1275000>; -+ }; -+ -+ opp-816000000 { -+ opp-microvolt = <1000000 1000000 1275000>; -+ }; -+ -+ opp-1008000000 { -+ opp-microvolt = <1175000 1175000 1275000>; -+ }; -+ -+ opp-1200000000 { -+ opp-microvolt = <1275000 1275000 1275000>; -+ }; -+}; -+ +&cru { + assigned-clocks = <&cru PLL_GPLL>, <&cru ARMCLK>, + <&cru PLL_CPLL>, <&cru ACLK_PERI>, diff --git a/patch/kernel/rk322x-current/01-linux-9001-rk3188-rbox-DTs.patch b/patch/kernel/rk322x-current/01-linux-9001-rk3188-rbox-DTs.patch new file mode 100644 index 000000000..bd7ea1f36 --- /dev/null +++ b/patch/kernel/rk322x-current/01-linux-9001-rk3188-rbox-DTs.patch @@ -0,0 +1,799 @@ +From 4f148f80254628f7c246ca0d38c4dbef18594ca1 Mon Sep 17 00:00:00 2001 +From: Alex Bee +Date: Sun, 16 Aug 2020 23:13:44 +0200 +Subject: [PATCH] ARM: dts: add RK3188T rbox devicetrees + +Signed-off-by: Alex Bee +--- + arch/arm/boot/dts/rk3188-rbox-cs918.dts | 144 ++++++++ + arch/arm/boot/dts/rk3188-rbox-cs968.dts | 170 +++++++++ + arch/arm/boot/dts/rk3188-rbox.dtsi | 452 ++++++++++++++++++++++++ + 3 files changed, 766 insertions(+) + create mode 100644 arch/arm/boot/dts/rk3188-rbox-cs918.dts + create mode 100644 arch/arm/boot/dts/rk3188-rbox-cs968.dts + create mode 100644 arch/arm/boot/dts/rk3188-rbox.dtsi + +diff --git a/arch/arm/boot/dts/rk3188-rbox-cs918.dts b/arch/arm/boot/dts/rk3188-rbox-cs918.dts +new file mode 100644 +index 000000000000..bc701e41e010 +--- /dev/null ++++ b/arch/arm/boot/dts/rk3188-rbox-cs918.dts +@@ -0,0 +1,144 @@ ++// SPDX-License-Identifier: (GPL-2.0+ OR MIT) ++/* ++ * Copyright (c) 2020 Alex Bee ++ */ ++ ++/dts-v1/; ++#include ++#include "rk3188-rbox.dtsi" ++ ++/ { ++ model = "RK3188T CS918"; ++ ++ memory@60000000 { ++ device_type = "memory"; ++ reg = <0x60000000 0x80000000>; ++ }; ++ ++ ext_rmii: ext-rmii { ++ compatible = "fixed-clock"; ++ clock-frequency = <50000000>; ++ clock-output-names = "ext_rmii"; ++ #clock-cells = <0>; ++ }; ++ ++ gpio-keys { ++ pinctrl-names = "default"; ++ pinctrl-0 = <&pwr_key &usb_int>; ++ compatible = "gpio-keys"; ++ autorepeat; ++ ++ power { ++ gpios = <&gpio0 RK_PA4 GPIO_ACTIVE_LOW>; ++ linux,code = ; ++ label = "GPIO Key Power"; ++ linux,input-type = <1>; ++ wakeup-source; ++ debounce-interval = <100>; ++ }; ++ ++ wake_on_usb: wake-on-usb { ++ label = "Wake-on-USB"; ++ gpios = <&gpio0 RK_PA7 GPIO_ACTIVE_LOW>; ++ linux,code = ; ++ wakeup-source; ++ }; ++ }; ++ ++ gpio-leds { ++ compatible = "gpio-leds"; ++ ++ sleep { ++ label = "red"; ++ gpios = <&gpio0 RK_PA2 GPIO_ACTIVE_LOW>; ++ default-state = "off"; ++ }; ++ }; ++ ++ vcc_otg: usb-otg-regulator { ++ compatible = "regulator-fixed"; ++ enable-active-high; ++ gpio = <&gpio3 RK_PD7 GPIO_ACTIVE_HIGH>; ++ pinctrl-names = "default"; ++ pinctrl-0 = <&otg_vbus_drv>, <&usb_wifi_power>; ++ regulator-name = "otg-vbus"; ++ regulator-min-microvolt = <5000000>; ++ regulator-max-microvolt = <5000000>; ++ }; ++}; ++ ++&emac { ++ assigned-clocks = <&cru SCLK_MAC>; ++ assigned-clock-parents = <&ext_rmii>; ++ pinctrl-0 = <&emac_xfer_ext>, <&emac_mdio>, <&phy_int>; ++ pinctrl-names = "default"; ++ phy = <&phy0>; ++ phy-supply = <&vcc_rmii>; ++ status = "okay"; ++ ++ phy0: ethernet-phy@0 { ++ reg = <0x0>; ++ /* Interrupt is not connected */ ++ }; ++}; ++ ++&nfc { ++ #address-cells = <1>; ++ #size-cells = <0>; ++ ++ nand@0 { ++ reg = <0>; ++ label = "rk-nand"; ++ nand-bus-width = <8>; ++ nand-ecc-mode = "hw"; ++ nand-ecc-step-size = <1024>; ++ nand-ecc-strength = <40>; ++ nand-is-boot-medium; ++ rockchip,boot-blks = <8>; ++ rockchip,boot-ecc-strength = <40>; ++ }; ++}; ++ ++&pinctrl { ++ emac { ++ emac_xfer_ext: emac-xfer-ext { ++ rockchip,pins = <3 RK_PC0 2 &pcfg_pull_up>, /* tx_en */ ++ <3 RK_PC1 2 &pcfg_pull_up>, /* txd1 */ ++ <3 RK_PC2 2 &pcfg_pull_up>, /* txd0 */ ++ <3 RK_PC3 2 &pcfg_pull_up>, /* rxd0 */ ++ <3 RK_PC4 2 &pcfg_pull_up>, /* rxd1 */ ++ <3 RK_PC5 3 &pcfg_pull_down>, /* mac_clk_ext */ ++ <3 RK_PC6 2 &pcfg_pull_down>, /* rx_err */ ++ <3 RK_PC7 2 &pcfg_pull_down>; /* crs_dvalid */ ++ }; ++ }; ++ ++ keys { ++ pwr_key: pwr-key { ++ rockchip,pins = <0 RK_PA4 RK_FUNC_GPIO &pcfg_pull_up>; ++ }; ++ }; ++ ++ rtl8201f { ++ phy_int: phy-int { ++ rockchip,pins = <3 RK_PD2 RK_FUNC_GPIO &pcfg_pull_up>; ++ }; ++ }; ++ ++ usb { ++ usb_int: usb-int { ++ rockchip,pins = <0 RK_PA7 RK_FUNC_GPIO &pcfg_pull_up>; ++ }; ++ otg_vbus_drv: otg-vbus-drv { ++ rockchip,pins = <3 RK_PD7 RK_FUNC_GPIO &pcfg_pull_none>; ++ }; ++ usb_wifi_power: usb-wifi-power { ++ rockchip,pins = <3 RK_PA0 RK_FUNC_GPIO &pcfg_pull_up>; ++ }; ++ ++ }; ++}; ++ ++&usbphy0 { ++ vbus-supply = <&vcc_otg>; ++}; +diff --git a/arch/arm/boot/dts/rk3188-rbox-cs968.dts b/arch/arm/boot/dts/rk3188-rbox-cs968.dts +new file mode 100644 +index 000000000000..a08e368d72dc +--- /dev/null ++++ b/arch/arm/boot/dts/rk3188-rbox-cs968.dts +@@ -0,0 +1,170 @@ ++// SPDX-License-Identifier: (GPL-2.0+ OR MIT) ++/* ++ * Copyright (c) 2020 Alex Bee ++ */ ++ ++/dts-v1/; ++#include ++#include "rk3188-rbox.dtsi" ++ ++/ { ++ model = "RK3188T CS968"; ++ ++ memory@60000000 { ++ device_type = "memory"; ++ reg = <0x60000000 0x80000000>; ++ }; ++ ++ gpio-keys { ++ pinctrl-names = "default"; ++ pinctrl-0 = <&usb_int>; ++ compatible = "gpio-keys"; ++ autorepeat; ++ ++ ++ wake_on_usb: wake-on-usb { ++ label = "Wake-on-USB"; ++ gpios = <&gpio0 RK_PA7 GPIO_ACTIVE_LOW>; ++ linux,code = ; ++ wakeup-source; ++ }; ++ }; ++ ++ gpio-leds { ++ compatible = "gpio-leds"; ++ ++ blue { ++ label = "blue"; ++ gpios = <&gpio0 RK_PB6 GPIO_ACTIVE_HIGH>; ++ default-state = "on"; ++ }; ++ ++ sleep { ++ label = "red"; ++ gpios = <&gpio0 RK_PB7 GPIO_ACTIVE_HIGH>; ++ default-state = "off"; ++ }; ++ }; ++ ++ ++ sdio_pwrseq: sdio-pwrseq { ++ compatible = "mmc-pwrseq-simple"; ++ clocks = <&pcf8563>; ++ clock-names = "ext_clock"; ++ pinctrl-names = "default"; ++ pinctrl-0 = <&wifi_reg_on>; ++ reset-gpios = <&gpio3 RK_PD0 GPIO_ACTIVE_LOW>; ++ }; ++ ++ vcc_otg: usb-otg-regulator { ++ compatible = "regulator-fixed"; ++ enable-active-high; ++ gpio = <&gpio3 RK_PD5 GPIO_ACTIVE_HIGH>; ++ pinctrl-names = "default"; ++ pinctrl-0 = <&otg_vbus_drv>; ++ regulator-name = "otg-vbus"; ++ regulator-min-microvolt = <5000000>; ++ regulator-max-microvolt = <5000000>; ++ }; ++ ++}; ++ ++&mmc1 { ++ bus-width = <4>; ++ clock-frequency = <25000000>; ++ mmc-pwrseq = <&sdio_pwrseq>; ++ non-removable; ++ pinctrl-names = "default"; ++ pinctrl-0 = <&sd1_clk>, <&sd1_cmd>, ++ <&sd1_bus4>; ++ vmmc-supply = <&vcc_io>; ++ vqmmc-supply = <&vccio_wl>; ++ cap-sd-highspeed; ++ status = "okay"; ++ #address-cells = <1>; ++ #size-cells = <0>; ++ ++ brcmf: wifi@1 { ++ reg = <0x1>; ++ compatible = "brcm,bcm4329-fmac"; ++ interrupt-parent = <&gpio3>; ++ interrupts = ; ++ interrupt-names = "host-wake"; ++ pinctrl-names = "default"; ++ pinctrl-0 = <&wifi_host_wake>; ++ }; ++}; ++ ++&nfc { ++ #address-cells = <1>; ++ #size-cells = <0>; ++ ++ nand@0 { ++ reg = <0>; ++ label = "rk-nand"; ++ nand-bus-width = <8>; ++ nand-ecc-mode = "hw"; ++ nand-ecc-step-size = <1024>; ++ nand-ecc-strength = <40>; ++ nand-is-boot-medium; ++ rockchip,boot-blks = <8>; ++ rockchip,boot-ecc-strength = <40>; ++ }; ++}; ++ ++&pinctrl { ++ ap6210 { ++ bt_host_wake: bt-host-wake { ++ rockchip,pins = <0 RK_PA5 RK_FUNC_GPIO &pcfg_pull_up>; ++ }; ++ ++ bt_reg_on: bt-reg-on { ++ rockchip,pins = <3 RK_PC7 RK_FUNC_GPIO &pcfg_pull_none>; ++ }; ++ ++ /* pin hog to pull the reset high */ ++ bt_rst: bt-rst { ++ rockchip,pins = <3 RK_PD1 RK_FUNC_GPIO &pcfg_output_high>; ++ }; ++ ++ bt_wake: bt-wake { ++ rockchip,pins = <3 RK_PC6 RK_FUNC_GPIO &pcfg_pull_none>; ++ }; ++ ++ wifi_host_wake: wifi-host-wake { ++ rockchip,pins = <3 RK_PD2 RK_FUNC_GPIO &pcfg_pull_up>; ++ }; ++ ++ wifi_reg_on: wifi-reg-on { ++ rockchip,pins = <3 RK_PD0 RK_FUNC_GPIO &pcfg_pull_none>; ++ }; ++ }; ++ ++ usb { ++ usb_int: usb-int { ++ rockchip,pins = <0 RK_PA7 RK_FUNC_GPIO &pcfg_pull_up>; ++ }; ++ otg_vbus_drv: otg-vbus-drv { ++ rockchip,pins = <3 RK_PD5 RK_FUNC_GPIO &pcfg_pull_none>; ++ }; ++ }; ++}; ++ ++&uart0 { ++ pinctrl-0 = <&uart0_xfer &uart0_cts &uart0_rts>; ++ uart-has-rtscts; ++ status = "okay"; ++ ++ bluetooth { ++ compatible = "brcm,bcm43438-bt"; ++ device-wakeup-gpios = <&gpio3 RK_PC6 GPIO_ACTIVE_HIGH>; ++ host-wakeup-gpios = <&gpio0 RK_PA5 GPIO_ACTIVE_HIGH>; ++ shutdown-gpios = <&gpio3 RK_PC7 GPIO_ACTIVE_HIGH>; ++ pinctrl-names = "default"; ++ pinctrl-0 = <&bt_host_wake &bt_reg_on &bt_rst &bt_wake>; ++ }; ++}; ++ ++&usbphy0 { ++ vbus-supply = <&vcc_otg>; ++}; +diff --git a/arch/arm/boot/dts/rk3188-rbox.dtsi b/arch/arm/boot/dts/rk3188-rbox.dtsi +new file mode 100644 +index 000000000000..7dcd4d2f19e6 +--- /dev/null ++++ b/arch/arm/boot/dts/rk3188-rbox.dtsi +@@ -0,0 +1,452 @@ ++// SPDX-License-Identifier: (GPL-2.0+ OR MIT) ++/* ++ * Copyright (c) 2020 Alex Bee ++ */ ++ ++/dts-v1/; ++#include ++#include "rk3188.dtsi" ++ ++/ { ++ hdmi-out { ++ compatible = "hdmi-connector"; ++ type = "c"; ++ ++ port { ++ hdmi_con_out: endpoint { ++ remote-endpoint = <&it66121_out>; ++ }; ++ }; ++ }; ++ ++ hdmi-sound { ++ compatible = "simple-audio-card"; ++ simple-audio-card,name = "HDMI"; ++ simple-audio-card,format = "i2s"; ++ simple-audio-card,mclk-fs = <128>; ++ ++ simple-audio-card,cpu { ++ sound-dai = <&i2s0>; ++ }; ++ ++ simple-audio-card,codec { ++ sound-dai = <&it66121>; ++ }; ++ }; ++ ++ ir_recv: gpio-ir-receiver { ++ compatible = "gpio-ir-receiver"; ++ gpios = <&gpio0 RK_PB2 GPIO_ACTIVE_LOW>; ++ pinctrl-names = "default"; ++ pinctrl-0 = <&ir_recv_pin>; ++ }; ++ ++ spdif-sound { ++ compatible = "simple-audio-card"; ++ simple-audio-card,name = "SPDIF"; ++ #address-cells = <1>; ++ #size-cells = <0>; ++ ++ simple-audio-card,dai-link@0 { ++ reg = <0>; ++ cpu { ++ sound-dai = <&spdif>; ++ }; ++ codec { ++ sound-dai = <&spdif_dit>; ++ }; ++ }; ++ }; ++ ++ spdif_dit: spdif-dit { ++ compatible = "linux,spdif-dit"; ++ #sound-dai-cells = <0>; ++ }; ++ ++ ++ vcc_host: usb-host-regulator { ++ compatible = "regulator-fixed"; ++ enable-active-high; ++ gpio = <&gpio0 RK_PA3 GPIO_ACTIVE_HIGH>; ++ pinctrl-names = "default"; ++ pinctrl-0 = <&host_vbus_drv>; ++ regulator-name = "host-pwr"; ++ regulator-min-microvolt = <5000000>; ++ regulator-max-microvolt = <5000000>; ++ }; ++ ++ vcc_sd0: sdmmc-regulator { ++ compatible = "regulator-fixed"; ++ regulator-name = "sdmmc-supply"; ++ regulator-min-microvolt = <3300000>; ++ regulator-max-microvolt = <3300000>; ++ gpio = <&gpio3 RK_PA1 GPIO_ACTIVE_LOW>; ++ pinctrl-names = "default"; ++ pinctrl-0 = <&sdmmc_pwr>; ++ startup-delay-us = <100000>; ++ vin-supply = <&vcc_io>; ++ }; ++ ++ vsys: vsys-regulator { ++ compatible = "regulator-fixed"; ++ regulator-name = "vsys"; ++ regulator-min-microvolt = <5000000>; ++ regulator-max-microvolt = <5000000>; ++ regulator-boot-on; ++ }; ++}; ++ ++&cpu0 { ++ cpu-supply = <&vdd_arm>; ++}; ++ ++&cpu1 { ++ cpu-supply = <&vdd_arm>; ++}; ++ ++&cpu2 { ++ cpu-supply = <&vdd_arm>; ++}; ++ ++&cpu3 { ++ cpu-supply = <&vdd_arm>; ++}; ++ ++&cru { ++ ++ assigned-clocks = <&cru PLL_GPLL>, <&cru PLL_CPLL>, ++ <&cru ACLK_CPU>, ++ <&cru HCLK_CPU>, <&cru PCLK_CPU>, ++ <&cru ACLK_PERI>, <&cru HCLK_PERI>, ++ <&cru PCLK_PERI>, <&cru ACLK_LCDC0>, ++ <&cru ACLK_LCDC1>; ++ assigned-clock-rates = <594000000>, <600000000>, ++ <297000000>, ++ <148500000>, <74250000>, ++ <297000000>, <148500000>, ++ <74250000>, <297000000>, ++ <297000000>; ++}; ++ ++&gpu { ++ assigned-clocks = <&cru ACLK_GPU>; ++ assigned-clock-rates = <200000000>; ++ assigned-clocks-parent = <&cru PLL_CPLL>; ++ mali-supply = <&vdd_log>; ++ status = "okay"; ++}; ++ ++/* ++ * since vdd_log also supplies other SoC components which ++ * do not have a devfreq driver (yet), we have to make sure, ++ * voltage is at least 1050000 mV ++ */ ++ ++&gpu_opp_table { ++ opp-133000000 { ++ opp-microvolt = <1050000>; ++ }; ++ opp-200000000 { ++ opp-microvolt = <1050000>; ++ }; ++ opp-266000000 { ++ opp-microvolt = <1050000>; ++ }; ++}; ++ ++&i2c1 { ++ clock-frequency = <400000>; ++ status = "okay"; ++ #address-cells = <1>; ++ #size-cells = <0>; ++ ++ pcf8563: rtc@51 { ++ compatible = "nxp,pcf8563"; ++ reg = <0x51>; ++ interrupt-parent = <&gpio0>; ++ interrupts = ; ++ pinctrl-names = "default"; ++ pinctrl-0 = <&rtc_int>; ++ #clock-cells = <0>; ++ clock-output-names = "xin32k"; ++ }; ++ ++ act8846: act8846@5a { ++ compatible = "active-semi,act8846"; ++ reg = <0x5a>; ++ status = "okay"; ++ system-power-controller; ++ ++ pinctrl-names = "default"; ++ pinctrl-0 = <&dvs0_ctl &pmic_int &power_on>; ++ ++ vp1-supply = <&vsys>; ++ vp2-supply = <&vsys>; ++ vp3-supply = <&vsys>; ++ vp4-supply = <&vsys>; ++ inl1-supply = <&vcc_io>; ++ inl2-supply = <&vsys>; ++ inl3-supply = <&vsys>; ++ ++ regulators { ++ vcc_ddr: REG1 { ++ regulator-name = "VCC_DDR"; ++ regulator-min-microvolt = <1200000>; ++ regulator-max-microvolt = <1200000>; ++ regulator-always-on; ++ }; ++ ++ vdd_log: REG2 { ++ regulator-name = "VDD_LOG"; ++ regulator-min-microvolt = <1000000>; ++ regulator-max-microvolt = <1250000>; ++ regulator-always-on; ++ }; ++ ++ vdd_arm: REG3 { ++ regulator-name = "VDD_ARM"; ++ regulator-min-microvolt = <875000>; ++ regulator-max-microvolt = <1350000>; ++ regulator-always-on; ++ }; ++ ++ vcc_io: REG4 { ++ regulator-name = "VCC_IO"; ++ regulator-min-microvolt = <3300000>; ++ regulator-max-microvolt = <3300000>; ++ regulator-always-on; ++ }; ++ ++ vdd_10: REG5 { ++ regulator-name = "VDD_10"; ++ regulator-min-microvolt = <1000000>; ++ regulator-max-microvolt = <1000000>; ++ regulator-always-on; ++ }; ++ ++ vdd_hdmi: REG6 { ++ regulator-name = "VDD_HDMI"; ++ regulator-min-microvolt = <1200000>; ++ regulator-max-microvolt = <1200000>; ++ regulator-always-on; ++ }; ++ ++ vcc18: REG7 { ++ regulator-name = "VCC_18"; ++ regulator-min-microvolt = <1800000>; ++ regulator-max-microvolt = <1800000>; ++ regulator-always-on; ++ }; ++ ++ vcca_33: REG8 { ++ regulator-name = "VCCA_33"; ++ regulator-min-microvolt = <3300000>; ++ regulator-max-microvolt = <3300000>; ++ regulator-always-on; ++ }; ++ ++ vcc_rmii: REG9 { ++ regulator-name = "VCC_RMII"; ++ regulator-min-microvolt = <3300000>; ++ regulator-max-microvolt = <3300000>; ++ }; ++ ++ vccio_wl: REG10 { ++ regulator-name = "VCCIO_WL"; ++ regulator-min-microvolt = <3300000>; ++ regulator-max-microvolt = <3300000>; ++ }; ++ ++ vcc_18: REG11 { ++ regulator-name = "VCC18_IO"; ++ regulator-min-microvolt = <1800000>; ++ regulator-max-microvolt = <1800000>; ++ regulator-always-on; ++ }; ++ ++ vcc28: REG12 { ++ regulator-name = "VCC_28"; ++ regulator-min-microvolt = <2800000>; ++ regulator-max-microvolt = <2800000>; ++ regulator-always-on; ++ }; ++ }; ++ }; ++}; ++ ++&i2c2 { ++ clock-frequency = <400000>; ++ status = "okay"; ++ ++ it66121: it-66121@4c { ++ compatible = "ite,it66121fn"; ++ pinctrl-names = "default"; ++ pinctrl-0 = <&hdmi_rst &it66121_int>; ++ vcn33-supply = <&vcca_33>; ++ vcn18-supply = <&vcc_18>; ++ vrf12-supply = <&vdd_hdmi>; ++ reset-gpios = <&gpio2 RK_PB2 GPIO_ACTIVE_HIGH>; ++ interrupt-parent = <&gpio2>; ++ interrupts = ; ++ reg = <0x4c>; ++ #sound-dai-cells = <0>; ++ ++ ports { ++ #address-cells = <1>; ++ #size-cells = <0>; ++ ++ port@0 { ++ reg = <0>; ++ #address-cells = <1>; ++ #size-cells = <0>; ++ ++ it66121_in: endpoint@0 { ++ reg = <0>; ++ remote-endpoint = <&vop1_out_rgb24>; ++ }; ++ }; ++ ++ port@1 { ++ reg = <1>; ++ #address-cells = <1>; ++ #size-cells = <0>; ++ ++ it66121_out: endpoint@0 { ++ reg = <0>; ++ remote-endpoint = <&hdmi_con_out>; ++ }; ++ }; ++ }; ++ }; ++}; ++ ++&i2s0 { ++ status = "okay"; ++}; ++ ++&mmc0 { ++ status = "okay"; ++ pinctrl-names = "default"; ++ pinctrl-0 = <&sd0_clk>, <&sd0_cmd>, ++ <&sd0_cd>, <&sd0_bus4>; ++ vmmc-supply = <&vcc_sd0>; ++ bus-width = <4>; ++ cap-mmc-highspeed; ++ cap-sd-highspeed; ++}; ++ ++&pinctrl { ++ pcfg_output_high: pcfg-output-high { ++ output-high; ++ }; ++ ++ pcfg_output_low: pcfg-output-low { ++ output-low; ++ }; ++ ++ pcfg_pull_default: pcfg_pull_default { ++ bias-pull-pin-default; ++ }; ++ ++ pcfg_pull_none_12ma: pcfg-pull-none-12ma { ++ bias-disable; ++ drive-strength = <12>; ++ }; ++ ++ act8846 { ++ dvs0_ctl: act8846-dvs0-ctl { ++ rockchip,pins = <3 RK_PD3 RK_FUNC_GPIO &pcfg_output_low>; ++ }; ++ ++ pmic_int: pmic-int { ++ rockchip,pins = <0 RK_PB3 RK_FUNC_GPIO &pcfg_pull_up>; ++ }; ++ }; ++ ++ keys { ++ pwr_hold: pwr-hold { ++ rockchip,pins = <0 RK_PA0 RK_FUNC_GPIO &pcfg_pull_up>; ++ }; ++ }; ++ ++ hdmi { ++ it66121_int: hdmi-int { ++ rockchip,pins = <2 RK_PD6 RK_FUNC_GPIO &pcfg_pull_up>; ++ }; ++ hdmi_rst: hdmi-rst { ++ rockchip,pins = <3 RK_PB2 RK_FUNC_GPIO &pcfg_pull_none>; ++ }; ++ }; ++ ++ ir-receiver { ++ ir_recv_pin: ir-recv-pin { ++ rockchip,pins = <0 RK_PB2 RK_FUNC_GPIO &pcfg_pull_none>; ++ }; ++ }; ++ ++ pcf8563 { ++ rtc_int: rtc-int { ++ rockchip,pins = <0 RK_PB5 RK_FUNC_GPIO &pcfg_pull_up>; ++ }; ++ }; ++ ++ power { ++ power_on: power-on { ++ rockchip,pins = <0 RK_PA0 RK_FUNC_GPIO &pcfg_pull_up>; ++ }; ++ }; ++ ++ sd0 { ++ sdmmc_pwr: sdmmc-pwr { ++ rockchip,pins = <3 RK_PA1 RK_FUNC_GPIO &pcfg_pull_none>; ++ }; ++ }; ++ ++ usb { ++ host_vbus_drv: host-vbus-drv { ++ rockchip,pins = <0 RK_PA3 RK_FUNC_GPIO &pcfg_pull_none>; ++ }; ++ }; ++}; ++ ++&spdif { ++ status = "okay"; ++}; ++ ++&uart2 { ++ status = "okay"; ++}; ++ ++&usbphy { ++ status = "okay"; ++}; ++ ++&usbphy1 { ++ vbus-supply = <&vcc_host>; ++}; ++ ++&usb_otg { ++ status = "okay"; ++}; ++ ++&usb_host { ++ status = "okay"; ++}; ++ ++&vop1 { ++ pinctrl-names = "default"; ++ pinctrl-0 = <&lcdc1_dclk &lcdc1_den &lcdc1_hsync ++ &lcdc1_vsync &lcdc1_rgb24>; ++ status = "okay"; ++}; ++ ++&vop1_out { ++ vop1_out_rgb24: endpoint@0 { ++ reg = <0>; ++ remote-endpoint = <&it66121_in>; ++ }; ++}; ++ ++&wdt { ++ status = "okay"; ++}; diff --git a/patch/kernel/rk322x-current/01-linux-9002-rk3066a-rbox-DTs.patch b/patch/kernel/rk322x-current/01-linux-9002-rk3066a-rbox-DTs.patch new file mode 100644 index 000000000..c4674c426 --- /dev/null +++ b/patch/kernel/rk322x-current/01-linux-9002-rk3066a-rbox-DTs.patch @@ -0,0 +1,1060 @@ +From c4ef14ce4c3290377aae77ee04c0134523a64abf Mon Sep 17 00:00:00 2001 +From: Alex Bee +Date: Mon, 14 Dec 2020 16:42:05 +0100 +Subject: [PATCH] ARM: dts: add RK3066a rbox devicetrees + +Signed-off-by: Alex Bee +--- + .../boot/dts/rk3066a-rbox-ammery-stick.dts | 456 ++++++++++++++ + arch/arm/boot/dts/rk3066a-rbox-minix-x5.dts | 579 ++++++++++++++++++ + 2 files changed, 1035 insertions(+) + create mode 100644 arch/arm/boot/dts/rk3066a-rbox-ammery-stick.dts + create mode 100644 arch/arm/boot/dts/rk3066a-rbox-minix-x5.dts + +diff --git a/arch/arm/boot/dts/rk3066a-rbox-ammery-stick.dts b/arch/arm/boot/dts/rk3066a-rbox-ammery-stick.dts +new file mode 100644 +index 000000000000..ddb8459a760c +--- /dev/null ++++ b/arch/arm/boot/dts/rk3066a-rbox-ammery-stick.dts +@@ -0,0 +1,456 @@ ++// SPDX-License-Identifier: (GPL-2.0+ OR MIT) ++/* ++ * Copyright (c) 2020 Alex Bee ++ */ ++ ++/dts-v1/; ++#include "rk3066a.dtsi" ++ ++/ { ++ model = "RK3066a ammery HDMI stick"; ++ compatible = "rockchip,rk3066a"; ++ ++ memory@60000000 { ++ device_type = "memory"; ++ reg = <0x60000000 0x40000000>; ++ }; ++ ++ /* ++ * We have to set this high voltage for all gpu-freqs ++ * in order to get 1,6 GHz CPU rate working at all times ++ */ ++ gpu_opp_table: opp-table2 { ++ compatible = "operating-points-v2"; ++ ++ opp-100000000 { ++ opp-hz = /bits/ 64 <100000000>; ++ opp-microvolt = <1300000>; ++ }; ++ ++ opp-200000000 { ++ opp-hz = /bits/ 64 <200000000>; ++ opp-microvolt = <1300000>; ++ }; ++ opp-400000000 { ++ opp-hz = /bits/ 64 <400000000>; ++ opp-microvolt = <1300000>; ++ }; ++ }; ++ ++ hdmi_con { ++ compatible = "hdmi-connector"; ++ type = "a"; ++ ++ port { ++ hdmi_con_in: endpoint { ++ remote-endpoint = <&hdmi_out_con>; ++ }; ++ }; ++ }; ++ ++ sdio_pwrseq: sdio-pwrseq { ++ compatible = "mmc-pwrseq-simple"; ++ clocks = <&xin32k>; ++ clock-names = "ext_clock"; ++ pinctrl-names = "default"; ++ pinctrl-0 = <&wifi_reg_on>; ++ reset-gpios = <&gpio3 RK_PD0 GPIO_ACTIVE_LOW>; ++ }; ++ ++ vdd_log: vdd-log { ++ compatible = "pwm-regulator"; ++ pwms = <&pwm3 0 5000>; ++ regulator-name = "vdd_log"; ++ regulator-min-microvolt = <890000>; ++ regulator-max-microvolt = <1400000>; ++ regulator-ramp-delay = <4000>; ++ pwm-dutycycle-range = <100 0>; ++ vin-supply = <&vsys>; ++ regulator-always-on; ++ regulator-boot-on; ++ }; ++ ++ vsys: vsys-regulator { ++ compatible = "regulator-fixed"; ++ regulator-name = "vsys"; ++ regulator-min-microvolt = <5000000>; ++ regulator-max-microvolt = <5000000>; ++ regulator-always-on; ++ regulator-boot-on; ++ }; ++ ++ vcc_sd: sdmmc-regulator { ++ compatible = "regulator-fixed"; ++ gpio = <&gpio3 RK_PA7 GPIO_ACTIVE_LOW>; ++ pinctrl-names = "default"; ++ pinctrl-0 = <&sdmmc_pwr>; ++ regulator-name = "vcc_sd"; ++ regulator-min-microvolt = <3300000>; ++ regulator-max-microvolt = <3300000>; ++ startup-delay-us = <100000>; ++ vin-supply = <&vcc_io>; ++ }; ++ ++ vcc_host: usb-host-regulator { ++ compatible = "regulator-fixed"; ++ enable-active-high; ++ gpio = <&gpio0 RK_PA6 GPIO_ACTIVE_HIGH>; ++ pinctrl-names = "default"; ++ pinctrl-0 = <&host_drv>; ++ regulator-name = "host-pwr"; ++ regulator-min-microvolt = <5000000>; ++ regulator-max-microvolt = <5000000>; ++ regulator-always-on; ++ vin-supply = <&vsys>; ++ }; ++ ++ vcc_otg: usb-otg-regulator { ++ compatible = "regulator-fixed"; ++ enable-active-high; ++ gpio = <&gpio0 RK_PA5 GPIO_ACTIVE_HIGH>; ++ pinctrl-names = "default"; ++ pinctrl-0 = <&otg_drv>; ++ regulator-name = "vcc_otg"; ++ regulator-min-microvolt = <5000000>; ++ regulator-max-microvolt = <5000000>; ++ regulator-always-on; ++ vin-supply = <&vsys>; ++ }; ++ ++ /* delivered from tps65910 pmic RTC, ++ * but there is no clock output in ++ * the driver ++ */ ++ xin32k: xin-32k { ++ compatible = "fixed-clock"; ++ clock-frequency = <32768>; ++ #clock-cells = <0>; ++ clock-output-names = "xin32k"; ++ }; ++}; ++ ++&cpu0_opp_table { ++ opp-1608000000 { ++ status = "okay"; ++ }; ++}; ++ ++&cpu0 { ++ cpu-supply = <&vdd_arm>; ++}; ++ ++&cpu1 { ++ cpu-supply = <&vdd_arm>; ++}; ++ ++&cru { ++ assigned-clocks = <&cru PLL_CPLL>, <&cru PLL_GPLL>, ++ <&cru ACLK_CPU>, <&cru HCLK_CPU>, ++ <&cru PCLK_CPU>, <&cru ACLK_PERI>, ++ <&cru HCLK_PERI>, <&cru PCLK_PERI>, ++ <&cru ACLK_LCDC0>, <&cru ACLK_LCDC1>; ++ assigned-clock-rates = <594000000>, <1200000000>, ++ <300000000>, <150000000>, ++ <75000000>, <300000000>, ++ <150000000>, <75000000>, ++ <297000000>, <297000000>; ++}; ++ ++&gpu { ++ operating-points-v2 = <&gpu_opp_table>; ++ mali-supply = <&vdd_log>; ++ status = "okay"; ++}; ++ ++&hdmi { ++ status = "okay"; ++}; ++ ++&hdmi_in_vop1 { ++ status = "disabled"; ++}; ++ ++&hdmi_out { ++ hdmi_out_con: endpoint { ++ remote-endpoint = <&hdmi_con_in>; ++ }; ++}; ++ ++&hdmi_sound { ++ status = "okay"; ++}; ++ ++&i2c1 { ++ status = "okay"; ++ ++ tps: tps@2d { ++ reg = <0x2d>; ++ interrupt-parent = <&gpio6>; ++ interrupts = ; ++ pinctrl-names = "default"; ++ pinctrl-0 = <&pmic_int &pwr_hold>; ++ ++ vcc1-supply = <&vsys>; ++ vcc2-supply = <&vsys>; ++ vcc3-supply = <&vsys>; ++ vcc4-supply = <&vsys>; ++ vcc5-supply = <&vcc_io>; ++ vcc6-supply = <&vcc_io>; ++ vcc7-supply = <&vsys>; ++ vccio-supply = <&vsys>; ++ ++ regulators { ++ vcc_rtc: regulator@0 { ++ regulator-name = "vcc_rtc"; ++ regulator-always-on; ++ }; ++ ++ vcc_io: regulator@1 { ++ regulator-name = "vcc_io"; ++ regulator-min-microvolt = <3300000>; ++ regulator-max-microvolt = <3300000>; ++ regulator-always-on; ++ regulator-boot-on; ++ }; ++ ++ vdd_arm: regulator@2 { ++ regulator-name = "vdd_arm"; ++ regulator-min-microvolt = <600000>; ++ regulator-max-microvolt = <1500000>; ++ regulator-always-on; ++ regulator-boot-on; ++ }; ++ ++ vcc_ddr: regulator@3 { ++ regulator-name = "vcc_ddr"; ++ regulator-min-microvolt = <600000>; ++ regulator-max-microvolt = <1500000>; ++ regulator-always-on; ++ regulator-boot-on; ++ }; ++ ++ vcc18: regulator@5 { ++ regulator-name = "vcc18"; ++ regulator-min-microvolt = <1800000>; ++ regulator-max-microvolt = <1800000>; ++ regulator-always-on; ++ }; ++ ++ vdd_11: regulator@6 { ++ regulator-name = "vdd_11"; ++ regulator-min-microvolt = <1100000>; ++ regulator-max-microvolt = <1100000>; ++ regulator-always-on; ++ }; ++ ++ vcc_25: regulator@7 { ++ regulator-name = "vcc_25"; ++ regulator-min-microvolt = <2500000>; ++ regulator-max-microvolt = <2500000>; ++ regulator-always-on; ++ }; ++ ++ vccio_wl: regulator@8 { ++ regulator-name = "vccio_wl"; ++ regulator-min-microvolt = <1800000>; ++ regulator-max-microvolt = <1800000>; ++ regulator-boot-on; ++ }; ++ ++ vcc25_hdmi: regulator@9 { ++ regulator-name = "vcc25_hdmi"; ++ regulator-min-microvolt = <2500000>; ++ regulator-max-microvolt = <2500000>; ++ regulator-always-on; ++ }; ++ ++ vcca_33: regulator@10 { ++ regulator-name = "vcca_33"; ++ regulator-min-microvolt = <3300000>; ++ regulator-max-microvolt = <3300000>; ++ regulator-boot-on; ++ regulator-always-on; ++ }; ++ ++ vcc_rmii: regulator@11 { ++ regulator-name = "vcc_rmii"; ++ regulator-min-microvolt = <3300000>; ++ regulator-max-microvolt = <3300000>; ++ }; ++ ++ vcc28_cif: regulator@12 { ++ regulator-name = "vcc28_cif"; ++ regulator-min-microvolt = <2800000>; ++ regulator-max-microvolt = <2800000>; ++ }; ++ }; ++ }; ++}; ++ ++#include "tps65910.dtsi" ++ ++&i2s0 { ++ status = "okay"; ++}; ++ ++&mmc0 { ++ bus-width = <4>; ++ disable-wp; ++ pinctrl-names = "default"; ++ pinctrl-0 = <&sd0_clk>, <&sd0_cmd>, <&sd0_cd>, <&sd0_bus4>; ++ vmmc-supply = <&vcc_sd>; ++ cap-mmc-highspeed; ++ cap-sd-highspeed; ++ status = "okay"; ++}; ++ ++&mmc1 { ++ bus-width = <4>; ++ clock-frequency = <50000000>; ++ mmc-pwrseq = <&sdio_pwrseq>; ++ non-removable; ++ pinctrl-names = "default"; ++ pinctrl-0 = <&sd1_clk>, <&sd1_cmd>, <&sd1_bus4>; ++ vmmc-supply = <&vcc_io>; ++ vqmmc-supply = <&vccio_wl>; ++ cap-mmc-highspeed; ++ cap-sd-highspeed; ++ status = "okay"; ++ #address-cells = <1>; ++ #size-cells = <0>; ++ ++ /* ++ * RK903 is compatible with Ampak AP6330 ++ * except: 2.4 GHz channels only ++ */ ++ wifi@0 { ++ reg = <0>; ++ compatible = "brcm,bcm4329-fmac"; ++ interrupt-parent = <&gpio3>; ++ interrupts = ; ++ interrupt-names = "host-wake"; ++ pinctrl-names = "default"; ++ pinctrl-0 = <&wifi_host_wake>; ++ }; ++}; ++ ++&pinctrl { ++ pcfg_output_high: pcfg-output-high { ++ output-high; ++ }; ++ ++ usb { ++ host_drv: host-drv { ++ rockchip,pins = <0 RK_PA6 RK_FUNC_GPIO &pcfg_pull_default>; ++ }; ++ ++ otg_drv: otg-drv { ++ rockchip,pins = <0 RK_PA5 RK_FUNC_GPIO &pcfg_pull_default>; ++ }; ++ ++ }; ++ ++ rk903 { ++ bt_host_wake: bt-host-wake { ++ rockchip,pins = <6 RK_PA7 RK_FUNC_GPIO &pcfg_pull_default>; ++ }; ++ ++ bt_reg_on: bt-reg-on { ++ rockchip,pins = <3 RK_PC7 RK_FUNC_GPIO &pcfg_pull_none>; ++ }; ++ ++ bt_rst: bt-rst { ++ rockchip,pins = <3 RK_PD1 RK_FUNC_GPIO &pcfg_output_high>; ++ }; ++ ++ bt_wake: bt-wake { ++ rockchip,pins = <3 RK_PC6 RK_FUNC_GPIO &pcfg_pull_none>; ++ }; ++ ++ wifi_host_wake: wifi-host-wake { ++ rockchip,pins = <3 RK_PD2 RK_FUNC_GPIO &pcfg_pull_default>; ++ }; ++ ++ wifi_reg_on: wifi-reg-on { ++ rockchip,pins = <3 RK_PD0 RK_FUNC_GPIO &pcfg_pull_none>; ++ }; ++ }; ++ ++ sdmmc { ++ sdmmc_pwr: sdmmc-pwr { ++ rockchip,pins = <3 RK_PA7 RK_FUNC_GPIO &pcfg_pull_default>; ++ }; ++ }; ++ ++ tps { ++ pmic_int: pmic-int { ++ rockchip,pins = <6 RK_PA4 RK_FUNC_GPIO &pcfg_pull_default>; ++ }; ++ ++ pwr_hold: pwr-hold { ++ rockchip,pins = <6 RK_PB0 RK_FUNC_GPIO &pcfg_output_high>; ++ }; ++ }; ++}; ++ ++&pwm3 { ++ status = "okay"; ++}; ++ ++&uart0 { ++ pinctrl-names = "default"; ++ pinctrl-0 = <&uart0_xfer>, <&uart0_cts>, ++ <&uart0_rts>; ++ uart-has-rtscts; ++ status = "okay"; ++ #address-cells = <1>; ++ #size-cells = <0>; ++ ++ /* ++ * BCM4330B2 patch is needed, .i.e. a ++ * BCM4330B1 with 26 MHz XTAL config ++ */ ++ bluetooth@0 { ++ reg = <0>; ++ compatible = "brcm,bcm43438-bt"; ++ clocks = <&xin32k>; ++ clock-names = "lpo"; ++ host-wakeup-gpios = <&gpio6 RK_PA7 GPIO_ACTIVE_HIGH>; ++ device-wakeup-gpios = <&gpio3 RK_PC6 GPIO_ACTIVE_HIGH>; ++ shutdown-gpios = <&gpio3 RK_PC7 GPIO_ACTIVE_HIGH>; ++ pinctrl-names = "default"; ++ pinctrl-0 = <&bt_host_wake>, <&bt_reg_on>, ++ <&bt_rst>, <&bt_wake>; ++ vbat-supply = <&vcc_io>; ++ vddio-supply = <&vccio_wl>; ++ }; ++}; ++ ++&uart2 { ++ status = "okay"; ++}; ++ ++&usb_host { ++ status = "okay"; ++}; ++ ++&usbphy { ++ status = "okay"; ++}; ++ ++&usb_otg { ++ status = "okay"; ++}; ++ ++&tsadc { ++ vref-supply = <&vcc_25>; ++ status = "okay"; ++}; ++ ++&vop0 { ++ status = "okay"; ++}; ++ ++&wdt { ++ status = "okay"; ++}; +diff --git a/arch/arm/boot/dts/rk3066a-rbox-minix-x5.dts b/arch/arm/boot/dts/rk3066a-rbox-minix-x5.dts +new file mode 100644 +index 000000000000..6f24f8b87b32 +--- /dev/null ++++ b/arch/arm/boot/dts/rk3066a-rbox-minix-x5.dts +@@ -0,0 +1,579 @@ ++// SPDX-License-Identifier: (GPL-2.0+ OR MIT) ++/* ++ * Copyright (c) 2020 Alex Bee ++ */ ++ ++/dts-v1/; ++#include ++#include "rk3066a.dtsi" ++ ++/ { ++ model = "MiniX X5"; ++ compatible = "minix,x5", "rockchip,rk3066a"; ++ ++ memory@60000000 { ++ device_type = "memory"; ++ reg = <0x60000000 0x40000000>; ++ }; ++ ++ /* ++ * We have to set this high voltage for all gpu-freqs ++ * in order to get 1,6 GHz CPU rate working at all times ++ */ ++ gpu_opp_table: opp-table2 { ++ compatible = "operating-points-v2"; ++ ++ opp-100000000 { ++ opp-hz = /bits/ 64 <100000000>; ++ opp-microvolt = <1300000>; ++ }; ++ ++ opp-200000000 { ++ opp-hz = /bits/ 64 <200000000>; ++ opp-microvolt = <1300000>; ++ }; ++ opp-400000000 { ++ opp-hz = /bits/ 64 <400000000>; ++ opp-microvolt = <1300000>; ++ }; ++ }; ++ ++ hdmi_con { ++ compatible = "hdmi-connector"; ++ type = "a"; ++ ++ port { ++ hdmi_con_in: endpoint { ++ remote-endpoint = <&hdmi_out_con>; ++ }; ++ }; ++ }; ++ ++ ir-receiver { ++ compatible = "gpio-ir-receiver"; ++ gpios = <&gpio6 RK_PA1 GPIO_ACTIVE_LOW>; ++ pinctrl-names = "default"; ++ pinctrl-0 = <&ir_int>; ++ }; ++ ++ gpio-keys { ++ compatible = "gpio-keys"; ++ ++ power { ++ wakeup-source; ++ gpios = <&gpio6 RK_PA2 GPIO_ACTIVE_LOW>; ++ label = "GPIO Power"; ++ linux,code = ; ++ pinctrl-names = "default"; ++ pinctrl-0 = <&pwr_key>; ++ }; ++ }; ++ ++ sound { ++ compatible = "simple-audio-card"; ++ simple-audio-card,format = "i2s"; ++ simple-audio-card,name = "rockchip,alc5631-codec"; ++ simple-audio-card,mclk-fs = <256>; ++ simple-audio-card,widgets = ++ "Microphone", "Microphone Jack", ++ "Headphone", "Headphone Jack"; ++ simple-audio-card,routing = ++ "MIC1", "Microphone Jack", ++ "MIC2", "Microphone Jack", ++ "Headphone Jack", "HPOL", ++ "Headphone Jack", "HPOR"; ++ ++ simple-audio-card,cpu { ++ sound-dai = <&i2s1>; ++ }; ++ ++ simple-audio-card,codec { ++ sound-dai = <&alc5631>; ++ }; ++ }; ++ ++ spdif-sound { ++ compatible = "simple-audio-card"; ++ simple-audio-card,name = "SPDIF"; ++ #address-cells = <1>; ++ #size-cells = <0>; ++ ++ simple-audio-card,dai-link@0 { ++ reg = <0>; ++ cpu { ++ sound-dai = <&spdif>; ++ }; ++ codec { ++ sound-dai = <&spdif_dit>; ++ }; ++ }; ++ }; ++ ++ spdif_dit: spdif-dit { ++ compatible = "linux,spdif-dit"; ++ #sound-dai-cells = <0>; ++ }; ++ ++ ++ sdio_pwrseq: sdio-pwrseq { ++ compatible = "mmc-pwrseq-simple"; ++ clocks = <&xin32k>; ++ clock-names = "ext_clock"; ++ pinctrl-names = "default"; ++ pinctrl-0 = <&wifi_reg_on>; ++ reset-gpios = <&gpio3 RK_PD0 GPIO_ACTIVE_LOW>; ++ }; ++ ++ vdd_log: vdd-log { ++ compatible = "pwm-regulator"; ++ pwms = <&pwm3 0 5000>; ++ regulator-name = "vdd_log"; ++ regulator-min-microvolt = <890000>; ++ regulator-max-microvolt = <1400000>; ++ regulator-ramp-delay = <4000>; ++ pwm-dutycycle-range = <100 0>; ++ vin-supply = <&vsys>; ++ regulator-always-on; ++ regulator-boot-on; ++ }; ++ ++ vsys: vsys-regulator { ++ compatible = "regulator-fixed"; ++ regulator-name = "vsys"; ++ regulator-min-microvolt = <5000000>; ++ regulator-max-microvolt = <5000000>; ++ regulator-always-on; ++ regulator-boot-on; ++ }; ++ ++ vcc_sd: sdmmc-regulator { ++ compatible = "regulator-fixed"; ++ gpio = <&gpio3 RK_PA7 GPIO_ACTIVE_LOW>; ++ pinctrl-names = "default"; ++ pinctrl-0 = <&sdmmc_pwr>; ++ regulator-name = "vcc_sd"; ++ regulator-min-microvolt = <3300000>; ++ regulator-max-microvolt = <3300000>; ++ startup-delay-us = <100000>; ++ vin-supply = <&vcc_io>; ++ }; ++ ++ vcc_host: usb-host-regulator { ++ compatible = "regulator-fixed"; ++ enable-active-high; ++ gpio = <&gpio0 RK_PA6 GPIO_ACTIVE_HIGH>; ++ pinctrl-names = "default"; ++ pinctrl-0 = <&host_drv>; ++ regulator-name = "host-pwr"; ++ regulator-min-microvolt = <5000000>; ++ regulator-max-microvolt = <5000000>; ++ regulator-always-on; ++ vin-supply = <&vsys>; ++ }; ++ ++ vcc_otg: usb-otg-regulator { ++ compatible = "regulator-fixed"; ++ enable-active-high; ++ gpio = <&gpio0 RK_PA5 GPIO_ACTIVE_HIGH>; ++ pinctrl-names = "default"; ++ pinctrl-0 = <&otg_drv>; ++ regulator-name = "vcc_otg"; ++ regulator-min-microvolt = <5000000>; ++ regulator-max-microvolt = <5000000>; ++ regulator-always-on; ++ vin-supply = <&vsys>; ++ }; ++ ++ /* delivered from tps65910 pmic RTC, ++ * but there is no clock output in ++ * the driver ++ */ ++ xin32k: xin-32k { ++ compatible = "fixed-clock"; ++ clock-frequency = <32768>; ++ #clock-cells = <0>; ++ clock-output-names = "xin32k"; ++ }; ++}; ++ ++&cpu0_opp_table { ++ opp-1608000000 { ++ status = "okay"; ++ }; ++}; ++ ++&cpu0 { ++ cpu-supply = <&vdd_arm>; ++}; ++ ++&cpu1 { ++ cpu-supply = <&vdd_arm>; ++}; ++&cru { ++ assigned-clocks = <&cru PLL_CPLL>, <&cru PLL_GPLL>, ++ <&cru ACLK_CPU>, <&cru HCLK_CPU>, ++ <&cru PCLK_CPU>, <&cru ACLK_PERI>, ++ <&cru HCLK_PERI>, <&cru PCLK_PERI>, ++ <&cru ACLK_LCDC0>, <&cru ACLK_LCDC1>; ++ assigned-clock-rates = <594000000>, <1200000000>, ++ <300000000>, <150000000>, ++ <75000000>, <300000000>, ++ <150000000>, <75000000>, ++ <297000000>, <297000000>; ++}; ++ ++&emac { ++ pinctrl-names = "default"; ++ pinctrl-0 = <&emac_xfer>, <&emac_mdio>, <&rmii_rst>; ++ phy = <&phy0>; ++ phy-supply = <&vcc_rmii>; ++ status = "okay"; ++ ++ phy0: ethernet-phy@0 { ++ reg = <0>; ++ reset-gpios = <&gpio1 RK_PD6 GPIO_ACTIVE_LOW>; ++ }; ++}; ++ ++&gpu { ++ operating-points-v2 = <&gpu_opp_table>; ++ mali-supply = <&vdd_log>; ++ status = "okay"; ++}; ++ ++&hdmi { ++ status = "okay"; ++}; ++ ++&hdmi_in_vop1 { ++ status = "disabled"; ++}; ++ ++&hdmi_out { ++ hdmi_out_con: endpoint { ++ remote-endpoint = <&hdmi_con_in>; ++ }; ++}; ++ ++&hdmi_sound { ++ status = "okay"; ++}; ++ ++&i2c0 { ++ status = "okay"; ++ ++ eeprom: eeprom@50 { ++ reg = <0x50>; ++ compatible = "atmel,24c16"; ++ pagesize = <16>; ++ }; ++ ++ alc5631: audio-codec@1a { ++ reg = <0x1a>; ++ compatible = "realtek,alc5631"; ++ clocks = <&cru SCLK_I2S1>; ++ clock-names = "mclk"; ++ #sound-dai-cells = <0>; ++ }; ++}; ++ ++&i2c1 { ++ status = "okay"; ++ ++ tps: tps@2d { ++ reg = <0x2d>; ++ interrupt-parent = <&gpio6>; ++ interrupts = ; ++ pinctrl-names = "default"; ++ pinctrl-0 = <&pmic_int &pwr_hold>; ++ ++ vcc1-supply = <&vsys>; ++ vcc2-supply = <&vsys>; ++ vcc3-supply = <&vsys>; ++ vcc4-supply = <&vsys>; ++ vcc5-supply = <&vcc_io>; ++ vcc6-supply = <&vcc_io>; ++ vcc7-supply = <&vsys>; ++ vccio-supply = <&vsys>; ++ ++ regulators { ++ vcc_rtc: regulator@0 { ++ regulator-name = "vcc_rtc"; ++ regulator-always-on; ++ }; ++ ++ vcc_io: regulator@1 { ++ regulator-name = "vcc_io"; ++ regulator-min-microvolt = <3300000>; ++ regulator-max-microvolt = <3300000>; ++ regulator-always-on; ++ regulator-boot-on; ++ }; ++ ++ vdd_arm: regulator@2 { ++ regulator-name = "vdd_arm"; ++ regulator-min-microvolt = <600000>; ++ regulator-max-microvolt = <1500000>; ++ regulator-always-on; ++ regulator-boot-on; ++ }; ++ ++ vcc_ddr: regulator@3 { ++ regulator-name = "vcc_ddr"; ++ regulator-min-microvolt = <600000>; ++ regulator-max-microvolt = <1500000>; ++ regulator-always-on; ++ regulator-boot-on; ++ }; ++ ++ vcc18: regulator@5 { ++ regulator-name = "vcc18"; ++ regulator-min-microvolt = <1800000>; ++ regulator-max-microvolt = <1800000>; ++ regulator-always-on; ++ }; ++ ++ vdd_11: regulator@6 { ++ regulator-name = "vdd_11"; ++ regulator-min-microvolt = <1100000>; ++ regulator-max-microvolt = <1100000>; ++ regulator-always-on; ++ }; ++ ++ vcc_25: regulator@7 { ++ regulator-name = "vcc_25"; ++ regulator-min-microvolt = <2500000>; ++ regulator-max-microvolt = <2500000>; ++ regulator-always-on; ++ }; ++ ++ vccio_wl: regulator@8 { ++ regulator-name = "vccio_wl"; ++ regulator-min-microvolt = <1800000>; ++ regulator-max-microvolt = <1800000>; ++ regulator-boot-on; ++ }; ++ ++ vcc25_hdmi: regulator@9 { ++ regulator-name = "vcc25_hdmi"; ++ regulator-min-microvolt = <2500000>; ++ regulator-max-microvolt = <2500000>; ++ regulator-always-on; ++ }; ++ ++ vcca_33: regulator@10 { ++ regulator-name = "vcca_33"; ++ regulator-min-microvolt = <3300000>; ++ regulator-max-microvolt = <3300000>; ++ regulator-boot-on; ++ regulator-always-on; ++ }; ++ ++ vcc_rmii: regulator@11 { ++ regulator-name = "vcc_rmii"; ++ regulator-min-microvolt = <3300000>; ++ regulator-max-microvolt = <3300000>; ++ }; ++ ++ vcc28_cif: regulator@12 { ++ regulator-name = "vcc28_cif"; ++ regulator-min-microvolt = <2800000>; ++ regulator-max-microvolt = <2800000>; ++ }; ++ }; ++ }; ++}; ++ ++#include "tps65910.dtsi" ++ ++&i2s0 { ++ status = "okay"; ++}; ++ ++&i2s1 { ++ status = "okay"; ++}; ++ ++&mmc0 { ++ bus-width = <4>; ++ disable-wp; ++ pinctrl-names = "default"; ++ pinctrl-0 = <&sd0_clk>, <&sd0_cmd>, <&sd0_cd>, <&sd0_bus4>; ++ vmmc-supply = <&vcc_sd>; ++ cap-mmc-highspeed; ++ cap-sd-highspeed; ++ status = "okay"; ++}; ++ ++&mmc1 { ++ bus-width = <4>; ++ clock-frequency = <50000000>; ++ mmc-pwrseq = <&sdio_pwrseq>; ++ non-removable; ++ pinctrl-names = "default"; ++ pinctrl-0 = <&sd1_clk>, <&sd1_cmd>, <&sd1_bus4>; ++ vmmc-supply = <&vcc_io>; ++ vqmmc-supply = <&vccio_wl>; ++ cap-mmc-highspeed; ++ cap-sd-highspeed; ++ status = "okay"; ++ #address-cells = <1>; ++ #size-cells = <0>; ++ ++ /* ++ * RK903 is compatible with Ampak AP6330 ++ * except: 2.4 GHz channels only ++ */ ++ wifi@0 { ++ reg = <0>; ++ compatible = "brcm,bcm4329-fmac"; ++ interrupt-parent = <&gpio3>; ++ interrupts = ; ++ interrupt-names = "host-wake"; ++ pinctrl-names = "default"; ++ pinctrl-0 = <&wifi_host_wake>; ++ }; ++}; ++ ++&pinctrl { ++ pcfg_output_high: pcfg-output-high { ++ output-high; ++ }; ++ ++ emac { ++ rmii_rst: rmii-rst { ++ rockchip,pins = <1 RK_PD6 RK_FUNC_GPIO &pcfg_output_high>; ++ }; ++ }; ++ ++ ir { ++ ir_int: ir-int { ++ rockchip,pins = <6 RK_PA1 RK_FUNC_GPIO &pcfg_pull_default>; ++ }; ++ }; ++ ++ keys { ++ pwr_key: pwr-key { ++ rockchip,pins = <6 RK_PA2 RK_FUNC_GPIO &pcfg_pull_default>; ++ }; ++ }; ++ ++ usb { ++ host_drv: host-drv { ++ rockchip,pins = <0 RK_PA6 RK_FUNC_GPIO &pcfg_pull_default>; ++ }; ++ ++ otg_drv: otg-drv { ++ rockchip,pins = <0 RK_PA5 RK_FUNC_GPIO &pcfg_pull_default>; ++ }; ++ ++ }; ++ ++ rk903 { ++ bt_host_wake: bt-host-wake { ++ rockchip,pins = <6 RK_PA7 RK_FUNC_GPIO &pcfg_pull_default>; ++ }; ++ ++ bt_reg_on: bt-reg-on { ++ rockchip,pins = <3 RK_PC7 RK_FUNC_GPIO &pcfg_pull_none>; ++ }; ++ ++ bt_rst: bt-rst { ++ rockchip,pins = <3 RK_PD1 RK_FUNC_GPIO &pcfg_output_high>; ++ }; ++ ++ bt_wake: bt-wake { ++ rockchip,pins = <3 RK_PC6 RK_FUNC_GPIO &pcfg_pull_none>; ++ }; ++ ++ wifi_host_wake: wifi-host-wake { ++ rockchip,pins = <3 RK_PD2 RK_FUNC_GPIO &pcfg_pull_default>; ++ }; ++ ++ wifi_reg_on: wifi-reg-on { ++ rockchip,pins = <3 RK_PD0 RK_FUNC_GPIO &pcfg_pull_none>; ++ }; ++ }; ++ ++ sdmmc { ++ sdmmc_pwr: sdmmc-pwr { ++ rockchip,pins = <3 RK_PA7 RK_FUNC_GPIO &pcfg_pull_default>; ++ }; ++ }; ++ ++ tps { ++ pmic_int: pmic-int { ++ rockchip,pins = <6 RK_PA4 RK_FUNC_GPIO &pcfg_pull_default>; ++ }; ++ ++ pwr_hold: pwr-hold { ++ rockchip,pins = <6 RK_PB0 RK_FUNC_GPIO &pcfg_output_high>; ++ }; ++ }; ++}; ++ ++&pwm3 { ++ status = "okay"; ++}; ++ ++&spdif { ++ status = "okay"; ++}; ++ ++&uart0 { ++ pinctrl-names = "default"; ++ pinctrl-0 = <&uart0_xfer>, <&uart0_cts>, ++ <&uart0_rts>; ++ uart-has-rtscts; ++ status = "okay"; ++ #address-cells = <1>; ++ #size-cells = <0>; ++ ++ /* ++ * BCM4330B2 patch is needed, .i.e. a ++ * BCM4330B1 with 26 MHz XTAL config ++ */ ++ bluetooth@0 { ++ reg = <0>; ++ compatible = "brcm,bcm43438-bt"; ++ clocks = <&xin32k>; ++ clock-names = "lpo"; ++ host-wakeup-gpios = <&gpio6 RK_PA7 GPIO_ACTIVE_HIGH>; ++ device-wakeup-gpios = <&gpio3 RK_PC6 GPIO_ACTIVE_HIGH>; ++ shutdown-gpios = <&gpio3 RK_PC7 GPIO_ACTIVE_HIGH>; ++ pinctrl-names = "default"; ++ pinctrl-0 = <&bt_host_wake>, <&bt_reg_on>, ++ <&bt_rst>, <&bt_wake>; ++ vbat-supply = <&vcc_io>; ++ vddio-supply = <&vccio_wl>; ++ }; ++}; ++ ++&uart2 { ++ status = "okay"; ++}; ++ ++&usb_host { ++ status = "okay"; ++}; ++ ++&usbphy { ++ status = "okay"; ++}; ++ ++&usb_otg { ++ status = "okay"; ++}; ++ ++&tsadc { ++ vref-supply = <&vcc_25>; ++ status = "okay"; ++}; ++ ++&vop0 { ++ status = "okay"; ++}; ++ ++&wdt { ++ status = "okay"; ++}; diff --git a/patch/kernel/rk322x-dev/01-linux-0001-rockchip-from-5.11.patch b/patch/kernel/rk322x-dev/01-linux-0001-rockchip-from-5.11.patch index 778408ed6..13b9e2f14 100644 --- a/patch/kernel/rk322x-dev/01-linux-0001-rockchip-from-5.11.patch +++ b/patch/kernel/rk322x-dev/01-linux-0001-rockchip-from-5.11.patch @@ -778,37 +778,6 @@ index eece97f97ef8..d13d2d497720 100644 int grf_offset; const char *supply_names[MAX_SUPPLIES]; -From d3563b841781439149bfa5accb9d4e1b53878de6 Mon Sep 17 00:00:00 2001 -From: Zhang Changzhong -Date: Fri, 4 Dec 2020 16:33:25 +0800 -Subject: [PATCH] soc: rockchip: io-domain: Fix error return code in - rockchip_iodomain_probe() - -Fix to return a negative error code from the error handling -case instead of 0, as done elsewhere in this function. - -Fixes: e943c43b32ce ("PM: AVS: rockchip-io: Move the driver to the rockchip specific drivers") -Reported-by: Hulk Robot -Signed-off-by: Zhang Changzhong -Link: https://lore.kernel.org/r/1607070805-33038-1-git-send-email-zhangchangzhong@huawei.com -Signed-off-by: Heiko Stuebner ---- - drivers/soc/rockchip/io-domain.c | 1 + - 1 file changed, 1 insertion(+) - -diff --git a/drivers/soc/rockchip/io-domain.c b/drivers/soc/rockchip/io-domain.c -index d13d2d497720..cf8182fc3642 100644 ---- a/drivers/soc/rockchip/io-domain.c -+++ b/drivers/soc/rockchip/io-domain.c -@@ -544,6 +544,7 @@ static int rockchip_iodomain_probe(struct platform_device *pdev) - if (uV < 0) { - dev_err(iod->dev, "Can't determine voltage: %s\n", - supply_name); -+ ret = uV; - goto unreg_notify; - } - - From ade714b4c3d73ce2b15553b48e688e8a48bdd507 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 @@ -1972,37 +1941,6 @@ index 000000000000..5a0ecb8faecf + }; +}; -From 443e4a66d5ee6a7da54debe8b53c2e5a8e18c0fd Mon Sep 17 00:00:00 2001 -From: Chen-Yu Tsai -Date: Thu, 26 Nov 2020 15:33:34 +0800 -Subject: [PATCH] arm64: dts: rockchip: Set dr_mode to "host" for OTG on - rk3328-roc-cc - -The board has a standard USB A female port connected to the USB OTG -controller's data pins. Set dr_mode in the OTG controller node to -indicate this usage, instead of having the implementation guess. - -Fixes: 2171f4fdac06 ("arm64: dts: rockchip: add roc-rk3328-cc board") -Signed-off-by: Chen-Yu Tsai -Link: https://lore.kernel.org/r/20201126073336.30794-2-wens@kernel.org -Signed-off-by: Heiko Stuebner ---- - arch/arm64/boot/dts/rockchip/rk3328-roc-cc.dts | 1 + - 1 file changed, 1 insertion(+) - -diff --git a/arch/arm64/boot/dts/rockchip/rk3328-roc-cc.dts b/arch/arm64/boot/dts/rockchip/rk3328-roc-cc.dts -index b70ffb1c6a63..b76282e704de 100644 ---- a/arch/arm64/boot/dts/rockchip/rk3328-roc-cc.dts -+++ b/arch/arm64/boot/dts/rockchip/rk3328-roc-cc.dts -@@ -334,6 +334,7 @@ &uart2 { - }; - - &usb20_otg { -+ dr_mode = "host"; - status = "okay"; - }; - - From 3cb90f8d11317b126a800de92315ed9a0a9cf8c8 Mon Sep 17 00:00:00 2001 From: Chen-Yu Tsai Date: Thu, 26 Nov 2020 15:33:35 +0800 @@ -3001,74 +2939,6 @@ index 60cd1c18cd4e..beee5fbb3443 100644 status = "okay"; clock-master; -From adf583a6a6ced9d68afba577759d70366d337eb8 Mon Sep 17 00:00:00 2001 -From: Chen-Yu Tsai -Date: Fri, 4 Dec 2020 14:48:05 +0800 -Subject: [PATCH] arm64: dts: rockchip: Fix UART pull-ups on rk3328 - -For UARTs, the local pull-ups should be on the RX pin, not the TX pin. -UARTs transmit active-low, so a disconnected RX pin should be pulled -high instead of left floating to prevent noise being interpreted as -transmissions. - -This gets rid of bogus sysrq events when the UART console is not -connected. - -Fixes: 52e02d377a72 ("arm64: dts: rockchip: add core dtsi file for RK3328 SoCs") -Signed-off-by: Chen-Yu Tsai -Link: https://lore.kernel.org/r/20201204064805.6480-1-wens@kernel.org -Signed-off-by: Heiko Stuebner ---- - arch/arm64/boot/dts/rockchip/rk3328.dtsi | 16 ++++++++-------- - 1 file changed, 8 insertions(+), 8 deletions(-) - -diff --git a/arch/arm64/boot/dts/rockchip/rk3328.dtsi b/arch/arm64/boot/dts/rockchip/rk3328.dtsi -index bbdb19a3e85d..db0d5c8e5f96 100644 ---- a/arch/arm64/boot/dts/rockchip/rk3328.dtsi -+++ b/arch/arm64/boot/dts/rockchip/rk3328.dtsi -@@ -1237,8 +1237,8 @@ otp_out: otp-out { - - uart0 { - uart0_xfer: uart0-xfer { -- rockchip,pins = <1 RK_PB1 1 &pcfg_pull_up>, -- <1 RK_PB0 1 &pcfg_pull_none>; -+ rockchip,pins = <1 RK_PB1 1 &pcfg_pull_none>, -+ <1 RK_PB0 1 &pcfg_pull_up>; - }; - - uart0_cts: uart0-cts { -@@ -1256,8 +1256,8 @@ uart0_rts_pin: uart0-rts-pin { - - uart1 { - uart1_xfer: uart1-xfer { -- rockchip,pins = <3 RK_PA4 4 &pcfg_pull_up>, -- <3 RK_PA6 4 &pcfg_pull_none>; -+ rockchip,pins = <3 RK_PA4 4 &pcfg_pull_none>, -+ <3 RK_PA6 4 &pcfg_pull_up>; - }; - - uart1_cts: uart1-cts { -@@ -1275,15 +1275,15 @@ uart1_rts_pin: uart1-rts-pin { - - uart2-0 { - uart2m0_xfer: uart2m0-xfer { -- rockchip,pins = <1 RK_PA0 2 &pcfg_pull_up>, -- <1 RK_PA1 2 &pcfg_pull_none>; -+ rockchip,pins = <1 RK_PA0 2 &pcfg_pull_none>, -+ <1 RK_PA1 2 &pcfg_pull_up>; - }; - }; - - uart2-1 { - uart2m1_xfer: uart2m1-xfer { -- rockchip,pins = <2 RK_PA0 1 &pcfg_pull_up>, -- <2 RK_PA1 1 &pcfg_pull_none>; -+ rockchip,pins = <2 RK_PA0 1 &pcfg_pull_none>, -+ <2 RK_PA1 1 &pcfg_pull_up>; - }; - }; - - From 6e7e897fb23b7291fbabda014628aba1a71dff79 Mon Sep 17 00:00:00 2001 From: Vicente Bergas Date: Tue, 1 Dec 2020 16:41:30 +0100 diff --git a/patch/kernel/rk322x-dev/01-linux-0020-drm-from-5.11.patch b/patch/kernel/rk322x-dev/01-linux-0020-drm-from-5.11.patch index fa080923a..ea8e5c5f1 100644 --- a/patch/kernel/rk322x-dev/01-linux-0020-drm-from-5.11.patch +++ b/patch/kernel/rk322x-dev/01-linux-0020-drm-from-5.11.patch @@ -242,162 +242,3 @@ index 9fef6413741d..feb04f127b55 100644 .audio_startup = dw_hdmi_i2s_audio_startup, .audio_shutdown = dw_hdmi_i2s_audio_shutdown, -From 4fc54b12725fbdf5a002517d7350f3778a6f65f3 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)