diff --git a/config/boards/odroidc2.conf b/config/boards/odroidc2.conf index 558e6bfce..c92756446 100644 --- a/config/boards/odroidc2.conf +++ b/config/boards/odroidc2.conf @@ -6,7 +6,7 @@ BOOTCONFIG="odroidc2_config" MODULES="bonding" MODULES_NEXT="" # -KERNEL_TARGET="default,dev" +KERNEL_TARGET="default,next,dev" CLI_TARGET="jessie,xenial:default" DESKTOP_TARGET="xenial:default" diff --git a/config/kernel/linux-odroidc2-next.config b/config/kernel/linux-odroidc2-next.config index ec574c41d..321c4295e 100644 --- a/config/kernel/linux-odroidc2-next.config +++ b/config/kernel/linux-odroidc2-next.config @@ -1,12 +1,11 @@ # # Automatically generated file; DO NOT EDIT. -# Linux/arm64 4.10.17 Kernel Configuration +# Linux/arm64 4.12.3 Kernel Configuration # CONFIG_ARM64=y CONFIG_64BIT=y CONFIG_ARCH_PHYS_ADDR_T_64BIT=y CONFIG_MMU=y -CONFIG_DEBUG_RODATA=y CONFIG_ARM64_PAGE_SHIFT=12 CONFIG_ARM64_CONT_SHIFT=4 CONFIG_ARCH_MMAP_RND_BITS_MIN=18 @@ -116,15 +115,17 @@ CONFIG_TASK_IO_ACCOUNTING=y CONFIG_PREEMPT_RCU=y # CONFIG_RCU_EXPERT is not set CONFIG_SRCU=y +CONFIG_TREE_SRCU=y # CONFIG_TASKS_RCU is not set CONFIG_RCU_STALL_COMMON=y +CONFIG_RCU_NEED_SEGCBLIST=y # CONFIG_TREE_RCU_TRACE is not set -# CONFIG_RCU_EXPEDITE_BOOT is not set CONFIG_BUILD_BIN2C=y CONFIG_IKCONFIG=y CONFIG_IKCONFIG_PROC=y CONFIG_LOG_BUF_SHIFT=17 CONFIG_LOG_CPU_MAX_BUF_SHIFT=12 +CONFIG_PRINTK_SAFE_LOG_BUF_SHIFT=13 CONFIG_GENERIC_SCHED_CLOCK=y CONFIG_ARCH_SUPPORTS_NUMA_BALANCING=y CONFIG_CGROUPS=y @@ -140,6 +141,7 @@ CONFIG_FAIR_GROUP_SCHED=y # CONFIG_CFS_BANDWIDTH is not set # CONFIG_RT_GROUP_SCHED is not set CONFIG_CGROUP_PIDS=y +# CONFIG_CGROUP_RDMA is not set # CONFIG_CGROUP_FREEZER is not set CONFIG_CGROUP_HUGETLB=y CONFIG_CPUSETS=y @@ -167,7 +169,6 @@ CONFIG_RD_LZMA=y CONFIG_RD_XZ=y CONFIG_RD_LZO=y CONFIG_RD_LZ4=y -CONFIG_INITRAMFS_COMPRESSION=".gz" CONFIG_CC_OPTIMIZE_FOR_PERFORMANCE=y # CONFIG_CC_OPTIMIZE_FOR_SIZE is not set CONFIG_SYSCTL=y @@ -204,6 +205,7 @@ CONFIG_PCI_QUIRKS=y CONFIG_MEMBARRIER=y # CONFIG_EMBEDDED is not set CONFIG_HAVE_PERF_EVENTS=y +# CONFIG_PC104 is not set # # Kernel Performance Events And Counters @@ -212,6 +214,7 @@ CONFIG_PERF_EVENTS=y # CONFIG_DEBUG_PERF_USE_VMALLOC is not set CONFIG_VM_EVENT_COUNTERS=y CONFIG_SLUB_DEBUG=y +# CONFIG_SLUB_MEMCG_SYSFS_ON is not set # CONFIG_COMPAT_BRK is not set # CONFIG_SLAB is not set CONFIG_SLUB=y @@ -219,6 +222,7 @@ CONFIG_SLUB=y CONFIG_SLUB_CPU_PARTIAL=y # CONFIG_SYSTEM_DATA_VERIFICATION is not set CONFIG_PROFILING=y +CONFIG_CRASH_CORE=y CONFIG_KEXEC_CORE=y # CONFIG_KPROBES is not set CONFIG_JUMP_LABEL=y @@ -232,6 +236,7 @@ CONFIG_HAVE_ARCH_TRACEHOOK=y CONFIG_HAVE_DMA_CONTIGUOUS=y CONFIG_GENERIC_SMP_IDLE_THREAD=y CONFIG_GENERIC_IDLE_POLL_SETUP=y +CONFIG_ARCH_HAS_SET_MEMORY=y CONFIG_HAVE_REGS_AND_STACK_ACCESS_API=y CONFIG_HAVE_CLK=y CONFIG_HAVE_DMA_API_DEBUG=y @@ -271,6 +276,12 @@ CONFIG_OLD_SIGSUSPEND3=y CONFIG_COMPAT_OLD_SIGACTION=y # CONFIG_CPU_NO_EFFICIENT_FFS is not set # CONFIG_HAVE_ARCH_VMAP_STACK is not set +# CONFIG_ARCH_OPTIONAL_KERNEL_RWX is not set +# CONFIG_ARCH_OPTIONAL_KERNEL_RWX_DEFAULT is not set +CONFIG_ARCH_HAS_STRICT_KERNEL_RWX=y +CONFIG_STRICT_KERNEL_RWX=y +CONFIG_ARCH_HAS_STRICT_MODULE_RWX=y +CONFIG_STRICT_MODULE_RWX=y # # GCOV-based kernel profiling @@ -292,6 +303,7 @@ CONFIG_MODULE_UNLOAD=y # CONFIG_TRIM_UNUSED_KSYMS is not set CONFIG_MODULES_TREE_LOOKUP=y CONFIG_BLOCK=y +CONFIG_BLK_SCSI_REQUEST=y CONFIG_BLK_DEV_BSG=y # CONFIG_BLK_DEV_BSGLIB is not set CONFIG_BLK_DEV_INTEGRITY=y @@ -299,6 +311,8 @@ CONFIG_BLK_DEV_INTEGRITY=y # CONFIG_BLK_DEV_THROTTLING is not set # CONFIG_BLK_CMDLINE_PARSER is not set # CONFIG_BLK_WBT is not set +CONFIG_BLK_DEBUG_FS=y +# CONFIG_BLK_SED_OPAL is not set # # Partition Types @@ -308,6 +322,7 @@ CONFIG_MSDOS_PARTITION=y CONFIG_EFI_PARTITION=y CONFIG_BLOCK_COMPAT=y CONFIG_BLK_MQ_PCI=y +CONFIG_BLK_MQ_VIRTIO=y # # IO Schedulers @@ -319,6 +334,9 @@ CONFIG_IOSCHED_CFQ=y CONFIG_DEFAULT_CFQ=y # CONFIG_DEFAULT_NOOP is not set CONFIG_DEFAULT_IOSCHED="cfq" +CONFIG_MQ_IOSCHED_DEADLINE=y +CONFIG_MQ_IOSCHED_KYBER=y +# CONFIG_IOSCHED_BFQ is not set CONFIG_PREEMPT_NOTIFIERS=y CONFIG_UNINLINE_SPIN_UNLOCK=y CONFIG_ARCH_SUPPORTS_ATOMIC_RMW=y @@ -354,6 +372,7 @@ CONFIG_ARCH_STRATIX10=y CONFIG_ARCH_TEGRA=y CONFIG_ARCH_SPRD=y CONFIG_ARCH_THUNDER=y +# CONFIG_ARCH_THUNDER2 is not set CONFIG_ARCH_UNIPHIER=y CONFIG_ARCH_VEXPRESS=y CONFIG_ARCH_VULCAN=y @@ -376,6 +395,7 @@ CONFIG_PCIEASPM=y # CONFIG_PCIEASPM_DEBUG is not set CONFIG_PCIEASPM_DEFAULT=y # CONFIG_PCIEASPM_POWERSAVE is not set +# CONFIG_PCIEASPM_POWER_SUPERSAVE is not set # CONFIG_PCIEASPM_PERFORMANCE is not set CONFIG_PCIE_PME=y # CONFIG_PCIE_DPC is not set @@ -394,30 +414,45 @@ CONFIG_PCI_IOV=y CONFIG_PCI_LABEL=y # CONFIG_HOTPLUG_PCI is not set +# +# DesignWare PCI Core Support +# +CONFIG_PCIE_DW=y +CONFIG_PCIE_DW_HOST=y +# CONFIG_PCIE_DW_PLAT is not set +CONFIG_PCI_LAYERSCAPE=y +CONFIG_PCI_HISI=y +CONFIG_PCIE_QCOM=y +CONFIG_PCIE_ARMADA_8K=y + # # PCI host controller drivers # CONFIG_PCI_AARDVARK=y # CONFIG_PCIE_XILINX_NWL is not set -# CONFIG_PCIE_DW_PLAT is not set -CONFIG_PCIE_DW=y # CONFIG_PCI_TEGRA is not set CONFIG_PCIE_RCAR=y CONFIG_PCI_HOST_COMMON=y CONFIG_PCI_HOST_GENERIC=y CONFIG_PCI_XGENE=y CONFIG_PCI_XGENE_MSI=y -CONFIG_PCI_LAYERSCAPE=y CONFIG_PCIE_IPROC=y CONFIG_PCIE_IPROC_PLATFORM=y CONFIG_PCIE_IPROC_MSI=y -CONFIG_PCI_HISI=y -CONFIG_PCIE_QCOM=y # CONFIG_PCI_HOST_THUNDER_PEM is not set # CONFIG_PCI_HOST_THUNDER_ECAM is not set -CONFIG_PCIE_ARMADA_8K=y # CONFIG_PCIE_ROCKCHIP is not set +# +# PCI Endpoint +# +# CONFIG_PCI_ENDPOINT is not set + +# +# PCI switch controller drivers +# +# CONFIG_PCI_SW_SWITCHTEC is not set + # # Kernel Features # @@ -436,6 +471,8 @@ CONFIG_ARM64_ERRATUM_843419=y CONFIG_CAVIUM_ERRATUM_22375=y CONFIG_CAVIUM_ERRATUM_23154=y CONFIG_CAVIUM_ERRATUM_27456=y +CONFIG_QCOM_FALKOR_ERRATUM_1003=y +CONFIG_QCOM_FALKOR_ERRATUM_1009=y CONFIG_QCOM_QDF2400_ERRATUM_0065=y CONFIG_ARM64_4K_PAGES=y # CONFIG_ARM64_16K_PAGES is not set @@ -510,6 +547,7 @@ CONFIG_SECCOMP=y CONFIG_PARAVIRT=y # CONFIG_PARAVIRT_TIME_ACCOUNTING is not set CONFIG_KEXEC=y +# CONFIG_CRASH_DUMP is not set CONFIG_XEN_DOM0=y CONFIG_XEN=y CONFIG_FORCE_MAX_ZONEORDER=11 @@ -623,12 +661,15 @@ CONFIG_CPUFREQ_DT=y CONFIG_CPUFREQ_DT_PLATDEV=y CONFIG_ARM_BIG_LITTLE_CPUFREQ=y # CONFIG_ARM_DT_BL_CPUFREQ is not set +# CONFIG_ARM_DB8500_CPUFREQ is not set # CONFIG_ARM_KIRKWOOD_CPUFREQ is not set # CONFIG_ARM_MT8173_CPUFREQ is not set CONFIG_ARM_SCPI_CPUFREQ=y CONFIG_ARM_TEGRA20_CPUFREQ=y CONFIG_ARM_TEGRA124_CPUFREQ=y +CONFIG_ARM_TEGRA186_CPUFREQ=m # CONFIG_ACPI_CPPC_CPUFREQ is not set +CONFIG_QORIQ_CPUFREQ=m CONFIG_NET=y CONFIG_NET_INGRESS=y @@ -915,6 +956,11 @@ CONFIG_BRIDGE=m CONFIG_BRIDGE_IGMP_SNOOPING=y CONFIG_BRIDGE_VLAN_FILTERING=y CONFIG_HAVE_NET_DSA=y +CONFIG_NET_DSA=m +CONFIG_NET_DSA_TAG_BRCM=y +CONFIG_NET_DSA_TAG_DSA=y +CONFIG_NET_DSA_TAG_EDSA=y +CONFIG_NET_DSA_TAG_TRAILER=y CONFIG_VLAN_8021Q=m CONFIG_VLAN_8021Q_GVRP=y CONFIG_VLAN_8021Q_MVRP=y @@ -937,7 +983,7 @@ CONFIG_DNS_RESOLVER=y # CONFIG_NETLINK_DIAG is not set # CONFIG_MPLS is not set # CONFIG_HSR is not set -# CONFIG_NET_SWITCHDEV is not set +CONFIG_NET_SWITCHDEV=y # CONFIG_NET_L3_MASTER_DEV is not set # CONFIG_QRTR is not set # CONFIG_NET_NCSI is not set @@ -972,10 +1018,17 @@ CONFIG_BT_LEDS=y # # Bluetooth device drivers # -# CONFIG_BT_HCIBTUSB is not set +CONFIG_BT_INTEL=m +CONFIG_BT_BCM=m +CONFIG_BT_RTL=m +CONFIG_BT_HCIBTUSB=m +CONFIG_BT_HCIBTUSB_BCM=y +CONFIG_BT_HCIBTUSB_RTL=y # CONFIG_BT_HCIBTSDIO is not set CONFIG_BT_HCIUART=m +CONFIG_BT_HCIUART_SERDEV=y # CONFIG_BT_HCIUART_H4 is not set +# CONFIG_BT_HCIUART_NOKIA is not set # CONFIG_BT_HCIUART_BCSP is not set # CONFIG_BT_HCIUART_ATH3K is not set CONFIG_BT_HCIUART_LL=y @@ -990,6 +1043,7 @@ CONFIG_BT_HCIUART_LL=y # CONFIG_BT_HCIBFUSB is not set # CONFIG_BT_HCIVHCI is not set # CONFIG_BT_MRVL is not set +# CONFIG_BT_ATH3K is not set # CONFIG_AF_RXRPC is not set # CONFIG_AF_KCM is not set # CONFIG_STREAM_PARSER is not set @@ -1020,16 +1074,19 @@ CONFIG_MAC80211_STA_HASH_MAX_SIZE=0 CONFIG_RFKILL=m CONFIG_RFKILL_LEDS=y CONFIG_RFKILL_INPUT=y -# CONFIG_RFKILL_REGULATOR is not set # CONFIG_RFKILL_GPIO is not set CONFIG_NET_9P=y CONFIG_NET_9P_VIRTIO=y +CONFIG_NET_9P_XEN=m # CONFIG_NET_9P_DEBUG is not set # CONFIG_CAIF is not set # CONFIG_CEPH_LIB is not set # CONFIG_NFC is not set +CONFIG_PSAMPLE=m +CONFIG_NET_IFE=m # CONFIG_LWTUNNEL is not set CONFIG_DST_CACHE=y +CONFIG_GRO_CELLS=y # CONFIG_NET_DEVLINK is not set CONFIG_MAY_USE_DEVLINK=y CONFIG_HAVE_EBPF_JIT=y @@ -1216,6 +1273,7 @@ CONFIG_BLK_DEV_NBD=m CONFIG_XEN_BLKDEV_FRONTEND=y # CONFIG_XEN_BLKDEV_BACKEND is not set CONFIG_VIRTIO_BLK=y +# CONFIG_VIRTIO_BLK_SCSI is not set # CONFIG_BLK_DEV_RBD is not set # CONFIG_BLK_DEV_RSXX is not set # CONFIG_BLK_DEV_NVME is not set @@ -1248,6 +1306,7 @@ CONFIG_VIRTIO_BLK=y # CONFIG_LATTICE_ECP3_CONFIG is not set CONFIG_SRAM=y CONFIG_VEXPRESS_SYSCFG=y +CONFIG_PCI_ENDPOINT_TEST=m # CONFIG_C2PORT is not set # @@ -1259,6 +1318,7 @@ CONFIG_EEPROM_AT25=m # CONFIG_EEPROM_MAX6875 is not set # CONFIG_EEPROM_93CX6 is not set # CONFIG_EEPROM_93XX46 is not set +CONFIG_EEPROM_IDT_89HPESX=m # CONFIG_CB710_CORE is not set # @@ -1523,6 +1583,7 @@ CONFIG_MACVTAP=m # CONFIG_NETPOLL is not set # CONFIG_NET_POLL_CONTROLLER is not set CONFIG_TUN=y +CONFIG_TAP=m # CONFIG_TUN_VNET_CROSS_LE is not set CONFIG_VETH=m CONFIG_VIRTIO_NET=y @@ -1536,6 +1597,20 @@ CONFIG_VIRTIO_NET=y # # Distributed Switch Architecture drivers # +CONFIG_NET_DSA_MV88E6060=m +CONFIG_NET_DSA_BCM_SF2=m +CONFIG_B53=m +CONFIG_B53_SPI_DRIVER=m +CONFIG_B53_MDIO_DRIVER=m +CONFIG_B53_MMAP_DRIVER=m +CONFIG_B53_SRAB_DRIVER=m +CONFIG_NET_DSA_MV88E6XXX=m +CONFIG_NET_DSA_MV88E6XXX_GLOBAL2=y +# CONFIG_NET_DSA_QCA8K is not set +# CONFIG_NET_DSA_LOOP is not set +# CONFIG_NET_DSA_MT7530 is not set +# CONFIG_NET_DSA_SMSC_LAN9303_I2C is not set +# CONFIG_NET_DSA_SMSC_LAN9303_MDIO is not set CONFIG_ETHERNET=y CONFIG_NET_VENDOR_3COM=y # CONFIG_VORTEX is not set @@ -1558,6 +1633,8 @@ CONFIG_NET_VENDOR_AMD=y CONFIG_AMD_XGBE=y # CONFIG_AMD_XGBE_HAVE_ECC is not set CONFIG_NET_XGENE=y +CONFIG_NET_XGENE_V2=m +CONFIG_NET_VENDOR_AQUANTIA=y CONFIG_NET_VENDOR_ARC=y # CONFIG_EMAC_ROCKCHIP is not set CONFIG_NET_VENDOR_ATHEROS=y @@ -1641,8 +1718,9 @@ CONFIG_IGBVF=y CONFIG_NET_VENDOR_I825XX=y # CONFIG_JME is not set CONFIG_NET_VENDOR_MARVELL=y -# CONFIG_MVMDIO is not set +CONFIG_MVMDIO=m # CONFIG_MVNETA is not set +CONFIG_MVPP2=m # CONFIG_PXA168_ETH is not set # CONFIG_SKGE is not set CONFIG_SKY2=y @@ -1668,7 +1746,8 @@ CONFIG_NET_VENDOR_NATSEMI=y # CONFIG_NATSEMI is not set # CONFIG_NS83820 is not set CONFIG_NET_VENDOR_NETRONOME=y -# CONFIG_NFP_NETVF is not set +CONFIG_NFP=m +# CONFIG_NFP_DEBUG is not set CONFIG_NET_VENDOR_8390=y # CONFIG_NE2K_PCI is not set CONFIG_NET_VENDOR_NVIDIA=y @@ -1697,6 +1776,7 @@ CONFIG_RAVB=y CONFIG_NET_VENDOR_RDC=y # CONFIG_R6040 is not set CONFIG_NET_VENDOR_ROCKER=y +CONFIG_ROCKER=m CONFIG_NET_VENDOR_SAMSUNG=y # CONFIG_SXGBE_ETH is not set CONFIG_NET_VENDOR_SEEQ=y @@ -1717,6 +1797,7 @@ CONFIG_SMSC911X=y CONFIG_NET_VENDOR_STMICRO=y CONFIG_STMMAC_ETH=m CONFIG_STMMAC_PLATFORM=m +CONFIG_DWMAC_DWC_QOS_ETH=m CONFIG_DWMAC_GENERIC=m CONFIG_DWMAC_IPQ806X=m CONFIG_DWMAC_MESON=m @@ -1728,8 +1809,6 @@ CONFIG_NET_VENDOR_SUN=y # CONFIG_SUNGEM is not set # CONFIG_CASSINI is not set # CONFIG_NIU is not set -CONFIG_NET_VENDOR_SYNOPSYS=y -# CONFIG_SYNOPSYS_DWC_ETH_QOS is not set CONFIG_NET_VENDOR_TEHUTI=y # CONFIG_TEHUTI is not set CONFIG_NET_VENDOR_TI=y @@ -1741,18 +1820,15 @@ CONFIG_NET_VENDOR_VIA=y CONFIG_NET_VENDOR_WIZNET=y # CONFIG_WIZNET_W5100 is not set # CONFIG_WIZNET_W5300 is not set +CONFIG_NET_VENDOR_SYNOPSYS=y +CONFIG_DWC_XLGMAC=m +CONFIG_DWC_XLGMAC_PCI=m # CONFIG_FDDI is not set # CONFIG_HIPPI is not set # CONFIG_NET_SB1000 is not set -CONFIG_PHYLIB=y -CONFIG_SWPHY=y -# CONFIG_LED_TRIGGER_PHY is not set - -# -# MDIO bus device drivers -# +CONFIG_MDIO_DEVICE=y # CONFIG_MDIO_BCM_IPROC is not set -# CONFIG_MDIO_BCM_UNIMAC is not set +CONFIG_MDIO_BCM_UNIMAC=m CONFIG_MDIO_BITBANG=y CONFIG_MDIO_BUS_MUX=y CONFIG_MDIO_BUS_MUX_BCM_IPROC=y @@ -1764,6 +1840,9 @@ CONFIG_MDIO_BUS_MUX_MMIOREG=y # CONFIG_MDIO_SUN4I is not set # CONFIG_MDIO_THUNDER is not set CONFIG_MDIO_XGENE=y +CONFIG_PHYLIB=y +CONFIG_SWPHY=y +# CONFIG_LED_TRIGGER_PHY is not set # # MII PHY device drivers @@ -1771,8 +1850,9 @@ CONFIG_MDIO_XGENE=y # CONFIG_AMD_PHY is not set # CONFIG_AQUANTIA_PHY is not set # CONFIG_AT803X_PHY is not set -# CONFIG_BCM7XXX_PHY is not set +CONFIG_BCM7XXX_PHY=m # CONFIG_BCM87XX_PHY is not set +CONFIG_BCM_NET_PHYLIB=m # CONFIG_BROADCOM_PHY is not set # CONFIG_CICADA_PHY is not set # CONFIG_DAVICOM_PHY is not set @@ -1941,7 +2021,7 @@ CONFIG_XEN_NETDEV_FRONTEND=y # CONFIG_INPUT=y CONFIG_INPUT_LEDS=y -# CONFIG_INPUT_FF_MEMLESS is not set +CONFIG_INPUT_FF_MEMLESS=m # CONFIG_INPUT_POLLDEV is not set # CONFIG_INPUT_SPARSEKMAP is not set # CONFIG_INPUT_MATRIXKMAP is not set @@ -1987,6 +2067,7 @@ CONFIG_KEYBOARD_GPIO=y # CONFIG_KEYBOARD_SH_KEYSC is not set # CONFIG_KEYBOARD_SUN4I_LRADC is not set # CONFIG_KEYBOARD_OMAP4 is not set +CONFIG_KEYBOARD_TM2_TOUCHKEY=m # CONFIG_KEYBOARD_XTKBD is not set # CONFIG_KEYBOARD_CROS_EC is not set # CONFIG_KEYBOARD_CAP11XX is not set @@ -1997,12 +2078,14 @@ CONFIG_MOUSE_PS2_ALPS=y CONFIG_MOUSE_PS2_BYD=y CONFIG_MOUSE_PS2_LOGIPS2PP=y CONFIG_MOUSE_PS2_SYNAPTICS=y +CONFIG_MOUSE_PS2_SYNAPTICS_SMBUS=y CONFIG_MOUSE_PS2_CYPRESS=y CONFIG_MOUSE_PS2_TRACKPOINT=y # CONFIG_MOUSE_PS2_ELANTECH is not set # CONFIG_MOUSE_PS2_SENTELIC is not set # CONFIG_MOUSE_PS2_TOUCHKIT is not set CONFIG_MOUSE_PS2_FOCALTECH=y +CONFIG_MOUSE_PS2_SMBUS=y # CONFIG_MOUSE_SERIAL is not set # CONFIG_MOUSE_APPLETOUCH is not set # CONFIG_MOUSE_BCM5974 is not set @@ -2021,12 +2104,13 @@ CONFIG_INPUT_MISC=y # CONFIG_INPUT_BMA150 is not set # CONFIG_INPUT_E3X0_BUTTON is not set CONFIG_INPUT_PM8941_PWRKEY=y +CONFIG_INPUT_PM8XXX_VIBRATOR=m # CONFIG_INPUT_MMA8450 is not set -# CONFIG_INPUT_MPU3050 is not set # CONFIG_INPUT_GP2A is not set # CONFIG_INPUT_GPIO_BEEPER is not set # CONFIG_INPUT_GPIO_TILT_POLLED is not set # CONFIG_INPUT_GPIO_DECODER is not set +CONFIG_INPUT_CPCAP_PWRBUTTON=m # CONFIG_INPUT_ATI_REMOTE2 is not set # CONFIG_INPUT_KEYSPAN_REMOTE is not set # CONFIG_INPUT_KXTJ9 is not set @@ -2097,6 +2181,7 @@ CONFIG_SERIAL_8250_PNP=y CONFIG_SERIAL_8250_CONSOLE=y CONFIG_SERIAL_8250_DMA=y CONFIG_SERIAL_8250_PCI=y +CONFIG_SERIAL_8250_EXAR=m CONFIG_SERIAL_8250_NR_UARTS=4 CONFIG_SERIAL_8250_RUNTIME_UARTS=4 CONFIG_SERIAL_8250_EXTENDED=y @@ -2155,6 +2240,7 @@ CONFIG_SERIAL_XILINX_PS_UART_CONSOLE=y CONFIG_SERIAL_MVEBU_UART=y CONFIG_SERIAL_MVEBU_CONSOLE=y CONFIG_SERIAL_MCTRL_GPIO=y +CONFIG_SERIAL_DEV_BUS=m CONFIG_HVC_DRIVER=y CONFIG_HVC_IRQ=y CONFIG_HVC_XEN=y @@ -2168,12 +2254,12 @@ CONFIG_HW_RANDOM_BCM2835=m CONFIG_HW_RANDOM_IPROC_RNG200=m CONFIG_HW_RANDOM_OMAP=m # CONFIG_HW_RANDOM_VIRTIO is not set -CONFIG_HW_RANDOM_EXYNOS=m CONFIG_HW_RANDOM_HISI=m CONFIG_HW_RANDOM_MSM=m CONFIG_HW_RANDOM_XGENE=m CONFIG_HW_RANDOM_MESON=m CONFIG_HW_RANDOM_CAVIUM=m +CONFIG_HW_RANDOM_MTK=m # CONFIG_R3964 is not set # CONFIG_APPLICOM is not set @@ -2201,6 +2287,7 @@ CONFIG_I2C_MUX=y # # CONFIG_I2C_ARB_GPIO_CHALLENGE is not set # CONFIG_I2C_MUX_GPIO is not set +CONFIG_I2C_MUX_LTC4306=m # CONFIG_I2C_MUX_PCA9541 is not set CONFIG_I2C_MUX_PCA954x=y # CONFIG_I2C_MUX_PINCTRL is not set @@ -2266,12 +2353,12 @@ CONFIG_I2C_RK3X=y # CONFIG_I2C_SH_MOBILE is not set # CONFIG_I2C_SIMTEC is not set CONFIG_I2C_TEGRA=y +CONFIG_I2C_TEGRA_BPMP=m # CONFIG_I2C_UNIPHIER is not set CONFIG_I2C_UNIPHIER_F=y # CONFIG_I2C_VERSATILE is not set # CONFIG_I2C_THUNDERX is not set # CONFIG_I2C_XILINX is not set -# CONFIG_I2C_XLP9XX is not set CONFIG_I2C_RCAR=y # @@ -2335,7 +2422,6 @@ CONFIG_SPI_S3C64XX=y # CONFIG_SPI_THUNDERX is not set # CONFIG_SPI_XCOMM is not set # CONFIG_SPI_XILINX is not set -# CONFIG_SPI_XLP is not set # CONFIG_SPI_ZYNQMP_GQSPI is not set # @@ -2378,7 +2464,9 @@ CONFIG_PINCTRL=y # # Pin controllers # +CONFIG_GENERIC_PINCTRL_GROUPS=y CONFIG_PINMUX=y +CONFIG_GENERIC_PINMUX_FUNCTIONS=y CONFIG_PINCONF=y CONFIG_GENERIC_PINCONF=y # CONFIG_DEBUG_PINCTRL is not set @@ -2397,8 +2485,11 @@ CONFIG_PINCTRL_NS2_MUX=y # CONFIG_PINCTRL_BERLIN_BG4CT is not set # CONFIG_PINCTRL_BAYTRAIL is not set # CONFIG_PINCTRL_CHERRYVIEW is not set +CONFIG_PINCTRL_INTEL=m # CONFIG_PINCTRL_BROXTON is not set +CONFIG_PINCTRL_GEMINILAKE=m # CONFIG_PINCTRL_SUNRISEPOINT is not set +CONFIG_PINCTRL_ARMADA_37XX=y CONFIG_PINCTRL_MSM=y # CONFIG_PINCTRL_APQ8064 is not set # CONFIG_PINCTRL_APQ8084 is not set @@ -2421,11 +2512,8 @@ CONFIG_PINCTRL_PFC_R8A7795=y CONFIG_PINCTRL_PFC_R8A7796=y CONFIG_PINCTRL_SUNXI=y # CONFIG_PINCTRL_SUN4I_A10 is not set -# CONFIG_PINCTRL_SUN5I_A10S is not set -# CONFIG_PINCTRL_SUN5I_A13 is not set -# CONFIG_PINCTRL_GR8 is not set +# CONFIG_PINCTRL_SUN5I is not set # CONFIG_PINCTRL_SUN6I_A31 is not set -# CONFIG_PINCTRL_SUN6I_A31S is not set # CONFIG_PINCTRL_SUN6I_A31_R is not set # CONFIG_PINCTRL_SUN7I_A20 is not set # CONFIG_PINCTRL_SUN8I_A23 is not set @@ -2433,10 +2521,13 @@ CONFIG_PINCTRL_SUNXI=y # CONFIG_PINCTRL_SUN8I_A83T is not set # CONFIG_PINCTRL_SUN8I_A23_R is not set # CONFIG_PINCTRL_SUN8I_H3 is not set -# CONFIG_PINCTRL_SUN8I_H3_R is not set +CONFIG_PINCTRL_SUN8I_H3_R=y +# CONFIG_PINCTRL_SUN8I_V3S is not set # CONFIG_PINCTRL_SUN9I_A80 is not set # CONFIG_PINCTRL_SUN9I_A80_R is not set CONFIG_PINCTRL_SUN50I_A64=y +CONFIG_PINCTRL_SUN50I_A64_R=y +CONFIG_PINCTRL_SUN50I_H5=y CONFIG_PINCTRL_TEGRA=y CONFIG_PINCTRL_TEGRA124=y CONFIG_PINCTRL_TEGRA210=y @@ -2451,12 +2542,7 @@ CONFIG_PINCTRL_UNIPHIER=y CONFIG_PINCTRL_UNIPHIER_LD11=y CONFIG_PINCTRL_UNIPHIER_LD20=y CONFIG_PINCTRL_MTK=y -# CONFIG_PINCTRL_MT2701 is not set -# CONFIG_PINCTRL_MT7623 is not set -# CONFIG_PINCTRL_MT8135 is not set -# CONFIG_PINCTRL_MT8127 is not set CONFIG_PINCTRL_MT8173=y -# CONFIG_PINCTRL_MT6397 is not set CONFIG_GPIOLIB=y CONFIG_OF_GPIO=y CONFIG_GPIO_ACPI=y @@ -2472,6 +2558,8 @@ CONFIG_GPIO_GENERIC=y # CONFIG_GPIO_ALTERA is not set # CONFIG_GPIO_AMDPT is not set CONFIG_GPIO_DWAPB=y +CONFIG_GPIO_EXAR=m +# CONFIG_GPIO_FTGPIO010 is not set CONFIG_GPIO_GENERIC_PLATFORM=y # CONFIG_GPIO_GRGPIO is not set # CONFIG_GPIO_MOCKUP is not set @@ -2509,6 +2597,7 @@ CONFIG_GPIO_MAX77620=y # PCI GPIO expanders # # CONFIG_GPIO_BT8XX is not set +CONFIG_GPIO_PCI_IDIO_16=m # CONFIG_GPIO_RDC321X is not set # @@ -2550,16 +2639,20 @@ CONFIG_POWER_SUPPLY=y # CONFIG_BATTERY_DS2780 is not set # CONFIG_BATTERY_DS2781 is not set # CONFIG_BATTERY_DS2782 is not set +CONFIG_BATTERY_LEGO_EV3=m # CONFIG_BATTERY_SBS is not set +CONFIG_CHARGER_SBS=m CONFIG_BATTERY_BQ27XXX=y CONFIG_BATTERY_BQ27XXX_I2C=y # CONFIG_BATTERY_MAX17040 is not set # CONFIG_BATTERY_MAX17042 is not set +CONFIG_CHARGER_CPCAP=m # CONFIG_CHARGER_ISP1704 is not set # CONFIG_CHARGER_MAX8903 is not set # CONFIG_CHARGER_LP8727 is not set # CONFIG_CHARGER_GPIO is not set # CONFIG_CHARGER_MANAGER is not set +CONFIG_CHARGER_DETECTOR_MAX14656=m # CONFIG_CHARGER_QCOM_SMBB is not set # CONFIG_CHARGER_BQ2415X is not set # CONFIG_CHARGER_BQ24190 is not set @@ -2593,6 +2686,7 @@ CONFIG_HWMON=y # CONFIG_SENSORS_ADT7475 is not set # CONFIG_SENSORS_ASC7621 is not set CONFIG_SENSORS_ARM_SCPI=y +CONFIG_SENSORS_ASPEED=m # CONFIG_SENSORS_ATXP1 is not set # CONFIG_SENSORS_DS620 is not set # CONFIG_SENSORS_DS1621 is not set @@ -2675,6 +2769,7 @@ CONFIG_SENSORS_LM90=m # CONFIG_SENSORS_SCH56XX_COMMON is not set # CONFIG_SENSORS_SCH5627 is not set # CONFIG_SENSORS_SCH5636 is not set +CONFIG_SENSORS_STTS751=m # CONFIG_SENSORS_SMM665 is not set # CONFIG_SENSORS_ADC128D818 is not set # CONFIG_SENSORS_ADS1015 is not set @@ -2710,6 +2805,7 @@ CONFIG_SENSORS_INA2XX=m # # CONFIG_SENSORS_ACPI_POWER is not set CONFIG_THERMAL=y +CONFIG_THERMAL_EMERGENCY_POWEROFF_DELAY_MS=0 CONFIG_THERMAL_HWMON=y CONFIG_THERMAL_OF=y # CONFIG_THERMAL_WRITABLE_TRIPS is not set @@ -2730,6 +2826,7 @@ CONFIG_HISI_THERMAL=y # CONFIG_QORIQ_THERMAL is not set # CONFIG_ROCKCHIP_THERMAL is not set # CONFIG_RCAR_THERMAL is not set +CONFIG_RCAR_GEN3_THERMAL=m # CONFIG_ARMADA_THERMAL is not set # @@ -2752,6 +2849,7 @@ CONFIG_EXYNOS_THERMAL=y # # Qualcomm thermal drivers # +# CONFIG_ZX2967_THERMAL is not set CONFIG_WATCHDOG=y CONFIG_WATCHDOG_CORE=y # CONFIG_WATCHDOG_NOWAYOUT is not set @@ -2781,6 +2879,7 @@ CONFIG_MESON_GXBB_WATCHDOG=m CONFIG_MESON_WATCHDOG=m # CONFIG_MEDIATEK_WATCHDOG is not set CONFIG_RENESAS_WDT=y +CONFIG_ZX2967_WATCHDOG=m # CONFIG_ALIM7101_WDT is not set # CONFIG_I6300ESB_WDT is not set CONFIG_BCM2835_WDT=y @@ -2867,6 +2966,7 @@ CONFIG_MFD_MAX77620=y # CONFIG_MFD_MT6397 is not set # CONFIG_MFD_MENF21BMC is not set # CONFIG_EZX_PCAP is not set +CONFIG_MFD_CPCAP=m # CONFIG_MFD_VIPERBOARD is not set # CONFIG_MFD_RETU is not set # CONFIG_MFD_PCF50633 is not set @@ -2891,6 +2991,7 @@ CONFIG_MFD_SYSCON=y # CONFIG_MFD_TI_AM335X_TSCADC is not set # CONFIG_MFD_LP3943 is not set # CONFIG_MFD_LP8788 is not set +CONFIG_MFD_TI_LMU=m # CONFIG_MFD_PALMAS is not set # CONFIG_TPS6105X is not set # CONFIG_TPS65010 is not set @@ -2928,6 +3029,7 @@ CONFIG_REGULATOR_FIXED_VOLTAGE=y # CONFIG_REGULATOR_ACT8865 is not set # CONFIG_REGULATOR_AD5398 is not set # CONFIG_REGULATOR_ANATOP is not set +CONFIG_REGULATOR_CPCAP=m # CONFIG_REGULATOR_DA9210 is not set # CONFIG_REGULATOR_DA9211 is not set # CONFIG_REGULATOR_FAN53555 is not set @@ -2935,6 +3037,7 @@ CONFIG_REGULATOR_GPIO=y CONFIG_REGULATOR_HI655X=y # CONFIG_REGULATOR_ISL9305 is not set # CONFIG_REGULATOR_ISL6271A is not set +CONFIG_REGULATOR_LM363X=m # CONFIG_REGULATOR_LP3971 is not set # CONFIG_REGULATOR_LP3972 is not set # CONFIG_REGULATOR_LP872X is not set @@ -2953,7 +3056,7 @@ CONFIG_REGULATOR_MAX77620=y # CONFIG_REGULATOR_PV88080 is not set # CONFIG_REGULATOR_PV88090 is not set CONFIG_REGULATOR_PWM=y -CONFIG_REGULATOR_QCOM_SMD_RPM=y +CONFIG_REGULATOR_QCOM_SMD_RPM=m CONFIG_REGULATOR_QCOM_SPMI=y CONFIG_REGULATOR_RK808=y # CONFIG_REGULATOR_S2MPA01 is not set @@ -2963,7 +3066,9 @@ CONFIG_REGULATOR_S2MPS11=y # CONFIG_REGULATOR_TPS62360 is not set # CONFIG_REGULATOR_TPS65023 is not set # CONFIG_REGULATOR_TPS6507X is not set +CONFIG_REGULATOR_TPS65132=m # CONFIG_REGULATOR_TPS6524X is not set +CONFIG_REGULATOR_VCTRL=m # CONFIG_REGULATOR_VEXPRESS is not set CONFIG_MEDIA_SUPPORT=m @@ -2988,6 +3093,7 @@ CONFIG_VIDEO_V4L2=m CONFIG_VIDEOBUF2_CORE=m CONFIG_VIDEOBUF2_MEMOPS=m CONFIG_VIDEOBUF2_DMA_CONTIG=m +CONFIG_VIDEOBUF2_VMALLOC=m CONFIG_DVB_CORE=m # CONFIG_DVB_NET is not set # CONFIG_TTPCI_EEPROM is not set @@ -3140,6 +3246,7 @@ CONFIG_TEGRA_HOST1X_FIREWALL=y CONFIG_DRM=m CONFIG_DRM_MIPI_DSI=y # CONFIG_DRM_DP_AUX_CHARDEV is not set +CONFIG_DRM_DEBUG_MM_SELFTEST=m CONFIG_DRM_KMS_HELPER=m CONFIG_DRM_KMS_FB_HELPER=y CONFIG_DRM_FBDEV_EMULATION=y @@ -3148,6 +3255,7 @@ CONFIG_DRM_FBDEV_OVERALLOC=100 CONFIG_DRM_TTM=m CONFIG_DRM_GEM_CMA_HELPER=y CONFIG_DRM_KMS_CMA_HELPER=y +CONFIG_DRM_VM=y # # I2C encoder or helper chips @@ -3175,7 +3283,7 @@ CONFIG_DRM_NOUVEAU_BACKLIGHT=y # CONFIG_DRM_MGAG200 is not set # CONFIG_DRM_CIRRUS_QEMU is not set CONFIG_DRM_RCAR_DU=m -CONFIG_DRM_RCAR_HDMI=y +CONFIG_DRM_RCAR_DW_HDMI=m CONFIG_DRM_RCAR_LVDS=y CONFIG_DRM_RCAR_VSP=y # CONFIG_DRM_QXL is not set @@ -3189,6 +3297,7 @@ CONFIG_DRM_MSM_DSI_PLL=y CONFIG_DRM_MSM_DSI_28NM_PHY=y CONFIG_DRM_MSM_DSI_20NM_PHY=y CONFIG_DRM_MSM_DSI_28NM_8960_PHY=y +CONFIG_DRM_MSM_DSI_14NM_PHY=y CONFIG_DRM_TEGRA=m # CONFIG_DRM_TEGRA_DEBUG is not set CONFIG_DRM_PANEL=y @@ -3196,14 +3305,17 @@ CONFIG_DRM_PANEL=y # # Display Panels # +CONFIG_DRM_PANEL_LVDS=m CONFIG_DRM_PANEL_SIMPLE=m # CONFIG_DRM_PANEL_JDI_LT070ME05000 is not set # CONFIG_DRM_PANEL_SAMSUNG_LD9040 is not set # CONFIG_DRM_PANEL_LG_LG4573 is not set # CONFIG_DRM_PANEL_PANASONIC_VVX10F034N00 is not set +CONFIG_DRM_PANEL_SAMSUNG_S6E3HA2=m # CONFIG_DRM_PANEL_SAMSUNG_S6E8AA0 is not set # CONFIG_DRM_PANEL_SHARP_LQ101R1SX01 is not set # CONFIG_DRM_PANEL_SHARP_LS043T1LE01 is not set +CONFIG_DRM_PANEL_SITRONIX_ST7789V=m CONFIG_DRM_BRIDGE=y # @@ -3211,6 +3323,8 @@ CONFIG_DRM_BRIDGE=y # # CONFIG_DRM_ANALOGIX_ANX78XX is not set # CONFIG_DRM_DUMB_VGA_DAC is not set +CONFIG_DRM_LVDS_ENCODER=m +CONFIG_DRM_MEGACHIPS_STDPXXXX_GE_B850V3_FW=m # CONFIG_DRM_NXP_PTN3460 is not set # CONFIG_DRM_PARADE_PS8622 is not set # CONFIG_DRM_SIL_SII8620 is not set @@ -3233,7 +3347,11 @@ CONFIG_HISI_KIRIN_DW_DSI=m # CONFIG_DRM_MXSFB is not set CONFIG_DRM_MESON=m CONFIG_DRM_MESON_DW_HDMI=m +CONFIG_DRM_TINYDRM=m +CONFIG_TINYDRM_MIPI_DBI=m +CONFIG_TINYDRM_MI0283QT=m # CONFIG_DRM_LEGACY is not set +CONFIG_DRM_LIB_RANDOM=y # # Frame buffer Devices @@ -3251,6 +3369,7 @@ CONFIG_FB_CFB_IMAGEBLIT=y CONFIG_FB_SYS_FILLRECT=y CONFIG_FB_SYS_COPYAREA=y CONFIG_FB_SYS_IMAGEBLIT=y +# CONFIG_FB_PROVIDE_GET_FB_UNMAPPED_AREA is not set # CONFIG_FB_FOREIGN_ENDIAN is not set CONFIG_FB_SYS_FOPS=y CONFIG_FB_DEFERRED_IO=y @@ -3333,6 +3452,7 @@ CONFIG_BACKLIGHT_LP855X=m # CONFIG_BACKLIGHT_GPIO is not set # CONFIG_BACKLIGHT_LV5207LP is not set # CONFIG_BACKLIGHT_BD6107 is not set +CONFIG_BACKLIGHT_ARCXCNN=m # CONFIG_VGASTATE is not set CONFIG_VIDEOMODE_HELPERS=y CONFIG_HDMI=y @@ -3485,27 +3605,25 @@ CONFIG_SND_BCM2835_SOC_I2S=m # CONFIG_SND_SOC_FSL_SPDIF is not set # CONFIG_SND_SOC_FSL_ESAI is not set # CONFIG_SND_SOC_IMX_AUDMUX is not set +CONFIG_SND_I2S_HI6210_I2S=m # CONFIG_SND_KIRKWOOD_SOC is not set # CONFIG_SND_SOC_IMG is not set # CONFIG_SND_SOC_MT2701 is not set # CONFIG_SND_SOC_MT8173 is not set - -# -# Amlogic SoC Audio Support -# -CONFIG_SND_MESON_AIU_I2S_DAI=m -CONFIG_SND_MESON_AIU_I2S_DMA=m -CONFIG_SND_MESON_AIU_COMMON=m +CONFIG_SND_SOC_MESON=m +CONFIG_SND_SOC_MESON_I2S=m +CONFIG_SND_SOC_MESON_SPDIF=m # CONFIG_SND_SOC_QCOM is not set # CONFIG_SND_SOC_ROCKCHIP is not set CONFIG_SND_SOC_SAMSUNG=y # CONFIG_SND_SAMSUNG_PCM is not set # CONFIG_SND_SAMSUNG_SPDIF is not set -# CONFIG_SND_SAMSUNG_I2S is not set +CONFIG_SND_SAMSUNG_I2S=m # CONFIG_SND_SOC_SAMSUNG_SMDK_WM8994 is not set # CONFIG_SND_SOC_SAMSUNG_SMDK_SPDIF is not set # CONFIG_SND_SOC_SMDK_WM8994_PCM is not set # CONFIG_SND_SOC_SNOW is not set +CONFIG_SND_SOC_ODROID=m # CONFIG_SND_SOC_ARNDALE_RT5631_ALC5631 is not set # @@ -3518,19 +3636,26 @@ CONFIG_SND_SOC_RCAR=y # Allwinner SoC Audio support # # CONFIG_SND_SUN4I_CODEC is not set +CONFIG_SND_SUN8I_CODEC_ANALOG=m # CONFIG_SND_SUN4I_I2S is not set # CONFIG_SND_SUN4I_SPDIF is not set # CONFIG_SND_SOC_TEGRA is not set # CONFIG_SND_SOC_XTFPGA_I2S is not set # CONFIG_ZX_SPDIF is not set # CONFIG_ZX_I2S is not set +CONFIG_ZX_TDM=m CONFIG_SND_SOC_I2C_AND_SPI=y # # CODEC drivers # # CONFIG_SND_SOC_AC97_CODEC is not set +CONFIG_SND_SOC_ADAU_UTILS=m # CONFIG_SND_SOC_ADAU1701 is not set +CONFIG_SND_SOC_ADAU17X1=m +CONFIG_SND_SOC_ADAU1761=m +CONFIG_SND_SOC_ADAU1761_I2C=m +CONFIG_SND_SOC_ADAU1761_SPI=m # CONFIG_SND_SOC_ADAU7002 is not set # CONFIG_SND_SOC_AK4104 is not set # CONFIG_SND_SOC_AK4554 is not set @@ -3542,6 +3667,7 @@ CONFIG_SND_SOC_AK4613=y # CONFIG_SND_SOC_CS35L32 is not set # CONFIG_SND_SOC_CS35L33 is not set # CONFIG_SND_SOC_CS35L34 is not set +CONFIG_SND_SOC_CS35L35=m # CONFIG_SND_SOC_CS42L42 is not set # CONFIG_SND_SOC_CS42L51_I2C is not set # CONFIG_SND_SOC_CS42L52 is not set @@ -3554,12 +3680,17 @@ CONFIG_SND_SOC_AK4613=y # CONFIG_SND_SOC_CS42XX8_I2C is not set # CONFIG_SND_SOC_CS4349 is not set # CONFIG_SND_SOC_CS53L30 is not set +CONFIG_SND_SOC_DIO2125=m CONFIG_SND_SOC_HDMI_CODEC=m -# CONFIG_SND_SOC_ES8328 is not set -# CONFIG_SND_SOC_ES7134LV is not set +# CONFIG_SND_SOC_ES7134 is not set +CONFIG_SND_SOC_ES8328=m +CONFIG_SND_SOC_ES8328_I2C=m +CONFIG_SND_SOC_ES8328_SPI=m # CONFIG_SND_SOC_GTM601 is not set # CONFIG_SND_SOC_INNO_RK3036 is not set +CONFIG_SND_SOC_MAX98090=m # CONFIG_SND_SOC_MAX98504 is not set +CONFIG_SND_SOC_MAX98927=m # CONFIG_SND_SOC_MAX9860 is not set # CONFIG_SND_SOC_MSM8916_WCD_ANALOG is not set # CONFIG_SND_SOC_MSM8916_WCD_DIGITAL is not set @@ -3574,6 +3705,8 @@ CONFIG_SND_SOC_HDMI_CODEC=m # CONFIG_SND_SOC_RT5631 is not set # CONFIG_SND_SOC_RT5677_SPI is not set # CONFIG_SND_SOC_SGTL5000 is not set +CONFIG_SND_SOC_SIGMADSP=m +CONFIG_SND_SOC_SIGMADSP_REGMAP=m # CONFIG_SND_SOC_SIRF_AUDIO_CODEC is not set # CONFIG_SND_SOC_SPDIF is not set # CONFIG_SND_SOC_SSM2602_SPI is not set @@ -3612,12 +3745,13 @@ CONFIG_SND_SOC_HDMI_CODEC=m # CONFIG_SND_SOC_WM8974 is not set # CONFIG_SND_SOC_WM8978 is not set # CONFIG_SND_SOC_WM8985 is not set +CONFIG_SND_SOC_NAU8540=m # CONFIG_SND_SOC_NAU8810 is not set +CONFIG_SND_SOC_NAU8824=m # CONFIG_SND_SOC_TPA6130A2 is not set CONFIG_SND_SIMPLE_CARD_UTILS=y CONFIG_SND_SIMPLE_CARD=y # CONFIG_SND_SIMPLE_SCU_CARD is not set -# CONFIG_SOUND_PRIME is not set # # HID support @@ -3632,9 +3766,11 @@ CONFIG_HID_GENERIC=y # Special HID drivers # CONFIG_HID_A4TECH=y +CONFIG_HID_ACCUTOUCH=m # CONFIG_HID_ACRUX is not set CONFIG_HID_APPLE=y # CONFIG_HID_APPLEIR is not set +CONFIG_HID_ASUS=m # CONFIG_HID_AUREAL is not set CONFIG_HID_BELKIN=y # CONFIG_HID_BETOP_FF is not set @@ -3676,6 +3812,7 @@ CONFIG_HID_LOGITECH=y CONFIG_HID_MICROSOFT=y CONFIG_HID_MONTEREY=y # CONFIG_HID_MULTITOUCH is not set +CONFIG_HID_NTI=m # CONFIG_HID_NTRIG is not set # CONFIG_HID_ORTEK is not set # CONFIG_HID_PANTHERLORD is not set @@ -3723,6 +3860,7 @@ CONFIG_USB_SUPPORT=y CONFIG_USB_COMMON=y CONFIG_USB_ARCH_HAS_HCD=y CONFIG_USB=y +CONFIG_USB_PCI=y # CONFIG_USB_ANNOUNCE_NEW_DEVICES is not set # @@ -3753,6 +3891,7 @@ CONFIG_USB_EHCI_HCD=y CONFIG_USB_EHCI_ROOT_HUB_TT=y CONFIG_USB_EHCI_TT_NEWSCHED=y CONFIG_USB_EHCI_PCI=y +CONFIG_USB_EHCI_HCD_ORION=y CONFIG_USB_EHCI_MSM=y # CONFIG_USB_EHCI_TEGRA is not set CONFIG_USB_EHCI_EXYNOS=y @@ -3770,6 +3909,7 @@ CONFIG_USB_OHCI_HCD_PLATFORM=y # CONFIG_USB_SL811_HCD is not set # CONFIG_USB_R8A66597_HCD is not set # CONFIG_USB_RENESAS_USBHS_HCD is not set +CONFIG_USB_PLATFORM_ROOTHUB=y # CONFIG_USB_HCD_TEST_MODE is not set CONFIG_USB_RENESAS_USBHS=m @@ -3875,6 +4015,7 @@ CONFIG_USB_ISP1760_DUAL_ROLE=y # CONFIG_USB_ISIGHTFW is not set # CONFIG_USB_YUREX is not set # CONFIG_USB_EZUSB_FX2 is not set +CONFIG_USB_HUB_USB251XB=m CONFIG_USB_HSIC_USB3503=y # CONFIG_USB_HSIC_USB4604 is not set # CONFIG_USB_LINK_LAYER_TEST is not set @@ -3920,6 +4061,10 @@ CONFIG_USB_RENESAS_USBHS_UDC=m # CONFIG_USB_GADGET_XILINX is not set # CONFIG_USB_DUMMY_HCD is not set # CONFIG_USB_CONFIGFS is not set + +# +# USB Power Delivery and Type-C drivers +# # CONFIG_USB_LED_TRIG is not set # CONFIG_USB_ULPI_BUS is not set # CONFIG_UWB is not set @@ -3959,29 +4104,35 @@ CONFIG_MMC_TMIO_CORE=y CONFIG_MMC_SDHI=y # CONFIG_MMC_CB710 is not set # CONFIG_MMC_VIA_SDMMC is not set +CONFIG_MMC_CAVIUM_THUNDERX=m CONFIG_MMC_DW=y CONFIG_MMC_DW_PLTFM=y CONFIG_MMC_DW_EXYNOS=y CONFIG_MMC_DW_K3=y # CONFIG_MMC_DW_PCI is not set CONFIG_MMC_DW_ROCKCHIP=y +CONFIG_MMC_DW_ZX=m # CONFIG_MMC_SH_MMCIF is not set # CONFIG_MMC_VUB300 is not set # CONFIG_MMC_USHC is not set # CONFIG_MMC_USDHI6ROL0 is not set CONFIG_MMC_SUNXI=y # CONFIG_MMC_TOSHIBA_PCI is not set +CONFIG_MMC_BCM2835=m # CONFIG_MMC_MTK is not set +CONFIG_MMC_SDHCI_XENON=m # CONFIG_MEMSTICK is not set CONFIG_NEW_LEDS=y CONFIG_LEDS_CLASS=y # CONFIG_LEDS_CLASS_FLASH is not set +# CONFIG_LEDS_BRIGHTNESS_HW_CHANGED is not set # # LED drivers # # CONFIG_LEDS_BCM6328 is not set # CONFIG_LEDS_BCM6358 is not set +CONFIG_LEDS_CPCAP=m # CONFIG_LEDS_LM3530 is not set # CONFIG_LEDS_LM3642 is not set # CONFIG_LEDS_PCA9532 is not set @@ -4137,6 +4288,7 @@ CONFIG_RTC_DRV_EFI=y # CONFIG_HAVE_S3C_RTC=y CONFIG_RTC_DRV_S3C=y +CONFIG_RTC_DRV_SH=m # CONFIG_RTC_DRV_PL030 is not set CONFIG_RTC_DRV_PL031=y CONFIG_RTC_DRV_SUN6I=y @@ -4147,6 +4299,7 @@ CONFIG_RTC_DRV_TEGRA=y # CONFIG_RTC_DRV_SNVS is not set CONFIG_RTC_DRV_XGENE=y # CONFIG_RTC_DRV_R7301 is not set +CONFIG_RTC_DRV_CPCAP=m # # HID Sensor RTC drivers @@ -4164,6 +4317,7 @@ CONFIG_DMA_ACPI=y CONFIG_DMA_OF=y # CONFIG_AMBA_PL08X is not set CONFIG_DMA_BCM2835=m +CONFIG_DMA_SUN6I=m # CONFIG_FSL_EDMA is not set # CONFIG_INTEL_IDMA64 is not set # CONFIG_K3_DMA is not set @@ -4227,6 +4381,7 @@ CONFIG_VIRTIO_MMIO=y # # Microsoft Hyper-V guest support # +# CONFIG_HYPERV_TSCPAGE is not set # # Xen driver support @@ -4263,6 +4418,7 @@ CONFIG_CLK_SP810=y CONFIG_CLK_VEXPRESS_OSC=y # CONFIG_COMMON_CLK_MAX77686 is not set CONFIG_COMMON_CLK_RK808=y +CONFIG_COMMON_CLK_HI655X=m CONFIG_COMMON_CLK_SCPI=y # CONFIG_COMMON_CLK_SI5351 is not set # CONFIG_COMMON_CLK_SI514 is not set @@ -4277,23 +4433,22 @@ CONFIG_COMMON_CLK_XGENE=y CONFIG_COMMON_CLK_PWM=y # CONFIG_COMMON_CLK_PXA is not set # CONFIG_COMMON_CLK_PIC32 is not set +CONFIG_COMMON_CLK_VC5=m CONFIG_COMMON_CLK_IPROC=y CONFIG_CLK_BCM_NS2=y CONFIG_COMMON_CLK_HI3516CV300=y CONFIG_COMMON_CLK_HI3519=y +CONFIG_COMMON_CLK_HI3660=y CONFIG_COMMON_CLK_HI3798CV200=y CONFIG_COMMON_CLK_HI6220=y CONFIG_RESET_HISI=y CONFIG_STUB_CLK_HI6220=y CONFIG_COMMON_CLK_MEDIATEK=y -CONFIG_COMMON_CLK_MT2701=y -# CONFIG_COMMON_CLK_MT2701_MMSYS is not set -# CONFIG_COMMON_CLK_MT2701_IMGSYS is not set -# CONFIG_COMMON_CLK_MT2701_VDECSYS is not set -# CONFIG_COMMON_CLK_MT2701_HIFSYS is not set -# CONFIG_COMMON_CLK_MT2701_ETHSYS is not set -# CONFIG_COMMON_CLK_MT2701_BDPSYS is not set -CONFIG_COMMON_CLK_MT8135=y +CONFIG_COMMON_CLK_MT6797=y +# CONFIG_COMMON_CLK_MT6797_MMSYS is not set +# CONFIG_COMMON_CLK_MT6797_IMGSYS is not set +# CONFIG_COMMON_CLK_MT6797_VDECSYS is not set +# CONFIG_COMMON_CLK_MT6797_VENCSYS is not set CONFIG_COMMON_CLK_MT8173=y CONFIG_COMMON_CLK_AMLOGIC=y CONFIG_COMMON_CLK_GXBB=y @@ -4336,10 +4491,9 @@ CONFIG_SUNXI_CCU_NKMP=y CONFIG_SUNXI_CCU_NM=y CONFIG_SUNXI_CCU_MP=y CONFIG_SUN50I_A64_CCU=y -# CONFIG_SUN6I_A31_CCU is not set -# CONFIG_SUN8I_A23_CCU is not set -# CONFIG_SUN8I_A33_CCU is not set # CONFIG_SUN8I_H3_CCU is not set +CONFIG_SUN8I_R_CCU=y +CONFIG_CLK_TEGRA_BPMP=y CONFIG_CLK_UNIPHIER=y CONFIG_HWSPINLOCK=y @@ -4358,7 +4512,10 @@ CONFIG_CLKSRC_MMIO=y CONFIG_ROCKCHIP_TIMER=y CONFIG_ARM_ARCH_TIMER=y CONFIG_ARM_ARCH_TIMER_EVTSTREAM=y +CONFIG_ARM_ARCH_TIMER_OOL_WORKAROUND=y CONFIG_FSL_ERRATUM_A008585=y +CONFIG_HISILICON_ERRATUM_161010101=y +CONFIG_ARM64_ERRATUM_858921=y CONFIG_ARM_TIMER_SP804=y # CONFIG_ATMEL_PIT is not set CONFIG_MTK_TIMER=y @@ -4380,6 +4537,7 @@ CONFIG_HI6220_MBOX=y CONFIG_TEGRA_HSP_MBOX=y # CONFIG_XGENE_SLIMPRO_MBOX is not set CONFIG_BCM_PDC_MBOX=y +CONFIG_BCM_FLEXRM_MBOX=m CONFIG_IOMMU_API=y CONFIG_IOMMU_SUPPORT=y @@ -4406,6 +4564,9 @@ CONFIG_ARM_SMMU=y # # Rpmsg drivers # +CONFIG_RPMSG=m +CONFIG_RPMSG_CHAR=m +CONFIG_RPMSG_QCOM_SMD=m # # SOC (System On Chip) specific Drivers @@ -4416,23 +4577,33 @@ CONFIG_ARM_SMMU=y # CONFIG_RASPBERRYPI_POWER=y CONFIG_FSL_GUTS=y + +# +# i.MX SoC drivers +# CONFIG_MTK_INFRACFG=y # CONFIG_MTK_PMIC_WRAP is not set CONFIG_MTK_SCPSYS=y # CONFIG_QCOM_GSBI is not set CONFIG_QCOM_SMEM=y -CONFIG_QCOM_SMD=y -CONFIG_QCOM_SMD_RPM=y +CONFIG_QCOM_SMD_RPM=m # CONFIG_QCOM_SMP2P is not set # CONFIG_QCOM_SMSM is not set # CONFIG_QCOM_WCNSS_CTRL is not set +CONFIG_ROCKCHIP_GRF=y CONFIG_ROCKCHIP_PM_DOMAINS=y CONFIG_SOC_SAMSUNG=y +CONFIG_EXYNOS_PMU=y +CONFIG_EXYNOS_PM_DOMAINS=y CONFIG_SUNXI_SRAM=y CONFIG_ARCH_TEGRA_132_SOC=y CONFIG_ARCH_TEGRA_210_SOC=y CONFIG_ARCH_TEGRA_186_SOC=y +CONFIG_SOC_TEGRA_FLOWCTRL=y +CONFIG_SOC_TEGRA_PMC=y +CONFIG_SOC_TEGRA_PMC_TEGRA186=y # CONFIG_SOC_TI is not set +# CONFIG_SOC_ZTE is not set # CONFIG_PM_DEVFREQ is not set CONFIG_EXTCON=y @@ -4448,15 +4619,22 @@ CONFIG_EXTCON=y CONFIG_EXTCON_USB_GPIO=y # CONFIG_MEMORY is not set CONFIG_IIO=y -# CONFIG_IIO_BUFFER is not set +CONFIG_IIO_BUFFER=y +CONFIG_IIO_BUFFER_CB=m +CONFIG_IIO_KFIFO_BUF=m +CONFIG_IIO_TRIGGERED_BUFFER=m # CONFIG_IIO_CONFIGFS is not set -# CONFIG_IIO_TRIGGER is not set +CONFIG_IIO_TRIGGER=y +CONFIG_IIO_CONSUMERS_PER_TRIGGER=2 # CONFIG_IIO_SW_DEVICE is not set # CONFIG_IIO_SW_TRIGGER is not set # # Accelerometers # +CONFIG_ADXL345=m +CONFIG_ADXL345_I2C=m +CONFIG_ADXL345_SPI=m # CONFIG_BMA180 is not set # CONFIG_BMA220 is not set # CONFIG_BMC150_ACCEL is not set @@ -4497,16 +4675,23 @@ CONFIG_IIO=y # CONFIG_BCM_IPROC_ADC is not set # CONFIG_BERLIN2_ADC is not set # CONFIG_CC10001_ADC is not set +CONFIG_CPCAP_ADC=m # CONFIG_ENVELOPE_DETECTOR is not set CONFIG_EXYNOS_ADC=y # CONFIG_HI8435 is not set +CONFIG_HX711=m # CONFIG_INA2XX_ADC is not set # CONFIG_LTC2485 is not set +CONFIG_LTC2497=m # CONFIG_MAX1027 is not set +CONFIG_MAX11100=m +CONFIG_MAX1118=m # CONFIG_MAX1363 is not set +CONFIG_MAX9611=m # CONFIG_MCP320X is not set # CONFIG_MCP3422 is not set # CONFIG_MEDIATEK_MT6577_AUXADC is not set +CONFIG_MESON_SARADC=m # CONFIG_NAU7802 is not set # CONFIG_QCOM_SPMI_IADC is not set # CONFIG_QCOM_SPMI_VADC is not set @@ -4517,7 +4702,9 @@ CONFIG_EXYNOS_ADC=y # CONFIG_TI_ADC128S052 is not set # CONFIG_TI_ADC161S626 is not set # CONFIG_TI_ADS1015 is not set +CONFIG_TI_ADS7950=m # CONFIG_TI_ADS8688 is not set +# CONFIG_TI_TLC4541 is not set # CONFIG_VF610_ADC is not set # @@ -4559,6 +4746,7 @@ CONFIG_EXYNOS_ADC=y # CONFIG_AD5593R is not set # CONFIG_AD5504 is not set # CONFIG_AD5624R_SPI is not set +CONFIG_LTC2632=m # CONFIG_AD5686 is not set # CONFIG_AD5755 is not set # CONFIG_AD5761 is not set @@ -4615,6 +4803,7 @@ CONFIG_EXYNOS_ADC=y # CONFIG_AFE4403 is not set # CONFIG_AFE4404 is not set # CONFIG_MAX30100 is not set +CONFIG_MAX30102=m # # Humidity sensors @@ -4637,6 +4826,9 @@ CONFIG_EXYNOS_ADC=y # CONFIG_KMX61 is not set # CONFIG_INV_MPU6050_I2C is not set # CONFIG_INV_MPU6050_SPI is not set +CONFIG_IIO_ST_LSM6DSX=m +CONFIG_IIO_ST_LSM6DSX_I2C=m +CONFIG_IIO_ST_LSM6DSX_SPI=m # # Light sensors @@ -4651,6 +4843,7 @@ CONFIG_EXYNOS_ADC=y # CONFIG_CM32181 is not set # CONFIG_CM3232 is not set # CONFIG_CM3323 is not set +# CONFIG_CM3605 is not set # CONFIG_CM36651 is not set # CONFIG_GP2AP020A00F is not set # CONFIG_SENSORS_ISL29018 is not set @@ -4671,6 +4864,7 @@ CONFIG_EXYNOS_ADC=y # CONFIG_US5182D is not set # CONFIG_VCNL4000 is not set # CONFIG_VEML6070 is not set +CONFIG_VL6180=m # # Magnetometer sensors @@ -4690,10 +4884,17 @@ CONFIG_EXYNOS_ADC=y # Inclinometer sensors # +# +# Triggers - standalone +# +CONFIG_IIO_INTERRUPT_TRIGGER=m +CONFIG_IIO_SYSFS_TRIGGER=m + # # Digital potentiometers # # CONFIG_DS1803 is not set +CONFIG_MAX5481=m # CONFIG_MAX5487 is not set # CONFIG_MCP4131 is not set # CONFIG_MCP4531 is not set @@ -4726,10 +4927,12 @@ CONFIG_EXYNOS_ADC=y # CONFIG_AS3935 is not set # -# Proximity sensors +# Proximity and distance sensors # # CONFIG_LIDAR_LITE_V2 is not set +CONFIG_SRF04=m # CONFIG_SX9500 is not set +CONFIG_SRF08=m # # Temperature sensors @@ -4737,6 +4940,7 @@ CONFIG_EXYNOS_ADC=y # CONFIG_MAXIM_THERMOCOUPLE is not set # CONFIG_MLX90614 is not set # CONFIG_TMP006 is not set +CONFIG_TMP007=m # CONFIG_TSYS01 is not set # CONFIG_TSYS02D is not set # CONFIG_NTB is not set @@ -4751,6 +4955,7 @@ CONFIG_PWM_BCM2835=m # CONFIG_PWM_HIBVT is not set CONFIG_PWM_MESON=m # CONFIG_PWM_MTK_DISP is not set +CONFIG_PWM_MEDIATEK=m # CONFIG_PWM_PCA9685 is not set # CONFIG_PWM_RCAR is not set # CONFIG_PWM_RENESAS_TPU is not set @@ -4772,11 +4977,13 @@ CONFIG_MVEBU_ODMI=y CONFIG_MVEBU_PIC=y CONFIG_LS_SCFG_MSI=y CONFIG_PARTITION_PERCPU=y +# CONFIG_QCOM_IRQ_COMBINER is not set # CONFIG_IPACK_BUS is not set CONFIG_ARCH_HAS_RESET_CONTROLLER=y CONFIG_RESET_CONTROLLER=y # CONFIG_RESET_ATH79 is not set CONFIG_RESET_BERLIN=y +# CONFIG_RESET_IMX7 is not set # CONFIG_RESET_LPC18XX is not set CONFIG_RESET_MESON=y # CONFIG_RESET_PISTACHIO is not set @@ -4785,7 +4992,9 @@ CONFIG_RESET_MESON=y CONFIG_RESET_SUNXI=y # CONFIG_TI_SYSCON_RESET is not set CONFIG_RESET_UNIPHIER=y +# CONFIG_RESET_ZX2967 is not set # CONFIG_RESET_ZYNQ is not set +CONFIG_COMMON_RESET_HI3660=y CONFIG_COMMON_RESET_HI6220=y CONFIG_RESET_TEGRA_BPMP=y # CONFIG_FMC is not set @@ -4814,6 +5023,7 @@ CONFIG_PHY_SAMSUNG_USB2=y # CONFIG_PHY_EXYNOS4X12_USB2 is not set # CONFIG_PHY_EXYNOS5250_USB2 is not set CONFIG_PHY_EXYNOS5_USBDRD=y +# CONFIG_PHY_EXYNOS_PCIE is not set # CONFIG_PHY_QCOM_APQ8064_SATA is not set # CONFIG_PHY_QCOM_IPQ806X_SATA is not set # CONFIG_PHY_ROCKCHIP_USB is not set @@ -4823,11 +5033,14 @@ CONFIG_PHY_ROCKCHIP_EMMC=y # CONFIG_PHY_ROCKCHIP_PCIE is not set # CONFIG_PHY_ROCKCHIP_TYPEC is not set CONFIG_PHY_XGENE=y +CONFIG_PHY_QCOM_QMP=m +CONFIG_PHY_QCOM_QUSB2=m # CONFIG_PHY_QCOM_UFS is not set CONFIG_PHY_BRCM_SATA=y CONFIG_PHY_TEGRA_XUSB=y CONFIG_PHY_NS2_PCIE=y CONFIG_PHY_MESON8B_USB2=y +CONFIG_PHY_MESON_GXL_USB=m # CONFIG_POWERCAP is not set # CONFIG_MCB is not set @@ -4835,6 +5048,9 @@ CONFIG_PHY_MESON8B_USB2=y # Performance monitor support # CONFIG_ARM_PMU=y +CONFIG_ARM_PMU_ACPI=y +# CONFIG_QCOM_L2_PMU is not set +# CONFIG_QCOM_L3_PMU is not set # CONFIG_XGENE_PMU is not set CONFIG_RAS=y @@ -4843,6 +5059,7 @@ CONFIG_RAS=y # # CONFIG_ANDROID is not set # CONFIG_LIBNVDIMM is not set +CONFIG_DAX=m # CONFIG_DEV_DAX is not set CONFIG_NVMEM=m # CONFIG_MTK_EFUSE is not set @@ -4859,6 +5076,17 @@ CONFIG_NVMEM_BCM_OCOTP=m # # CONFIG_FPGA is not set +# +# FSI support +# +CONFIG_FSI=m +CONFIG_TEE=m + +# +# TEE drivers +# +# CONFIG_OPTEE is not set + # # Firmware Drivers # @@ -4874,6 +5102,7 @@ CONFIG_RASPBERRYPI_FIRMWARE=y CONFIG_QCOM_SCM=y CONFIG_QCOM_SCM_64=y CONFIG_HAVE_ARM_SMCCC=y +# CONFIG_GOOGLE_FIRMWARE is not set # # EFI (Extensible Firmware Interface) Support @@ -4915,12 +5144,14 @@ CONFIG_ACPI_TABLE_UPGRADE=y CONFIG_ACPI_CONTAINER=y # CONFIG_ACPI_HED is not set # CONFIG_ACPI_CUSTOM_METHOD is not set +# CONFIG_ACPI_BGRT is not set CONFIG_ACPI_REDUCED_HARDWARE_ONLY=y CONFIG_HAVE_ACPI_APEI=y # CONFIG_ACPI_APEI is not set # CONFIG_PMIC_OPREGION is not set # CONFIG_ACPI_CONFIGFS is not set CONFIG_ACPI_IORT=y +CONFIG_ACPI_GTDT=y # # File systems @@ -5174,10 +5405,6 @@ CONFIG_MESSAGE_LOGLEVEL_DEFAULT=4 # Compile-time checks and compiler options # # CONFIG_DEBUG_INFO is not set -# CONFIG_DEBUG_INFO_REDUCED is not set -# CONFIG_DEBUG_INFO_SPLIT is not set -# CONFIG_DEBUG_INFO_DWARF4 is not set -# CONFIG_GDB_SCRIPTS is not set CONFIG_ENABLE_WARN_DEPRECATED=y CONFIG_ENABLE_MUST_CHECK=y CONFIG_FRAME_WARN=2048 @@ -5194,6 +5421,7 @@ CONFIG_FRAME_POINTER=y # CONFIG_DEBUG_FORCE_WEAK_PER_CPU is not set CONFIG_MAGIC_SYSRQ=y CONFIG_MAGIC_SYSRQ_DEFAULT_ENABLE=0x1 +CONFIG_MAGIC_SYSRQ_SERIAL=y CONFIG_DEBUG_KERNEL=y # @@ -5202,6 +5430,7 @@ CONFIG_DEBUG_KERNEL=y # CONFIG_PAGE_EXTENSION is not set # CONFIG_DEBUG_PAGEALLOC is not set # CONFIG_PAGE_POISONING is not set +# CONFIG_DEBUG_RODATA_TEST is not set # CONFIG_DEBUG_OBJECTS is not set # CONFIG_SLUB_DEBUG_ON is not set # CONFIG_SLUB_STATS is not set @@ -5209,6 +5438,8 @@ CONFIG_HAVE_DEBUG_KMEMLEAK=y # CONFIG_DEBUG_KMEMLEAK is not set # CONFIG_DEBUG_STACK_USAGE is not set # CONFIG_DEBUG_VM is not set +CONFIG_ARCH_HAS_DEBUG_VIRTUAL=y +# CONFIG_DEBUG_VIRTUAL is not set CONFIG_DEBUG_MEMORY_INIT=y # CONFIG_DEBUG_PER_CPU_MAPS is not set CONFIG_HAVE_ARCH_KASAN=y @@ -5236,7 +5467,6 @@ CONFIG_SCHED_INFO=y # CONFIG_SCHEDSTATS is not set # CONFIG_SCHED_STACK_END_CHECK is not set # CONFIG_DEBUG_TIMEKEEPING is not set -# CONFIG_TIMER_STATS is not set # CONFIG_DEBUG_PREEMPT is not set # @@ -5252,6 +5482,7 @@ CONFIG_SCHED_INFO=y # CONFIG_DEBUG_ATOMIC_SLEEP is not set # CONFIG_DEBUG_LOCKING_API_SELFTESTS is not set # CONFIG_LOCK_TORTURE_TEST is not set +CONFIG_WW_MUTEX_SELFTEST=m # CONFIG_STACKTRACE is not set # CONFIG_DEBUG_KOBJECT is not set CONFIG_HAVE_DEBUG_BUGVERBOSE=y @@ -5293,6 +5524,7 @@ CONFIG_TRACING_SUPPORT=y # # CONFIG_LKDTM is not set # CONFIG_TEST_LIST_SORT is not set +CONFIG_TEST_SORT=m # CONFIG_BACKTRACE_SELF_TEST is not set # CONFIG_RBTREE_TEST is not set # CONFIG_INTERVAL_TREE_TEST is not set @@ -5328,26 +5560,28 @@ CONFIG_ARCH_HAS_DEVMEM_IS_ALLOWED=y # CONFIG_PID_IN_CONTEXTIDR is not set # CONFIG_ARM64_RANDOMIZE_TEXT_OFFSET is not set # CONFIG_DEBUG_WX is not set -CONFIG_DEBUG_SET_MODULE_RONX=y # CONFIG_DEBUG_ALIGN_RODATA is not set +CONFIG_ARM64_RELOC_TEST=m # CONFIG_CORESIGHT is not set # # Security options # CONFIG_KEYS=y +CONFIG_KEYS_COMPAT=y # CONFIG_PERSISTENT_KEYRINGS is not set # CONFIG_BIG_KEYS is not set # CONFIG_ENCRYPTED_KEYS is not set # CONFIG_KEY_DH_OPERATIONS is not set # CONFIG_SECURITY_DMESG_RESTRICT is not set CONFIG_SECURITY=y +# CONFIG_SECURITY_WRITABLE_HOOKS is not set # CONFIG_SECURITYFS is not set # CONFIG_SECURITY_NETWORK is not set # CONFIG_SECURITY_PATH is not set CONFIG_HAVE_HARDENED_USERCOPY_ALLOCATOR=y -CONFIG_HAVE_ARCH_HARDENED_USERCOPY=y # CONFIG_HARDENED_USERCOPY is not set +# CONFIG_STATIC_USERMODEHELPER is not set # CONFIG_SECURITY_SMACK is not set # CONFIG_SECURITY_TOMOYO is not set # CONFIG_SECURITY_APPARMOR is not set @@ -5382,7 +5616,7 @@ CONFIG_CRYPTO_KPP2=y CONFIG_CRYPTO_ACOMP2=y # CONFIG_CRYPTO_RSA is not set # CONFIG_CRYPTO_DH is not set -# CONFIG_CRYPTO_ECDH is not set +CONFIG_CRYPTO_ECDH=m CONFIG_CRYPTO_MANAGER=y CONFIG_CRYPTO_MANAGER2=y # CONFIG_CRYPTO_USER is not set @@ -5397,6 +5631,7 @@ CONFIG_CRYPTO_CRYPTD=y CONFIG_CRYPTO_AUTHENC=m # CONFIG_CRYPTO_TEST is not set CONFIG_CRYPTO_SIMD=y +CONFIG_CRYPTO_ENGINE=m # # Authenticated Encryption with Associated Data @@ -5436,15 +5671,15 @@ CONFIG_CRYPTO_CRCT10DIF=y CONFIG_CRYPTO_GHASH=m # CONFIG_CRYPTO_POLY1305 is not set # CONFIG_CRYPTO_MD4 is not set -# CONFIG_CRYPTO_MD5 is not set +CONFIG_CRYPTO_MD5=m # CONFIG_CRYPTO_MICHAEL_MIC is not set # CONFIG_CRYPTO_RMD128 is not set # CONFIG_CRYPTO_RMD160 is not set # CONFIG_CRYPTO_RMD256 is not set # CONFIG_CRYPTO_RMD320 is not set -# CONFIG_CRYPTO_SHA1 is not set +CONFIG_CRYPTO_SHA1=m CONFIG_CRYPTO_SHA256=y -# CONFIG_CRYPTO_SHA512 is not set +CONFIG_CRYPTO_SHA512=m # CONFIG_CRYPTO_SHA3 is not set # CONFIG_CRYPTO_TGR192 is not set # CONFIG_CRYPTO_WP512 is not set @@ -5453,17 +5688,18 @@ CONFIG_CRYPTO_SHA256=y # Ciphers # CONFIG_CRYPTO_AES=y +CONFIG_CRYPTO_AES_TI=m # CONFIG_CRYPTO_ANUBIS is not set CONFIG_CRYPTO_ARC4=m # CONFIG_CRYPTO_BLOWFISH is not set # CONFIG_CRYPTO_CAMELLIA is not set # CONFIG_CRYPTO_CAST5 is not set # CONFIG_CRYPTO_CAST6 is not set -# CONFIG_CRYPTO_DES is not set +CONFIG_CRYPTO_DES=m # CONFIG_CRYPTO_FCRYPT is not set # CONFIG_CRYPTO_KHAZAD is not set # CONFIG_CRYPTO_SALSA20 is not set -# CONFIG_CRYPTO_CHACHA20 is not set +CONFIG_CRYPTO_CHACHA20=m # CONFIG_CRYPTO_SEED is not set # CONFIG_CRYPTO_SERPENT is not set # CONFIG_CRYPTO_TEA is not set @@ -5496,16 +5732,22 @@ CONFIG_CRYPTO_HW=y # CONFIG_CRYPTO_DEV_MARVELL_CESA is not set # CONFIG_CRYPTO_DEV_FSL_CAAM is not set # CONFIG_CRYPTO_DEV_FSL_CAAM_CRYPTO_API_DESC is not set +CONFIG_CRYPTO_DEV_EXYNOS_RNG=m # CONFIG_CRYPTO_DEV_S5P is not set # CONFIG_CRYPTO_DEV_CCP is not set +CONFIG_CRYPTO_DEV_CPT=m +CONFIG_CAVIUM_CPT=m +CONFIG_CRYPTO_DEV_CAVIUM_ZIP=m # CONFIG_CRYPTO_DEV_QCE is not set # CONFIG_CRYPTO_DEV_ROCKCHIP is not set CONFIG_CRYPTO_DEV_VIRTIO=m +CONFIG_CRYPTO_DEV_BCM_SPU=m # CONFIG_ASYMMETRIC_KEY_TYPE is not set # # Certificates for signature checking # +# CONFIG_SYSTEM_BLACKLIST_KEYRING is not set CONFIG_ARM64_CRYPTO=y # CONFIG_CRYPTO_SHA256_ARM64 is not set # CONFIG_CRYPTO_SHA512_ARM64 is not set @@ -5514,11 +5756,13 @@ CONFIG_CRYPTO_SHA2_ARM64_CE=y CONFIG_CRYPTO_GHASH_ARM64_CE=y # CONFIG_CRYPTO_CRCT10DIF_ARM64_CE is not set # CONFIG_CRYPTO_CRC32_ARM64_CE is not set +CONFIG_CRYPTO_AES_ARM64=m CONFIG_CRYPTO_AES_ARM64_CE=y CONFIG_CRYPTO_AES_ARM64_CE_CCM=y CONFIG_CRYPTO_AES_ARM64_CE_BLK=y -# CONFIG_CRYPTO_AES_ARM64_NEON_BLK is not set -CONFIG_CRYPTO_CRC32_ARM64=y +CONFIG_CRYPTO_AES_ARM64_NEON_BLK=m +CONFIG_CRYPTO_CHACHA20_NEON=m +CONFIG_CRYPTO_AES_ARM64_BS=m # CONFIG_BINARY_PRINTF is not set # @@ -5577,6 +5821,8 @@ CONFIG_ASSOCIATIVE_ARRAY=y CONFIG_HAS_IOMEM=y CONFIG_HAS_IOPORT_MAP=y CONFIG_HAS_DMA=y +# CONFIG_DMA_NOOP_OPS is not set +# CONFIG_DMA_VIRT_OPS is not set CONFIG_CPU_RMAP=y CONFIG_DQL=y CONFIG_GLOB=y @@ -5596,3 +5842,4 @@ CONFIG_FONT_8x16=y CONFIG_SG_POOL=y CONFIG_ARCH_HAS_SG_CHAIN=y CONFIG_SBITMAP=y +CONFIG_PRIME_NUMBERS=m diff --git a/config/sources/odroidc2.conf b/config/sources/odroidc2.conf index 79e552945..85e295b3f 100644 --- a/config/sources/odroidc2.conf +++ b/config/sources/odroidc2.conf @@ -22,7 +22,7 @@ case $BRANCH in ;; next) KERNELSOURCE=$MAINLINE_KERNEL_SOURCE - KERNELBRANCH='branch:linux-4.10.y' + KERNELBRANCH='branch:linux-4.12.y' KERNELDIR=$MAINLINE_KERNEL_DIR ;; dev) diff --git a/patch/kernel/odroidc2-next/0001-ARM64-dts-meson-gxbb-Add-gpio-ranges.patch b/patch/kernel/odroidc2-next/0001-ARM64-dts-meson-gxbb-Add-gpio-ranges.patch deleted file mode 100644 index 4823cee17..000000000 --- a/patch/kernel/odroidc2-next/0001-ARM64-dts-meson-gxbb-Add-gpio-ranges.patch +++ /dev/null @@ -1,32 +0,0 @@ -From 86f0b91719a9d97095187af6ddaade3b34dc1257 Mon Sep 17 00:00:00 2001 -From: Neil Armstrong -Date: Thu, 16 Mar 2017 09:38:10 +0100 -Subject: [PATCH 01/93] ARM64: dts: meson-gxbb: Add gpio-ranges - ---- - arch/arm64/boot/dts/amlogic/meson-gxbb.dtsi | 2 ++ - 1 file changed, 2 insertions(+) - -diff --git a/arch/arm64/boot/dts/amlogic/meson-gxbb.dtsi b/arch/arm64/boot/dts/amlogic/meson-gxbb.dtsi -index b353073..2be29a3 100644 ---- a/arch/arm64/boot/dts/amlogic/meson-gxbb.dtsi -+++ b/arch/arm64/boot/dts/amlogic/meson-gxbb.dtsi -@@ -186,6 +186,7 @@ - reg-names = "mux", "pull", "gpio"; - gpio-controller; - #gpio-cells = <2>; -+ gpio-ranges = <&pinctrl_aobus 0 0 14>; - }; - - uart_ao_a_pins: uart_ao_a { -@@ -279,6 +280,7 @@ - reg-names = "mux", "pull", "pull-enable", "gpio"; - gpio-controller; - #gpio-cells = <2>; -+ gpio-ranges = <&pinctrl_periphs 0 14 120>; - }; - - emmc_pins: emmc { --- -1.9.1 - diff --git a/patch/kernel/odroidc2-next/0057-Add-HDMI-support-for-Odroid-C2.patch b/patch/kernel/odroidc2-next/0001-Add-HDMI-support-for-Odroid-C2.patch similarity index 82% rename from patch/kernel/odroidc2-next/0057-Add-HDMI-support-for-Odroid-C2.patch rename to patch/kernel/odroidc2-next/0001-Add-HDMI-support-for-Odroid-C2.patch index 4b4c92f71..d8c349319 100644 --- a/patch/kernel/odroidc2-next/0057-Add-HDMI-support-for-Odroid-C2.patch +++ b/patch/kernel/odroidc2-next/0001-Add-HDMI-support-for-Odroid-C2.patch @@ -1,14 +1,15 @@ -From d074af897d4547d239f93b55c7baa4cf47a9f535 Mon Sep 17 00:00:00 2001 +From 8ede929172f118c43ef1664fe66b56dadff3310f Mon Sep 17 00:00:00 2001 From: Neil Armstrong Date: Tue, 28 Feb 2017 15:22:54 +0100 -Subject: [PATCH 57/93] Add HDMI support for Odroid-C2 +Subject: [PATCH 01/79] Add HDMI support for Odroid-C2 +Signed-off-by: Neil Armstrong --- .../arm64/boot/dts/amlogic/meson-gxbb-odroidc2.dts | 23 ++++++++++++++++++++++ 1 file changed, 23 insertions(+) diff --git a/arch/arm64/boot/dts/amlogic/meson-gxbb-odroidc2.dts b/arch/arm64/boot/dts/amlogic/meson-gxbb-odroidc2.dts -index 492ac35..ee77c3d 100644 +index 54a9c6a..0066b1a 100644 --- a/arch/arm64/boot/dts/amlogic/meson-gxbb-odroidc2.dts +++ b/arch/arm64/boot/dts/amlogic/meson-gxbb-odroidc2.dts @@ -135,6 +135,17 @@ @@ -29,7 +30,7 @@ index 492ac35..ee77c3d 100644 }; &scpi_clocks { -@@ -240,3 +251,15 @@ +@@ -309,3 +320,15 @@ vmmc-supply = <&vcc3v3>; vqmmc-supply = <&vcc1v8>; }; diff --git a/patch/kernel/odroidc2-next/0088-drm-meson-select-dw-hdmi-i2s-audio-for-meson-hdmi.patch b/patch/kernel/odroidc2-next/0002-drm-meson-select-dw-hdmi-i2s-audio-for-meson-hdmi.patch similarity index 75% rename from patch/kernel/odroidc2-next/0088-drm-meson-select-dw-hdmi-i2s-audio-for-meson-hdmi.patch rename to patch/kernel/odroidc2-next/0002-drm-meson-select-dw-hdmi-i2s-audio-for-meson-hdmi.patch index e962aaa78..a599999e0 100644 --- a/patch/kernel/odroidc2-next/0088-drm-meson-select-dw-hdmi-i2s-audio-for-meson-hdmi.patch +++ b/patch/kernel/odroidc2-next/0002-drm-meson-select-dw-hdmi-i2s-audio-for-meson-hdmi.patch @@ -1,9 +1,10 @@ -From d3527920b1ab4959557bda86974b143228746ce9 Mon Sep 17 00:00:00 2001 +From aa7bd7ebd01c4a7a1e7f1cdca431e5447313fefc Mon Sep 17 00:00:00 2001 From: Jerome Brunet Date: Tue, 14 Feb 2017 19:18:04 +0100 -Subject: [PATCH 88/93] drm/meson: select dw-hdmi i2s audio for meson hdmi +Subject: [PATCH 02/79] drm/meson: select dw-hdmi i2s audio for meson hdmi Signed-off-by: Jerome Brunet +Signed-off-by: Neil Armstrong --- drivers/gpu/drm/meson/Kconfig | 1 + 1 file changed, 1 insertion(+) diff --git a/patch/kernel/odroidc2-next/0002-pinctrl-meson-use-gpio-ranges-from-DT.patch b/patch/kernel/odroidc2-next/0002-pinctrl-meson-use-gpio-ranges-from-DT.patch deleted file mode 100644 index a99cdbef6..000000000 --- a/patch/kernel/odroidc2-next/0002-pinctrl-meson-use-gpio-ranges-from-DT.patch +++ /dev/null @@ -1,40 +0,0 @@ -From be24356f2a4214a9efbb28441f58cfd91aefb4b4 Mon Sep 17 00:00:00 2001 -From: Neil Armstrong -Date: Thu, 16 Mar 2017 09:40:16 +0100 -Subject: [PATCH 02/93] pinctrl: meson: use gpio-ranges from DT - ---- - drivers/pinctrl/meson/pinctrl-meson.c | 14 +------------- - 1 file changed, 1 insertion(+), 13 deletions(-) - -diff --git a/drivers/pinctrl/meson/pinctrl-meson.c b/drivers/pinctrl/meson/pinctrl-meson.c -index 620c231a..3372ce9 100644 ---- a/drivers/pinctrl/meson/pinctrl-meson.c -+++ b/drivers/pinctrl/meson/pinctrl-meson.c -@@ -557,22 +557,10 @@ static int meson_gpiolib_register(struct meson_pinctrl *pc) - if (ret) { - dev_err(pc->dev, "can't add gpio chip %s\n", - pc->data->name); -- goto fail; -- } -- -- ret = gpiochip_add_pin_range(&pc->chip, dev_name(pc->dev), -- 0, pc->data->pin_base, -- pc->chip.ngpio); -- if (ret) { -- dev_err(pc->dev, "can't add pin range\n"); -- goto fail; -+ return ret; - } - - return 0; --fail: -- gpiochip_remove(&pc->chip); -- -- return ret; - } - - static struct regmap_config meson_regmap_config = { --- -1.9.1 - diff --git a/patch/kernel/odroidc2-next/0003-ARM64-dts-meson-gxbb-Add-USB-Hub-GPIO-hog.patch b/patch/kernel/odroidc2-next/0003-ARM64-dts-meson-gxbb-Add-USB-Hub-GPIO-hog.patch deleted file mode 100644 index ded5b6f23..000000000 --- a/patch/kernel/odroidc2-next/0003-ARM64-dts-meson-gxbb-Add-USB-Hub-GPIO-hog.patch +++ /dev/null @@ -1,32 +0,0 @@ -From 58d7c939ec531f768b03b0be2a714805a6aac3cf Mon Sep 17 00:00:00 2001 -From: Neil Armstrong -Date: Thu, 16 Mar 2017 09:40:48 +0100 -Subject: [PATCH 03/93] ARM64: dts: meson-gxbb: Add USB Hub GPIO hog - ---- - arch/arm64/boot/dts/amlogic/meson-gxbb-odroidc2.dts | 9 +++++++++ - 1 file changed, 9 insertions(+) - -diff --git a/arch/arm64/boot/dts/amlogic/meson-gxbb-odroidc2.dts b/arch/arm64/boot/dts/amlogic/meson-gxbb-odroidc2.dts -index c59403a..492ac35 100644 ---- a/arch/arm64/boot/dts/amlogic/meson-gxbb-odroidc2.dts -+++ b/arch/arm64/boot/dts/amlogic/meson-gxbb-odroidc2.dts -@@ -177,6 +177,15 @@ - pinctrl-names = "default"; - }; - -+&gpio_ao { -+ usb-hub { -+ gpio-hog; -+ gpios = ; -+ output-high; -+ line-name = "usb-hub-reset"; -+ }; -+}; -+ - &usb0_phy { - status = "okay"; - phy-supply = <&usb_otg_pwr>; --- -1.9.1 - diff --git a/patch/kernel/odroidc2-next/0092-drm-bridge-dw-hdmi-Use-AUTO-CTS-setup-mode-when-non-.patch b/patch/kernel/odroidc2-next/0003-drm-bridge-dw-hdmi-Use-AUTO-CTS-setup-mode-when-non-.patch similarity index 92% rename from patch/kernel/odroidc2-next/0092-drm-bridge-dw-hdmi-Use-AUTO-CTS-setup-mode-when-non-.patch rename to patch/kernel/odroidc2-next/0003-drm-bridge-dw-hdmi-Use-AUTO-CTS-setup-mode-when-non-.patch index c46602120..ee3222aac 100644 --- a/patch/kernel/odroidc2-next/0092-drm-bridge-dw-hdmi-Use-AUTO-CTS-setup-mode-when-non-.patch +++ b/patch/kernel/odroidc2-next/0003-drm-bridge-dw-hdmi-Use-AUTO-CTS-setup-mode-when-non-.patch @@ -1,15 +1,16 @@ -From 4dc44c40b6a55b15c2ce5189ce6b9d328b8b4344 Mon Sep 17 00:00:00 2001 +From 095d92c205f588fbeb207a124eb860ea57dd568a Mon Sep 17 00:00:00 2001 From: Neil Armstrong Date: Mon, 27 Mar 2017 11:08:24 +0200 -Subject: [PATCH 92/93] drm: bridge: dw-hdmi: Use AUTO CTS setup mode when +Subject: [PATCH 03/79] drm: bridge: dw-hdmi: Use AUTO CTS setup mode when non-AHB audio +Signed-off-by: Neil Armstrong --- drivers/gpu/drm/bridge/synopsys/dw-hdmi.c | 43 +++++++++++++++++++------------ 1 file changed, 27 insertions(+), 16 deletions(-) diff --git a/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c b/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c -index 910d579..ad8d62a 100644 +index 4e1f54a..ee788ca 100644 --- a/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c +++ b/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c @@ -420,8 +420,12 @@ static void hdmi_set_cts_n(struct dw_hdmi *hdmi, unsigned int cts, diff --git a/patch/kernel/odroidc2-next/0004-drm-fb-helper-Add-multi-buffer-support-for-cma-fbdev.patch b/patch/kernel/odroidc2-next/0004-drm-fb-helper-Add-multi-buffer-support-for-cma-fbdev.patch deleted file mode 100644 index 6ecfe9bb0..000000000 --- a/patch/kernel/odroidc2-next/0004-drm-fb-helper-Add-multi-buffer-support-for-cma-fbdev.patch +++ /dev/null @@ -1,75 +0,0 @@ -From cbe0dba01d39c008cff6460bfcb1366801b4a41c Mon Sep 17 00:00:00 2001 -From: Xinliang Liu -Date: Wed, 15 Feb 2017 17:19:08 +0100 -Subject: [PATCH 04/93] drm/fb-helper: Add multi buffer support for cma fbdev - -This patch add a config to support to create multi buffer for cma fbdev. -Such as double buffer and triple buffer. - -Cma fbdev is convient to add a legency fbdev. And still many Android -devices use fbdev now and at least double buffer is needed for these -Android devices, so that a buffer flip can be operated. It will need -some time for Android device vendors to abondon legency fbdev. So multi -buffer for fbdev is needed. - -Signed-off-by: Xinliang Liu -[s.christ@phytec.de: Picking patch from - https://lkml.org/lkml/2015/9/14/188] -Signed-off-by: Stefan Christ -Signed-off-by: Maxime Ripard ---- - drivers/gpu/drm/Kconfig | 9 +++++++++ - drivers/gpu/drm/drm_fb_helper.c | 10 ++++++++++ - 2 files changed, 19 insertions(+) - -diff --git a/drivers/gpu/drm/Kconfig b/drivers/gpu/drm/Kconfig -index ebfe840..700c8b8 100644 ---- a/drivers/gpu/drm/Kconfig -+++ b/drivers/gpu/drm/Kconfig -@@ -84,6 +84,15 @@ config DRM_FBDEV_EMULATION - - If in doubt, say "Y". - -+config DRM_FBDEV_OVERALLOC -+ int "Overallocation of the fbdev buffer" -+ depends on DRM_FBDEV_EMULATION -+ default 100 -+ help -+ Defines the fbdev buffer overallocation in percent. Default -+ is 100. Typical values for double buffering will be 200, -+ triple buffering 300. -+ - config DRM_LOAD_EDID_FIRMWARE - bool "Allow to specify an EDID data set instead of probing for it" - depends on DRM_KMS_HELPER -diff --git a/drivers/gpu/drm/drm_fb_helper.c b/drivers/gpu/drm/drm_fb_helper.c -index e934b54..c6de87a 100644 ---- a/drivers/gpu/drm/drm_fb_helper.c -+++ b/drivers/gpu/drm/drm_fb_helper.c -@@ -48,6 +48,12 @@ - MODULE_PARM_DESC(fbdev_emulation, - "Enable legacy fbdev emulation [default=true]"); - -+static int drm_fbdev_overalloc = CONFIG_DRM_FBDEV_OVERALLOC; -+module_param(drm_fbdev_overalloc, int, 0444); -+MODULE_PARM_DESC(drm_fbdev_overalloc, -+ "Overallocation of the fbdev buffer (%) [default=" -+ __MODULE_STRING(CONFIG_DRM_FBDEV_OVERALLOC) "]"); -+ - static LIST_HEAD(kernel_fb_helper_list); - static DEFINE_MUTEX(kernel_fb_helper_lock); - -@@ -1573,6 +1579,10 @@ static int drm_fb_helper_single_fb_probe(struct drm_fb_helper *fb_helper, - sizes.fb_height = sizes.surface_height = 768; - } - -+ /* Handle our overallocation */ -+ sizes.surface_height *= drm_fbdev_overalloc; -+ sizes.surface_height /= 100; -+ - /* push down into drivers */ - ret = (*fb_helper->funcs->fb_probe)(fb_helper, &sizes); - if (ret < 0) --- -1.9.1 - diff --git a/patch/kernel/odroidc2-next/0004-dt-bindings-clock-gxbb-aoclk-Add-CEC-32k-clock.patch b/patch/kernel/odroidc2-next/0004-dt-bindings-clock-gxbb-aoclk-Add-CEC-32k-clock.patch new file mode 100644 index 000000000..6ab621cee --- /dev/null +++ b/patch/kernel/odroidc2-next/0004-dt-bindings-clock-gxbb-aoclk-Add-CEC-32k-clock.patch @@ -0,0 +1,26 @@ +From 4923e7dd3aa1d072bb63ee46bdfc59f82de89a9c Mon Sep 17 00:00:00 2001 +From: Neil Armstrong +Date: Tue, 30 May 2017 16:45:06 +0200 +Subject: [PATCH 04/79] dt-bindings: clock: gxbb-aoclk: Add CEC 32k clock + +This patchadds the clock binding entry for the CEC 32K AO Clock. + +Signed-off-by: Neil Armstrong +--- + include/dt-bindings/clock/gxbb-aoclkc.h | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/include/dt-bindings/clock/gxbb-aoclkc.h b/include/dt-bindings/clock/gxbb-aoclkc.h +index 3175148..9d15e22 100644 +--- a/include/dt-bindings/clock/gxbb-aoclkc.h ++++ b/include/dt-bindings/clock/gxbb-aoclkc.h +@@ -62,5 +62,6 @@ + #define CLKID_AO_UART1 3 + #define CLKID_AO_UART2 4 + #define CLKID_AO_IR_BLASTER 5 ++#define CLKID_AO_CEC_32K 6 + + #endif +-- +1.9.1 + diff --git a/patch/kernel/odroidc2-next/0005-clk-meson-gxbb-aoclk-Add-CEC-32k-clock.patch b/patch/kernel/odroidc2-next/0005-clk-meson-gxbb-aoclk-Add-CEC-32k-clock.patch new file mode 100644 index 000000000..c0ac26d01 --- /dev/null +++ b/patch/kernel/odroidc2-next/0005-clk-meson-gxbb-aoclk-Add-CEC-32k-clock.patch @@ -0,0 +1,376 @@ +From 7e59aa215674f39cebb870b68bc0dc54c73cd407 Mon Sep 17 00:00:00 2001 +From: Neil Armstrong +Date: Tue, 30 May 2017 16:45:28 +0200 +Subject: [PATCH 05/79] clk: meson: gxbb-aoclk: Add CEC 32k clock + +The CEC 32K AO Clock is a dual divider with dual counter to provide a more +precise 32768Hz clock for the CEC subsystem from the external xtal. + +The AO clocks management registers are spread among the AO register space, +so this patch also adds management of these registers mappings then uses them +for the CEC 32K AO clock management. + +Signed-off-by: Neil Armstrong +--- + drivers/clk/meson/Makefile | 2 +- + drivers/clk/meson/gxbb-aoclk-32k.c | 188 +++++++++++++++++++++++++++++++++++++ + drivers/clk/meson/gxbb-aoclk.c | 59 ++++++++++-- + drivers/clk/meson/gxbb-aoclk.h | 23 +++++ + 4 files changed, 265 insertions(+), 7 deletions(-) + create mode 100644 drivers/clk/meson/gxbb-aoclk-32k.c + create mode 100644 drivers/clk/meson/gxbb-aoclk.h + +diff --git a/drivers/clk/meson/Makefile b/drivers/clk/meson/Makefile +index 83b6d9d..e315057 100644 +--- a/drivers/clk/meson/Makefile ++++ b/drivers/clk/meson/Makefile +@@ -4,4 +4,4 @@ + + obj-$(CONFIG_COMMON_CLK_AMLOGIC) += clk-pll.o clk-cpu.o clk-mpll.o clk-audio-divider.o + obj-$(CONFIG_COMMON_CLK_MESON8B) += meson8b.o +-obj-$(CONFIG_COMMON_CLK_GXBB) += gxbb.o gxbb-aoclk.o ++obj-$(CONFIG_COMMON_CLK_GXBB) += gxbb.o gxbb-aoclk.o gxbb-aoclk-32k.o +diff --git a/drivers/clk/meson/gxbb-aoclk-32k.c b/drivers/clk/meson/gxbb-aoclk-32k.c +new file mode 100644 +index 0000000..3c06413 +--- /dev/null ++++ b/drivers/clk/meson/gxbb-aoclk-32k.c +@@ -0,0 +1,188 @@ ++/* ++ * Copyright (c) 2017 BayLibre, SAS. ++ * Author: Neil Armstrong ++ * ++ * SPDX-License-Identifier: GPL-2.0+ ++ */ ++ ++#include ++#include ++#include ++#include "gxbb-aoclk.h" ++ ++/* ++ * The AO Domain embeds a dual/divider to generate a more precise ++ * 32,768KHz clock for low-power suspend mode and CEC. ++ */ ++ ++#define AO_RTC_ALT_CLK_CNTL0 0x0 ++#define AO_RTC_ALT_CLK_CNTL1 0x4 ++#define AO_CRT_CLK_CNTL1 0x0 ++#define AO_RTI_PWR_CNTL_REG0 0x4 ++ ++#define CLK_CNTL0_N1_MASK GENMASK(11, 0) ++#define CLK_CNTL0_N2_MASK GENMASK(23, 12) ++#define CLK_CNTL0_DUALDIV_EN BIT(28) ++#define CLK_CNTL0_OUT_GATE_EN BIT(30) ++#define CLK_CNTL0_IN_GATE_EN BIT(31) ++ ++#define CLK_CNTL1_M1_MASK GENMASK(11, 0) ++#define CLK_CNTL1_M2_MASK GENMASK(23, 12) ++#define CLK_CNTL1_BYPASS_EN BIT(24) ++#define CLK_CNTL1_SELECT_OSC BIT(27) ++ ++#define PWR_CNTL_ALT_32K_SEL GENMASK(13, 10) ++ ++struct cec_32k_freq_table { ++ unsigned long parent_rate; ++ unsigned long target_rate; ++ bool dualdiv; ++ unsigned int n1; ++ unsigned int n2; ++ unsigned int m1; ++ unsigned int m2; ++}; ++ ++static const struct cec_32k_freq_table aoclk_cec_32k_table[] = { ++ [0] = { ++ .parent_rate = 24000000, ++ .target_rate = 32768, ++ .dualdiv = true, ++ .n1 = 733, ++ .n2 = 732, ++ .m1 = 8, ++ .m2 = 11, ++ }, ++}; ++ ++/* ++ * If CLK_CNTL0_DUALDIV_EN == 0 ++ * - will use N1 divider only ++ * If CLK_CNTL0_DUALDIV_EN == 1 ++ * - hold M1 cycles of N1 divider then changes to N2 ++ * - hold M2 cycles of N2 divider then changes to N1 ++ * Then we can get more accurate division. ++ */ ++static unsigned long aoclk_cec_32k_recalc_rate(struct clk_hw *hw, ++ unsigned long parent_rate) ++{ ++ struct aoclk_cec_32k *cec_32k = to_aoclk_cec_32k(hw); ++ u32 reg0, reg1; ++ ++ reg0 = readl_relaxed(cec_32k->rtc_base + AO_RTC_ALT_CLK_CNTL0); ++ reg1 = readl_relaxed(cec_32k->rtc_base + AO_RTC_ALT_CLK_CNTL1); ++ ++ if (reg1 & CLK_CNTL1_BYPASS_EN) ++ return parent_rate; ++ ++ if (reg0 & CLK_CNTL0_DUALDIV_EN) { ++ unsigned long n1, n2, m1, m2, f1, f2, p1, p2; ++ ++ n1 = FIELD_GET(CLK_CNTL0_N1_MASK, reg0) + 1; ++ n2 = FIELD_GET(CLK_CNTL0_N2_MASK, reg0) + 1; ++ ++ m1 = FIELD_GET(CLK_CNTL1_M1_MASK, reg1) + 1; ++ m2 = FIELD_GET(CLK_CNTL1_M2_MASK, reg1) + 1; ++ ++ f1 = DIV_ROUND_CLOSEST(parent_rate, n1); ++ f2 = DIV_ROUND_CLOSEST(parent_rate, n2); ++ ++ p1 = DIV_ROUND_CLOSEST(100000000 * m1, f1 * (m1 + m2)); ++ p2 = DIV_ROUND_CLOSEST(100000000 * m2, f2 * (m1 + m2)); ++ ++ return DIV_ROUND_UP(100000000, p1 + p2); ++ } ++ else { ++ unsigned long n1 = FIELD_GET(CLK_CNTL0_N1_MASK, reg0) + 1; ++ ++ return DIV_ROUND_CLOSEST(parent_rate, n1); ++ } ++} ++ ++static const struct cec_32k_freq_table *find_cec_32k_freq(unsigned long rate, ++ unsigned long prate) ++{ ++ int i; ++ ++ for (i = 0 ; i < ARRAY_SIZE(aoclk_cec_32k_table) ; ++i) ++ if (aoclk_cec_32k_table[i].parent_rate == prate && ++ aoclk_cec_32k_table[i].target_rate == rate) ++ return &aoclk_cec_32k_table[i]; ++ ++ return NULL; ++} ++ ++static long aoclk_cec_32k_round_rate(struct clk_hw *hw, unsigned long rate, ++ unsigned long *prate) ++{ ++ const struct cec_32k_freq_table *freq = find_cec_32k_freq(rate, ++ *prate); ++ ++ /* If invalid return first one */ ++ if (!freq) ++ return freq[0].target_rate; ++ ++ return freq->target_rate; ++} ++ ++static int aoclk_cec_32k_set_rate(struct clk_hw *hw, unsigned long rate, ++ unsigned long parent_rate) ++{ ++ const struct cec_32k_freq_table *freq = find_cec_32k_freq(rate, ++ parent_rate); ++ struct aoclk_cec_32k *cec_32k = to_aoclk_cec_32k(hw); ++ u32 reg = 0; ++ ++ if (!freq) ++ return -EINVAL; ++ ++ /* Disable clock */ ++ reg = readl(cec_32k->rtc_base + AO_RTC_ALT_CLK_CNTL0); ++ reg &= ~(CLK_CNTL0_IN_GATE_EN | CLK_CNTL0_OUT_GATE_EN); ++ writel(reg, cec_32k->rtc_base + AO_RTC_ALT_CLK_CNTL0); ++ ++ if (freq->dualdiv) ++ reg = CLK_CNTL0_DUALDIV_EN | ++ FIELD_PREP(CLK_CNTL0_N1_MASK, freq->n1 - 1) | ++ FIELD_PREP(CLK_CNTL0_N2_MASK, freq->n2 - 1); ++ else ++ reg = FIELD_PREP(CLK_CNTL0_N1_MASK, freq->n1 - 1); ++ ++ writel_relaxed(reg, cec_32k->rtc_base + AO_RTC_ALT_CLK_CNTL0); ++ ++ if (freq->dualdiv) ++ reg = FIELD_PREP(CLK_CNTL1_M1_MASK, freq->m1 - 1) | ++ FIELD_PREP(CLK_CNTL1_M2_MASK, freq->m2 - 1); ++ else ++ reg = FIELD_PREP(CLK_CNTL1_M1_MASK, freq->m1 - 1); ++ ++ writel_relaxed(reg, cec_32k->rtc_base + AO_RTC_ALT_CLK_CNTL1); ++ ++ /* Enable clock */ ++ reg = readl(cec_32k->rtc_base + AO_RTC_ALT_CLK_CNTL0); ++ reg |= CLK_CNTL0_IN_GATE_EN; ++ writel(reg, cec_32k->rtc_base + AO_RTC_ALT_CLK_CNTL0); ++ ++ udelay(200); ++ ++ reg |= CLK_CNTL0_OUT_GATE_EN; ++ writel(reg, cec_32k->rtc_base + AO_RTC_ALT_CLK_CNTL0); ++ ++ reg = readl(cec_32k->crt_base + AO_CRT_CLK_CNTL1); ++ reg |= CLK_CNTL1_SELECT_OSC; /* select cts_rtc_oscin_clk */ ++ writel(reg, cec_32k->crt_base + AO_CRT_CLK_CNTL1); ++ ++ /* Select 32k from XTAL */ ++ regmap_write_bits(cec_32k->pwr_regmap, ++ AO_RTI_PWR_CNTL_REG0, ++ PWR_CNTL_ALT_32K_SEL, ++ FIELD_PREP(PWR_CNTL_ALT_32K_SEL, 4)); ++ ++ return 0; ++} ++ ++const struct clk_ops meson_aoclk_cec_32k_ops = { ++ .recalc_rate = aoclk_cec_32k_recalc_rate, ++ .round_rate = aoclk_cec_32k_round_rate, ++ .set_rate = aoclk_cec_32k_set_rate, ++}; +diff --git a/drivers/clk/meson/gxbb-aoclk.c b/drivers/clk/meson/gxbb-aoclk.c +index b45c5fb..e47f021 100644 +--- a/drivers/clk/meson/gxbb-aoclk.c ++++ b/drivers/clk/meson/gxbb-aoclk.c +@@ -56,9 +56,13 @@ + #include + #include + #include ++#include ++#include + #include ++#include + #include + #include ++#include "gxbb-aoclk.h" + + static DEFINE_SPINLOCK(gxbb_aoclk_lock); + +@@ -104,6 +108,17 @@ static int gxbb_aoclk_do_reset(struct reset_controller_dev *rcdev, + GXBB_AO_GATE(uart2, 5); + GXBB_AO_GATE(ir_blaster, 6); + ++static struct aoclk_cec_32k cec_32k_ao = { ++ .lock = &gxbb_aoclk_lock, ++ .hw.init = &(struct clk_init_data) { ++ .name = "cec_32k_ao", ++ .ops = &meson_aoclk_cec_32k_ops, ++ .parent_names = (const char *[]){ "xtal" }, ++ .num_parents = 1, ++ .flags = CLK_IGNORE_UNUSED, ++ }, ++}; ++ + static unsigned int gxbb_aoclk_reset[] = { + [RESET_AO_REMOTE] = 16, + [RESET_AO_I2C_MASTER] = 18, +@@ -130,28 +145,52 @@ static int gxbb_aoclk_do_reset(struct reset_controller_dev *rcdev, + [CLKID_AO_UART1] = &uart1_ao.hw, + [CLKID_AO_UART2] = &uart2_ao.hw, + [CLKID_AO_IR_BLASTER] = &ir_blaster_ao.hw, ++ [CLKID_AO_CEC_32K] = &cec_32k_ao.hw, + }, +- .num = ARRAY_SIZE(gxbb_aoclk_gate), ++ .num = 7, + }; + + static int gxbb_aoclkc_probe(struct platform_device *pdev) + { +- struct resource *res; ++ struct gxbb_aoclk_reset_controller *rstc; ++ struct device *dev = &pdev->dev; ++ struct regmap *regmap_pwr; ++ void __iomem *base_crt; ++ void __iomem *base_rtc; + void __iomem *base; ++ struct resource *res; + int ret, clkid; +- struct device *dev = &pdev->dev; +- struct gxbb_aoclk_reset_controller *rstc; + + rstc = devm_kzalloc(dev, sizeof(*rstc), GFP_KERNEL); + if (!rstc) + return -ENOMEM; + + /* Generic clocks */ +- res = platform_get_resource(pdev, IORESOURCE_MEM, 0); ++ res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "aoclk"); + base = devm_ioremap_resource(dev, res); + if (IS_ERR(base)) + return PTR_ERR(base); + ++ /* CRT base */ ++ res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "aocrt"); ++ base_crt = devm_ioremap_resource(dev, res); ++ if (IS_ERR(base_crt)) ++ return PTR_ERR(base_crt); ++ ++ /* RTC base */ ++ res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "aortc"); ++ base_rtc = devm_ioremap_resource(dev, res); ++ if (IS_ERR(base_rtc)) ++ return PTR_ERR(base_rtc); ++ ++ /* PWR regmap */ ++ regmap_pwr = syscon_regmap_lookup_by_phandle(dev->of_node, ++ "amlogic,pwr-ctrl"); ++ if (IS_ERR(regmap_pwr)) { ++ dev_err(dev, "failed to get PWR regmap\n"); ++ return -ENODEV; ++ } ++ + /* Reset Controller */ + rstc->base = base; + rstc->data = gxbb_aoclk_reset; +@@ -163,7 +202,7 @@ static int gxbb_aoclkc_probe(struct platform_device *pdev) + /* + * Populate base address and register all clks + */ +- for (clkid = 0; clkid < gxbb_aoclk_onecell_data.num; clkid++) { ++ for (clkid = 0; clkid < ARRAY_SIZE(gxbb_aoclk_gate); clkid++) { + gxbb_aoclk_gate[clkid]->reg = base; + + ret = devm_clk_hw_register(dev, +@@ -172,6 +211,14 @@ static int gxbb_aoclkc_probe(struct platform_device *pdev) + return ret; + } + ++ /* Specific clocks */ ++ cec_32k_ao.crt_base = base_crt; ++ cec_32k_ao.rtc_base = base_rtc; ++ cec_32k_ao.pwr_regmap = regmap_pwr; ++ ret = devm_clk_hw_register(dev, &cec_32k_ao.hw); ++ if (ret) ++ return ret; ++ + return of_clk_add_hw_provider(dev->of_node, of_clk_hw_onecell_get, + &gxbb_aoclk_onecell_data); + } +diff --git a/drivers/clk/meson/gxbb-aoclk.h b/drivers/clk/meson/gxbb-aoclk.h +new file mode 100644 +index 0000000..5925a6b +--- /dev/null ++++ b/drivers/clk/meson/gxbb-aoclk.h +@@ -0,0 +1,23 @@ ++/* ++ * Copyright (c) 2017 BayLibre, SAS ++ * Author: Neil Armstrong ++ * ++ * SPDX-License-Identifier: GPL-2.0+ ++ */ ++ ++#ifndef __GXBB_AOCLKC_H ++#define __GXBB_AOCLKC_H ++ ++struct aoclk_cec_32k { ++ struct clk_hw hw; ++ void __iomem *crt_base; ++ void __iomem *rtc_base; ++ struct regmap *pwr_regmap; ++ spinlock_t *lock; ++}; ++ ++#define to_aoclk_cec_32k(_hw) container_of(_hw, struct aoclk_cec_32k, hw) ++ ++extern const struct clk_ops meson_aoclk_cec_32k_ops; ++ ++#endif /* __GXBB_AOCLKC_H */ +-- +1.9.1 + diff --git a/patch/kernel/odroidc2-next/0005-drm-fb-helper-implement-ioctl-FBIO_WAITFORVSYNC.patch b/patch/kernel/odroidc2-next/0005-drm-fb-helper-implement-ioctl-FBIO_WAITFORVSYNC.patch deleted file mode 100644 index e1ca55749..000000000 --- a/patch/kernel/odroidc2-next/0005-drm-fb-helper-implement-ioctl-FBIO_WAITFORVSYNC.patch +++ /dev/null @@ -1,135 +0,0 @@ -From c48872078789c6911e47e1c74d2024407c4daa8d Mon Sep 17 00:00:00 2001 -From: Stefan Christ -Date: Wed, 15 Feb 2017 17:19:09 +0100 -Subject: [PATCH 05/93] drm/fb-helper: implement ioctl FBIO_WAITFORVSYNC - -Implement legacy framebuffer ioctl FBIO_WAITFORVSYNC in the generic -framebuffer emulation driver. Legacy framebuffer users like non kms/drm -based OpenGL(ES)/EGL implementations may require the ioctl to -synchronize drawing or buffer flip for double buffering. It is tested on -the i.MX6. - -Code is based on - https://github.com/Xilinx/linux-xlnx/blob/master/drivers/gpu/drm/xilinx/xilinx_drm_fb.c#L196 - -Signed-off-by: Stefan Christ -Signed-off-by: Maxime Ripard ---- - drivers/gpu/drm/drm_fb_helper.c | 63 +++++++++++++++++++++++++++++++++++++++++ - include/drm/drm_fb_helper.h | 12 +++++++- - 2 files changed, 74 insertions(+), 1 deletion(-) - -diff --git a/drivers/gpu/drm/drm_fb_helper.c b/drivers/gpu/drm/drm_fb_helper.c -index c6de87a..15ee964 100644 ---- a/drivers/gpu/drm/drm_fb_helper.c -+++ b/drivers/gpu/drm/drm_fb_helper.c -@@ -1240,6 +1240,69 @@ int drm_fb_helper_setcmap(struct fb_cmap *cmap, struct fb_info *info) - EXPORT_SYMBOL(drm_fb_helper_setcmap); - - /** -+ * drm_fb_helper_ioctl - legacy ioctl implementation -+ * @info: fbdev registered by the helper -+ * @cmd: ioctl command -+ * @arg: ioctl argument -+ * -+ * A helper to implement the standard fbdev ioctl. Only -+ * FBIO_WAITFORVSYNC is implemented for now. -+ */ -+int drm_fb_helper_ioctl(struct fb_info *info, unsigned int cmd, -+ unsigned long arg) -+{ -+ struct drm_fb_helper *fb_helper = info->par; -+ struct drm_device *dev = fb_helper->dev; -+ struct drm_mode_set *mode_set; -+ struct drm_crtc *crtc; -+ u32 karg; -+ int ret = 0; -+ -+ mutex_lock(&dev->mode_config.mutex); -+ if (!drm_fb_helper_is_bound(fb_helper)) { -+ ret = -EBUSY; -+ goto unlock; -+ } -+ -+ switch (cmd) { -+ case FBIO_WAITFORVSYNC: -+ if (get_user(karg, (__u32 __user *)arg)) { -+ ret = -EFAULT; -+ goto unlock; -+ } -+ -+ if (karg >= fb_helper->crtc_count) { -+ ret = -EINVAL; -+ goto unlock; -+ } -+ -+ mode_set = &fb_helper->crtc_info[karg].mode_set; -+ crtc = mode_set->crtc; -+ -+ /* -+ * Only wait for a vblank event if the CRTC is -+ * enabled, otherwise just don't do anythintg, -+ * not even report an error. -+ */ -+ ret = drm_crtc_vblank_get(crtc); -+ if (!ret) { -+ drm_crtc_wait_one_vblank(crtc); -+ drm_crtc_vblank_put(crtc); -+ } -+ -+ ret = 0; -+ goto unlock; -+ default: -+ ret = -ENOTTY; -+ } -+ -+unlock: -+ mutex_unlock(&dev->mode_config.mutex); -+ return ret; -+} -+EXPORT_SYMBOL(drm_fb_helper_ioctl); -+ -+/** - * drm_fb_helper_check_var - implementation for ->fb_check_var - * @var: screeninfo to check - * @info: fbdev registered by the helper -diff --git a/include/drm/drm_fb_helper.h b/include/drm/drm_fb_helper.h -index 975deed..2891888 100644 ---- a/include/drm/drm_fb_helper.h -+++ b/include/drm/drm_fb_helper.h -@@ -230,7 +230,8 @@ struct drm_fb_helper { - .fb_blank = drm_fb_helper_blank, \ - .fb_pan_display = drm_fb_helper_pan_display, \ - .fb_debug_enter = drm_fb_helper_debug_enter, \ -- .fb_debug_leave = drm_fb_helper_debug_leave -+ .fb_debug_leave = drm_fb_helper_debug_leave, \ -+ .fb_ioctl = drm_fb_helper_ioctl - - #ifdef CONFIG_DRM_FBDEV_EMULATION - void drm_fb_helper_prepare(struct drm_device *dev, struct drm_fb_helper *helper, -@@ -286,6 +287,9 @@ void drm_fb_helper_set_suspend_unlocked(struct drm_fb_helper *fb_helper, - - int drm_fb_helper_setcmap(struct fb_cmap *cmap, struct fb_info *info); - -+int drm_fb_helper_ioctl(struct fb_info *info, unsigned int cmd, -+ unsigned long arg); -+ - int drm_fb_helper_hotplug_event(struct drm_fb_helper *fb_helper); - int drm_fb_helper_initial_config(struct drm_fb_helper *fb_helper, int bpp_sel); - int drm_fb_helper_single_add_all_connectors(struct drm_fb_helper *fb_helper); -@@ -377,6 +381,12 @@ static inline int drm_fb_helper_setcmap(struct fb_cmap *cmap, - return 0; - } - -+static inline int drm_fb_helper_ioctl(struct fb_info *info, unsigned int cmd, -+ unsigned long arg) -+{ -+ return 0; -+} -+ - static inline void drm_fb_helper_unlink_fbi(struct drm_fb_helper *fb_helper) - { - } --- -1.9.1 - diff --git a/patch/kernel/odroidc2-next/0006-ARM64-dts-meson-gx-Add-PWR-and-CRT-RTC-nodes-and-adr.patch b/patch/kernel/odroidc2-next/0006-ARM64-dts-meson-gx-Add-PWR-and-CRT-RTC-nodes-and-adr.patch new file mode 100644 index 000000000..e4ae38c76 --- /dev/null +++ b/patch/kernel/odroidc2-next/0006-ARM64-dts-meson-gx-Add-PWR-and-CRT-RTC-nodes-and-adr.patch @@ -0,0 +1,45 @@ +From 9fa0d1f1e56768773b58eb486bf59561b1cc6e18 Mon Sep 17 00:00:00 2001 +From: Neil Armstrong +Date: Fri, 23 Jun 2017 15:27:38 +0200 +Subject: [PATCH 06/79] ARM64: dts: meson-gx: Add PWR and CRT/RTC nodes and + adresses + +The AO 32KHz generation registers are split among multiple registers : + - The CRT Control + - The RTC Clock Control + - The AO Domain PWR Control + +Signed-off-by: Neil Armstrong +--- + arch/arm64/boot/dts/amlogic/meson-gx.dtsi | 11 ++++++++++- + 1 file changed, 10 insertions(+), 1 deletion(-) + +diff --git a/arch/arm64/boot/dts/amlogic/meson-gx.dtsi b/arch/arm64/boot/dts/amlogic/meson-gx.dtsi +index 436b875..4fd2926 100644 +--- a/arch/arm64/boot/dts/amlogic/meson-gx.dtsi ++++ b/arch/arm64/boot/dts/amlogic/meson-gx.dtsi +@@ -358,11 +358,20 @@ + #size-cells = <2>; + ranges = <0x0 0x0 0x0 0xc8100000 0x0 0x100000>; + ++ pwr_AO: power-control@00c { ++ compatible = "amlogic,gx-pwr-ctrl", "syscon"; ++ reg = <0x0 0x0000c 0x0 0x8>; ++ }; ++ + clkc_AO: clock-controller@040 { + compatible = "amlogic,gx-aoclkc", "amlogic,gxbb-aoclkc"; +- reg = <0x0 0x00040 0x0 0x4>; ++ reg = <0x0 0x00040 0x0 0x4>, ++ <0x0 0x00068 0x0 0x4>, ++ <0x0 0x00094 0x0 0x8>; ++ reg-names = "aoclk", "aocrt", "aortc"; + #clock-cells = <1>; + #reset-cells = <1>; ++ amlogic,pwr-ctrl = <&pwr_AO>; + }; + + uart_AO: serial@4c0 { +-- +1.9.1 + diff --git a/patch/kernel/odroidc2-next/0006-Disable-DRM-fbdev-FBIO_WAITFORVSYNC-to-achieve-full-.patch b/patch/kernel/odroidc2-next/0006-Disable-DRM-fbdev-FBIO_WAITFORVSYNC-to-achieve-full-.patch deleted file mode 100644 index fc31f9ce0..000000000 --- a/patch/kernel/odroidc2-next/0006-Disable-DRM-fbdev-FBIO_WAITFORVSYNC-to-achieve-full-.patch +++ /dev/null @@ -1,24 +0,0 @@ -From e0c4b1d6b1ac850cb22d574bb485b3cc2ed36903 Mon Sep 17 00:00:00 2001 -From: Neil Armstrong -Date: Tue, 28 Feb 2017 15:23:14 +0100 -Subject: [PATCH 06/93] Disable DRM fbdev FBIO_WAITFORVSYNC to achieve full FPS - ---- - drivers/gpu/drm/drm_fb_helper.c | 1 + - 1 file changed, 1 insertion(+) - -diff --git a/drivers/gpu/drm/drm_fb_helper.c b/drivers/gpu/drm/drm_fb_helper.c -index 15ee964..7b739a8 100644 ---- a/drivers/gpu/drm/drm_fb_helper.c -+++ b/drivers/gpu/drm/drm_fb_helper.c -@@ -1266,6 +1266,7 @@ int drm_fb_helper_ioctl(struct fb_info *info, unsigned int cmd, - - switch (cmd) { - case FBIO_WAITFORVSYNC: -+ goto unlock; - if (get_user(karg, (__u32 __user *)arg)) { - ret = -EFAULT; - goto unlock; --- -1.9.1 - diff --git a/patch/kernel/odroidc2-next/0007-ARM64-dts-meson-gx-Add-AO-CEC-nodes.patch b/patch/kernel/odroidc2-next/0007-ARM64-dts-meson-gx-Add-AO-CEC-nodes.patch new file mode 100644 index 000000000..1d10dc2cb --- /dev/null +++ b/patch/kernel/odroidc2-next/0007-ARM64-dts-meson-gx-Add-AO-CEC-nodes.patch @@ -0,0 +1,208 @@ +From abcaac146da294f437f1a8589b27aced142b4da5 Mon Sep 17 00:00:00 2001 +From: Neil Armstrong +Date: Tue, 30 May 2017 16:46:16 +0200 +Subject: [PATCH 07/79] ARM64: dts: meson-gx: Add AO CEC nodes + +This patch adds the AO CEC node in all the HDMI enabled boards DTS. + +Signed-off-by: Neil Armstrong +--- + arch/arm64/boot/dts/amlogic/meson-gx-p23x-q20x.dtsi | 7 +++++++ + arch/arm64/boot/dts/amlogic/meson-gx.dtsi | 6 ++++++ + arch/arm64/boot/dts/amlogic/meson-gxbb-nexbox-a95x.dts | 7 +++++++ + arch/arm64/boot/dts/amlogic/meson-gxbb-p20x.dtsi | 7 +++++++ + arch/arm64/boot/dts/amlogic/meson-gxbb.dtsi | 6 ++++++ + arch/arm64/boot/dts/amlogic/meson-gxl-s905d-p230.dts | 7 +++++++ + arch/arm64/boot/dts/amlogic/meson-gxl-s905x-nexbox-a95x.dts | 7 +++++++ + arch/arm64/boot/dts/amlogic/meson-gxl-s905x-p212.dts | 7 +++++++ + arch/arm64/boot/dts/amlogic/meson-gxl.dtsi | 6 ++++++ + arch/arm64/boot/dts/amlogic/meson-gxm-nexbox-a1.dts | 7 +++++++ + 10 files changed, 67 insertions(+) + +diff --git a/arch/arm64/boot/dts/amlogic/meson-gx-p23x-q20x.dtsi b/arch/arm64/boot/dts/amlogic/meson-gx-p23x-q20x.dtsi +index a84e276..54718ee 100644 +--- a/arch/arm64/boot/dts/amlogic/meson-gx-p23x-q20x.dtsi ++++ b/arch/arm64/boot/dts/amlogic/meson-gx-p23x-q20x.dtsi +@@ -210,6 +210,13 @@ + status = "okay"; + }; + ++&cec_AO { ++ status = "okay"; ++ pinctrl-0 = <&ao_cec_pins>; ++ pinctrl-names = "default"; ++ hdmi-phandle = <&hdmi_tx>; ++}; ++ + &cvbs_vdac_port { + cvbs_vdac_out: endpoint { + remote-endpoint = <&cvbs_connector_in>; +diff --git a/arch/arm64/boot/dts/amlogic/meson-gx.dtsi b/arch/arm64/boot/dts/amlogic/meson-gx.dtsi +index 4fd2926..8901eeb 100644 +--- a/arch/arm64/boot/dts/amlogic/meson-gx.dtsi ++++ b/arch/arm64/boot/dts/amlogic/meson-gx.dtsi +@@ -374,6 +374,12 @@ + amlogic,pwr-ctrl = <&pwr_AO>; + }; + ++ cec_AO: cec@100 { ++ compatible = "amlogic,meson-gx-ao-cec"; ++ reg = <0x0 0x00100 0x0 0x14>; ++ interrupts = ; ++ }; ++ + uart_AO: serial@4c0 { + compatible = "amlogic,meson-uart"; + reg = <0x0 0x004c0 0x0 0x14>; +diff --git a/arch/arm64/boot/dts/amlogic/meson-gxbb-nexbox-a95x.dts b/arch/arm64/boot/dts/amlogic/meson-gxbb-nexbox-a95x.dts +index 87198ea..9af807e 100644 +--- a/arch/arm64/boot/dts/amlogic/meson-gxbb-nexbox-a95x.dts ++++ b/arch/arm64/boot/dts/amlogic/meson-gxbb-nexbox-a95x.dts +@@ -171,6 +171,13 @@ + pinctrl-names = "default"; + }; + ++&cec_AO { ++ status = "okay"; ++ pinctrl-0 = <&ao_cec_pins>; ++ pinctrl-names = "default"; ++ hdmi-phandle = <&hdmi_tx>; ++}; ++ + ðmac { + status = "okay"; + pinctrl-0 = <ð_rmii_pins>; +diff --git a/arch/arm64/boot/dts/amlogic/meson-gxbb-p20x.dtsi b/arch/arm64/boot/dts/amlogic/meson-gxbb-p20x.dtsi +index 3c6c0b7..3ed5c99 100644 +--- a/arch/arm64/boot/dts/amlogic/meson-gxbb-p20x.dtsi ++++ b/arch/arm64/boot/dts/amlogic/meson-gxbb-p20x.dtsi +@@ -250,6 +250,13 @@ + clock-names = "clkin0"; + }; + ++&cec_AO { ++ status = "okay"; ++ pinctrl-0 = <&ao_cec_pins>; ++ pinctrl-names = "default"; ++ hdmi-phandle = <&hdmi_tx>; ++}; ++ + &cvbs_vdac_port { + cvbs_vdac_out: endpoint { + remote-endpoint = <&cvbs_connector_in>; +diff --git a/arch/arm64/boot/dts/amlogic/meson-gxbb.dtsi b/arch/arm64/boot/dts/amlogic/meson-gxbb.dtsi +index 86105a6..d760d93 100644 +--- a/arch/arm64/boot/dts/amlogic/meson-gxbb.dtsi ++++ b/arch/arm64/boot/dts/amlogic/meson-gxbb.dtsi +@@ -97,6 +97,12 @@ + }; + }; + ++ ++&cec_AO { ++ clocks = <&clkc_AO CLKID_AO_CEC_32K>; ++ clock-names = "core"; ++}; ++ + ðmac { + clocks = <&clkc CLKID_ETH>, + <&clkc CLKID_FCLK_DIV2>, +diff --git a/arch/arm64/boot/dts/amlogic/meson-gxl-s905d-p230.dts b/arch/arm64/boot/dts/amlogic/meson-gxl-s905d-p230.dts +index f9fbfda..49e19aa 100644 +--- a/arch/arm64/boot/dts/amlogic/meson-gxl-s905d-p230.dts ++++ b/arch/arm64/boot/dts/amlogic/meson-gxl-s905d-p230.dts +@@ -86,6 +86,13 @@ + }; + }; + ++&cec_AO { ++ status = "okay"; ++ pinctrl-0 = <&ao_cec_pins>; ++ pinctrl-names = "default"; ++ hdmi-phandle = <&hdmi_tx>; ++}; ++ + /* P230 has exclusive choice between internal or external PHY */ + ðmac { + pinctrl-0 = <ð_pins>; +diff --git a/arch/arm64/boot/dts/amlogic/meson-gxl-s905x-nexbox-a95x.dts b/arch/arm64/boot/dts/amlogic/meson-gxl-s905x-nexbox-a95x.dts +index 8873c05..55ec11a 100644 +--- a/arch/arm64/boot/dts/amlogic/meson-gxl-s905x-nexbox-a95x.dts ++++ b/arch/arm64/boot/dts/amlogic/meson-gxl-s905x-nexbox-a95x.dts +@@ -225,6 +225,13 @@ + clock-names = "clkin0"; + }; + ++&cec_AO { ++ status = "okay"; ++ pinctrl-0 = <&ao_cec_pins>; ++ pinctrl-names = "default"; ++ hdmi-phandle = <&hdmi_tx>; ++}; ++ + &cvbs_vdac_port { + cvbs_vdac_out: endpoint { + remote-endpoint = <&cvbs_connector_in>; +diff --git a/arch/arm64/boot/dts/amlogic/meson-gxl-s905x-p212.dts b/arch/arm64/boot/dts/amlogic/meson-gxl-s905x-p212.dts +index db31e09..99a01ff 100644 +--- a/arch/arm64/boot/dts/amlogic/meson-gxl-s905x-p212.dts ++++ b/arch/arm64/boot/dts/amlogic/meson-gxl-s905x-p212.dts +@@ -60,6 +60,13 @@ + }; + }; + ++&cec_AO { ++ status = "okay"; ++ pinctrl-0 = <&ao_cec_pins>; ++ pinctrl-names = "default"; ++ hdmi-phandle = <&hdmi_tx>; ++}; ++ + &cvbs_vdac_port { + cvbs_vdac_out: endpoint { + remote-endpoint = <&cvbs_connector_in>; +diff --git a/arch/arm64/boot/dts/amlogic/meson-gxl.dtsi b/arch/arm64/boot/dts/amlogic/meson-gxl.dtsi +index d8e096d..3a1ccf5 100644 +--- a/arch/arm64/boot/dts/amlogic/meson-gxl.dtsi ++++ b/arch/arm64/boot/dts/amlogic/meson-gxl.dtsi +@@ -43,6 +43,7 @@ + + #include "meson-gx.dtsi" + #include ++#include + #include + #include + +@@ -564,6 +565,11 @@ + compatible = "amlogic,meson-gxl-vpu", "amlogic,meson-gx-vpu"; + }; + ++&cec_AO { ++ clocks = <&clkc_AO CLKID_AO_CEC_32K>; ++ clock-names = "core"; ++}; ++ + &hdmi_tx { + compatible = "amlogic,meson-gxl-dw-hdmi", "amlogic,meson-gx-dw-hdmi"; + resets = <&reset RESET_HDMITX_CAPB3>, +diff --git a/arch/arm64/boot/dts/amlogic/meson-gxm-nexbox-a1.dts b/arch/arm64/boot/dts/amlogic/meson-gxm-nexbox-a1.dts +index 11b0bf4..3a327dd 100644 +--- a/arch/arm64/boot/dts/amlogic/meson-gxm-nexbox-a1.dts ++++ b/arch/arm64/boot/dts/amlogic/meson-gxm-nexbox-a1.dts +@@ -191,6 +191,13 @@ + }; + }; + ++&cec_AO { ++ status = "okay"; ++ pinctrl-0 = <&ao_cec_pins>; ++ pinctrl-names = "default"; ++ hdmi-phandle = <&hdmi_tx>; ++}; ++ + &cvbs_vdac_port { + cvbs_vdac_out: endpoint { + remote-endpoint = <&cvbs_connector_in>; +-- +1.9.1 + diff --git a/patch/kernel/odroidc2-next/0007-clk-meson-gxbb-Add-MALI-clocks-and-fix-GP0-pll-suppo.patch b/patch/kernel/odroidc2-next/0007-clk-meson-gxbb-Add-MALI-clocks-and-fix-GP0-pll-suppo.patch deleted file mode 100644 index bb4418828..000000000 --- a/patch/kernel/odroidc2-next/0007-clk-meson-gxbb-Add-MALI-clocks-and-fix-GP0-pll-suppo.patch +++ /dev/null @@ -1,442 +0,0 @@ -From bc80d5294931d37c19ef76d0a1bb144ad51b66f9 Mon Sep 17 00:00:00 2001 -From: Neil Armstrong -Date: Wed, 1 Feb 2017 11:45:04 +0100 -Subject: [PATCH 07/93] clk: meson-gxbb: Add MALI clocks and fix GP0 pll - support - -The Mali is clocked by two identical clock paths behind a glitch free mux -to safely change frequency while running. - -The optimal clock frequency is provided by the GP0 PLL, but unlike Meson8 the -GXBB GP0 PLL needs some tweaking and need some SoC specific values to be set -in order to setup the PLL. - -Since these values will change for GXL and GXM, add an init table that will -be changed for GXL or GXM. - -For the MALI clocks, introduce them as Composite clocks to simplify the -management. -To handle composite clocks, a gxbb_composite structure is added to dynamically -create the composite clock at probe and fill accordingly the DT table. - -Finally the glitch free mux is added and other muxes and dividers are also -grouped in initialization tables. ---- - drivers/clk/meson/clk-pll.c | 34 ++++-- - drivers/clk/meson/clkc.h | 3 + - drivers/clk/meson/gxbb.c | 211 +++++++++++++++++++++++++++++++++- - drivers/clk/meson/gxbb.h | 7 +- - include/dt-bindings/clock/gxbb-clkc.h | 4 + - 5 files changed, 245 insertions(+), 14 deletions(-) - -diff --git a/drivers/clk/meson/clk-pll.c b/drivers/clk/meson/clk-pll.c -index 4adc1e8..b5ff81b 100644 ---- a/drivers/clk/meson/clk-pll.c -+++ b/drivers/clk/meson/clk-pll.c -@@ -132,6 +132,24 @@ static int meson_clk_pll_wait_lock(struct meson_clk_pll *pll, - return -ETIMEDOUT; - } - -+static void meson_clk_pll_init(struct meson_clk_pll *pll) -+{ -+ if (pll->init_count && pll->init_regs && pll->init_data) { -+ unsigned int i; -+ -+ for (i = 0; i < pll->init_count; ++i) -+ writel(pll->init_data[i], pll->init_regs[i]); -+ } else { -+ struct parm *p; -+ u32 reg; -+ -+ /* PLL reset */ -+ p = &pll->n; -+ reg = readl(pll->base + p->reg_off); -+ writel(reg | MESON_PLL_RESET, pll->base + p->reg_off); -+ } -+} -+ - static int meson_clk_pll_set_rate(struct clk_hw *hw, unsigned long rate, - unsigned long parent_rate) - { -@@ -151,19 +169,18 @@ static int meson_clk_pll_set_rate(struct clk_hw *hw, unsigned long rate, - if (!rate_set) - return -EINVAL; - -- /* PLL reset */ -- p = &pll->n; -- reg = readl(pll->base + p->reg_off); -- writel(reg | MESON_PLL_RESET, pll->base + p->reg_off); -- -- reg = PARM_SET(p->width, p->shift, reg, rate_set->n); -- writel(reg, pll->base + p->reg_off); -+ meson_clk_pll_init(pll); - - p = &pll->m; - reg = readl(pll->base + p->reg_off); - reg = PARM_SET(p->width, p->shift, reg, rate_set->m); - writel(reg, pll->base + p->reg_off); - -+ p = &pll->n; -+ reg = readl(pll->base + p->reg_off); -+ reg = PARM_SET(p->width, p->shift, reg, rate_set->n); -+ writel(reg, pll->base + p->reg_off); -+ - p = &pll->od; - reg = readl(pll->base + p->reg_off); - reg = PARM_SET(p->width, p->shift, reg, rate_set->od); -@@ -184,6 +201,9 @@ static int meson_clk_pll_set_rate(struct clk_hw *hw, unsigned long rate, - } - - p = &pll->n; -+ reg = readl(pll->base + p->reg_off); -+ writel(reg & ~MESON_PLL_RESET, pll->base + p->reg_off); -+ - ret = meson_clk_pll_wait_lock(pll, p); - if (ret) { - pr_warn("%s: pll did not lock, trying to restore old rate %lu\n", -diff --git a/drivers/clk/meson/clkc.h b/drivers/clk/meson/clkc.h -index 9bb70e7..22a6335 100644 ---- a/drivers/clk/meson/clkc.h -+++ b/drivers/clk/meson/clkc.h -@@ -70,6 +70,9 @@ struct meson_clk_pll { - struct parm frac; - struct parm od; - struct parm od2; -+ void __iomem **init_regs; -+ u32 *init_data; -+ unsigned int init_count; - const struct pll_rate_table *rate_table; - unsigned int rate_count; - spinlock_t *lock; -diff --git a/drivers/clk/meson/gxbb.c b/drivers/clk/meson/gxbb.c -index 9d9af44..d1dac0f 100644 ---- a/drivers/clk/meson/gxbb.c -+++ b/drivers/clk/meson/gxbb.c -@@ -352,6 +352,20 @@ - }, - }; - -+static void __iomem *gxbb_gp0_init_regs[] = { -+ (void *)HHI_GP0_PLL_CNTL, -+ (void *)HHI_GP0_PLL_CNTL2, -+ (void *)HHI_GP0_PLL_CNTL3, -+ (void *)HHI_GP0_PLL_CNTL4, -+}; -+ -+static u32 gxbb_gp0_init_data[] = { -+ 0x6a000228, -+ 0x69c80000, -+ 0x0a5590c4, -+ 0x0000500d, -+}; -+ - static struct meson_clk_pll gxbb_gp0_pll = { - .m = { - .reg_off = HHI_GP0_PLL_CNTL, -@@ -368,6 +382,9 @@ - .shift = 16, - .width = 2, - }, -+ .init_regs = gxbb_gp0_init_regs, -+ .init_data = gxbb_gp0_init_data, -+ .init_count = 4, - .rate_table = gp0_pll_rate_table, - .rate_count = ARRAY_SIZE(gp0_pll_rate_table), - .lock = &clk_lock, -@@ -550,6 +567,75 @@ - }, - }; - -+/* Mali Clock components */ -+static u32 mux_table_mali_0_1[] = {0, 1, 2, 3, 4, 5, 6, 7}; -+const char *gxbb_mali_0_1_parent_names[] = { -+ "xtal", "gp0_pll", "mpll2", "mpll1", "fclk_div7", -+ "fclk_div4", "fclk_div3", "fclk_div5" -+}; -+ -+static struct clk_mux gxbb_mali_0_sel = { -+ .reg = (void *)HHI_MALI_CLK_CNTL, -+ .mask = 0x3, -+ .shift = 9, -+ .table = mux_table_mali_0_1, -+ .lock = &clk_lock, -+}; -+ -+static struct clk_divider gxbb_mali_0_div = { -+ .reg = (void *)HHI_MALI_CLK_CNTL, -+ .shift = 0, -+ .width = 7, -+ .lock = &clk_lock, -+}; -+ -+static struct clk_gate gxbb_mali_0_en = { -+ .reg = (void *)HHI_MALI_CLK_CNTL, -+ .bit_idx = 8, -+ .lock = &clk_lock, -+}; -+ -+static struct clk_mux gxbb_mali_1_sel = { -+ .reg = (void *)HHI_MALI_CLK_CNTL, -+ .mask = 0x3, -+ .shift = 25, -+ .table = mux_table_mali_0_1, -+ .lock = &clk_lock, -+}; -+ -+static struct clk_divider gxbb_mali_1_div = { -+ .reg = (void *)HHI_MALI_CLK_CNTL, -+ .shift = 16, -+ .width = 7, -+ .lock = &clk_lock, -+}; -+ -+static struct clk_gate gxbb_mali_1_en = { -+ .reg = (void *)HHI_MALI_CLK_CNTL, -+ .bit_idx = 24, -+ .lock = &clk_lock, -+}; -+ -+static u32 mux_table_mali[] = {0, 1}; -+const char *gxbb_mali_parent_names[] = { -+ "mali_0", "mali_1" -+}; -+ -+static struct clk_mux gxbb_mali = { -+ .reg = (void *)HHI_MALI_CLK_CNTL, -+ .mask = 1, -+ .shift = 31, -+ .table = mux_table_mali, -+ .lock = &clk_lock, -+ .hw.init = &(struct clk_init_data){ -+ .name = "mali", -+ .ops = &clk_mux_ops, -+ .parent_names = gxbb_mali_parent_names, -+ .num_parents = 2, -+ .flags = (CLK_SET_RATE_NO_REPARENT | CLK_IGNORE_UNUSED), -+ }, -+}; -+ - /* the mother of dragons^W gates */ - static struct clk_gate gxbb_clk81 = { - .reg = (void *)HHI_MPEG_CLK_CNTL, -@@ -754,6 +840,9 @@ - [CLKID_SD_EMMC_A] = &gxbb_emmc_a.hw, - [CLKID_SD_EMMC_B] = &gxbb_emmc_b.hw, - [CLKID_SD_EMMC_C] = &gxbb_emmc_c.hw, -+ [CLKID_MALI] = &gxbb_mali.hw, -+ /* This sentinel entry makes sure the table is large enough */ -+ [NR_CLKS] = NULL, /* Sentinel */ - }, - .num = NR_CLKS, - }; -@@ -856,6 +945,66 @@ - &gxbb_emmc_a, - &gxbb_emmc_b, - &gxbb_emmc_c, -+ &gxbb_mali_0_en, -+ &gxbb_mali_1_en, -+}; -+ -+static struct clk_mux *gxbb_clk_muxes[] = { -+ &gxbb_mpeg_clk_sel, -+ &gxbb_mali_0_sel, -+ &gxbb_mali_1_sel, -+ &gxbb_mali, -+}; -+ -+static struct clk_divider *gxbb_clk_dividers[] = { -+ &gxbb_mpeg_clk_div, -+ &gxbb_mali_0_div, -+ &gxbb_mali_1_div, -+}; -+ -+struct gxbb_composite_clk { -+ unsigned int id; -+ const char *name; -+ const char * const *parent_names; -+ int num_parents; -+ struct clk_hw *mux_hw; -+ const struct clk_ops *mux_ops; -+ struct clk_hw *rate_hw; -+ const struct clk_ops *rate_ops; -+ struct clk_hw *gate_hw; -+ const struct clk_ops *gate_ops; -+ unsigned long flags; -+}; -+ -+/* Convenient table to register the composite clocks */ -+ -+static struct gxbb_composite_clk gxbb_composite_clks[] = { -+ { -+ .id = CLKID_MALI_0, -+ .name = "mali_0", -+ .parent_names = gxbb_mali_0_1_parent_names, -+ .num_parents = ARRAY_SIZE(gxbb_mali_0_1_parent_names), -+ .mux_hw = &gxbb_mali_0_sel.hw, -+ .mux_ops = &clk_mux_ops, -+ .rate_hw = &gxbb_mali_0_div.hw, -+ .rate_ops = &clk_divider_ops, -+ .gate_hw = &gxbb_mali_0_en.hw, -+ .gate_ops = &clk_gate_ops, -+ .flags = (CLK_SET_RATE_NO_REPARENT | CLK_IGNORE_UNUSED), -+ }, -+ { -+ .id = CLKID_MALI_1, -+ .name = "mali_1", -+ .parent_names = gxbb_mali_0_1_parent_names, -+ .num_parents = ARRAY_SIZE(gxbb_mali_0_1_parent_names), -+ .mux_hw = &gxbb_mali_1_sel.hw, -+ .mux_ops = &clk_mux_ops, -+ .rate_hw = &gxbb_mali_1_div.hw, -+ .rate_ops = &clk_divider_ops, -+ .gate_hw = &gxbb_mali_1_en.hw, -+ .gate_ops = &clk_gate_ops, -+ .flags = (CLK_SET_RATE_NO_REPARENT | CLK_IGNORE_UNUSED), -+ }, - }; - - static int gxbb_clkc_probe(struct platform_device *pdev) -@@ -884,24 +1033,61 @@ static int gxbb_clkc_probe(struct platform_device *pdev) - /* Populate the base address for CPU clk */ - gxbb_cpu_clk.base = clk_base; - -- /* Populate the base address for the MPEG clks */ -- gxbb_mpeg_clk_sel.reg = clk_base + (u64)gxbb_mpeg_clk_sel.reg; -- gxbb_mpeg_clk_div.reg = clk_base + (u64)gxbb_mpeg_clk_div.reg; -+ /* Populate base address for muxes */ -+ for (i = 0; i < ARRAY_SIZE(gxbb_clk_muxes); i++) -+ gxbb_clk_muxes[i]->reg = clk_base + -+ (u64)gxbb_clk_muxes[i]->reg; -+ -+ /* Populate base address for dividers */ -+ for (i = 0; i < ARRAY_SIZE(gxbb_clk_dividers); i++) -+ gxbb_clk_dividers[i]->reg = clk_base + -+ (u64)gxbb_clk_dividers[i]->reg; - - /* Populate base address for gates */ - for (i = 0; i < ARRAY_SIZE(gxbb_clk_gates); i++) - gxbb_clk_gates[i]->reg = clk_base + - (u64)gxbb_clk_gates[i]->reg; - -+ /* Populate base for GP0 init table */ -+ for (i = 0; i < ARRAY_SIZE(gxbb_gp0_init_regs); ++i) -+ gxbb_gp0_init_regs[i] = clk_base + -+ (u64)gxbb_gp0_init_regs[i]; -+ - /* - * register all clks - */ - for (clkid = 0; clkid < NR_CLKS; clkid++) { -+ if (!gxbb_hw_onecell_data.hws[clkid]) -+ continue; -+ - ret = devm_clk_hw_register(dev, gxbb_hw_onecell_data.hws[clkid]); - if (ret) - goto iounmap; - } - -+ /* Register Composite Clocks */ -+ for (i = 0 ; i < ARRAY_SIZE(gxbb_composite_clks); ++i) { -+ struct gxbb_composite_clk *comp = &gxbb_composite_clks[i]; -+ struct clk_hw *hw; -+ -+ hw = clk_hw_register_composite(dev, comp->name, -+ comp->parent_names, -+ comp->num_parents, -+ comp->mux_hw, comp->mux_ops, -+ comp->rate_hw, comp->rate_ops, -+ comp->gate_hw, comp->gate_ops, -+ comp->flags); -+ if (IS_ERR(hw)) { -+ ret = PTR_ERR(hw); -+ -+ pr_err("%s: Failed to register composite clock %s\n", -+ __func__, comp->name); -+ -+ goto unregister_composites; -+ } -+ gxbb_hw_onecell_data.hws[comp->id] = hw; -+ } -+ - /* - * Register CPU clk notifier - * -@@ -922,11 +1108,26 @@ static int gxbb_clkc_probe(struct platform_device *pdev) - if (ret) { - pr_err("%s: failed to register clock notifier for cpu_clk\n", - __func__); -- goto iounmap; -+ goto unregister_composites; - } - -- return of_clk_add_hw_provider(dev->of_node, of_clk_hw_onecell_get, -+ ret = of_clk_add_hw_provider(dev->of_node, of_clk_hw_onecell_get, - &gxbb_hw_onecell_data); -+ if (!ret) -+ return ret; -+ -+unregister_composites: -+ for (i = 0 ; i < ARRAY_SIZE(gxbb_composite_clks); ++i) { -+ struct gxbb_composite_clk *comp = &gxbb_composite_clks[i]; -+ struct clk *clk; -+ -+ if (gxbb_hw_onecell_data.hws[comp->id]) { -+ clk = gxbb_hw_onecell_data.hws[comp->id]->clk; -+ clk_unregister_composite(clk); -+ } -+ -+ gxbb_hw_onecell_data.hws[comp->id] = NULL; -+ } - - iounmap: - iounmap(clk_base); -diff --git a/drivers/clk/meson/gxbb.h b/drivers/clk/meson/gxbb.h -index 0252939..f79ab57 100644 ---- a/drivers/clk/meson/gxbb.h -+++ b/drivers/clk/meson/gxbb.h -@@ -177,7 +177,7 @@ - /* CLKID_FCLK_DIV4 */ - #define CLKID_FCLK_DIV5 7 - #define CLKID_FCLK_DIV7 8 --#define CLKID_GP0_PLL 9 -+/* CLKID_GP0_PLL */ - #define CLKID_MPEG_SEL 10 - #define CLKID_MPEG_DIV 11 - /* CLKID_CLK81 */ -@@ -265,8 +265,11 @@ - /* CLKID_SD_EMMC_A */ - /* CLKID_SD_EMMC_B */ - /* CLKID_SD_EMMC_C */ -+/* CLKID_MALI_0 */ -+/* CLKID_MALI_1 */ -+/* CLKID_MALI */ - --#define NR_CLKS 97 -+#define NR_CLKS 100 - - /* include the CLKIDs that have been made part of the stable DT binding */ - #include -diff --git a/include/dt-bindings/clock/gxbb-clkc.h b/include/dt-bindings/clock/gxbb-clkc.h -index baade6f..7bbc1d0 100644 ---- a/include/dt-bindings/clock/gxbb-clkc.h -+++ b/include/dt-bindings/clock/gxbb-clkc.h -@@ -10,6 +10,7 @@ - #define CLKID_FCLK_DIV2 4 - #define CLKID_FCLK_DIV3 5 - #define CLKID_FCLK_DIV4 6 -+#define CLKID_GP0_PLL 9 - #define CLKID_CLK81 12 - #define CLKID_MPLL2 15 - #define CLKID_SPI 34 -@@ -24,5 +25,8 @@ - #define CLKID_SD_EMMC_A 94 - #define CLKID_SD_EMMC_B 95 - #define CLKID_SD_EMMC_C 96 -+#define CLKID_MALI_0 97 -+#define CLKID_MALI_1 98 -+#define CLKID_MALI 99 - - #endif /* __GXBB_CLKC_H */ --- -1.9.1 - diff --git a/patch/kernel/odroidc2-next/0008-ARM64-dts-meson-gxbb-Add-Mali-node.patch b/patch/kernel/odroidc2-next/0008-ARM64-dts-meson-gxbb-Add-Mali-node.patch deleted file mode 100644 index d9dc5c381..000000000 --- a/patch/kernel/odroidc2-next/0008-ARM64-dts-meson-gxbb-Add-Mali-node.patch +++ /dev/null @@ -1,61 +0,0 @@ -From 992ae3b904d0ace47dcf33f8cc117a17f1cff0c2 Mon Sep 17 00:00:00 2001 -From: Neil Armstrong -Date: Wed, 1 Feb 2017 11:45:40 +0100 -Subject: [PATCH 08/93] ARM64: dts: meson-gxbb: Add Mali node - -Add the Mali-450 MP3 node for GXBB. ---- - arch/arm64/boot/dts/amlogic/meson-gxbb.dtsi | 37 +++++++++++++++++++++++++++++ - 1 file changed, 37 insertions(+) - -diff --git a/arch/arm64/boot/dts/amlogic/meson-gxbb.dtsi b/arch/arm64/boot/dts/amlogic/meson-gxbb.dtsi -index 2be29a3..bbb034d 100644 ---- a/arch/arm64/boot/dts/amlogic/meson-gxbb.dtsi -+++ b/arch/arm64/boot/dts/amlogic/meson-gxbb.dtsi -@@ -476,6 +476,43 @@ - }; - }; - -+&apb { -+ mali: gpu@c0000 { -+ compatible = "amlogic,meson-gxbb-mali", "arm,mali-450"; -+ reg = <0x0 0xc0000 0x0 0x40000>; -+ interrupts = , -+ , -+ , -+ , -+ , -+ , -+ , -+ , -+ , -+ ; -+ interrupt-names = "gp", "gpmmu", "pp", "pmu", -+ "pp0", "ppmmu0", "pp1", "ppmmu1", -+ "pp2", "ppmmu2"; -+ clocks = <&clkc CLKID_CLK81>, <&clkc CLKID_MALI>; -+ clock-names = "bus", "core"; -+ -+ /* -+ * Mali clocking is provided by two identical clock paths -+ * MALI_0 and MALI_1 muxed to a single clock by a glitch -+ * free mux to safely change frequency while running. -+ */ -+ assigned-clocks = <&clkc CLKID_GP0_PLL>, -+ <&clkc CLKID_MALI_0>, -+ <&clkc CLKID_MALI>; /* Glitch free mux */ -+ assigned-clock-parents = <0>, /* Do Nothing */ -+ <&clkc CLKID_GP0_PLL>, -+ <&clkc CLKID_MALI_0>; -+ assigned-clock-rates = <744000000>, -+ <744000000>, -+ <0>; /* Do Nothing */ -+ }; -+}; -+ - &i2c_A { - clocks = <&clkc CLKID_I2C>; - }; --- -1.9.1 - diff --git a/patch/kernel/odroidc2-next/0008-drm-bridge-dw_hdmi-add-cec-notifier-support.patch b/patch/kernel/odroidc2-next/0008-drm-bridge-dw_hdmi-add-cec-notifier-support.patch new file mode 100644 index 000000000..5f5294174 --- /dev/null +++ b/patch/kernel/odroidc2-next/0008-drm-bridge-dw_hdmi-add-cec-notifier-support.patch @@ -0,0 +1,81 @@ +From ab3f6488b7ea751456324f57d27179599c151136 Mon Sep 17 00:00:00 2001 +From: Russell King +Date: Fri, 4 Dec 2015 10:47:35 +0000 +Subject: [PATCH 08/79] drm/bridge: dw_hdmi: add cec notifier support + +Add CEC notifier support to the HDMI bridge driver, so that the CEC +part of the IP can receive its physical address. + +Signed-off-by: Russell King +Signed-off-by: Neil Armstrong +--- + drivers/gpu/drm/bridge/synopsys/dw-hdmi.c | 18 ++++++++++++++++++ + 1 file changed, 18 insertions(+) + +diff --git a/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c b/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c +index ee788ca..5eff1e5 100644 +--- a/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c ++++ b/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c +@@ -33,6 +33,8 @@ + #include + #include + ++#include ++ + #include "dw-hdmi.h" + #include "dw-hdmi-audio.h" + +@@ -173,6 +175,8 @@ struct dw_hdmi { + + unsigned int reg_shift; + struct regmap *regm; ++ ++ struct cec_notifier *cec_notifier; + }; + + #define HDMI_IH_PHY_STAT0_RX_SENSE \ +@@ -1881,6 +1885,7 @@ static int dw_hdmi_connector_get_modes(struct drm_connector *connector) + hdmi->sink_is_hdmi = drm_detect_hdmi_monitor(edid); + hdmi->sink_has_audio = drm_detect_monitor_audio(edid); + drm_mode_connector_update_edid_property(connector, edid); ++ cec_notifier_set_phys_addr_from_edid(hdmi->cec_notifier, edid); + ret = drm_add_edid_modes(connector, edid); + /* Store the ELD */ + drm_edid_to_eld(connector, edid); +@@ -2077,6 +2082,10 @@ void __dw_hdmi_setup_rx_sense(struct dw_hdmi *hdmi, bool hpd, bool rx_sense) + dw_hdmi_update_phy_mask(hdmi); + } + mutex_unlock(&hdmi->mutex); ++ ++ if (!rx_sense && !hpd) ++ cec_notifier_set_phys_addr(hdmi->cec_notifier, ++ CEC_PHYS_ADDR_INVALID); + } + + void dw_hdmi_setup_rx_sense(struct device *dev, bool hpd, bool rx_sense) +@@ -2376,6 +2385,12 @@ static int dw_hdmi_detect_phy(struct dw_hdmi *hdmi) + if (ret) + goto err_iahb; + ++ hdmi->cec_notifier = cec_notifier_get(dev); ++ if (!hdmi->cec_notifier) { ++ ret = -ENOMEM; ++ goto err_iahb; ++ } ++ + /* + * To prevent overflows in HDMI_IH_FC_STAT2, set the clk regenerator + * N and cts values before enabling phy +@@ -2448,6 +2463,9 @@ static int dw_hdmi_detect_phy(struct dw_hdmi *hdmi) + hdmi->ddc = NULL; + } + ++ if (hdmi->cec_notifier) ++ cec_notifier_put(hdmi->cec_notifier); ++ + clk_disable_unprepare(hdmi->iahb_clk); + err_isfr: + clk_disable_unprepare(hdmi->isfr_clk); +-- +1.9.1 + diff --git a/patch/kernel/odroidc2-next/0009-ARM64-dts-meson-gxbb-Add-support-for-WeTek-Hub-and-P.patch b/patch/kernel/odroidc2-next/0009-ARM64-dts-meson-gxbb-Add-support-for-WeTek-Hub-and-P.patch deleted file mode 100644 index df9224405..000000000 --- a/patch/kernel/odroidc2-next/0009-ARM64-dts-meson-gxbb-Add-support-for-WeTek-Hub-and-P.patch +++ /dev/null @@ -1,212 +0,0 @@ -From d7efc514cff47e958849fa122bc81839541b3dba Mon Sep 17 00:00:00 2001 -From: Neil Armstrong -Date: Wed, 18 Jan 2017 10:33:04 +0100 -Subject: [PATCH 09/93] ARM64: dts: meson-gxbb: Add support for WeTek Hub and - Play - -Adds support for the WeTek Hub and Play2 boards. -The Hub is an extremely small IPTv Set-Top-Box and the Play2 is a more -traditionnal Satellite or Terrestrial and IPTv Set-Top-Box. - -Both are based on the p200 Reference Design and out-of-tree support is -based on OpenELEC kernel at [1]. - -[1] https://github.com/wetek-enigma/linux-amlogic - -Signed-off-by: Neil Armstrong ---- - arch/arm64/boot/dts/amlogic/Makefile | 2 + - .../boot/dts/amlogic/meson-gxbb-wetek-hub.dts | 66 +++++++++++++++ - .../boot/dts/amlogic/meson-gxbb-wetek-play2.dts | 94 ++++++++++++++++++++++ - 3 files changed, 162 insertions(+) - create mode 100644 arch/arm64/boot/dts/amlogic/meson-gxbb-wetek-hub.dts - create mode 100644 arch/arm64/boot/dts/amlogic/meson-gxbb-wetek-play2.dts - -diff --git a/arch/arm64/boot/dts/amlogic/Makefile b/arch/arm64/boot/dts/amlogic/Makefile -index 0d7bfbf..cc2e2dd 100644 ---- a/arch/arm64/boot/dts/amlogic/Makefile -+++ b/arch/arm64/boot/dts/amlogic/Makefile -@@ -5,6 +5,8 @@ dtb-$(CONFIG_ARCH_MESON) += meson-gxbb-p201.dtb - dtb-$(CONFIG_ARCH_MESON) += meson-gxbb-vega-s95-pro.dtb - dtb-$(CONFIG_ARCH_MESON) += meson-gxbb-vega-s95-meta.dtb - dtb-$(CONFIG_ARCH_MESON) += meson-gxbb-vega-s95-telos.dtb -+dtb-$(CONFIG_ARCH_MESON) += meson-gxbb-wetek-hub.dtb -+dtb-$(CONFIG_ARCH_MESON) += meson-gxbb-wetek-play2.dtb - dtb-$(CONFIG_ARCH_MESON) += meson-gxl-s905x-p212.dtb - dtb-$(CONFIG_ARCH_MESON) += meson-gxl-s905d-p230.dtb - dtb-$(CONFIG_ARCH_MESON) += meson-gxl-s905d-p231.dtb -diff --git a/arch/arm64/boot/dts/amlogic/meson-gxbb-wetek-hub.dts b/arch/arm64/boot/dts/amlogic/meson-gxbb-wetek-hub.dts -new file mode 100644 -index 0000000..56f8559 ---- /dev/null -+++ b/arch/arm64/boot/dts/amlogic/meson-gxbb-wetek-hub.dts -@@ -0,0 +1,66 @@ -+/* -+ * Copyright (c) 2016 BayLibre, Inc. -+ * Author: Neil Armstrong -+ * -+ * This file is dual-licensed: you can use it either under the terms -+ * of the GPL or the X11 license, at your option. Note that this dual -+ * licensing only applies to this file, and not this project as a -+ * whole. -+ * -+ * a) This library is free software; you can redistribute it and/or -+ * modify it under the terms of the GNU General Public License as -+ * published by the Free Software Foundation; either version 2 of the -+ * License, or (at your option) any later version. -+ * -+ * This library is distributed in the hope that it will be useful, -+ * but WITHOUT ANY WARRANTY; without even the implied warranty of -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -+ * GNU General Public License for more details. -+ * -+ * Or, alternatively, -+ * -+ * b) Permission is hereby granted, free of charge, to any person -+ * obtaining a copy of this software and associated documentation -+ * files (the "Software"), to deal in the Software without -+ * restriction, including without limitation the rights to use, -+ * copy, modify, merge, publish, distribute, sublicense, and/or -+ * sell copies of the Software, and to permit persons to whom the -+ * Software is furnished to do so, subject to the following -+ * conditions: -+ * -+ * The above copyright notice and this permission notice shall be -+ * included in all copies or substantial portions of the Software. -+ * -+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES -+ * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT -+ * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, -+ * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING -+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR -+ * OTHER DEALINGS IN THE SOFTWARE. -+ */ -+ -+/dts-v1/; -+ -+#include "meson-gxbb-p20x.dtsi" -+ -+/ { -+ compatible = "wetek,hub", "amlogic,meson-gxbb"; -+ model = "WeTek Hub"; -+ -+ leds { -+ compatible = "gpio-leds"; -+ -+ system { -+ label = "wetek-play:system-status"; -+ gpios = <&gpio_ao GPIOAO_13 GPIO_ACTIVE_HIGH>; -+ default-state = "on"; -+ panic-indicator; -+ }; -+ }; -+ -+ cvbs-connector { -+ status = "disabled"; -+ }; -+}; -diff --git a/arch/arm64/boot/dts/amlogic/meson-gxbb-wetek-play2.dts b/arch/arm64/boot/dts/amlogic/meson-gxbb-wetek-play2.dts -new file mode 100644 -index 0000000..ea79fdd ---- /dev/null -+++ b/arch/arm64/boot/dts/amlogic/meson-gxbb-wetek-play2.dts -@@ -0,0 +1,94 @@ -+/* -+ * Copyright (c) 2016 BayLibre, Inc. -+ * Author: Neil Armstrong -+ * -+ * This file is dual-licensed: you can use it either under the terms -+ * of the GPL or the X11 license, at your option. Note that this dual -+ * licensing only applies to this file, and not this project as a -+ * whole. -+ * -+ * a) This library is free software; you can redistribute it and/or -+ * modify it under the terms of the GNU General Public License as -+ * published by the Free Software Foundation; either version 2 of the -+ * License, or (at your option) any later version. -+ * -+ * This library is distributed in the hope that it will be useful, -+ * but WITHOUT ANY WARRANTY; without even the implied warranty of -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -+ * GNU General Public License for more details. -+ * -+ * Or, alternatively, -+ * -+ * b) Permission is hereby granted, free of charge, to any person -+ * obtaining a copy of this software and associated documentation -+ * files (the "Software"), to deal in the Software without -+ * restriction, including without limitation the rights to use, -+ * copy, modify, merge, publish, distribute, sublicense, and/or -+ * sell copies of the Software, and to permit persons to whom the -+ * Software is furnished to do so, subject to the following -+ * conditions: -+ * -+ * The above copyright notice and this permission notice shall be -+ * included in all copies or substantial portions of the Software. -+ * -+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES -+ * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT -+ * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, -+ * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING -+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR -+ * OTHER DEALINGS IN THE SOFTWARE. -+ */ -+ -+/dts-v1/; -+ -+#include "meson-gxbb-p20x.dtsi" -+#include -+ -+/ { -+ compatible = "wetek,play2", "amlogic,meson-gxbb"; -+ model = "WeTek Play 2"; -+ -+ leds { -+ compatible = "gpio-leds"; -+ -+ system { -+ label = "wetek-play:system-status"; -+ gpios = <&gpio_ao GPIOAO_13 GPIO_ACTIVE_HIGH>; -+ default-state = "on"; -+ panic-indicator; -+ }; -+ -+ wifi { -+ label = "wetek-play:wifi-status"; -+ gpios = <&gpio GPIODV_26 GPIO_ACTIVE_HIGH>; -+ default-state = "off"; -+ }; -+ -+ ethernet { -+ label = "wetek-play:ethernet-status"; -+ gpios = <&gpio GPIODV_27 GPIO_ACTIVE_HIGH>; -+ default-state = "off"; -+ }; -+ }; -+ -+ gpio-keys-polled { -+ compatible = "gpio-keys-polled"; -+ #address-cells = <1>; -+ #size-cells = <0>; -+ poll-interval = <100>; -+ -+ button@0 { -+ label = "reset"; -+ linux,code = ; -+ gpios = <&gpio_ao GPIOAO_3 GPIO_ACTIVE_LOW>; -+ }; -+ }; -+}; -+ -+&i2c_A { -+ status = "okay"; -+ pinctrl-0 = <&i2c_a_pins>; -+ pinctrl-names = "default"; -+}; --- -1.9.1 - diff --git a/patch/kernel/odroidc2-next/0009-platform-Add-Amlogic-Meson-AO-CEC-Controller-driver.patch b/patch/kernel/odroidc2-next/0009-platform-Add-Amlogic-Meson-AO-CEC-Controller-driver.patch new file mode 100644 index 000000000..efae2f029 --- /dev/null +++ b/patch/kernel/odroidc2-next/0009-platform-Add-Amlogic-Meson-AO-CEC-Controller-driver.patch @@ -0,0 +1,724 @@ +From c3be57d7fef20314fffd81e74b70ea75e35a4d26 Mon Sep 17 00:00:00 2001 +From: Neil Armstrong +Date: Tue, 30 May 2017 15:50:21 +0200 +Subject: [PATCH 09/79] platform: Add Amlogic Meson AO CEC Controller driver + +The Amlogic SoC embeds a standalone CEC controller, this patch adds a driver +for such controller. +The controller does not need HPD to be active, and could support up to max +5 logical addresses, but only 1 is handled since the Suspend firmware can +make use of this unique logical address to wake up the device. + +The Suspend firmware configuration will be added in an other patchset. + +Signed-off-by: Neil Armstrong +--- + drivers/media/platform/Kconfig | 11 + + drivers/media/platform/Makefile | 2 + + drivers/media/platform/meson/Makefile | 1 + + drivers/media/platform/meson/ao-cec.c | 653 ++++++++++++++++++++++++++++++++++ + 4 files changed, 667 insertions(+) + create mode 100644 drivers/media/platform/meson/Makefile + create mode 100644 drivers/media/platform/meson/ao-cec.c + +diff --git a/drivers/media/platform/Kconfig b/drivers/media/platform/Kconfig +index 041cb80..857e068 100644 +--- a/drivers/media/platform/Kconfig ++++ b/drivers/media/platform/Kconfig +@@ -499,6 +499,17 @@ menuconfig CEC_PLATFORM_DRIVERS + + if CEC_PLATFORM_DRIVERS + ++config VIDEO_MESON_AO_CEC ++ tristate "Amlogic Meson AO CEC driver" ++ depends on ARCH_MESON || COMPILE_TEST ++ select CEC_CORE ++ select CEC_NOTIFIER ++ ---help--- ++ This is a driver for Amlogic Meson SoCs AO CEC interface. It uses the ++ generic CEC framework interface. ++ CEC bus is present in the HDMI connector and enables communication ++ between compatible devices. ++ + config VIDEO_SAMSUNG_S5P_CEC + tristate "Samsung S5P CEC driver" + depends on PLAT_S5P || ARCH_EXYNOS || COMPILE_TEST +diff --git a/drivers/media/platform/Makefile b/drivers/media/platform/Makefile +index 63303d6..db15c59 100644 +--- a/drivers/media/platform/Makefile ++++ b/drivers/media/platform/Makefile +@@ -77,3 +77,5 @@ obj-$(CONFIG_VIDEO_MEDIATEK_VCODEC) += mtk-vcodec/ + obj-$(CONFIG_VIDEO_MEDIATEK_MDP) += mtk-mdp/ + + obj-$(CONFIG_VIDEO_MEDIATEK_JPEG) += mtk-jpeg/ ++ ++obj-y += meson/ +diff --git a/drivers/media/platform/meson/Makefile b/drivers/media/platform/meson/Makefile +new file mode 100644 +index 0000000..597beb8 +--- /dev/null ++++ b/drivers/media/platform/meson/Makefile +@@ -0,0 +1 @@ ++obj-$(CONFIG_VIDEO_MESON_AO_CEC) += ao-cec.o +diff --git a/drivers/media/platform/meson/ao-cec.c b/drivers/media/platform/meson/ao-cec.c +new file mode 100644 +index 0000000..26d7c3e8 +--- /dev/null ++++ b/drivers/media/platform/meson/ao-cec.c +@@ -0,0 +1,653 @@ ++/* ++ * Driver for Amlogic Meson AO CEC Controller ++ * ++ * Copyright (C) 2015 Amlogic, Inc. All rights reserved ++ * Copyright (C) 2017 BayLibre, SAS ++ * Author: Neil Armstrong ++ * ++ * SPDX-License-Identifier: GPL-2.0+ ++ */ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++/* CEC Registers */ ++ ++/* ++ * [2:1] cntl_clk ++ * - 0 = Disable clk (Power-off mode) ++ * - 1 = Enable gated clock (Normal mode) ++ * - 2 = Enable free-run clk (Debug mode) ++ */ ++#define CEC_GEN_CNTL_REG 0x00 ++ ++#define CEC_GEN_CNTL_RESET BIT(0) ++#define CEC_GEN_CNTL_CLK_DISABLE 0 ++#define CEC_GEN_CNTL_CLK_ENABLE 1 ++#define CEC_GEN_CNTL_CLK_ENABLE_DBG 2 ++#define CEC_GEN_CNTL_CLK_CTRL_MASK GENMASK(2, 1) ++ ++/* ++ * [7:0] cec_reg_addr ++ * [15:8] cec_reg_wrdata ++ * [16] cec_reg_wr ++ * - 0 = Read ++ * - 1 = Write ++ * [23] bus free ++ * [31:24] cec_reg_rddata ++ */ ++#define CEC_RW_REG 0x04 ++ ++#define CEC_RW_ADDR GENMASK(7, 0) ++#define CEC_RW_WR_DATA GENMASK(15, 8) ++#define CEC_RW_WRITE_EN BIT(16) ++#define CEC_RW_BUS_BUSY BIT(23) ++#define CEC_RW_RD_DATA GENMASK(31, 24) ++ ++/* ++ * [1] tx intr ++ * [2] rx intr ++ */ ++#define CEC_INTR_MASKN_REG 0x08 ++#define CEC_INTR_CLR_REG 0x0c ++#define CEC_INTR_STAT_REG 0x10 ++ ++#define CEC_INTR_TX BIT(1) ++#define CEC_INTR_RX BIT(2) ++ ++/* CEC Commands */ ++ ++#define CEC_TX_MSG_0_HEADER 0x00 ++#define CEC_TX_MSG_1_OPCODE 0x01 ++#define CEC_TX_MSG_2_OP1 0x02 ++#define CEC_TX_MSG_3_OP2 0x03 ++#define CEC_TX_MSG_4_OP3 0x04 ++#define CEC_TX_MSG_5_OP4 0x05 ++#define CEC_TX_MSG_6_OP5 0x06 ++#define CEC_TX_MSG_7_OP6 0x07 ++#define CEC_TX_MSG_8_OP7 0x08 ++#define CEC_TX_MSG_9_OP8 0x09 ++#define CEC_TX_MSG_A_OP9 0x0A ++#define CEC_TX_MSG_B_OP10 0x0B ++#define CEC_TX_MSG_C_OP11 0x0C ++#define CEC_TX_MSG_D_OP12 0x0D ++#define CEC_TX_MSG_E_OP13 0x0E ++#define CEC_TX_MSG_F_OP14 0x0F ++#define CEC_TX_MSG_LENGTH 0x10 ++#define CEC_TX_MSG_CMD 0x11 ++#define CEC_TX_WRITE_BUF 0x12 ++#define CEC_TX_CLEAR_BUF 0x13 ++#define CEC_RX_MSG_CMD 0x14 ++#define CEC_RX_CLEAR_BUF 0x15 ++#define CEC_LOGICAL_ADDR0 0x16 ++#define CEC_LOGICAL_ADDR1 0x17 ++#define CEC_LOGICAL_ADDR2 0x18 ++#define CEC_LOGICAL_ADDR3 0x19 ++#define CEC_LOGICAL_ADDR4 0x1A ++#define CEC_CLOCK_DIV_H 0x1B ++#define CEC_CLOCK_DIV_L 0x1C ++#define CEC_QUIESCENT_25MS_BIT7_0 0x20 ++#define CEC_QUIESCENT_25MS_BIT11_8 0x21 ++#define CEC_STARTBITMINL2H_3MS5_BIT7_0 0x22 ++#define CEC_STARTBITMINL2H_3MS5_BIT8 0x23 ++#define CEC_STARTBITMAXL2H_3MS9_BIT7_0 0x24 ++#define CEC_STARTBITMAXL2H_3MS9_BIT8 0x25 ++#define CEC_STARTBITMINH_0MS6_BIT7_0 0x26 ++#define CEC_STARTBITMINH_0MS6_BIT8 0x27 ++#define CEC_STARTBITMAXH_1MS0_BIT7_0 0x28 ++#define CEC_STARTBITMAXH_1MS0_BIT8 0x29 ++#define CEC_STARTBITMINTOT_4MS3_BIT7_0 0x2A ++#define CEC_STARTBITMINTOT_4MS3_BIT9_8 0x2B ++#define CEC_STARTBITMAXTOT_4MS7_BIT7_0 0x2C ++#define CEC_STARTBITMAXTOT_4MS7_BIT9_8 0x2D ++#define CEC_LOGIC1MINL2H_0MS4_BIT7_0 0x2E ++#define CEC_LOGIC1MINL2H_0MS4_BIT8 0x2F ++#define CEC_LOGIC1MAXL2H_0MS8_BIT7_0 0x30 ++#define CEC_LOGIC1MAXL2H_0MS8_BIT8 0x31 ++#define CEC_LOGIC0MINL2H_1MS3_BIT7_0 0x32 ++#define CEC_LOGIC0MINL2H_1MS3_BIT8 0x33 ++#define CEC_LOGIC0MAXL2H_1MS7_BIT7_0 0x34 ++#define CEC_LOGIC0MAXL2H_1MS7_BIT8 0x35 ++#define CEC_LOGICMINTOTAL_2MS05_BIT7_0 0x36 ++#define CEC_LOGICMINTOTAL_2MS05_BIT9_8 0x37 ++#define CEC_LOGICMAXHIGH_2MS8_BIT7_0 0x38 ++#define CEC_LOGICMAXHIGH_2MS8_BIT8 0x39 ++#define CEC_LOGICERRLOW_3MS4_BIT7_0 0x3A ++#define CEC_LOGICERRLOW_3MS4_BIT8 0x3B ++#define CEC_NOMSMPPOINT_1MS05 0x3C ++#define CEC_DELCNTR_LOGICERR 0x3E ++#define CEC_TXTIME_17MS_BIT7_0 0x40 ++#define CEC_TXTIME_17MS_BIT10_8 0x41 ++#define CEC_TXTIME_2BIT_BIT7_0 0x42 ++#define CEC_TXTIME_2BIT_BIT10_8 0x43 ++#define CEC_TXTIME_4BIT_BIT7_0 0x44 ++#define CEC_TXTIME_4BIT_BIT10_8 0x45 ++#define CEC_STARTBITNOML2H_3MS7_BIT7_0 0x46 ++#define CEC_STARTBITNOML2H_3MS7_BIT8 0x47 ++#define CEC_STARTBITNOMH_0MS8_BIT7_0 0x48 ++#define CEC_STARTBITNOMH_0MS8_BIT8 0x49 ++#define CEC_LOGIC1NOML2H_0MS6_BIT7_0 0x4A ++#define CEC_LOGIC1NOML2H_0MS6_BIT8 0x4B ++#define CEC_LOGIC0NOML2H_1MS5_BIT7_0 0x4C ++#define CEC_LOGIC0NOML2H_1MS5_BIT8 0x4D ++#define CEC_LOGIC1NOMH_1MS8_BIT7_0 0x4E ++#define CEC_LOGIC1NOMH_1MS8_BIT8 0x4F ++#define CEC_LOGIC0NOMH_0MS9_BIT7_0 0x50 ++#define CEC_LOGIC0NOMH_0MS9_BIT8 0x51 ++#define CEC_LOGICERRLOW_3MS6_BIT7_0 0x52 ++#define CEC_LOGICERRLOW_3MS6_BIT8 0x53 ++#define CEC_CHKCONTENTION_0MS1 0x54 ++#define CEC_PREPARENXTBIT_0MS05_BIT7_0 0x56 ++#define CEC_PREPARENXTBIT_0MS05_BIT8 0x57 ++#define CEC_NOMSMPACKPOINT_0MS45 0x58 ++#define CEC_ACK0NOML2H_1MS5_BIT7_0 0x5A ++#define CEC_ACK0NOML2H_1MS5_BIT8 0x5B ++#define CEC_BUGFIX_DISABLE_0 0x60 ++#define CEC_BUGFIX_DISABLE_1 0x61 ++#define CEC_RX_MSG_0_HEADER 0x80 ++#define CEC_RX_MSG_1_OPCODE 0x81 ++#define CEC_RX_MSG_2_OP1 0x82 ++#define CEC_RX_MSG_3_OP2 0x83 ++#define CEC_RX_MSG_4_OP3 0x84 ++#define CEC_RX_MSG_5_OP4 0x85 ++#define CEC_RX_MSG_6_OP5 0x86 ++#define CEC_RX_MSG_7_OP6 0x87 ++#define CEC_RX_MSG_8_OP7 0x88 ++#define CEC_RX_MSG_9_OP8 0x89 ++#define CEC_RX_MSG_A_OP9 0x8A ++#define CEC_RX_MSG_B_OP10 0x8B ++#define CEC_RX_MSG_C_OP11 0x8C ++#define CEC_RX_MSG_D_OP12 0x8D ++#define CEC_RX_MSG_E_OP13 0x8E ++#define CEC_RX_MSG_F_OP14 0x8F ++#define CEC_RX_MSG_LENGTH 0x90 ++#define CEC_RX_MSG_STATUS 0x91 ++#define CEC_RX_NUM_MSG 0x92 ++#define CEC_TX_MSG_STATUS 0x93 ++#define CEC_TX_NUM_MSG 0x94 ++ ++ ++/* CEC_TX_MSG_CMD definition */ ++#define TX_NO_OP 0 /* No transaction */ ++#define TX_REQ_CURRENT 1 /* Transmit earliest message in buffer */ ++#define TX_ABORT 2 /* Abort transmitting earliest message */ ++#define TX_REQ_NEXT 3 /* Overwrite earliest msg, transmit next */ ++ ++/* tx_msg_status definition */ ++#define TX_IDLE 0 /* No transaction */ ++#define TX_BUSY 1 /* Transmitter is busy */ ++#define TX_DONE 2 /* Message successfully transmitted */ ++#define TX_ERROR 3 /* Message transmitted with error */ ++ ++/* rx_msg_cmd */ ++#define RX_NO_OP 0 /* No transaction */ ++#define RX_ACK_CURRENT 1 /* Read earliest message in buffer */ ++#define RX_DISABLE 2 /* Disable receiving latest message */ ++#define RX_ACK_NEXT 3 /* Clear earliest msg, read next */ ++ ++/* rx_msg_status */ ++#define RX_IDLE 0 /* No transaction */ ++#define RX_BUSY 1 /* Receiver is busy */ ++#define RX_DONE 2 /* Message has been received successfully */ ++#define RX_ERROR 3 /* Message has been received with error */ ++ ++/* RX_CLEAR_BUF options */ ++#define CLEAR_START 1 ++#define CLEAR_STOP 0 ++ ++/* CEC_LOGICAL_ADDRx options */ ++#define LOGICAL_ADDR_MASK 0xf ++#define LOGICAL_ADDR_VALID BIT(4) ++#define LOGICAL_ADDR_DISABLE 0 ++ ++#define CEC_CLK_RATE 32768 ++ ++struct meson_ao_cec_device { ++ struct platform_device *pdev; ++ void __iomem *base; ++ struct clk *core; ++ spinlock_t cec_reg_lock; ++ struct cec_notifier *notify; ++ struct cec_adapter *adap; ++ struct cec_msg rx_msg; ++}; ++ ++#define writel_bits_relaxed(mask, val, addr) \ ++ writel_relaxed((readl_relaxed(addr) & ~(mask)) | (val), addr) ++ ++static inline void meson_ao_cec_wait_busy(struct meson_ao_cec_device *ao_cec) ++{ ++ while (readl_relaxed(ao_cec->base + CEC_RW_REG) & ++ CEC_RW_BUS_BUSY) ++ ; ++} ++ ++static u8 meson_ao_cec_read(struct meson_ao_cec_device *ao_cec, ++ unsigned long address) ++{ ++ unsigned long flags; ++ u32 reg = FIELD_PREP(CEC_RW_ADDR, address); ++ u8 data; ++ ++ spin_lock_irqsave(&ao_cec->cec_reg_lock, flags); ++ ++ meson_ao_cec_wait_busy(ao_cec); ++ ++ writel_relaxed(reg, ao_cec->base + CEC_RW_REG); ++ ++ meson_ao_cec_wait_busy(ao_cec); ++ ++ data = FIELD_GET(CEC_RW_RD_DATA, ++ readl_relaxed(ao_cec->base + CEC_RW_REG)); ++ ++ spin_unlock_irqrestore(&ao_cec->cec_reg_lock, flags); ++ ++ return data; ++} ++ ++static void meson_ao_cec_write(struct meson_ao_cec_device *ao_cec, ++ unsigned long address, u8 data) ++{ ++ unsigned long flags; ++ u32 reg = FIELD_PREP(CEC_RW_ADDR, address) | ++ FIELD_PREP(CEC_RW_WR_DATA, data) | ++ CEC_RW_WRITE_EN; ++ ++ spin_lock_irqsave(&ao_cec->cec_reg_lock, flags); ++ ++ meson_ao_cec_wait_busy(ao_cec); ++ ++ writel_relaxed(reg, ao_cec->base + CEC_RW_REG); ++ ++ spin_unlock_irqrestore(&ao_cec->cec_reg_lock, flags); ++} ++ ++static inline void meson_ao_cec_irq_setup(struct meson_ao_cec_device *ao_cec, ++ bool enable) ++{ ++ u32 cfg = CEC_INTR_TX | CEC_INTR_RX; ++ ++ writel_bits_relaxed(cfg, enable ? cfg : 0, ++ ao_cec->base + CEC_INTR_MASKN_REG); ++} ++ ++static inline void meson_ao_cec_clear(struct meson_ao_cec_device *ao_cec) ++{ ++ meson_ao_cec_write(ao_cec, CEC_RX_MSG_CMD, RX_DISABLE); ++ meson_ao_cec_write(ao_cec, CEC_TX_MSG_CMD, TX_ABORT); ++ meson_ao_cec_write(ao_cec, CEC_RX_CLEAR_BUF, 1); ++ meson_ao_cec_write(ao_cec, CEC_TX_CLEAR_BUF, 1); ++ ++ udelay(100); ++ ++ meson_ao_cec_write(ao_cec, CEC_RX_CLEAR_BUF, 0); ++ meson_ao_cec_write(ao_cec, CEC_TX_CLEAR_BUF, 0); ++ ++ udelay(100); ++ ++ meson_ao_cec_write(ao_cec, CEC_RX_MSG_CMD, RX_NO_OP); ++ meson_ao_cec_write(ao_cec, CEC_TX_MSG_CMD, TX_NO_OP); ++} ++ ++static void meson_ao_cec_arbit_bit_time_set(struct meson_ao_cec_device *ao_cec, ++ unsigned int bit_set, ++ unsigned int time_set) ++{ ++ switch (bit_set) { ++ case 3: ++ meson_ao_cec_write(ao_cec, CEC_TXTIME_4BIT_BIT7_0, ++ time_set & 0xff); ++ meson_ao_cec_write(ao_cec, CEC_TXTIME_4BIT_BIT10_8, ++ (time_set >> 8) & 0x7); ++ break; ++ ++ case 5: ++ meson_ao_cec_write(ao_cec, CEC_TXTIME_2BIT_BIT7_0, ++ time_set & 0xff); ++ meson_ao_cec_write(ao_cec, CEC_TXTIME_2BIT_BIT10_8, ++ (time_set >> 8) & 0x7); ++ break; ++ ++ case 7: ++ meson_ao_cec_write(ao_cec, CEC_TXTIME_17MS_BIT7_0, ++ time_set & 0xff); ++ meson_ao_cec_write(ao_cec, CEC_TXTIME_17MS_BIT10_8, ++ (time_set >> 8) & 0x7); ++ break; ++ } ++} ++ ++static irqreturn_t meson_ao_cec_irq(int irq, void *data) ++{ ++ struct meson_ao_cec_device *ao_cec = data; ++ u32 stat = readl_relaxed(ao_cec->base + CEC_INTR_STAT_REG); ++ ++ if (stat) ++ return IRQ_WAKE_THREAD; ++ ++ return IRQ_NONE; ++} ++ ++static void meson_ao_cec_irq_tx(struct meson_ao_cec_device *ao_cec) ++{ ++ unsigned long tx_status = 0; ++ u8 stat = meson_ao_cec_read(ao_cec, CEC_TX_MSG_STATUS); ++ ++ switch (stat) { ++ case TX_DONE: ++ tx_status = CEC_TX_STATUS_OK; ++ break; ++ ++ case TX_BUSY: ++ tx_status = CEC_TX_STATUS_ARB_LOST; ++ break; ++ ++ case TX_IDLE: ++ tx_status = CEC_TX_STATUS_LOW_DRIVE; ++ break; ++ ++ case TX_ERROR: ++ default: ++ tx_status = CEC_TX_STATUS_NACK; ++ } ++ ++ /* Clear Interruption */ ++ writel_relaxed(CEC_INTR_TX, ao_cec->base + CEC_INTR_CLR_REG); ++ ++ /* Stop TX */ ++ meson_ao_cec_write(ao_cec, CEC_TX_MSG_CMD, TX_NO_OP); ++ ++ cec_transmit_attempt_done(ao_cec->adap, tx_status); ++} ++ ++static void meson_ao_cec_irq_rx(struct meson_ao_cec_device *ao_cec) ++{ ++ u8 stat = meson_ao_cec_read(ao_cec, CEC_RX_MSG_STATUS); ++ int i; ++ ++ /* RX Error */ ++ if (stat != RX_DONE || ++ meson_ao_cec_read(ao_cec, CEC_RX_NUM_MSG) != 1) ++ goto rx_out; ++ ++ ao_cec->rx_msg.len = meson_ao_cec_read(ao_cec, CEC_RX_MSG_LENGTH) + 1; ++ if (ao_cec->rx_msg.len > CEC_MAX_MSG_SIZE) ++ ao_cec->rx_msg.len = CEC_MAX_MSG_SIZE; ++ ++ for (i = 0; i < ao_cec->rx_msg.len; i++) ++ ao_cec->rx_msg.msg[i] = ++ meson_ao_cec_read(ao_cec, CEC_RX_MSG_0_HEADER + i); ++ ++ cec_received_msg(ao_cec->adap, &ao_cec->rx_msg); ++ ++rx_out: ++ /* Clear Interruption */ ++ writel_relaxed(CEC_INTR_RX, ao_cec->base + CEC_INTR_CLR_REG); ++ ++ /* Ack RX message */ ++ meson_ao_cec_write(ao_cec, CEC_RX_MSG_CMD, RX_ACK_CURRENT); ++ meson_ao_cec_write(ao_cec, CEC_RX_MSG_CMD, RX_NO_OP); ++ ++ /* Clear RX buffer */ ++ meson_ao_cec_write(ao_cec, CEC_RX_CLEAR_BUF, CLEAR_START); ++ meson_ao_cec_write(ao_cec, CEC_RX_CLEAR_BUF, CLEAR_STOP); ++} ++ ++static irqreturn_t meson_ao_cec_irq_thread(int irq, void *data) ++{ ++ struct meson_ao_cec_device *ao_cec = data; ++ u32 stat = readl_relaxed(ao_cec->base + CEC_INTR_STAT_REG); ++ ++ if (stat & CEC_INTR_TX) ++ meson_ao_cec_irq_tx(ao_cec); ++ ++ meson_ao_cec_irq_rx(ao_cec); ++ ++ return IRQ_HANDLED; ++} ++ ++static int meson_ao_cec_set_log_addr(struct cec_adapter *adap, u8 logical_addr) ++{ ++ struct meson_ao_cec_device *ao_cec = adap->priv; ++ ++ meson_ao_cec_write(ao_cec, CEC_LOGICAL_ADDR0, LOGICAL_ADDR_DISABLE); ++ ++ meson_ao_cec_clear(ao_cec); ++ ++ if (logical_addr == CEC_LOG_ADDR_INVALID) ++ return 0; ++ ++ meson_ao_cec_write(ao_cec, CEC_LOGICAL_ADDR0, ++ logical_addr & LOGICAL_ADDR_MASK); ++ ++ udelay(100); ++ ++ meson_ao_cec_write(ao_cec, CEC_LOGICAL_ADDR0, ++ (logical_addr & LOGICAL_ADDR_MASK) | ++ LOGICAL_ADDR_VALID); ++ ++ return 0; ++} ++ ++static int meson_ao_cec_transmit(struct cec_adapter *adap, u8 attempts, ++ u32 signal_free_time, struct cec_msg *msg) ++{ ++ struct meson_ao_cec_device *ao_cec = adap->priv; ++ u8 reg; ++ int i; ++ ++ reg = meson_ao_cec_read(ao_cec, CEC_TX_MSG_STATUS); ++ if (reg == TX_BUSY) { ++ dev_err(&ao_cec->pdev->dev, "%s: busy TX\n", __func__); ++ meson_ao_cec_write(ao_cec, CEC_TX_MSG_CMD, TX_ABORT); ++ } ++ ++ for (i = 0; i < msg->len; i++) ++ meson_ao_cec_write(ao_cec, CEC_TX_MSG_0_HEADER + i, ++ msg->msg[i]); ++ ++ meson_ao_cec_write(ao_cec, CEC_TX_MSG_LENGTH, msg->len - 1); ++ meson_ao_cec_write(ao_cec, CEC_TX_MSG_CMD, TX_REQ_CURRENT); ++ ++ return 0; ++} ++ ++static int meson_ao_cec_adap_enable(struct cec_adapter *adap, bool enable) ++{ ++ struct meson_ao_cec_device *ao_cec = adap->priv; ++ ++ meson_ao_cec_irq_setup(ao_cec, false); ++ ++ writel_bits_relaxed(CEC_GEN_CNTL_RESET, CEC_GEN_CNTL_RESET, ++ ao_cec->base + CEC_GEN_CNTL_REG); ++ ++ if (!enable) ++ return 0; ++ ++ /* Enable gated clock (Normal mode). */ ++ writel_bits_relaxed(CEC_GEN_CNTL_CLK_CTRL_MASK, ++ FIELD_PREP(CEC_GEN_CNTL_CLK_CTRL_MASK, ++ CEC_GEN_CNTL_CLK_ENABLE), ++ ao_cec->base + CEC_GEN_CNTL_REG); ++ ++ udelay(100); ++ ++ /* Release Reset */ ++ writel_bits_relaxed(CEC_GEN_CNTL_RESET, 0, ++ ao_cec->base + CEC_GEN_CNTL_REG); ++ ++ /* Clear buffers */ ++ meson_ao_cec_clear(ao_cec); ++ ++ /* CEC arbitration 3/5/7 bit time set. */ ++ meson_ao_cec_arbit_bit_time_set(ao_cec, 3, 0x118); ++ meson_ao_cec_arbit_bit_time_set(ao_cec, 5, 0x000); ++ meson_ao_cec_arbit_bit_time_set(ao_cec, 7, 0x2aa); ++ ++ meson_ao_cec_irq_setup(ao_cec, true); ++ ++ return 0; ++} ++ ++static const struct cec_adap_ops meson_ao_cec_ops = { ++ .adap_enable = meson_ao_cec_adap_enable, ++ .adap_log_addr = meson_ao_cec_set_log_addr, ++ .adap_transmit = meson_ao_cec_transmit, ++}; ++ ++static int meson_ao_cec_probe(struct platform_device *pdev) ++{ ++ struct meson_ao_cec_device *ao_cec; ++ struct platform_device *hdmi_dev; ++ struct device_node *np; ++ struct resource *res; ++ int ret, irq; ++ ++ np = of_parse_phandle(pdev->dev.of_node, "hdmi-phandle", 0); ++ if (!np) { ++ dev_err(&pdev->dev, "Failed to find hdmi node\n"); ++ return -ENODEV; ++ } ++ ++ hdmi_dev = of_find_device_by_node(np); ++ if (hdmi_dev == NULL) ++ return -EPROBE_DEFER; ++ ++ ao_cec = devm_kzalloc(&pdev->dev, sizeof(*ao_cec), GFP_KERNEL); ++ if (!ao_cec) ++ return -ENOMEM; ++ ++ spin_lock_init(&ao_cec->cec_reg_lock); ++ ++ ao_cec->notify = cec_notifier_get(&hdmi_dev->dev); ++ if (!ao_cec->notify) ++ return -ENOMEM; ++ ++ ao_cec->adap = cec_allocate_adapter(&meson_ao_cec_ops, ao_cec, ++ "meson_ao_cec", ++ CEC_CAP_LOG_ADDRS | ++ CEC_CAP_TRANSMIT | ++ CEC_CAP_RC, ++ 1); /* Use 1 for now */ ++ if (IS_ERR(ao_cec->adap)) { ++ ret = PTR_ERR(ao_cec->adap); ++ goto out_probe_notify; ++ } ++ ++ ao_cec->adap->owner = THIS_MODULE; ++ ++ res = platform_get_resource(pdev, IORESOURCE_MEM, 0); ++ ao_cec->base = devm_ioremap_resource(&pdev->dev, res); ++ if (IS_ERR(ao_cec->base)) { ++ ret = PTR_ERR(ao_cec->base); ++ goto out_probe_adapter; ++ } ++ ++ irq = platform_get_irq(pdev, 0); ++ ret = devm_request_threaded_irq(&pdev->dev, irq, ++ meson_ao_cec_irq, ++ meson_ao_cec_irq_thread, ++ 0, NULL, ao_cec); ++ if (ret) { ++ dev_err(&pdev->dev, "irq request failed\n"); ++ goto out_probe_adapter; ++ } ++ ++ ao_cec->core = devm_clk_get(&pdev->dev, "core"); ++ if (IS_ERR(ao_cec->core)) { ++ dev_err(&pdev->dev, "core clock request failed\n"); ++ ret = PTR_ERR(ao_cec->core); ++ goto out_probe_adapter; ++ } ++ ++ ret = clk_prepare_enable(ao_cec->core); ++ if (ret) { ++ dev_err(&pdev->dev, "core clock enable failed\n"); ++ goto out_probe_adapter; ++ } ++ ++ ret = clk_set_rate(ao_cec->core, CEC_CLK_RATE); ++ if (ret) { ++ dev_err(&pdev->dev, "core clock set rate failed\n"); ++ goto out_probe_clk; ++ } ++ ++ device_reset_optional(&pdev->dev); ++ ++ ao_cec->pdev = pdev; ++ platform_set_drvdata(pdev, ao_cec); ++ ++ ret = cec_register_adapter(ao_cec->adap, &pdev->dev); ++ if (ret < 0) { ++ cec_notifier_put(ao_cec->notify); ++ goto out_probe_clk; ++ } ++ ++ /* Setup Hardware */ ++ writel_relaxed(CEC_GEN_CNTL_RESET, ++ ao_cec->base + CEC_GEN_CNTL_REG); ++ ++ cec_register_cec_notifier(ao_cec->adap, ao_cec->notify); ++ ++ return 0; ++ ++out_probe_clk: ++ clk_disable_unprepare(ao_cec->core); ++ ++out_probe_adapter: ++ cec_delete_adapter(ao_cec->adap); ++ ++out_probe_notify: ++ cec_notifier_put(ao_cec->notify); ++ ++ dev_err(&pdev->dev, "CEC controller registration failed\n"); ++ ++ return ret; ++} ++ ++static int meson_ao_cec_remove(struct platform_device *pdev) ++{ ++ struct meson_ao_cec_device *ao_cec = platform_get_drvdata(pdev); ++ ++ clk_disable_unprepare(ao_cec->core); ++ ++ cec_unregister_adapter(ao_cec->adap); ++ ++ cec_notifier_put(ao_cec->notify); ++ ++ return 0; ++} ++ ++static const struct of_device_id meson_ao_cec_of_match[] = { ++ { .compatible = "amlogic,meson-gx-ao-cec", }, ++ { /* sentinel */ } ++}; ++MODULE_DEVICE_TABLE(of, meson_ao_cec_of_match); ++ ++static struct platform_driver meson_ao_cec_driver = { ++ .probe = meson_ao_cec_probe, ++ .remove = meson_ao_cec_remove, ++ .driver = { ++ .name = "meson-ao-cec", ++ .of_match_table = of_match_ptr(meson_ao_cec_of_match), ++ }, ++}; ++ ++module_platform_driver(meson_ao_cec_driver); ++ ++MODULE_DESCRIPTION("Meson AO CEC Controller driver"); ++MODULE_AUTHOR("Neil Armstrong "); ++MODULE_LICENSE("GPL"); +-- +1.9.1 + diff --git a/patch/kernel/odroidc2-next/0010-ARM64-dts-meson-gxbb-Add-CEC-pins-nodes.patch b/patch/kernel/odroidc2-next/0010-ARM64-dts-meson-gxbb-Add-CEC-pins-nodes.patch new file mode 100644 index 000000000..77fa48780 --- /dev/null +++ b/patch/kernel/odroidc2-next/0010-ARM64-dts-meson-gxbb-Add-CEC-pins-nodes.patch @@ -0,0 +1,40 @@ +From 6fd7485ab55a72cd7bce9e4f69dc95a6fe06e685 Mon Sep 17 00:00:00 2001 +From: Neil Armstrong +Date: Wed, 24 May 2017 09:41:12 +0200 +Subject: [PATCH 10/79] ARM64: dts: meson-gxbb: Add CEC pins nodes + +Add the AO and EE domain CEC pins nodes for the Amlogic Meson GXBB SoCs. + +Signed-off-by: Neil Armstrong +--- + arch/arm64/boot/dts/amlogic/meson-gxbb.dtsi | 14 ++++++++++++++ + 1 file changed, 14 insertions(+) + +diff --git a/arch/arm64/boot/dts/amlogic/meson-gxbb.dtsi b/arch/arm64/boot/dts/amlogic/meson-gxbb.dtsi +index d760d93..daa49ae 100644 +--- a/arch/arm64/boot/dts/amlogic/meson-gxbb.dtsi ++++ b/arch/arm64/boot/dts/amlogic/meson-gxbb.dtsi +@@ -255,6 +255,20 @@ + function = "spdif_out_ao"; + }; + }; ++ ++ ao_cec_pins: ao_cec { ++ mux { ++ groups = "ao_cec"; ++ function = "cec_ao"; ++ }; ++ }; ++ ++ ee_cec_pins: ee_cec { ++ mux { ++ groups = "ee_cec"; ++ function = "cec_ao"; ++ }; ++ }; + }; + }; + +-- +1.9.1 + diff --git a/patch/kernel/odroidc2-next/0010-drm-bridge-Link-encoder-and-bridge-in-core-code.patch b/patch/kernel/odroidc2-next/0010-drm-bridge-Link-encoder-and-bridge-in-core-code.patch deleted file mode 100644 index 31c2ee7d1..000000000 --- a/patch/kernel/odroidc2-next/0010-drm-bridge-Link-encoder-and-bridge-in-core-code.patch +++ /dev/null @@ -1,639 +0,0 @@ -From b53f55423fe344ecdd5bc8b2437170013a0a46e4 Mon Sep 17 00:00:00 2001 -From: Laurent Pinchart -Date: Mon, 28 Nov 2016 17:59:08 +0200 -Subject: [PATCH 10/93] drm: bridge: Link encoder and bridge in core code - -Instead of linking encoders and bridges in every driver (and getting it -wrong half of the time, as many drivers forget to set the drm_bridge -encoder pointer), do so in core code. The drm_bridge_attach() function -needs the encoder and optional previous bridge to perform that task, -update all the callers. - -Signed-off-by: Laurent Pinchart -Acked-by: Stefan Agner # For DCU -Acked-by: Boris Brezillon # For atmel-hlcdc -Acked-by: Vincent Abriou # For STI -Acked-by: Maxime Ripard # For sun4i -Acked-by: Xinliang Liu # For hisilicon -Acked-by: Jyri Sarha # For tilcdc -Reviewed-by: Daniel Vetter -Signed-off-by: Archit Taneja -Link: http://patchwork.freedesktop.org/patch/msgid/1481709550-29226-4-git-send-email-laurent.pinchart+renesas@ideasonboard.com ---- - drivers/gpu/drm/arc/arcpgu_hdmi.c | 5 +-- - drivers/gpu/drm/atmel-hlcdc/atmel_hlcdc_output.c | 4 +- - drivers/gpu/drm/bridge/analogix/analogix_dp_core.c | 4 +- - drivers/gpu/drm/bridge/dw-hdmi.c | 3 +- - drivers/gpu/drm/drm_bridge.c | 46 ++++++++++++++++------ - drivers/gpu/drm/drm_simple_kms_helper.c | 4 +- - drivers/gpu/drm/exynos/exynos_dp.c | 5 +-- - drivers/gpu/drm/exynos/exynos_drm_dsi.c | 6 +-- - drivers/gpu/drm/fsl-dcu/fsl_dcu_drm_rgb.c | 5 +-- - drivers/gpu/drm/hisilicon/kirin/dw_drm_dsi.c | 5 +-- - drivers/gpu/drm/imx/imx-ldb.c | 6 +-- - drivers/gpu/drm/imx/parallel-display.c | 4 +- - drivers/gpu/drm/mediatek/mtk_dpi.c | 8 ++-- - drivers/gpu/drm/mediatek/mtk_dsi.c | 24 ++--------- - drivers/gpu/drm/mediatek/mtk_hdmi.c | 11 +++--- - drivers/gpu/drm/msm/dsi/dsi_manager.c | 17 +++++--- - drivers/gpu/drm/msm/edp/edp_bridge.c | 2 +- - drivers/gpu/drm/msm/hdmi/hdmi_bridge.c | 2 +- - drivers/gpu/drm/rcar-du/rcar_du_hdmienc.c | 5 +-- - drivers/gpu/drm/sti/sti_dvo.c | 3 +- - drivers/gpu/drm/sti/sti_hda.c | 3 +- - drivers/gpu/drm/sti/sti_hdmi.c | 3 +- - drivers/gpu/drm/sun4i/sun4i_rgb.c | 13 +++--- - drivers/gpu/drm/tilcdc/tilcdc_external.c | 4 +- - include/drm/drm_bridge.h | 3 +- - 25 files changed, 85 insertions(+), 110 deletions(-) - -diff --git a/drivers/gpu/drm/arc/arcpgu_hdmi.c b/drivers/gpu/drm/arc/arcpgu_hdmi.c -index b69c66b..0ce7f39 100644 ---- a/drivers/gpu/drm/arc/arcpgu_hdmi.c -+++ b/drivers/gpu/drm/arc/arcpgu_hdmi.c -@@ -47,10 +47,7 @@ int arcpgu_drm_hdmi_init(struct drm_device *drm, struct device_node *np) - return ret; - - /* Link drm_bridge to encoder */ -- bridge->encoder = encoder; -- encoder->bridge = bridge; -- -- ret = drm_bridge_attach(drm, bridge); -+ ret = drm_bridge_attach(encoder, bridge, NULL); - if (ret) - drm_encoder_cleanup(encoder); - -diff --git a/drivers/gpu/drm/atmel-hlcdc/atmel_hlcdc_output.c b/drivers/gpu/drm/atmel-hlcdc/atmel_hlcdc_output.c -index 6119b50..e7799b6 100644 ---- a/drivers/gpu/drm/atmel-hlcdc/atmel_hlcdc_output.c -+++ b/drivers/gpu/drm/atmel-hlcdc/atmel_hlcdc_output.c -@@ -230,9 +230,7 @@ static int atmel_hlcdc_attach_endpoint(struct drm_device *dev, - of_node_put(np); - - if (bridge) { -- output->encoder.bridge = bridge; -- bridge->encoder = &output->encoder; -- ret = drm_bridge_attach(dev, bridge); -+ ret = drm_bridge_attach(&output->encoder, bridge, NULL); - if (!ret) - return 0; - } -diff --git a/drivers/gpu/drm/bridge/analogix/analogix_dp_core.c b/drivers/gpu/drm/bridge/analogix/analogix_dp_core.c -index 18eefdc..dfae80f 100644 ---- a/drivers/gpu/drm/bridge/analogix/analogix_dp_core.c -+++ b/drivers/gpu/drm/bridge/analogix/analogix_dp_core.c -@@ -1227,12 +1227,10 @@ static int analogix_dp_create_bridge(struct drm_device *drm_dev, - - dp->bridge = bridge; - -- dp->encoder->bridge = bridge; - bridge->driver_private = dp; -- bridge->encoder = dp->encoder; - bridge->funcs = &analogix_dp_bridge_funcs; - -- ret = drm_bridge_attach(drm_dev, bridge); -+ ret = drm_bridge_attach(dp->encoder, bridge, NULL); - if (ret) { - DRM_ERROR("failed to attach drm bridge\n"); - return -EINVAL; -diff --git a/drivers/gpu/drm/bridge/dw-hdmi.c b/drivers/gpu/drm/bridge/dw-hdmi.c -index 235ce7d..f5009ae 100644 ---- a/drivers/gpu/drm/bridge/dw-hdmi.c -+++ b/drivers/gpu/drm/bridge/dw-hdmi.c -@@ -1841,13 +1841,12 @@ static int dw_hdmi_register(struct drm_device *drm, struct dw_hdmi *hdmi) - hdmi->bridge = bridge; - bridge->driver_private = hdmi; - bridge->funcs = &dw_hdmi_bridge_funcs; -- ret = drm_bridge_attach(drm, bridge); -+ ret = drm_bridge_attach(encoder, bridge, NULL); - if (ret) { - DRM_ERROR("Failed to initialize bridge with drm\n"); - return -EINVAL; - } - -- encoder->bridge = bridge; - hdmi->connector.polled = DRM_CONNECTOR_POLL_HPD; - - drm_connector_helper_add(&hdmi->connector, -diff --git a/drivers/gpu/drm/drm_bridge.c b/drivers/gpu/drm/drm_bridge.c -index 0ee052b..850bd65 100644 ---- a/drivers/gpu/drm/drm_bridge.c -+++ b/drivers/gpu/drm/drm_bridge.c -@@ -26,6 +26,7 @@ - #include - - #include -+#include - - /** - * DOC: overview -@@ -92,32 +93,53 @@ void drm_bridge_remove(struct drm_bridge *bridge) - EXPORT_SYMBOL(drm_bridge_remove); - - /** -- * drm_bridge_attach - associate given bridge to our DRM device -+ * drm_bridge_attach - attach the bridge to an encoder's chain - * -- * @dev: DRM device -- * @bridge: bridge control structure -+ * @encoder: DRM encoder -+ * @bridge: bridge to attach -+ * @previous: previous bridge in the chain (optional) - * -- * Called by a kms driver to link one of our encoder/bridge to the given -- * bridge. -+ * Called by a kms driver to link the bridge to an encoder's chain. The previous -+ * argument specifies the previous bridge in the chain. If NULL, the bridge is -+ * linked directly at the encoder's output. Otherwise it is linked at the -+ * previous bridge's output. - * -- * Note that setting up links between the bridge and our encoder/bridge -- * objects needs to be handled by the kms driver itself. -+ * If non-NULL the previous bridge must be already attached by a call to this -+ * function. - * - * RETURNS: - * Zero on success, error code on failure - */ --int drm_bridge_attach(struct drm_device *dev, struct drm_bridge *bridge) -+int drm_bridge_attach(struct drm_encoder *encoder, struct drm_bridge *bridge, -+ struct drm_bridge *previous) - { -- if (!dev || !bridge) -+ int ret; -+ -+ if (!encoder || !bridge) -+ return -EINVAL; -+ -+ if (previous && (!previous->dev || previous->encoder != encoder)) - return -EINVAL; - - if (bridge->dev) - return -EBUSY; - -- bridge->dev = dev; -+ bridge->dev = encoder->dev; -+ bridge->encoder = encoder; -+ -+ if (bridge->funcs->attach) { -+ ret = bridge->funcs->attach(bridge); -+ if (ret < 0) { -+ bridge->dev = NULL; -+ bridge->encoder = NULL; -+ return ret; -+ } -+ } - -- if (bridge->funcs->attach) -- return bridge->funcs->attach(bridge); -+ if (previous) -+ previous->next = bridge; -+ else -+ encoder->bridge = bridge; - - return 0; - } -diff --git a/drivers/gpu/drm/drm_simple_kms_helper.c b/drivers/gpu/drm/drm_simple_kms_helper.c -index 7bae08c..ba7be61 100644 ---- a/drivers/gpu/drm/drm_simple_kms_helper.c -+++ b/drivers/gpu/drm/drm_simple_kms_helper.c -@@ -182,9 +182,7 @@ static void drm_simple_kms_plane_cleanup_fb(struct drm_plane *plane, - int drm_simple_display_pipe_attach_bridge(struct drm_simple_display_pipe *pipe, - struct drm_bridge *bridge) - { -- bridge->encoder = &pipe->encoder; -- pipe->encoder.bridge = bridge; -- return drm_bridge_attach(pipe->encoder.dev, bridge); -+ return drm_bridge_attach(&pipe->encoder, bridge, NULL); - } - EXPORT_SYMBOL(drm_simple_display_pipe_attach_bridge); - -diff --git a/drivers/gpu/drm/exynos/exynos_dp.c b/drivers/gpu/drm/exynos/exynos_dp.c -index 528229f..1ef0be3 100644 ---- a/drivers/gpu/drm/exynos/exynos_dp.c -+++ b/drivers/gpu/drm/exynos/exynos_dp.c -@@ -99,7 +99,6 @@ static int exynos_dp_bridge_attach(struct analogix_dp_plat_data *plat_data, - struct drm_connector *connector) - { - struct exynos_dp_device *dp = to_dp(plat_data); -- struct drm_encoder *encoder = &dp->encoder; - int ret; - - drm_connector_register(connector); -@@ -107,9 +106,7 @@ static int exynos_dp_bridge_attach(struct analogix_dp_plat_data *plat_data, - - /* Pre-empt DP connector creation if there's a bridge */ - if (dp->ptn_bridge) { -- bridge->next = dp->ptn_bridge; -- dp->ptn_bridge->encoder = encoder; -- ret = drm_bridge_attach(encoder->dev, dp->ptn_bridge); -+ ret = drm_bridge_attach(&dp->encoder, dp->ptn_bridge, bridge); - if (ret) { - DRM_ERROR("Failed to attach bridge to drm\n"); - bridge->next = NULL; -diff --git a/drivers/gpu/drm/exynos/exynos_drm_dsi.c b/drivers/gpu/drm/exynos/exynos_drm_dsi.c -index e07cb1f..812e2ec 100644 ---- a/drivers/gpu/drm/exynos/exynos_drm_dsi.c -+++ b/drivers/gpu/drm/exynos/exynos_drm_dsi.c -@@ -1718,10 +1718,8 @@ static int exynos_dsi_bind(struct device *dev, struct device *master, - } - - bridge = of_drm_find_bridge(dsi->bridge_node); -- if (bridge) { -- encoder->bridge = bridge; -- drm_bridge_attach(drm_dev, bridge); -- } -+ if (bridge) -+ drm_bridge_attach(encoder, bridge, NULL); - - return mipi_dsi_host_register(&dsi->dsi_host); - } -diff --git a/drivers/gpu/drm/fsl-dcu/fsl_dcu_drm_rgb.c b/drivers/gpu/drm/fsl-dcu/fsl_dcu_drm_rgb.c -index 05a8ee1..c365145 100644 ---- a/drivers/gpu/drm/fsl-dcu/fsl_dcu_drm_rgb.c -+++ b/drivers/gpu/drm/fsl-dcu/fsl_dcu_drm_rgb.c -@@ -160,10 +160,7 @@ static int fsl_dcu_attach_endpoint(struct fsl_dcu_drm_device *fsl_dev, - if (!bridge) - return -ENODEV; - -- fsl_dev->encoder.bridge = bridge; -- bridge->encoder = &fsl_dev->encoder; -- -- return drm_bridge_attach(fsl_dev->drm, bridge); -+ return drm_bridge_attach(&fsl_dev->encoder, bridge, NULL); - } - - int fsl_dcu_create_outputs(struct fsl_dcu_drm_device *fsl_dev) -diff --git a/drivers/gpu/drm/hisilicon/kirin/dw_drm_dsi.c b/drivers/gpu/drm/hisilicon/kirin/dw_drm_dsi.c -index 998452a..1737e98 100644 ---- a/drivers/gpu/drm/hisilicon/kirin/dw_drm_dsi.c -+++ b/drivers/gpu/drm/hisilicon/kirin/dw_drm_dsi.c -@@ -709,10 +709,7 @@ static int dsi_bridge_init(struct drm_device *dev, struct dw_dsi *dsi) - int ret; - - /* associate the bridge to dsi encoder */ -- encoder->bridge = bridge; -- bridge->encoder = encoder; -- -- ret = drm_bridge_attach(dev, bridge); -+ ret = drm_bridge_attach(encoder, bridge, NULL); - if (ret) { - DRM_ERROR("failed to attach external bridge\n"); - return ret; -diff --git a/drivers/gpu/drm/imx/imx-ldb.c b/drivers/gpu/drm/imx/imx-ldb.c -index 516d064..ec49ea3 100644 ---- a/drivers/gpu/drm/imx/imx-ldb.c -+++ b/drivers/gpu/drm/imx/imx-ldb.c -@@ -454,10 +454,8 @@ static int imx_ldb_register(struct drm_device *drm, - DRM_MODE_ENCODER_LVDS, NULL); - - if (imx_ldb_ch->bridge) { -- imx_ldb_ch->bridge->encoder = encoder; -- -- imx_ldb_ch->encoder.bridge = imx_ldb_ch->bridge; -- ret = drm_bridge_attach(drm, imx_ldb_ch->bridge); -+ ret = drm_bridge_attach(&imx_ldb_ch->encoder, -+ imx_ldb_ch->bridge, NULL); - if (ret) { - DRM_ERROR("Failed to initialize bridge with drm\n"); - return ret; -diff --git a/drivers/gpu/drm/imx/parallel-display.c b/drivers/gpu/drm/imx/parallel-display.c -index 8582a83..51d9f73 100644 ---- a/drivers/gpu/drm/imx/parallel-display.c -+++ b/drivers/gpu/drm/imx/parallel-display.c -@@ -191,9 +191,7 @@ static int imx_pd_register(struct drm_device *drm, - drm_panel_attach(imxpd->panel, &imxpd->connector); - - if (imxpd->bridge) { -- imxpd->bridge->encoder = encoder; -- encoder->bridge = imxpd->bridge; -- ret = drm_bridge_attach(drm, imxpd->bridge); -+ ret = drm_bridge_attach(encoder, imxpd->bridge, NULL); - if (ret < 0) { - dev_err(imxpd->dev, "failed to attach bridge: %d\n", - ret); -diff --git a/drivers/gpu/drm/mediatek/mtk_dpi.c b/drivers/gpu/drm/mediatek/mtk_dpi.c -index 90fb831..3bd3bd6 100644 ---- a/drivers/gpu/drm/mediatek/mtk_dpi.c -+++ b/drivers/gpu/drm/mediatek/mtk_dpi.c -@@ -63,6 +63,7 @@ enum mtk_dpi_out_color_format { - struct mtk_dpi { - struct mtk_ddp_comp ddp_comp; - struct drm_encoder encoder; -+ struct drm_bridge *bridge; - void __iomem *regs; - struct device *dev; - struct clk *engine_clk; -@@ -620,8 +621,7 @@ static int mtk_dpi_bind(struct device *dev, struct device *master, void *data) - /* Currently DPI0 is fixed to be driven by OVL1 */ - dpi->encoder.possible_crtcs = BIT(1); - -- dpi->encoder.bridge->encoder = &dpi->encoder; -- ret = drm_bridge_attach(dpi->encoder.dev, dpi->encoder.bridge); -+ ret = drm_bridge_attach(&dpi->encoder, dpi->bridge, NULL); - if (ret) { - dev_err(dev, "Failed to attach bridge: %d\n", ret); - goto err_cleanup; -@@ -718,9 +718,9 @@ static int mtk_dpi_probe(struct platform_device *pdev) - - dev_info(dev, "Found bridge node: %s\n", bridge_node->full_name); - -- dpi->encoder.bridge = of_drm_find_bridge(bridge_node); -+ dpi->bridge = of_drm_find_bridge(bridge_node); - of_node_put(bridge_node); -- if (!dpi->encoder.bridge) -+ if (!dpi->bridge) - return -EPROBE_DEFER; - - comp_id = mtk_ddp_comp_get_id(dev->of_node, MTK_DPI); -diff --git a/drivers/gpu/drm/mediatek/mtk_dsi.c b/drivers/gpu/drm/mediatek/mtk_dsi.c -index 2c42f90..dd71cbb 100644 ---- a/drivers/gpu/drm/mediatek/mtk_dsi.c -+++ b/drivers/gpu/drm/mediatek/mtk_dsi.c -@@ -622,26 +622,6 @@ static int mtk_dsi_connector_get_modes(struct drm_connector *connector) - .get_modes = mtk_dsi_connector_get_modes, - }; - --static int mtk_drm_attach_bridge(struct drm_bridge *bridge, -- struct drm_encoder *encoder) --{ -- int ret; -- -- if (!bridge) -- return -ENOENT; -- -- encoder->bridge = bridge; -- bridge->encoder = encoder; -- ret = drm_bridge_attach(encoder->dev, bridge); -- if (ret) { -- DRM_ERROR("Failed to attach bridge to drm\n"); -- encoder->bridge = NULL; -- bridge->encoder = NULL; -- } -- -- return ret; --} -- - static int mtk_dsi_create_connector(struct drm_device *drm, struct mtk_dsi *dsi) - { - int ret; -@@ -692,8 +672,10 @@ static int mtk_dsi_create_conn_enc(struct drm_device *drm, struct mtk_dsi *dsi) - dsi->encoder.possible_crtcs = 1; - - /* If there's a bridge, attach to it and let it create the connector */ -- ret = mtk_drm_attach_bridge(dsi->bridge, &dsi->encoder); -+ ret = drm_bridge_attach(&dsi->encoder, dsi->bridge, NULL); - if (ret) { -+ DRM_ERROR("Failed to attach bridge to drm\n"); -+ - /* Otherwise create our own connector and attach to a panel */ - ret = mtk_dsi_create_connector(drm, dsi); - if (ret) -diff --git a/drivers/gpu/drm/mediatek/mtk_hdmi.c b/drivers/gpu/drm/mediatek/mtk_hdmi.c -index 0e8c4d9..c262512 100644 ---- a/drivers/gpu/drm/mediatek/mtk_hdmi.c -+++ b/drivers/gpu/drm/mediatek/mtk_hdmi.c -@@ -149,6 +149,7 @@ struct hdmi_audio_param { - - struct mtk_hdmi { - struct drm_bridge bridge; -+ struct drm_bridge *next_bridge; - struct drm_connector conn; - struct device *dev; - struct phy *phy; -@@ -1314,9 +1315,9 @@ static int mtk_hdmi_bridge_attach(struct drm_bridge *bridge) - return ret; - } - -- if (bridge->next) { -- bridge->next->encoder = bridge->encoder; -- ret = drm_bridge_attach(bridge->encoder->dev, bridge->next); -+ if (hdmi->next_bridge) { -+ ret = drm_bridge_attach(bridge->encoder, hdmi->next_bridge, -+ bridge); - if (ret) { - dev_err(hdmi->dev, - "Failed to attach external bridge: %d\n", ret); -@@ -1510,8 +1511,8 @@ static int mtk_hdmi_dt_parse_pdata(struct mtk_hdmi *hdmi, - of_node_put(ep); - - if (!of_device_is_compatible(remote, "hdmi-connector")) { -- hdmi->bridge.next = of_drm_find_bridge(remote); -- if (!hdmi->bridge.next) { -+ hdmi->next_bridge = of_drm_find_bridge(remote); -+ if (!hdmi->next_bridge) { - dev_err(dev, "Waiting for external bridge\n"); - of_node_put(remote); - return -EPROBE_DEFER; -diff --git a/drivers/gpu/drm/msm/dsi/dsi_manager.c b/drivers/gpu/drm/msm/dsi/dsi_manager.c -index c8d1f19..2bd8dad 100644 ---- a/drivers/gpu/drm/msm/dsi/dsi_manager.c -+++ b/drivers/gpu/drm/msm/dsi/dsi_manager.c -@@ -579,6 +579,7 @@ struct drm_bridge *msm_dsi_manager_bridge_init(u8 id) - struct msm_dsi *msm_dsi = dsi_mgr_get_dsi(id); - struct drm_bridge *bridge = NULL; - struct dsi_bridge *dsi_bridge; -+ struct drm_encoder *encoder; - int ret; - - dsi_bridge = devm_kzalloc(msm_dsi->dev->dev, -@@ -590,10 +591,18 @@ struct drm_bridge *msm_dsi_manager_bridge_init(u8 id) - - dsi_bridge->id = id; - -+ /* -+ * HACK: we may not know the external DSI bridge device's mode -+ * flags here. We'll get to know them only when the device -+ * attaches to the dsi host. For now, assume the bridge supports -+ * DSI video mode -+ */ -+ encoder = msm_dsi->encoders[MSM_DSI_VIDEO_ENCODER_ID]; -+ - bridge = &dsi_bridge->base; - bridge->funcs = &dsi_mgr_bridge_funcs; - -- ret = drm_bridge_attach(msm_dsi->dev, bridge); -+ ret = drm_bridge_attach(encoder, bridge, NULL); - if (ret) - goto fail; - -@@ -628,11 +637,7 @@ struct drm_connector *msm_dsi_manager_ext_bridge_init(u8 id) - encoder = msm_dsi->encoders[MSM_DSI_VIDEO_ENCODER_ID]; - - /* link the internal dsi bridge to the external bridge */ -- int_bridge->next = ext_bridge; -- /* set the external bridge's encoder as dsi's encoder */ -- ext_bridge->encoder = encoder; -- -- drm_bridge_attach(dev, ext_bridge); -+ drm_bridge_attach(encoder, ext_bridge, int_bridge); - - /* - * we need the drm_connector created by the external bridge -diff --git a/drivers/gpu/drm/msm/edp/edp_bridge.c b/drivers/gpu/drm/msm/edp/edp_bridge.c -index 2bc73f82..931a5c9 100644 ---- a/drivers/gpu/drm/msm/edp/edp_bridge.c -+++ b/drivers/gpu/drm/msm/edp/edp_bridge.c -@@ -106,7 +106,7 @@ struct drm_bridge *msm_edp_bridge_init(struct msm_edp *edp) - bridge = &edp_bridge->base; - bridge->funcs = &edp_bridge_funcs; - -- ret = drm_bridge_attach(edp->dev, bridge); -+ ret = drm_bridge_attach(edp->encoder, bridge, NULL); - if (ret) - goto fail; - -diff --git a/drivers/gpu/drm/msm/hdmi/hdmi_bridge.c b/drivers/gpu/drm/msm/hdmi/hdmi_bridge.c -index bacbd5d..4e6d1bf 100644 ---- a/drivers/gpu/drm/msm/hdmi/hdmi_bridge.c -+++ b/drivers/gpu/drm/msm/hdmi/hdmi_bridge.c -@@ -227,7 +227,7 @@ struct drm_bridge *msm_hdmi_bridge_init(struct hdmi *hdmi) - bridge = &hdmi_bridge->base; - bridge->funcs = &msm_hdmi_bridge_funcs; - -- ret = drm_bridge_attach(hdmi->dev, bridge); -+ ret = drm_bridge_attach(hdmi->encoder, bridge, NULL); - if (ret) - goto fail; - -diff --git a/drivers/gpu/drm/rcar-du/rcar_du_hdmienc.c b/drivers/gpu/drm/rcar-du/rcar_du_hdmienc.c -index f9515f5..c4c5d1ab 100644 ---- a/drivers/gpu/drm/rcar-du/rcar_du_hdmienc.c -+++ b/drivers/gpu/drm/rcar-du/rcar_du_hdmienc.c -@@ -124,10 +124,7 @@ int rcar_du_hdmienc_init(struct rcar_du_device *rcdu, - hdmienc->renc = renc; - - /* Link the bridge to the encoder. */ -- bridge->encoder = encoder; -- encoder->bridge = bridge; -- -- ret = drm_bridge_attach(rcdu->ddev, bridge); -+ ret = drm_bridge_attach(encoder, bridge, NULL); - if (ret) { - drm_encoder_cleanup(encoder); - return ret; -diff --git a/drivers/gpu/drm/sti/sti_dvo.c b/drivers/gpu/drm/sti/sti_dvo.c -index e8c1ed0..411dc6e 100644 ---- a/drivers/gpu/drm/sti/sti_dvo.c -+++ b/drivers/gpu/drm/sti/sti_dvo.c -@@ -478,14 +478,13 @@ static int sti_dvo_bind(struct device *dev, struct device *master, void *data) - return err; - } - -- err = drm_bridge_attach(drm_dev, bridge); -+ err = drm_bridge_attach(encoder, bridge, NULL); - if (err) { - DRM_ERROR("Failed to attach bridge\n"); - return err; - } - - dvo->bridge = bridge; -- encoder->bridge = bridge; - connector->encoder = encoder; - dvo->encoder = encoder; - -diff --git a/drivers/gpu/drm/sti/sti_hda.c b/drivers/gpu/drm/sti/sti_hda.c -index 96f336d..66d37d78 100644 ---- a/drivers/gpu/drm/sti/sti_hda.c -+++ b/drivers/gpu/drm/sti/sti_hda.c -@@ -707,9 +707,8 @@ static int sti_hda_bind(struct device *dev, struct device *master, void *data) - - bridge->driver_private = hda; - bridge->funcs = &sti_hda_bridge_funcs; -- drm_bridge_attach(drm_dev, bridge); -+ drm_bridge_attach(encoder, bridge, NULL); - -- encoder->bridge = bridge; - connector->encoder = encoder; - - drm_connector = (struct drm_connector *)connector; -diff --git a/drivers/gpu/drm/sti/sti_hdmi.c b/drivers/gpu/drm/sti/sti_hdmi.c -index 376b076..f0af1ae 100644 ---- a/drivers/gpu/drm/sti/sti_hdmi.c -+++ b/drivers/gpu/drm/sti/sti_hdmi.c -@@ -1308,9 +1308,8 @@ static int sti_hdmi_bind(struct device *dev, struct device *master, void *data) - - bridge->driver_private = hdmi; - bridge->funcs = &sti_hdmi_bridge_funcs; -- drm_bridge_attach(drm_dev, bridge); -+ drm_bridge_attach(encoder, bridge, NULL); - -- encoder->bridge = bridge; - connector->encoder = encoder; - - drm_connector = (struct drm_connector *)connector; -diff --git a/drivers/gpu/drm/sun4i/sun4i_rgb.c b/drivers/gpu/drm/sun4i/sun4i_rgb.c -index f5e86fe..757208f 100644 ---- a/drivers/gpu/drm/sun4i/sun4i_rgb.c -+++ b/drivers/gpu/drm/sun4i/sun4i_rgb.c -@@ -208,6 +208,7 @@ int sun4i_rgb_init(struct drm_device *drm) - struct sun4i_drv *drv = drm->dev_private; - struct sun4i_tcon *tcon = drv->tcon; - struct drm_encoder *encoder; -+ struct drm_bridge *bridge; - struct sun4i_rgb *rgb; - int ret; - -@@ -218,8 +219,8 @@ int sun4i_rgb_init(struct drm_device *drm) - encoder = &rgb->encoder; - - tcon->panel = sun4i_tcon_find_panel(tcon->dev->of_node); -- encoder->bridge = sun4i_tcon_find_bridge(tcon->dev->of_node); -- if (IS_ERR(tcon->panel) && IS_ERR(encoder->bridge)) { -+ bridge = sun4i_tcon_find_bridge(tcon->dev->of_node); -+ if (IS_ERR(tcon->panel) && IS_ERR(bridge)) { - dev_info(drm->dev, "No panel or bridge found... RGB output disabled\n"); - return 0; - } -@@ -260,16 +261,12 @@ int sun4i_rgb_init(struct drm_device *drm) - } - } - -- if (!IS_ERR(encoder->bridge)) { -- encoder->bridge->encoder = &rgb->encoder; -- -- ret = drm_bridge_attach(drm, encoder->bridge); -+ if (!IS_ERR(bridge)) { -+ ret = drm_bridge_attach(encoder, bridge, NULL); - if (ret) { - dev_err(drm->dev, "Couldn't attach our bridge\n"); - goto err_cleanup_connector; - } -- } else { -- encoder->bridge = NULL; - } - - return 0; -diff --git a/drivers/gpu/drm/tilcdc/tilcdc_external.c b/drivers/gpu/drm/tilcdc/tilcdc_external.c -index c67d7cd..b0dd5e8 100644 ---- a/drivers/gpu/drm/tilcdc/tilcdc_external.c -+++ b/drivers/gpu/drm/tilcdc/tilcdc_external.c -@@ -167,10 +167,8 @@ int tilcdc_attach_bridge(struct drm_device *ddev, struct drm_bridge *bridge) - int ret; - - priv->external_encoder->possible_crtcs = BIT(0); -- priv->external_encoder->bridge = bridge; -- bridge->encoder = priv->external_encoder; - -- ret = drm_bridge_attach(ddev, bridge); -+ ret = drm_bridge_attach(priv->external_encoder, bridge, NULL); - if (ret) { - dev_err(ddev->dev, "drm_bridge_attach() failed %d\n", ret); - return ret; -diff --git a/include/drm/drm_bridge.h b/include/drm/drm_bridge.h -index 530a1d6..94e5ee9 100644 ---- a/include/drm/drm_bridge.h -+++ b/include/drm/drm_bridge.h -@@ -201,7 +201,8 @@ struct drm_bridge { - int drm_bridge_add(struct drm_bridge *bridge); - void drm_bridge_remove(struct drm_bridge *bridge); - struct drm_bridge *of_drm_find_bridge(struct device_node *np); --int drm_bridge_attach(struct drm_device *dev, struct drm_bridge *bridge); -+int drm_bridge_attach(struct drm_encoder *encoder, struct drm_bridge *bridge, -+ struct drm_bridge *previous); - void drm_bridge_detach(struct drm_bridge *bridge); - - bool drm_bridge_mode_fixup(struct drm_bridge *bridge, --- -1.9.1 - diff --git a/patch/kernel/odroidc2-next/0011-ARM64-dts-meson-gxl-Add-CEC-pins-nodes.patch b/patch/kernel/odroidc2-next/0011-ARM64-dts-meson-gxl-Add-CEC-pins-nodes.patch new file mode 100644 index 000000000..960681584 --- /dev/null +++ b/patch/kernel/odroidc2-next/0011-ARM64-dts-meson-gxl-Add-CEC-pins-nodes.patch @@ -0,0 +1,40 @@ +From 629ad838c870b17536666327dcedbd0f8762cae8 Mon Sep 17 00:00:00 2001 +From: Neil Armstrong +Date: Wed, 24 May 2017 09:41:48 +0200 +Subject: [PATCH 11/79] ARM64: dts: meson-gxl: Add CEC pins nodes + +Add the AO and EE domain CEC pins nodes for the Amlogic Meson GXL SoCs. + +Signed-off-by: Neil Armstrong +--- + arch/arm64/boot/dts/amlogic/meson-gxl.dtsi | 14 ++++++++++++++ + 1 file changed, 14 insertions(+) + +diff --git a/arch/arm64/boot/dts/amlogic/meson-gxl.dtsi b/arch/arm64/boot/dts/amlogic/meson-gxl.dtsi +index 3a1ccf5..15539f9 100644 +--- a/arch/arm64/boot/dts/amlogic/meson-gxl.dtsi ++++ b/arch/arm64/boot/dts/amlogic/meson-gxl.dtsi +@@ -191,6 +191,20 @@ + function = "spdif_out_ao"; + }; + }; ++ ++ ao_cec_pins: ao_cec { ++ mux { ++ groups = "ao_cec"; ++ function = "cec_ao"; ++ }; ++ }; ++ ++ ee_cec_pins: ee_cec { ++ mux { ++ groups = "ee_cec"; ++ function = "cec_ao"; ++ }; ++ }; + }; + }; + +-- +1.9.1 + diff --git a/patch/kernel/odroidc2-next/0011-drm-bridge-dw-hdmi-Merge-__hdmi_phy_i2c_write-and-hd.patch b/patch/kernel/odroidc2-next/0011-drm-bridge-dw-hdmi-Merge-__hdmi_phy_i2c_write-and-hd.patch deleted file mode 100644 index 56710ca7e..000000000 --- a/patch/kernel/odroidc2-next/0011-drm-bridge-dw-hdmi-Merge-__hdmi_phy_i2c_write-and-hd.patch +++ /dev/null @@ -1,48 +0,0 @@ -From 4d69de06ed2934b45c0e6b2a5056ef2a7caa0b9a Mon Sep 17 00:00:00 2001 -From: Laurent Pinchart -Date: Tue, 17 Jan 2017 10:28:51 +0200 -Subject: [PATCH 11/93] drm: bridge: dw-hdmi: Merge __hdmi_phy_i2c_write and - hdmi_phy_i2c_write - -The latter is just an int wrapper around the former void function that -unconditionally returns 0. As the return value is never checked, merge -the two functions into one. - -Signed-off-by: Laurent Pinchart -Reviewed-by: Jose Abreu -Signed-off-by: Archit Taneja -Link: http://patchwork.freedesktop.org/patch/msgid/20170117082910.27023-2-laurent.pinchart+renesas@ideasonboard.com ---- - drivers/gpu/drm/bridge/dw-hdmi.c | 9 +-------- - 1 file changed, 1 insertion(+), 8 deletions(-) - -diff --git a/drivers/gpu/drm/bridge/dw-hdmi.c b/drivers/gpu/drm/bridge/dw-hdmi.c -index f5009ae..a668550 100644 ---- a/drivers/gpu/drm/bridge/dw-hdmi.c -+++ b/drivers/gpu/drm/bridge/dw-hdmi.c -@@ -868,7 +868,7 @@ static bool hdmi_phy_wait_i2c_done(struct dw_hdmi *hdmi, int msec) - return true; - } - --static void __hdmi_phy_i2c_write(struct dw_hdmi *hdmi, unsigned short data, -+static void hdmi_phy_i2c_write(struct dw_hdmi *hdmi, unsigned short data, - unsigned char addr) - { - hdmi_writeb(hdmi, 0xFF, HDMI_IH_I2CMPHY_STAT0); -@@ -882,13 +882,6 @@ static void __hdmi_phy_i2c_write(struct dw_hdmi *hdmi, unsigned short data, - hdmi_phy_wait_i2c_done(hdmi, 1000); - } - --static int hdmi_phy_i2c_write(struct dw_hdmi *hdmi, unsigned short data, -- unsigned char addr) --{ -- __hdmi_phy_i2c_write(hdmi, data, addr); -- return 0; --} -- - static void dw_hdmi_phy_enable_powerdown(struct dw_hdmi *hdmi, bool enable) - { - hdmi_mask_writeb(hdmi, !enable, HDMI_PHY_CONF0, --- -1.9.1 - diff --git a/patch/kernel/odroidc2-next/0012-ARM64-dts-meson-gxl-Add-Ethernet-PHY-LEDS-pins-nodes.patch b/patch/kernel/odroidc2-next/0012-ARM64-dts-meson-gxl-Add-Ethernet-PHY-LEDS-pins-nodes.patch new file mode 100644 index 000000000..a0a5d31ad --- /dev/null +++ b/patch/kernel/odroidc2-next/0012-ARM64-dts-meson-gxl-Add-Ethernet-PHY-LEDS-pins-nodes.patch @@ -0,0 +1,41 @@ +From 69c139fa21249718dfd9d6f14a7b374ae28c8215 Mon Sep 17 00:00:00 2001 +From: Neil Armstrong +Date: Wed, 24 May 2017 09:44:45 +0200 +Subject: [PATCH 12/79] ARM64: dts: meson-gxl: Add Ethernet PHY LEDS pins nodes + +The Amlogic Meson GXL SoCs embeds an 10/100 Ethernet PHY, this patchs adds +the Link and Activity LEDs signals pins nodes. + +Signed-off-by: Neil Armstrong +--- + arch/arm64/boot/dts/amlogic/meson-gxl.dtsi | 14 ++++++++++++++ + 1 file changed, 14 insertions(+) + +diff --git a/arch/arm64/boot/dts/amlogic/meson-gxl.dtsi b/arch/arm64/boot/dts/amlogic/meson-gxl.dtsi +index 15539f9..dc7c53f 100644 +--- a/arch/arm64/boot/dts/amlogic/meson-gxl.dtsi ++++ b/arch/arm64/boot/dts/amlogic/meson-gxl.dtsi +@@ -369,6 +369,20 @@ + }; + }; + ++ eth_link_led_pins: eth_link_led { ++ mux { ++ groups = "eth_link_led"; ++ function = "eth_led"; ++ }; ++ }; ++ ++ eth_act_led_pins: eth_act_led { ++ mux { ++ groups = "eth_act_led"; ++ function = "eth_led"; ++ }; ++ }; ++ + pwm_a_pins: pwm_a { + mux { + groups = "pwm_a"; +-- +1.9.1 + diff --git a/patch/kernel/odroidc2-next/0012-drm-bridge-dw-hdmi-Remove-unneeded-arguments-to-bind.patch b/patch/kernel/odroidc2-next/0012-drm-bridge-dw-hdmi-Remove-unneeded-arguments-to-bind.patch deleted file mode 100644 index c5d39d48d..000000000 --- a/patch/kernel/odroidc2-next/0012-drm-bridge-dw-hdmi-Remove-unneeded-arguments-to-bind.patch +++ /dev/null @@ -1,121 +0,0 @@ -From fefa6576d7b085c7712fdc2b5af10e61f3fa1841 Mon Sep 17 00:00:00 2001 -From: Laurent Pinchart -Date: Tue, 17 Jan 2017 10:28:52 +0200 -Subject: [PATCH 12/93] drm: bridge: dw-hdmi: Remove unneeded arguments to - bind/unbind functions - -The master argument isn't used. The data argument, a void pointer, is -used by the bind function only where it's cast to a drm_device pointer, -which can easily be obtained from the encoder argument instead. Remove -them. - -Signed-off-by: Laurent Pinchart -Reviewed-by: Jose Abreu -Signed-off-by: Archit Taneja -Link: http://patchwork.freedesktop.org/patch/msgid/20170117082910.27023-3-laurent.pinchart+renesas@ideasonboard.com ---- - drivers/gpu/drm/bridge/dw-hdmi.c | 8 +++----- - drivers/gpu/drm/imx/dw_hdmi-imx.c | 4 ++-- - drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c | 4 ++-- - include/drm/bridge/dw_hdmi.h | 5 ++--- - 4 files changed, 9 insertions(+), 12 deletions(-) - -diff --git a/drivers/gpu/drm/bridge/dw-hdmi.c b/drivers/gpu/drm/bridge/dw-hdmi.c -index a668550..f868946 100644 ---- a/drivers/gpu/drm/bridge/dw-hdmi.c -+++ b/drivers/gpu/drm/bridge/dw-hdmi.c -@@ -1854,12 +1854,10 @@ static int dw_hdmi_register(struct drm_device *drm, struct dw_hdmi *hdmi) - return 0; - } - --int dw_hdmi_bind(struct device *dev, struct device *master, -- void *data, struct drm_encoder *encoder, -+int dw_hdmi_bind(struct device *dev, struct drm_encoder *encoder, - struct resource *iores, int irq, - const struct dw_hdmi_plat_data *plat_data) - { -- struct drm_device *drm = data; - struct device_node *np = dev->of_node; - struct platform_device_info pdevinfo; - struct device_node *ddc_node; -@@ -1992,7 +1990,7 @@ int dw_hdmi_bind(struct device *dev, struct device *master, - if (ret) - goto err_iahb; - -- ret = dw_hdmi_register(drm, hdmi); -+ ret = dw_hdmi_register(encoder->dev, hdmi); - if (ret) - goto err_iahb; - -@@ -2059,7 +2057,7 @@ int dw_hdmi_bind(struct device *dev, struct device *master, - } - EXPORT_SYMBOL_GPL(dw_hdmi_bind); - --void dw_hdmi_unbind(struct device *dev, struct device *master, void *data) -+void dw_hdmi_unbind(struct device *dev) - { - struct dw_hdmi *hdmi = dev_get_drvdata(dev); - -diff --git a/drivers/gpu/drm/imx/dw_hdmi-imx.c b/drivers/gpu/drm/imx/dw_hdmi-imx.c -index 359cd27..f796658 100644 ---- a/drivers/gpu/drm/imx/dw_hdmi-imx.c -+++ b/drivers/gpu/drm/imx/dw_hdmi-imx.c -@@ -249,7 +249,7 @@ static int dw_hdmi_imx_bind(struct device *dev, struct device *master, - drm_encoder_init(drm, encoder, &dw_hdmi_imx_encoder_funcs, - DRM_MODE_ENCODER_TMDS, NULL); - -- ret = dw_hdmi_bind(dev, master, data, encoder, iores, irq, plat_data); -+ ret = dw_hdmi_bind(dev, encoder, iores, irq, plat_data); - - /* - * If dw_hdmi_bind() fails we'll never call dw_hdmi_unbind(), -@@ -264,7 +264,7 @@ static int dw_hdmi_imx_bind(struct device *dev, struct device *master, - static void dw_hdmi_imx_unbind(struct device *dev, struct device *master, - void *data) - { -- return dw_hdmi_unbind(dev, master, data); -+ return dw_hdmi_unbind(dev); - } - - static const struct component_ops dw_hdmi_imx_ops = { -diff --git a/drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c b/drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c -index 0665fb9..e8fb5c5 100644 ---- a/drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c -+++ b/drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c -@@ -301,7 +301,7 @@ static int dw_hdmi_rockchip_bind(struct device *dev, struct device *master, - drm_encoder_init(drm, encoder, &dw_hdmi_rockchip_encoder_funcs, - DRM_MODE_ENCODER_TMDS, NULL); - -- ret = dw_hdmi_bind(dev, master, data, encoder, iores, irq, plat_data); -+ ret = dw_hdmi_bind(dev, encoder, iores, irq, plat_data); - - /* - * If dw_hdmi_bind() fails we'll never call dw_hdmi_unbind(), -@@ -316,7 +316,7 @@ static int dw_hdmi_rockchip_bind(struct device *dev, struct device *master, - static void dw_hdmi_rockchip_unbind(struct device *dev, struct device *master, - void *data) - { -- return dw_hdmi_unbind(dev, master, data); -+ return dw_hdmi_unbind(dev); - } - - static const struct component_ops dw_hdmi_rockchip_ops = { -diff --git a/include/drm/bridge/dw_hdmi.h b/include/drm/bridge/dw_hdmi.h -index bae79f3..11edda6 100644 ---- a/include/drm/bridge/dw_hdmi.h -+++ b/include/drm/bridge/dw_hdmi.h -@@ -56,9 +56,8 @@ struct dw_hdmi_plat_data { - struct drm_display_mode *mode); - }; - --void dw_hdmi_unbind(struct device *dev, struct device *master, void *data); --int dw_hdmi_bind(struct device *dev, struct device *master, -- void *data, struct drm_encoder *encoder, -+void dw_hdmi_unbind(struct device *dev); -+int dw_hdmi_bind(struct device *dev, struct drm_encoder *encoder, - struct resource *iores, int irq, - const struct dw_hdmi_plat_data *plat_data); - --- -1.9.1 - diff --git a/patch/kernel/odroidc2-next/0013-ARM64-dts-meson-gxbb-Add-SPI-pinctrl-nodes.patch b/patch/kernel/odroidc2-next/0013-ARM64-dts-meson-gxbb-Add-SPI-pinctrl-nodes.patch new file mode 100644 index 000000000..23b1c91e2 --- /dev/null +++ b/patch/kernel/odroidc2-next/0013-ARM64-dts-meson-gxbb-Add-SPI-pinctrl-nodes.patch @@ -0,0 +1,42 @@ +From f620469d663615a805ca21169013ba79089e2339 Mon Sep 17 00:00:00 2001 +From: Neil Armstrong +Date: Mon, 22 May 2017 15:14:45 +0200 +Subject: [PATCH 13/79] ARM64: dts: meson-gxbb: Add SPI pinctrl nodes + +This patch adds the SPICC Controller pins nodes for Amlogic GXBB SoCs. + +Signed-off-by: Neil Armstrong +--- + arch/arm64/boot/dts/amlogic/meson-gxbb.dtsi | 16 ++++++++++++++++ + 1 file changed, 16 insertions(+) + +diff --git a/arch/arm64/boot/dts/amlogic/meson-gxbb.dtsi b/arch/arm64/boot/dts/amlogic/meson-gxbb.dtsi +index daa49ae..1d4c861 100644 +--- a/arch/arm64/boot/dts/amlogic/meson-gxbb.dtsi ++++ b/arch/arm64/boot/dts/amlogic/meson-gxbb.dtsi +@@ -310,6 +310,22 @@ + }; + }; + ++ spi_pins: spi { ++ mux { ++ groups = "spi_miso", ++ "spi_mosi", ++ "spi_sclk"; ++ function = "spi"; ++ }; ++ }; ++ ++ spi_ss0_pins: spi-ss0 { ++ mux { ++ groups = "spi_ss0"; ++ function = "spi"; ++ }; ++ }; ++ + sdcard_pins: sdcard { + mux { + groups = "sdcard_d0", +-- +1.9.1 + diff --git a/patch/kernel/odroidc2-next/0013-drm-bridge-dw-hdmi-Remove-unused-function-parameter.patch b/patch/kernel/odroidc2-next/0013-drm-bridge-dw-hdmi-Remove-unused-function-parameter.patch deleted file mode 100644 index a826c1871..000000000 --- a/patch/kernel/odroidc2-next/0013-drm-bridge-dw-hdmi-Remove-unused-function-parameter.patch +++ /dev/null @@ -1,55 +0,0 @@ -From 4c8725b2de2a5b87850fb7cfa9d2ecf4499e05fb Mon Sep 17 00:00:00 2001 -From: Kieran Bingham -Date: Tue, 17 Jan 2017 10:28:53 +0200 -Subject: [PATCH 13/93] drm: bridge: dw-hdmi: Remove unused function parameter - -The 'prep' parameter passed to hdmi_phy_configure() is useless. It is -hardcoded as 0, and if set, simply prevents the configure function from -executing. - -Remove it. - -Signed-off-by: Kieran Bingham -Signed-off-by: Laurent Pinchart -Reviewed-by: Jose Abreu -Signed-off-by: Archit Taneja -Link: http://patchwork.freedesktop.org/patch/msgid/20170117082910.27023-4-laurent.pinchart+renesas@ideasonboard.com ---- - drivers/gpu/drm/bridge/dw-hdmi.c | 7 ++----- - 1 file changed, 2 insertions(+), 5 deletions(-) - -diff --git a/drivers/gpu/drm/bridge/dw-hdmi.c b/drivers/gpu/drm/bridge/dw-hdmi.c -index f868946..5f8044a 100644 ---- a/drivers/gpu/drm/bridge/dw-hdmi.c -+++ b/drivers/gpu/drm/bridge/dw-hdmi.c -@@ -931,7 +931,7 @@ static void dw_hdmi_phy_sel_interface_control(struct dw_hdmi *hdmi, u8 enable) - HDMI_PHY_CONF0_SELDIPIF_MASK); - } - --static int hdmi_phy_configure(struct dw_hdmi *hdmi, unsigned char prep, -+static int hdmi_phy_configure(struct dw_hdmi *hdmi, - unsigned char res, int cscon) - { - unsigned res_idx; -@@ -941,9 +941,6 @@ static int hdmi_phy_configure(struct dw_hdmi *hdmi, unsigned char prep, - const struct dw_hdmi_curr_ctrl *curr_ctrl = pdata->cur_ctr; - const struct dw_hdmi_phy_config *phy_config = pdata->phy_config; - -- if (prep) -- return -EINVAL; -- - switch (res) { - case 0: /* color resolution 0 is 8 bit colour depth */ - case 8: -@@ -1072,7 +1069,7 @@ static int dw_hdmi_phy_init(struct dw_hdmi *hdmi) - dw_hdmi_phy_enable_powerdown(hdmi, true); - - /* Enable CSC */ -- ret = hdmi_phy_configure(hdmi, 0, 8, cscon); -+ ret = hdmi_phy_configure(hdmi, 8, cscon); - if (ret) - return ret; - } --- -1.9.1 - diff --git a/patch/kernel/odroidc2-next/0014-ARM64-dts-meson-gxl-Add-SPI-pinctrl-nodes.patch b/patch/kernel/odroidc2-next/0014-ARM64-dts-meson-gxl-Add-SPI-pinctrl-nodes.patch new file mode 100644 index 000000000..ecac27054 --- /dev/null +++ b/patch/kernel/odroidc2-next/0014-ARM64-dts-meson-gxl-Add-SPI-pinctrl-nodes.patch @@ -0,0 +1,42 @@ +From d83151a6b97f039c3efa13d70d9697ef1fd887ac Mon Sep 17 00:00:00 2001 +From: Neil Armstrong +Date: Mon, 22 May 2017 15:15:13 +0200 +Subject: [PATCH 14/79] ARM64: dts: meson-gxl: Add SPI pinctrl nodes + +This patch adds the SPICC Controller pins nodes for Amlogic GXL SoCs. + +Signed-off-by: Neil Armstrong +--- + arch/arm64/boot/dts/amlogic/meson-gxl.dtsi | 16 ++++++++++++++++ + 1 file changed, 16 insertions(+) + +diff --git a/arch/arm64/boot/dts/amlogic/meson-gxl.dtsi b/arch/arm64/boot/dts/amlogic/meson-gxl.dtsi +index dc7c53f..6584e46 100644 +--- a/arch/arm64/boot/dts/amlogic/meson-gxl.dtsi ++++ b/arch/arm64/boot/dts/amlogic/meson-gxl.dtsi +@@ -246,6 +246,22 @@ + }; + }; + ++ spi_pins: spi { ++ mux { ++ groups = "spi_miso", ++ "spi_mosi", ++ "spi_sclk"; ++ function = "spi"; ++ }; ++ }; ++ ++ spi_ss0_pins: spi-ss0 { ++ mux { ++ groups = "spi_ss0"; ++ function = "spi"; ++ }; ++ }; ++ + sdcard_pins: sdcard { + mux { + groups = "sdcard_d0", +-- +1.9.1 + diff --git a/patch/kernel/odroidc2-next/0014-drm-bridge-dw-hdmi-Embed-drm_bridge-in-struct-dw_hdm.patch b/patch/kernel/odroidc2-next/0014-drm-bridge-dw-hdmi-Embed-drm_bridge-in-struct-dw_hdm.patch deleted file mode 100644 index 2825ccd9b..000000000 --- a/patch/kernel/odroidc2-next/0014-drm-bridge-dw-hdmi-Embed-drm_bridge-in-struct-dw_hdm.patch +++ /dev/null @@ -1,60 +0,0 @@ -From 891854dbb712fe784cc0553c05bd05a8734d6a3e Mon Sep 17 00:00:00 2001 -From: Laurent Pinchart -Date: Tue, 17 Jan 2017 10:28:54 +0200 -Subject: [PATCH 14/93] drm: bridge: dw-hdmi: Embed drm_bridge in struct - dw_hdmi - -The drm_bridge instance is always needed, there's no point in allocating -it separately. - -Signed-off-by: Laurent Pinchart -Reviewed-by: Jose Abreu -Signed-off-by: Archit Taneja -Link: http://patchwork.freedesktop.org/patch/msgid/20170117082910.27023-5-laurent.pinchart+renesas@ideasonboard.com ---- - drivers/gpu/drm/bridge/dw-hdmi.c | 13 +++---------- - 1 file changed, 3 insertions(+), 10 deletions(-) - -diff --git a/drivers/gpu/drm/bridge/dw-hdmi.c b/drivers/gpu/drm/bridge/dw-hdmi.c -index 5f8044a..2c85b6c 100644 ---- a/drivers/gpu/drm/bridge/dw-hdmi.c -+++ b/drivers/gpu/drm/bridge/dw-hdmi.c -@@ -116,7 +116,7 @@ struct dw_hdmi_i2c { - struct dw_hdmi { - struct drm_connector connector; - struct drm_encoder *encoder; -- struct drm_bridge *bridge; -+ struct drm_bridge bridge; - - struct platform_device *audio; - enum dw_hdmi_devtype dev_type; -@@ -1806,7 +1806,7 @@ static irqreturn_t dw_hdmi_irq(int irq, void *dev_id) - if (intr_stat & HDMI_IH_PHY_STAT0_HPD) { - dev_dbg(hdmi->dev, "EVENT=%s\n", - phy_int_pol & HDMI_PHY_HPD ? "plugin" : "plugout"); -- drm_helper_hpd_irq_event(hdmi->bridge->dev); -+ drm_helper_hpd_irq_event(hdmi->bridge.dev); - } - - hdmi_writeb(hdmi, intr_stat, HDMI_IH_PHY_STAT0); -@@ -1819,16 +1819,9 @@ static irqreturn_t dw_hdmi_irq(int irq, void *dev_id) - static int dw_hdmi_register(struct drm_device *drm, struct dw_hdmi *hdmi) - { - struct drm_encoder *encoder = hdmi->encoder; -- struct drm_bridge *bridge; -+ struct drm_bridge *bridge = &hdmi->bridge; - int ret; - -- bridge = devm_kzalloc(drm->dev, sizeof(*bridge), GFP_KERNEL); -- if (!bridge) { -- DRM_ERROR("Failed to allocate drm bridge\n"); -- return -ENOMEM; -- } -- -- hdmi->bridge = bridge; - bridge->driver_private = hdmi; - bridge->funcs = &dw_hdmi_bridge_funcs; - ret = drm_bridge_attach(encoder, bridge, NULL); --- -1.9.1 - diff --git a/patch/kernel/odroidc2-next/0015-drm-bridge-dw-hdmi-Remove-encoder-field-from-struct-.patch b/patch/kernel/odroidc2-next/0015-drm-bridge-dw-hdmi-Remove-encoder-field-from-struct-.patch deleted file mode 100644 index ae957e699..000000000 --- a/patch/kernel/odroidc2-next/0015-drm-bridge-dw-hdmi-Remove-encoder-field-from-struct-.patch +++ /dev/null @@ -1,68 +0,0 @@ -From 9fef18b9a29bb46c33bd724b1f66296b69fa65df Mon Sep 17 00:00:00 2001 -From: Laurent Pinchart -Date: Tue, 17 Jan 2017 10:28:55 +0200 -Subject: [PATCH 15/93] drm: bridge: dw-hdmi: Remove encoder field from struct - dw_hdmi - -The field isn't needed, remove it. - -Signed-off-by: Laurent Pinchart -Reviewed-by: Jose Abreu -Signed-off-by: Archit Taneja -Link: http://patchwork.freedesktop.org/patch/msgid/20170117082910.27023-6-laurent.pinchart+renesas@ideasonboard.com ---- - drivers/gpu/drm/bridge/dw-hdmi.c | 9 +++------ - 1 file changed, 3 insertions(+), 6 deletions(-) - -diff --git a/drivers/gpu/drm/bridge/dw-hdmi.c b/drivers/gpu/drm/bridge/dw-hdmi.c -index 2c85b6c..ef10bb8 100644 ---- a/drivers/gpu/drm/bridge/dw-hdmi.c -+++ b/drivers/gpu/drm/bridge/dw-hdmi.c -@@ -115,7 +115,6 @@ struct dw_hdmi_i2c { - - struct dw_hdmi { - struct drm_connector connector; -- struct drm_encoder *encoder; - struct drm_bridge bridge; - - struct platform_device *audio; -@@ -1816,9 +1815,8 @@ static irqreturn_t dw_hdmi_irq(int irq, void *dev_id) - return IRQ_HANDLED; - } - --static int dw_hdmi_register(struct drm_device *drm, struct dw_hdmi *hdmi) -+static int dw_hdmi_register(struct drm_encoder *encoder, struct dw_hdmi *hdmi) - { -- struct drm_encoder *encoder = hdmi->encoder; - struct drm_bridge *bridge = &hdmi->bridge; - int ret; - -@@ -1835,7 +1833,7 @@ static int dw_hdmi_register(struct drm_device *drm, struct dw_hdmi *hdmi) - drm_connector_helper_add(&hdmi->connector, - &dw_hdmi_connector_helper_funcs); - -- drm_connector_init(drm, &hdmi->connector, -+ drm_connector_init(encoder->dev, &hdmi->connector, - &dw_hdmi_connector_funcs, - DRM_MODE_CONNECTOR_HDMIA); - -@@ -1867,7 +1865,6 @@ int dw_hdmi_bind(struct device *dev, struct drm_encoder *encoder, - hdmi->dev = dev; - hdmi->dev_type = plat_data->dev_type; - hdmi->sample_rate = 48000; -- hdmi->encoder = encoder; - hdmi->disabled = true; - hdmi->rxsense = true; - hdmi->phy_mask = (u8)~(HDMI_PHY_HPD | HDMI_PHY_RX_SENSE); -@@ -1980,7 +1977,7 @@ int dw_hdmi_bind(struct device *dev, struct drm_encoder *encoder, - if (ret) - goto err_iahb; - -- ret = dw_hdmi_register(encoder->dev, hdmi); -+ ret = dw_hdmi_register(encoder, hdmi); - if (ret) - goto err_iahb; - --- -1.9.1 - diff --git a/patch/kernel/odroidc2-next/0015-pinctrl-meson-gxl-Fix-typo-in-AO-I2S-pins.patch b/patch/kernel/odroidc2-next/0015-pinctrl-meson-gxl-Fix-typo-in-AO-I2S-pins.patch new file mode 100644 index 000000000..1a398db99 --- /dev/null +++ b/patch/kernel/odroidc2-next/0015-pinctrl-meson-gxl-Fix-typo-in-AO-I2S-pins.patch @@ -0,0 +1,32 @@ +From 0f14939959a72d4cec1ed3343af441fe930aedf7 Mon Sep 17 00:00:00 2001 +From: Neil Armstrong +Date: Tue, 23 May 2017 17:57:34 +0200 +Subject: [PATCH 15/79] pinctrl: meson-gxl: Fix typo in AO I2S pins + +The AO I2S pins were incorrectly defined with the EE pin offset. + +Cc: Jerome Brunet +Fixes: 2899adf0422 ("pinctrl: meson: gxl: add i2s output pins") +Signed-off-by: Neil Armstrong +--- + drivers/pinctrl/meson/pinctrl-meson-gxl.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +diff --git a/drivers/pinctrl/meson/pinctrl-meson-gxl.c b/drivers/pinctrl/meson/pinctrl-meson-gxl.c +index 998210e..0673115 100644 +--- a/drivers/pinctrl/meson/pinctrl-meson-gxl.c ++++ b/drivers/pinctrl/meson/pinctrl-meson-gxl.c +@@ -271,8 +271,8 @@ + static const unsigned int pwm_ao_b_pins[] = { PIN(GPIOAO_9, 0) }; + static const unsigned int pwm_ao_b_6_pins[] = { PIN(GPIOAO_6, 0) }; + +-static const unsigned int i2s_out_ch23_ao_pins[] = { PIN(GPIOAO_8, EE_OFF) }; +-static const unsigned int i2s_out_ch45_ao_pins[] = { PIN(GPIOAO_9, EE_OFF) }; ++static const unsigned int i2s_out_ch23_ao_pins[] = { PIN(GPIOAO_8, 0) }; ++static const unsigned int i2s_out_ch45_ao_pins[] = { PIN(GPIOAO_9, 0) }; + + static const unsigned int spdif_out_ao_6_pins[] = { PIN(GPIOAO_6, EE_OFF) }; + static const unsigned int spdif_out_ao_9_pins[] = { PIN(GPIOAO_9, EE_OFF) }; +-- +1.9.1 + diff --git a/patch/kernel/odroidc2-next/0016-drm-bridge-dw-hdmi-Don-t-forward-HPD-events-to-DRM-c.patch b/patch/kernel/odroidc2-next/0016-drm-bridge-dw-hdmi-Don-t-forward-HPD-events-to-DRM-c.patch deleted file mode 100644 index f486c23fe..000000000 --- a/patch/kernel/odroidc2-next/0016-drm-bridge-dw-hdmi-Don-t-forward-HPD-events-to-DRM-c.patch +++ /dev/null @@ -1,35 +0,0 @@ -From 259254dabd150067bf932e192dd9ed8b3d545755 Mon Sep 17 00:00:00 2001 -From: Laurent Pinchart -Date: Tue, 17 Jan 2017 10:28:56 +0200 -Subject: [PATCH 16/93] drm: bridge: dw-hdmi: Don't forward HPD events to DRM - core before attach - -Hotplug events should only be forwarded to the DRM core by the interrupt -handler when the bridge has been attached, otherwise the DRM device -pointer will be NULL, resulting in a crash. - -Signed-off-by: Laurent Pinchart -Reviewed-by: Jose Abreu -Signed-off-by: Archit Taneja -Link: http://patchwork.freedesktop.org/patch/msgid/20170117082910.27023-7-laurent.pinchart+renesas@ideasonboard.com ---- - drivers/gpu/drm/bridge/dw-hdmi.c | 3 ++- - 1 file changed, 2 insertions(+), 1 deletion(-) - -diff --git a/drivers/gpu/drm/bridge/dw-hdmi.c b/drivers/gpu/drm/bridge/dw-hdmi.c -index ef10bb8..488dc1a 100644 ---- a/drivers/gpu/drm/bridge/dw-hdmi.c -+++ b/drivers/gpu/drm/bridge/dw-hdmi.c -@@ -1805,7 +1805,8 @@ static irqreturn_t dw_hdmi_irq(int irq, void *dev_id) - if (intr_stat & HDMI_IH_PHY_STAT0_HPD) { - dev_dbg(hdmi->dev, "EVENT=%s\n", - phy_int_pol & HDMI_PHY_HPD ? "plugin" : "plugout"); -- drm_helper_hpd_irq_event(hdmi->bridge.dev); -+ if (hdmi->bridge.dev) -+ drm_helper_hpd_irq_event(hdmi->bridge.dev); - } - - hdmi_writeb(hdmi, intr_stat, HDMI_IH_PHY_STAT0); --- -1.9.1 - diff --git a/patch/kernel/odroidc2-next/0016-pinctrl-meson-gxl-Fix-typo-in-AO-SPDIF-pins.patch b/patch/kernel/odroidc2-next/0016-pinctrl-meson-gxl-Fix-typo-in-AO-SPDIF-pins.patch new file mode 100644 index 000000000..2d2ac439d --- /dev/null +++ b/patch/kernel/odroidc2-next/0016-pinctrl-meson-gxl-Fix-typo-in-AO-SPDIF-pins.patch @@ -0,0 +1,32 @@ +From 846811f8445bb82b54aac0b102c3d29f278cb587 Mon Sep 17 00:00:00 2001 +From: Neil Armstrong +Date: Wed, 24 May 2017 09:35:13 +0200 +Subject: [PATCH 16/79] pinctrl: meson-gxl: Fix typo in AO SPDIF pins + +The AO SPDIF pins were incorrectly defined with the EE pin offset. + +Cc: Jerome Brunet +Fixes: b840d649f9ec ("pinctrl: meson: gxl: add spdif output pins") +Signed-off-by: Neil Armstrong +--- + drivers/pinctrl/meson/pinctrl-meson-gxl.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +diff --git a/drivers/pinctrl/meson/pinctrl-meson-gxl.c b/drivers/pinctrl/meson/pinctrl-meson-gxl.c +index 0673115..c59e377 100644 +--- a/drivers/pinctrl/meson/pinctrl-meson-gxl.c ++++ b/drivers/pinctrl/meson/pinctrl-meson-gxl.c +@@ -274,8 +274,8 @@ + static const unsigned int i2s_out_ch23_ao_pins[] = { PIN(GPIOAO_8, 0) }; + static const unsigned int i2s_out_ch45_ao_pins[] = { PIN(GPIOAO_9, 0) }; + +-static const unsigned int spdif_out_ao_6_pins[] = { PIN(GPIOAO_6, EE_OFF) }; +-static const unsigned int spdif_out_ao_9_pins[] = { PIN(GPIOAO_9, EE_OFF) }; ++static const unsigned int spdif_out_ao_6_pins[] = { PIN(GPIOAO_6, 0) }; ++static const unsigned int spdif_out_ao_9_pins[] = { PIN(GPIOAO_9, 0) }; + + static struct meson_pmx_group meson_gxl_periphs_groups[] = { + GPIO_GROUP(GPIOZ_0, EE_OFF), +-- +1.9.1 + diff --git a/patch/kernel/odroidc2-next/0017-drm-bridge-dw-hdmi-Move-IRQ-and-IO-resource-allocati.patch b/patch/kernel/odroidc2-next/0017-drm-bridge-dw-hdmi-Move-IRQ-and-IO-resource-allocati.patch deleted file mode 100644 index d41c0f5b3..000000000 --- a/patch/kernel/odroidc2-next/0017-drm-bridge-dw-hdmi-Move-IRQ-and-IO-resource-allocati.patch +++ /dev/null @@ -1,167 +0,0 @@ -From 1de2e27b041a944da876ec10a530991d82dfd991 Mon Sep 17 00:00:00 2001 -From: Laurent Pinchart -Date: Tue, 17 Jan 2017 10:28:57 +0200 -Subject: [PATCH 17/93] drm: bridge: dw-hdmi: Move IRQ and IO resource - allocation to common code - -There's no need to duplicate identical code in multiple drivers (two at -the moment, one more to come soon). Move it to the dw-hdmi core where it -can be shared. If resource allocation ever becomes device-specific later -we'll always have the option of splitting it out again. - -While it at pass the platform device to the bind function to avoid -having to cast struct device to struct platform_device. - -Signed-off-by: Laurent Pinchart -Reviewed-by: Jose Abreu -Signed-off-by: Archit Taneja -Link: http://patchwork.freedesktop.org/patch/msgid/20170117082910.27023-8-laurent.pinchart+renesas@ideasonboard.com ---- - drivers/gpu/drm/bridge/dw-hdmi.c | 13 ++++++++++--- - drivers/gpu/drm/imx/dw_hdmi-imx.c | 12 +----------- - drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c | 12 +----------- - include/drm/bridge/dw_hdmi.h | 3 +-- - 4 files changed, 13 insertions(+), 27 deletions(-) - -diff --git a/drivers/gpu/drm/bridge/dw-hdmi.c b/drivers/gpu/drm/bridge/dw-hdmi.c -index 488dc1a..563cbec 100644 ---- a/drivers/gpu/drm/bridge/dw-hdmi.c -+++ b/drivers/gpu/drm/bridge/dw-hdmi.c -@@ -1843,14 +1843,16 @@ static int dw_hdmi_register(struct drm_encoder *encoder, struct dw_hdmi *hdmi) - return 0; - } - --int dw_hdmi_bind(struct device *dev, struct drm_encoder *encoder, -- struct resource *iores, int irq, -+int dw_hdmi_bind(struct platform_device *pdev, struct drm_encoder *encoder, - const struct dw_hdmi_plat_data *plat_data) - { -+ struct device *dev = &pdev->dev; - struct device_node *np = dev->of_node; - struct platform_device_info pdevinfo; - struct device_node *ddc_node; - struct dw_hdmi *hdmi; -+ struct resource *iores; -+ int irq; - int ret; - u32 val = 1; - u8 config0; -@@ -1903,6 +1905,7 @@ int dw_hdmi_bind(struct device *dev, struct drm_encoder *encoder, - dev_dbg(hdmi->dev, "no ddc property found\n"); - } - -+ iores = platform_get_resource(pdev, IORESOURCE_MEM, 0); - hdmi->regs = devm_ioremap_resource(dev, iores); - if (IS_ERR(hdmi->regs)) { - ret = PTR_ERR(hdmi->regs); -@@ -1945,6 +1948,10 @@ int dw_hdmi_bind(struct device *dev, struct drm_encoder *encoder, - - initialize_hdmi_ih_mutes(hdmi); - -+ irq = platform_get_irq(pdev, 0); -+ if (irq < 0) -+ goto err_iahb; -+ - ret = devm_request_threaded_irq(dev, irq, dw_hdmi_hardirq, - dw_hdmi_irq, IRQF_SHARED, - dev_name(dev), hdmi); -@@ -2025,7 +2032,7 @@ int dw_hdmi_bind(struct device *dev, struct drm_encoder *encoder, - if (hdmi->i2c) - dw_hdmi_i2c_init(hdmi); - -- dev_set_drvdata(dev, hdmi); -+ platform_set_drvdata(pdev, hdmi); - - return 0; - -diff --git a/drivers/gpu/drm/imx/dw_hdmi-imx.c b/drivers/gpu/drm/imx/dw_hdmi-imx.c -index f796658..f645275 100644 ---- a/drivers/gpu/drm/imx/dw_hdmi-imx.c -+++ b/drivers/gpu/drm/imx/dw_hdmi-imx.c -@@ -207,8 +207,6 @@ static int dw_hdmi_imx_bind(struct device *dev, struct device *master, - struct drm_device *drm = data; - struct drm_encoder *encoder; - struct imx_hdmi *hdmi; -- struct resource *iores; -- int irq; - int ret; - - if (!pdev->dev.of_node) -@@ -223,14 +221,6 @@ static int dw_hdmi_imx_bind(struct device *dev, struct device *master, - hdmi->dev = &pdev->dev; - encoder = &hdmi->encoder; - -- irq = platform_get_irq(pdev, 0); -- if (irq < 0) -- return irq; -- -- iores = platform_get_resource(pdev, IORESOURCE_MEM, 0); -- if (!iores) -- return -ENXIO; -- - encoder->possible_crtcs = drm_of_find_possible_crtcs(drm, dev->of_node); - /* - * If we failed to find the CRTC(s) which this encoder is -@@ -249,7 +239,7 @@ static int dw_hdmi_imx_bind(struct device *dev, struct device *master, - drm_encoder_init(drm, encoder, &dw_hdmi_imx_encoder_funcs, - DRM_MODE_ENCODER_TMDS, NULL); - -- ret = dw_hdmi_bind(dev, encoder, iores, irq, plat_data); -+ ret = dw_hdmi_bind(pdev, encoder, plat_data); - - /* - * If dw_hdmi_bind() fails we'll never call dw_hdmi_unbind(), -diff --git a/drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c b/drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c -index e8fb5c5..a6d4a02 100644 ---- a/drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c -+++ b/drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c -@@ -257,8 +257,6 @@ static int dw_hdmi_rockchip_bind(struct device *dev, struct device *master, - struct drm_device *drm = data; - struct drm_encoder *encoder; - struct rockchip_hdmi *hdmi; -- struct resource *iores; -- int irq; - int ret; - - if (!pdev->dev.of_node) -@@ -273,14 +271,6 @@ static int dw_hdmi_rockchip_bind(struct device *dev, struct device *master, - hdmi->dev = &pdev->dev; - encoder = &hdmi->encoder; - -- irq = platform_get_irq(pdev, 0); -- if (irq < 0) -- return irq; -- -- iores = platform_get_resource(pdev, IORESOURCE_MEM, 0); -- if (!iores) -- return -ENXIO; -- - encoder->possible_crtcs = drm_of_find_possible_crtcs(drm, dev->of_node); - /* - * If we failed to find the CRTC(s) which this encoder is -@@ -301,7 +291,7 @@ static int dw_hdmi_rockchip_bind(struct device *dev, struct device *master, - drm_encoder_init(drm, encoder, &dw_hdmi_rockchip_encoder_funcs, - DRM_MODE_ENCODER_TMDS, NULL); - -- ret = dw_hdmi_bind(dev, encoder, iores, irq, plat_data); -+ ret = dw_hdmi_bind(pdev, encoder, plat_data); - - /* - * If dw_hdmi_bind() fails we'll never call dw_hdmi_unbind(), -diff --git a/include/drm/bridge/dw_hdmi.h b/include/drm/bridge/dw_hdmi.h -index 11edda6..94ff6ed 100644 ---- a/include/drm/bridge/dw_hdmi.h -+++ b/include/drm/bridge/dw_hdmi.h -@@ -57,8 +57,7 @@ struct dw_hdmi_plat_data { - }; - - void dw_hdmi_unbind(struct device *dev); --int dw_hdmi_bind(struct device *dev, struct drm_encoder *encoder, -- struct resource *iores, int irq, -+int dw_hdmi_bind(struct platform_device *pdev, struct drm_encoder *encoder, - const struct dw_hdmi_plat_data *plat_data); - - void dw_hdmi_set_sample_rate(struct dw_hdmi *hdmi, unsigned int rate); --- -1.9.1 - diff --git a/patch/kernel/odroidc2-next/0017-pinctrl-meson-gxbb-Add-CEC-pins.patch b/patch/kernel/odroidc2-next/0017-pinctrl-meson-gxbb-Add-CEC-pins.patch new file mode 100644 index 000000000..c982d1bad --- /dev/null +++ b/patch/kernel/odroidc2-next/0017-pinctrl-meson-gxbb-Add-CEC-pins.patch @@ -0,0 +1,57 @@ +From b39031e8d8ba32cb03a500c82f2d9c05784a6747 Mon Sep 17 00:00:00 2001 +From: Neil Armstrong +Date: Tue, 23 May 2017 17:56:18 +0200 +Subject: [PATCH 17/79] pinctrl: meson-gxbb: Add CEC pins + +Add the AO and EE domain CEC pins for the Amlogic Meson GXBB SoCs. + +Signed-off-by: Neil Armstrong +--- + drivers/pinctrl/meson/pinctrl-meson-gxbb.c | 10 ++++++++++ + 1 file changed, 10 insertions(+) + +diff --git a/drivers/pinctrl/meson/pinctrl-meson-gxbb.c b/drivers/pinctrl/meson/pinctrl-meson-gxbb.c +index 9b00be1..114e690 100644 +--- a/drivers/pinctrl/meson/pinctrl-meson-gxbb.c ++++ b/drivers/pinctrl/meson/pinctrl-meson-gxbb.c +@@ -290,6 +290,9 @@ + static const unsigned int spdif_out_ao_6_pins[] = { PIN(GPIOAO_6, 0) }; + static const unsigned int spdif_out_ao_13_pins[] = { PIN(GPIOAO_13, 0) }; + ++static const unsigned int ao_cec_pins[] = { PIN(GPIOAO_12, 0) }; ++static const unsigned int ee_cec_pins[] = { PIN(GPIOAO_12, 0) }; ++ + static struct meson_pmx_group meson_gxbb_periphs_groups[] = { + GPIO_GROUP(GPIOZ_0, EE_OFF), + GPIO_GROUP(GPIOZ_1, EE_OFF), +@@ -551,6 +554,8 @@ + GROUP(i2s_out_ch45_ao, 1, 1), + GROUP(spdif_out_ao_6, 0, 16), + GROUP(spdif_out_ao_13, 0, 4), ++ GROUP(ao_cec, 0, 15), ++ GROUP(ee_cec, 0, 14), + }; + + static const char * const gpio_periphs_groups[] = { +@@ -739,6 +744,10 @@ + "spdif_out_ao_6", "spdif_out_ao_13", + }; + ++static const char * const cec_ao_groups[] = { ++ "ao_cec", "ee_cec", ++}; ++ + static struct meson_pmx_func meson_gxbb_periphs_functions[] = { + FUNCTION(gpio_periphs), + FUNCTION(emmc), +@@ -779,6 +788,7 @@ + FUNCTION(pwm_ao_b), + FUNCTION(i2s_out_ao), + FUNCTION(spdif_out_ao), ++ FUNCTION(cec_ao), + }; + + static struct meson_bank meson_gxbb_periphs_banks[] = { +-- +1.9.1 + diff --git a/patch/kernel/odroidc2-next/0018-drm-bridge-dw-hdmi-Reorder-functions-to-prepare-for-.patch b/patch/kernel/odroidc2-next/0018-drm-bridge-dw-hdmi-Reorder-functions-to-prepare-for-.patch deleted file mode 100644 index fce83b643..000000000 --- a/patch/kernel/odroidc2-next/0018-drm-bridge-dw-hdmi-Reorder-functions-to-prepare-for-.patch +++ /dev/null @@ -1,111 +0,0 @@ -From 78e502a47988bfdb298e8416444c0f1f6e7e93a4 Mon Sep 17 00:00:00 2001 -From: Laurent Pinchart -Date: Tue, 17 Jan 2017 10:28:58 +0200 -Subject: [PATCH 18/93] drm: bridge: dw-hdmi: Reorder functions to prepare for - next commit - -The next commit will reference structures and functions in a way that -currently requires forward declarations. Reorder the functions to avoid -that. No functional change to the code is performed. - -Signed-off-by: Laurent Pinchart -Reviewed-by: Jose Abreu -Signed-off-by: Archit Taneja -Link: http://patchwork.freedesktop.org/patch/msgid/20170117082910.27023-9-laurent.pinchart+renesas@ideasonboard.com ---- - drivers/gpu/drm/bridge/dw-hdmi.c | 72 ++++++++++++++++++++-------------------- - 1 file changed, 36 insertions(+), 36 deletions(-) - -diff --git a/drivers/gpu/drm/bridge/dw-hdmi.c b/drivers/gpu/drm/bridge/dw-hdmi.c -index 563cbec..92ce9e5 100644 ---- a/drivers/gpu/drm/bridge/dw-hdmi.c -+++ b/drivers/gpu/drm/bridge/dw-hdmi.c -@@ -1575,42 +1575,6 @@ static void dw_hdmi_update_phy_mask(struct dw_hdmi *hdmi) - hdmi_writeb(hdmi, hdmi->phy_mask, HDMI_PHY_MASK0); - } - --static void dw_hdmi_bridge_mode_set(struct drm_bridge *bridge, -- struct drm_display_mode *orig_mode, -- struct drm_display_mode *mode) --{ -- struct dw_hdmi *hdmi = bridge->driver_private; -- -- mutex_lock(&hdmi->mutex); -- -- /* Store the display mode for plugin/DKMS poweron events */ -- memcpy(&hdmi->previous_mode, mode, sizeof(hdmi->previous_mode)); -- -- mutex_unlock(&hdmi->mutex); --} -- --static void dw_hdmi_bridge_disable(struct drm_bridge *bridge) --{ -- struct dw_hdmi *hdmi = bridge->driver_private; -- -- mutex_lock(&hdmi->mutex); -- hdmi->disabled = true; -- dw_hdmi_update_power(hdmi); -- dw_hdmi_update_phy_mask(hdmi); -- mutex_unlock(&hdmi->mutex); --} -- --static void dw_hdmi_bridge_enable(struct drm_bridge *bridge) --{ -- struct dw_hdmi *hdmi = bridge->driver_private; -- -- mutex_lock(&hdmi->mutex); -- hdmi->disabled = false; -- dw_hdmi_update_power(hdmi); -- dw_hdmi_update_phy_mask(hdmi); -- mutex_unlock(&hdmi->mutex); --} -- - static enum drm_connector_status - dw_hdmi_connector_detect(struct drm_connector *connector, bool force) - { -@@ -1703,6 +1667,42 @@ static void dw_hdmi_connector_force(struct drm_connector *connector) - .best_encoder = drm_atomic_helper_best_encoder, - }; - -+static void dw_hdmi_bridge_mode_set(struct drm_bridge *bridge, -+ struct drm_display_mode *orig_mode, -+ struct drm_display_mode *mode) -+{ -+ struct dw_hdmi *hdmi = bridge->driver_private; -+ -+ mutex_lock(&hdmi->mutex); -+ -+ /* Store the display mode for plugin/DKMS poweron events */ -+ memcpy(&hdmi->previous_mode, mode, sizeof(hdmi->previous_mode)); -+ -+ mutex_unlock(&hdmi->mutex); -+} -+ -+static void dw_hdmi_bridge_disable(struct drm_bridge *bridge) -+{ -+ struct dw_hdmi *hdmi = bridge->driver_private; -+ -+ mutex_lock(&hdmi->mutex); -+ hdmi->disabled = true; -+ dw_hdmi_update_power(hdmi); -+ dw_hdmi_update_phy_mask(hdmi); -+ mutex_unlock(&hdmi->mutex); -+} -+ -+static void dw_hdmi_bridge_enable(struct drm_bridge *bridge) -+{ -+ struct dw_hdmi *hdmi = bridge->driver_private; -+ -+ mutex_lock(&hdmi->mutex); -+ hdmi->disabled = false; -+ dw_hdmi_update_power(hdmi); -+ dw_hdmi_update_phy_mask(hdmi); -+ mutex_unlock(&hdmi->mutex); -+} -+ - static const struct drm_bridge_funcs dw_hdmi_bridge_funcs = { - .enable = dw_hdmi_bridge_enable, - .disable = dw_hdmi_bridge_disable, --- -1.9.1 - diff --git a/patch/kernel/odroidc2-next/0018-pinctrl-meson-gxl-Add-CEC-pins.patch b/patch/kernel/odroidc2-next/0018-pinctrl-meson-gxl-Add-CEC-pins.patch new file mode 100644 index 000000000..7b2e66aa2 --- /dev/null +++ b/patch/kernel/odroidc2-next/0018-pinctrl-meson-gxl-Add-CEC-pins.patch @@ -0,0 +1,57 @@ +From 4f867c391de6437aeeb725bf5beab4f88366ef34 Mon Sep 17 00:00:00 2001 +From: Neil Armstrong +Date: Tue, 23 May 2017 17:50:47 +0200 +Subject: [PATCH 18/79] pinctrl: meson-gxl: Add CEC pins + +Add the AO and EE domain CEC pins for the Amlogic Meson GXL SoCs. + +Signed-off-by: Neil Armstrong +--- + drivers/pinctrl/meson/pinctrl-meson-gxl.c | 10 ++++++++++ + 1 file changed, 10 insertions(+) + +diff --git a/drivers/pinctrl/meson/pinctrl-meson-gxl.c b/drivers/pinctrl/meson/pinctrl-meson-gxl.c +index c59e377..da7f3e9 100644 +--- a/drivers/pinctrl/meson/pinctrl-meson-gxl.c ++++ b/drivers/pinctrl/meson/pinctrl-meson-gxl.c +@@ -277,6 +277,9 @@ + static const unsigned int spdif_out_ao_6_pins[] = { PIN(GPIOAO_6, 0) }; + static const unsigned int spdif_out_ao_9_pins[] = { PIN(GPIOAO_9, 0) }; + ++static const unsigned int ao_cec_pins[] = { PIN(GPIOAO_8, 0) }; ++static const unsigned int ee_cec_pins[] = { PIN(GPIOAO_8, 0) }; ++ + static struct meson_pmx_group meson_gxl_periphs_groups[] = { + GPIO_GROUP(GPIOZ_0, EE_OFF), + GPIO_GROUP(GPIOZ_1, EE_OFF), +@@ -518,6 +521,8 @@ + GROUP(i2s_out_ch45_ao, 1, 1), + GROUP(spdif_out_ao_6, 0, 16), + GROUP(spdif_out_ao_9, 0, 4), ++ GROUP(ao_cec, 0, 15), ++ GROUP(ee_cec, 0, 14), + }; + + static const char * const gpio_periphs_groups[] = { +@@ -689,6 +694,10 @@ + "spdif_out_ao_6", "spdif_out_ao_9", + }; + ++static const char * const cec_ao_groups[] = { ++ "ao_cec", "ee_cec", ++}; ++ + static struct meson_pmx_func meson_gxl_periphs_functions[] = { + FUNCTION(gpio_periphs), + FUNCTION(emmc), +@@ -726,6 +735,7 @@ + FUNCTION(pwm_ao_b), + FUNCTION(i2s_out_ao), + FUNCTION(spdif_out_ao), ++ FUNCTION(cec_ao), + }; + + static struct meson_bank meson_gxl_periphs_banks[] = { +-- +1.9.1 + diff --git a/patch/kernel/odroidc2-next/0019-drm-bridge-dw-hdmi-Create-connector-in-the-bridge-at.patch b/patch/kernel/odroidc2-next/0019-drm-bridge-dw-hdmi-Create-connector-in-the-bridge-at.patch deleted file mode 100644 index 5e3400860..000000000 --- a/patch/kernel/odroidc2-next/0019-drm-bridge-dw-hdmi-Create-connector-in-the-bridge-at.patch +++ /dev/null @@ -1,88 +0,0 @@ -From 8b9fed5697ca5dad3197822eb34ae317f45a16a5 Mon Sep 17 00:00:00 2001 -From: Laurent Pinchart -Date: Tue, 17 Jan 2017 10:28:59 +0200 -Subject: [PATCH 19/93] drm: bridge: dw-hdmi: Create connector in the bridge - attach operation - -The DRM device is not guaranteed by the bridge API to be available -before the attach callback. The driver performs properly at the moment -as it doesn't use the drm_bridge_add() registration method. As this will -be changed later, move connector creation to attach time to ensure -compatibility with the API. - -Signed-off-by: Laurent Pinchart -Reviewed-by: Jose Abreu -Signed-off-by: Archit Taneja -Link: http://patchwork.freedesktop.org/patch/msgid/20170117082910.27023-10-laurent.pinchart+renesas@ideasonboard.com ---- - drivers/gpu/drm/bridge/dw-hdmi.c | 33 ++++++++++++++++++++------------- - 1 file changed, 20 insertions(+), 13 deletions(-) - -diff --git a/drivers/gpu/drm/bridge/dw-hdmi.c b/drivers/gpu/drm/bridge/dw-hdmi.c -index 92ce9e5..88cd40a 100644 ---- a/drivers/gpu/drm/bridge/dw-hdmi.c -+++ b/drivers/gpu/drm/bridge/dw-hdmi.c -@@ -1667,6 +1667,25 @@ static void dw_hdmi_connector_force(struct drm_connector *connector) - .best_encoder = drm_atomic_helper_best_encoder, - }; - -+static int dw_hdmi_bridge_attach(struct drm_bridge *bridge) -+{ -+ struct dw_hdmi *hdmi = bridge->driver_private; -+ struct drm_encoder *encoder = bridge->encoder; -+ struct drm_connector *connector = &hdmi->connector; -+ -+ connector->interlace_allowed = 1; -+ connector->polled = DRM_CONNECTOR_POLL_HPD; -+ -+ drm_connector_helper_add(connector, &dw_hdmi_connector_helper_funcs); -+ -+ drm_connector_init(bridge->dev, connector, &dw_hdmi_connector_funcs, -+ DRM_MODE_CONNECTOR_HDMIA); -+ -+ drm_mode_connector_attach_encoder(connector, encoder); -+ -+ return 0; -+} -+ - static void dw_hdmi_bridge_mode_set(struct drm_bridge *bridge, - struct drm_display_mode *orig_mode, - struct drm_display_mode *mode) -@@ -1704,6 +1723,7 @@ static void dw_hdmi_bridge_enable(struct drm_bridge *bridge) - } - - static const struct drm_bridge_funcs dw_hdmi_bridge_funcs = { -+ .attach = dw_hdmi_bridge_attach, - .enable = dw_hdmi_bridge_enable, - .disable = dw_hdmi_bridge_disable, - .mode_set = dw_hdmi_bridge_mode_set, -@@ -1829,17 +1849,6 @@ static int dw_hdmi_register(struct drm_encoder *encoder, struct dw_hdmi *hdmi) - return -EINVAL; - } - -- hdmi->connector.polled = DRM_CONNECTOR_POLL_HPD; -- -- drm_connector_helper_add(&hdmi->connector, -- &dw_hdmi_connector_helper_funcs); -- -- drm_connector_init(encoder->dev, &hdmi->connector, -- &dw_hdmi_connector_funcs, -- DRM_MODE_CONNECTOR_HDMIA); -- -- drm_mode_connector_attach_encoder(&hdmi->connector, encoder); -- - return 0; - } - -@@ -1862,8 +1871,6 @@ int dw_hdmi_bind(struct platform_device *pdev, struct drm_encoder *encoder, - if (!hdmi) - return -ENOMEM; - -- hdmi->connector.interlace_allowed = 1; -- - hdmi->plat_data = plat_data; - hdmi->dev = dev; - hdmi->dev_type = plat_data->dev_type; --- -1.9.1 - diff --git a/patch/kernel/odroidc2-next/0019-pinctrl-meson-gxl-Add-Ethernet-PHY-LEDS-pins.patch b/patch/kernel/odroidc2-next/0019-pinctrl-meson-gxl-Add-Ethernet-PHY-LEDS-pins.patch new file mode 100644 index 000000000..e6adc9749 --- /dev/null +++ b/patch/kernel/odroidc2-next/0019-pinctrl-meson-gxl-Add-Ethernet-PHY-LEDS-pins.patch @@ -0,0 +1,58 @@ +From d68ddd72a278abaeeec0ebccd7146f50fce9a4af Mon Sep 17 00:00:00 2001 +From: Neil Armstrong +Date: Tue, 23 May 2017 17:53:43 +0200 +Subject: [PATCH 19/79] pinctrl: meson-gxl: Add Ethernet PHY LEDS pins + +The Amlogic Meson GXL SoCs embeds an 10/100 Ethernet PHY, this patchs enables +the Link and Activity LEDs signals. + +Signed-off-by: Neil Armstrong +--- + drivers/pinctrl/meson/pinctrl-meson-gxl.c | 10 ++++++++++ + 1 file changed, 10 insertions(+) + +diff --git a/drivers/pinctrl/meson/pinctrl-meson-gxl.c b/drivers/pinctrl/meson/pinctrl-meson-gxl.c +index da7f3e9..7adc7c2 100644 +--- a/drivers/pinctrl/meson/pinctrl-meson-gxl.c ++++ b/drivers/pinctrl/meson/pinctrl-meson-gxl.c +@@ -234,6 +234,9 @@ + + static const unsigned int spdif_out_h_pins[] = { PIN(GPIOH_4, EE_OFF) }; + ++static const unsigned int eth_link_led_pins[] = { PIN(GPIOZ_14, EE_OFF) }; ++static const unsigned int eth_act_led_pins[] = { PIN(GPIOZ_15, EE_OFF) }; ++ + static const struct pinctrl_pin_desc meson_gxl_aobus_pins[] = { + MESON_PIN(GPIOAO_0, 0), + MESON_PIN(GPIOAO_1, 0), +@@ -428,6 +431,8 @@ + GROUP(i2s_out_ch23_z, 3, 26), + GROUP(i2s_out_ch45_z, 3, 25), + GROUP(i2s_out_ch67_z, 3, 24), ++ GROUP(eth_link_led, 4, 25), ++ GROUP(eth_act_led, 4, 24), + + /* Bank H */ + GROUP(hdmi_hpd, 6, 31), +@@ -652,6 +657,10 @@ + "spdif_out_h", + }; + ++static const char * const eth_led_groups[] = { ++ "eth_link_led", "eth_act_led", ++}; ++ + static const char * const gpio_aobus_groups[] = { + "GPIOAO_0", "GPIOAO_1", "GPIOAO_2", "GPIOAO_3", "GPIOAO_4", + "GPIOAO_5", "GPIOAO_6", "GPIOAO_7", "GPIOAO_8", "GPIOAO_9", +@@ -722,6 +731,7 @@ + FUNCTION(hdmi_i2c), + FUNCTION(i2s_out), + FUNCTION(spdif_out), ++ FUNCTION(eth_led), + }; + + static struct meson_pmx_func meson_gxl_aobus_functions[] = { +-- +1.9.1 + diff --git a/patch/kernel/odroidc2-next/0020-drm-bridge-dw-hdmi-Implement-DRM-bridge-registration.patch b/patch/kernel/odroidc2-next/0020-drm-bridge-dw-hdmi-Implement-DRM-bridge-registration.patch deleted file mode 100644 index 05b69276e..000000000 --- a/patch/kernel/odroidc2-next/0020-drm-bridge-dw-hdmi-Implement-DRM-bridge-registration.patch +++ /dev/null @@ -1,220 +0,0 @@ -From 200c0b9edb6b1203d6db6391d940f69b6f56e1d6 Mon Sep 17 00:00:00 2001 -From: Laurent Pinchart -Date: Tue, 17 Jan 2017 10:29:00 +0200 -Subject: [PATCH 20/93] drm: bridge: dw-hdmi: Implement DRM bridge registration - -As an option for drivers not based on the component framework, register -the bridge with the DRM core with the DRM bridge API. Existing drivers -based on dw_hdmi_bind() and dw_hdmi_unbind() are not affected as those -functions are preserved with their current behaviour. - -Signed-off-by: Laurent Pinchart -Reviewed-by: Jose Abreu -Signed-off-by: Archit Taneja -Link: http://patchwork.freedesktop.org/patch/msgid/20170117082910.27023-11-laurent.pinchart+renesas@ideasonboard.com ---- - drivers/gpu/drm/bridge/dw-hdmi.c | 112 ++++++++++++++++++++++++++++----------- - include/drm/bridge/dw_hdmi.h | 3 ++ - 2 files changed, 83 insertions(+), 32 deletions(-) - -diff --git a/drivers/gpu/drm/bridge/dw-hdmi.c b/drivers/gpu/drm/bridge/dw-hdmi.c -index 88cd40a..107fea4 100644 ---- a/drivers/gpu/drm/bridge/dw-hdmi.c -+++ b/drivers/gpu/drm/bridge/dw-hdmi.c -@@ -1836,24 +1836,9 @@ static irqreturn_t dw_hdmi_irq(int irq, void *dev_id) - return IRQ_HANDLED; - } - --static int dw_hdmi_register(struct drm_encoder *encoder, struct dw_hdmi *hdmi) --{ -- struct drm_bridge *bridge = &hdmi->bridge; -- int ret; -- -- bridge->driver_private = hdmi; -- bridge->funcs = &dw_hdmi_bridge_funcs; -- ret = drm_bridge_attach(encoder, bridge, NULL); -- if (ret) { -- DRM_ERROR("Failed to initialize bridge with drm\n"); -- return -EINVAL; -- } -- -- return 0; --} -- --int dw_hdmi_bind(struct platform_device *pdev, struct drm_encoder *encoder, -- const struct dw_hdmi_plat_data *plat_data) -+static struct dw_hdmi * -+__dw_hdmi_probe(struct platform_device *pdev, -+ const struct dw_hdmi_plat_data *plat_data) - { - struct device *dev = &pdev->dev; - struct device_node *np = dev->of_node; -@@ -1869,7 +1854,7 @@ int dw_hdmi_bind(struct platform_device *pdev, struct drm_encoder *encoder, - - hdmi = devm_kzalloc(dev, sizeof(*hdmi), GFP_KERNEL); - if (!hdmi) -- return -ENOMEM; -+ return ERR_PTR(-ENOMEM); - - hdmi->plat_data = plat_data; - hdmi->dev = dev; -@@ -1896,7 +1881,7 @@ int dw_hdmi_bind(struct platform_device *pdev, struct drm_encoder *encoder, - break; - default: - dev_err(dev, "reg-io-width must be 1 or 4\n"); -- return -EINVAL; -+ return ERR_PTR(-EINVAL); - } - - ddc_node = of_parse_phandle(np, "ddc-i2c-bus", 0); -@@ -1905,7 +1890,7 @@ int dw_hdmi_bind(struct platform_device *pdev, struct drm_encoder *encoder, - of_node_put(ddc_node); - if (!hdmi->ddc) { - dev_dbg(hdmi->dev, "failed to read ddc node\n"); -- return -EPROBE_DEFER; -+ return ERR_PTR(-EPROBE_DEFER); - } - - } else { -@@ -1956,8 +1941,10 @@ int dw_hdmi_bind(struct platform_device *pdev, struct drm_encoder *encoder, - initialize_hdmi_ih_mutes(hdmi); - - irq = platform_get_irq(pdev, 0); -- if (irq < 0) -+ if (irq < 0) { -+ ret = irq; - goto err_iahb; -+ } - - ret = devm_request_threaded_irq(dev, irq, dw_hdmi_hardirq, - dw_hdmi_irq, IRQF_SHARED, -@@ -1988,11 +1975,11 @@ int dw_hdmi_bind(struct platform_device *pdev, struct drm_encoder *encoder, - hdmi_writeb(hdmi, HDMI_IH_PHY_STAT0_HPD | HDMI_IH_PHY_STAT0_RX_SENSE, - HDMI_IH_PHY_STAT0); - -- ret = dw_hdmi_fb_registered(hdmi); -- if (ret) -- goto err_iahb; -+ hdmi->bridge.driver_private = hdmi; -+ hdmi->bridge.funcs = &dw_hdmi_bridge_funcs; -+ hdmi->bridge.of_node = pdev->dev.of_node; - -- ret = dw_hdmi_register(encoder, hdmi); -+ ret = dw_hdmi_fb_registered(hdmi); - if (ret) - goto err_iahb; - -@@ -2041,7 +2028,7 @@ int dw_hdmi_bind(struct platform_device *pdev, struct drm_encoder *encoder, - - platform_set_drvdata(pdev, hdmi); - -- return 0; -+ return hdmi; - - err_iahb: - if (hdmi->i2c) { -@@ -2055,14 +2042,11 @@ int dw_hdmi_bind(struct platform_device *pdev, struct drm_encoder *encoder, - err_res: - i2c_put_adapter(hdmi->ddc); - -- return ret; -+ return ERR_PTR(ret); - } --EXPORT_SYMBOL_GPL(dw_hdmi_bind); - --void dw_hdmi_unbind(struct device *dev) -+static void __dw_hdmi_remove(struct dw_hdmi *hdmi) - { -- struct dw_hdmi *hdmi = dev_get_drvdata(dev); -- - if (hdmi->audio && !IS_ERR(hdmi->audio)) - platform_device_unregister(hdmi->audio); - -@@ -2077,6 +2061,70 @@ void dw_hdmi_unbind(struct device *dev) - else - i2c_put_adapter(hdmi->ddc); - } -+ -+/* ----------------------------------------------------------------------------- -+ * Probe/remove API, used from platforms based on the DRM bridge API. -+ */ -+int dw_hdmi_probe(struct platform_device *pdev, -+ const struct dw_hdmi_plat_data *plat_data) -+{ -+ struct dw_hdmi *hdmi; -+ int ret; -+ -+ hdmi = __dw_hdmi_probe(pdev, plat_data); -+ if (IS_ERR(hdmi)) -+ return PTR_ERR(hdmi); -+ -+ ret = drm_bridge_add(&hdmi->bridge); -+ if (ret < 0) { -+ __dw_hdmi_remove(hdmi); -+ return ret; -+ } -+ -+ return 0; -+} -+EXPORT_SYMBOL_GPL(dw_hdmi_probe); -+ -+void dw_hdmi_remove(struct platform_device *pdev) -+{ -+ struct dw_hdmi *hdmi = platform_get_drvdata(pdev); -+ -+ drm_bridge_remove(&hdmi->bridge); -+ -+ __dw_hdmi_remove(hdmi); -+} -+EXPORT_SYMBOL_GPL(dw_hdmi_remove); -+ -+/* ----------------------------------------------------------------------------- -+ * Bind/unbind API, used from platforms based on the component framework. -+ */ -+int dw_hdmi_bind(struct platform_device *pdev, struct drm_encoder *encoder, -+ const struct dw_hdmi_plat_data *plat_data) -+{ -+ struct dw_hdmi *hdmi; -+ int ret; -+ -+ hdmi = __dw_hdmi_probe(pdev, plat_data); -+ if (IS_ERR(hdmi)) -+ return PTR_ERR(hdmi); -+ -+ ret = drm_bridge_attach(encoder, &hdmi->bridge, NULL); -+ if (ret) { -+ dw_hdmi_remove(pdev); -+ DRM_ERROR("Failed to initialize bridge with drm\n"); -+ return ret; -+ } -+ -+ return 0; -+} -+EXPORT_SYMBOL_GPL(dw_hdmi_bind); -+ -+void dw_hdmi_unbind(struct device *dev) -+{ -+ struct dw_hdmi *hdmi = dev_get_drvdata(dev); -+ -+ __dw_hdmi_remove(hdmi); -+} - EXPORT_SYMBOL_GPL(dw_hdmi_unbind); - - MODULE_AUTHOR("Sascha Hauer "); -diff --git a/include/drm/bridge/dw_hdmi.h b/include/drm/bridge/dw_hdmi.h -index 94ff6ed..3bb22a8 100644 ---- a/include/drm/bridge/dw_hdmi.h -+++ b/include/drm/bridge/dw_hdmi.h -@@ -56,6 +56,9 @@ struct dw_hdmi_plat_data { - struct drm_display_mode *mode); - }; - -+int dw_hdmi_probe(struct platform_device *pdev, -+ const struct dw_hdmi_plat_data *plat_data); -+void dw_hdmi_remove(struct platform_device *pdev); - void dw_hdmi_unbind(struct device *dev); - int dw_hdmi_bind(struct platform_device *pdev, struct drm_encoder *encoder, - const struct dw_hdmi_plat_data *plat_data); --- -1.9.1 - diff --git a/patch/kernel/odroidc2-next/0020-pinctrl-meson-gxl-Add-missing-GPIODV_18-pin-entry.patch b/patch/kernel/odroidc2-next/0020-pinctrl-meson-gxl-Add-missing-GPIODV_18-pin-entry.patch new file mode 100644 index 000000000..c439687be --- /dev/null +++ b/patch/kernel/odroidc2-next/0020-pinctrl-meson-gxl-Add-missing-GPIODV_18-pin-entry.patch @@ -0,0 +1,28 @@ +From 20c88cc6c1c4d6fb3903be634b54fd0659f2e364 Mon Sep 17 00:00:00 2001 +From: Neil Armstrong +Date: Tue, 23 May 2017 11:53:57 +0200 +Subject: [PATCH 20/79] pinctrl: meson-gxl: Add missing GPIODV_18 pin entry + +GPIODV_18 entry was missing in the original driver push. + +Fixes: 0f15f500ff2c ("pinctrl: meson: Add GXL pinctrl definitions") +Signed-off-by: Neil Armstrong +--- + drivers/pinctrl/meson/pinctrl-meson-gxl.c | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/drivers/pinctrl/meson/pinctrl-meson-gxl.c b/drivers/pinctrl/meson/pinctrl-meson-gxl.c +index 7adc7c2..6a486cb 100644 +--- a/drivers/pinctrl/meson/pinctrl-meson-gxl.c ++++ b/drivers/pinctrl/meson/pinctrl-meson-gxl.c +@@ -89,6 +89,7 @@ + MESON_PIN(GPIODV_15, EE_OFF), + MESON_PIN(GPIODV_16, EE_OFF), + MESON_PIN(GPIODV_17, EE_OFF), ++ MESON_PIN(GPIODV_18, EE_OFF), + MESON_PIN(GPIODV_19, EE_OFF), + MESON_PIN(GPIODV_20, EE_OFF), + MESON_PIN(GPIODV_21, EE_OFF), +-- +1.9.1 + diff --git a/patch/kernel/odroidc2-next/0021-drm-bridge-dw-hdmi-Remove-PHY-configuration-resoluti.patch b/patch/kernel/odroidc2-next/0021-drm-bridge-dw-hdmi-Remove-PHY-configuration-resoluti.patch deleted file mode 100644 index daf6ef393..000000000 --- a/patch/kernel/odroidc2-next/0021-drm-bridge-dw-hdmi-Remove-PHY-configuration-resoluti.patch +++ /dev/null @@ -1,83 +0,0 @@ -From 8fb0058965b30a39f1e0e3820b96013cfbf6bfc6 Mon Sep 17 00:00:00 2001 -From: Kieran Bingham -Date: Tue, 17 Jan 2017 10:29:01 +0200 -Subject: [PATCH 21/93] drm: bridge: dw-hdmi: Remove PHY configuration - resolution parameter - -The current code hard codes the call of hdmi_phy_configure() to be 8bpp -and provides extraneous error checking to verify that this hardcoded -value is correct. Simplify the implementation by removing the argument. - -Signed-off-by: Kieran Bingham -Signed-off-by: Laurent Pinchart -Reviewed-by: Jose Abreu -Signed-off-by: Archit Taneja -Link: http://patchwork.freedesktop.org/patch/msgid/20170117082910.27023-12-laurent.pinchart+renesas@ideasonboard.com ---- - drivers/gpu/drm/bridge/dw-hdmi.c | 27 +++++---------------------- - 1 file changed, 5 insertions(+), 22 deletions(-) - -diff --git a/drivers/gpu/drm/bridge/dw-hdmi.c b/drivers/gpu/drm/bridge/dw-hdmi.c -index 107fea4..b4fb0bd 100644 ---- a/drivers/gpu/drm/bridge/dw-hdmi.c -+++ b/drivers/gpu/drm/bridge/dw-hdmi.c -@@ -930,31 +930,14 @@ static void dw_hdmi_phy_sel_interface_control(struct dw_hdmi *hdmi, u8 enable) - HDMI_PHY_CONF0_SELDIPIF_MASK); - } - --static int hdmi_phy_configure(struct dw_hdmi *hdmi, -- unsigned char res, int cscon) -+static int hdmi_phy_configure(struct dw_hdmi *hdmi, int cscon) - { -- unsigned res_idx; - u8 val, msec; - const struct dw_hdmi_plat_data *pdata = hdmi->plat_data; - const struct dw_hdmi_mpll_config *mpll_config = pdata->mpll_cfg; - const struct dw_hdmi_curr_ctrl *curr_ctrl = pdata->cur_ctr; - const struct dw_hdmi_phy_config *phy_config = pdata->phy_config; - -- switch (res) { -- case 0: /* color resolution 0 is 8 bit colour depth */ -- case 8: -- res_idx = DW_HDMI_RES_8; -- break; -- case 10: -- res_idx = DW_HDMI_RES_10; -- break; -- case 12: -- res_idx = DW_HDMI_RES_12; -- break; -- default: -- return -EINVAL; -- } -- - /* PLL/MPLL Cfg - always match on final entry */ - for (; mpll_config->mpixelclock != ~0UL; mpll_config++) - if (hdmi->hdmi_data.video_mode.mpixelclock <= -@@ -1004,11 +987,11 @@ static int hdmi_phy_configure(struct dw_hdmi *hdmi, - HDMI_PHY_I2CM_SLAVE_ADDR); - hdmi_phy_test_clear(hdmi, 0); - -- hdmi_phy_i2c_write(hdmi, mpll_config->res[res_idx].cpce, 0x06); -- hdmi_phy_i2c_write(hdmi, mpll_config->res[res_idx].gmp, 0x15); -+ hdmi_phy_i2c_write(hdmi, mpll_config->res[0].cpce, 0x06); -+ hdmi_phy_i2c_write(hdmi, mpll_config->res[0].gmp, 0x15); - - /* CURRCTRL */ -- hdmi_phy_i2c_write(hdmi, curr_ctrl->curr[res_idx], 0x10); -+ hdmi_phy_i2c_write(hdmi, curr_ctrl->curr[0], 0x10); - - hdmi_phy_i2c_write(hdmi, 0x0000, 0x13); /* PLLPHBYCTRL */ - hdmi_phy_i2c_write(hdmi, 0x0006, 0x17); -@@ -1068,7 +1051,7 @@ static int dw_hdmi_phy_init(struct dw_hdmi *hdmi) - dw_hdmi_phy_enable_powerdown(hdmi, true); - - /* Enable CSC */ -- ret = hdmi_phy_configure(hdmi, 8, cscon); -+ ret = hdmi_phy_configure(hdmi, cscon); - if (ret) - return ret; - } --- -1.9.1 - diff --git a/patch/kernel/odroidc2-next/0021-pinctrl-meson-gxbb-Add-missing-GPIODV_18-pin-entry.patch b/patch/kernel/odroidc2-next/0021-pinctrl-meson-gxbb-Add-missing-GPIODV_18-pin-entry.patch new file mode 100644 index 000000000..86046ddbc --- /dev/null +++ b/patch/kernel/odroidc2-next/0021-pinctrl-meson-gxbb-Add-missing-GPIODV_18-pin-entry.patch @@ -0,0 +1,28 @@ +From 8dc15df570ea27434fa31704ca2bf2684471c2b4 Mon Sep 17 00:00:00 2001 +From: Neil Armstrong +Date: Tue, 23 May 2017 16:03:44 +0200 +Subject: [PATCH 21/79] pinctrl: meson-gxbb: Add missing GPIODV_18 pin entry + +GPIODV_18 entry was missing in the original driver push. + +Fixes: 468c234f9ed7 ("pinctrl: amlogic: Add support for Amlogic Meson GXBB SoC") +Signed-off-by: Neil Armstrong +--- + drivers/pinctrl/meson/pinctrl-meson-gxbb.c | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/drivers/pinctrl/meson/pinctrl-meson-gxbb.c b/drivers/pinctrl/meson/pinctrl-meson-gxbb.c +index 114e690..2ccd776 100644 +--- a/drivers/pinctrl/meson/pinctrl-meson-gxbb.c ++++ b/drivers/pinctrl/meson/pinctrl-meson-gxbb.c +@@ -85,6 +85,7 @@ + MESON_PIN(GPIODV_15, EE_OFF), + MESON_PIN(GPIODV_16, EE_OFF), + MESON_PIN(GPIODV_17, EE_OFF), ++ MESON_PIN(GPIODV_18, EE_OFF), + MESON_PIN(GPIODV_19, EE_OFF), + MESON_PIN(GPIODV_20, EE_OFF), + MESON_PIN(GPIODV_21, EE_OFF), +-- +1.9.1 + diff --git a/patch/kernel/odroidc2-next/0022-cec-add-cec_s_phys_addr_from_edid-helper-function.patch b/patch/kernel/odroidc2-next/0022-cec-add-cec_s_phys_addr_from_edid-helper-function.patch new file mode 100644 index 000000000..4527953ba --- /dev/null +++ b/patch/kernel/odroidc2-next/0022-cec-add-cec_s_phys_addr_from_edid-helper-function.patch @@ -0,0 +1,104 @@ +From 1c11d32e68aa3591701810fc88fb1ed0e12d730d Mon Sep 17 00:00:00 2001 +From: Hans Verkuil +Date: Wed, 7 Jun 2017 11:46:08 -0300 +Subject: [PATCH 22/79] cec: add cec_s_phys_addr_from_edid helper function + +This function simplifies the integration of CEC in DRM drivers. + +Signed-off-by: Hans Verkuil +Signed-off-by: Mauro Carvalho Chehab +Signed-off-by: Neil Armstrong +--- + Documentation/media/kapi/cec-core.rst | 8 ++++++++ + drivers/media/cec/cec-adap.c | 14 ++++++++++++++ + include/media/cec.h | 9 +++++++++ + 3 files changed, 31 insertions(+) + +diff --git a/Documentation/media/kapi/cec-core.rst b/Documentation/media/kapi/cec-core.rst +index 7a04c53..278b358 100644 +--- a/Documentation/media/kapi/cec-core.rst ++++ b/Documentation/media/kapi/cec-core.rst +@@ -307,6 +307,14 @@ to another valid physical address, then this function will first set the + address to CEC_PHYS_ADDR_INVALID before enabling the new physical address. + + .. c:function:: ++ void cec_s_phys_addr_from_edid(struct cec_adapter *adap, ++ const struct edid *edid); ++ ++A helper function that extracts the physical address from the edid struct ++and calls cec_s_phys_addr() with that address, or CEC_PHYS_ADDR_INVALID ++if the EDID did not contain a physical address or edid was a NULL pointer. ++ ++.. c:function:: + int cec_s_log_addrs(struct cec_adapter *adap, + struct cec_log_addrs *log_addrs, bool block); + +diff --git a/drivers/media/cec/cec-adap.c b/drivers/media/cec/cec-adap.c +index 9dfc798..8a4417f 100644 +--- a/drivers/media/cec/cec-adap.c ++++ b/drivers/media/cec/cec-adap.c +@@ -28,6 +28,8 @@ + #include + #include + ++#include ++ + #include "cec-priv.h" + + static void cec_fill_msg_report_features(struct cec_adapter *adap, +@@ -1404,6 +1406,18 @@ void cec_s_phys_addr(struct cec_adapter *adap, u16 phys_addr, bool block) + } + EXPORT_SYMBOL_GPL(cec_s_phys_addr); + ++void cec_s_phys_addr_from_edid(struct cec_adapter *adap, ++ const struct edid *edid) ++{ ++ u16 pa = CEC_PHYS_ADDR_INVALID; ++ ++ if (edid && edid->extensions) ++ pa = cec_get_edid_phys_addr((const u8 *)edid, ++ EDID_LENGTH * (edid->extensions + 1), NULL); ++ cec_s_phys_addr(adap, pa, false); ++} ++EXPORT_SYMBOL_GPL(cec_s_phys_addr_from_edid); ++ + /* + * Called from either the ioctl or a driver to set the logical addresses. + * +diff --git a/include/media/cec.h b/include/media/cec.h +index 201f060..ae206e2 100644 +--- a/include/media/cec.h ++++ b/include/media/cec.h +@@ -206,6 +206,8 @@ static inline bool cec_is_sink(const struct cec_adapter *adap) + #define cec_phys_addr_exp(pa) \ + ((pa) >> 12), ((pa) >> 8) & 0xf, ((pa) >> 4) & 0xf, (pa) & 0xf + ++struct edid; ++ + #if IS_REACHABLE(CONFIG_CEC_CORE) + struct cec_adapter *cec_allocate_adapter(const struct cec_adap_ops *ops, + void *priv, const char *name, u32 caps, u8 available_las); +@@ -217,6 +219,8 @@ int cec_s_log_addrs(struct cec_adapter *adap, struct cec_log_addrs *log_addrs, + bool block); + void cec_s_phys_addr(struct cec_adapter *adap, u16 phys_addr, + bool block); ++void cec_s_phys_addr_from_edid(struct cec_adapter *adap, ++ const struct edid *edid); + int cec_transmit_msg(struct cec_adapter *adap, struct cec_msg *msg, + bool block); + +@@ -326,6 +330,11 @@ static inline void cec_s_phys_addr(struct cec_adapter *adap, u16 phys_addr, + { + } + ++static inline void cec_s_phys_addr_from_edid(struct cec_adapter *adap, ++ const struct edid *edid) ++{ ++} ++ + static inline u16 cec_get_edid_phys_addr(const u8 *edid, unsigned int size, + unsigned int *offset) + { +-- +1.9.1 + diff --git a/patch/kernel/odroidc2-next/0022-drm-bridge-dw-hdmi-Rename-CONF0-SPARECTRL-bit-to-SVS.patch b/patch/kernel/odroidc2-next/0022-drm-bridge-dw-hdmi-Rename-CONF0-SPARECTRL-bit-to-SVS.patch deleted file mode 100644 index f64486666..000000000 --- a/patch/kernel/odroidc2-next/0022-drm-bridge-dw-hdmi-Rename-CONF0-SPARECTRL-bit-to-SVS.patch +++ /dev/null @@ -1,68 +0,0 @@ -From c7604b72b3695ee449d16916aa474b23c53af425 Mon Sep 17 00:00:00 2001 -From: Laurent Pinchart -Date: Tue, 17 Jan 2017 10:29:02 +0200 -Subject: [PATCH 22/93] drm: bridge: dw-hdmi: Rename CONF0 SPARECTRL bit to - SVSRET - -The bit is documented in a Rockchip BSP as - - #define m_SVSRET_SIG (1 << 5) /* depend on PHY_MHL_COMB0=1 */ - -This is confirmed by a Renesas platform, which uses a 2.0 DWC HDMI TX as -the RK3288. Rename the bit accordingly. - -Signed-off-by: Laurent Pinchart -Reviewed-by: Jose Abreu -Signed-off-by: Archit Taneja -Link: http://patchwork.freedesktop.org/patch/msgid/20170117082910.27023-13-laurent.pinchart+renesas@ideasonboard.com ---- - drivers/gpu/drm/bridge/dw-hdmi.c | 8 ++++---- - drivers/gpu/drm/bridge/dw-hdmi.h | 4 ++-- - 2 files changed, 6 insertions(+), 6 deletions(-) - -diff --git a/drivers/gpu/drm/bridge/dw-hdmi.c b/drivers/gpu/drm/bridge/dw-hdmi.c -index b4fb0bd..06c252f 100644 ---- a/drivers/gpu/drm/bridge/dw-hdmi.c -+++ b/drivers/gpu/drm/bridge/dw-hdmi.c -@@ -895,11 +895,11 @@ static void dw_hdmi_phy_enable_tmds(struct dw_hdmi *hdmi, u8 enable) - HDMI_PHY_CONF0_ENTMDS_MASK); - } - --static void dw_hdmi_phy_enable_spare(struct dw_hdmi *hdmi, u8 enable) -+static void dw_hdmi_phy_enable_svsret(struct dw_hdmi *hdmi, u8 enable) - { - hdmi_mask_writeb(hdmi, enable, HDMI_PHY_CONF0, -- HDMI_PHY_CONF0_SPARECTRL_OFFSET, -- HDMI_PHY_CONF0_SPARECTRL_MASK); -+ HDMI_PHY_CONF0_SVSRET_OFFSET, -+ HDMI_PHY_CONF0_SVSRET_MASK); - } - - static void dw_hdmi_phy_gen2_pddq(struct dw_hdmi *hdmi, u8 enable) -@@ -1014,7 +1014,7 @@ static int hdmi_phy_configure(struct dw_hdmi *hdmi, int cscon) - dw_hdmi_phy_gen2_pddq(hdmi, 0); - - if (hdmi->dev_type == RK3288_HDMI) -- dw_hdmi_phy_enable_spare(hdmi, 1); -+ dw_hdmi_phy_enable_svsret(hdmi, 1); - - /*Wait for PHY PLL lock */ - msec = 5; -diff --git a/drivers/gpu/drm/bridge/dw-hdmi.h b/drivers/gpu/drm/bridge/dw-hdmi.h -index 55135bb..08235ae 100644 ---- a/drivers/gpu/drm/bridge/dw-hdmi.h -+++ b/drivers/gpu/drm/bridge/dw-hdmi.h -@@ -847,8 +847,8 @@ enum { - HDMI_PHY_CONF0_PDZ_OFFSET = 7, - HDMI_PHY_CONF0_ENTMDS_MASK = 0x40, - HDMI_PHY_CONF0_ENTMDS_OFFSET = 6, -- HDMI_PHY_CONF0_SPARECTRL_MASK = 0x20, -- HDMI_PHY_CONF0_SPARECTRL_OFFSET = 5, -+ HDMI_PHY_CONF0_SVSRET_MASK = 0x20, -+ HDMI_PHY_CONF0_SVSRET_OFFSET = 5, - HDMI_PHY_CONF0_GEN2_PDDQ_MASK = 0x10, - HDMI_PHY_CONF0_GEN2_PDDQ_OFFSET = 4, - HDMI_PHY_CONF0_GEN2_TXPWRON_MASK = 0x8, --- -1.9.1 - diff --git a/patch/kernel/odroidc2-next/0023-cec-add-cec_phys_addr_invalidate-helper-function.patch b/patch/kernel/odroidc2-next/0023-cec-add-cec_phys_addr_invalidate-helper-function.patch new file mode 100644 index 000000000..0872debb2 --- /dev/null +++ b/patch/kernel/odroidc2-next/0023-cec-add-cec_phys_addr_invalidate-helper-function.patch @@ -0,0 +1,40 @@ +From f853954636579085c6c21bf7df08af2c44f77042 Mon Sep 17 00:00:00 2001 +From: Hans Verkuil +Date: Wed, 7 Jun 2017 11:46:09 -0300 +Subject: [PATCH 23/79] cec: add cec_phys_addr_invalidate() helper function + +Simplifies setting the physical address to CEC_PHYS_ADDR_INVALID. + +Signed-off-by: Hans Verkuil +Signed-off-by: Hans Verkuil +Signed-off-by: Mauro Carvalho Chehab +Signed-off-by: Neil Armstrong +--- + include/media/cec.h | 13 +++++++++++++ + 1 file changed, 13 insertions(+) + +diff --git a/include/media/cec.h b/include/media/cec.h +index ae206e2..fc69588 100644 +--- a/include/media/cec.h ++++ b/include/media/cec.h +@@ -360,4 +360,17 @@ static inline int cec_phys_addr_validate(u16 phys_addr, u16 *parent, u16 *port) + + #endif + ++/** ++ * cec_phys_addr_invalidate() - set the physical address to INVALID ++ * ++ * @adap: the CEC adapter ++ * ++ * This is a simple helper function to invalidate the physical ++ * address. ++ */ ++static inline void cec_phys_addr_invalidate(struct cec_adapter *adap) ++{ ++ cec_s_phys_addr(adap, CEC_PHYS_ADDR_INVALID, false); ++} ++ + #endif /* _MEDIA_CEC_H */ +-- +1.9.1 + diff --git a/patch/kernel/odroidc2-next/0023-drm-bridge-dw-hdmi-Reject-invalid-product-IDs.patch b/patch/kernel/odroidc2-next/0023-drm-bridge-dw-hdmi-Reject-invalid-product-IDs.patch deleted file mode 100644 index 2e649f312..000000000 --- a/patch/kernel/odroidc2-next/0023-drm-bridge-dw-hdmi-Reject-invalid-product-IDs.patch +++ /dev/null @@ -1,95 +0,0 @@ -From a2bdacb64471d710bb4bdbc70e27d276eaae6d00 Mon Sep 17 00:00:00 2001 -From: Laurent Pinchart -Date: Tue, 17 Jan 2017 10:29:03 +0200 -Subject: [PATCH 23/93] drm: bridge: dw-hdmi: Reject invalid product IDs - -The DWC HDMI TX can be recognized by the two product identification -registers. If the registers don't read as expect the IP will be very -different than what the driver has been designed for, or will be -misconfigured in a way that makes it non-operational (invalid memory -address, incorrect clocks, ...). We should reject this situation with an -error. - -While this isn't critical for proper operation with supported IPs at the -moment, the driver will soon gain automatic device-specific handling -based on runtime device identification. This change makes it easier to -implement that without having to default to a random guess in case the -device can't be identified. - -While at it print a readable version number in the device identification -message instead of raw register values. - -Signed-off-by: Laurent Pinchart -Reviewed-by: Jose Abreu -Signed-off-by: Archit Taneja -Link: http://patchwork.freedesktop.org/patch/msgid/20170117082910.27023-14-laurent.pinchart+renesas@ideasonboard.com ---- - drivers/gpu/drm/bridge/dw-hdmi.c | 25 +++++++++++++++++++------ - drivers/gpu/drm/bridge/dw-hdmi.h | 8 ++++++++ - 2 files changed, 27 insertions(+), 6 deletions(-) - -diff --git a/drivers/gpu/drm/bridge/dw-hdmi.c b/drivers/gpu/drm/bridge/dw-hdmi.c -index 06c252f..1809247 100644 ---- a/drivers/gpu/drm/bridge/dw-hdmi.c -+++ b/drivers/gpu/drm/bridge/dw-hdmi.c -@@ -1832,6 +1832,9 @@ static irqreturn_t dw_hdmi_irq(int irq, void *dev_id) - int irq; - int ret; - u32 val = 1; -+ u16 version; -+ u8 prod_id0; -+ u8 prod_id1; - u8 config0; - u8 config1; - -@@ -1914,12 +1917,22 @@ static irqreturn_t dw_hdmi_irq(int irq, void *dev_id) - } - - /* Product and revision IDs */ -- dev_info(dev, -- "Detected HDMI controller 0x%x:0x%x:0x%x:0x%x\n", -- hdmi_readb(hdmi, HDMI_DESIGN_ID), -- hdmi_readb(hdmi, HDMI_REVISION_ID), -- hdmi_readb(hdmi, HDMI_PRODUCT_ID0), -- hdmi_readb(hdmi, HDMI_PRODUCT_ID1)); -+ version = (hdmi_readb(hdmi, HDMI_DESIGN_ID) << 8) -+ | (hdmi_readb(hdmi, HDMI_REVISION_ID) << 0); -+ prod_id0 = hdmi_readb(hdmi, HDMI_PRODUCT_ID0); -+ prod_id1 = hdmi_readb(hdmi, HDMI_PRODUCT_ID1); -+ -+ if (prod_id0 != HDMI_PRODUCT_ID0_HDMI_TX || -+ (prod_id1 & ~HDMI_PRODUCT_ID1_HDCP) != HDMI_PRODUCT_ID1_HDMI_TX) { -+ dev_err(dev, "Unsupported HDMI controller (%04x:%02x:%02x)\n", -+ version, prod_id0, prod_id1); -+ ret = -ENODEV; -+ goto err_iahb; -+ } -+ -+ dev_info(dev, "Detected HDMI TX controller v%x.%03x %s HDCP\n", -+ version >> 12, version & 0xfff, -+ prod_id1 & HDMI_PRODUCT_ID1_HDCP ? "with" : "without"); - - initialize_hdmi_ih_mutes(hdmi); - -diff --git a/drivers/gpu/drm/bridge/dw-hdmi.h b/drivers/gpu/drm/bridge/dw-hdmi.h -index 08235ae..91d7fab 100644 ---- a/drivers/gpu/drm/bridge/dw-hdmi.h -+++ b/drivers/gpu/drm/bridge/dw-hdmi.h -@@ -545,6 +545,14 @@ - #define HDMI_I2CM_FS_SCL_LCNT_0_ADDR 0x7E12 - - enum { -+/* PRODUCT_ID0 field values */ -+ HDMI_PRODUCT_ID0_HDMI_TX = 0xa0, -+ -+/* PRODUCT_ID1 field values */ -+ HDMI_PRODUCT_ID1_HDCP = 0xc0, -+ HDMI_PRODUCT_ID1_HDMI_RX = 0x02, -+ HDMI_PRODUCT_ID1_HDMI_TX = 0x01, -+ - /* CONFIG0_ID field values */ - HDMI_CONFIG0_I2S = 0x10, - --- -1.9.1 - diff --git a/patch/kernel/odroidc2-next/0024-cec-add-cec_transmit_attempt_done-helper-function.patch b/patch/kernel/odroidc2-next/0024-cec-add-cec_transmit_attempt_done-helper-function.patch new file mode 100644 index 000000000..357b9b778 --- /dev/null +++ b/patch/kernel/odroidc2-next/0024-cec-add-cec_transmit_attempt_done-helper-function.patch @@ -0,0 +1,104 @@ +From e7f6f1daa5b19c35fbf25d6f5501273023a41f72 Mon Sep 17 00:00:00 2001 +From: Hans Verkuil +Date: Wed, 7 Jun 2017 11:46:10 -0300 +Subject: [PATCH 24/79] cec: add cec_transmit_attempt_done helper function + +A simpler variant of cec_transmit_done to be used where the HW does +just a single attempt at a transmit. So if the status indicates an +error, then the corresponding error count will always be 1 and this +function figures that out based on the status argument. + +Signed-off-by: Hans Verkuil +Signed-off-by: Mauro Carvalho Chehab +Signed-off-by: Neil Armstrong +--- + Documentation/media/kapi/cec-core.rst | 10 ++++++++++ + drivers/media/cec/cec-adap.c | 26 ++++++++++++++++++++++++++ + include/media/cec.h | 6 ++++++ + 3 files changed, 42 insertions(+) + +diff --git a/Documentation/media/kapi/cec-core.rst b/Documentation/media/kapi/cec-core.rst +index 278b358..8a65c69 100644 +--- a/Documentation/media/kapi/cec-core.rst ++++ b/Documentation/media/kapi/cec-core.rst +@@ -194,6 +194,11 @@ When a transmit finished (successfully or otherwise): + void cec_transmit_done(struct cec_adapter *adap, u8 status, u8 arb_lost_cnt, + u8 nack_cnt, u8 low_drive_cnt, u8 error_cnt); + ++or: ++ ++.. c:function:: ++ void cec_transmit_attempt_done(struct cec_adapter *adap, u8 status); ++ + The status can be one of: + + CEC_TX_STATUS_OK: +@@ -231,6 +236,11 @@ to 1, if the hardware does support retry then either set these counters to + 0 if the hardware provides no feedback of which errors occurred and how many + times, or fill in the correct values as reported by the hardware. + ++The cec_transmit_attempt_done() function is a helper for cases where the ++hardware never retries, so the transmit is always for just a single ++attempt. It will call cec_transmit_done() in turn, filling in 1 for the ++count argument corresponding to the status. Or all 0 if the status was OK. ++ + When a CEC message was received: + + .. c:function:: +diff --git a/drivers/media/cec/cec-adap.c b/drivers/media/cec/cec-adap.c +index 8a4417f..193cea1 100644 +--- a/drivers/media/cec/cec-adap.c ++++ b/drivers/media/cec/cec-adap.c +@@ -546,6 +546,32 @@ void cec_transmit_done(struct cec_adapter *adap, u8 status, u8 arb_lost_cnt, + } + EXPORT_SYMBOL_GPL(cec_transmit_done); + ++void cec_transmit_attempt_done(struct cec_adapter *adap, u8 status) ++{ ++ switch (status) { ++ case CEC_TX_STATUS_OK: ++ cec_transmit_done(adap, status, 0, 0, 0, 0); ++ return; ++ case CEC_TX_STATUS_ARB_LOST: ++ cec_transmit_done(adap, status, 1, 0, 0, 0); ++ return; ++ case CEC_TX_STATUS_NACK: ++ cec_transmit_done(adap, status, 0, 1, 0, 0); ++ return; ++ case CEC_TX_STATUS_LOW_DRIVE: ++ cec_transmit_done(adap, status, 0, 0, 1, 0); ++ return; ++ case CEC_TX_STATUS_ERROR: ++ cec_transmit_done(adap, status, 0, 0, 0, 1); ++ return; ++ default: ++ /* Should never happen */ ++ WARN(1, "cec-%s: invalid status 0x%02x\n", adap->name, status); ++ return; ++ } ++} ++EXPORT_SYMBOL_GPL(cec_transmit_attempt_done); ++ + /* + * Called when waiting for a reply times out. + */ +diff --git a/include/media/cec.h b/include/media/cec.h +index fc69588..23c1faa 100644 +--- a/include/media/cec.h ++++ b/include/media/cec.h +@@ -227,6 +227,12 @@ int cec_transmit_msg(struct cec_adapter *adap, struct cec_msg *msg, + /* Called by the adapter */ + void cec_transmit_done(struct cec_adapter *adap, u8 status, u8 arb_lost_cnt, + u8 nack_cnt, u8 low_drive_cnt, u8 error_cnt); ++/* ++ * Simplified version of cec_transmit_done for hardware that doesn't retry ++ * failed transmits. So this is always just one attempt in which case ++ * the status is sufficient. ++ */ ++void cec_transmit_attempt_done(struct cec_adapter *adap, u8 status); + void cec_received_msg(struct cec_adapter *adap, struct cec_msg *msg); + + /** +-- +1.9.1 + diff --git a/patch/kernel/odroidc2-next/0024-drm-bridge-dw-hdmi-Detect-AHB-audio-DMA-using-correc.patch b/patch/kernel/odroidc2-next/0024-drm-bridge-dw-hdmi-Detect-AHB-audio-DMA-using-correc.patch deleted file mode 100644 index 6556ed2e4..000000000 --- a/patch/kernel/odroidc2-next/0024-drm-bridge-dw-hdmi-Detect-AHB-audio-DMA-using-correc.patch +++ /dev/null @@ -1,62 +0,0 @@ -From dce4baf82ad245b9fc6a6fe6945e484ac9f32fa4 Mon Sep 17 00:00:00 2001 -From: Laurent Pinchart -Date: Tue, 17 Jan 2017 10:29:04 +0200 -Subject: [PATCH 24/93] drm: bridge: dw-hdmi: Detect AHB audio DMA using - correct register - -Bit 0 in CONFIG1_ID tells whether the IP core uses an AHB slave -interface for control. The correct way to identify AHB audio DMA support -is through bit 1 in CONFIG3_ID. - -Signed-off-by: Laurent Pinchart -Reviewed-by: Jose Abreu -Signed-off-by: Archit Taneja -Link: http://patchwork.freedesktop.org/patch/msgid/20170117082910.27023-15-laurent.pinchart+renesas@ideasonboard.com ---- - drivers/gpu/drm/bridge/dw-hdmi.c | 6 +++--- - drivers/gpu/drm/bridge/dw-hdmi.h | 4 ++++ - 2 files changed, 7 insertions(+), 3 deletions(-) - -diff --git a/drivers/gpu/drm/bridge/dw-hdmi.c b/drivers/gpu/drm/bridge/dw-hdmi.c -index 1809247..730a7558 100644 ---- a/drivers/gpu/drm/bridge/dw-hdmi.c -+++ b/drivers/gpu/drm/bridge/dw-hdmi.c -@@ -1836,7 +1836,7 @@ static irqreturn_t dw_hdmi_irq(int irq, void *dev_id) - u8 prod_id0; - u8 prod_id1; - u8 config0; -- u8 config1; -+ u8 config3; - - hdmi = devm_kzalloc(dev, sizeof(*hdmi), GFP_KERNEL); - if (!hdmi) -@@ -1988,9 +1988,9 @@ static irqreturn_t dw_hdmi_irq(int irq, void *dev_id) - pdevinfo.id = PLATFORM_DEVID_AUTO; - - config0 = hdmi_readb(hdmi, HDMI_CONFIG0_ID); -- config1 = hdmi_readb(hdmi, HDMI_CONFIG1_ID); -+ config3 = hdmi_readb(hdmi, HDMI_CONFIG3_ID); - -- if (config1 & HDMI_CONFIG1_AHB) { -+ if (config3 & HDMI_CONFIG3_AHBAUDDMA) { - struct dw_hdmi_audio_data audio; - - audio.phys = iores->start; -diff --git a/drivers/gpu/drm/bridge/dw-hdmi.h b/drivers/gpu/drm/bridge/dw-hdmi.h -index 91d7fab..a4fd64a 100644 ---- a/drivers/gpu/drm/bridge/dw-hdmi.h -+++ b/drivers/gpu/drm/bridge/dw-hdmi.h -@@ -559,6 +559,10 @@ enum { - /* CONFIG1_ID field values */ - HDMI_CONFIG1_AHB = 0x01, - -+/* CONFIG3_ID field values */ -+ HDMI_CONFIG3_AHBAUDDMA = 0x02, -+ HDMI_CONFIG3_GPAUD = 0x01, -+ - /* IH_FC_INT2 field values */ - HDMI_IH_FC_INT2_OVERFLOW_MASK = 0x03, - HDMI_IH_FC_INT2_LOW_PRIORITY_OVERFLOW = 0x02, --- -1.9.1 - diff --git a/patch/kernel/odroidc2-next/0025-cec-add-CEC_CAP_NEEDS_HPD.patch b/patch/kernel/odroidc2-next/0025-cec-add-CEC_CAP_NEEDS_HPD.patch new file mode 100644 index 000000000..a7feac146 --- /dev/null +++ b/patch/kernel/odroidc2-next/0025-cec-add-CEC_CAP_NEEDS_HPD.patch @@ -0,0 +1,176 @@ +From e4826bb782c7fca70e8c1b7cbe1bb726400399b5 Mon Sep 17 00:00:00 2001 +From: Hans Verkuil +Date: Wed, 7 Jun 2017 11:46:12 -0300 +Subject: [PATCH 25/79] cec: add CEC_CAP_NEEDS_HPD + +Add a new capability CEC_CAP_NEEDS_HPD. If this capability is set +then the hardware can only use CEC if the HDMI Hotplug Detect pin +is high. Such hardware cannot handle the corner case in the CEC specification +where it is possible to transmit messages even if no hotplug signal is +present (needed for some displays that turn off the HPD when in standby, +but still have CEC enabled). + +Typically hardware that needs this capability have the HPD wired to the CEC +block, often to a 'power' or 'active' pin. + +Signed-off-by: Hans Verkuil +Signed-off-by: Mauro Carvalho Chehab +Signed-off-by: Neil Armstrong +--- + drivers/media/cec/cec-adap.c | 20 ++++++++++++++------ + drivers/media/cec/cec-api.c | 5 ++++- + drivers/media/cec/cec-core.c | 1 + + include/media/cec.h | 1 + + include/uapi/linux/cec.h | 2 ++ + 5 files changed, 22 insertions(+), 7 deletions(-) + +diff --git a/drivers/media/cec/cec-adap.c b/drivers/media/cec/cec-adap.c +index 193cea1..ab82e84 100644 +--- a/drivers/media/cec/cec-adap.c ++++ b/drivers/media/cec/cec-adap.c +@@ -368,6 +368,8 @@ int cec_thread_func(void *_adap) + * transmit should be canceled. + */ + err = wait_event_interruptible_timeout(adap->kthread_waitq, ++ (adap->needs_hpd && ++ (!adap->is_configured && !adap->is_configuring)) || + kthread_should_stop() || + (!adap->transmitting && + !list_empty(&adap->transmit_queue)), +@@ -383,7 +385,9 @@ int cec_thread_func(void *_adap) + + mutex_lock(&adap->lock); + +- if (kthread_should_stop()) { ++ if ((adap->needs_hpd && ++ (!adap->is_configured && !adap->is_configuring)) || ++ kthread_should_stop()) { + cec_flush(adap); + goto unlock; + } +@@ -675,7 +679,7 @@ int cec_transmit_msg_fh(struct cec_adapter *adap, struct cec_msg *msg, + return -EINVAL; + } + if (!adap->is_configured && !adap->is_configuring) { +- if (msg->msg[0] != 0xf0) { ++ if (adap->needs_hpd || msg->msg[0] != 0xf0) { + dprintk(1, "%s: adapter is unconfigured\n", __func__); + return -ENONET; + } +@@ -1154,7 +1158,9 @@ static int cec_config_log_addr(struct cec_adapter *adap, + */ + static void cec_adap_unconfigure(struct cec_adapter *adap) + { +- WARN_ON(adap->ops->adap_log_addr(adap, CEC_LOG_ADDR_INVALID)); ++ if (!adap->needs_hpd || ++ adap->phys_addr != CEC_PHYS_ADDR_INVALID) ++ WARN_ON(adap->ops->adap_log_addr(adap, CEC_LOG_ADDR_INVALID)); + adap->log_addrs.log_addr_mask = 0; + adap->is_configuring = false; + adap->is_configured = false; +@@ -1383,6 +1389,8 @@ void __cec_s_phys_addr(struct cec_adapter *adap, u16 phys_addr, bool block) + if (phys_addr == adap->phys_addr || adap->devnode.unregistered) + return; + ++ dprintk(1, "new physical address %x.%x.%x.%x\n", ++ cec_phys_addr_exp(phys_addr)); + if (phys_addr == CEC_PHYS_ADDR_INVALID || + adap->phys_addr != CEC_PHYS_ADDR_INVALID) { + adap->phys_addr = CEC_PHYS_ADDR_INVALID; +@@ -1392,7 +1400,7 @@ void __cec_s_phys_addr(struct cec_adapter *adap, u16 phys_addr, bool block) + if (adap->monitor_all_cnt) + WARN_ON(call_op(adap, adap_monitor_all_enable, false)); + mutex_lock(&adap->devnode.lock); +- if (list_empty(&adap->devnode.fhs)) ++ if (adap->needs_hpd || list_empty(&adap->devnode.fhs)) + WARN_ON(adap->ops->adap_enable(adap, false)); + mutex_unlock(&adap->devnode.lock); + if (phys_addr == CEC_PHYS_ADDR_INVALID) +@@ -1400,7 +1408,7 @@ void __cec_s_phys_addr(struct cec_adapter *adap, u16 phys_addr, bool block) + } + + mutex_lock(&adap->devnode.lock); +- if (list_empty(&adap->devnode.fhs) && ++ if ((adap->needs_hpd || list_empty(&adap->devnode.fhs)) && + adap->ops->adap_enable(adap, true)) { + mutex_unlock(&adap->devnode.lock); + return; +@@ -1408,7 +1416,7 @@ void __cec_s_phys_addr(struct cec_adapter *adap, u16 phys_addr, bool block) + + if (adap->monitor_all_cnt && + call_op(adap, adap_monitor_all_enable, true)) { +- if (list_empty(&adap->devnode.fhs)) ++ if (adap->needs_hpd || list_empty(&adap->devnode.fhs)) + WARN_ON(adap->ops->adap_enable(adap, false)); + mutex_unlock(&adap->devnode.lock); + return; +diff --git a/drivers/media/cec/cec-api.c b/drivers/media/cec/cec-api.c +index 999926f..f7eb4c5 100644 +--- a/drivers/media/cec/cec-api.c ++++ b/drivers/media/cec/cec-api.c +@@ -202,7 +202,8 @@ static long cec_transmit(struct cec_adapter *adap, struct cec_fh *fh, + err = -EPERM; + else if (adap->is_configuring) + err = -ENONET; +- else if (!adap->is_configured && msg.msg[0] != 0xf0) ++ else if (!adap->is_configured && ++ (adap->needs_hpd || msg.msg[0] != 0xf0)) + err = -ENONET; + else if (cec_is_busy(adap, fh)) + err = -EBUSY; +@@ -515,6 +516,7 @@ static int cec_open(struct inode *inode, struct file *filp) + + mutex_lock(&devnode->lock); + if (list_empty(&devnode->fhs) && ++ !adap->needs_hpd && + adap->phys_addr == CEC_PHYS_ADDR_INVALID) { + err = adap->ops->adap_enable(adap, true); + if (err) { +@@ -559,6 +561,7 @@ static int cec_release(struct inode *inode, struct file *filp) + mutex_lock(&devnode->lock); + list_del(&fh->list); + if (list_empty(&devnode->fhs) && ++ !adap->needs_hpd && + adap->phys_addr == CEC_PHYS_ADDR_INVALID) { + WARN_ON(adap->ops->adap_enable(adap, false)); + } +diff --git a/drivers/media/cec/cec-core.c b/drivers/media/cec/cec-core.c +index 2f87748..b516d59 100644 +--- a/drivers/media/cec/cec-core.c ++++ b/drivers/media/cec/cec-core.c +@@ -230,6 +230,7 @@ struct cec_adapter *cec_allocate_adapter(const struct cec_adap_ops *ops, + adap->log_addrs.cec_version = CEC_OP_CEC_VERSION_2_0; + adap->log_addrs.vendor_id = CEC_VENDOR_ID_NONE; + adap->capabilities = caps; ++ adap->needs_hpd = caps & CEC_CAP_NEEDS_HPD; + adap->available_log_addrs = available_las; + adap->sequence = 0; + adap->ops = ops; +diff --git a/include/media/cec.h b/include/media/cec.h +index 23c1faa..56643b2 100644 +--- a/include/media/cec.h ++++ b/include/media/cec.h +@@ -164,6 +164,7 @@ struct cec_adapter { + u8 available_log_addrs; + + u16 phys_addr; ++ bool needs_hpd; + bool is_configuring; + bool is_configured; + u32 monitor_all_cnt; +diff --git a/include/uapi/linux/cec.h b/include/uapi/linux/cec.h +index a0dfe27..44579a2 100644 +--- a/include/uapi/linux/cec.h ++++ b/include/uapi/linux/cec.h +@@ -336,6 +336,8 @@ static inline int cec_is_unconfigured(__u16 log_addr_mask) + #define CEC_CAP_RC (1 << 4) + /* Hardware can monitor all messages, not just directed and broadcast. */ + #define CEC_CAP_MONITOR_ALL (1 << 5) ++/* Hardware can use CEC only if the HDMI HPD pin is high. */ ++#define CEC_CAP_NEEDS_HPD (1 << 6) + + /** + * struct cec_caps - CEC capabilities structure. +-- +1.9.1 + diff --git a/patch/kernel/odroidc2-next/0025-drm-bridge-dw-hdmi-Handle-overflow-workaround-based-.patch b/patch/kernel/odroidc2-next/0025-drm-bridge-dw-hdmi-Handle-overflow-workaround-based-.patch deleted file mode 100644 index 18a74d182..000000000 --- a/patch/kernel/odroidc2-next/0025-drm-bridge-dw-hdmi-Handle-overflow-workaround-based-.patch +++ /dev/null @@ -1,123 +0,0 @@ -From 3b3c8dc7038a16dfeb29388d6b5afbef869ebc2d Mon Sep 17 00:00:00 2001 -From: Laurent Pinchart -Date: Tue, 17 Jan 2017 10:29:05 +0200 -Subject: [PATCH 25/93] drm: bridge: dw-hdmi: Handle overflow workaround based - on device version - -Use the device version queried at runtime instead of the device type -provided through platform data to handle the overflow workaround. This -will make support of other SoCs integrating the same HDMI TX controller -version easier. - -Among the supported platforms only i.MX6DL and i.MX6Q have been -identified as needing the workaround. Disabling it on Rockchip RK3288 -(which integrates a v2.00a controller) didn't produce any error or -artifact. - -Signed-off-by: Laurent Pinchart -Reviewed-by: Jose Abreu -Signed-off-by: Archit Taneja -Link: http://patchwork.freedesktop.org/patch/msgid/20170117082910.27023-16-laurent.pinchart+renesas@ideasonboard.com ---- - drivers/gpu/drm/bridge/dw-hdmi.c | 46 ++++++++++++++++++++++++++++------------ - 1 file changed, 33 insertions(+), 13 deletions(-) - -diff --git a/drivers/gpu/drm/bridge/dw-hdmi.c b/drivers/gpu/drm/bridge/dw-hdmi.c -index 730a7558..f4faa14 100644 ---- a/drivers/gpu/drm/bridge/dw-hdmi.c -+++ b/drivers/gpu/drm/bridge/dw-hdmi.c -@@ -117,8 +117,10 @@ struct dw_hdmi { - struct drm_connector connector; - struct drm_bridge bridge; - -- struct platform_device *audio; - enum dw_hdmi_devtype dev_type; -+ unsigned int version; -+ -+ struct platform_device *audio; - struct device *dev; - struct clk *isfr_clk; - struct clk *iahb_clk; -@@ -1323,19 +1325,38 @@ static void hdmi_enable_audio_clk(struct dw_hdmi *hdmi) - /* Workaround to clear the overflow condition */ - static void dw_hdmi_clear_overflow(struct dw_hdmi *hdmi) - { -- int count; -+ unsigned int count; -+ unsigned int i; - u8 val; - -- /* TMDS software reset */ -- hdmi_writeb(hdmi, (u8)~HDMI_MC_SWRSTZ_TMDSSWRST_REQ, HDMI_MC_SWRSTZ); -+ /* -+ * Under some circumstances the Frame Composer arithmetic unit can miss -+ * an FC register write due to being busy processing the previous one. -+ * The issue can be worked around by issuing a TMDS software reset and -+ * then write one of the FC registers several times. -+ * -+ * The number of iterations matters and depends on the HDMI TX revision -+ * (and possibly on the platform). So far only i.MX6Q (v1.30a) and -+ * i.MX6DL (v1.31a) have been identified as needing the workaround, with -+ * 4 and 1 iterations respectively. -+ */ - -- val = hdmi_readb(hdmi, HDMI_FC_INVIDCONF); -- if (hdmi->dev_type == IMX6DL_HDMI) { -- hdmi_writeb(hdmi, val, HDMI_FC_INVIDCONF); -+ switch (hdmi->version) { -+ case 0x130a: -+ count = 4; -+ break; -+ case 0x131a: -+ count = 1; -+ break; -+ default: - return; - } - -- for (count = 0; count < 4; count++) -+ /* TMDS software reset */ -+ hdmi_writeb(hdmi, (u8)~HDMI_MC_SWRSTZ_TMDSSWRST_REQ, HDMI_MC_SWRSTZ); -+ -+ val = hdmi_readb(hdmi, HDMI_FC_INVIDCONF); -+ for (i = 0; i < count; i++) - hdmi_writeb(hdmi, val, HDMI_FC_INVIDCONF); - } - -@@ -1832,7 +1853,6 @@ static irqreturn_t dw_hdmi_irq(int irq, void *dev_id) - int irq; - int ret; - u32 val = 1; -- u16 version; - u8 prod_id0; - u8 prod_id1; - u8 config0; -@@ -1917,21 +1937,21 @@ static irqreturn_t dw_hdmi_irq(int irq, void *dev_id) - } - - /* Product and revision IDs */ -- version = (hdmi_readb(hdmi, HDMI_DESIGN_ID) << 8) -- | (hdmi_readb(hdmi, HDMI_REVISION_ID) << 0); -+ hdmi->version = (hdmi_readb(hdmi, HDMI_DESIGN_ID) << 8) -+ | (hdmi_readb(hdmi, HDMI_REVISION_ID) << 0); - prod_id0 = hdmi_readb(hdmi, HDMI_PRODUCT_ID0); - prod_id1 = hdmi_readb(hdmi, HDMI_PRODUCT_ID1); - - if (prod_id0 != HDMI_PRODUCT_ID0_HDMI_TX || - (prod_id1 & ~HDMI_PRODUCT_ID1_HDCP) != HDMI_PRODUCT_ID1_HDMI_TX) { - dev_err(dev, "Unsupported HDMI controller (%04x:%02x:%02x)\n", -- version, prod_id0, prod_id1); -+ hdmi->version, prod_id0, prod_id1); - ret = -ENODEV; - goto err_iahb; - } - - dev_info(dev, "Detected HDMI TX controller v%x.%03x %s HDCP\n", -- version >> 12, version & 0xfff, -+ hdmi->version >> 12, hdmi->version & 0xfff, - prod_id1 & HDMI_PRODUCT_ID1_HDCP ? "with" : "without"); - - initialize_hdmi_ih_mutes(hdmi); --- -1.9.1 - diff --git a/patch/kernel/odroidc2-next/0026-drm-bridge-dw-hdmi-Detect-PHY-type-at-runtime.patch b/patch/kernel/odroidc2-next/0026-drm-bridge-dw-hdmi-Detect-PHY-type-at-runtime.patch deleted file mode 100644 index 09f935a7b..000000000 --- a/patch/kernel/odroidc2-next/0026-drm-bridge-dw-hdmi-Detect-PHY-type-at-runtime.patch +++ /dev/null @@ -1,149 +0,0 @@ -From c69ce1e08f7d1eeb8de98544ecc1c1c12fe91408 Mon Sep 17 00:00:00 2001 -From: Laurent Pinchart -Date: Tue, 17 Jan 2017 10:29:06 +0200 -Subject: [PATCH 26/93] drm: bridge: dw-hdmi: Detect PHY type at runtime - -Detect the PHY type and use it to handle the PHY type-specific SVSRET -signal. - -Signed-off-by: Laurent Pinchart -Signed-off-by: Archit Taneja -Link: http://patchwork.freedesktop.org/patch/msgid/20170117082910.27023-17-laurent.pinchart+renesas@ideasonboard.com ---- - drivers/gpu/drm/bridge/dw-hdmi.c | 68 ++++++++++++++++++++++++++++++++++++++-- - include/drm/bridge/dw_hdmi.h | 10 ++++++ - 2 files changed, 75 insertions(+), 3 deletions(-) - -diff --git a/drivers/gpu/drm/bridge/dw-hdmi.c b/drivers/gpu/drm/bridge/dw-hdmi.c -index f4faa14..ef4f2f9 100644 ---- a/drivers/gpu/drm/bridge/dw-hdmi.c -+++ b/drivers/gpu/drm/bridge/dw-hdmi.c -@@ -113,6 +113,12 @@ struct dw_hdmi_i2c { - bool is_regaddr; - }; - -+struct dw_hdmi_phy_data { -+ enum dw_hdmi_phy_type type; -+ const char *name; -+ bool has_svsret; -+}; -+ - struct dw_hdmi { - struct drm_connector connector; - struct drm_bridge bridge; -@@ -134,7 +140,9 @@ struct dw_hdmi { - u8 edid[HDMI_EDID_LEN]; - bool cable_plugin; - -+ const struct dw_hdmi_phy_data *phy; - bool phy_enabled; -+ - struct drm_display_mode previous_mode; - - struct i2c_adapter *ddc; -@@ -1015,7 +1023,8 @@ static int hdmi_phy_configure(struct dw_hdmi *hdmi, int cscon) - dw_hdmi_phy_gen2_txpwron(hdmi, 1); - dw_hdmi_phy_gen2_pddq(hdmi, 0); - -- if (hdmi->dev_type == RK3288_HDMI) -+ /* The DWC MHL and HDMI 2.0 PHYs need the SVSRET signal to be set. */ -+ if (hdmi->phy->has_svsret) - dw_hdmi_phy_enable_svsret(hdmi, 1); - - /*Wait for PHY PLL lock */ -@@ -1840,6 +1849,54 @@ static irqreturn_t dw_hdmi_irq(int irq, void *dev_id) - return IRQ_HANDLED; - } - -+static const struct dw_hdmi_phy_data dw_hdmi_phys[] = { -+ { -+ .type = DW_HDMI_PHY_DWC_HDMI_TX_PHY, -+ .name = "DWC HDMI TX PHY", -+ }, { -+ .type = DW_HDMI_PHY_DWC_MHL_PHY_HEAC, -+ .name = "DWC MHL PHY + HEAC PHY", -+ .has_svsret = true, -+ }, { -+ .type = DW_HDMI_PHY_DWC_MHL_PHY, -+ .name = "DWC MHL PHY", -+ .has_svsret = true, -+ }, { -+ .type = DW_HDMI_PHY_DWC_HDMI_3D_TX_PHY_HEAC, -+ .name = "DWC HDMI 3D TX PHY + HEAC PHY", -+ }, { -+ .type = DW_HDMI_PHY_DWC_HDMI_3D_TX_PHY, -+ .name = "DWC HDMI 3D TX PHY", -+ }, { -+ .type = DW_HDMI_PHY_DWC_HDMI20_TX_PHY, -+ .name = "DWC HDMI 2.0 TX PHY", -+ .has_svsret = true, -+ } -+}; -+ -+static int dw_hdmi_detect_phy(struct dw_hdmi *hdmi) -+{ -+ unsigned int i; -+ u8 phy_type; -+ -+ phy_type = hdmi_readb(hdmi, HDMI_CONFIG2_ID); -+ -+ for (i = 0; i < ARRAY_SIZE(dw_hdmi_phys); ++i) { -+ if (dw_hdmi_phys[i].type == phy_type) { -+ hdmi->phy = &dw_hdmi_phys[i]; -+ return 0; -+ } -+ } -+ -+ if (phy_type == DW_HDMI_PHY_VENDOR_PHY) -+ dev_err(hdmi->dev, "Unsupported vendor HDMI PHY\n"); -+ else -+ dev_err(hdmi->dev, "Unsupported HDMI PHY type (%02x)\n", -+ phy_type); -+ -+ return -ENODEV; -+} -+ - static struct dw_hdmi * - __dw_hdmi_probe(struct platform_device *pdev, - const struct dw_hdmi_plat_data *plat_data) -@@ -1950,9 +2007,14 @@ static irqreturn_t dw_hdmi_irq(int irq, void *dev_id) - goto err_iahb; - } - -- dev_info(dev, "Detected HDMI TX controller v%x.%03x %s HDCP\n", -+ ret = dw_hdmi_detect_phy(hdmi); -+ if (ret < 0) -+ goto err_iahb; -+ -+ dev_info(dev, "Detected HDMI TX controller v%x.%03x %s HDCP (%s)\n", - hdmi->version >> 12, hdmi->version & 0xfff, -- prod_id1 & HDMI_PRODUCT_ID1_HDCP ? "with" : "without"); -+ prod_id1 & HDMI_PRODUCT_ID1_HDCP ? "with" : "without", -+ hdmi->phy->name); - - initialize_hdmi_ih_mutes(hdmi); - -diff --git a/include/drm/bridge/dw_hdmi.h b/include/drm/bridge/dw_hdmi.h -index 3bb22a8..b080a17 100644 ---- a/include/drm/bridge/dw_hdmi.h -+++ b/include/drm/bridge/dw_hdmi.h -@@ -27,6 +27,16 @@ enum dw_hdmi_devtype { - RK3288_HDMI, - }; - -+enum dw_hdmi_phy_type { -+ DW_HDMI_PHY_DWC_HDMI_TX_PHY = 0x00, -+ DW_HDMI_PHY_DWC_MHL_PHY_HEAC = 0xb2, -+ DW_HDMI_PHY_DWC_MHL_PHY = 0xc2, -+ DW_HDMI_PHY_DWC_HDMI_3D_TX_PHY_HEAC = 0xe2, -+ DW_HDMI_PHY_DWC_HDMI_3D_TX_PHY = 0xf2, -+ DW_HDMI_PHY_DWC_HDMI20_TX_PHY = 0xf3, -+ DW_HDMI_PHY_VENDOR_PHY = 0xfe, -+}; -+ - struct dw_hdmi_mpll_config { - unsigned long mpixelclock; - struct { --- -1.9.1 - diff --git a/patch/kernel/odroidc2-next/0026-dt-bindings-clock-gxbb-expose-audin-clock-gate.patch b/patch/kernel/odroidc2-next/0026-dt-bindings-clock-gxbb-expose-audin-clock-gate.patch new file mode 100644 index 000000000..da9c307a1 --- /dev/null +++ b/patch/kernel/odroidc2-next/0026-dt-bindings-clock-gxbb-expose-audin-clock-gate.patch @@ -0,0 +1,42 @@ +From 5337b8bcf8f92396880e95094f639a343ef5453a Mon Sep 17 00:00:00 2001 +From: Jerome Brunet +Date: Thu, 30 Mar 2017 15:11:42 +0200 +Subject: [PATCH 26/79] dt-bindings: clock: gxbb: expose audin clock gate + +Expose the clock gate required to power AUDIN block + +Signed-off-by: Jerome Brunet +Signed-off-by: Neil Armstrong +--- + drivers/clk/meson/gxbb.h | 2 +- + include/dt-bindings/clock/gxbb-clkc.h | 1 + + 2 files changed, 2 insertions(+), 1 deletion(-) + +diff --git a/drivers/clk/meson/gxbb.h b/drivers/clk/meson/gxbb.h +index 93b8f07..5c24285 100644 +--- a/drivers/clk/meson/gxbb.h ++++ b/drivers/clk/meson/gxbb.h +@@ -205,7 +205,7 @@ + #define CLKID_HIU_IFACE 32 + #define CLKID_ASSIST_MISC 33 + /* CLKID_SPI */ +-#define CLKID_I2S_SPDIF 35 ++/* CLKID_I2S_SPDIF */ + /* CLKID_ETH */ + #define CLKID_DEMUX 37 + /* CLKID_AIU_GLUE */ +diff --git a/include/dt-bindings/clock/gxbb-clkc.h b/include/dt-bindings/clock/gxbb-clkc.h +index 3190e30..ba8a9be 100644 +--- a/include/dt-bindings/clock/gxbb-clkc.h ++++ b/include/dt-bindings/clock/gxbb-clkc.h +@@ -17,6 +17,7 @@ + #define CLKID_SAR_ADC 23 + #define CLKID_RNG0 25 + #define CLKID_SPI 34 ++#define CLKID_I2S_SPDIF 35 + #define CLKID_ETH 36 + #define CLKID_AIU_GLUE 38 + #define CLKID_I2S_OUT 40 +-- +1.9.1 + diff --git a/patch/kernel/odroidc2-next/0027-ASoC-meson-add-meson-audio-core-driver.patch b/patch/kernel/odroidc2-next/0027-ASoC-meson-add-meson-audio-core-driver.patch new file mode 100644 index 000000000..b23922c4c --- /dev/null +++ b/patch/kernel/odroidc2-next/0027-ASoC-meson-add-meson-audio-core-driver.patch @@ -0,0 +1,312 @@ +From d4b067ab4833a89ccbd6c67bf5245621794dbe73 Mon Sep 17 00:00:00 2001 +From: Jerome Brunet +Date: Thu, 30 Mar 2017 11:49:55 +0200 +Subject: [PATCH 27/79] ASoC: meson: add meson audio core driver + +This patch adds support for the audio core driver for the Amlogic Meson SoC +family. The purpose of this driver is to properly reset the audio block and +provide register access for the different devices scattered in this address +space. This includes output and input DMAs, pcm, i2s and spdif dai, card +level routing, internal codec for the gxl variant + +For more information, please refer to the section 5 of the public datasheet +of the S905 (gxbb). This datasheet is available here: [0]. + +[0]: http://dn.odroid.com/S905/DataSheet/S905_Public_Datasheet_V1.1.4.pdf + +Signed-off-by: Jerome Brunet +Signed-off-by: Neil Armstrong +--- + sound/soc/Kconfig | 1 + + sound/soc/Makefile | 1 + + sound/soc/meson/Kconfig | 9 ++ + sound/soc/meson/Makefile | 3 + + sound/soc/meson/audio-core.c | 190 +++++++++++++++++++++++++++++++++++++++++++ + sound/soc/meson/audio-core.h | 28 +++++++ + 6 files changed, 232 insertions(+) + create mode 100644 sound/soc/meson/Kconfig + create mode 100644 sound/soc/meson/Makefile + create mode 100644 sound/soc/meson/audio-core.c + create mode 100644 sound/soc/meson/audio-core.h + +diff --git a/sound/soc/Kconfig b/sound/soc/Kconfig +index c0abad2..7db316f 100644 +--- a/sound/soc/Kconfig ++++ b/sound/soc/Kconfig +@@ -55,6 +55,7 @@ source "sound/soc/kirkwood/Kconfig" + source "sound/soc/img/Kconfig" + source "sound/soc/intel/Kconfig" + source "sound/soc/mediatek/Kconfig" ++source "sound/soc/meson/Kconfig" + source "sound/soc/mxs/Kconfig" + source "sound/soc/pxa/Kconfig" + source "sound/soc/qcom/Kconfig" +diff --git a/sound/soc/Makefile b/sound/soc/Makefile +index 39c27a5..d9892c3 100644 +--- a/sound/soc/Makefile ++++ b/sound/soc/Makefile +@@ -32,6 +32,7 @@ obj-$(CONFIG_SND_SOC) += jz4740/ + obj-$(CONFIG_SND_SOC) += img/ + obj-$(CONFIG_SND_SOC) += intel/ + obj-$(CONFIG_SND_SOC) += mediatek/ ++obj-$(CONFIG_SND_SOC) += meson/ + obj-$(CONFIG_SND_SOC) += mxs/ + obj-$(CONFIG_SND_SOC) += nuc900/ + obj-$(CONFIG_SND_SOC) += omap/ +diff --git a/sound/soc/meson/Kconfig b/sound/soc/meson/Kconfig +new file mode 100644 +index 0000000..216c850 +--- /dev/null ++++ b/sound/soc/meson/Kconfig +@@ -0,0 +1,9 @@ ++menuconfig SND_SOC_MESON ++ tristate "ASoC support for Amlogic Meson SoCs" ++ depends on ARCH_MESON || COMPILE_TEST ++ select MFD_CORE ++ select REGMAP_MMIO ++ help ++ Say Y or M if you want to add support for codecs attached to ++ the Amlogic Meson SoCs Audio interfaces. You will also need to ++ select the audio interfaces to support below. +diff --git a/sound/soc/meson/Makefile b/sound/soc/meson/Makefile +new file mode 100644 +index 0000000..22028ab +--- /dev/null ++++ b/sound/soc/meson/Makefile +@@ -0,0 +1,3 @@ ++snd-soc-meson-audio-core-objs := audio-core.o ++ ++obj-$(CONFIG_SND_SOC_MESON) += snd-soc-meson-audio-core.o +diff --git a/sound/soc/meson/audio-core.c b/sound/soc/meson/audio-core.c +new file mode 100644 +index 0000000..99993ec +--- /dev/null ++++ b/sound/soc/meson/audio-core.c +@@ -0,0 +1,190 @@ ++/* ++ * Copyright (C) 2017 BayLibre, SAS ++ * Author: Jerome Brunet ++ * Copyright (C) 2017 Amlogic, Inc. All rights reserved. ++ * ++ * This program is free software; you can redistribute it and/or ++ * modify it under the terms of the GNU General Public License as ++ * published by the Free Software Foundation; either version 2 of the ++ * License, or (at your option) any later version. ++ * ++ * This program is distributed in the hope that it will be useful, but ++ * WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ * General Public License for more details. ++ * ++ * You should have received a copy of the GNU General Public License ++ * along with this program; if not, see . ++ */ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#include "audio-core.h" ++ ++#define DRV_NAME "meson-audio-core" ++ ++static const char * const acore_clock_names[] = { "aiu_top", ++ "aiu_glue", ++ "audin" }; ++ ++static int meson_acore_init_clocks(struct device *dev) ++{ ++ struct clk *clock; ++ int i, ret; ++ ++ for (i = 0; i < ARRAY_SIZE(acore_clock_names); i++) { ++ clock = devm_clk_get(dev, acore_clock_names[i]); ++ if (IS_ERR(clock)) { ++ if (PTR_ERR(clock) != -EPROBE_DEFER) ++ dev_err(dev, "Failed to get %s clock\n", ++ acore_clock_names[i]); ++ return PTR_ERR(clock); ++ } ++ ++ ret = clk_prepare_enable(clock); ++ if (ret) { ++ dev_err(dev, "Failed to enable %s clock\n", ++ acore_clock_names[i]); ++ return ret; ++ } ++ ++ ret = devm_add_action_or_reset(dev, ++ (void(*)(void *))clk_disable_unprepare, ++ clock); ++ if (ret) ++ return ret; ++ } ++ ++ return 0; ++} ++ ++static const char * const acore_reset_names[] = { "aiu", ++ "audin" }; ++ ++static int meson_acore_init_resets(struct device *dev) ++{ ++ struct reset_control *reset; ++ int i, ret; ++ ++ for (i = 0; i < ARRAY_SIZE(acore_reset_names); i++) { ++ reset = devm_reset_control_get_exclusive(dev, ++ acore_reset_names[i]); ++ if (IS_ERR(reset)) { ++ if (PTR_ERR(reset) != -EPROBE_DEFER) ++ dev_err(dev, "Failed to get %s reset\n", ++ acore_reset_names[i]); ++ return PTR_ERR(reset); ++ } ++ ++ ret = reset_control_reset(reset); ++ if (ret) { ++ dev_err(dev, "Failed to pulse %s reset\n", ++ acore_reset_names[i]); ++ return ret; ++ } ++ } ++ ++ return 0; ++} ++ ++static const struct regmap_config meson_acore_regmap_config = { ++ .reg_bits = 32, ++ .val_bits = 32, ++ .reg_stride = 4, ++}; ++ ++static const struct mfd_cell meson_acore_devs[] = { ++ { ++ .name = "meson-i2s-dai", ++ .of_compatible = "amlogic,meson-i2s-dai", ++ }, ++ { ++ .name = "meson-spdif-dai", ++ .of_compatible = "amlogic,meson-spdif-dai", ++ }, ++ { ++ .name = "meson-aiu-i2s-dma", ++ .of_compatible = "amlogic,meson-aiu-i2s-dma", ++ }, ++ { ++ .name = "meson-aiu-spdif-dma", ++ .of_compatible = "amlogic,meson-aiu-spdif-dma", ++ }, ++}; ++ ++static int meson_acore_probe(struct platform_device *pdev) ++{ ++ struct device *dev = &pdev->dev; ++ struct meson_audio_core_data *data; ++ struct resource *res; ++ void __iomem *regs; ++ int ret; ++ ++ data = devm_kzalloc(dev, sizeof(*data), GFP_KERNEL); ++ if (!data) ++ return -ENOMEM; ++ platform_set_drvdata(pdev, data); ++ ++ ret = meson_acore_init_clocks(dev); ++ if (ret) ++ return ret; ++ ++ ret = meson_acore_init_resets(dev); ++ if (ret) ++ return ret; ++ ++ res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "aiu"); ++ regs = devm_ioremap_resource(dev, res); ++ if (IS_ERR(regs)) ++ return PTR_ERR(regs); ++ ++ data->aiu = devm_regmap_init_mmio(dev, regs, ++ &meson_acore_regmap_config); ++ if (IS_ERR(data->aiu)) { ++ dev_err(dev, "Couldn't create the AIU regmap\n"); ++ return PTR_ERR(data->aiu); ++ } ++ ++ res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "audin"); ++ regs = devm_ioremap_resource(dev, res); ++ if (IS_ERR(regs)) ++ return PTR_ERR(regs); ++ ++ data->audin = devm_regmap_init_mmio(dev, regs, ++ &meson_acore_regmap_config); ++ if (IS_ERR(data->audin)) { ++ dev_err(dev, "Couldn't create the AUDIN regmap\n"); ++ return PTR_ERR(data->audin); ++ } ++ ++ return devm_mfd_add_devices(dev, PLATFORM_DEVID_AUTO, meson_acore_devs, ++ ARRAY_SIZE(meson_acore_devs), NULL, 0, ++ NULL); ++} ++ ++static const struct of_device_id meson_acore_of_match[] = { ++ { .compatible = "amlogic,meson-audio-core", }, ++ { .compatible = "amlogic,meson-gxbb-audio-core", }, ++ { .compatible = "amlogic,meson-gxl-audio-core", }, ++ {} ++}; ++MODULE_DEVICE_TABLE(of, meson_acore_of_match); ++ ++static struct platform_driver meson_acore_pdrv = { ++ .probe = meson_acore_probe, ++ .driver = { ++ .name = DRV_NAME, ++ .of_match_table = meson_acore_of_match, ++ }, ++}; ++module_platform_driver(meson_acore_pdrv); ++ ++MODULE_DESCRIPTION("Meson Audio Core Driver"); ++MODULE_AUTHOR("Jerome Brunet "); ++MODULE_LICENSE("GPL v2"); +diff --git a/sound/soc/meson/audio-core.h b/sound/soc/meson/audio-core.h +new file mode 100644 +index 0000000..6e7a24c +--- /dev/null ++++ b/sound/soc/meson/audio-core.h +@@ -0,0 +1,28 @@ ++/* ++ * Copyright (C) 2017 BayLibre, SAS ++ * Author: Jerome Brunet ++ * Copyright (C) 2017 Amlogic, Inc. All rights reserved. ++ * ++ * This program is free software; you can redistribute it and/or ++ * modify it under the terms of the GNU General Public License as ++ * published by the Free Software Foundation; either version 2 of the ++ * License, or (at your option) any later version. ++ * ++ * This program is distributed in the hope that it will be useful, but ++ * WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ * General Public License for more details. ++ * ++ * You should have received a copy of the GNU General Public License ++ * along with this program; if not, see . ++ */ ++ ++#ifndef _MESON_AUDIO_CORE_H_ ++#define _MESON_AUDIO_CORE_H_ ++ ++struct meson_audio_core_data { ++ struct regmap *aiu; ++ struct regmap *audin; ++}; ++ ++#endif /* _MESON_AUDIO_CORE_H_ */ +-- +1.9.1 + diff --git a/patch/kernel/odroidc2-next/0027-drm-bridge-dw-hdmi-Define-and-use-macros-for-PHY-reg.patch b/patch/kernel/odroidc2-next/0027-drm-bridge-dw-hdmi-Define-and-use-macros-for-PHY-reg.patch deleted file mode 100644 index 5d490c30a..000000000 --- a/patch/kernel/odroidc2-next/0027-drm-bridge-dw-hdmi-Define-and-use-macros-for-PHY-reg.patch +++ /dev/null @@ -1,145 +0,0 @@ -From d7ce5ad1e16494b6881a9b3e641f224f5d27597b Mon Sep 17 00:00:00 2001 -From: Laurent Pinchart -Date: Tue, 17 Jan 2017 10:29:07 +0200 -Subject: [PATCH 27/93] drm: bridge: dw-hdmi: Define and use macros for PHY - register addresses - -Replace the hardcoded register address numerical values with macros to -clarify the code. - -This change has been tested by comparing the assembly code before and -after the change. - -Signed-off-by: Laurent Pinchart -Reviewed-by: Jose Abreu -Signed-off-by: Archit Taneja -Link: http://patchwork.freedesktop.org/patch/msgid/20170117082910.27023-18-laurent.pinchart+renesas@ideasonboard.com ---- - drivers/gpu/drm/bridge/dw-hdmi.c | 35 ++++++++++++--------- - drivers/gpu/drm/bridge/dw-hdmi.h | 66 ++++++++++++++++++++++++++++++++++++++++ - 2 files changed, 86 insertions(+), 15 deletions(-) - -diff --git a/drivers/gpu/drm/bridge/dw-hdmi.c b/drivers/gpu/drm/bridge/dw-hdmi.c -index ef4f2f9..6e605fd 100644 ---- a/drivers/gpu/drm/bridge/dw-hdmi.c -+++ b/drivers/gpu/drm/bridge/dw-hdmi.c -@@ -997,21 +997,26 @@ static int hdmi_phy_configure(struct dw_hdmi *hdmi, int cscon) - HDMI_PHY_I2CM_SLAVE_ADDR); - hdmi_phy_test_clear(hdmi, 0); - -- hdmi_phy_i2c_write(hdmi, mpll_config->res[0].cpce, 0x06); -- hdmi_phy_i2c_write(hdmi, mpll_config->res[0].gmp, 0x15); -- -- /* CURRCTRL */ -- hdmi_phy_i2c_write(hdmi, curr_ctrl->curr[0], 0x10); -- -- hdmi_phy_i2c_write(hdmi, 0x0000, 0x13); /* PLLPHBYCTRL */ -- hdmi_phy_i2c_write(hdmi, 0x0006, 0x17); -- -- hdmi_phy_i2c_write(hdmi, phy_config->term, 0x19); /* TXTERM */ -- hdmi_phy_i2c_write(hdmi, phy_config->sym_ctr, 0x09); /* CKSYMTXCTRL */ -- hdmi_phy_i2c_write(hdmi, phy_config->vlev_ctr, 0x0E); /* VLEVCTRL */ -- -- /* REMOVE CLK TERM */ -- hdmi_phy_i2c_write(hdmi, 0x8000, 0x05); /* CKCALCTRL */ -+ hdmi_phy_i2c_write(hdmi, mpll_config->res[0].cpce, -+ HDMI_3D_TX_PHY_CPCE_CTRL); -+ hdmi_phy_i2c_write(hdmi, mpll_config->res[0].gmp, -+ HDMI_3D_TX_PHY_GMPCTRL); -+ hdmi_phy_i2c_write(hdmi, curr_ctrl->curr[0], -+ HDMI_3D_TX_PHY_CURRCTRL); -+ -+ hdmi_phy_i2c_write(hdmi, 0, HDMI_3D_TX_PHY_PLLPHBYCTRL); -+ hdmi_phy_i2c_write(hdmi, HDMI_3D_TX_PHY_MSM_CTRL_CKO_SEL_FB_CLK, -+ HDMI_3D_TX_PHY_MSM_CTRL); -+ -+ hdmi_phy_i2c_write(hdmi, phy_config->term, HDMI_3D_TX_PHY_TXTERM); -+ hdmi_phy_i2c_write(hdmi, phy_config->sym_ctr, -+ HDMI_3D_TX_PHY_CKSYMTXCTRL); -+ hdmi_phy_i2c_write(hdmi, phy_config->vlev_ctr, -+ HDMI_3D_TX_PHY_VLEVCTRL); -+ -+ /* Override and disable clock termination. */ -+ hdmi_phy_i2c_write(hdmi, HDMI_3D_TX_PHY_CKCALCTRL_OVERRIDE, -+ HDMI_3D_TX_PHY_CKCALCTRL); - - dw_hdmi_phy_enable_powerdown(hdmi, false); - -diff --git a/drivers/gpu/drm/bridge/dw-hdmi.h b/drivers/gpu/drm/bridge/dw-hdmi.h -index a4fd64a..f3c149c 100644 ---- a/drivers/gpu/drm/bridge/dw-hdmi.h -+++ b/drivers/gpu/drm/bridge/dw-hdmi.h -@@ -1085,4 +1085,70 @@ enum { - HDMI_I2CM_CTLINT_ARB_MASK = 0x4, - }; - -+/* -+ * HDMI 3D TX PHY registers -+ */ -+#define HDMI_3D_TX_PHY_PWRCTRL 0x00 -+#define HDMI_3D_TX_PHY_SERDIVCTRL 0x01 -+#define HDMI_3D_TX_PHY_SERCKCTRL 0x02 -+#define HDMI_3D_TX_PHY_SERCKKILLCTRL 0x03 -+#define HDMI_3D_TX_PHY_TXRESCTRL 0x04 -+#define HDMI_3D_TX_PHY_CKCALCTRL 0x05 -+#define HDMI_3D_TX_PHY_CPCE_CTRL 0x06 -+#define HDMI_3D_TX_PHY_TXCLKMEASCTRL 0x07 -+#define HDMI_3D_TX_PHY_TXMEASCTRL 0x08 -+#define HDMI_3D_TX_PHY_CKSYMTXCTRL 0x09 -+#define HDMI_3D_TX_PHY_CMPSEQCTRL 0x0a -+#define HDMI_3D_TX_PHY_CMPPWRCTRL 0x0b -+#define HDMI_3D_TX_PHY_CMPMODECTRL 0x0c -+#define HDMI_3D_TX_PHY_MEASCTRL 0x0d -+#define HDMI_3D_TX_PHY_VLEVCTRL 0x0e -+#define HDMI_3D_TX_PHY_D2ACTRL 0x0f -+#define HDMI_3D_TX_PHY_CURRCTRL 0x10 -+#define HDMI_3D_TX_PHY_DRVANACTRL 0x11 -+#define HDMI_3D_TX_PHY_PLLMEASCTRL 0x12 -+#define HDMI_3D_TX_PHY_PLLPHBYCTRL 0x13 -+#define HDMI_3D_TX_PHY_GRP_CTRL 0x14 -+#define HDMI_3D_TX_PHY_GMPCTRL 0x15 -+#define HDMI_3D_TX_PHY_MPLLMEASCTRL 0x16 -+#define HDMI_3D_TX_PHY_MSM_CTRL 0x17 -+#define HDMI_3D_TX_PHY_SCRPB_STATUS 0x18 -+#define HDMI_3D_TX_PHY_TXTERM 0x19 -+#define HDMI_3D_TX_PHY_PTRPT_ENBL 0x1a -+#define HDMI_3D_TX_PHY_PATTERNGEN 0x1b -+#define HDMI_3D_TX_PHY_SDCAP_MODE 0x1c -+#define HDMI_3D_TX_PHY_SCOPEMODE 0x1d -+#define HDMI_3D_TX_PHY_DIGTXMODE 0x1e -+#define HDMI_3D_TX_PHY_STR_STATUS 0x1f -+#define HDMI_3D_TX_PHY_SCOPECNT0 0x20 -+#define HDMI_3D_TX_PHY_SCOPECNT1 0x21 -+#define HDMI_3D_TX_PHY_SCOPECNT2 0x22 -+#define HDMI_3D_TX_PHY_SCOPECNTCLK 0x23 -+#define HDMI_3D_TX_PHY_SCOPESAMPLE 0x24 -+#define HDMI_3D_TX_PHY_SCOPECNTMSB01 0x25 -+#define HDMI_3D_TX_PHY_SCOPECNTMSB2CK 0x26 -+ -+/* HDMI_3D_TX_PHY_CKCALCTRL values */ -+#define HDMI_3D_TX_PHY_CKCALCTRL_OVERRIDE BIT(15) -+ -+/* HDMI_3D_TX_PHY_MSM_CTRL values */ -+#define HDMI_3D_TX_PHY_MSM_CTRL_MPLL_PH_SEL_CK BIT(13) -+#define HDMI_3D_TX_PHY_MSM_CTRL_CKO_SEL_CLK_REF_MPLL (0 << 1) -+#define HDMI_3D_TX_PHY_MSM_CTRL_CKO_SEL_OFF (1 << 1) -+#define HDMI_3D_TX_PHY_MSM_CTRL_CKO_SEL_PCLK (2 << 1) -+#define HDMI_3D_TX_PHY_MSM_CTRL_CKO_SEL_FB_CLK (3 << 1) -+#define HDMI_3D_TX_PHY_MSM_CTRL_SCOPE_CK_SEL BIT(0) -+ -+/* HDMI_3D_TX_PHY_PTRPT_ENBL values */ -+#define HDMI_3D_TX_PHY_PTRPT_ENBL_OVERRIDE BIT(15) -+#define HDMI_3D_TX_PHY_PTRPT_ENBL_PG_SKIP_BIT2 BIT(8) -+#define HDMI_3D_TX_PHY_PTRPT_ENBL_PG_SKIP_BIT1 BIT(7) -+#define HDMI_3D_TX_PHY_PTRPT_ENBL_PG_SKIP_BIT0 BIT(6) -+#define HDMI_3D_TX_PHY_PTRPT_ENBL_CK_REF_ENB BIT(5) -+#define HDMI_3D_TX_PHY_PTRPT_ENBL_RCAL_ENB BIT(4) -+#define HDMI_3D_TX_PHY_PTRPT_ENBL_TX_CLK_ALIGN_ENB BIT(3) -+#define HDMI_3D_TX_PHY_PTRPT_ENBL_TX_READY BIT(2) -+#define HDMI_3D_TX_PHY_PTRPT_ENBL_CKO_WORD_ENB BIT(1) -+#define HDMI_3D_TX_PHY_PTRPT_ENBL_REFCLK_ENB BIT(0) -+ - #endif /* __DW_HDMI_H__ */ --- -1.9.1 - diff --git a/patch/kernel/odroidc2-next/0074-snd-meson-add-aiu-register-definitions.patch b/patch/kernel/odroidc2-next/0028-ASoC-meson-add-register-definitions.patch similarity index 54% rename from patch/kernel/odroidc2-next/0074-snd-meson-add-aiu-register-definitions.patch rename to patch/kernel/odroidc2-next/0028-ASoC-meson-add-register-definitions.patch index 4a5a94198..0258c965d 100644 --- a/patch/kernel/odroidc2-next/0074-snd-meson-add-aiu-register-definitions.patch +++ b/patch/kernel/odroidc2-next/0028-ASoC-meson-add-register-definitions.patch @@ -1,20 +1,25 @@ -From d8358b5a254018c6329d4da6fb215bcecdfbceae Mon Sep 17 00:00:00 2001 +From 45ed0fea98d308d6cae17be657dd01d5ee729d87 Mon Sep 17 00:00:00 2001 From: Jerome Brunet -Date: Thu, 19 Jan 2017 15:49:08 +0100 -Subject: [PATCH 74/93] snd: meson: add aiu register definitions +Date: Thu, 30 Mar 2017 12:00:10 +0200 +Subject: [PATCH 28/79] ASoC: meson: add register definitions + +Add the register definition for the AIU and AUDIN blocks Signed-off-by: Jerome Brunet +Signed-off-by: Neil Armstrong --- - sound/soc/meson/aiu-regs.h | 186 +++++++++++++++++++++++++++++++++++++++++++++ - 1 file changed, 186 insertions(+) + sound/soc/meson/aiu-regs.h | 182 +++++++++++++++++++++++++++++++++++++++++++ + sound/soc/meson/audin-regs.h | 148 +++++++++++++++++++++++++++++++++++ + 2 files changed, 330 insertions(+) create mode 100644 sound/soc/meson/aiu-regs.h + create mode 100644 sound/soc/meson/audin-regs.h diff --git a/sound/soc/meson/aiu-regs.h b/sound/soc/meson/aiu-regs.h new file mode 100644 -index 0000000..3b1945c +index 0000000..67391e6 --- /dev/null +++ b/sound/soc/meson/aiu-regs.h -@@ -0,0 +1,186 @@ +@@ -0,0 +1,182 @@ +/* + * Copyright (C) 2017 BayLibre, SAS + * Author: Jerome Brunet @@ -37,10 +42,6 @@ index 0000000..3b1945c +#ifndef _AIU_REGS_H_ +#define _AIU_REGS_H_ + -+/* Base address of AIU within Cbus */ -+#define AIU_CBUS_BASE 0x5400 /* REALLY USEFUL ??? */ -+ -+/* AIU Registers */ +#define AIU_958_BPF 0x000 +#define AIU_958_BRST 0x004 +#define AIU_958_LENGTH 0x008 @@ -85,7 +86,7 @@ index 0000000..3b1945c +#define AIU_CODEC_ADC_LRCLK_CTRL 0x0A4 +#define AIU_HDMI_CLK_DATA_CTRL 0x0A8 +#define AIU_CODEC_CLK_DATA_CTRL 0x0AC -+#define AIU_ACODEC_CTRL 0x0B0 /* Unknown */ ++#define AIU_ACODEC_CTRL 0x0B0 +#define AIU_958_CHSTAT_R0 0x0C0 +#define AIU_958_CHSTAT_R1 0x0C4 +#define AIU_958_VALID_CTRL 0x0C8 @@ -201,6 +202,160 @@ index 0000000..3b1945c +#define AIU_I2S_CBUS_DDR_ADDR 0x2AC + +#endif /* _AIU_REGS_H_ */ +diff --git a/sound/soc/meson/audin-regs.h b/sound/soc/meson/audin-regs.h +new file mode 100644 +index 0000000..f224610 +--- /dev/null ++++ b/sound/soc/meson/audin-regs.h +@@ -0,0 +1,148 @@ ++/* ++ * Copyright (C) 2017 BayLibre, SAS ++ * Author: Jerome Brunet ++ * Copyright (C) 2017 Amlogic, Inc. All rights reserved. ++ * ++ * This program is free software; you can redistribute it and/or ++ * modify it under the terms of the GNU General Public License as ++ * published by the Free Software Foundation; either version 2 of the ++ * License, or (at your option) any later version. ++ * ++ * This program is distributed in the hope that it will be useful, but ++ * WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ * General Public License for more details. ++ * ++ * You should have received a copy of the GNU General Public License ++ * along with this program; if not, see . ++ */ ++ ++#ifndef _AUDIN_REGS_H_ ++#define _AUDIN_REGS_H_ ++ ++/* ++ * Note : ++ * Datasheet issue page 196 ++ * AUDIN_MUTE_VAL 0x35 => impossible: Already assigned to AUDIN_FIFO1_PTR ++ * AUDIN_FIFO1_PTR is more likely to be correct here since surrounding registers ++ * also deal with AUDIN_FIFO1 ++ * ++ * Clarification needed from Amlogic ++ */ ++ ++#define AUDIN_SPDIF_MODE 0x000 ++#define AUDIN_SPDIF_FS_CLK_RLTN 0x004 ++#define AUDIN_SPDIF_CHNL_STS_A 0x008 ++#define AUDIN_SPDIF_CHNL_STS_B 0x00C ++#define AUDIN_SPDIF_MISC 0x010 ++#define AUDIN_SPDIF_NPCM_PCPD 0x014 ++#define AUDIN_SPDIF_END 0x03C /* Unknown */ ++#define AUDIN_I2SIN_CTRL 0x040 ++#define AUDIN_SOURCE_SEL 0x044 ++#define AUDIN_DECODE_FORMAT 0x048 ++#define AUDIN_DECODE_CONTROL_STATUS 0x04C ++#define AUDIN_DECODE_CHANNEL_STATUS_A_0 0x050 ++#define AUDIN_DECODE_CHANNEL_STATUS_A_1 0x054 ++#define AUDIN_DECODE_CHANNEL_STATUS_A_2 0x058 ++#define AUDIN_DECODE_CHANNEL_STATUS_A_3 0x05C ++#define AUDIN_DECODE_CHANNEL_STATUS_A_4 0x060 ++#define AUDIN_DECODE_CHANNEL_STATUS_A_5 0x064 ++#define AUDIN_FIFO0_START 0x080 ++#define AUDIN_FIFO0_END 0x084 ++#define AUDIN_FIFO0_PTR 0x088 ++#define AUDIN_FIFO0_INTR 0x08C ++#define AUDIN_FIFO0_RDPTR 0x090 ++#define AUDIN_FIFO0_CTRL 0x094 ++#define AUDIN_FIFO0_CTRL1 0x098 ++#define AUDIN_FIFO0_LVL0 0x09C ++#define AUDIN_FIFO0_LVL1 0x0A0 ++#define AUDIN_FIFO0_LVL2 0x0A4 ++#define AUDIN_FIFO0_REQID 0x0C0 ++#define AUDIN_FIFO0_WRAP 0x0C4 ++#define AUDIN_FIFO1_START 0x0CC ++#define AUDIN_FIFO1_END 0x0D0 ++#define AUDIN_FIFO1_PTR 0x0D4 ++#define AUDIN_FIFO1_INTR 0x0D8 ++#define AUDIN_FIFO1_RDPTR 0x0DC ++#define AUDIN_FIFO1_CTRL 0x0E0 ++#define AUDIN_FIFO1_CTRL1 0x0E4 ++#define AUDIN_FIFO1_LVL0 0x100 ++#define AUDIN_FIFO1_LVL1 0x104 ++#define AUDIN_FIFO1_LVL2 0x108 ++#define AUDIN_FIFO1_REQID 0x10C ++#define AUDIN_FIFO1_WRAP 0x110 ++#define AUDIN_FIFO2_START 0x114 ++#define AUDIN_FIFO2_END 0x118 ++#define AUDIN_FIFO2_PTR 0x11C ++#define AUDIN_FIFO2_INTR 0x120 ++#define AUDIN_FIFO2_RDPTR 0x124 ++#define AUDIN_FIFO2_CTRL 0x128 ++#define AUDIN_FIFO2_CTRL1 0x12C ++#define AUDIN_FIFO2_LVL0 0x130 ++#define AUDIN_FIFO2_LVL1 0x134 ++#define AUDIN_FIFO2_LVL2 0x138 ++#define AUDIN_FIFO2_REQID 0x13C ++#define AUDIN_FIFO2_WRAP 0x140 ++#define AUDIN_INT_CTRL 0x144 ++#define AUDIN_FIFO_INT 0x148 ++#define PCMIN_CTRL0 0x180 ++#define PCMIN_CTRL1 0x184 ++#define PCMIN1_CTRL0 0x188 ++#define PCMIN1_CTRL1 0x18C ++#define PCMOUT_CTRL0 0x1C0 ++#define PCMOUT_CTRL1 0x1C4 ++#define PCMOUT_CTRL2 0x1C8 ++#define PCMOUT_CTRL3 0x1CC ++#define PCMOUT1_CTRL0 0x1D0 ++#define PCMOUT1_CTRL1 0x1D4 ++#define PCMOUT1_CTRL2 0x1D8 ++#define PCMOUT1_CTRL3 0x1DC ++#define AUDOUT_CTRL 0x200 ++#define AUDOUT_CTRL1 0x204 ++#define AUDOUT_BUF0_STA 0x208 ++#define AUDOUT_BUF0_EDA 0x20C ++#define AUDOUT_BUF0_WPTR 0x210 ++#define AUDOUT_BUF1_STA 0x214 ++#define AUDOUT_BUF1_EDA 0x218 ++#define AUDOUT_BUF1_WPTR 0x21C ++#define AUDOUT_FIFO_RPTR 0x220 ++#define AUDOUT_INTR_PTR 0x224 ++#define AUDOUT_FIFO_STS 0x228 ++#define AUDOUT1_CTRL 0x240 ++#define AUDOUT1_CTRL1 0x244 ++#define AUDOUT1_BUF0_STA 0x248 ++#define AUDOUT1_BUF0_EDA 0x24C ++#define AUDOUT1_BUF0_WPTR 0x250 ++#define AUDOUT1_BUF1_STA 0x254 ++#define AUDOUT1_BUF1_EDA 0x258 ++#define AUDOUT1_BUF1_WPTR 0x25C ++#define AUDOUT1_FIFO_RPTR 0x260 ++#define AUDOUT1_INTR_PTR 0x264 ++#define AUDOUT1_FIFO_STS 0x268 ++#define AUDIN_HDMI_MEAS_CTRL 0x280 ++#define AUDIN_HDMI_MEAS_CYCLES_M1 0x284 ++#define AUDIN_HDMI_MEAS_INTR_MASKN 0x288 ++#define AUDIN_HDMI_MEAS_INTR_STAT 0x28C ++#define AUDIN_HDMI_REF_CYCLES_STAT_0 0x290 ++#define AUDIN_HDMI_REF_CYCLES_STAT_1 0x294 ++#define AUDIN_HDMIRX_AFIFO_STAT 0x298 ++#define AUDIN_FIFO0_PIO_STS 0x2C0 ++#define AUDIN_FIFO0_PIO_RDL 0x2C4 ++#define AUDIN_FIFO0_PIO_RDH 0x2C8 ++#define AUDIN_FIFO1_PIO_STS 0x2CC ++#define AUDIN_FIFO1_PIO_RDL 0x2D0 ++#define AUDIN_FIFO1_PIO_RDH 0x2D4 ++#define AUDIN_FIFO2_PIO_STS 0x2D8 ++#define AUDIN_FIFO2_PIO_RDL 0x2DC ++#define AUDIN_FIFO2_PIO_RDH 0x2E0 ++#define AUDOUT_FIFO_PIO_STS 0x2E4 ++#define AUDOUT_FIFO_PIO_WRL 0x2E8 ++#define AUDOUT_FIFO_PIO_WRH 0x2EC ++#define AUDOUT1_FIFO_PIO_STS 0x2F0 /* Unknown */ ++#define AUDOUT1_FIFO_PIO_WRL 0x2F4 /* Unknown */ ++#define AUDOUT1_FIFO_PIO_WRH 0x2F8 /* Unknown */ ++#define AUD_RESAMPLE_CTRL0 0x2FC ++#define AUD_RESAMPLE_CTRL1 0x300 ++#define AUD_RESAMPLE_STATUS 0x304 ++ ++#endif /* _AUDIN_REGS_H_ */ -- 1.9.1 diff --git a/patch/kernel/odroidc2-next/0028-drm-bridge-dw-hdmi-Fix-the-name-of-the-PHY-reset-mac.patch b/patch/kernel/odroidc2-next/0028-drm-bridge-dw-hdmi-Fix-the-name-of-the-PHY-reset-mac.patch deleted file mode 100644 index 5620b08ed..000000000 --- a/patch/kernel/odroidc2-next/0028-drm-bridge-dw-hdmi-Fix-the-name-of-the-PHY-reset-mac.patch +++ /dev/null @@ -1,59 +0,0 @@ -From 9e151c1acfd889a938f6f49bb07b14c101fa56d5 Mon Sep 17 00:00:00 2001 -From: Laurent Pinchart -Date: Tue, 17 Jan 2017 10:29:08 +0200 -Subject: [PATCH 28/93] drm: bridge: dw-hdmi: Fix the name of the PHY reset - macros - -The PHY reset signal is controlled by bit PHYRSTZ in the MC_PHYRSTZ -register. The signal is active low on Gen1 PHYs and active high on Gen2 -PHYs. The driver toggles the signal high then low, which is correct for -all currently supported platforms, but the register values macros are -incorrectly named. Replace them with a single macro named after the bit, -and add a comment to the source code to explain the behaviour. - -The driver's behaviour isn't changed by this rename, the code will still -need to be fixed to support Gen1 PHYs. - -Signed-off-by: Laurent Pinchart -Reviewed-by: Jose Abreu -Signed-off-by: Archit Taneja -Link: http://patchwork.freedesktop.org/patch/msgid/20170117082910.27023-19-laurent.pinchart+renesas@ideasonboard.com ---- - drivers/gpu/drm/bridge/dw-hdmi.c | 6 +++--- - drivers/gpu/drm/bridge/dw-hdmi.h | 3 +-- - 2 files changed, 4 insertions(+), 5 deletions(-) - -diff --git a/drivers/gpu/drm/bridge/dw-hdmi.c b/drivers/gpu/drm/bridge/dw-hdmi.c -index 6e605fd..93e8816 100644 ---- a/drivers/gpu/drm/bridge/dw-hdmi.c -+++ b/drivers/gpu/drm/bridge/dw-hdmi.c -@@ -986,9 +986,9 @@ static int hdmi_phy_configure(struct dw_hdmi *hdmi, int cscon) - /* gen2 pddq */ - dw_hdmi_phy_gen2_pddq(hdmi, 1); - -- /* PHY reset */ -- hdmi_writeb(hdmi, HDMI_MC_PHYRSTZ_DEASSERT, HDMI_MC_PHYRSTZ); -- hdmi_writeb(hdmi, HDMI_MC_PHYRSTZ_ASSERT, HDMI_MC_PHYRSTZ); -+ /* PHY reset. The reset signal is active high on Gen2 PHYs. */ -+ hdmi_writeb(hdmi, HDMI_MC_PHYRSTZ_PHYRSTZ, HDMI_MC_PHYRSTZ); -+ hdmi_writeb(hdmi, 0, HDMI_MC_PHYRSTZ); - - hdmi_writeb(hdmi, HDMI_MC_HEACPHY_RST_ASSERT, HDMI_MC_HEACPHY_RST); - -diff --git a/drivers/gpu/drm/bridge/dw-hdmi.h b/drivers/gpu/drm/bridge/dw-hdmi.h -index f3c149c..325b0b8 100644 ---- a/drivers/gpu/drm/bridge/dw-hdmi.h -+++ b/drivers/gpu/drm/bridge/dw-hdmi.h -@@ -989,8 +989,7 @@ enum { - HDMI_MC_FLOWCTRL_FEED_THROUGH_OFF_CSC_BYPASS = 0x0, - - /* MC_PHYRSTZ field values */ -- HDMI_MC_PHYRSTZ_ASSERT = 0x0, -- HDMI_MC_PHYRSTZ_DEASSERT = 0x1, -+ HDMI_MC_PHYRSTZ_PHYRSTZ = 0x01, - - /* MC_HEACPHY_RST field values */ - HDMI_MC_HEACPHY_RST_ASSERT = 0x1, --- -1.9.1 - diff --git a/patch/kernel/odroidc2-next/0076-snd-soc-meson-support-for-aiu-i2s-dma.patch b/patch/kernel/odroidc2-next/0029-ASoC-meson-add-aiu-i2s-dma-support.patch similarity index 53% rename from patch/kernel/odroidc2-next/0076-snd-soc-meson-support-for-aiu-i2s-dma.patch rename to patch/kernel/odroidc2-next/0029-ASoC-meson-add-aiu-i2s-dma-support.patch index 6d060ec1a..6eca2571b 100644 --- a/patch/kernel/odroidc2-next/0076-snd-soc-meson-support-for-aiu-i2s-dma.patch +++ b/patch/kernel/odroidc2-next/0029-ASoC-meson-add-aiu-i2s-dma-support.patch @@ -1,163 +1,50 @@ -From 0a351cf435e75a028694a7d5782f2b46582b004d Mon Sep 17 00:00:00 2001 +From 98fd2d06e53a52a033317864b317549e6f3e9245 Mon Sep 17 00:00:00 2001 From: Jerome Brunet -Date: Sun, 12 Feb 2017 00:50:07 +0100 -Subject: [PATCH 76/93] snd: soc: meson: support for aiu i2s dma +Date: Thu, 30 Mar 2017 12:14:40 +0200 +Subject: [PATCH 29/79] ASoC: meson: add aiu i2s dma support -Initial support for meson aiu i2s dma -TO BE COMPLETED ... +Add support for the i2s output dma which is part of the AIU block Signed-off-by: Jerome Brunet +Signed-off-by: Neil Armstrong --- - sound/soc/Kconfig | 1 + - sound/soc/Makefile | 1 + - sound/soc/meson/Kconfig | 17 ++ + sound/soc/meson/Kconfig | 7 + sound/soc/meson/Makefile | 2 + - sound/soc/meson/aiu-common.c | 69 ++++++++ - sound/soc/meson/aiu-i2s-dma.c | 400 ++++++++++++++++++++++++++++++++++++++++++ - sound/soc/meson/aiu.h | 6 + - 7 files changed, 496 insertions(+) - create mode 100644 sound/soc/meson/Kconfig - create mode 100644 sound/soc/meson/Makefile - create mode 100644 sound/soc/meson/aiu-common.c + sound/soc/meson/aiu-i2s-dma.c | 367 ++++++++++++++++++++++++++++++++++++++++++ + 3 files changed, 376 insertions(+) create mode 100644 sound/soc/meson/aiu-i2s-dma.c - create mode 100644 sound/soc/meson/aiu.h -diff --git a/sound/soc/Kconfig b/sound/soc/Kconfig -index 182d92e..58ed5cf 100644 ---- a/sound/soc/Kconfig -+++ b/sound/soc/Kconfig -@@ -54,6 +54,7 @@ source "sound/soc/kirkwood/Kconfig" - source "sound/soc/img/Kconfig" - source "sound/soc/intel/Kconfig" - source "sound/soc/mediatek/Kconfig" -+source "sound/soc/meson/Kconfig" - source "sound/soc/mxs/Kconfig" - source "sound/soc/pxa/Kconfig" - source "sound/soc/qcom/Kconfig" -diff --git a/sound/soc/Makefile b/sound/soc/Makefile -index 9a30f21..fbe16ac 100644 ---- a/sound/soc/Makefile -+++ b/sound/soc/Makefile -@@ -31,6 +31,7 @@ obj-$(CONFIG_SND_SOC) += jz4740/ - obj-$(CONFIG_SND_SOC) += img/ - obj-$(CONFIG_SND_SOC) += intel/ - obj-$(CONFIG_SND_SOC) += mediatek/ -+obj-$(CONFIG_SND_SOC) += meson/ - obj-$(CONFIG_SND_SOC) += mxs/ - obj-$(CONFIG_SND_SOC) += nuc900/ - obj-$(CONFIG_SND_SOC) += omap/ diff --git a/sound/soc/meson/Kconfig b/sound/soc/meson/Kconfig -new file mode 100644 -index 0000000..f2504c6 ---- /dev/null +index 216c850..ad31a11 100644 +--- a/sound/soc/meson/Kconfig +++ b/sound/soc/meson/Kconfig -@@ -0,0 +1,17 @@ -+menu "Amlogic SoC Audio Support" -+ depends on ARCH_MESON || COMPILE_TEST +@@ -7,3 +7,10 @@ menuconfig SND_SOC_MESON + Say Y or M if you want to add support for codecs attached to + the Amlogic Meson SoCs Audio interfaces. You will also need to + select the audio interfaces to support below. + -+config SND_MESON_AIU_I2S_DMA -+ tristate "Meson I2S Output DMA Support" -+ select MFD_SYSCON -+ select SND_MESON_AIU_COMMON ++config SND_SOC_MESON_I2S ++ tristate "Meson i2s interface" ++ depends on SND_SOC_MESON + help -+ This adds ASoC driver the Amlogic Meson i2s DAI -+ If unsure select "N". -+ -+endmenu -+ -+config SND_MESON_AIU_COMMON -+ tristate -+ depends on ARCH_MESON -+ depends on REGMAP_MMIO ++ Say Y or M if you want to add support for i2s dma driver for Amlogic ++ Meson SoCs. diff --git a/sound/soc/meson/Makefile b/sound/soc/meson/Makefile -new file mode 100644 -index 0000000..b237894 ---- /dev/null +index 22028ab..273f275 100644 +--- a/sound/soc/meson/Makefile +++ b/sound/soc/meson/Makefile -@@ -0,0 +1,2 @@ -+obj-$(CONFIG_SND_MESON_AIU_COMMON) += aiu-common.o -+obj-$(CONFIG_SND_MESON_AIU_I2S_DMA) += aiu-i2s-dma.o -diff --git a/sound/soc/meson/aiu-common.c b/sound/soc/meson/aiu-common.c -new file mode 100644 -index 0000000..9beee94 ---- /dev/null -+++ b/sound/soc/meson/aiu-common.c -@@ -0,0 +1,69 @@ -+/* -+ * Copyright (C) 2017 BayLibre, SAS -+ * Author: Jerome Brunet -+ * Copyright (C) 2017 Amlogic, Inc. All rights reserved. -+ * -+ * This program is free software; you can redistribute it and/or -+ * modify it under the terms of the GNU General Public License as -+ * published by the Free Software Foundation; either version 2 of the -+ * License, or (at your option) any later version. -+ * -+ * This program is distributed in the hope that it will be useful, but -+ * WITHOUT ANY WARRANTY; without even the implied warranty of -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -+ * General Public License for more details. -+ * -+ * You should have received a copy of the GNU General Public License -+ * along with this program; if not, see . -+ */ -+ -+#include -+#include -+#include -+ -+ -+static const char* aiu_gate_names[] = { "aiu_top", "aiu_glue" }; -+ -+static int aiu_common_register_clk_gates(struct platform_device *pdev) -+{ -+ struct device *dev = &pdev->dev; -+ struct clk *gate; -+ int i, ret; -+ -+ for (i = 0; i < ARRAY_SIZE(aiu_gate_names); i++) { -+ gate = devm_clk_get(dev, aiu_gate_names[i]); -+ if (IS_ERR(gate)) { -+ if (PTR_ERR(gate) != -EPROBE_DEFER) -+ dev_err(dev, "Failed to get %s clock gate\n", -+ aiu_gate_names[i]); -+ return PTR_ERR(gate); -+ } -+ -+ ret = clk_prepare_enable(gate); -+ if (ret) { -+ dev_err(dev, "failed to enable %s clock gate\n", -+ aiu_gate_names[i]); -+ return ret; -+ } -+ } -+ -+ return 0; -+} -+ -+int aiu_common_register(struct platform_device *pdev) -+{ -+ int ret; -+ -+ ret = aiu_common_register_clk_gates(pdev); -+ if (ret) -+ return ret; -+ -+ /* FIXME: We should also handle the AIU reset here */ -+ -+ return 0; -+} -+EXPORT_SYMBOL_GPL(aiu_common_register); -+ -+MODULE_DESCRIPTION("Meson AIU common helper"); -+MODULE_AUTHOR("Jerome Brunet "); -+MODULE_LICENSE("GPL v2"); +@@ -1,3 +1,5 @@ + snd-soc-meson-audio-core-objs := audio-core.o ++snd-soc-meson-aiu-i2s-dma-objs := aiu-i2s-dma.o + + obj-$(CONFIG_SND_SOC_MESON) += snd-soc-meson-audio-core.o ++obj-$(CONFIG_SND_SOC_MESON_I2S) += snd-soc-meson-aiu-i2s-dma.o diff --git a/sound/soc/meson/aiu-i2s-dma.c b/sound/soc/meson/aiu-i2s-dma.c new file mode 100644 -index 0000000..1e8886c +index 0000000..bab950d --- /dev/null +++ b/sound/soc/meson/aiu-i2s-dma.c -@@ -0,0 +1,400 @@ +@@ -0,0 +1,367 @@ +/* + * Copyright (C) 2017 BayLibre, SAS + * Author: Jerome Brunet @@ -177,8 +64,6 @@ index 0000000..1e8886c + * along with this program; if not, see . + */ + -+#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt -+ +#include +#include +#include @@ -189,16 +74,14 @@ index 0000000..1e8886c +#include +#include + -+#include "aiu.h" +#include "aiu-regs.h" ++#include "audio-core.h" + +#define DRV_NAME "meson-aiu-i2s-dma" + +struct aiu_i2s_dma { -+ struct regmap* regmap; -+ -+ struct clk* i2s_out; -+ ++ struct meson_audio_core_data *core; ++ struct clk *fast; + int irq; +}; + @@ -218,21 +101,17 @@ index 0000000..1e8886c +#define AIU_MEM_I2S_MASKS_CH_RD(ch) ((ch) << 0) +#define AIU_RST_SOFT_I2S_FAST_DOMAIN BIT(0) +#define AIU_RST_SOFT_I2S_SLOW_DOMAIN BIT(1) -+#define AIU_I2S_SOURCE_DESC_MODE_8CH BIT(0) -+#define AIU_I2S_SOURCE_DESC_MODE_24BIT BIT(5) -+#define AIU_I2S_SOURCE_DESC_MODE_32BIT BIT(9) -+#define AIU_I2S_SOURCE_DESC_MODE_SPLIT BIT(11) + +/* + * The DMA works by i2s "blocks" (or DMA burst). The burst size and the memory + * layout expected depends on the mode of operation. + * -+ * - Normal mode: -+ * The channels are expected to be packed in 32 bytes groups interleaved the -+ * buffer. AIU_MEM_I2S_MASKS_CH_MEM is a bitfield representing the channels -+ * present in memory. AIU_MEM_I2S_MASKS_CH_MEM represents the channels read by -+ * the DMA. This very flexible but the unsual memory layout makes it less easy -+ * to deal with. The burst size is 32 bytes times the number of channels read. ++ * - Normal mode: The channels are expected to be packed in 32 bytes groups ++ * interleaved the buffer. AIU_MEM_I2S_MASKS_CH_MEM is a bitfield representing ++ * the channels present in memory. AIU_MEM_I2S_MASKS_CH_MEM represents the ++ * channels read by the DMA. This is very flexible but the unsual memory layout ++ * makes it less easy to deal with. The burst size is 32 bytes times the number ++ * of channels read. + * + * - Split mode: + * Classical channel interleaved frame organisation. In this mode, @@ -265,20 +144,20 @@ index 0000000..1e8886c + .channels_min = 2, + .channels_max = 8, + .period_bytes_min = AIU_I2S_DMA_BURST, -+ .period_bytes_max = AIU_I2S_DMA_BURST * 65535, /* 8192, */ ++ .period_bytes_max = AIU_I2S_DMA_BURST * 65535, + .periods_min = 2, + .periods_max = UINT_MAX, -+ .buffer_bytes_max = 1* 1024 * 1024, ++ .buffer_bytes_max = 1 * 1024 * 1024, + .fifo_size = 0, +}; + +static struct aiu_i2s_dma *aiu_i2s_dma_priv(struct snd_pcm_substream *s) +{ + struct snd_soc_pcm_runtime *rtd = s->private_data; ++ + return snd_soc_platform_get_drvdata(rtd->platform); +} + -+ +static snd_pcm_uframes_t +aiu_i2s_dma_pointer(struct snd_pcm_substream *substream) +{ @@ -287,7 +166,7 @@ index 0000000..1e8886c + unsigned int addr; + int ret; + -+ ret = regmap_read(priv->regmap, AIU_MEM_I2S_RD_PTR, ++ ret = regmap_read(priv->core->aiu, AIU_MEM_I2S_RD_PTR, + &addr); + if (ret) + return 0; @@ -300,7 +179,7 @@ index 0000000..1e8886c + unsigned int en_mask = (AIU_MEM_I2S_CONTROL_FILL_EN | + AIU_MEM_I2S_CONTROL_EMPTY_EN); + -+ regmap_update_bits(priv->regmap, AIU_MEM_I2S_CONTROL, en_mask, ++ regmap_update_bits(priv->core->aiu, AIU_MEM_I2S_CONTROL, en_mask, + enable ? en_mask : 0); + +} @@ -329,17 +208,17 @@ index 0000000..1e8886c + +static void __dma_init_mem(struct aiu_i2s_dma *priv) +{ -+ regmap_update_bits(priv->regmap, AIU_MEM_I2S_CONTROL, ++ regmap_update_bits(priv->core->aiu, AIU_MEM_I2S_CONTROL, + AIU_MEM_I2S_CONTROL_INIT, + AIU_MEM_I2S_CONTROL_INIT); -+ regmap_update_bits(priv->regmap, AIU_MEM_I2S_BUF_CNTL, ++ regmap_update_bits(priv->core->aiu, AIU_MEM_I2S_BUF_CNTL, + AIU_MEM_I2S_BUF_CNTL_INIT, + AIU_MEM_I2S_BUF_CNTL_INIT); + -+ regmap_update_bits(priv->regmap, AIU_MEM_I2S_CONTROL, ++ regmap_update_bits(priv->core->aiu, AIU_MEM_I2S_CONTROL, + AIU_MEM_I2S_CONTROL_INIT, + 0); -+ regmap_update_bits(priv->regmap, AIU_MEM_I2S_BUF_CNTL, ++ regmap_update_bits(priv->core->aiu, AIU_MEM_I2S_BUF_CNTL, + AIU_MEM_I2S_BUF_CNTL_INIT, + 0); +} @@ -359,7 +238,7 @@ index 0000000..1e8886c + struct snd_pcm_runtime *runtime = substream->runtime; + struct aiu_i2s_dma *priv = aiu_i2s_dma_priv(substream); + int ret; -+ u32 burst_num, desc = 0, mem_ctl = 0; ++ u32 burst_num, mem_ctl; + dma_addr_t end_ptr; + + ret = snd_pcm_lib_malloc_pages(substream, params_buffer_bytes(params)); @@ -367,48 +246,26 @@ index 0000000..1e8886c + return ret; + + /* Setup memory layout */ -+ if (params_physical_width(params) == 16) { -+ mem_ctl |= AIU_MEM_I2S_CONTROL_MODE_16BIT; -+ } else { -+ desc |= AIU_I2S_SOURCE_DESC_MODE_24BIT; -+ desc |= AIU_I2S_SOURCE_DESC_MODE_32BIT; -+ } ++ if (params_physical_width(params) == 16) ++ mem_ctl = AIU_MEM_I2S_CONTROL_MODE_16BIT; ++ else ++ mem_ctl = 0; + -+ switch (params_channels(params)) { -+ case 2: /* Nothing to do */ -+ break; -+ case 8: -+ desc |= AIU_I2S_SOURCE_DESC_MODE_8CH; -+ break; -+ default: -+ return -EINVAL; -+ } -+ -+ /* Enable split mode - samples interleaved */ -+ desc |= AIU_I2S_SOURCE_DESC_MODE_SPLIT; -+ -+ regmap_update_bits(priv->regmap, AIU_MEM_I2S_CONTROL, ++ regmap_update_bits(priv->core->aiu, AIU_MEM_I2S_CONTROL, + AIU_MEM_I2S_CONTROL_MODE_16BIT, + mem_ctl); + -+ regmap_update_bits(priv->regmap, AIU_I2S_SOURCE_DESC, -+ AIU_I2S_SOURCE_DESC_MODE_8CH | -+ AIU_I2S_SOURCE_DESC_MODE_24BIT | -+ AIU_I2S_SOURCE_DESC_MODE_32BIT | -+ AIU_I2S_SOURCE_DESC_MODE_SPLIT, -+ desc); -+ + /* Initialize memory pointers */ -+ regmap_write(priv->regmap, AIU_MEM_I2S_START_PTR, runtime->dma_addr); -+ regmap_write(priv->regmap, AIU_MEM_I2S_RD_PTR, runtime->dma_addr); ++ regmap_write(priv->core->aiu, AIU_MEM_I2S_START_PTR, runtime->dma_addr); ++ regmap_write(priv->core->aiu, AIU_MEM_I2S_RD_PTR, runtime->dma_addr); + + /* The end pointer is the address of the last valid block */ + end_ptr = runtime->dma_addr + runtime->dma_bytes - AIU_I2S_DMA_BURST; -+ regmap_write(priv->regmap, AIU_MEM_I2S_END_PTR, end_ptr); ++ regmap_write(priv->core->aiu, AIU_MEM_I2S_END_PTR, end_ptr); + + /* Memory masks */ + burst_num = params_period_bytes(params) / AIU_I2S_DMA_BURST; -+ regmap_write(priv->regmap, AIU_MEM_I2S_MASKS, ++ regmap_write(priv->core->aiu, AIU_MEM_I2S_MASKS, + AIU_MEM_I2S_MASKS_CH_RD(0xff) | + AIU_MEM_I2S_MASKS_CH_MEM(0xff) | + AIU_MEM_I2S_MASKS_IRQ_BLOCK(burst_num)); @@ -456,22 +313,26 @@ index 0000000..1e8886c + + /* Request the I2S DDR irq */ + ret = request_irq(priv->irq, aiu_i2s_dma_irq_block, 0, -+ "meson-aiu-i2s-block", substream); ++ DRV_NAME, substream); + if (ret) + return ret; + -+ /* Enable the DDR to FIFO clock gate */ -+ return clk_prepare_enable(priv->i2s_out); ++ /* Power up the i2s fast domain - can't write the registers w/o it */ ++ ret = clk_prepare_enable(priv->fast); ++ if (ret) ++ return ret; ++ ++ /* Make sure the dma is initially disabled */ ++ __dma_enable(priv, false); ++ ++ return 0; +} + +static int aiu_i2s_dma_close(struct snd_pcm_substream *substream) +{ + struct aiu_i2s_dma *priv = aiu_i2s_dma_priv(substream); + -+ /* First close the clock gate so the DMA is definitely halted */ -+ clk_disable_unprepare(priv->i2s_out); -+ -+ /* Free the irq */ ++ clk_disable_unprepare(priv->fast); + free_irq(priv->irq, substream); + + return 0; @@ -507,28 +368,19 @@ index 0000000..1e8886c +{ + struct device *dev = &pdev->dev; + struct aiu_i2s_dma *priv; -+ int ret; + -+ priv = devm_kzalloc(&pdev->dev, sizeof(*priv), GFP_KERNEL); -+ if(!priv) ++ priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL); ++ if (!priv) + return -ENOMEM; ++ + platform_set_drvdata(pdev, priv); ++ priv->core = dev_get_drvdata(dev->parent); + -+ ret = aiu_common_register(pdev); -+ if (ret) -+ return ret; -+ -+ priv->regmap = syscon_node_to_regmap(dev->parent->of_node); -+ if (IS_ERR(priv->regmap)) { -+ dev_err(dev, "failed to get our regmap\n"); -+ return PTR_ERR(priv->regmap); -+ } -+ -+ priv->i2s_out = devm_clk_get(dev, "i2s_out"); -+ if (IS_ERR(priv->i2s_out)) { -+ if(PTR_ERR(priv->i2s_out) != -EPROBE_DEFER) -+ dev_err(dev, "Can't get i2s_out\n"); -+ return PTR_ERR(priv->i2s_out); ++ priv->fast = devm_clk_get(dev, "fast"); ++ if (IS_ERR(priv->fast)) { ++ if (PTR_ERR(priv->fast) != -EPROBE_DEFER) ++ dev_err(dev, "Can't get i2s fast domain clock\n"); ++ return PTR_ERR(priv->fast); + } + + priv->irq = platform_get_irq(pdev, 0); @@ -540,17 +392,19 @@ index 0000000..1e8886c + return snd_soc_register_platform(dev, &aiu_i2s_platform); +} + -+static const struct of_device_id aiu_i2s_dma_match[] = { ++static const struct of_device_id aiu_i2s_dma_of_match[] = { + { .compatible = "amlogic,meson-aiu-i2s-dma", }, ++ { .compatible = "amlogic,meson-gxbb-aiu-i2s-dma", }, ++ { .compatible = "amlogic,meson-gxl-aiu-i2s-dma", }, + {} +}; -+MODULE_DEVICE_TABLE(of, aiu_i2s_dma_match); ++MODULE_DEVICE_TABLE(of, aiu_i2s_dma_of_match); + +static struct platform_driver aiu_i2s_dma_pdrv = { + .probe = aiu_i2s_dma_probe, + .driver = { + .name = DRV_NAME, -+ .of_match_table = aiu_i2s_dma_match, ++ .of_match_table = aiu_i2s_dma_of_match, + }, +}; +module_platform_driver(aiu_i2s_dma_pdrv); @@ -558,18 +412,6 @@ index 0000000..1e8886c +MODULE_DESCRIPTION("Meson AIU i2s DMA ASoC Driver"); +MODULE_AUTHOR("Jerome Brunet "); +MODULE_LICENSE("GPL v2"); -diff --git a/sound/soc/meson/aiu.h b/sound/soc/meson/aiu.h -new file mode 100644 -index 0000000..a9d1c58 ---- /dev/null -+++ b/sound/soc/meson/aiu.h -@@ -0,0 +1,6 @@ -+#ifndef _AIU_H_ -+#define _AIU_H_ -+ -+int aiu_common_register(struct platform_device *pdev); -+ -+#endif /* _AIU_H_ */ -- 1.9.1 diff --git a/patch/kernel/odroidc2-next/0029-drm-bridge-dw-hdmi-Assert-SVSRET-before-resetting-th.patch b/patch/kernel/odroidc2-next/0029-drm-bridge-dw-hdmi-Assert-SVSRET-before-resetting-th.patch deleted file mode 100644 index 678a8912a..000000000 --- a/patch/kernel/odroidc2-next/0029-drm-bridge-dw-hdmi-Assert-SVSRET-before-resetting-th.patch +++ /dev/null @@ -1,49 +0,0 @@ -From 9faac4dec35ecb92a6eb348a0904b5484b89df72 Mon Sep 17 00:00:00 2001 -From: Laurent Pinchart -Date: Tue, 17 Jan 2017 10:29:09 +0200 -Subject: [PATCH 29/93] drm: bridge: dw-hdmi: Assert SVSRET before resetting - the PHY - -According to the PHY IP core vendor, the SVSRET signal must be asserted -before resetting the PHY. Tests on RK3288 and R-Car Gen3 showed no -regression, the change should thus be safe. - -Signed-off-by: Laurent Pinchart -Reviewed-by: Jose Abreu -Signed-off-by: Archit Taneja -Link: http://patchwork.freedesktop.org/patch/msgid/20170117082910.27023-20-laurent.pinchart+renesas@ideasonboard.com ---- - drivers/gpu/drm/bridge/dw-hdmi.c | 10 +++++----- - 1 file changed, 5 insertions(+), 5 deletions(-) - -diff --git a/drivers/gpu/drm/bridge/dw-hdmi.c b/drivers/gpu/drm/bridge/dw-hdmi.c -index 93e8816..4fda071 100644 ---- a/drivers/gpu/drm/bridge/dw-hdmi.c -+++ b/drivers/gpu/drm/bridge/dw-hdmi.c -@@ -986,6 +986,10 @@ static int hdmi_phy_configure(struct dw_hdmi *hdmi, int cscon) - /* gen2 pddq */ - dw_hdmi_phy_gen2_pddq(hdmi, 1); - -+ /* Leave low power consumption mode by asserting SVSRET. */ -+ if (hdmi->phy->has_svsret) -+ dw_hdmi_phy_enable_svsret(hdmi, 1); -+ - /* PHY reset. The reset signal is active high on Gen2 PHYs. */ - hdmi_writeb(hdmi, HDMI_MC_PHYRSTZ_PHYRSTZ, HDMI_MC_PHYRSTZ); - hdmi_writeb(hdmi, 0, HDMI_MC_PHYRSTZ); -@@ -1028,11 +1032,7 @@ static int hdmi_phy_configure(struct dw_hdmi *hdmi, int cscon) - dw_hdmi_phy_gen2_txpwron(hdmi, 1); - dw_hdmi_phy_gen2_pddq(hdmi, 0); - -- /* The DWC MHL and HDMI 2.0 PHYs need the SVSRET signal to be set. */ -- if (hdmi->phy->has_svsret) -- dw_hdmi_phy_enable_svsret(hdmi, 1); -- -- /*Wait for PHY PLL lock */ -+ /* Wait for PHY PLL lock */ - msec = 5; - do { - val = hdmi_readb(hdmi, HDMI_PHY_STAT0) & HDMI_PHY_TX_PHY_LOCK; --- -1.9.1 - diff --git a/patch/kernel/odroidc2-next/0030-ASoC-meson-add-initial-i2s-dai-support.patch b/patch/kernel/odroidc2-next/0030-ASoC-meson-add-initial-i2s-dai-support.patch new file mode 100644 index 000000000..082d2dfcf --- /dev/null +++ b/patch/kernel/odroidc2-next/0030-ASoC-meson-add-initial-i2s-dai-support.patch @@ -0,0 +1,515 @@ +From e976fda45f89573b89d118ded17112aae8a0f8f5 Mon Sep 17 00:00:00 2001 +From: Jerome Brunet +Date: Thu, 30 Mar 2017 12:17:27 +0200 +Subject: [PATCH 30/79] ASoC: meson: add initial i2s dai support + +Add support for the i2s dai found on Amlogic Meson SoC family. +With this initial implementation, only playback is supported. +Capture will be part of furture work. + +Signed-off-by: Jerome Brunet +Signed-off-by: Neil Armstrong +--- + sound/soc/meson/Kconfig | 2 +- + sound/soc/meson/Makefile | 2 + + sound/soc/meson/i2s-dai.c | 465 ++++++++++++++++++++++++++++++++++++++++++++++ + 3 files changed, 468 insertions(+), 1 deletion(-) + create mode 100644 sound/soc/meson/i2s-dai.c + +diff --git a/sound/soc/meson/Kconfig b/sound/soc/meson/Kconfig +index ad31a11..604c9e2 100644 +--- a/sound/soc/meson/Kconfig ++++ b/sound/soc/meson/Kconfig +@@ -12,5 +12,5 @@ config SND_SOC_MESON_I2S + tristate "Meson i2s interface" + depends on SND_SOC_MESON + help +- Say Y or M if you want to add support for i2s dma driver for Amlogic ++ Say Y or M if you want to add support for i2s driver for Amlogic + Meson SoCs. +diff --git a/sound/soc/meson/Makefile b/sound/soc/meson/Makefile +index 273f275..ea06dde 100644 +--- a/sound/soc/meson/Makefile ++++ b/sound/soc/meson/Makefile +@@ -1,5 +1,7 @@ + snd-soc-meson-audio-core-objs := audio-core.o + snd-soc-meson-aiu-i2s-dma-objs := aiu-i2s-dma.o ++snd-soc-meson-i2s-dai-objs := i2s-dai.o + + obj-$(CONFIG_SND_SOC_MESON) += snd-soc-meson-audio-core.o + obj-$(CONFIG_SND_SOC_MESON_I2S) += snd-soc-meson-aiu-i2s-dma.o ++obj-$(CONFIG_SND_SOC_MESON_I2S) += snd-soc-meson-i2s-dai.o +diff --git a/sound/soc/meson/i2s-dai.c b/sound/soc/meson/i2s-dai.c +new file mode 100644 +index 0000000..1008af8 +--- /dev/null ++++ b/sound/soc/meson/i2s-dai.c +@@ -0,0 +1,465 @@ ++/* ++ * Copyright (C) 2017 BayLibre, SAS ++ * Author: Jerome Brunet ++ * Copyright (C) 2017 Amlogic, Inc. All rights reserved. ++ * ++ * This program is free software; you can redistribute it and/or ++ * modify it under the terms of the GNU General Public License as ++ * published by the Free Software Foundation; either version 2 of the ++ * License, or (at your option) any later version. ++ * ++ * This program is distributed in the hope that it will be useful, but ++ * WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ * General Public License for more details. ++ * ++ * You should have received a copy of the GNU General Public License ++ * along with this program; if not, see . ++ */ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#include ++#include ++#include ++ ++#include "aiu-regs.h" ++#include "audio-core.h" ++ ++#define DRV_NAME "meson-i2s-dai" ++ ++struct meson_i2s_dai { ++ struct meson_audio_core_data *core; ++ struct clk *mclk; ++ struct clk *bclks; ++ struct clk *iface; ++ struct clk *fast; ++ bool bclks_idle; ++}; ++ ++#define AIU_CLK_CTRL_I2S_DIV_EN BIT(0) ++#define AIU_CLK_CTRL_I2S_DIV_MASK GENMASK(3, 2) ++#define AIU_CLK_CTRL_AOCLK_POLARITY_MASK BIT(6) ++#define AIU_CLK_CTRL_AOCLK_POLARITY_NORMAL (0 << 6) ++#define AIU_CLK_CTRL_AOCLK_POLARITY_INVERTED (1 << 6) ++#define AIU_CLK_CTRL_ALRCLK_POLARITY_MASK BIT(7) ++#define AIU_CLK_CTRL_ALRCLK_POLARITY_NORMAL (0 << 7) ++#define AIU_CLK_CTRL_ALRCLK_POLARITY_INVERTED (1 << 7) ++#define AIU_CLK_CTRL_ALRCLK_SKEW_MASK GENMASK(9, 8) ++#define AIU_CLK_CTRL_ALRCLK_LEFT_J (0 << 8) ++#define AIU_CLK_CTRL_ALRCLK_I2S (1 << 8) ++#define AIU_CLK_CTRL_ALRCLK_RIGHT_J (2 << 8) ++#define AIU_CLK_CTRL_MORE_I2S_DIV_MASK GENMASK(5, 0) ++#define AIU_CLK_CTRL_MORE_I2S_DIV(div) (((div) - 1) << 0) ++#define AIU_CODEC_DAC_LRCLK_CTRL_DIV_MASK GENMASK(11, 0) ++#define AIU_CODEC_DAC_LRCLK_CTRL_DIV(div) (((div) - 1) << 0) ++#define AIU_I2S_DAC_CFG_PAYLOAD_SIZE_MASK GENMASK(1, 0) ++#define AIU_I2S_DAC_CFG_AOCLK_32 (0 << 0) ++#define AIU_I2S_DAC_CFG_AOCLK_48 (2 << 0) ++#define AIU_I2S_DAC_CFG_AOCLK_64 (3 << 0) ++#define AIU_I2S_MISC_HOLD_EN BIT(2) ++#define AIU_I2S_SOURCE_DESC_MODE_8CH BIT(0) ++#define AIU_I2S_SOURCE_DESC_MODE_24BIT BIT(5) ++#define AIU_I2S_SOURCE_DESC_MODE_32BIT BIT(9) ++#define AIU_I2S_SOURCE_DESC_MODE_SPLIT BIT(11) ++ ++static void __hold(struct meson_i2s_dai *priv, bool enable) ++{ ++ regmap_update_bits(priv->core->aiu, AIU_I2S_MISC, ++ AIU_I2S_MISC_HOLD_EN, ++ enable ? AIU_I2S_MISC_HOLD_EN : 0); ++} ++ ++static void __divider_enable(struct meson_i2s_dai *priv, bool enable) ++{ ++ regmap_update_bits(priv->core->aiu, AIU_CLK_CTRL, ++ AIU_CLK_CTRL_I2S_DIV_EN, ++ enable ? AIU_CLK_CTRL_I2S_DIV_EN : 0); ++} ++ ++static void __playback_start(struct meson_i2s_dai *priv) ++{ ++ __divider_enable(priv, true); ++ __hold(priv, false); ++} ++ ++static void __playback_stop(struct meson_i2s_dai *priv, bool clk_force) ++{ ++ __hold(priv, true); ++ /* Disable the bit clks if necessary */ ++ if (clk_force || !priv->bclks_idle) ++ __divider_enable(priv, false); ++} ++ ++static int meson_i2s_dai_trigger(struct snd_pcm_substream *substream, int cmd, ++ struct snd_soc_dai *dai) ++{ ++ struct meson_i2s_dai *priv = snd_soc_dai_get_drvdata(dai); ++ bool clk_force_stop = false; ++ ++ switch (cmd) { ++ case SNDRV_PCM_TRIGGER_START: ++ case SNDRV_PCM_TRIGGER_RESUME: ++ case SNDRV_PCM_TRIGGER_PAUSE_RELEASE: ++ __playback_start(priv); ++ return 0; ++ ++ case SNDRV_PCM_TRIGGER_STOP: ++ case SNDRV_PCM_TRIGGER_SUSPEND: ++ clk_force_stop = true; ++ case SNDRV_PCM_TRIGGER_PAUSE_PUSH: ++ __playback_stop(priv, clk_force_stop); ++ return 0; ++ ++ default: ++ return -EINVAL; ++ } ++} ++ ++static int __bclks_set_rate(struct meson_i2s_dai *priv, unsigned int srate, ++ unsigned int width) ++{ ++ unsigned int fs; ++ ++ /* Get the oversampling factor */ ++ fs = DIV_ROUND_CLOSEST(clk_get_rate(priv->mclk), srate); ++ ++ /* ++ * This DAI is usually connected to the dw-hdmi which does not support ++ * bclk being 32 * lrclk or 48 * lrclk ++ * Restrict to blck = 64 * lrclk ++ */ ++ if (fs % 64) ++ return -EINVAL; ++ ++ /* Set the divider between lrclk and bclk */ ++ regmap_update_bits(priv->core->aiu, AIU_I2S_DAC_CFG, ++ AIU_I2S_DAC_CFG_PAYLOAD_SIZE_MASK, ++ AIU_I2S_DAC_CFG_AOCLK_64); ++ ++ regmap_update_bits(priv->core->aiu, AIU_CODEC_DAC_LRCLK_CTRL, ++ AIU_CODEC_DAC_LRCLK_CTRL_DIV_MASK, ++ AIU_CODEC_DAC_LRCLK_CTRL_DIV(64)); ++ ++ /* Use CLK_MORE for the i2s divider */ ++ regmap_update_bits(priv->core->aiu, AIU_CLK_CTRL, ++ AIU_CLK_CTRL_I2S_DIV_MASK, ++ 0); ++ ++ regmap_update_bits(priv->core->aiu, AIU_CLK_CTRL_MORE, ++ AIU_CLK_CTRL_MORE_I2S_DIV_MASK, ++ AIU_CLK_CTRL_MORE_I2S_DIV(fs / 64)); ++ ++ return 0; ++} ++ ++static int __setup_desc(struct meson_i2s_dai *priv, unsigned int width, ++ unsigned int channels) ++{ ++ u32 desc = 0; ++ ++ switch (width) { ++ case 24: ++ /* ++ * For some reason, 24 bits wide audio don't play well ++ * if the 32 bits mode is not set ++ */ ++ desc |= (AIU_I2S_SOURCE_DESC_MODE_24BIT | ++ AIU_I2S_SOURCE_DESC_MODE_32BIT); ++ break; ++ case 16: ++ break; ++ ++ default: ++ return -EINVAL; ++ } ++ ++ switch (channels) { ++ case 2: /* Nothing to do */ ++ break; ++ case 8: ++ /* TODO: Still requires testing ... */ ++ desc |= AIU_I2S_SOURCE_DESC_MODE_8CH; ++ break; ++ default: ++ return -EINVAL; ++ } ++ ++ regmap_update_bits(priv->core->aiu, AIU_I2S_SOURCE_DESC, ++ AIU_I2S_SOURCE_DESC_MODE_8CH | ++ AIU_I2S_SOURCE_DESC_MODE_24BIT | ++ AIU_I2S_SOURCE_DESC_MODE_32BIT, ++ desc); ++ ++ return 0; ++} ++ ++static int meson_i2s_dai_hw_params(struct snd_pcm_substream *substream, ++ struct snd_pcm_hw_params *params, ++ struct snd_soc_dai *dai) ++{ ++ struct meson_i2s_dai *priv = snd_soc_dai_get_drvdata(dai); ++ unsigned int width = params_width(params); ++ unsigned int channels = params_channels(params); ++ unsigned int rate = params_rate(params); ++ int ret; ++ ++ ret = __setup_desc(priv, width, channels); ++ if (ret) { ++ dev_err(dai->dev, "Unable set to set i2s description\n"); ++ return ret; ++ } ++ ++ ret = __bclks_set_rate(priv, rate, width); ++ if (ret) { ++ dev_err(dai->dev, "Unable set to the i2s clock rates\n"); ++ return ret; ++ } ++ ++ return 0; ++} ++ ++static int meson_i2s_dai_set_fmt(struct snd_soc_dai *dai, unsigned int fmt) ++{ ++ struct meson_i2s_dai *priv = snd_soc_dai_get_drvdata(dai); ++ u32 val; ++ ++ if ((fmt & SND_SOC_DAIFMT_MASTER_MASK) != SND_SOC_DAIFMT_CBS_CFS) ++ return -EINVAL; ++ ++ /* DAI output mode */ ++ switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) { ++ case SND_SOC_DAIFMT_I2S: ++ val = AIU_CLK_CTRL_ALRCLK_I2S; ++ break; ++ case SND_SOC_DAIFMT_LEFT_J: ++ val = AIU_CLK_CTRL_ALRCLK_LEFT_J; ++ break; ++ case SND_SOC_DAIFMT_RIGHT_J: ++ val = AIU_CLK_CTRL_ALRCLK_RIGHT_J; ++ break; ++ default: ++ return -EINVAL; ++ } ++ ++ regmap_update_bits(priv->core->aiu, AIU_CLK_CTRL, ++ AIU_CLK_CTRL_ALRCLK_SKEW_MASK, ++ val); ++ ++ /* DAI clock polarity */ ++ switch (fmt & SND_SOC_DAIFMT_INV_MASK) { ++ case SND_SOC_DAIFMT_IB_IF: ++ /* Invert both clocks */ ++ val = AIU_CLK_CTRL_ALRCLK_POLARITY_INVERTED | ++ AIU_CLK_CTRL_AOCLK_POLARITY_INVERTED; ++ break; ++ case SND_SOC_DAIFMT_IB_NF: ++ /* Invert bit clock */ ++ val = AIU_CLK_CTRL_ALRCLK_POLARITY_NORMAL | ++ AIU_CLK_CTRL_AOCLK_POLARITY_INVERTED; ++ break; ++ case SND_SOC_DAIFMT_NB_IF: ++ /* Invert frame clock */ ++ val = AIU_CLK_CTRL_ALRCLK_POLARITY_INVERTED | ++ AIU_CLK_CTRL_AOCLK_POLARITY_NORMAL; ++ break; ++ case SND_SOC_DAIFMT_NB_NF: ++ /* Normal clocks */ ++ val = AIU_CLK_CTRL_ALRCLK_POLARITY_NORMAL | ++ AIU_CLK_CTRL_AOCLK_POLARITY_NORMAL; ++ break; ++ default: ++ return -EINVAL; ++ } ++ ++ regmap_update_bits(priv->core->aiu, AIU_CLK_CTRL, ++ AIU_CLK_CTRL_ALRCLK_POLARITY_MASK | ++ AIU_CLK_CTRL_AOCLK_POLARITY_MASK, ++ val); ++ ++ switch (fmt & SND_SOC_DAIFMT_CLOCK_MASK) { ++ case SND_SOC_DAIFMT_CONT: ++ priv->bclks_idle = true; ++ break; ++ case SND_SOC_DAIFMT_GATED: ++ priv->bclks_idle = false; ++ break; ++ default: ++ return -EINVAL; ++ } ++ ++ return 0; ++} ++ ++static int meson_i2s_dai_set_sysclk(struct snd_soc_dai *dai, int clk_id, ++ unsigned int freq, int dir) ++{ ++ struct meson_i2s_dai *priv = snd_soc_dai_get_drvdata(dai); ++ int ret; ++ ++ if (WARN_ON(clk_id != 0)) ++ return -EINVAL; ++ ++ if (dir == SND_SOC_CLOCK_IN) ++ return 0; ++ ++ ret = clk_set_rate(priv->mclk, freq); ++ if (ret) { ++ dev_err(dai->dev, "Failed to set sysclk to %uHz", freq); ++ return ret; ++ } ++ ++ return 0; ++} ++ ++static int meson_i2s_dai_startup(struct snd_pcm_substream *substream, ++ struct snd_soc_dai *dai) ++{ ++ struct meson_i2s_dai *priv = snd_soc_dai_get_drvdata(dai); ++ int ret; ++ ++ /* Power up the i2s fast domain - can't write the registers w/o it */ ++ ret = clk_prepare_enable(priv->fast); ++ if (ret) ++ goto out_clk_fast; ++ ++ /* Make sure nothing gets out of the DAI yet */ ++ __hold(priv, true); ++ ++ /* I2S encoder needs the mixer interface gate */ ++ ret = clk_prepare_enable(priv->iface); ++ if (ret) ++ goto out_clk_iface; ++ ++ /* Enable the i2s master clock */ ++ ret = clk_prepare_enable(priv->mclk); ++ if (ret) ++ goto out_mclk; ++ ++ /* Enable the bit clock gate */ ++ ret = clk_prepare_enable(priv->bclks); ++ if (ret) ++ goto out_bclks; ++ ++ /* Make sure the interface expect a memory layout we can work with */ ++ regmap_update_bits(priv->core->aiu, AIU_I2S_SOURCE_DESC, ++ AIU_I2S_SOURCE_DESC_MODE_SPLIT, ++ AIU_I2S_SOURCE_DESC_MODE_SPLIT); ++ ++ return 0; ++ ++out_bclks: ++ clk_disable_unprepare(priv->mclk); ++out_mclk: ++ clk_disable_unprepare(priv->iface); ++out_clk_iface: ++ clk_disable_unprepare(priv->fast); ++out_clk_fast: ++ return ret; ++} ++ ++static void meson_i2s_dai_shutdown(struct snd_pcm_substream *substream, ++ struct snd_soc_dai *dai) ++{ ++ struct meson_i2s_dai *priv = snd_soc_dai_get_drvdata(dai); ++ ++ clk_disable_unprepare(priv->bclks); ++ clk_disable_unprepare(priv->mclk); ++ clk_disable_unprepare(priv->iface); ++ clk_disable_unprepare(priv->fast); ++} ++ ++static const struct snd_soc_dai_ops meson_i2s_dai_ops = { ++ .startup = meson_i2s_dai_startup, ++ .shutdown = meson_i2s_dai_shutdown, ++ .trigger = meson_i2s_dai_trigger, ++ .hw_params = meson_i2s_dai_hw_params, ++ .set_fmt = meson_i2s_dai_set_fmt, ++ .set_sysclk = meson_i2s_dai_set_sysclk, ++}; ++ ++static struct snd_soc_dai_driver meson_i2s_dai = { ++ .playback = { ++ .stream_name = "Playback", ++ .channels_min = 2, ++ .channels_max = 8, ++ .rates = SNDRV_PCM_RATE_8000_192000, ++ .formats = (SNDRV_PCM_FMTBIT_S16_LE | ++ SNDRV_PCM_FMTBIT_S24_LE) ++ }, ++ .ops = &meson_i2s_dai_ops, ++}; ++ ++static const struct snd_soc_component_driver meson_i2s_dai_component = { ++ .name = DRV_NAME, ++}; ++ ++static int meson_i2s_dai_probe(struct platform_device *pdev) ++{ ++ struct device *dev = &pdev->dev; ++ struct meson_i2s_dai *priv; ++ ++ priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL); ++ if (!priv) ++ return -ENOMEM; ++ ++ platform_set_drvdata(pdev, priv); ++ priv->core = dev_get_drvdata(dev->parent); ++ ++ priv->fast = devm_clk_get(dev, "fast"); ++ if (IS_ERR(priv->fast)) { ++ if (PTR_ERR(priv->fast) != -EPROBE_DEFER) ++ dev_err(dev, "Can't get the i2s fast domain clock\n"); ++ return PTR_ERR(priv->fast); ++ } ++ ++ priv->iface = devm_clk_get(dev, "iface"); ++ if (IS_ERR(priv->iface)) { ++ if (PTR_ERR(priv->iface) != -EPROBE_DEFER) ++ dev_err(dev, "Can't get i2s dai clock gate\n"); ++ return PTR_ERR(priv->iface); ++ } ++ ++ priv->bclks = devm_clk_get(dev, "bclks"); ++ if (IS_ERR(priv->bclks)) { ++ if (PTR_ERR(priv->bclks) != -EPROBE_DEFER) ++ dev_err(dev, "Can't get bit clocks gate\n"); ++ return PTR_ERR(priv->bclks); ++ } ++ ++ priv->mclk = devm_clk_get(dev, "mclk"); ++ if (IS_ERR(priv->mclk)) { ++ if (PTR_ERR(priv->mclk) != -EPROBE_DEFER) ++ dev_err(dev, "failed to get the i2s master clock\n"); ++ return PTR_ERR(priv->mclk); ++ } ++ ++ return devm_snd_soc_register_component(dev, &meson_i2s_dai_component, ++ &meson_i2s_dai, 1); ++} ++ ++static const struct of_device_id meson_i2s_dai_of_match[] = { ++ { .compatible = "amlogic,meson-i2s-dai", }, ++ { .compatible = "amlogic,meson-gxbb-i2s-dai", }, ++ { .compatible = "amlogic,meson-gxl-i2s-dai", }, ++ {} ++}; ++MODULE_DEVICE_TABLE(of, meson_i2s_dai_of_match); ++ ++static struct platform_driver meson_i2s_dai_pdrv = { ++ .probe = meson_i2s_dai_probe, ++ .driver = { ++ .name = DRV_NAME, ++ .of_match_table = meson_i2s_dai_of_match, ++ }, ++}; ++module_platform_driver(meson_i2s_dai_pdrv); ++ ++MODULE_DESCRIPTION("Meson i2s DAI ASoC Driver"); ++MODULE_AUTHOR("Jerome Brunet "); ++MODULE_LICENSE("GPL v2"); +-- +1.9.1 + diff --git a/patch/kernel/odroidc2-next/0030-drm-bridge-dw-hdmi-fix-building-without-CONFIG_OF.patch b/patch/kernel/odroidc2-next/0030-drm-bridge-dw-hdmi-fix-building-without-CONFIG_OF.patch deleted file mode 100644 index aba51e948..000000000 --- a/patch/kernel/odroidc2-next/0030-drm-bridge-dw-hdmi-fix-building-without-CONFIG_OF.patch +++ /dev/null @@ -1,40 +0,0 @@ -From e9b6ad390a468f272176a6ceb103d63a46094be4 Mon Sep 17 00:00:00 2001 -From: Arnd Bergmann -Date: Mon, 23 Jan 2017 13:20:38 +0100 -Subject: [PATCH 30/93] drm: bridge: dw-hdmi: fix building without CONFIG_OF - -The of_node member in struct drm_bridge is hidden when CONFIG_OF -is disabled, causing a build error: - -drivers/gpu/drm/bridge/dw-hdmi.c: In function '__dw_hdmi_probe': -drivers/gpu/drm/bridge/dw-hdmi.c:2063:14: error: 'struct drm_bridge' has no member named 'of_node' - -We could fix this either using a Kconfig dependency on CONFIG_OF -or making the one line conditional. The latter gives us better -compile test coverage, so this is what I'm doing here. - -Fixes: 69497eb9234e ("drm: bridge: dw-hdmi: Implement DRM bridge registration") -Signed-off-by: Arnd Bergmann -Signed-off-by: Archit Taneja -Link: http://patchwork.freedesktop.org/patch/msgid/20170123122312.3290934-1-arnd@arndb.de ---- - drivers/gpu/drm/bridge/dw-hdmi.c | 2 ++ - 1 file changed, 2 insertions(+) - -diff --git a/drivers/gpu/drm/bridge/dw-hdmi.c b/drivers/gpu/drm/bridge/dw-hdmi.c -index 4fda071..9a9ec27 100644 ---- a/drivers/gpu/drm/bridge/dw-hdmi.c -+++ b/drivers/gpu/drm/bridge/dw-hdmi.c -@@ -2060,7 +2060,9 @@ static int dw_hdmi_detect_phy(struct dw_hdmi *hdmi) - - hdmi->bridge.driver_private = hdmi; - hdmi->bridge.funcs = &dw_hdmi_bridge_funcs; -+#ifdef CONFIG_OF - hdmi->bridge.of_node = pdev->dev.of_node; -+#endif - - ret = dw_hdmi_fb_registered(hdmi); - if (ret) --- -1.9.1 - diff --git a/patch/kernel/odroidc2-next/0031-ASoC-meson-add-aiu-spdif-dma-support.patch b/patch/kernel/odroidc2-next/0031-ASoC-meson-add-aiu-spdif-dma-support.patch new file mode 100644 index 000000000..9f32e4e8f --- /dev/null +++ b/patch/kernel/odroidc2-next/0031-ASoC-meson-add-aiu-spdif-dma-support.patch @@ -0,0 +1,439 @@ +From e3ad81320cb0d2282f7a31bceab130bf4105a711 Mon Sep 17 00:00:00 2001 +From: Jerome Brunet +Date: Thu, 30 Mar 2017 13:43:52 +0200 +Subject: [PATCH 31/79] ASoC: meson: add aiu spdif dma support + +Add support for the spdif output dma which is part of the AIU block + +Signed-off-by: Jerome Brunet +Signed-off-by: Neil Armstrong +--- + sound/soc/meson/Kconfig | 7 + + sound/soc/meson/Makefile | 2 + + sound/soc/meson/aiu-spdif-dma.c | 385 ++++++++++++++++++++++++++++++++++++++++ + 3 files changed, 394 insertions(+) + create mode 100644 sound/soc/meson/aiu-spdif-dma.c + +diff --git a/sound/soc/meson/Kconfig b/sound/soc/meson/Kconfig +index 604c9e2..8af3258 100644 +--- a/sound/soc/meson/Kconfig ++++ b/sound/soc/meson/Kconfig +@@ -14,3 +14,10 @@ config SND_SOC_MESON_I2S + help + Say Y or M if you want to add support for i2s driver for Amlogic + Meson SoCs. ++ ++config SND_SOC_MESON_SPDIF ++ tristate "Meson spdif interface" ++ depends on SND_SOC_MESON ++ help ++ Say Y or M if you want to add support for spdif dma driver for Amlogic ++ Meson SoCs. +diff --git a/sound/soc/meson/Makefile b/sound/soc/meson/Makefile +index ea06dde..cef9a9d 100644 +--- a/sound/soc/meson/Makefile ++++ b/sound/soc/meson/Makefile +@@ -1,7 +1,9 @@ + snd-soc-meson-audio-core-objs := audio-core.o + snd-soc-meson-aiu-i2s-dma-objs := aiu-i2s-dma.o ++snd-soc-meson-aiu-spdif-dma-objs := aiu-spdif-dma.o + snd-soc-meson-i2s-dai-objs := i2s-dai.o + + obj-$(CONFIG_SND_SOC_MESON) += snd-soc-meson-audio-core.o + obj-$(CONFIG_SND_SOC_MESON_I2S) += snd-soc-meson-aiu-i2s-dma.o + obj-$(CONFIG_SND_SOC_MESON_I2S) += snd-soc-meson-i2s-dai.o ++obj-$(CONFIG_SND_SOC_MESON_SPDIF) += snd-soc-meson-aiu-spdif-dma.o +diff --git a/sound/soc/meson/aiu-spdif-dma.c b/sound/soc/meson/aiu-spdif-dma.c +new file mode 100644 +index 0000000..e3ff74b +--- /dev/null ++++ b/sound/soc/meson/aiu-spdif-dma.c +@@ -0,0 +1,385 @@ ++/* ++ * Copyright (C) 2017 BayLibre, SAS ++ * Author: Jerome Brunet ++ * Copyright (C) 2017 Amlogic, Inc. All rights reserved. ++ * ++ * This program is free software; you can redistribute it and/or ++ * modify it under the terms of the GNU General Public License as ++ * published by the Free Software Foundation; either version 2 of the ++ * License, or (at your option) any later version. ++ * ++ * This program is distributed in the hope that it will be useful, but ++ * WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ * General Public License for more details. ++ * ++ * You should have received a copy of the GNU General Public License ++ * along with this program; if not, see . ++ */ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#include ++#include ++ ++#include "aiu-regs.h" ++#include "audio-core.h" ++ ++#define DRV_NAME "meson-aiu-spdif-dma" ++ ++struct aiu_spdif_dma { ++ struct meson_audio_core_data *core; ++ struct clk *fast; ++ int irq; ++}; ++ ++#define AIU_958_DCU_FF_CTRL_EN BIT(0) ++#define AIU_958_DCU_FF_CTRL_AUTO_DISABLE BIT(1) ++#define AIU_958_DCU_FF_CTRL_IRQ_MODE_MASK GENMASK(3, 2) ++#define AIU_958_DCU_FF_CTRL_IRQ_OUT_THD BIT(2) ++#define AIU_958_DCU_FF_CTRL_IRQ_FRAME_READ BIT(3) ++#define AIU_958_DCU_FF_CTRL_SYNC_HEAD_EN BIT(4) ++#define AIU_958_DCU_FF_CTRL_BYTE_SEEK BIT(5) ++#define AIU_958_DCU_FF_CTRL_CONTINUE BIT(6) ++#define AIU_MEM_IEC958_BUF_CNTL_INIT BIT(0) ++#define AIU_MEM_IEC958_CONTROL_INIT BIT(0) ++#define AIU_MEM_IEC958_CONTROL_FILL_EN BIT(1) ++#define AIU_MEM_IEC958_CONTROL_EMPTY_EN BIT(2) ++#define AIU_MEM_IEC958_CONTROL_ENDIAN_MASK GENMASK(5, 3) ++#define AIU_MEM_IEC958_CONTROL_RD_DDR BIT(6) ++#define AIU_MEM_IEC958_CONTROL_MODE_16BIT BIT(7) ++#define AIU_MEM_IEC958_MASKS_CH_MEM_MASK GENMASK(15, 8) ++#define AIU_MEM_IEC958_MASKS_CH_MEM(ch) ((ch) << 8) ++#define AIU_MEM_IEC958_MASKS_CH_RD_MASK GENMASK(7, 0) ++#define AIU_MEM_IEC958_MASKS_CH_RD(ch) ((ch) << 0) ++ ++#define AIU_SPDIF_DMA_BURST 8 ++#define AIU_SPDIF_BPF_MAX USHRT_MAX ++ ++static struct snd_pcm_hardware aiu_spdif_dma_hw = { ++ .info = (SNDRV_PCM_INFO_INTERLEAVED | ++ SNDRV_PCM_INFO_MMAP | ++ SNDRV_PCM_INFO_MMAP_VALID | ++ SNDRV_PCM_INFO_PAUSE), ++ ++ .formats = (SNDRV_PCM_FMTBIT_S16_LE | ++ SNDRV_PCM_FMTBIT_S24_LE | ++ SNDRV_PCM_FMTBIT_S32_LE), ++ ++ .rates = (SNDRV_PCM_RATE_32000 | ++ SNDRV_PCM_RATE_44100 | ++ SNDRV_PCM_RATE_48000 | ++ SNDRV_PCM_RATE_96000 | ++ SNDRV_PCM_RATE_192000), ++ /* ++ * TODO: The DMA can change the endianness, the msb position ++ * and deal with unsigned - support this later on ++ */ ++ ++ .channels_min = 2, ++ .channels_max = 2, ++ .period_bytes_min = AIU_SPDIF_DMA_BURST, ++ .period_bytes_max = AIU_SPDIF_BPF_MAX, ++ .periods_min = 2, ++ .periods_max = UINT_MAX, ++ .buffer_bytes_max = 1 * 1024 * 1024, ++ .fifo_size = 0, ++}; ++ ++static struct aiu_spdif_dma *aiu_spdif_dma_priv(struct snd_pcm_substream *s) ++{ ++ struct snd_soc_pcm_runtime *rtd = s->private_data; ++ ++ return snd_soc_platform_get_drvdata(rtd->platform); ++} ++ ++static snd_pcm_uframes_t ++aiu_spdif_dma_pointer(struct snd_pcm_substream *substream) ++{ ++ struct snd_pcm_runtime *runtime = substream->runtime; ++ struct aiu_spdif_dma *priv = aiu_spdif_dma_priv(substream); ++ unsigned int addr; ++ int ret; ++ ++ ret = regmap_read(priv->core->aiu, AIU_MEM_IEC958_RD_PTR, ++ &addr); ++ if (ret) ++ return 0; ++ ++ return bytes_to_frames(runtime, addr - (unsigned int)runtime->dma_addr); ++} ++ ++static void __dma_enable(struct aiu_spdif_dma *priv, bool enable) ++{ ++ unsigned int en_mask = (AIU_MEM_IEC958_CONTROL_FILL_EN | ++ AIU_MEM_IEC958_CONTROL_EMPTY_EN); ++ ++ regmap_update_bits(priv->core->aiu, AIU_MEM_IEC958_CONTROL, en_mask, ++ enable ? en_mask : 0); ++} ++ ++static void __dcu_fifo_enable(struct aiu_spdif_dma *priv, bool enable) ++{ ++ regmap_update_bits(priv->core->aiu, AIU_958_DCU_FF_CTRL, ++ AIU_958_DCU_FF_CTRL_EN, ++ enable ? AIU_958_DCU_FF_CTRL_EN : 0); ++} ++ ++static int aiu_spdif_dma_trigger(struct snd_pcm_substream *substream, int cmd) ++{ ++ struct aiu_spdif_dma *priv = aiu_spdif_dma_priv(substream); ++ ++ switch (cmd) { ++ case SNDRV_PCM_TRIGGER_START: ++ case SNDRV_PCM_TRIGGER_RESUME: ++ case SNDRV_PCM_TRIGGER_PAUSE_RELEASE: ++ __dcu_fifo_enable(priv, true); ++ __dma_enable(priv, true); ++ break; ++ case SNDRV_PCM_TRIGGER_SUSPEND: ++ case SNDRV_PCM_TRIGGER_PAUSE_PUSH: ++ case SNDRV_PCM_TRIGGER_STOP: ++ __dma_enable(priv, false); ++ __dcu_fifo_enable(priv, false); ++ break; ++ default: ++ return -EINVAL; ++ } ++ ++ return 0; ++} ++ ++static void __dma_init_mem(struct aiu_spdif_dma *priv) ++{ ++ regmap_update_bits(priv->core->aiu, AIU_MEM_IEC958_CONTROL, ++ AIU_MEM_IEC958_CONTROL_INIT, ++ AIU_MEM_IEC958_CONTROL_INIT); ++ regmap_update_bits(priv->core->aiu, AIU_MEM_IEC958_BUF_CNTL, ++ AIU_MEM_IEC958_BUF_CNTL_INIT, ++ AIU_MEM_IEC958_BUF_CNTL_INIT); ++ ++ regmap_update_bits(priv->core->aiu, AIU_MEM_IEC958_CONTROL, ++ AIU_MEM_IEC958_CONTROL_INIT, ++ 0); ++ regmap_update_bits(priv->core->aiu, AIU_MEM_IEC958_BUF_CNTL, ++ AIU_MEM_IEC958_BUF_CNTL_INIT, ++ 0); ++} ++ ++static int aiu_spdif_dma_prepare(struct snd_pcm_substream *substream) ++{ ++ struct aiu_spdif_dma *priv = aiu_spdif_dma_priv(substream); ++ ++ __dma_init_mem(priv); ++ ++ return 0; ++} ++ ++static int __setup_memory_layout(struct aiu_spdif_dma *priv, ++ unsigned int width) ++{ ++ u32 mem_ctl = AIU_MEM_IEC958_CONTROL_RD_DDR; ++ ++ if (width == 16) ++ mem_ctl |= AIU_MEM_IEC958_CONTROL_MODE_16BIT; ++ ++ regmap_update_bits(priv->core->aiu, AIU_MEM_IEC958_CONTROL, ++ AIU_MEM_IEC958_CONTROL_ENDIAN_MASK | ++ AIU_MEM_IEC958_CONTROL_MODE_16BIT | ++ AIU_MEM_IEC958_CONTROL_RD_DDR, ++ mem_ctl); ++ ++ return 0; ++} ++ ++static int aiu_spdif_dma_hw_params(struct snd_pcm_substream *substream, ++ struct snd_pcm_hw_params *params) ++{ ++ struct snd_pcm_runtime *runtime = substream->runtime; ++ struct aiu_spdif_dma *priv = aiu_spdif_dma_priv(substream); ++ int ret; ++ dma_addr_t end_ptr; ++ ++ ret = snd_pcm_lib_malloc_pages(substream, params_buffer_bytes(params)); ++ if (ret < 0) ++ return ret; ++ ++ ret = __setup_memory_layout(priv, params_physical_width(params)); ++ if (ret) ++ return ret; ++ ++ /* Initialize memory pointers */ ++ regmap_write(priv->core->aiu, ++ AIU_MEM_IEC958_START_PTR, runtime->dma_addr); ++ regmap_write(priv->core->aiu, ++ AIU_MEM_IEC958_RD_PTR, runtime->dma_addr); ++ ++ /* The end pointer is the address of the last valid block */ ++ end_ptr = runtime->dma_addr + runtime->dma_bytes - AIU_SPDIF_DMA_BURST; ++ regmap_write(priv->core->aiu, AIU_MEM_IEC958_END_PTR, end_ptr); ++ ++ /* Memory masks */ ++ regmap_write(priv->core->aiu, AIU_MEM_IEC958_MASKS, ++ AIU_MEM_IEC958_MASKS_CH_RD(0xff) | ++ AIU_MEM_IEC958_MASKS_CH_MEM(0xff)); ++ ++ /* Setup the number bytes read by the FIFO between each IRQ */ ++ regmap_write(priv->core->aiu, AIU_958_BPF, params_period_bytes(params)); ++ ++ /* ++ * AUTO_DISABLE and SYNC_HEAD are enabled by default but ++ * this should be disabled in PCM (uncompressed) mode ++ */ ++ regmap_update_bits(priv->core->aiu, AIU_958_DCU_FF_CTRL, ++ AIU_958_DCU_FF_CTRL_AUTO_DISABLE | ++ AIU_958_DCU_FF_CTRL_IRQ_MODE_MASK | ++ AIU_958_DCU_FF_CTRL_SYNC_HEAD_EN, ++ AIU_958_DCU_FF_CTRL_IRQ_FRAME_READ); ++ ++ return 0; ++} ++ ++static int aiu_spdif_dma_hw_free(struct snd_pcm_substream *substream) ++{ ++ return snd_pcm_lib_free_pages(substream); ++} ++ ++static irqreturn_t aiu_spdif_dma_irq(int irq, void *dev_id) ++{ ++ struct snd_pcm_substream *playback = dev_id; ++ ++ snd_pcm_period_elapsed(playback); ++ ++ return IRQ_HANDLED; ++} ++ ++static int aiu_spdif_dma_open(struct snd_pcm_substream *substream) ++{ ++ struct aiu_spdif_dma *priv = aiu_spdif_dma_priv(substream); ++ int ret; ++ ++ snd_soc_set_runtime_hwparams(substream, &aiu_spdif_dma_hw); ++ ++ /* ++ * Make sure the buffer and period size are multiple of the DMA burst ++ * size ++ */ ++ ret = snd_pcm_hw_constraint_step(substream->runtime, 0, ++ SNDRV_PCM_HW_PARAM_BUFFER_BYTES, ++ AIU_SPDIF_DMA_BURST); ++ if (ret) ++ return ret; ++ ++ ret = snd_pcm_hw_constraint_step(substream->runtime, 0, ++ SNDRV_PCM_HW_PARAM_PERIOD_BYTES, ++ AIU_SPDIF_DMA_BURST); ++ if (ret) ++ return ret; ++ ++ /* Request the SPDIF DDR irq */ ++ ret = request_irq(priv->irq, aiu_spdif_dma_irq, 0, ++ DRV_NAME, substream); ++ if (ret) ++ return ret; ++ ++ /* Power up the spdif fast domain - can't write the register w/o it */ ++ ret = clk_prepare_enable(priv->fast); ++ if (ret) ++ return ret; ++ ++ /* Make sure the dma is initially halted */ ++ __dma_enable(priv, false); ++ __dcu_fifo_enable(priv, false); ++ ++ return 0; ++} ++ ++static int aiu_spdif_dma_close(struct snd_pcm_substream *substream) ++{ ++ struct aiu_spdif_dma *priv = aiu_spdif_dma_priv(substream); ++ ++ clk_disable_unprepare(priv->fast); ++ free_irq(priv->irq, substream); ++ ++ return 0; ++} ++ ++static const struct snd_pcm_ops aiu_spdif_dma_ops = { ++ .open = aiu_spdif_dma_open, ++ .close = aiu_spdif_dma_close, ++ .ioctl = snd_pcm_lib_ioctl, ++ .hw_params = aiu_spdif_dma_hw_params, ++ .hw_free = aiu_spdif_dma_hw_free, ++ .prepare = aiu_spdif_dma_prepare, ++ .pointer = aiu_spdif_dma_pointer, ++ .trigger = aiu_spdif_dma_trigger, ++}; ++ ++static int aiu_spdif_dma_new(struct snd_soc_pcm_runtime *rtd) ++{ ++ struct snd_card *card = rtd->card->snd_card; ++ size_t size = aiu_spdif_dma_hw.buffer_bytes_max; ++ ++ return snd_pcm_lib_preallocate_pages_for_all(rtd->pcm, ++ SNDRV_DMA_TYPE_DEV, ++ card->dev, size, size); ++} ++ ++struct snd_soc_platform_driver aiu_spdif_platform = { ++ .ops = &aiu_spdif_dma_ops, ++ .pcm_new = aiu_spdif_dma_new, ++}; ++ ++static int aiu_spdif_dma_probe(struct platform_device *pdev) ++{ ++ struct device *dev = &pdev->dev; ++ struct aiu_spdif_dma *priv; ++ ++ priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL); ++ if (!priv) ++ return -ENOMEM; ++ ++ platform_set_drvdata(pdev, priv); ++ priv->core = dev_get_drvdata(dev->parent); ++ ++ priv->fast = devm_clk_get(dev, "fast"); ++ if (IS_ERR(priv->fast)) { ++ if (PTR_ERR(priv->fast) != -EPROBE_DEFER) ++ dev_err(dev, "Can't get spdif fast domain clock\n"); ++ return PTR_ERR(priv->fast); ++ } ++ ++ priv->irq = platform_get_irq(pdev, 0); ++ if (priv->irq <= 0) { ++ dev_err(dev, "Can't get spdif ddr irq\n"); ++ return priv->irq; ++ } ++ ++ return snd_soc_register_platform(dev, &aiu_spdif_platform); ++} ++ ++static const struct of_device_id aiu_spdif_dma_of_match[] = { ++ { .compatible = "amlogic,meson-aiu-spdif-dma", }, ++ { .compatible = "amlogic,meson-gxbb-aiu-spdif-dma", }, ++ { .compatible = "amlogic,meson-gxl-aiu-spdif-dma", }, ++ {} ++}; ++MODULE_DEVICE_TABLE(of, aiu_spdif_dma_of_match); ++ ++static struct platform_driver aiu_spdif_dma_pdrv = { ++ .probe = aiu_spdif_dma_probe, ++ .driver = { ++ .name = DRV_NAME, ++ .of_match_table = aiu_spdif_dma_of_match, ++ }, ++}; ++module_platform_driver(aiu_spdif_dma_pdrv); ++ ++MODULE_DESCRIPTION("Meson AIU spdif DMA ASoC Driver"); ++MODULE_AUTHOR("Jerome Brunet "); ++MODULE_LICENSE("GPL"); +-- +1.9.1 + diff --git a/patch/kernel/odroidc2-next/0031-drm-bridge-dw-hdmi-Remove-unused-functions.patch b/patch/kernel/odroidc2-next/0031-drm-bridge-dw-hdmi-Remove-unused-functions.patch deleted file mode 100644 index 5497de79d..000000000 --- a/patch/kernel/odroidc2-next/0031-drm-bridge-dw-hdmi-Remove-unused-functions.patch +++ /dev/null @@ -1,57 +0,0 @@ -From 1ab78b07672b5e80bff302b1f2fab863a3107f2e Mon Sep 17 00:00:00 2001 -From: Laurent Pinchart -Date: Fri, 3 Mar 2017 19:19:58 +0200 -Subject: [PATCH 31/93] drm: bridge: dw-hdmi: Remove unused functions - -Most of the hdmi_phy_test_*() functions are unused. Remove them. - -Signed-off-by: Laurent Pinchart -Tested-by: Neil Armstrong -Reviewed-by: Jose Abreu -Tested-by: Nickey Yang -Signed-off-by: Archit Taneja -Link: http://patchwork.freedesktop.org/patch/msgid/20170303172007.26541-2-laurent.pinchart+renesas@ideasonboard.com ---- - drivers/gpu/drm/bridge/dw-hdmi.c | 26 -------------------------- - 1 file changed, 26 deletions(-) - -diff --git a/drivers/gpu/drm/bridge/dw-hdmi.c b/drivers/gpu/drm/bridge/dw-hdmi.c -index 9a9ec27..ce74963 100644 ---- a/drivers/gpu/drm/bridge/dw-hdmi.c -+++ b/drivers/gpu/drm/bridge/dw-hdmi.c -@@ -837,32 +837,6 @@ static inline void hdmi_phy_test_clear(struct dw_hdmi *hdmi, - HDMI_PHY_TST0_TSTCLR_MASK, HDMI_PHY_TST0); - } - --static inline void hdmi_phy_test_enable(struct dw_hdmi *hdmi, -- unsigned char bit) --{ -- hdmi_modb(hdmi, bit << HDMI_PHY_TST0_TSTEN_OFFSET, -- HDMI_PHY_TST0_TSTEN_MASK, HDMI_PHY_TST0); --} -- --static inline void hdmi_phy_test_clock(struct dw_hdmi *hdmi, -- unsigned char bit) --{ -- hdmi_modb(hdmi, bit << HDMI_PHY_TST0_TSTCLK_OFFSET, -- HDMI_PHY_TST0_TSTCLK_MASK, HDMI_PHY_TST0); --} -- --static inline void hdmi_phy_test_din(struct dw_hdmi *hdmi, -- unsigned char bit) --{ -- hdmi_writeb(hdmi, bit, HDMI_PHY_TST1); --} -- --static inline void hdmi_phy_test_dout(struct dw_hdmi *hdmi, -- unsigned char bit) --{ -- hdmi_writeb(hdmi, bit, HDMI_PHY_TST2); --} -- - static bool hdmi_phy_wait_i2c_done(struct dw_hdmi *hdmi, int msec) - { - u32 val; --- -1.9.1 - diff --git a/patch/kernel/odroidc2-next/0032-ASoC-meson-add-initial-spdif-dai-support.patch b/patch/kernel/odroidc2-next/0032-ASoC-meson-add-initial-spdif-dai-support.patch new file mode 100644 index 000000000..1664ead5f --- /dev/null +++ b/patch/kernel/odroidc2-next/0032-ASoC-meson-add-initial-spdif-dai-support.patch @@ -0,0 +1,430 @@ +From f526e3ef0f6b52f591d93f2a68f25dd6062b592c Mon Sep 17 00:00:00 2001 +From: Jerome Brunet +Date: Thu, 30 Mar 2017 13:46:03 +0200 +Subject: [PATCH 32/79] ASoC: meson: add initial spdif dai support + +Add support for the spdif dai found on Amlogic Meson SoC family. +With this initial implementation, only uncompressed pcm playback +from the spdif dma is supported. Future work will add compressed +support, pcm playback from i2s dma and capture. + +Signed-off-by: Jerome Brunet +Signed-off-by: Neil Armstrong +--- + sound/soc/meson/Kconfig | 3 +- + sound/soc/meson/Makefile | 2 + + sound/soc/meson/spdif-dai.c | 374 ++++++++++++++++++++++++++++++++++++++++++++ + 3 files changed, 378 insertions(+), 1 deletion(-) + create mode 100644 sound/soc/meson/spdif-dai.c + +diff --git a/sound/soc/meson/Kconfig b/sound/soc/meson/Kconfig +index 8af3258..92422e7 100644 +--- a/sound/soc/meson/Kconfig ++++ b/sound/soc/meson/Kconfig +@@ -18,6 +18,7 @@ config SND_SOC_MESON_I2S + config SND_SOC_MESON_SPDIF + tristate "Meson spdif interface" + depends on SND_SOC_MESON ++ select SND_PCM_IEC958 + help +- Say Y or M if you want to add support for spdif dma driver for Amlogic ++ Say Y or M if you want to add support for spdif driver for Amlogic + Meson SoCs. +diff --git a/sound/soc/meson/Makefile b/sound/soc/meson/Makefile +index cef9a9d..bc4391c 100644 +--- a/sound/soc/meson/Makefile ++++ b/sound/soc/meson/Makefile +@@ -2,8 +2,10 @@ snd-soc-meson-audio-core-objs := audio-core.o + snd-soc-meson-aiu-i2s-dma-objs := aiu-i2s-dma.o + snd-soc-meson-aiu-spdif-dma-objs := aiu-spdif-dma.o + snd-soc-meson-i2s-dai-objs := i2s-dai.o ++snd-soc-meson-spdif-dai-objs := spdif-dai.o + + obj-$(CONFIG_SND_SOC_MESON) += snd-soc-meson-audio-core.o + obj-$(CONFIG_SND_SOC_MESON_I2S) += snd-soc-meson-aiu-i2s-dma.o + obj-$(CONFIG_SND_SOC_MESON_I2S) += snd-soc-meson-i2s-dai.o + obj-$(CONFIG_SND_SOC_MESON_SPDIF) += snd-soc-meson-aiu-spdif-dma.o ++obj-$(CONFIG_SND_SOC_MESON_SPDIF) += snd-soc-meson-spdif-dai.o +diff --git a/sound/soc/meson/spdif-dai.c b/sound/soc/meson/spdif-dai.c +new file mode 100644 +index 0000000..e763000 +--- /dev/null ++++ b/sound/soc/meson/spdif-dai.c +@@ -0,0 +1,374 @@ ++/* ++ * Copyright (C) 2017 BayLibre, SAS ++ * Author: Jerome Brunet ++ * Copyright (C) 2017 Amlogic, Inc. All rights reserved. ++ * ++ * This program is free software; you can redistribute it and/or ++ * modify it under the terms of the GNU General Public License as ++ * published by the Free Software Foundation; either version 2 of the ++ * License, or (at your option) any later version. ++ * ++ * This program is distributed in the hope that it will be useful, but ++ * WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ * General Public License for more details. ++ * ++ * You should have received a copy of the GNU General Public License ++ * along with this program; if not, see . ++ */ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#include ++#include ++#include ++#include ++ ++#include "aiu-regs.h" ++#include "audio-core.h" ++ ++#define DRV_NAME "meson-spdif-dai" ++ ++struct meson_spdif_dai { ++ struct meson_audio_core_data *core; ++ struct clk *iface; ++ struct clk *fast; ++ struct clk *mclk_i958; ++ struct clk *mclk; ++}; ++ ++#define AIU_CLK_CTRL_958_DIV_EN BIT(1) ++#define AIU_CLK_CTRL_958_DIV_MASK GENMASK(5, 4) ++#define AIU_CLK_CTRL_958_DIV_MORE BIT(12) ++#define AIU_MEM_IEC958_CONTROL_MODE_LINEAR BIT(8) ++#define AIU_958_CTRL_HOLD_EN BIT(0) ++#define AIU_958_MISC_NON_PCM BIT(0) ++#define AIU_958_MISC_MODE_16BITS BIT(1) ++#define AIU_958_MISC_16BITS_ALIGN_MASK GENMASK(6, 5) ++#define AIU_958_MISC_16BITS_ALIGN(val) ((val) << 5) ++#define AIU_958_MISC_MODE_32BITS BIT(7) ++#define AIU_958_MISC_32BITS_SHIFT_MASK GENMASK(10, 8) ++#define AIU_958_MISC_32BITS_SHIFT(val) ((val) << 8) ++#define AIU_958_MISC_U_FROM_STREAM BIT(12) ++#define AIU_958_MISC_FORCE_LR BIT(13) ++ ++#define AIU_CS_WORD_LEN 4 ++ ++static void __hold(struct meson_spdif_dai *priv, bool enable) ++{ ++ regmap_update_bits(priv->core->aiu, AIU_958_CTRL, ++ AIU_958_CTRL_HOLD_EN, ++ enable ? AIU_958_CTRL_HOLD_EN : 0); ++} ++ ++static void __divider_enable(struct meson_spdif_dai *priv, bool enable) ++{ ++ regmap_update_bits(priv->core->aiu, AIU_CLK_CTRL, ++ AIU_CLK_CTRL_958_DIV_EN, ++ enable ? AIU_CLK_CTRL_958_DIV_EN : 0); ++} ++ ++static void __playback_start(struct meson_spdif_dai *priv) ++{ ++ __divider_enable(priv, true); ++ __hold(priv, false); ++} ++ ++static void __playback_stop(struct meson_spdif_dai *priv) ++{ ++ __hold(priv, true); ++ __divider_enable(priv, false); ++} ++ ++static int meson_spdif_dai_trigger(struct snd_pcm_substream *substream, int cmd, ++ struct snd_soc_dai *dai) ++{ ++ struct meson_spdif_dai *priv = snd_soc_dai_get_drvdata(dai); ++ ++ switch (cmd) { ++ case SNDRV_PCM_TRIGGER_START: ++ case SNDRV_PCM_TRIGGER_RESUME: ++ case SNDRV_PCM_TRIGGER_PAUSE_RELEASE: ++ __playback_start(priv); ++ return 0; ++ ++ case SNDRV_PCM_TRIGGER_STOP: ++ case SNDRV_PCM_TRIGGER_SUSPEND: ++ case SNDRV_PCM_TRIGGER_PAUSE_PUSH: ++ __playback_stop(priv); ++ return 0; ++ ++ default: ++ return -EINVAL; ++ } ++} ++ ++static int __setup_spdif_clk(struct meson_spdif_dai *priv, unsigned int rate) ++{ ++ unsigned int mrate; ++ ++ /* Leave the internal divisor alone */ ++ regmap_update_bits(priv->core->aiu, AIU_CLK_CTRL, ++ AIU_CLK_CTRL_958_DIV_MASK | ++ AIU_CLK_CTRL_958_DIV_MORE, ++ 0); ++ ++ /* 2 * 32bits per subframe * 2 channels = 128 */ ++ mrate = rate * 128; ++ return clk_set_rate(priv->mclk, mrate); ++} ++ ++static int __setup_cs_word(struct meson_spdif_dai *priv, ++ struct snd_pcm_hw_params *params) ++{ ++ u8 cs[AIU_CS_WORD_LEN]; ++ u32 val; ++ int ret; ++ ++ ret = snd_pcm_create_iec958_consumer_hw_params(params, cs, ++ AIU_CS_WORD_LEN); ++ if (ret < 0) ++ return -EINVAL; ++ ++ /* Write the 1st half word */ ++ val = cs[1] | cs[0] << 8; ++ regmap_write(priv->core->aiu, AIU_958_CHSTAT_L0, val); ++ regmap_write(priv->core->aiu, AIU_958_CHSTAT_R0, val); ++ ++ /* Write the 2nd half word */ ++ val = cs[3] | cs[2] << 8; ++ regmap_write(priv->core->aiu, AIU_958_CHSTAT_L1, val); ++ regmap_write(priv->core->aiu, AIU_958_CHSTAT_R1, val); ++ ++ return 0; ++} ++ ++static int __setup_pcm_fmt(struct meson_spdif_dai *priv, ++ unsigned int width) ++{ ++ u32 val = 0; ++ ++ switch (width) { ++ case 16: ++ val |= AIU_958_MISC_MODE_16BITS; ++ val |= AIU_958_MISC_16BITS_ALIGN(2); ++ break; ++ case 32: ++ case 24: ++ /* ++ * Looks like this should only be set for 32bits mode, but the ++ * vendor kernel sets it like this for 24bits as well, let's ++ * try and see ++ */ ++ val |= AIU_958_MISC_MODE_32BITS; ++ break; ++ default: ++ return -EINVAL; ++ } ++ ++ /* No idea what this actually does, copying the vendor kernel for now */ ++ val |= AIU_958_MISC_FORCE_LR; ++ val |= AIU_958_MISC_U_FROM_STREAM; ++ ++ regmap_update_bits(priv->core->aiu, AIU_958_MISC, ++ AIU_958_MISC_NON_PCM | ++ AIU_958_MISC_MODE_16BITS | ++ AIU_958_MISC_16BITS_ALIGN_MASK | ++ AIU_958_MISC_MODE_32BITS | ++ AIU_958_MISC_FORCE_LR, ++ val); ++ ++ return 0; ++} ++ ++static int meson_spdif_dai_hw_params(struct snd_pcm_substream *substream, ++ struct snd_pcm_hw_params *params, ++ struct snd_soc_dai *dai) ++{ ++ struct meson_spdif_dai *priv = snd_soc_dai_get_drvdata(dai); ++ int ret; ++ ++ ret = __setup_spdif_clk(priv, params_rate(params)); ++ if (ret) { ++ dev_err(dai->dev, "Unable to set the spdif clock\n"); ++ return ret; ++ } ++ ++ ret = __setup_cs_word(priv, params); ++ if (ret) { ++ dev_err(dai->dev, "Unable to set the channel status word\n"); ++ return ret; ++ } ++ ++ ret = __setup_pcm_fmt(priv, params_width(params)); ++ if (ret) { ++ dev_err(dai->dev, "Unable to set the pcm format\n"); ++ return ret; ++ } ++ ++ return 0; ++} ++ ++static int meson_spdif_dai_startup(struct snd_pcm_substream *substream, ++ struct snd_soc_dai *dai) ++{ ++ struct meson_spdif_dai *priv = snd_soc_dai_get_drvdata(dai); ++ int ret; ++ ++ /* Power up the spdif fast domain - can't write the registers w/o it */ ++ ret = clk_prepare_enable(priv->fast); ++ if (ret) ++ goto out_clk_fast; ++ ++ /* Make sure nothing gets out of the DAI yet*/ ++ __hold(priv, true); ++ ++ ret = clk_set_parent(priv->mclk, priv->mclk_i958); ++ if (ret) ++ return ret; ++ ++ /* Enable the clock gate */ ++ ret = clk_prepare_enable(priv->iface); ++ if (ret) ++ goto out_clk_iface; ++ ++ /* Enable the spdif clock */ ++ ret = clk_prepare_enable(priv->mclk); ++ if (ret) ++ goto out_mclk; ++ ++ /* ++ * Make sure the interface expect a memory layout we can work with ++ * MEM prefixed register usually belong to the DMA, but when the spdif ++ * DAI takes data from the i2s buffer, we need to make sure it works in ++ * split mode and not the "normal mode" (channel samples packed in ++ * 32 bytes groups) ++ */ ++ regmap_update_bits(priv->core->aiu, AIU_MEM_IEC958_CONTROL, ++ AIU_MEM_IEC958_CONTROL_MODE_LINEAR, ++ AIU_MEM_IEC958_CONTROL_MODE_LINEAR); ++ ++ return 0; ++ ++out_mclk: ++ clk_disable_unprepare(priv->iface); ++out_clk_iface: ++ clk_disable_unprepare(priv->fast); ++out_clk_fast: ++ return ret; ++} ++ ++static void meson_spdif_dai_shutdown(struct snd_pcm_substream *substream, ++ struct snd_soc_dai *dai) ++{ ++ struct meson_spdif_dai *priv = snd_soc_dai_get_drvdata(dai); ++ ++ clk_disable_unprepare(priv->iface); ++ clk_disable_unprepare(priv->mclk); ++ clk_disable_unprepare(priv->fast); ++} ++ ++static const struct snd_soc_dai_ops meson_spdif_dai_ops = { ++ .startup = meson_spdif_dai_startup, ++ .shutdown = meson_spdif_dai_shutdown, ++ .trigger = meson_spdif_dai_trigger, ++ .hw_params = meson_spdif_dai_hw_params, ++}; ++ ++static struct snd_soc_dai_driver meson_spdif_dai = { ++ .playback = { ++ .stream_name = "Playback", ++ .channels_min = 2, ++ .channels_max = 2, ++ .rates = (SNDRV_PCM_RATE_32000 | ++ SNDRV_PCM_RATE_44100 | ++ SNDRV_PCM_RATE_48000 | ++ SNDRV_PCM_RATE_96000 | ++ SNDRV_PCM_RATE_192000), ++ .formats = (SNDRV_PCM_FMTBIT_S16_LE | ++ SNDRV_PCM_FMTBIT_S24_LE) ++ }, ++ .ops = &meson_spdif_dai_ops, ++}; ++ ++static const struct snd_soc_component_driver meson_spdif_dai_component = { ++ .name = DRV_NAME, ++}; ++ ++static int meson_spdif_dai_probe(struct platform_device *pdev) ++{ ++ struct device *dev = &pdev->dev; ++ struct meson_spdif_dai *priv; ++ ++ priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL); ++ if (!priv) ++ return -ENOMEM; ++ ++ platform_set_drvdata(pdev, priv); ++ priv->core = dev_get_drvdata(dev->parent); ++ ++ priv->fast = devm_clk_get(dev, "fast"); ++ if (IS_ERR(priv->fast)) { ++ if (PTR_ERR(priv->fast) != -EPROBE_DEFER) ++ dev_err(dev, "Can't get spdif fast domain clockt\n"); ++ return PTR_ERR(priv->fast); ++ } ++ ++ priv->iface = devm_clk_get(dev, "iface"); ++ if (IS_ERR(priv->iface)) { ++ if (PTR_ERR(priv->iface) != -EPROBE_DEFER) ++ dev_err(dev, ++ "Can't get the dai clock gate\n"); ++ return PTR_ERR(priv->iface); ++ } ++ ++ priv->mclk_i958 = devm_clk_get(dev, "mclk_i958"); ++ if (IS_ERR(priv->mclk_i958)) { ++ if (PTR_ERR(priv->mclk_i958) != -EPROBE_DEFER) ++ dev_err(dev, "Can't get the spdif master clock\n"); ++ return PTR_ERR(priv->mclk_i958); ++ } ++ ++ /* ++ * TODO: the spdif dai can also get its data from the i2s fifo. ++ * For this use-case, the DAI driver will need to get the i2s master ++ * clock in order to reparent the spdif clock from cts_mclk_i958 to ++ * cts_amclk ++ */ ++ ++ priv->mclk = devm_clk_get(dev, "mclk"); ++ if (IS_ERR(priv->mclk)) { ++ if (PTR_ERR(priv->mclk) != -EPROBE_DEFER) ++ dev_err(dev, "Can't get the spdif input mux clock\n"); ++ return PTR_ERR(priv->mclk); ++ } ++ ++ return devm_snd_soc_register_component(dev, &meson_spdif_dai_component, ++ &meson_spdif_dai, 1); ++} ++ ++static const struct of_device_id meson_spdif_dai_of_match[] = { ++ { .compatible = "amlogic,meson-spdif-dai", }, ++ { .compatible = "amlogic,meson-gxbb-spdif-dai", }, ++ { .compatible = "amlogic,meson-gxl-spdif-dai", }, ++ {} ++}; ++MODULE_DEVICE_TABLE(of, meson_spdif_dai_of_match); ++ ++static struct platform_driver meson_spdif_dai_pdrv = { ++ .probe = meson_spdif_dai_probe, ++ .driver = { ++ .name = DRV_NAME, ++ .of_match_table = meson_spdif_dai_of_match, ++ }, ++}; ++module_platform_driver(meson_spdif_dai_pdrv); ++ ++MODULE_DESCRIPTION("Meson spdif DAI ASoC Driver"); ++MODULE_AUTHOR("Jerome Brunet "); ++MODULE_LICENSE("GPL v2"); +-- +1.9.1 + diff --git a/patch/kernel/odroidc2-next/0032-drm-bridge-dw-hdmi-Move-CSC-configuration-out-of-PHY.patch b/patch/kernel/odroidc2-next/0032-drm-bridge-dw-hdmi-Move-CSC-configuration-out-of-PHY.patch deleted file mode 100644 index c8d278982..000000000 --- a/patch/kernel/odroidc2-next/0032-drm-bridge-dw-hdmi-Move-CSC-configuration-out-of-PHY.patch +++ /dev/null @@ -1,85 +0,0 @@ -From 83ea2ac12ecbd8d77aa2ac7c3effcdac8301ef26 Mon Sep 17 00:00:00 2001 -From: Laurent Pinchart -Date: Fri, 3 Mar 2017 19:19:59 +0200 -Subject: [PATCH 32/93] drm: bridge: dw-hdmi: Move CSC configuration out of PHY - code - -The color space converter isn't part of the PHY, move its configuration -out of PHY code. - -Signed-off-by: Laurent Pinchart -Tested-by: Neil Armstrong -Reviewed-by: Jose Abreu -Signed-off-by: Archit Taneja -Link: http://patchwork.freedesktop.org/patch/msgid/20170303172007.26541-3-laurent.pinchart+renesas@ideasonboard.com ---- - drivers/gpu/drm/bridge/dw-hdmi.c | 25 ++++++++++--------------- - 1 file changed, 10 insertions(+), 15 deletions(-) - -diff --git a/drivers/gpu/drm/bridge/dw-hdmi.c b/drivers/gpu/drm/bridge/dw-hdmi.c -index ce74963..906583b 100644 ---- a/drivers/gpu/drm/bridge/dw-hdmi.c -+++ b/drivers/gpu/drm/bridge/dw-hdmi.c -@@ -914,7 +914,7 @@ static void dw_hdmi_phy_sel_interface_control(struct dw_hdmi *hdmi, u8 enable) - HDMI_PHY_CONF0_SELDIPIF_MASK); - } - --static int hdmi_phy_configure(struct dw_hdmi *hdmi, int cscon) -+static int hdmi_phy_configure(struct dw_hdmi *hdmi) - { - u8 val, msec; - const struct dw_hdmi_plat_data *pdata = hdmi->plat_data; -@@ -946,14 +946,6 @@ static int hdmi_phy_configure(struct dw_hdmi *hdmi, int cscon) - return -EINVAL; - } - -- /* Enable csc path */ -- if (cscon) -- val = HDMI_MC_FLOWCTRL_FEED_THROUGH_OFF_CSC_IN_PATH; -- else -- val = HDMI_MC_FLOWCTRL_FEED_THROUGH_OFF_CSC_BYPASS; -- -- hdmi_writeb(hdmi, val, HDMI_MC_FLOWCTRL); -- - /* gen2 tx power off */ - dw_hdmi_phy_gen2_txpwron(hdmi, 0); - -@@ -1028,10 +1020,6 @@ static int hdmi_phy_configure(struct dw_hdmi *hdmi, int cscon) - static int dw_hdmi_phy_init(struct dw_hdmi *hdmi) - { - int i, ret; -- bool cscon; -- -- /*check csc whether needed activated in HDMI mode */ -- cscon = hdmi->sink_is_hdmi && is_color_space_conversion(hdmi); - - /* HDMI Phy spec says to do the phy initialization sequence twice */ - for (i = 0; i < 2; i++) { -@@ -1040,8 +1028,7 @@ static int dw_hdmi_phy_init(struct dw_hdmi *hdmi) - dw_hdmi_phy_enable_tmds(hdmi, 0); - dw_hdmi_phy_enable_powerdown(hdmi, true); - -- /* Enable CSC */ -- ret = hdmi_phy_configure(hdmi, cscon); -+ ret = hdmi_phy_configure(hdmi); - if (ret) - return ret; - } -@@ -1303,6 +1290,14 @@ static void dw_hdmi_enable_video_path(struct dw_hdmi *hdmi) - clkdis &= ~HDMI_MC_CLKDIS_CSCCLK_DISABLE; - hdmi_writeb(hdmi, clkdis, HDMI_MC_CLKDIS); - } -+ -+ /* Enable color space conversion if needed (for HDMI sinks only). */ -+ if (hdmi->sink_is_hdmi && is_color_space_conversion(hdmi)) -+ hdmi_writeb(hdmi, HDMI_MC_FLOWCTRL_FEED_THROUGH_OFF_CSC_IN_PATH, -+ HDMI_MC_FLOWCTRL); -+ else -+ hdmi_writeb(hdmi, HDMI_MC_FLOWCTRL_FEED_THROUGH_OFF_CSC_BYPASS, -+ HDMI_MC_FLOWCTRL); - } - - static void hdmi_enable_audio_clk(struct dw_hdmi *hdmi) --- -1.9.1 - diff --git a/patch/kernel/odroidc2-next/0033-ARM64-defconfig-enable-audio-support-for-meson-SoCs-.patch b/patch/kernel/odroidc2-next/0033-ARM64-defconfig-enable-audio-support-for-meson-SoCs-.patch new file mode 100644 index 000000000..1feee3642 --- /dev/null +++ b/patch/kernel/odroidc2-next/0033-ARM64-defconfig-enable-audio-support-for-meson-SoCs-.patch @@ -0,0 +1,33 @@ +From f0bd8f7b16c1d75d562e0731704e96efa6ea3966 Mon Sep 17 00:00:00 2001 +From: Jerome Brunet +Date: Fri, 31 Mar 2017 15:55:03 +0200 +Subject: [PATCH 33/79] ARM64: defconfig: enable audio support for meson SoCs + as module + +Add audio support for meson SoCs. This includes the audio core +driver and the i2s and spdif output interfaces + +Signed-off-by: Jerome Brunet +Signed-off-by: Neil Armstrong +--- + arch/arm64/configs/defconfig | 4 ++++ + 1 file changed, 4 insertions(+) + +diff --git a/arch/arm64/configs/defconfig b/arch/arm64/configs/defconfig +index 97c123e..cd4114f 100644 +--- a/arch/arm64/configs/defconfig ++++ b/arch/arm64/configs/defconfig +@@ -365,6 +365,10 @@ CONFIG_SOUND=y + CONFIG_SND=y + CONFIG_SND_SOC=y + CONFIG_SND_BCM2835_SOC_I2S=m ++CONFIG_SND_SOC_MESON=m ++CONFIG_SND_SOC_MESON_I2S=m ++CONFIG_SND_SOC_MESON_SPDIF=m ++CONFIG_SND_SOC_RCAR=y + CONFIG_SND_SOC_SAMSUNG=y + CONFIG_SND_SOC_RCAR=y + CONFIG_SND_SOC_AK4613=y +-- +1.9.1 + diff --git a/patch/kernel/odroidc2-next/0033-drm-bridge-dw-hdmi-Enable-CSC-even-for-DVI.patch b/patch/kernel/odroidc2-next/0033-drm-bridge-dw-hdmi-Enable-CSC-even-for-DVI.patch deleted file mode 100644 index ad7f73bf8..000000000 --- a/patch/kernel/odroidc2-next/0033-drm-bridge-dw-hdmi-Enable-CSC-even-for-DVI.patch +++ /dev/null @@ -1,37 +0,0 @@ -From 63411a28c0aad6f7df41c8d835d479d45ca35101 Mon Sep 17 00:00:00 2001 -From: Neil Armstrong -Date: Fri, 3 Mar 2017 19:20:00 +0200 -Subject: [PATCH 33/93] drm: bridge: dw-hdmi: Enable CSC even for DVI - -If the input pixel format is not RGB, the CSC must be enabled in order to -provide valid pixel to DVI sinks. -This patch removes the hdmi only dependency on the CSC enabling. - -Reviewed-by: Jose Abreu -Reviewed-by: Laurent Pinchart -Signed-off-by: Neil Armstrong -Tested-by: Neil Armstrong -Signed-off-by: Archit Taneja -Link: http://patchwork.freedesktop.org/patch/msgid/20170303172007.26541-4-laurent.pinchart+renesas@ideasonboard.com ---- - drivers/gpu/drm/bridge/dw-hdmi.c | 4 ++-- - 1 file changed, 2 insertions(+), 2 deletions(-) - -diff --git a/drivers/gpu/drm/bridge/dw-hdmi.c b/drivers/gpu/drm/bridge/dw-hdmi.c -index 906583b..d863b33 100644 ---- a/drivers/gpu/drm/bridge/dw-hdmi.c -+++ b/drivers/gpu/drm/bridge/dw-hdmi.c -@@ -1291,8 +1291,8 @@ static void dw_hdmi_enable_video_path(struct dw_hdmi *hdmi) - hdmi_writeb(hdmi, clkdis, HDMI_MC_CLKDIS); - } - -- /* Enable color space conversion if needed (for HDMI sinks only). */ -- if (hdmi->sink_is_hdmi && is_color_space_conversion(hdmi)) -+ /* Enable color space conversion if needed */ -+ if (is_color_space_conversion(hdmi)) - hdmi_writeb(hdmi, HDMI_MC_FLOWCTRL_FEED_THROUGH_OFF_CSC_IN_PATH, - HDMI_MC_FLOWCTRL); - else --- -1.9.1 - diff --git a/patch/kernel/odroidc2-next/0034-ARM64-defconfig-enable-CONFIG_SND_SOC_ES7134-as-modu.patch b/patch/kernel/odroidc2-next/0034-ARM64-defconfig-enable-CONFIG_SND_SOC_ES7134-as-modu.patch new file mode 100644 index 000000000..99c6c64f1 --- /dev/null +++ b/patch/kernel/odroidc2-next/0034-ARM64-defconfig-enable-CONFIG_SND_SOC_ES7134-as-modu.patch @@ -0,0 +1,27 @@ +From 25b66766a7ebe95b2f083f27a808997d8438842c Mon Sep 17 00:00:00 2001 +From: Jerome Brunet +Date: Fri, 31 Mar 2017 15:52:11 +0200 +Subject: [PATCH 34/79] ARM64: defconfig: enable CONFIG_SND_SOC_ES7134 as + module + +Signed-off-by: Jerome Brunet +Signed-off-by: Neil Armstrong +--- + arch/arm64/configs/defconfig | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/arch/arm64/configs/defconfig b/arch/arm64/configs/defconfig +index cd4114f..21f519d 100644 +--- a/arch/arm64/configs/defconfig ++++ b/arch/arm64/configs/defconfig +@@ -372,6 +372,7 @@ CONFIG_SND_SOC_RCAR=y + CONFIG_SND_SOC_SAMSUNG=y + CONFIG_SND_SOC_RCAR=y + CONFIG_SND_SOC_AK4613=y ++CONFIG_SND_SOC_ES7134=m + CONFIG_USB=y + CONFIG_USB_OTG=y + CONFIG_USB_XHCI_HCD=y +-- +1.9.1 + diff --git a/patch/kernel/odroidc2-next/0034-drm-bridge-dw-hdmi-Fix-the-PHY-power-down-sequence.patch b/patch/kernel/odroidc2-next/0034-drm-bridge-dw-hdmi-Fix-the-PHY-power-down-sequence.patch deleted file mode 100644 index 99be9c427..000000000 --- a/patch/kernel/odroidc2-next/0034-drm-bridge-dw-hdmi-Fix-the-PHY-power-down-sequence.patch +++ /dev/null @@ -1,150 +0,0 @@ -From 4910824c44da97e1e8f1b934e75d0d40aaabaddc Mon Sep 17 00:00:00 2001 -From: Laurent Pinchart -Date: Mon, 6 Mar 2017 01:35:39 +0200 -Subject: [PATCH 34/93] drm: bridge: dw-hdmi: Fix the PHY power down sequence - -The PHY requires us to wait for the PHY to switch to low power mode -after deasserting TXPWRON and before asserting PDDQ in the power down -sequence, otherwise power down will fail. - -The PHY power down can be monitored though the TX_READY bit, available -through I2C in the PHY registers, or the TX_PHY_LOCK bit, available -through the HDMI TX registers. As the two are equivalent, let's pick the -easier solution of polling the TX_PHY_LOCK bit. - -The power down code is currently duplicated in multiple places. To avoid -spreading multiple calls to a TX_PHY_LOCK poll function, we have to -refactor the power down code and group it all in a single function. - -Tests showed that one poll iteration was enough for TX_PHY_LOCK to -become low, without requiring any additional delay. Retrying the read -five times with a 1ms to 2ms delay between each attempt should thus be -more than enough. - -Signed-off-by: Laurent Pinchart -Tested-by: Neil Armstrong -Reviewed-by: Jose Abreu -Signed-off-by: Archit Taneja -Link: http://patchwork.freedesktop.org/patch/msgid/20170305233539.11898-1-laurent.pinchart+renesas@ideasonboard.com ---- - drivers/gpu/drm/bridge/dw-hdmi.c | 52 +++++++++++++++++++++++++++++++++------- - 1 file changed, 43 insertions(+), 9 deletions(-) - -diff --git a/drivers/gpu/drm/bridge/dw-hdmi.c b/drivers/gpu/drm/bridge/dw-hdmi.c -index d863b33..3a1cd4c 100644 ---- a/drivers/gpu/drm/bridge/dw-hdmi.c -+++ b/drivers/gpu/drm/bridge/dw-hdmi.c -@@ -116,6 +116,7 @@ struct dw_hdmi_i2c { - struct dw_hdmi_phy_data { - enum dw_hdmi_phy_type type; - const char *name; -+ unsigned int gen; - bool has_svsret; - }; - -@@ -914,6 +915,40 @@ static void dw_hdmi_phy_sel_interface_control(struct dw_hdmi *hdmi, u8 enable) - HDMI_PHY_CONF0_SELDIPIF_MASK); - } - -+static void dw_hdmi_phy_power_off(struct dw_hdmi *hdmi) -+{ -+ const struct dw_hdmi_phy_data *phy = hdmi->phy; -+ unsigned int i; -+ u16 val; -+ -+ if (phy->gen == 1) { -+ dw_hdmi_phy_enable_tmds(hdmi, 0); -+ dw_hdmi_phy_enable_powerdown(hdmi, true); -+ return; -+ } -+ -+ dw_hdmi_phy_gen2_txpwron(hdmi, 0); -+ -+ /* -+ * Wait for TX_PHY_LOCK to be deasserted to indicate that the PHY went -+ * to low power mode. -+ */ -+ for (i = 0; i < 5; ++i) { -+ val = hdmi_readb(hdmi, HDMI_PHY_STAT0); -+ if (!(val & HDMI_PHY_TX_PHY_LOCK)) -+ break; -+ -+ usleep_range(1000, 2000); -+ } -+ -+ if (val & HDMI_PHY_TX_PHY_LOCK) -+ dev_warn(hdmi->dev, "PHY failed to power down\n"); -+ else -+ dev_dbg(hdmi->dev, "PHY powered down in %u iterations\n", i); -+ -+ dw_hdmi_phy_gen2_pddq(hdmi, 1); -+} -+ - static int hdmi_phy_configure(struct dw_hdmi *hdmi) - { - u8 val, msec; -@@ -946,11 +981,7 @@ static int hdmi_phy_configure(struct dw_hdmi *hdmi) - return -EINVAL; - } - -- /* gen2 tx power off */ -- dw_hdmi_phy_gen2_txpwron(hdmi, 0); -- -- /* gen2 pddq */ -- dw_hdmi_phy_gen2_pddq(hdmi, 1); -+ dw_hdmi_phy_power_off(hdmi); - - /* Leave low power consumption mode by asserting SVSRET. */ - if (hdmi->phy->has_svsret) -@@ -1025,8 +1056,6 @@ static int dw_hdmi_phy_init(struct dw_hdmi *hdmi) - for (i = 0; i < 2; i++) { - dw_hdmi_phy_sel_data_en_pol(hdmi, 1); - dw_hdmi_phy_sel_interface_control(hdmi, 0); -- dw_hdmi_phy_enable_tmds(hdmi, 0); -- dw_hdmi_phy_enable_powerdown(hdmi, true); - - ret = hdmi_phy_configure(hdmi); - if (ret) -@@ -1256,8 +1285,7 @@ static void dw_hdmi_phy_disable(struct dw_hdmi *hdmi) - if (!hdmi->phy_enabled) - return; - -- dw_hdmi_phy_enable_tmds(hdmi, 0); -- dw_hdmi_phy_enable_powerdown(hdmi, true); -+ dw_hdmi_phy_power_off(hdmi); - - hdmi->phy_enabled = false; - } -@@ -1827,23 +1855,29 @@ static irqreturn_t dw_hdmi_irq(int irq, void *dev_id) - { - .type = DW_HDMI_PHY_DWC_HDMI_TX_PHY, - .name = "DWC HDMI TX PHY", -+ .gen = 1, - }, { - .type = DW_HDMI_PHY_DWC_MHL_PHY_HEAC, - .name = "DWC MHL PHY + HEAC PHY", -+ .gen = 2, - .has_svsret = true, - }, { - .type = DW_HDMI_PHY_DWC_MHL_PHY, - .name = "DWC MHL PHY", -+ .gen = 2, - .has_svsret = true, - }, { - .type = DW_HDMI_PHY_DWC_HDMI_3D_TX_PHY_HEAC, - .name = "DWC HDMI 3D TX PHY + HEAC PHY", -+ .gen = 2, - }, { - .type = DW_HDMI_PHY_DWC_HDMI_3D_TX_PHY, - .name = "DWC HDMI 3D TX PHY", -+ .gen = 2, - }, { - .type = DW_HDMI_PHY_DWC_HDMI20_TX_PHY, - .name = "DWC HDMI 2.0 TX PHY", -+ .gen = 2, - .has_svsret = true, - } - }; --- -1.9.1 - diff --git a/patch/kernel/odroidc2-next/0035-ARM64-defconfig-enable-CONFIG_SND_SOC_DIO2125-as-mod.patch b/patch/kernel/odroidc2-next/0035-ARM64-defconfig-enable-CONFIG_SND_SOC_DIO2125-as-mod.patch new file mode 100644 index 000000000..e8b5d0096 --- /dev/null +++ b/patch/kernel/odroidc2-next/0035-ARM64-defconfig-enable-CONFIG_SND_SOC_DIO2125-as-mod.patch @@ -0,0 +1,27 @@ +From e23a5c9ce63bcacd81a63ed7f5a3049138de9cb0 Mon Sep 17 00:00:00 2001 +From: Jerome Brunet +Date: Fri, 31 Mar 2017 15:50:39 +0200 +Subject: [PATCH 35/79] ARM64: defconfig: enable CONFIG_SND_SOC_DIO2125 as + module + +Signed-off-by: Jerome Brunet +Signed-off-by: Neil Armstrong +--- + arch/arm64/configs/defconfig | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/arch/arm64/configs/defconfig b/arch/arm64/configs/defconfig +index 21f519d..6fe57e4 100644 +--- a/arch/arm64/configs/defconfig ++++ b/arch/arm64/configs/defconfig +@@ -372,6 +372,7 @@ CONFIG_SND_SOC_RCAR=y + CONFIG_SND_SOC_SAMSUNG=y + CONFIG_SND_SOC_RCAR=y + CONFIG_SND_SOC_AK4613=y ++CONFIG_SND_SOC_DIO2125=m + CONFIG_SND_SOC_ES7134=m + CONFIG_USB=y + CONFIG_USB_OTG=y +-- +1.9.1 + diff --git a/patch/kernel/odroidc2-next/0035-drm-bridge-dw-hdmi-Fix-the-PHY-power-up-sequence.patch b/patch/kernel/odroidc2-next/0035-drm-bridge-dw-hdmi-Fix-the-PHY-power-up-sequence.patch deleted file mode 100644 index 5da4732e3..000000000 --- a/patch/kernel/odroidc2-next/0035-drm-bridge-dw-hdmi-Fix-the-PHY-power-up-sequence.patch +++ /dev/null @@ -1,113 +0,0 @@ -From be5d590fc7021d9fa4aa9acd528f72047e8fd82b Mon Sep 17 00:00:00 2001 -From: Laurent Pinchart -Date: Mon, 6 Mar 2017 01:35:57 +0200 -Subject: [PATCH 35/93] drm: bridge: dw-hdmi: Fix the PHY power up sequence - -When powering the PHY up we need to wait for the PLL to lock. This is -done by polling the TX_PHY_LOCK bit in the HDMI_PHY_STAT0 register -(interrupt-based wait could be implemented as well but is likely -overkill). The bit is asserted when the PLL locks, but the current code -incorrectly waits for the bit to be deasserted. Fix it, and while at it, -replace the udelay() with a sleep as the code never runs in -non-sleepable context. - -To be consistent with the power down implementation move the poll loop -to the power off function. - -Signed-off-by: Laurent Pinchart -Tested-by: Neil Armstrong -Reviewed-by: Jose Abreu -Signed-off-by: Archit Taneja -Link: http://patchwork.freedesktop.org/patch/msgid/20170305233557.11945-1-laurent.pinchart+renesas@ideasonboard.com ---- - drivers/gpu/drm/bridge/dw-hdmi.c | 65 +++++++++++++++++++++++----------------- - 1 file changed, 37 insertions(+), 28 deletions(-) - -diff --git a/drivers/gpu/drm/bridge/dw-hdmi.c b/drivers/gpu/drm/bridge/dw-hdmi.c -index 3a1cd4c..c25eac8 100644 ---- a/drivers/gpu/drm/bridge/dw-hdmi.c -+++ b/drivers/gpu/drm/bridge/dw-hdmi.c -@@ -949,9 +949,44 @@ static void dw_hdmi_phy_power_off(struct dw_hdmi *hdmi) - dw_hdmi_phy_gen2_pddq(hdmi, 1); - } - -+static int dw_hdmi_phy_power_on(struct dw_hdmi *hdmi) -+{ -+ const struct dw_hdmi_phy_data *phy = hdmi->phy; -+ unsigned int i; -+ u8 val; -+ -+ if (phy->gen == 1) { -+ dw_hdmi_phy_enable_powerdown(hdmi, false); -+ -+ /* Toggle TMDS enable. */ -+ dw_hdmi_phy_enable_tmds(hdmi, 0); -+ dw_hdmi_phy_enable_tmds(hdmi, 1); -+ return 0; -+ } -+ -+ dw_hdmi_phy_gen2_txpwron(hdmi, 1); -+ dw_hdmi_phy_gen2_pddq(hdmi, 0); -+ -+ /* Wait for PHY PLL lock */ -+ for (i = 0; i < 5; ++i) { -+ val = hdmi_readb(hdmi, HDMI_PHY_STAT0) & HDMI_PHY_TX_PHY_LOCK; -+ if (val) -+ break; -+ -+ usleep_range(1000, 2000); -+ } -+ -+ if (!val) { -+ dev_err(hdmi->dev, "PHY PLL failed to lock\n"); -+ return -ETIMEDOUT; -+ } -+ -+ dev_dbg(hdmi->dev, "PHY PLL locked %u iterations\n", i); -+ return 0; -+} -+ - static int hdmi_phy_configure(struct dw_hdmi *hdmi) - { -- u8 val, msec; - const struct dw_hdmi_plat_data *pdata = hdmi->plat_data; - const struct dw_hdmi_mpll_config *mpll_config = pdata->mpll_cfg; - const struct dw_hdmi_curr_ctrl *curr_ctrl = pdata->cur_ctr; -@@ -1019,33 +1054,7 @@ static int hdmi_phy_configure(struct dw_hdmi *hdmi) - hdmi_phy_i2c_write(hdmi, HDMI_3D_TX_PHY_CKCALCTRL_OVERRIDE, - HDMI_3D_TX_PHY_CKCALCTRL); - -- dw_hdmi_phy_enable_powerdown(hdmi, false); -- -- /* toggle TMDS enable */ -- dw_hdmi_phy_enable_tmds(hdmi, 0); -- dw_hdmi_phy_enable_tmds(hdmi, 1); -- -- /* gen2 tx power on */ -- dw_hdmi_phy_gen2_txpwron(hdmi, 1); -- dw_hdmi_phy_gen2_pddq(hdmi, 0); -- -- /* Wait for PHY PLL lock */ -- msec = 5; -- do { -- val = hdmi_readb(hdmi, HDMI_PHY_STAT0) & HDMI_PHY_TX_PHY_LOCK; -- if (!val) -- break; -- -- if (msec == 0) { -- dev_err(hdmi->dev, "PHY PLL not locked\n"); -- return -ETIMEDOUT; -- } -- -- udelay(1000); -- msec--; -- } while (1); -- -- return 0; -+ return dw_hdmi_phy_power_on(hdmi); - } - - static int dw_hdmi_phy_init(struct dw_hdmi *hdmi) --- -1.9.1 - diff --git a/patch/kernel/odroidc2-next/0036-ARM64-defconfig-enable-CONFIG_SND_SOC_SPDIF-as-modul.patch b/patch/kernel/odroidc2-next/0036-ARM64-defconfig-enable-CONFIG_SND_SOC_SPDIF-as-modul.patch new file mode 100644 index 000000000..1a2942201 --- /dev/null +++ b/patch/kernel/odroidc2-next/0036-ARM64-defconfig-enable-CONFIG_SND_SOC_SPDIF-as-modul.patch @@ -0,0 +1,26 @@ +From d2922cf55cc2d5a0cd32d4d7055bbb3b1dacd459 Mon Sep 17 00:00:00 2001 +From: Jerome Brunet +Date: Fri, 31 Mar 2017 15:53:05 +0200 +Subject: [PATCH 36/79] ARM64: defconfig: enable CONFIG_SND_SOC_SPDIF as module + +Signed-off-by: Jerome Brunet +Signed-off-by: Neil Armstrong +--- + arch/arm64/configs/defconfig | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/arch/arm64/configs/defconfig b/arch/arm64/configs/defconfig +index 6fe57e4..5da1e44 100644 +--- a/arch/arm64/configs/defconfig ++++ b/arch/arm64/configs/defconfig +@@ -374,6 +374,7 @@ CONFIG_SND_SOC_RCAR=y + CONFIG_SND_SOC_AK4613=y + CONFIG_SND_SOC_DIO2125=m + CONFIG_SND_SOC_ES7134=m ++CONFIG_SND_SOC_SPDIF=m + CONFIG_USB=y + CONFIG_USB_OTG=y + CONFIG_USB_XHCI_HCD=y +-- +1.9.1 + diff --git a/patch/kernel/odroidc2-next/0036-drm-bridge-dw-hdmi-Create-PHY-operations.patch b/patch/kernel/odroidc2-next/0036-drm-bridge-dw-hdmi-Create-PHY-operations.patch deleted file mode 100644 index 1c77609fc..000000000 --- a/patch/kernel/odroidc2-next/0036-drm-bridge-dw-hdmi-Create-PHY-operations.patch +++ /dev/null @@ -1,268 +0,0 @@ -From 815a37cd2514fc9fac5913bdefad6fcbff35d743 Mon Sep 17 00:00:00 2001 -From: Laurent Pinchart -Date: Mon, 6 Mar 2017 01:36:15 +0200 -Subject: [PATCH 36/93] drm: bridge: dw-hdmi: Create PHY operations - -The HDMI TX controller support different PHYs whose programming -interface can vary significantly, especially with vendor PHYs that are -not provided by Synopsys. To support them, create a PHY operation -structure that can be provided by the platform glue layer. The existing -PHY handling code (limited to Synopsys PHY support) is refactored into a -set of default PHY operations that are used automatically when the -platform glue doesn't provide its own operations. - -Signed-off-by: Laurent Pinchart -Tested-by: Neil Armstrong -Reviewed-by: Jose Abreu -Signed-off-by: Archit Taneja -Link: http://patchwork.freedesktop.org/patch/msgid/20170305233615.11993-1-laurent.pinchart+renesas@ideasonboard.com ---- - drivers/gpu/drm/bridge/dw-hdmi.c | 95 ++++++++++++++++++++++++++++------------ - include/drm/bridge/dw_hdmi.h | 18 +++++++- - 2 files changed, 82 insertions(+), 31 deletions(-) - -diff --git a/drivers/gpu/drm/bridge/dw-hdmi.c b/drivers/gpu/drm/bridge/dw-hdmi.c -index c25eac8..cb27038 100644 ---- a/drivers/gpu/drm/bridge/dw-hdmi.c -+++ b/drivers/gpu/drm/bridge/dw-hdmi.c -@@ -141,8 +141,12 @@ struct dw_hdmi { - u8 edid[HDMI_EDID_LEN]; - bool cable_plugin; - -- const struct dw_hdmi_phy_data *phy; -- bool phy_enabled; -+ struct { -+ const struct dw_hdmi_phy_ops *ops; -+ const char *name; -+ void *data; -+ bool enabled; -+ } phy; - - struct drm_display_mode previous_mode; - -@@ -831,6 +835,10 @@ static void hdmi_video_packetize(struct dw_hdmi *hdmi) - HDMI_VP_CONF); - } - -+/* ----------------------------------------------------------------------------- -+ * Synopsys PHY Handling -+ */ -+ - static inline void hdmi_phy_test_clear(struct dw_hdmi *hdmi, - unsigned char bit) - { -@@ -917,7 +925,7 @@ static void dw_hdmi_phy_sel_interface_control(struct dw_hdmi *hdmi, u8 enable) - - static void dw_hdmi_phy_power_off(struct dw_hdmi *hdmi) - { -- const struct dw_hdmi_phy_data *phy = hdmi->phy; -+ const struct dw_hdmi_phy_data *phy = hdmi->phy.data; - unsigned int i; - u16 val; - -@@ -951,7 +959,7 @@ static void dw_hdmi_phy_power_off(struct dw_hdmi *hdmi) - - static int dw_hdmi_phy_power_on(struct dw_hdmi *hdmi) - { -- const struct dw_hdmi_phy_data *phy = hdmi->phy; -+ const struct dw_hdmi_phy_data *phy = hdmi->phy.data; - unsigned int i; - u8 val; - -@@ -987,6 +995,7 @@ static int dw_hdmi_phy_power_on(struct dw_hdmi *hdmi) - - static int hdmi_phy_configure(struct dw_hdmi *hdmi) - { -+ const struct dw_hdmi_phy_data *phy = hdmi->phy.data; - const struct dw_hdmi_plat_data *pdata = hdmi->plat_data; - const struct dw_hdmi_mpll_config *mpll_config = pdata->mpll_cfg; - const struct dw_hdmi_curr_ctrl *curr_ctrl = pdata->cur_ctr; -@@ -1019,7 +1028,7 @@ static int hdmi_phy_configure(struct dw_hdmi *hdmi) - dw_hdmi_phy_power_off(hdmi); - - /* Leave low power consumption mode by asserting SVSRET. */ -- if (hdmi->phy->has_svsret) -+ if (phy->has_svsret) - dw_hdmi_phy_enable_svsret(hdmi, 1); - - /* PHY reset. The reset signal is active high on Gen2 PHYs. */ -@@ -1057,7 +1066,8 @@ static int hdmi_phy_configure(struct dw_hdmi *hdmi) - return dw_hdmi_phy_power_on(hdmi); - } - --static int dw_hdmi_phy_init(struct dw_hdmi *hdmi) -+static int dw_hdmi_phy_init(struct dw_hdmi *hdmi, void *data, -+ struct drm_display_mode *mode) - { - int i, ret; - -@@ -1071,10 +1081,31 @@ static int dw_hdmi_phy_init(struct dw_hdmi *hdmi) - return ret; - } - -- hdmi->phy_enabled = true; - return 0; - } - -+static void dw_hdmi_phy_disable(struct dw_hdmi *hdmi, void *data) -+{ -+ dw_hdmi_phy_power_off(hdmi); -+} -+ -+static enum drm_connector_status dw_hdmi_phy_read_hpd(struct dw_hdmi *hdmi, -+ void *data) -+{ -+ return hdmi_readb(hdmi, HDMI_PHY_STAT0) & HDMI_PHY_HPD ? -+ connector_status_connected : connector_status_disconnected; -+} -+ -+static const struct dw_hdmi_phy_ops dw_hdmi_synopsys_phy_ops = { -+ .init = dw_hdmi_phy_init, -+ .disable = dw_hdmi_phy_disable, -+ .read_hpd = dw_hdmi_phy_read_hpd, -+}; -+ -+/* ----------------------------------------------------------------------------- -+ * HDMI TX Setup -+ */ -+ - static void hdmi_tx_hdcp_config(struct dw_hdmi *hdmi) - { - u8 de; -@@ -1289,16 +1320,6 @@ static void hdmi_av_composer(struct dw_hdmi *hdmi, - hdmi_writeb(hdmi, vsync_len, HDMI_FC_VSYNCINWIDTH); - } - --static void dw_hdmi_phy_disable(struct dw_hdmi *hdmi) --{ -- if (!hdmi->phy_enabled) -- return; -- -- dw_hdmi_phy_power_off(hdmi); -- -- hdmi->phy_enabled = false; --} -- - /* HDMI Initialization Step B.4 */ - static void dw_hdmi_enable_video_path(struct dw_hdmi *hdmi) - { -@@ -1431,9 +1452,10 @@ static int dw_hdmi_setup(struct dw_hdmi *hdmi, struct drm_display_mode *mode) - hdmi_av_composer(hdmi, mode); - - /* HDMI Initializateion Step B.2 */ -- ret = dw_hdmi_phy_init(hdmi); -+ ret = hdmi->phy.ops->init(hdmi, hdmi->phy.data, &hdmi->previous_mode); - if (ret) - return ret; -+ hdmi->phy.enabled = true; - - /* HDMI Initialization Step B.3 */ - dw_hdmi_enable_video_path(hdmi); -@@ -1548,7 +1570,11 @@ static void dw_hdmi_poweron(struct dw_hdmi *hdmi) - - static void dw_hdmi_poweroff(struct dw_hdmi *hdmi) - { -- dw_hdmi_phy_disable(hdmi); -+ if (hdmi->phy.enabled) { -+ hdmi->phy.ops->disable(hdmi, hdmi->phy.data); -+ hdmi->phy.enabled = false; -+ } -+ - hdmi->bridge_is_on = false; - } - -@@ -1611,8 +1637,7 @@ static void dw_hdmi_update_phy_mask(struct dw_hdmi *hdmi) - dw_hdmi_update_phy_mask(hdmi); - mutex_unlock(&hdmi->mutex); - -- return hdmi_readb(hdmi, HDMI_PHY_STAT0) & HDMI_PHY_HPD ? -- connector_status_connected : connector_status_disconnected; -+ return hdmi->phy.ops->read_hpd(hdmi, hdmi->phy.data); - } - - static int dw_hdmi_connector_get_modes(struct drm_connector *connector) -@@ -1898,19 +1923,31 @@ static int dw_hdmi_detect_phy(struct dw_hdmi *hdmi) - - phy_type = hdmi_readb(hdmi, HDMI_CONFIG2_ID); - -+ if (phy_type == DW_HDMI_PHY_VENDOR_PHY) { -+ /* Vendor PHYs require support from the glue layer. */ -+ if (!hdmi->plat_data->phy_ops || !hdmi->plat_data->phy_name) { -+ dev_err(hdmi->dev, -+ "Vendor HDMI PHY not supported by glue layer\n"); -+ return -ENODEV; -+ } -+ -+ hdmi->phy.ops = hdmi->plat_data->phy_ops; -+ hdmi->phy.data = hdmi->plat_data->phy_data; -+ hdmi->phy.name = hdmi->plat_data->phy_name; -+ return 0; -+ } -+ -+ /* Synopsys PHYs are handled internally. */ - for (i = 0; i < ARRAY_SIZE(dw_hdmi_phys); ++i) { - if (dw_hdmi_phys[i].type == phy_type) { -- hdmi->phy = &dw_hdmi_phys[i]; -+ hdmi->phy.ops = &dw_hdmi_synopsys_phy_ops; -+ hdmi->phy.name = dw_hdmi_phys[i].name; -+ hdmi->phy.data = (void *)&dw_hdmi_phys[i]; - return 0; - } - } - -- if (phy_type == DW_HDMI_PHY_VENDOR_PHY) -- dev_err(hdmi->dev, "Unsupported vendor HDMI PHY\n"); -- else -- dev_err(hdmi->dev, "Unsupported HDMI PHY type (%02x)\n", -- phy_type); -- -+ dev_err(hdmi->dev, "Unsupported HDMI PHY type (%02x)\n", phy_type); - return -ENODEV; - } - -@@ -2031,7 +2068,7 @@ static int dw_hdmi_detect_phy(struct dw_hdmi *hdmi) - dev_info(dev, "Detected HDMI TX controller v%x.%03x %s HDCP (%s)\n", - hdmi->version >> 12, hdmi->version & 0xfff, - prod_id1 & HDMI_PRODUCT_ID1_HDCP ? "with" : "without", -- hdmi->phy->name); -+ hdmi->phy.name); - - initialize_hdmi_ih_mutes(hdmi); - -diff --git a/include/drm/bridge/dw_hdmi.h b/include/drm/bridge/dw_hdmi.h -index b080a17..0f583ca 100644 ---- a/include/drm/bridge/dw_hdmi.h -+++ b/include/drm/bridge/dw_hdmi.h -@@ -57,13 +57,27 @@ struct dw_hdmi_phy_config { - u16 vlev_ctr; /* voltage level control */ - }; - -+struct dw_hdmi_phy_ops { -+ int (*init)(struct dw_hdmi *hdmi, void *data, -+ struct drm_display_mode *mode); -+ void (*disable)(struct dw_hdmi *hdmi, void *data); -+ enum drm_connector_status (*read_hpd)(struct dw_hdmi *hdmi, void *data); -+}; -+ - struct dw_hdmi_plat_data { - enum dw_hdmi_devtype dev_type; -+ enum drm_mode_status (*mode_valid)(struct drm_connector *connector, -+ struct drm_display_mode *mode); -+ -+ /* Vendor PHY support */ -+ const struct dw_hdmi_phy_ops *phy_ops; -+ const char *phy_name; -+ void *phy_data; -+ -+ /* Synopsys PHY support */ - const struct dw_hdmi_mpll_config *mpll_cfg; - const struct dw_hdmi_curr_ctrl *cur_ctr; - const struct dw_hdmi_phy_config *phy_config; -- enum drm_mode_status (*mode_valid)(struct drm_connector *connector, -- struct drm_display_mode *mode); - }; - - int dw_hdmi_probe(struct platform_device *pdev, --- -1.9.1 - diff --git a/patch/kernel/odroidc2-next/0037-ARM64-dts-meson-gx-add-audio-controller-nodes.patch b/patch/kernel/odroidc2-next/0037-ARM64-dts-meson-gx-add-audio-controller-nodes.patch new file mode 100644 index 000000000..3f72c661f --- /dev/null +++ b/patch/kernel/odroidc2-next/0037-ARM64-dts-meson-gx-add-audio-controller-nodes.patch @@ -0,0 +1,194 @@ +From 76c374731322248f9e48241e0debdfed6d794a44 Mon Sep 17 00:00:00 2001 +From: Jerome Brunet +Date: Thu, 30 Mar 2017 15:19:04 +0200 +Subject: [PATCH 37/79] ARM64: dts: meson-gx: add audio controller nodes + +Add audio controller nodes for Amlogic meson gxbb and gxl. +This includes the audio-core node, the i2s and spdif DAIs, i2s and spdif +aiu DMAs. + +Audio on this SoC family is still a work in progress. More nodes are likely +to be added later on (pcm DAIs, input DMAs, etc ...) + +Signed-off-by: Jerome Brunet +Signed-off-by: Neil Armstrong +--- + arch/arm64/boot/dts/amlogic/meson-gx.dtsi | 35 ++++++++++++++++++++++++++ + arch/arm64/boot/dts/amlogic/meson-gxbb.dtsi | 38 +++++++++++++++++++++++++++++ + arch/arm64/boot/dts/amlogic/meson-gxl.dtsi | 37 ++++++++++++++++++++++++++++ + 3 files changed, 110 insertions(+) + +diff --git a/arch/arm64/boot/dts/amlogic/meson-gx.dtsi b/arch/arm64/boot/dts/amlogic/meson-gx.dtsi +index 8901eeb..2251881 100644 +--- a/arch/arm64/boot/dts/amlogic/meson-gx.dtsi ++++ b/arch/arm64/boot/dts/amlogic/meson-gx.dtsi +@@ -224,6 +224,41 @@ + #reset-cells = <1>; + }; + ++ audio: audio@5400 { ++ compatible = "amlogic,meson-audio-core"; ++ reg = <0x0 0x5400 0x0 0x2ac>, ++ <0x0 0xa000 0x0 0x304>; ++ reg-names = "aiu", "audin"; ++ status = "disabled"; ++ ++ aiu_i2s_dma: aiu_i2s_dma { ++ #sound-dai-cells = <0>; ++ compatible = "amlogic,meson-aiu-i2s-dma"; ++ interrupts = ; ++ status = "disabled"; ++ }; ++ ++ aiu_spdif_dma: aiu_spdif_dma { ++ #sound-dai-cells = <0>; ++ compatible = "amlogic,meson-aiu-spdif-dma"; ++ interrupts = ; ++ status = "disabled"; ++ }; ++ ++ i2s_dai: i2s_dai { ++ #sound-dai-cells = <0>; ++ compatible = "amlogic,meson-i2s-dai"; ++ status = "disabled"; ++ }; ++ ++ spdif_dai: spdif_dai { ++ #sound-dai-cells = <0>; ++ compatible = "amlogic,meson-spdif-dai"; ++ status = "disabled"; ++ }; ++ ++ }; ++ + uart_A: serial@84c0 { + compatible = "amlogic,meson-uart"; + reg = <0x0 0x84c0 0x0 0x14>; +diff --git a/arch/arm64/boot/dts/amlogic/meson-gxbb.dtsi b/arch/arm64/boot/dts/amlogic/meson-gxbb.dtsi +index 1d4c861..92d2b91 100644 +--- a/arch/arm64/boot/dts/amlogic/meson-gxbb.dtsi ++++ b/arch/arm64/boot/dts/amlogic/meson-gxbb.dtsi +@@ -602,6 +602,27 @@ + }; + }; + ++&audio { ++ clocks = <&clkc CLKID_AIU>, ++ <&clkc CLKID_AIU_GLUE>, ++ <&clkc CLKID_I2S_SPDIF>; ++ clock-names = "aiu_top", "aiu_glue", "audin"; ++ resets = <&reset RESET_AIU>, ++ <&reset RESET_AUDIN>; ++ reset-names = "aiu", "audin"; ++}; ++ ++&aiu_i2s_dma { ++ clocks = <&clkc CLKID_I2S_OUT>; ++ clock-names = "fast"; ++}; ++ ++&aiu_spdif_dma { ++ clocks = <&clkc CLKID_IEC958>; ++ clock-names = "fast"; ++ ++}; ++ + &i2c_A { + clocks = <&clkc CLKID_I2C>; + }; +@@ -618,6 +639,14 @@ + clocks = <&clkc CLKID_I2C>; + }; + ++&i2s_dai { ++ clocks = <&clkc CLKID_I2S_OUT>, ++ <&clkc CLKID_MIXER_IFACE>, ++ <&clkc CLKID_AOCLK_GATE>, ++ <&clkc CLKID_CTS_AMCLK>; ++ clock-names = "fast", "iface", "bclks", "mclk"; ++}; ++ + &saradc { + compatible = "amlogic,meson-gxbb-saradc", "amlogic,meson-saradc"; + clocks = <&xtal>, +@@ -649,6 +678,15 @@ + clock-names = "core", "clkin0", "clkin1"; + }; + ++&spdif_dai { ++ clocks = <&clkc CLKID_IEC958>, ++ <&clkc CLKID_IEC958_GATE>, ++ <&clkc CLKID_CTS_MCLK_I958>, ++ <&clkc CLKID_CTS_AMCLK>, ++ <&clkc CLKID_CTS_I958>; ++ clock-names = "fast", "iface", "mclk_i958", "mclk_i2s", "mclk"; ++}; ++ + &spifc { + clocks = <&clkc CLKID_SPI>; + }; +diff --git a/arch/arm64/boot/dts/amlogic/meson-gxl.dtsi b/arch/arm64/boot/dts/amlogic/meson-gxl.dtsi +index 6584e46..de0a26b 100644 +--- a/arch/arm64/boot/dts/amlogic/meson-gxl.dtsi ++++ b/arch/arm64/boot/dts/amlogic/meson-gxl.dtsi +@@ -208,6 +208,26 @@ + }; + }; + ++&audio { ++ clocks = <&clkc CLKID_AIU>, ++ <&clkc CLKID_AIU_GLUE>, ++ <&clkc CLKID_I2S_SPDIF>; ++ clock-names = "aiu_top", "aiu_glue", "audin"; ++ resets = <&reset RESET_AIU>, ++ <&reset RESET_AUDIN>; ++ reset-names = "aiu", "audin"; ++}; ++ ++&aiu_i2s_dma { ++ clocks = <&clkc CLKID_I2S_OUT>; ++ clock-names = "fast"; ++}; ++ ++&aiu_spdif_dma { ++ clocks = <&clkc CLKID_IEC958>; ++ clock-names = "fast"; ++}; ++ + &periphs { + pinctrl_periphs: pinctrl@4b0 { + compatible = "amlogic,meson-gxl-periphs-pinctrl"; +@@ -570,6 +590,14 @@ + clocks = <&clkc CLKID_I2C>; + }; + ++&i2s_dai { ++ clocks = <&clkc CLKID_I2S_OUT>, ++ <&clkc CLKID_MIXER_IFACE>, ++ <&clkc CLKID_AOCLK_GATE>, ++ <&clkc CLKID_CTS_AMCLK>; ++ clock-names = "fast", "iface", "bclks", "mclk"; ++}; ++ + &saradc { + compatible = "amlogic,meson-gxl-saradc", "amlogic,meson-saradc"; + clocks = <&xtal>, +@@ -601,6 +629,15 @@ + clock-names = "core", "clkin0", "clkin1"; + }; + ++&spdif_dai { ++ clocks = <&clkc CLKID_IEC958>, ++ <&clkc CLKID_IEC958_GATE>, ++ <&clkc CLKID_CTS_MCLK_I958>, ++ <&clkc CLKID_CTS_AMCLK>, ++ <&clkc CLKID_CTS_I958>; ++ clock-names = "fast", "iface", "mclk_i958", "mclk_i2s", "mclk"; ++}; ++ + &spifc { + clocks = <&clkc CLKID_SPI>; + }; +-- +1.9.1 + diff --git a/patch/kernel/odroidc2-next/0037-drm-bridge-dw-hdmi-Add-support-for-custom-PHY-config.patch b/patch/kernel/odroidc2-next/0037-drm-bridge-dw-hdmi-Add-support-for-custom-PHY-config.patch deleted file mode 100644 index c6ac92fb2..000000000 --- a/patch/kernel/odroidc2-next/0037-drm-bridge-dw-hdmi-Add-support-for-custom-PHY-config.patch +++ /dev/null @@ -1,251 +0,0 @@ -From 3fdd6b3e658373e45ecbe36093403a30bd309df5 Mon Sep 17 00:00:00 2001 -From: Kieran Bingham -Date: Fri, 3 Mar 2017 19:20:04 +0200 -Subject: [PATCH 37/93] drm: bridge: dw-hdmi: Add support for custom PHY - configuration - -The DWC HDMI TX controller interfaces with a companion PHY. While -Synopsys provides multiple standard PHYs, SoC vendors can also integrate -a custom PHY. - -Modularize PHY configuration to support vendor PHYs through platform -data. The existing PHY configuration code was originally written to -support the DWC HDMI 3D TX PHY, and seems to be compatible with the DWC -MLP PHY. The HDMI 2.0 PHY will require a separate configuration -function. - -Signed-off-by: Kieran Bingham -Signed-off-by: Laurent Pinchart -Tested-by: Neil Armstrong -Reviewed-by: Jose Abreu -Signed-off-by: Archit Taneja -Link: http://patchwork.freedesktop.org/patch/msgid/20170303172007.26541-8-laurent.pinchart+renesas@ideasonboard.com ---- - drivers/gpu/drm/bridge/dw-hdmi.c | 109 ++++++++++++++++++++++++++------------- - include/drm/bridge/dw_hdmi.h | 7 +++ - 2 files changed, 81 insertions(+), 35 deletions(-) - -diff --git a/drivers/gpu/drm/bridge/dw-hdmi.c b/drivers/gpu/drm/bridge/dw-hdmi.c -index cb27038..b835d81 100644 ---- a/drivers/gpu/drm/bridge/dw-hdmi.c -+++ b/drivers/gpu/drm/bridge/dw-hdmi.c -@@ -118,6 +118,9 @@ struct dw_hdmi_phy_data { - const char *name; - unsigned int gen; - bool has_svsret; -+ int (*configure)(struct dw_hdmi *hdmi, -+ const struct dw_hdmi_plat_data *pdata, -+ unsigned long mpixelclock); - }; - - struct dw_hdmi { -@@ -860,8 +863,8 @@ static bool hdmi_phy_wait_i2c_done(struct dw_hdmi *hdmi, int msec) - return true; - } - --static void hdmi_phy_i2c_write(struct dw_hdmi *hdmi, unsigned short data, -- unsigned char addr) -+void dw_hdmi_phy_i2c_write(struct dw_hdmi *hdmi, unsigned short data, -+ unsigned char addr) - { - hdmi_writeb(hdmi, 0xFF, HDMI_IH_I2CMPHY_STAT0); - hdmi_writeb(hdmi, addr, HDMI_PHY_I2CM_ADDRESS_ADDR); -@@ -873,6 +876,7 @@ static void hdmi_phy_i2c_write(struct dw_hdmi *hdmi, unsigned short data, - HDMI_PHY_I2CM_OPERATION_ADDR); - hdmi_phy_wait_i2c_done(hdmi, 1000); - } -+EXPORT_SYMBOL_GPL(dw_hdmi_phy_i2c_write); - - static void dw_hdmi_phy_enable_powerdown(struct dw_hdmi *hdmi, bool enable) - { -@@ -993,37 +997,67 @@ static int dw_hdmi_phy_power_on(struct dw_hdmi *hdmi) - return 0; - } - --static int hdmi_phy_configure(struct dw_hdmi *hdmi) -+/* -+ * PHY configuration function for the DWC HDMI 3D TX PHY. Based on the available -+ * information the DWC MHL PHY has the same register layout and is thus also -+ * supported by this function. -+ */ -+static int hdmi_phy_configure_dwc_hdmi_3d_tx(struct dw_hdmi *hdmi, -+ const struct dw_hdmi_plat_data *pdata, -+ unsigned long mpixelclock) - { -- const struct dw_hdmi_phy_data *phy = hdmi->phy.data; -- const struct dw_hdmi_plat_data *pdata = hdmi->plat_data; - const struct dw_hdmi_mpll_config *mpll_config = pdata->mpll_cfg; - const struct dw_hdmi_curr_ctrl *curr_ctrl = pdata->cur_ctr; - const struct dw_hdmi_phy_config *phy_config = pdata->phy_config; - - /* PLL/MPLL Cfg - always match on final entry */ - for (; mpll_config->mpixelclock != ~0UL; mpll_config++) -- if (hdmi->hdmi_data.video_mode.mpixelclock <= -- mpll_config->mpixelclock) -+ if (mpixelclock <= mpll_config->mpixelclock) - break; - - for (; curr_ctrl->mpixelclock != ~0UL; curr_ctrl++) -- if (hdmi->hdmi_data.video_mode.mpixelclock <= -- curr_ctrl->mpixelclock) -+ if (mpixelclock <= curr_ctrl->mpixelclock) - break; - - for (; phy_config->mpixelclock != ~0UL; phy_config++) -- if (hdmi->hdmi_data.video_mode.mpixelclock <= -- phy_config->mpixelclock) -+ if (mpixelclock <= phy_config->mpixelclock) - break; - - if (mpll_config->mpixelclock == ~0UL || - curr_ctrl->mpixelclock == ~0UL || -- phy_config->mpixelclock == ~0UL) { -- dev_err(hdmi->dev, "Pixel clock %d - unsupported by HDMI\n", -- hdmi->hdmi_data.video_mode.mpixelclock); -+ phy_config->mpixelclock == ~0UL) - return -EINVAL; -- } -+ -+ dw_hdmi_phy_i2c_write(hdmi, mpll_config->res[0].cpce, -+ HDMI_3D_TX_PHY_CPCE_CTRL); -+ dw_hdmi_phy_i2c_write(hdmi, mpll_config->res[0].gmp, -+ HDMI_3D_TX_PHY_GMPCTRL); -+ dw_hdmi_phy_i2c_write(hdmi, curr_ctrl->curr[0], -+ HDMI_3D_TX_PHY_CURRCTRL); -+ -+ dw_hdmi_phy_i2c_write(hdmi, 0, HDMI_3D_TX_PHY_PLLPHBYCTRL); -+ dw_hdmi_phy_i2c_write(hdmi, HDMI_3D_TX_PHY_MSM_CTRL_CKO_SEL_FB_CLK, -+ HDMI_3D_TX_PHY_MSM_CTRL); -+ -+ dw_hdmi_phy_i2c_write(hdmi, phy_config->term, HDMI_3D_TX_PHY_TXTERM); -+ dw_hdmi_phy_i2c_write(hdmi, phy_config->sym_ctr, -+ HDMI_3D_TX_PHY_CKSYMTXCTRL); -+ dw_hdmi_phy_i2c_write(hdmi, phy_config->vlev_ctr, -+ HDMI_3D_TX_PHY_VLEVCTRL); -+ -+ /* Override and disable clock termination. */ -+ dw_hdmi_phy_i2c_write(hdmi, HDMI_3D_TX_PHY_CKCALCTRL_OVERRIDE, -+ HDMI_3D_TX_PHY_CKCALCTRL); -+ -+ return 0; -+} -+ -+static int hdmi_phy_configure(struct dw_hdmi *hdmi) -+{ -+ const struct dw_hdmi_phy_data *phy = hdmi->phy.data; -+ const struct dw_hdmi_plat_data *pdata = hdmi->plat_data; -+ unsigned long mpixelclock = hdmi->hdmi_data.video_mode.mpixelclock; -+ int ret; - - dw_hdmi_phy_power_off(hdmi); - -@@ -1042,26 +1076,16 @@ static int hdmi_phy_configure(struct dw_hdmi *hdmi) - HDMI_PHY_I2CM_SLAVE_ADDR); - hdmi_phy_test_clear(hdmi, 0); - -- hdmi_phy_i2c_write(hdmi, mpll_config->res[0].cpce, -- HDMI_3D_TX_PHY_CPCE_CTRL); -- hdmi_phy_i2c_write(hdmi, mpll_config->res[0].gmp, -- HDMI_3D_TX_PHY_GMPCTRL); -- hdmi_phy_i2c_write(hdmi, curr_ctrl->curr[0], -- HDMI_3D_TX_PHY_CURRCTRL); -- -- hdmi_phy_i2c_write(hdmi, 0, HDMI_3D_TX_PHY_PLLPHBYCTRL); -- hdmi_phy_i2c_write(hdmi, HDMI_3D_TX_PHY_MSM_CTRL_CKO_SEL_FB_CLK, -- HDMI_3D_TX_PHY_MSM_CTRL); -- -- hdmi_phy_i2c_write(hdmi, phy_config->term, HDMI_3D_TX_PHY_TXTERM); -- hdmi_phy_i2c_write(hdmi, phy_config->sym_ctr, -- HDMI_3D_TX_PHY_CKSYMTXCTRL); -- hdmi_phy_i2c_write(hdmi, phy_config->vlev_ctr, -- HDMI_3D_TX_PHY_VLEVCTRL); -- -- /* Override and disable clock termination. */ -- hdmi_phy_i2c_write(hdmi, HDMI_3D_TX_PHY_CKCALCTRL_OVERRIDE, -- HDMI_3D_TX_PHY_CKCALCTRL); -+ /* Write to the PHY as configured by the platform */ -+ if (pdata->configure_phy) -+ ret = pdata->configure_phy(hdmi, pdata, mpixelclock); -+ else -+ ret = phy->configure(hdmi, pdata, mpixelclock); -+ if (ret) { -+ dev_err(hdmi->dev, "PHY configuration failed (clock %lu)\n", -+ mpixelclock); -+ return ret; -+ } - - return dw_hdmi_phy_power_on(hdmi); - } -@@ -1895,24 +1919,31 @@ static irqreturn_t dw_hdmi_irq(int irq, void *dev_id) - .name = "DWC MHL PHY + HEAC PHY", - .gen = 2, - .has_svsret = true, -+ .configure = hdmi_phy_configure_dwc_hdmi_3d_tx, - }, { - .type = DW_HDMI_PHY_DWC_MHL_PHY, - .name = "DWC MHL PHY", - .gen = 2, - .has_svsret = true, -+ .configure = hdmi_phy_configure_dwc_hdmi_3d_tx, - }, { - .type = DW_HDMI_PHY_DWC_HDMI_3D_TX_PHY_HEAC, - .name = "DWC HDMI 3D TX PHY + HEAC PHY", - .gen = 2, -+ .configure = hdmi_phy_configure_dwc_hdmi_3d_tx, - }, { - .type = DW_HDMI_PHY_DWC_HDMI_3D_TX_PHY, - .name = "DWC HDMI 3D TX PHY", - .gen = 2, -+ .configure = hdmi_phy_configure_dwc_hdmi_3d_tx, - }, { - .type = DW_HDMI_PHY_DWC_HDMI20_TX_PHY, - .name = "DWC HDMI 2.0 TX PHY", - .gen = 2, - .has_svsret = true, -+ }, { -+ .type = DW_HDMI_PHY_VENDOR_PHY, -+ .name = "Vendor PHY", - } - }; - -@@ -1943,6 +1974,14 @@ static int dw_hdmi_detect_phy(struct dw_hdmi *hdmi) - hdmi->phy.ops = &dw_hdmi_synopsys_phy_ops; - hdmi->phy.name = dw_hdmi_phys[i].name; - hdmi->phy.data = (void *)&dw_hdmi_phys[i]; -+ -+ if (!dw_hdmi_phys[i].configure && -+ !hdmi->plat_data->configure_phy) { -+ dev_err(hdmi->dev, "%s requires platform support\n", -+ hdmi->phy.name); -+ return -ENODEV; -+ } -+ - return 0; - } - } -diff --git a/include/drm/bridge/dw_hdmi.h b/include/drm/bridge/dw_hdmi.h -index 0f583ca..dd33025 100644 ---- a/include/drm/bridge/dw_hdmi.h -+++ b/include/drm/bridge/dw_hdmi.h -@@ -78,6 +78,9 @@ struct dw_hdmi_plat_data { - const struct dw_hdmi_mpll_config *mpll_cfg; - const struct dw_hdmi_curr_ctrl *cur_ctr; - const struct dw_hdmi_phy_config *phy_config; -+ int (*configure_phy)(struct dw_hdmi *hdmi, -+ const struct dw_hdmi_plat_data *pdata, -+ unsigned long mpixelclock); - }; - - int dw_hdmi_probe(struct platform_device *pdev, -@@ -91,4 +94,8 @@ int dw_hdmi_bind(struct platform_device *pdev, struct drm_encoder *encoder, - void dw_hdmi_audio_enable(struct dw_hdmi *hdmi); - void dw_hdmi_audio_disable(struct dw_hdmi *hdmi); - -+/* PHY configuration */ -+void dw_hdmi_phy_i2c_write(struct dw_hdmi *hdmi, unsigned short data, -+ unsigned char addr); -+ - #endif /* __IMX_HDMI_H__ */ --- -1.9.1 - diff --git a/patch/kernel/odroidc2-next/0038-ARM64-dts-meson-gxbb-p20x-add-i2s-codec-node.patch b/patch/kernel/odroidc2-next/0038-ARM64-dts-meson-gxbb-p20x-add-i2s-codec-node.patch new file mode 100644 index 000000000..103dd5091 --- /dev/null +++ b/patch/kernel/odroidc2-next/0038-ARM64-dts-meson-gxbb-p20x-add-i2s-codec-node.patch @@ -0,0 +1,34 @@ +From fb22697ac3dfd363e9d51307d1bb168bd6cf1c41 Mon Sep 17 00:00:00 2001 +From: Jerome Brunet +Date: Thu, 30 Mar 2017 15:28:24 +0200 +Subject: [PATCH 38/79] ARM64: dts: meson-gxbb-p20x: add i2s codec node + +Add the node for the i2s codec Everest 7134 found on the P20x reference +design + +Signed-off-by: Jerome Brunet +Signed-off-by: Neil Armstrong +--- + arch/arm64/boot/dts/amlogic/meson-gxbb-p20x.dtsi | 6 ++++++ + 1 file changed, 6 insertions(+) + +diff --git a/arch/arm64/boot/dts/amlogic/meson-gxbb-p20x.dtsi b/arch/arm64/boot/dts/amlogic/meson-gxbb-p20x.dtsi +index 3ed5c99..07b0f21 100644 +--- a/arch/arm64/boot/dts/amlogic/meson-gxbb-p20x.dtsi ++++ b/arch/arm64/boot/dts/amlogic/meson-gxbb-p20x.dtsi +@@ -146,6 +146,12 @@ + }; + }; + }; ++ ++ i2s_codec: external-codec { ++ #sound-dai-cells = <0>; ++ compatible = "everest,es7134"; ++ status = "okay"; ++ }; + }; + + /* This UART is brought out to the DB9 connector */ +-- +1.9.1 + diff --git a/patch/kernel/odroidc2-next/0038-drm-bridge-dw-hdmi-Remove-device-type-from-platform-.patch b/patch/kernel/odroidc2-next/0038-drm-bridge-dw-hdmi-Remove-device-type-from-platform-.patch deleted file mode 100644 index 8a6b8f14d..000000000 --- a/patch/kernel/odroidc2-next/0038-drm-bridge-dw-hdmi-Remove-device-type-from-platform-.patch +++ /dev/null @@ -1,103 +0,0 @@ -From c5bdf6120fed0d57d7e602abc01f0cbacf275737 Mon Sep 17 00:00:00 2001 -From: Kieran Bingham -Date: Fri, 3 Mar 2017 19:20:05 +0200 -Subject: [PATCH 38/93] drm: bridge: dw-hdmi: Remove device type from platform - data - -The device type isn't used anymore now that workarounds and PHY-specific -operations are performed based on version information read at runtime. -Remove it. - -Signed-off-by: Kieran Bingham -Signed-off-by: Laurent Pinchart -Tested-by: Neil Armstrong -Reviewed-by: Jose Abreu -Signed-off-by: Archit Taneja -Link: http://patchwork.freedesktop.org/patch/msgid/20170303172007.26541-9-laurent.pinchart+renesas@ideasonboard.com ---- - drivers/gpu/drm/bridge/dw-hdmi.c | 2 -- - drivers/gpu/drm/imx/dw_hdmi-imx.c | 2 -- - drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c | 1 - - include/drm/bridge/dw_hdmi.h | 7 ------- - 4 files changed, 12 deletions(-) - -diff --git a/drivers/gpu/drm/bridge/dw-hdmi.c b/drivers/gpu/drm/bridge/dw-hdmi.c -index b835d81..132c006 100644 ---- a/drivers/gpu/drm/bridge/dw-hdmi.c -+++ b/drivers/gpu/drm/bridge/dw-hdmi.c -@@ -127,7 +127,6 @@ struct dw_hdmi { - struct drm_connector connector; - struct drm_bridge bridge; - -- enum dw_hdmi_devtype dev_type; - unsigned int version; - - struct platform_device *audio; -@@ -2014,7 +2013,6 @@ static int dw_hdmi_detect_phy(struct dw_hdmi *hdmi) - - hdmi->plat_data = plat_data; - hdmi->dev = dev; -- hdmi->dev_type = plat_data->dev_type; - hdmi->sample_rate = 48000; - hdmi->disabled = true; - hdmi->rxsense = true; -diff --git a/drivers/gpu/drm/imx/dw_hdmi-imx.c b/drivers/gpu/drm/imx/dw_hdmi-imx.c -index f645275..f039641 100644 ---- a/drivers/gpu/drm/imx/dw_hdmi-imx.c -+++ b/drivers/gpu/drm/imx/dw_hdmi-imx.c -@@ -175,7 +175,6 @@ static enum drm_mode_status imx6dl_hdmi_mode_valid(struct drm_connector *con, - .mpll_cfg = imx_mpll_cfg, - .cur_ctr = imx_cur_ctr, - .phy_config = imx_phy_config, -- .dev_type = IMX6Q_HDMI, - .mode_valid = imx6q_hdmi_mode_valid, - }; - -@@ -183,7 +182,6 @@ static enum drm_mode_status imx6dl_hdmi_mode_valid(struct drm_connector *con, - .mpll_cfg = imx_mpll_cfg, - .cur_ctr = imx_cur_ctr, - .phy_config = imx_phy_config, -- .dev_type = IMX6DL_HDMI, - .mode_valid = imx6dl_hdmi_mode_valid, - }; - -diff --git a/drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c b/drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c -index a6d4a02..d538274 100644 ---- a/drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c -+++ b/drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c -@@ -237,7 +237,6 @@ static void dw_hdmi_rockchip_encoder_enable(struct drm_encoder *encoder) - .mpll_cfg = rockchip_mpll_cfg, - .cur_ctr = rockchip_cur_ctr, - .phy_config = rockchip_phy_config, -- .dev_type = RK3288_HDMI, - }; - - static const struct of_device_id dw_hdmi_rockchip_dt_ids[] = { -diff --git a/include/drm/bridge/dw_hdmi.h b/include/drm/bridge/dw_hdmi.h -index dd33025..545f04fa 100644 ---- a/include/drm/bridge/dw_hdmi.h -+++ b/include/drm/bridge/dw_hdmi.h -@@ -21,12 +21,6 @@ enum { - DW_HDMI_RES_MAX, - }; - --enum dw_hdmi_devtype { -- IMX6Q_HDMI, -- IMX6DL_HDMI, -- RK3288_HDMI, --}; -- - enum dw_hdmi_phy_type { - DW_HDMI_PHY_DWC_HDMI_TX_PHY = 0x00, - DW_HDMI_PHY_DWC_MHL_PHY_HEAC = 0xb2, -@@ -65,7 +59,6 @@ struct dw_hdmi_phy_ops { - }; - - struct dw_hdmi_plat_data { -- enum dw_hdmi_devtype dev_type; - enum drm_mode_status (*mode_valid)(struct drm_connector *connector, - struct drm_display_mode *mode); - --- -1.9.1 - diff --git a/patch/kernel/odroidc2-next/0039-ARM64-dts-meson-gxbb-p20x-add-analog-amplifier-node.patch b/patch/kernel/odroidc2-next/0039-ARM64-dts-meson-gxbb-p20x-add-analog-amplifier-node.patch new file mode 100644 index 000000000..6cda0e028 --- /dev/null +++ b/patch/kernel/odroidc2-next/0039-ARM64-dts-meson-gxbb-p20x-add-analog-amplifier-node.patch @@ -0,0 +1,34 @@ +From c834ddb8c5ca2957b7adb99a2a864f1892884e5e Mon Sep 17 00:00:00 2001 +From: Jerome Brunet +Date: Thu, 30 Mar 2017 15:32:17 +0200 +Subject: [PATCH 39/79] ARM64: dts: meson-gxbb-p20x: add analog amplifier node + +Add the node for the analog sound amplifier Dioo 2125 found on the p20x +reference design + +Signed-off-by: Jerome Brunet +Signed-off-by: Neil Armstrong +--- + arch/arm64/boot/dts/amlogic/meson-gxbb-p20x.dtsi | 6 ++++++ + 1 file changed, 6 insertions(+) + +diff --git a/arch/arm64/boot/dts/amlogic/meson-gxbb-p20x.dtsi b/arch/arm64/boot/dts/amlogic/meson-gxbb-p20x.dtsi +index 07b0f21..b9fc07c 100644 +--- a/arch/arm64/boot/dts/amlogic/meson-gxbb-p20x.dtsi ++++ b/arch/arm64/boot/dts/amlogic/meson-gxbb-p20x.dtsi +@@ -152,6 +152,12 @@ + compatible = "everest,es7134"; + status = "okay"; + }; ++ ++ amp: analog-amplifier { ++ compatible = "dioo,dio2125"; ++ enable-gpios = <&gpio GPIOH_3 0>; ++ status = "okay"; ++ }; + }; + + /* This UART is brought out to the DB9 connector */ +-- +1.9.1 + diff --git a/patch/kernel/odroidc2-next/0039-drm-bridge-dw-hdmi-Switch-to-regmap-for-register-acc.patch b/patch/kernel/odroidc2-next/0039-drm-bridge-dw-hdmi-Switch-to-regmap-for-register-acc.patch deleted file mode 100644 index e6634a9c3..000000000 --- a/patch/kernel/odroidc2-next/0039-drm-bridge-dw-hdmi-Switch-to-regmap-for-register-acc.patch +++ /dev/null @@ -1,227 +0,0 @@ -From bee2b64f57985618a1b824362c427eb469f41e06 Mon Sep 17 00:00:00 2001 -From: Neil Armstrong -Date: Fri, 3 Mar 2017 19:20:06 +0200 -Subject: [PATCH 39/93] drm: bridge: dw-hdmi: Switch to regmap for register - access - -The Synopsys Designware HDMI TX Controller does not enforce register -access on platforms instanciating it. The current driver supports two -different types of memory-mapped flat register access, but in order to -support the Amlogic Meson SoCs integration, and provide a more generic -way to handle all sorts of register mapping, switch the register access -to use the regmap infrastructure. - -In the case of registers that are not flat memory-mapped or do not -conform to the current driver implementation, a regmap struct can be -given in the plat_data and be used at probe or bind. - -Since the AHB audio driver is only available with direct memory access, -only allow the I2S audio driver to be registered is directly -memory-mapped. - -Signed-off-by: Neil Armstrong -Reviewed-by: Laurent Pinchart -Tested-by: Laurent Pinchart -Tested-by: Neil Armstrong -Reviewed-by: Jose Abreu -Signed-off-by: Archit Taneja -Link: http://patchwork.freedesktop.org/patch/msgid/20170303172007.26541-10-laurent.pinchart+renesas@ideasonboard.com ---- - drivers/gpu/drm/bridge/dw-hdmi.c | 109 +++++++++++++++++++++------------------ - include/drm/bridge/dw_hdmi.h | 1 + - 2 files changed, 59 insertions(+), 51 deletions(-) - -diff --git a/drivers/gpu/drm/bridge/dw-hdmi.c b/drivers/gpu/drm/bridge/dw-hdmi.c -index 132c006..026a0dc 100644 ---- a/drivers/gpu/drm/bridge/dw-hdmi.c -+++ b/drivers/gpu/drm/bridge/dw-hdmi.c -@@ -19,6 +19,7 @@ - #include - #include - #include -+#include - #include - - #include -@@ -171,8 +172,8 @@ struct dw_hdmi { - unsigned int audio_n; - bool audio_enable; - -- void (*write)(struct dw_hdmi *hdmi, u8 val, int offset); -- u8 (*read)(struct dw_hdmi *hdmi, int offset); -+ unsigned int reg_shift; -+ struct regmap *regm; - }; - - #define HDMI_IH_PHY_STAT0_RX_SENSE \ -@@ -183,42 +184,23 @@ struct dw_hdmi { - (HDMI_PHY_RX_SENSE0 | HDMI_PHY_RX_SENSE1 | \ - HDMI_PHY_RX_SENSE2 | HDMI_PHY_RX_SENSE3) - --static void dw_hdmi_writel(struct dw_hdmi *hdmi, u8 val, int offset) --{ -- writel(val, hdmi->regs + (offset << 2)); --} -- --static u8 dw_hdmi_readl(struct dw_hdmi *hdmi, int offset) --{ -- return readl(hdmi->regs + (offset << 2)); --} -- --static void dw_hdmi_writeb(struct dw_hdmi *hdmi, u8 val, int offset) --{ -- writeb(val, hdmi->regs + offset); --} -- --static u8 dw_hdmi_readb(struct dw_hdmi *hdmi, int offset) --{ -- return readb(hdmi->regs + offset); --} -- - static inline void hdmi_writeb(struct dw_hdmi *hdmi, u8 val, int offset) - { -- hdmi->write(hdmi, val, offset); -+ regmap_write(hdmi->regm, offset << hdmi->reg_shift, val); - } - - static inline u8 hdmi_readb(struct dw_hdmi *hdmi, int offset) - { -- return hdmi->read(hdmi, offset); -+ unsigned int val = 0; -+ -+ regmap_read(hdmi->regm, offset << hdmi->reg_shift, &val); -+ -+ return val; - } - - static void hdmi_modb(struct dw_hdmi *hdmi, u8 data, u8 mask, unsigned reg) - { -- u8 val = hdmi_readb(hdmi, reg) & ~mask; -- -- val |= data & mask; -- hdmi_writeb(hdmi, val, reg); -+ regmap_update_bits(hdmi->regm, reg << hdmi->reg_shift, mask, data); - } - - static void hdmi_mask_writeb(struct dw_hdmi *hdmi, u8 data, unsigned int reg, -@@ -1989,6 +1971,20 @@ static int dw_hdmi_detect_phy(struct dw_hdmi *hdmi) - return -ENODEV; - } - -+static const struct regmap_config hdmi_regmap_8bit_config = { -+ .reg_bits = 32, -+ .val_bits = 8, -+ .reg_stride = 1, -+ .max_register = HDMI_I2CM_FS_SCL_LCNT_0_ADDR, -+}; -+ -+static const struct regmap_config hdmi_regmap_32bit_config = { -+ .reg_bits = 32, -+ .val_bits = 32, -+ .reg_stride = 4, -+ .max_register = HDMI_I2CM_FS_SCL_LCNT_0_ADDR << 2, -+}; -+ - static struct dw_hdmi * - __dw_hdmi_probe(struct platform_device *pdev, - const struct dw_hdmi_plat_data *plat_data) -@@ -1998,7 +1994,7 @@ static int dw_hdmi_detect_phy(struct dw_hdmi *hdmi) - struct platform_device_info pdevinfo; - struct device_node *ddc_node; - struct dw_hdmi *hdmi; -- struct resource *iores; -+ struct resource *iores = NULL; - int irq; - int ret; - u32 val = 1; -@@ -2022,22 +2018,6 @@ static int dw_hdmi_detect_phy(struct dw_hdmi *hdmi) - mutex_init(&hdmi->audio_mutex); - spin_lock_init(&hdmi->audio_lock); - -- of_property_read_u32(np, "reg-io-width", &val); -- -- switch (val) { -- case 4: -- hdmi->write = dw_hdmi_writel; -- hdmi->read = dw_hdmi_readl; -- break; -- case 1: -- hdmi->write = dw_hdmi_writeb; -- hdmi->read = dw_hdmi_readb; -- break; -- default: -- dev_err(dev, "reg-io-width must be 1 or 4\n"); -- return ERR_PTR(-EINVAL); -- } -- - ddc_node = of_parse_phandle(np, "ddc-i2c-bus", 0); - if (ddc_node) { - hdmi->ddc = of_get_i2c_adapter_by_node(ddc_node); -@@ -2051,11 +2031,38 @@ static int dw_hdmi_detect_phy(struct dw_hdmi *hdmi) - dev_dbg(hdmi->dev, "no ddc property found\n"); - } - -- iores = platform_get_resource(pdev, IORESOURCE_MEM, 0); -- hdmi->regs = devm_ioremap_resource(dev, iores); -- if (IS_ERR(hdmi->regs)) { -- ret = PTR_ERR(hdmi->regs); -- goto err_res; -+ if (!plat_data->regm) { -+ const struct regmap_config *reg_config; -+ -+ of_property_read_u32(np, "reg-io-width", &val); -+ switch (val) { -+ case 4: -+ reg_config = &hdmi_regmap_32bit_config; -+ hdmi->reg_shift = 2; -+ break; -+ case 1: -+ reg_config = &hdmi_regmap_8bit_config; -+ break; -+ default: -+ dev_err(dev, "reg-io-width must be 1 or 4\n"); -+ return ERR_PTR(-EINVAL); -+ } -+ -+ iores = platform_get_resource(pdev, IORESOURCE_MEM, 0); -+ hdmi->regs = devm_ioremap_resource(dev, iores); -+ if (IS_ERR(hdmi->regs)) { -+ ret = PTR_ERR(hdmi->regs); -+ goto err_res; -+ } -+ -+ hdmi->regm = devm_regmap_init_mmio(dev, hdmi->regs, reg_config); -+ if (IS_ERR(hdmi->regm)) { -+ dev_err(dev, "Failed to configure regmap\n"); -+ ret = PTR_ERR(hdmi->regm); -+ goto err_res; -+ } -+ } else { -+ hdmi->regm = plat_data->regm; - } - - hdmi->isfr_clk = devm_clk_get(hdmi->dev, "isfr"); -@@ -2165,7 +2172,7 @@ static int dw_hdmi_detect_phy(struct dw_hdmi *hdmi) - config0 = hdmi_readb(hdmi, HDMI_CONFIG0_ID); - config3 = hdmi_readb(hdmi, HDMI_CONFIG3_ID); - -- if (config3 & HDMI_CONFIG3_AHBAUDDMA) { -+ if (iores && config3 & HDMI_CONFIG3_AHBAUDDMA) { - struct dw_hdmi_audio_data audio; - - audio.phys = iores->start; -diff --git a/include/drm/bridge/dw_hdmi.h b/include/drm/bridge/dw_hdmi.h -index 545f04fa..bcceee8 100644 ---- a/include/drm/bridge/dw_hdmi.h -+++ b/include/drm/bridge/dw_hdmi.h -@@ -59,6 +59,7 @@ struct dw_hdmi_phy_ops { - }; - - struct dw_hdmi_plat_data { -+ struct regmap *regm; - enum drm_mode_status (*mode_valid)(struct drm_connector *connector, - struct drm_display_mode *mode); - --- -1.9.1 - diff --git a/patch/kernel/odroidc2-next/0040-ARM64-dts-meson-gxbb-p20x-add-spdif-codec-node.patch b/patch/kernel/odroidc2-next/0040-ARM64-dts-meson-gxbb-p20x-add-spdif-codec-node.patch new file mode 100644 index 000000000..05b738732 --- /dev/null +++ b/patch/kernel/odroidc2-next/0040-ARM64-dts-meson-gxbb-p20x-add-spdif-codec-node.patch @@ -0,0 +1,33 @@ +From 6f0475d8b6b9792d1aee758a1674aa77a6c4232e Mon Sep 17 00:00:00 2001 +From: Jerome Brunet +Date: Thu, 30 Mar 2017 17:49:00 +0200 +Subject: [PATCH 40/79] ARM64: dts: meson-gxbb-p20x: add spdif codec node + +Add spdif-dit node to the meson gxbb reference design + +Signed-off-by: Jerome Brunet +Signed-off-by: Neil Armstrong +--- + arch/arm64/boot/dts/amlogic/meson-gxbb-p20x.dtsi | 6 ++++++ + 1 file changed, 6 insertions(+) + +diff --git a/arch/arm64/boot/dts/amlogic/meson-gxbb-p20x.dtsi b/arch/arm64/boot/dts/amlogic/meson-gxbb-p20x.dtsi +index b9fc07c..c8559be 100644 +--- a/arch/arm64/boot/dts/amlogic/meson-gxbb-p20x.dtsi ++++ b/arch/arm64/boot/dts/amlogic/meson-gxbb-p20x.dtsi +@@ -158,6 +158,12 @@ + enable-gpios = <&gpio GPIOH_3 0>; + status = "okay"; + }; ++ ++ spdif_out: spdif-out { ++ #sound-dai-cells = <0>; ++ compatible = "linux,spdif-dit"; ++ status = "okay"; ++ }; + }; + + /* This UART is brought out to the DB9 connector */ +-- +1.9.1 + diff --git a/patch/kernel/odroidc2-next/0040-drm-bridge-dw-hdmi-Move-the-driver-to-a-separate-dir.patch b/patch/kernel/odroidc2-next/0040-drm-bridge-dw-hdmi-Move-the-driver-to-a-separate-dir.patch deleted file mode 100644 index d41898b46..000000000 --- a/patch/kernel/odroidc2-next/0040-drm-bridge-dw-hdmi-Move-the-driver-to-a-separate-dir.patch +++ /dev/null @@ -1,8771 +0,0 @@ -From 4d45bc82a8f08d46123f99adec34798f8f4666fd Mon Sep 17 00:00:00 2001 -From: Laurent Pinchart -Date: Fri, 10 Mar 2017 15:48:12 +0530 -Subject: [PATCH 40/93] drm: bridge: dw-hdmi: Move the driver to a separate - directory. - -The driver is already made of 5 separate source files. Move it to a -newly created directory named synopsys where more Synopsys bridge -drivers can be added later (for the DisplayPort controller for -instance). - -Suggested-by: Jose Abreu -Signed-off-by: Laurent Pinchart -Reviewed-by: Jose Abreu -Signed-off-by: Archit Taneja -Link: http://patchwork.freedesktop.org/patch/msgid/20170303172007.26541-10-laurent.pinchart+renesas@ideasonboard.com ---- - drivers/gpu/drm/bridge/Kconfig | 26 +- - drivers/gpu/drm/bridge/Makefile | 4 +- - drivers/gpu/drm/bridge/dw-hdmi-ahb-audio.c | 652 ------ - drivers/gpu/drm/bridge/dw-hdmi-audio.h | 21 - - drivers/gpu/drm/bridge/dw-hdmi-i2s-audio.c | 141 -- - drivers/gpu/drm/bridge/dw-hdmi.c | 2314 -------------------- - drivers/gpu/drm/bridge/dw-hdmi.h | 1153 ---------- - drivers/gpu/drm/bridge/synopsys/Kconfig | 23 + - drivers/gpu/drm/bridge/synopsys/Makefile | 5 + - .../gpu/drm/bridge/synopsys/dw-hdmi-ahb-audio.c | 652 ++++++ - drivers/gpu/drm/bridge/synopsys/dw-hdmi-audio.h | 21 + - .../gpu/drm/bridge/synopsys/dw-hdmi-i2s-audio.c | 141 ++ - drivers/gpu/drm/bridge/synopsys/dw-hdmi.c | 2314 ++++++++++++++++++++ - drivers/gpu/drm/bridge/synopsys/dw-hdmi.h | 1153 ++++++++++ - 14 files changed, 4312 insertions(+), 4308 deletions(-) - delete mode 100644 drivers/gpu/drm/bridge/dw-hdmi-ahb-audio.c - delete mode 100644 drivers/gpu/drm/bridge/dw-hdmi-audio.h - delete mode 100644 drivers/gpu/drm/bridge/dw-hdmi-i2s-audio.c - delete mode 100644 drivers/gpu/drm/bridge/dw-hdmi.c - delete mode 100644 drivers/gpu/drm/bridge/dw-hdmi.h - create mode 100644 drivers/gpu/drm/bridge/synopsys/Kconfig - create mode 100644 drivers/gpu/drm/bridge/synopsys/Makefile - create mode 100644 drivers/gpu/drm/bridge/synopsys/dw-hdmi-ahb-audio.c - create mode 100644 drivers/gpu/drm/bridge/synopsys/dw-hdmi-audio.h - create mode 100644 drivers/gpu/drm/bridge/synopsys/dw-hdmi-i2s-audio.c - create mode 100644 drivers/gpu/drm/bridge/synopsys/dw-hdmi.c - create mode 100644 drivers/gpu/drm/bridge/synopsys/dw-hdmi.h - -diff --git a/drivers/gpu/drm/bridge/Kconfig b/drivers/gpu/drm/bridge/Kconfig -index eb8688e..02e211c 100644 ---- a/drivers/gpu/drm/bridge/Kconfig -+++ b/drivers/gpu/drm/bridge/Kconfig -@@ -24,30 +24,6 @@ config DRM_DUMB_VGA_DAC - help - Support for RGB to VGA DAC based bridges - --config DRM_DW_HDMI -- tristate -- select DRM_KMS_HELPER -- --config DRM_DW_HDMI_AHB_AUDIO -- tristate "Synopsis Designware AHB Audio interface" -- depends on DRM_DW_HDMI && SND -- select SND_PCM -- select SND_PCM_ELD -- select SND_PCM_IEC958 -- help -- Support the AHB Audio interface which is part of the Synopsis -- Designware HDMI block. This is used in conjunction with -- the i.MX6 HDMI driver. -- --config DRM_DW_HDMI_I2S_AUDIO -- tristate "Synopsis Designware I2S Audio interface" -- depends on SND_SOC -- depends on DRM_DW_HDMI -- select SND_SOC_HDMI_CODEC -- help -- Support the I2S Audio interface which is part of the Synopsis -- Designware HDMI block. -- - config DRM_NXP_PTN3460 - tristate "NXP PTN3460 DP/LVDS bridge" - depends on OF -@@ -101,4 +77,6 @@ source "drivers/gpu/drm/bridge/analogix/Kconfig" - - source "drivers/gpu/drm/bridge/adv7511/Kconfig" - -+source "drivers/gpu/drm/bridge/synopsys/Kconfig" -+ - endmenu -diff --git a/drivers/gpu/drm/bridge/Makefile b/drivers/gpu/drm/bridge/Makefile -index 2e83a785..103f82e 100644 ---- a/drivers/gpu/drm/bridge/Makefile -+++ b/drivers/gpu/drm/bridge/Makefile -@@ -2,9 +2,6 @@ ccflags-y := -Iinclude/drm - - obj-$(CONFIG_DRM_ANALOGIX_ANX78XX) += analogix-anx78xx.o - obj-$(CONFIG_DRM_DUMB_VGA_DAC) += dumb-vga-dac.o --obj-$(CONFIG_DRM_DW_HDMI) += dw-hdmi.o --obj-$(CONFIG_DRM_DW_HDMI_AHB_AUDIO) += dw-hdmi-ahb-audio.o --obj-$(CONFIG_DRM_DW_HDMI_I2S_AUDIO) += dw-hdmi-i2s-audio.o - obj-$(CONFIG_DRM_NXP_PTN3460) += nxp-ptn3460.o - obj-$(CONFIG_DRM_PARADE_PS8622) += parade-ps8622.o - obj-$(CONFIG_DRM_SIL_SII8620) += sil-sii8620.o -@@ -13,3 +10,4 @@ obj-$(CONFIG_DRM_TOSHIBA_TC358767) += tc358767.o - obj-$(CONFIG_DRM_ANALOGIX_DP) += analogix/ - obj-$(CONFIG_DRM_I2C_ADV7511) += adv7511/ - obj-$(CONFIG_DRM_TI_TFP410) += ti-tfp410.o -+obj-y += synopsys/ -diff --git a/drivers/gpu/drm/bridge/dw-hdmi-ahb-audio.c b/drivers/gpu/drm/bridge/dw-hdmi-ahb-audio.c -deleted file mode 100644 -index 8f2d137..0000000 ---- a/drivers/gpu/drm/bridge/dw-hdmi-ahb-audio.c -+++ /dev/null -@@ -1,652 +0,0 @@ --/* -- * DesignWare HDMI audio driver -- * -- * This program is free software; you can redistribute it and/or modify -- * it under the terms of the GNU General Public License version 2 as -- * published by the Free Software Foundation. -- * -- * Written and tested against the Designware HDMI Tx found in iMX6. -- */ --#include --#include --#include --#include --#include --#include -- --#include --#include --#include --#include --#include --#include -- --#include "dw-hdmi-audio.h" -- --#define DRIVER_NAME "dw-hdmi-ahb-audio" -- --/* Provide some bits rather than bit offsets */ --enum { -- HDMI_AHB_DMA_CONF0_SW_FIFO_RST = BIT(7), -- HDMI_AHB_DMA_CONF0_EN_HLOCK = BIT(3), -- HDMI_AHB_DMA_START_START = BIT(0), -- HDMI_AHB_DMA_STOP_STOP = BIT(0), -- HDMI_IH_MUTE_AHBDMAAUD_STAT0_ERROR = BIT(5), -- HDMI_IH_MUTE_AHBDMAAUD_STAT0_LOST = BIT(4), -- HDMI_IH_MUTE_AHBDMAAUD_STAT0_RETRY = BIT(3), -- HDMI_IH_MUTE_AHBDMAAUD_STAT0_DONE = BIT(2), -- HDMI_IH_MUTE_AHBDMAAUD_STAT0_BUFFFULL = BIT(1), -- HDMI_IH_MUTE_AHBDMAAUD_STAT0_BUFFEMPTY = BIT(0), -- HDMI_IH_MUTE_AHBDMAAUD_STAT0_ALL = -- HDMI_IH_MUTE_AHBDMAAUD_STAT0_ERROR | -- HDMI_IH_MUTE_AHBDMAAUD_STAT0_LOST | -- HDMI_IH_MUTE_AHBDMAAUD_STAT0_RETRY | -- HDMI_IH_MUTE_AHBDMAAUD_STAT0_DONE | -- HDMI_IH_MUTE_AHBDMAAUD_STAT0_BUFFFULL | -- HDMI_IH_MUTE_AHBDMAAUD_STAT0_BUFFEMPTY, -- HDMI_IH_AHBDMAAUD_STAT0_ERROR = BIT(5), -- HDMI_IH_AHBDMAAUD_STAT0_LOST = BIT(4), -- HDMI_IH_AHBDMAAUD_STAT0_RETRY = BIT(3), -- HDMI_IH_AHBDMAAUD_STAT0_DONE = BIT(2), -- HDMI_IH_AHBDMAAUD_STAT0_BUFFFULL = BIT(1), -- HDMI_IH_AHBDMAAUD_STAT0_BUFFEMPTY = BIT(0), -- HDMI_IH_AHBDMAAUD_STAT0_ALL = -- HDMI_IH_AHBDMAAUD_STAT0_ERROR | -- HDMI_IH_AHBDMAAUD_STAT0_LOST | -- HDMI_IH_AHBDMAAUD_STAT0_RETRY | -- HDMI_IH_AHBDMAAUD_STAT0_DONE | -- HDMI_IH_AHBDMAAUD_STAT0_BUFFFULL | -- HDMI_IH_AHBDMAAUD_STAT0_BUFFEMPTY, -- HDMI_AHB_DMA_CONF0_INCR16 = 2 << 1, -- HDMI_AHB_DMA_CONF0_INCR8 = 1 << 1, -- HDMI_AHB_DMA_CONF0_INCR4 = 0, -- HDMI_AHB_DMA_CONF0_BURST_MODE = BIT(0), -- HDMI_AHB_DMA_MASK_DONE = BIT(7), -- -- HDMI_REVISION_ID = 0x0001, -- HDMI_IH_AHBDMAAUD_STAT0 = 0x0109, -- HDMI_IH_MUTE_AHBDMAAUD_STAT0 = 0x0189, -- HDMI_FC_AUDICONF2 = 0x1027, -- HDMI_FC_AUDSCONF = 0x1063, -- HDMI_FC_AUDSCONF_LAYOUT1 = 1 << 0, -- HDMI_FC_AUDSCONF_LAYOUT0 = 0 << 0, -- HDMI_AHB_DMA_CONF0 = 0x3600, -- HDMI_AHB_DMA_START = 0x3601, -- HDMI_AHB_DMA_STOP = 0x3602, -- HDMI_AHB_DMA_THRSLD = 0x3603, -- HDMI_AHB_DMA_STRADDR0 = 0x3604, -- HDMI_AHB_DMA_STPADDR0 = 0x3608, -- HDMI_AHB_DMA_MASK = 0x3614, -- HDMI_AHB_DMA_POL = 0x3615, -- HDMI_AHB_DMA_CONF1 = 0x3616, -- HDMI_AHB_DMA_BUFFPOL = 0x361a, --}; -- --struct dw_hdmi_channel_conf { -- u8 conf1; -- u8 ca; --}; -- --/* -- * The default mapping of ALSA channels to HDMI channels and speaker -- * allocation bits. Note that we can't do channel remapping here - -- * channels must be in the same order. -- * -- * Mappings for alsa-lib pcm/surround*.conf files: -- * -- * Front Sur4.0 Sur4.1 Sur5.0 Sur5.1 Sur7.1 -- * Channels 2 4 6 6 6 8 -- * -- * Our mapping from ALSA channel to CEA686D speaker name and HDMI channel: -- * -- * Number of ALSA channels -- * ALSA Channel 2 3 4 5 6 7 8 -- * 0 FL:0 = = = = = = -- * 1 FR:1 = = = = = = -- * 2 FC:3 RL:4 LFE:2 = = = -- * 3 RR:5 RL:4 FC:3 = = -- * 4 RR:5 RL:4 = = -- * 5 RR:5 = = -- * 6 RC:6 = -- * 7 RLC/FRC RLC/FRC -- */ --static struct dw_hdmi_channel_conf default_hdmi_channel_config[7] = { -- { 0x03, 0x00 }, /* FL,FR */ -- { 0x0b, 0x02 }, /* FL,FR,FC */ -- { 0x33, 0x08 }, /* FL,FR,RL,RR */ -- { 0x37, 0x09 }, /* FL,FR,LFE,RL,RR */ -- { 0x3f, 0x0b }, /* FL,FR,LFE,FC,RL,RR */ -- { 0x7f, 0x0f }, /* FL,FR,LFE,FC,RL,RR,RC */ -- { 0xff, 0x13 }, /* FL,FR,LFE,FC,RL,RR,[FR]RC,[FR]LC */ --}; -- --struct snd_dw_hdmi { -- struct snd_card *card; -- struct snd_pcm *pcm; -- spinlock_t lock; -- struct dw_hdmi_audio_data data; -- struct snd_pcm_substream *substream; -- void (*reformat)(struct snd_dw_hdmi *, size_t, size_t); -- void *buf_src; -- void *buf_dst; -- dma_addr_t buf_addr; -- unsigned buf_offset; -- unsigned buf_period; -- unsigned buf_size; -- unsigned channels; -- u8 revision; -- u8 iec_offset; -- u8 cs[192][8]; --}; -- --static void dw_hdmi_writel(u32 val, void __iomem *ptr) --{ -- writeb_relaxed(val, ptr); -- writeb_relaxed(val >> 8, ptr + 1); -- writeb_relaxed(val >> 16, ptr + 2); -- writeb_relaxed(val >> 24, ptr + 3); --} -- --/* -- * Convert to hardware format: The userspace buffer contains IEC958 samples, -- * with the PCUV bits in bits 31..28 and audio samples in bits 27..4. We -- * need these to be in bits 27..24, with the IEC B bit in bit 28, and audio -- * samples in 23..0. -- * -- * Default preamble in bits 3..0: 8 = block start, 4 = even 2 = odd -- * -- * Ideally, we could do with having the data properly formatted in userspace. -- */ --static void dw_hdmi_reformat_iec958(struct snd_dw_hdmi *dw, -- size_t offset, size_t bytes) --{ -- u32 *src = dw->buf_src + offset; -- u32 *dst = dw->buf_dst + offset; -- u32 *end = dw->buf_src + offset + bytes; -- -- do { -- u32 b, sample = *src++; -- -- b = (sample & 8) << (28 - 3); -- -- sample >>= 4; -- -- *dst++ = sample | b; -- } while (src < end); --} -- --static u32 parity(u32 sample) --{ -- sample ^= sample >> 16; -- sample ^= sample >> 8; -- sample ^= sample >> 4; -- sample ^= sample >> 2; -- sample ^= sample >> 1; -- return (sample & 1) << 27; --} -- --static void dw_hdmi_reformat_s24(struct snd_dw_hdmi *dw, -- size_t offset, size_t bytes) --{ -- u32 *src = dw->buf_src + offset; -- u32 *dst = dw->buf_dst + offset; -- u32 *end = dw->buf_src + offset + bytes; -- -- do { -- unsigned i; -- u8 *cs; -- -- cs = dw->cs[dw->iec_offset++]; -- if (dw->iec_offset >= 192) -- dw->iec_offset = 0; -- -- i = dw->channels; -- do { -- u32 sample = *src++; -- -- sample &= ~0xff000000; -- sample |= *cs++ << 24; -- sample |= parity(sample & ~0xf8000000); -- -- *dst++ = sample; -- } while (--i); -- } while (src < end); --} -- --static void dw_hdmi_create_cs(struct snd_dw_hdmi *dw, -- struct snd_pcm_runtime *runtime) --{ -- u8 cs[4]; -- unsigned ch, i, j; -- -- snd_pcm_create_iec958_consumer(runtime, cs, sizeof(cs)); -- -- memset(dw->cs, 0, sizeof(dw->cs)); -- -- for (ch = 0; ch < 8; ch++) { -- cs[2] &= ~IEC958_AES2_CON_CHANNEL; -- cs[2] |= (ch + 1) << 4; -- -- for (i = 0; i < ARRAY_SIZE(cs); i++) { -- unsigned c = cs[i]; -- -- for (j = 0; j < 8; j++, c >>= 1) -- dw->cs[i * 8 + j][ch] = (c & 1) << 2; -- } -- } -- dw->cs[0][0] |= BIT(4); --} -- --static void dw_hdmi_start_dma(struct snd_dw_hdmi *dw) --{ -- void __iomem *base = dw->data.base; -- unsigned offset = dw->buf_offset; -- unsigned period = dw->buf_period; -- u32 start, stop; -- -- dw->reformat(dw, offset, period); -- -- /* Clear all irqs before enabling irqs and starting DMA */ -- writeb_relaxed(HDMI_IH_AHBDMAAUD_STAT0_ALL, -- base + HDMI_IH_AHBDMAAUD_STAT0); -- -- start = dw->buf_addr + offset; -- stop = start + period - 1; -- -- /* Setup the hardware start/stop addresses */ -- dw_hdmi_writel(start, base + HDMI_AHB_DMA_STRADDR0); -- dw_hdmi_writel(stop, base + HDMI_AHB_DMA_STPADDR0); -- -- writeb_relaxed((u8)~HDMI_AHB_DMA_MASK_DONE, base + HDMI_AHB_DMA_MASK); -- writeb(HDMI_AHB_DMA_START_START, base + HDMI_AHB_DMA_START); -- -- offset += period; -- if (offset >= dw->buf_size) -- offset = 0; -- dw->buf_offset = offset; --} -- --static void dw_hdmi_stop_dma(struct snd_dw_hdmi *dw) --{ -- /* Disable interrupts before disabling DMA */ -- writeb_relaxed(~0, dw->data.base + HDMI_AHB_DMA_MASK); -- writeb_relaxed(HDMI_AHB_DMA_STOP_STOP, dw->data.base + HDMI_AHB_DMA_STOP); --} -- --static irqreturn_t snd_dw_hdmi_irq(int irq, void *data) --{ -- struct snd_dw_hdmi *dw = data; -- struct snd_pcm_substream *substream; -- unsigned stat; -- -- stat = readb_relaxed(dw->data.base + HDMI_IH_AHBDMAAUD_STAT0); -- if (!stat) -- return IRQ_NONE; -- -- writeb_relaxed(stat, dw->data.base + HDMI_IH_AHBDMAAUD_STAT0); -- -- substream = dw->substream; -- if (stat & HDMI_IH_AHBDMAAUD_STAT0_DONE && substream) { -- snd_pcm_period_elapsed(substream); -- -- spin_lock(&dw->lock); -- if (dw->substream) -- dw_hdmi_start_dma(dw); -- spin_unlock(&dw->lock); -- } -- -- return IRQ_HANDLED; --} -- --static struct snd_pcm_hardware dw_hdmi_hw = { -- .info = SNDRV_PCM_INFO_INTERLEAVED | -- SNDRV_PCM_INFO_BLOCK_TRANSFER | -- SNDRV_PCM_INFO_MMAP | -- SNDRV_PCM_INFO_MMAP_VALID, -- .formats = SNDRV_PCM_FMTBIT_IEC958_SUBFRAME_LE | -- SNDRV_PCM_FMTBIT_S24_LE, -- .rates = SNDRV_PCM_RATE_32000 | -- SNDRV_PCM_RATE_44100 | -- SNDRV_PCM_RATE_48000 | -- SNDRV_PCM_RATE_88200 | -- SNDRV_PCM_RATE_96000 | -- SNDRV_PCM_RATE_176400 | -- SNDRV_PCM_RATE_192000, -- .channels_min = 2, -- .channels_max = 8, -- .buffer_bytes_max = 1024 * 1024, -- .period_bytes_min = 256, -- .period_bytes_max = 8192, /* ERR004323: must limit to 8k */ -- .periods_min = 2, -- .periods_max = 16, -- .fifo_size = 0, --}; -- --static int dw_hdmi_open(struct snd_pcm_substream *substream) --{ -- struct snd_pcm_runtime *runtime = substream->runtime; -- struct snd_dw_hdmi *dw = substream->private_data; -- void __iomem *base = dw->data.base; -- int ret; -- -- runtime->hw = dw_hdmi_hw; -- -- ret = snd_pcm_hw_constraint_eld(runtime, dw->data.eld); -- if (ret < 0) -- return ret; -- -- ret = snd_pcm_limit_hw_rates(runtime); -- if (ret < 0) -- return ret; -- -- ret = snd_pcm_hw_constraint_integer(runtime, -- SNDRV_PCM_HW_PARAM_PERIODS); -- if (ret < 0) -- return ret; -- -- /* Limit the buffer size to the size of the preallocated buffer */ -- ret = snd_pcm_hw_constraint_minmax(runtime, -- SNDRV_PCM_HW_PARAM_BUFFER_SIZE, -- 0, substream->dma_buffer.bytes); -- if (ret < 0) -- return ret; -- -- /* Clear FIFO */ -- writeb_relaxed(HDMI_AHB_DMA_CONF0_SW_FIFO_RST, -- base + HDMI_AHB_DMA_CONF0); -- -- /* Configure interrupt polarities */ -- writeb_relaxed(~0, base + HDMI_AHB_DMA_POL); -- writeb_relaxed(~0, base + HDMI_AHB_DMA_BUFFPOL); -- -- /* Keep interrupts masked, and clear any pending */ -- writeb_relaxed(~0, base + HDMI_AHB_DMA_MASK); -- writeb_relaxed(~0, base + HDMI_IH_AHBDMAAUD_STAT0); -- -- ret = request_irq(dw->data.irq, snd_dw_hdmi_irq, IRQF_SHARED, -- "dw-hdmi-audio", dw); -- if (ret) -- return ret; -- -- /* Un-mute done interrupt */ -- writeb_relaxed(HDMI_IH_MUTE_AHBDMAAUD_STAT0_ALL & -- ~HDMI_IH_MUTE_AHBDMAAUD_STAT0_DONE, -- base + HDMI_IH_MUTE_AHBDMAAUD_STAT0); -- -- return 0; --} -- --static int dw_hdmi_close(struct snd_pcm_substream *substream) --{ -- struct snd_dw_hdmi *dw = substream->private_data; -- -- /* Mute all interrupts */ -- writeb_relaxed(HDMI_IH_MUTE_AHBDMAAUD_STAT0_ALL, -- dw->data.base + HDMI_IH_MUTE_AHBDMAAUD_STAT0); -- -- free_irq(dw->data.irq, dw); -- -- return 0; --} -- --static int dw_hdmi_hw_free(struct snd_pcm_substream *substream) --{ -- return snd_pcm_lib_free_vmalloc_buffer(substream); --} -- --static int dw_hdmi_hw_params(struct snd_pcm_substream *substream, -- struct snd_pcm_hw_params *params) --{ -- /* Allocate the PCM runtime buffer, which is exposed to userspace. */ -- return snd_pcm_lib_alloc_vmalloc_buffer(substream, -- params_buffer_bytes(params)); --} -- --static int dw_hdmi_prepare(struct snd_pcm_substream *substream) --{ -- struct snd_pcm_runtime *runtime = substream->runtime; -- struct snd_dw_hdmi *dw = substream->private_data; -- u8 threshold, conf0, conf1, layout, ca; -- -- /* Setup as per 3.0.5 FSL 4.1.0 BSP */ -- switch (dw->revision) { -- case 0x0a: -- conf0 = HDMI_AHB_DMA_CONF0_BURST_MODE | -- HDMI_AHB_DMA_CONF0_INCR4; -- if (runtime->channels == 2) -- threshold = 126; -- else -- threshold = 124; -- break; -- case 0x1a: -- conf0 = HDMI_AHB_DMA_CONF0_BURST_MODE | -- HDMI_AHB_DMA_CONF0_INCR8; -- threshold = 128; -- break; -- default: -- /* NOTREACHED */ -- return -EINVAL; -- } -- -- dw_hdmi_set_sample_rate(dw->data.hdmi, runtime->rate); -- -- /* Minimum number of bytes in the fifo. */ -- runtime->hw.fifo_size = threshold * 32; -- -- conf0 |= HDMI_AHB_DMA_CONF0_EN_HLOCK; -- conf1 = default_hdmi_channel_config[runtime->channels - 2].conf1; -- ca = default_hdmi_channel_config[runtime->channels - 2].ca; -- -- /* -- * For >2 channel PCM audio, we need to select layout 1 -- * and set an appropriate channel map. -- */ -- if (runtime->channels > 2) -- layout = HDMI_FC_AUDSCONF_LAYOUT1; -- else -- layout = HDMI_FC_AUDSCONF_LAYOUT0; -- -- writeb_relaxed(threshold, dw->data.base + HDMI_AHB_DMA_THRSLD); -- writeb_relaxed(conf0, dw->data.base + HDMI_AHB_DMA_CONF0); -- writeb_relaxed(conf1, dw->data.base + HDMI_AHB_DMA_CONF1); -- writeb_relaxed(layout, dw->data.base + HDMI_FC_AUDSCONF); -- writeb_relaxed(ca, dw->data.base + HDMI_FC_AUDICONF2); -- -- switch (runtime->format) { -- case SNDRV_PCM_FORMAT_IEC958_SUBFRAME_LE: -- dw->reformat = dw_hdmi_reformat_iec958; -- break; -- case SNDRV_PCM_FORMAT_S24_LE: -- dw_hdmi_create_cs(dw, runtime); -- dw->reformat = dw_hdmi_reformat_s24; -- break; -- } -- dw->iec_offset = 0; -- dw->channels = runtime->channels; -- dw->buf_src = runtime->dma_area; -- dw->buf_dst = substream->dma_buffer.area; -- dw->buf_addr = substream->dma_buffer.addr; -- dw->buf_period = snd_pcm_lib_period_bytes(substream); -- dw->buf_size = snd_pcm_lib_buffer_bytes(substream); -- -- return 0; --} -- --static int dw_hdmi_trigger(struct snd_pcm_substream *substream, int cmd) --{ -- struct snd_dw_hdmi *dw = substream->private_data; -- unsigned long flags; -- int ret = 0; -- -- switch (cmd) { -- case SNDRV_PCM_TRIGGER_START: -- spin_lock_irqsave(&dw->lock, flags); -- dw->buf_offset = 0; -- dw->substream = substream; -- dw_hdmi_start_dma(dw); -- dw_hdmi_audio_enable(dw->data.hdmi); -- spin_unlock_irqrestore(&dw->lock, flags); -- substream->runtime->delay = substream->runtime->period_size; -- break; -- -- case SNDRV_PCM_TRIGGER_STOP: -- spin_lock_irqsave(&dw->lock, flags); -- dw->substream = NULL; -- dw_hdmi_stop_dma(dw); -- dw_hdmi_audio_disable(dw->data.hdmi); -- spin_unlock_irqrestore(&dw->lock, flags); -- break; -- -- default: -- ret = -EINVAL; -- break; -- } -- -- return ret; --} -- --static snd_pcm_uframes_t dw_hdmi_pointer(struct snd_pcm_substream *substream) --{ -- struct snd_pcm_runtime *runtime = substream->runtime; -- struct snd_dw_hdmi *dw = substream->private_data; -- -- /* -- * We are unable to report the exact hardware position as -- * reading the 32-bit DMA position using 8-bit reads is racy. -- */ -- return bytes_to_frames(runtime, dw->buf_offset); --} -- --static struct snd_pcm_ops snd_dw_hdmi_ops = { -- .open = dw_hdmi_open, -- .close = dw_hdmi_close, -- .ioctl = snd_pcm_lib_ioctl, -- .hw_params = dw_hdmi_hw_params, -- .hw_free = dw_hdmi_hw_free, -- .prepare = dw_hdmi_prepare, -- .trigger = dw_hdmi_trigger, -- .pointer = dw_hdmi_pointer, -- .page = snd_pcm_lib_get_vmalloc_page, --}; -- --static int snd_dw_hdmi_probe(struct platform_device *pdev) --{ -- const struct dw_hdmi_audio_data *data = pdev->dev.platform_data; -- struct device *dev = pdev->dev.parent; -- struct snd_dw_hdmi *dw; -- struct snd_card *card; -- struct snd_pcm *pcm; -- unsigned revision; -- int ret; -- -- writeb_relaxed(HDMI_IH_MUTE_AHBDMAAUD_STAT0_ALL, -- data->base + HDMI_IH_MUTE_AHBDMAAUD_STAT0); -- revision = readb_relaxed(data->base + HDMI_REVISION_ID); -- if (revision != 0x0a && revision != 0x1a) { -- dev_err(dev, "dw-hdmi-audio: unknown revision 0x%02x\n", -- revision); -- return -ENXIO; -- } -- -- ret = snd_card_new(dev, SNDRV_DEFAULT_IDX1, SNDRV_DEFAULT_STR1, -- THIS_MODULE, sizeof(struct snd_dw_hdmi), &card); -- if (ret < 0) -- return ret; -- -- strlcpy(card->driver, DRIVER_NAME, sizeof(card->driver)); -- strlcpy(card->shortname, "DW-HDMI", sizeof(card->shortname)); -- snprintf(card->longname, sizeof(card->longname), -- "%s rev 0x%02x, irq %d", card->shortname, revision, -- data->irq); -- -- dw = card->private_data; -- dw->card = card; -- dw->data = *data; -- dw->revision = revision; -- -- spin_lock_init(&dw->lock); -- -- ret = snd_pcm_new(card, "DW HDMI", 0, 1, 0, &pcm); -- if (ret < 0) -- goto err; -- -- dw->pcm = pcm; -- pcm->private_data = dw; -- strlcpy(pcm->name, DRIVER_NAME, sizeof(pcm->name)); -- snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK, &snd_dw_hdmi_ops); -- -- /* -- * To support 8-channel 96kHz audio reliably, we need 512k -- * to satisfy alsa with our restricted period (ERR004323). -- */ -- snd_pcm_lib_preallocate_pages_for_all(pcm, SNDRV_DMA_TYPE_DEV, -- dev, 128 * 1024, 1024 * 1024); -- -- ret = snd_card_register(card); -- if (ret < 0) -- goto err; -- -- platform_set_drvdata(pdev, dw); -- -- return 0; -- --err: -- snd_card_free(card); -- return ret; --} -- --static int snd_dw_hdmi_remove(struct platform_device *pdev) --{ -- struct snd_dw_hdmi *dw = platform_get_drvdata(pdev); -- -- snd_card_free(dw->card); -- -- return 0; --} -- --#if defined(CONFIG_PM_SLEEP) && defined(IS_NOT_BROKEN) --/* -- * This code is fine, but requires implementation in the dw_hdmi_trigger() -- * method which is currently missing as I have no way to test this. -- */ --static int snd_dw_hdmi_suspend(struct device *dev) --{ -- struct snd_dw_hdmi *dw = dev_get_drvdata(dev); -- -- snd_power_change_state(dw->card, SNDRV_CTL_POWER_D3cold); -- snd_pcm_suspend_all(dw->pcm); -- -- return 0; --} -- --static int snd_dw_hdmi_resume(struct device *dev) --{ -- struct snd_dw_hdmi *dw = dev_get_drvdata(dev); -- -- snd_power_change_state(dw->card, SNDRV_CTL_POWER_D0); -- -- return 0; --} -- --static SIMPLE_DEV_PM_OPS(snd_dw_hdmi_pm, snd_dw_hdmi_suspend, -- snd_dw_hdmi_resume); --#define PM_OPS &snd_dw_hdmi_pm --#else --#define PM_OPS NULL --#endif -- --static struct platform_driver snd_dw_hdmi_driver = { -- .probe = snd_dw_hdmi_probe, -- .remove = snd_dw_hdmi_remove, -- .driver = { -- .name = DRIVER_NAME, -- .pm = PM_OPS, -- }, --}; -- --module_platform_driver(snd_dw_hdmi_driver); -- --MODULE_AUTHOR("Russell King "); --MODULE_DESCRIPTION("Synopsis Designware HDMI AHB ALSA interface"); --MODULE_LICENSE("GPL v2"); --MODULE_ALIAS("platform:" DRIVER_NAME); -diff --git a/drivers/gpu/drm/bridge/dw-hdmi-audio.h b/drivers/gpu/drm/bridge/dw-hdmi-audio.h -deleted file mode 100644 -index fd1f745..0000000 ---- a/drivers/gpu/drm/bridge/dw-hdmi-audio.h -+++ /dev/null -@@ -1,21 +0,0 @@ --#ifndef DW_HDMI_AUDIO_H --#define DW_HDMI_AUDIO_H -- --struct dw_hdmi; -- --struct dw_hdmi_audio_data { -- phys_addr_t phys; -- void __iomem *base; -- int irq; -- struct dw_hdmi *hdmi; -- u8 *eld; --}; -- --struct dw_hdmi_i2s_audio_data { -- struct dw_hdmi *hdmi; -- -- void (*write)(struct dw_hdmi *hdmi, u8 val, int offset); -- u8 (*read)(struct dw_hdmi *hdmi, int offset); --}; -- --#endif -diff --git a/drivers/gpu/drm/bridge/dw-hdmi-i2s-audio.c b/drivers/gpu/drm/bridge/dw-hdmi-i2s-audio.c -deleted file mode 100644 -index aaf287d..0000000 ---- a/drivers/gpu/drm/bridge/dw-hdmi-i2s-audio.c -+++ /dev/null -@@ -1,141 +0,0 @@ --/* -- * dw-hdmi-i2s-audio.c -- * -- * Copyright (c) 2016 Kuninori Morimoto -- * -- * This program is free software; you can redistribute it and/or modify -- * it under the terms of the GNU General Public License version 2 as -- * published by the Free Software Foundation. -- */ --#include -- --#include -- --#include "dw-hdmi.h" --#include "dw-hdmi-audio.h" -- --#define DRIVER_NAME "dw-hdmi-i2s-audio" -- --static inline void hdmi_write(struct dw_hdmi_i2s_audio_data *audio, -- u8 val, int offset) --{ -- struct dw_hdmi *hdmi = audio->hdmi; -- -- audio->write(hdmi, val, offset); --} -- --static inline u8 hdmi_read(struct dw_hdmi_i2s_audio_data *audio, int offset) --{ -- struct dw_hdmi *hdmi = audio->hdmi; -- -- return audio->read(hdmi, offset); --} -- --static int dw_hdmi_i2s_hw_params(struct device *dev, void *data, -- struct hdmi_codec_daifmt *fmt, -- struct hdmi_codec_params *hparms) --{ -- struct dw_hdmi_i2s_audio_data *audio = data; -- struct dw_hdmi *hdmi = audio->hdmi; -- u8 conf0 = 0; -- u8 conf1 = 0; -- u8 inputclkfs = 0; -- -- /* it cares I2S only */ -- if ((fmt->fmt != HDMI_I2S) || -- (fmt->bit_clk_master | fmt->frame_clk_master)) { -- dev_err(dev, "unsupported format/settings\n"); -- return -EINVAL; -- } -- -- inputclkfs = HDMI_AUD_INPUTCLKFS_64FS; -- conf0 = HDMI_AUD_CONF0_I2S_ALL_ENABLE; -- -- switch (hparms->sample_width) { -- case 16: -- conf1 = HDMI_AUD_CONF1_WIDTH_16; -- break; -- case 24: -- case 32: -- conf1 = HDMI_AUD_CONF1_WIDTH_24; -- break; -- } -- -- dw_hdmi_set_sample_rate(hdmi, hparms->sample_rate); -- -- hdmi_write(audio, inputclkfs, HDMI_AUD_INPUTCLKFS); -- hdmi_write(audio, conf0, HDMI_AUD_CONF0); -- hdmi_write(audio, conf1, HDMI_AUD_CONF1); -- -- dw_hdmi_audio_enable(hdmi); -- -- return 0; --} -- --static void dw_hdmi_i2s_audio_shutdown(struct device *dev, void *data) --{ -- struct dw_hdmi_i2s_audio_data *audio = data; -- struct dw_hdmi *hdmi = audio->hdmi; -- -- dw_hdmi_audio_disable(hdmi); -- -- hdmi_write(audio, HDMI_AUD_CONF0_SW_RESET, HDMI_AUD_CONF0); --} -- --static struct hdmi_codec_ops dw_hdmi_i2s_ops = { -- .hw_params = dw_hdmi_i2s_hw_params, -- .audio_shutdown = dw_hdmi_i2s_audio_shutdown, --}; -- --static int snd_dw_hdmi_probe(struct platform_device *pdev) --{ -- struct dw_hdmi_i2s_audio_data *audio = pdev->dev.platform_data; -- struct platform_device_info pdevinfo; -- struct hdmi_codec_pdata pdata; -- struct platform_device *platform; -- -- pdata.ops = &dw_hdmi_i2s_ops; -- pdata.i2s = 1; -- pdata.max_i2s_channels = 6; -- pdata.data = audio; -- -- memset(&pdevinfo, 0, sizeof(pdevinfo)); -- pdevinfo.parent = pdev->dev.parent; -- pdevinfo.id = PLATFORM_DEVID_AUTO; -- pdevinfo.name = HDMI_CODEC_DRV_NAME; -- pdevinfo.data = &pdata; -- pdevinfo.size_data = sizeof(pdata); -- pdevinfo.dma_mask = DMA_BIT_MASK(32); -- -- platform = platform_device_register_full(&pdevinfo); -- if (IS_ERR(platform)) -- return PTR_ERR(platform); -- -- dev_set_drvdata(&pdev->dev, platform); -- -- return 0; --} -- --static int snd_dw_hdmi_remove(struct platform_device *pdev) --{ -- struct platform_device *platform = dev_get_drvdata(&pdev->dev); -- -- platform_device_unregister(platform); -- -- return 0; --} -- --static struct platform_driver snd_dw_hdmi_driver = { -- .probe = snd_dw_hdmi_probe, -- .remove = snd_dw_hdmi_remove, -- .driver = { -- .name = DRIVER_NAME, -- .owner = THIS_MODULE, -- }, --}; --module_platform_driver(snd_dw_hdmi_driver); -- --MODULE_AUTHOR("Kuninori Morimoto "); --MODULE_DESCRIPTION("Synopsis Designware HDMI I2S ALSA SoC interface"); --MODULE_LICENSE("GPL v2"); --MODULE_ALIAS("platform:" DRIVER_NAME); -diff --git a/drivers/gpu/drm/bridge/dw-hdmi.c b/drivers/gpu/drm/bridge/dw-hdmi.c -deleted file mode 100644 -index 026a0dc..0000000 ---- a/drivers/gpu/drm/bridge/dw-hdmi.c -+++ /dev/null -@@ -1,2314 +0,0 @@ --/* -- * DesignWare High-Definition Multimedia Interface (HDMI) driver -- * -- * Copyright (C) 2013-2015 Mentor Graphics Inc. -- * Copyright (C) 2011-2013 Freescale Semiconductor, Inc. -- * Copyright (C) 2010, Guennadi Liakhovetski -- * -- * This program is free software; you can redistribute it and/or modify -- * it under the terms of the GNU General Public License as published by -- * the Free Software Foundation; either version 2 of the License, or -- * (at your option) any later version. -- * -- */ --#include --#include --#include --#include --#include --#include --#include --#include --#include --#include -- --#include --#include --#include --#include --#include --#include --#include -- --#include "dw-hdmi.h" --#include "dw-hdmi-audio.h" -- --#define HDMI_EDID_LEN 512 -- --#define RGB 0 --#define YCBCR444 1 --#define YCBCR422_16BITS 2 --#define YCBCR422_8BITS 3 --#define XVYCC444 4 -- --enum hdmi_datamap { -- RGB444_8B = 0x01, -- RGB444_10B = 0x03, -- RGB444_12B = 0x05, -- RGB444_16B = 0x07, -- YCbCr444_8B = 0x09, -- YCbCr444_10B = 0x0B, -- YCbCr444_12B = 0x0D, -- YCbCr444_16B = 0x0F, -- YCbCr422_8B = 0x16, -- YCbCr422_10B = 0x14, -- YCbCr422_12B = 0x12, --}; -- --static const u16 csc_coeff_default[3][4] = { -- { 0x2000, 0x0000, 0x0000, 0x0000 }, -- { 0x0000, 0x2000, 0x0000, 0x0000 }, -- { 0x0000, 0x0000, 0x2000, 0x0000 } --}; -- --static const u16 csc_coeff_rgb_out_eitu601[3][4] = { -- { 0x2000, 0x6926, 0x74fd, 0x010e }, -- { 0x2000, 0x2cdd, 0x0000, 0x7e9a }, -- { 0x2000, 0x0000, 0x38b4, 0x7e3b } --}; -- --static const u16 csc_coeff_rgb_out_eitu709[3][4] = { -- { 0x2000, 0x7106, 0x7a02, 0x00a7 }, -- { 0x2000, 0x3264, 0x0000, 0x7e6d }, -- { 0x2000, 0x0000, 0x3b61, 0x7e25 } --}; -- --static const u16 csc_coeff_rgb_in_eitu601[3][4] = { -- { 0x2591, 0x1322, 0x074b, 0x0000 }, -- { 0x6535, 0x2000, 0x7acc, 0x0200 }, -- { 0x6acd, 0x7534, 0x2000, 0x0200 } --}; -- --static const u16 csc_coeff_rgb_in_eitu709[3][4] = { -- { 0x2dc5, 0x0d9b, 0x049e, 0x0000 }, -- { 0x62f0, 0x2000, 0x7d11, 0x0200 }, -- { 0x6756, 0x78ab, 0x2000, 0x0200 } --}; -- --struct hdmi_vmode { -- bool mdataenablepolarity; -- -- unsigned int mpixelclock; -- unsigned int mpixelrepetitioninput; -- unsigned int mpixelrepetitionoutput; --}; -- --struct hdmi_data_info { -- unsigned int enc_in_format; -- unsigned int enc_out_format; -- unsigned int enc_color_depth; -- unsigned int colorimetry; -- unsigned int pix_repet_factor; -- unsigned int hdcp_enable; -- struct hdmi_vmode video_mode; --}; -- --struct dw_hdmi_i2c { -- struct i2c_adapter adap; -- -- struct mutex lock; /* used to serialize data transfers */ -- struct completion cmp; -- u8 stat; -- -- u8 slave_reg; -- bool is_regaddr; --}; -- --struct dw_hdmi_phy_data { -- enum dw_hdmi_phy_type type; -- const char *name; -- unsigned int gen; -- bool has_svsret; -- int (*configure)(struct dw_hdmi *hdmi, -- const struct dw_hdmi_plat_data *pdata, -- unsigned long mpixelclock); --}; -- --struct dw_hdmi { -- struct drm_connector connector; -- struct drm_bridge bridge; -- -- unsigned int version; -- -- struct platform_device *audio; -- struct device *dev; -- struct clk *isfr_clk; -- struct clk *iahb_clk; -- struct dw_hdmi_i2c *i2c; -- -- struct hdmi_data_info hdmi_data; -- const struct dw_hdmi_plat_data *plat_data; -- -- int vic; -- -- u8 edid[HDMI_EDID_LEN]; -- bool cable_plugin; -- -- struct { -- const struct dw_hdmi_phy_ops *ops; -- const char *name; -- void *data; -- bool enabled; -- } phy; -- -- struct drm_display_mode previous_mode; -- -- struct i2c_adapter *ddc; -- void __iomem *regs; -- bool sink_is_hdmi; -- bool sink_has_audio; -- -- struct mutex mutex; /* for state below and previous_mode */ -- enum drm_connector_force force; /* mutex-protected force state */ -- bool disabled; /* DRM has disabled our bridge */ -- bool bridge_is_on; /* indicates the bridge is on */ -- bool rxsense; /* rxsense state */ -- u8 phy_mask; /* desired phy int mask settings */ -- -- spinlock_t audio_lock; -- struct mutex audio_mutex; -- unsigned int sample_rate; -- unsigned int audio_cts; -- unsigned int audio_n; -- bool audio_enable; -- -- unsigned int reg_shift; -- struct regmap *regm; --}; -- --#define HDMI_IH_PHY_STAT0_RX_SENSE \ -- (HDMI_IH_PHY_STAT0_RX_SENSE0 | HDMI_IH_PHY_STAT0_RX_SENSE1 | \ -- HDMI_IH_PHY_STAT0_RX_SENSE2 | HDMI_IH_PHY_STAT0_RX_SENSE3) -- --#define HDMI_PHY_RX_SENSE \ -- (HDMI_PHY_RX_SENSE0 | HDMI_PHY_RX_SENSE1 | \ -- HDMI_PHY_RX_SENSE2 | HDMI_PHY_RX_SENSE3) -- --static inline void hdmi_writeb(struct dw_hdmi *hdmi, u8 val, int offset) --{ -- regmap_write(hdmi->regm, offset << hdmi->reg_shift, val); --} -- --static inline u8 hdmi_readb(struct dw_hdmi *hdmi, int offset) --{ -- unsigned int val = 0; -- -- regmap_read(hdmi->regm, offset << hdmi->reg_shift, &val); -- -- return val; --} -- --static void hdmi_modb(struct dw_hdmi *hdmi, u8 data, u8 mask, unsigned reg) --{ -- regmap_update_bits(hdmi->regm, reg << hdmi->reg_shift, mask, data); --} -- --static void hdmi_mask_writeb(struct dw_hdmi *hdmi, u8 data, unsigned int reg, -- u8 shift, u8 mask) --{ -- hdmi_modb(hdmi, data << shift, mask, reg); --} -- --static void dw_hdmi_i2c_init(struct dw_hdmi *hdmi) --{ -- /* Software reset */ -- hdmi_writeb(hdmi, 0x00, HDMI_I2CM_SOFTRSTZ); -- -- /* Set Standard Mode speed (determined to be 100KHz on iMX6) */ -- hdmi_writeb(hdmi, 0x00, HDMI_I2CM_DIV); -- -- /* Set done, not acknowledged and arbitration interrupt polarities */ -- hdmi_writeb(hdmi, HDMI_I2CM_INT_DONE_POL, HDMI_I2CM_INT); -- hdmi_writeb(hdmi, HDMI_I2CM_CTLINT_NAC_POL | HDMI_I2CM_CTLINT_ARB_POL, -- HDMI_I2CM_CTLINT); -- -- /* Clear DONE and ERROR interrupts */ -- hdmi_writeb(hdmi, HDMI_IH_I2CM_STAT0_ERROR | HDMI_IH_I2CM_STAT0_DONE, -- HDMI_IH_I2CM_STAT0); -- -- /* Mute DONE and ERROR interrupts */ -- hdmi_writeb(hdmi, HDMI_IH_I2CM_STAT0_ERROR | HDMI_IH_I2CM_STAT0_DONE, -- HDMI_IH_MUTE_I2CM_STAT0); --} -- --static int dw_hdmi_i2c_read(struct dw_hdmi *hdmi, -- unsigned char *buf, unsigned int length) --{ -- struct dw_hdmi_i2c *i2c = hdmi->i2c; -- int stat; -- -- if (!i2c->is_regaddr) { -- dev_dbg(hdmi->dev, "set read register address to 0\n"); -- i2c->slave_reg = 0x00; -- i2c->is_regaddr = true; -- } -- -- while (length--) { -- reinit_completion(&i2c->cmp); -- -- hdmi_writeb(hdmi, i2c->slave_reg++, HDMI_I2CM_ADDRESS); -- hdmi_writeb(hdmi, HDMI_I2CM_OPERATION_READ, -- HDMI_I2CM_OPERATION); -- -- stat = wait_for_completion_timeout(&i2c->cmp, HZ / 10); -- if (!stat) -- return -EAGAIN; -- -- /* Check for error condition on the bus */ -- if (i2c->stat & HDMI_IH_I2CM_STAT0_ERROR) -- return -EIO; -- -- *buf++ = hdmi_readb(hdmi, HDMI_I2CM_DATAI); -- } -- -- return 0; --} -- --static int dw_hdmi_i2c_write(struct dw_hdmi *hdmi, -- unsigned char *buf, unsigned int length) --{ -- struct dw_hdmi_i2c *i2c = hdmi->i2c; -- int stat; -- -- if (!i2c->is_regaddr) { -- /* Use the first write byte as register address */ -- i2c->slave_reg = buf[0]; -- length--; -- buf++; -- i2c->is_regaddr = true; -- } -- -- while (length--) { -- reinit_completion(&i2c->cmp); -- -- hdmi_writeb(hdmi, *buf++, HDMI_I2CM_DATAO); -- hdmi_writeb(hdmi, i2c->slave_reg++, HDMI_I2CM_ADDRESS); -- hdmi_writeb(hdmi, HDMI_I2CM_OPERATION_WRITE, -- HDMI_I2CM_OPERATION); -- -- stat = wait_for_completion_timeout(&i2c->cmp, HZ / 10); -- if (!stat) -- return -EAGAIN; -- -- /* Check for error condition on the bus */ -- if (i2c->stat & HDMI_IH_I2CM_STAT0_ERROR) -- return -EIO; -- } -- -- return 0; --} -- --static int dw_hdmi_i2c_xfer(struct i2c_adapter *adap, -- struct i2c_msg *msgs, int num) --{ -- struct dw_hdmi *hdmi = i2c_get_adapdata(adap); -- struct dw_hdmi_i2c *i2c = hdmi->i2c; -- u8 addr = msgs[0].addr; -- int i, ret = 0; -- -- dev_dbg(hdmi->dev, "xfer: num: %d, addr: %#x\n", num, addr); -- -- for (i = 0; i < num; i++) { -- if (msgs[i].addr != addr) { -- dev_warn(hdmi->dev, -- "unsupported transfer, changed slave address\n"); -- return -EOPNOTSUPP; -- } -- -- if (msgs[i].len == 0) { -- dev_dbg(hdmi->dev, -- "unsupported transfer %d/%d, no data\n", -- i + 1, num); -- return -EOPNOTSUPP; -- } -- } -- -- mutex_lock(&i2c->lock); -- -- /* Unmute DONE and ERROR interrupts */ -- hdmi_writeb(hdmi, 0x00, HDMI_IH_MUTE_I2CM_STAT0); -- -- /* Set slave device address taken from the first I2C message */ -- hdmi_writeb(hdmi, addr, HDMI_I2CM_SLAVE); -- -- /* Set slave device register address on transfer */ -- i2c->is_regaddr = false; -- -- for (i = 0; i < num; i++) { -- dev_dbg(hdmi->dev, "xfer: num: %d/%d, len: %d, flags: %#x\n", -- i + 1, num, msgs[i].len, msgs[i].flags); -- -- if (msgs[i].flags & I2C_M_RD) -- ret = dw_hdmi_i2c_read(hdmi, msgs[i].buf, msgs[i].len); -- else -- ret = dw_hdmi_i2c_write(hdmi, msgs[i].buf, msgs[i].len); -- -- if (ret < 0) -- break; -- } -- -- if (!ret) -- ret = num; -- -- /* Mute DONE and ERROR interrupts */ -- hdmi_writeb(hdmi, HDMI_IH_I2CM_STAT0_ERROR | HDMI_IH_I2CM_STAT0_DONE, -- HDMI_IH_MUTE_I2CM_STAT0); -- -- mutex_unlock(&i2c->lock); -- -- return ret; --} -- --static u32 dw_hdmi_i2c_func(struct i2c_adapter *adapter) --{ -- return I2C_FUNC_I2C | I2C_FUNC_SMBUS_EMUL; --} -- --static const struct i2c_algorithm dw_hdmi_algorithm = { -- .master_xfer = dw_hdmi_i2c_xfer, -- .functionality = dw_hdmi_i2c_func, --}; -- --static struct i2c_adapter *dw_hdmi_i2c_adapter(struct dw_hdmi *hdmi) --{ -- struct i2c_adapter *adap; -- struct dw_hdmi_i2c *i2c; -- int ret; -- -- i2c = devm_kzalloc(hdmi->dev, sizeof(*i2c), GFP_KERNEL); -- if (!i2c) -- return ERR_PTR(-ENOMEM); -- -- mutex_init(&i2c->lock); -- init_completion(&i2c->cmp); -- -- adap = &i2c->adap; -- adap->class = I2C_CLASS_DDC; -- adap->owner = THIS_MODULE; -- adap->dev.parent = hdmi->dev; -- adap->algo = &dw_hdmi_algorithm; -- strlcpy(adap->name, "DesignWare HDMI", sizeof(adap->name)); -- i2c_set_adapdata(adap, hdmi); -- -- ret = i2c_add_adapter(adap); -- if (ret) { -- dev_warn(hdmi->dev, "cannot add %s I2C adapter\n", adap->name); -- devm_kfree(hdmi->dev, i2c); -- return ERR_PTR(ret); -- } -- -- hdmi->i2c = i2c; -- -- dev_info(hdmi->dev, "registered %s I2C bus driver\n", adap->name); -- -- return adap; --} -- --static void hdmi_set_cts_n(struct dw_hdmi *hdmi, unsigned int cts, -- unsigned int n) --{ -- /* Must be set/cleared first */ -- hdmi_modb(hdmi, 0, HDMI_AUD_CTS3_CTS_MANUAL, HDMI_AUD_CTS3); -- -- /* nshift factor = 0 */ -- hdmi_modb(hdmi, 0, HDMI_AUD_CTS3_N_SHIFT_MASK, HDMI_AUD_CTS3); -- -- hdmi_writeb(hdmi, ((cts >> 16) & HDMI_AUD_CTS3_AUDCTS19_16_MASK) | -- HDMI_AUD_CTS3_CTS_MANUAL, HDMI_AUD_CTS3); -- hdmi_writeb(hdmi, (cts >> 8) & 0xff, HDMI_AUD_CTS2); -- hdmi_writeb(hdmi, cts & 0xff, HDMI_AUD_CTS1); -- -- hdmi_writeb(hdmi, (n >> 16) & 0x0f, HDMI_AUD_N3); -- hdmi_writeb(hdmi, (n >> 8) & 0xff, HDMI_AUD_N2); -- hdmi_writeb(hdmi, n & 0xff, HDMI_AUD_N1); --} -- --static unsigned int hdmi_compute_n(unsigned int freq, unsigned long pixel_clk) --{ -- unsigned int n = (128 * freq) / 1000; -- unsigned int mult = 1; -- -- while (freq > 48000) { -- mult *= 2; -- freq /= 2; -- } -- -- switch (freq) { -- case 32000: -- if (pixel_clk == 25175000) -- n = 4576; -- else if (pixel_clk == 27027000) -- n = 4096; -- else if (pixel_clk == 74176000 || pixel_clk == 148352000) -- n = 11648; -- else -- n = 4096; -- n *= mult; -- break; -- -- case 44100: -- if (pixel_clk == 25175000) -- n = 7007; -- else if (pixel_clk == 74176000) -- n = 17836; -- else if (pixel_clk == 148352000) -- n = 8918; -- else -- n = 6272; -- n *= mult; -- break; -- -- case 48000: -- if (pixel_clk == 25175000) -- n = 6864; -- else if (pixel_clk == 27027000) -- n = 6144; -- else if (pixel_clk == 74176000) -- n = 11648; -- else if (pixel_clk == 148352000) -- n = 5824; -- else -- n = 6144; -- n *= mult; -- break; -- -- default: -- break; -- } -- -- return n; --} -- --static void hdmi_set_clk_regenerator(struct dw_hdmi *hdmi, -- unsigned long pixel_clk, unsigned int sample_rate) --{ -- unsigned long ftdms = pixel_clk; -- unsigned int n, cts; -- u64 tmp; -- -- n = hdmi_compute_n(sample_rate, pixel_clk); -- -- /* -- * Compute the CTS value from the N value. Note that CTS and N -- * can be up to 20 bits in total, so we need 64-bit math. Also -- * note that our TDMS clock is not fully accurate; it is accurate -- * to kHz. This can introduce an unnecessary remainder in the -- * calculation below, so we don't try to warn about that. -- */ -- tmp = (u64)ftdms * n; -- do_div(tmp, 128 * sample_rate); -- cts = tmp; -- -- dev_dbg(hdmi->dev, "%s: fs=%uHz ftdms=%lu.%03luMHz N=%d cts=%d\n", -- __func__, sample_rate, ftdms / 1000000, (ftdms / 1000) % 1000, -- n, cts); -- -- spin_lock_irq(&hdmi->audio_lock); -- hdmi->audio_n = n; -- hdmi->audio_cts = cts; -- hdmi_set_cts_n(hdmi, cts, hdmi->audio_enable ? n : 0); -- spin_unlock_irq(&hdmi->audio_lock); --} -- --static void hdmi_init_clk_regenerator(struct dw_hdmi *hdmi) --{ -- mutex_lock(&hdmi->audio_mutex); -- hdmi_set_clk_regenerator(hdmi, 74250000, hdmi->sample_rate); -- mutex_unlock(&hdmi->audio_mutex); --} -- --static void hdmi_clk_regenerator_update_pixel_clock(struct dw_hdmi *hdmi) --{ -- mutex_lock(&hdmi->audio_mutex); -- hdmi_set_clk_regenerator(hdmi, hdmi->hdmi_data.video_mode.mpixelclock, -- hdmi->sample_rate); -- mutex_unlock(&hdmi->audio_mutex); --} -- --void dw_hdmi_set_sample_rate(struct dw_hdmi *hdmi, unsigned int rate) --{ -- mutex_lock(&hdmi->audio_mutex); -- hdmi->sample_rate = rate; -- hdmi_set_clk_regenerator(hdmi, hdmi->hdmi_data.video_mode.mpixelclock, -- hdmi->sample_rate); -- mutex_unlock(&hdmi->audio_mutex); --} --EXPORT_SYMBOL_GPL(dw_hdmi_set_sample_rate); -- --void dw_hdmi_audio_enable(struct dw_hdmi *hdmi) --{ -- unsigned long flags; -- -- spin_lock_irqsave(&hdmi->audio_lock, flags); -- hdmi->audio_enable = true; -- hdmi_set_cts_n(hdmi, hdmi->audio_cts, hdmi->audio_n); -- spin_unlock_irqrestore(&hdmi->audio_lock, flags); --} --EXPORT_SYMBOL_GPL(dw_hdmi_audio_enable); -- --void dw_hdmi_audio_disable(struct dw_hdmi *hdmi) --{ -- unsigned long flags; -- -- spin_lock_irqsave(&hdmi->audio_lock, flags); -- hdmi->audio_enable = false; -- hdmi_set_cts_n(hdmi, hdmi->audio_cts, 0); -- spin_unlock_irqrestore(&hdmi->audio_lock, flags); --} --EXPORT_SYMBOL_GPL(dw_hdmi_audio_disable); -- --/* -- * this submodule is responsible for the video data synchronization. -- * for example, for RGB 4:4:4 input, the data map is defined as -- * pin{47~40} <==> R[7:0] -- * pin{31~24} <==> G[7:0] -- * pin{15~8} <==> B[7:0] -- */ --static void hdmi_video_sample(struct dw_hdmi *hdmi) --{ -- int color_format = 0; -- u8 val; -- -- if (hdmi->hdmi_data.enc_in_format == RGB) { -- if (hdmi->hdmi_data.enc_color_depth == 8) -- color_format = 0x01; -- else if (hdmi->hdmi_data.enc_color_depth == 10) -- color_format = 0x03; -- else if (hdmi->hdmi_data.enc_color_depth == 12) -- color_format = 0x05; -- else if (hdmi->hdmi_data.enc_color_depth == 16) -- color_format = 0x07; -- else -- return; -- } else if (hdmi->hdmi_data.enc_in_format == YCBCR444) { -- if (hdmi->hdmi_data.enc_color_depth == 8) -- color_format = 0x09; -- else if (hdmi->hdmi_data.enc_color_depth == 10) -- color_format = 0x0B; -- else if (hdmi->hdmi_data.enc_color_depth == 12) -- color_format = 0x0D; -- else if (hdmi->hdmi_data.enc_color_depth == 16) -- color_format = 0x0F; -- else -- return; -- } else if (hdmi->hdmi_data.enc_in_format == YCBCR422_8BITS) { -- if (hdmi->hdmi_data.enc_color_depth == 8) -- color_format = 0x16; -- else if (hdmi->hdmi_data.enc_color_depth == 10) -- color_format = 0x14; -- else if (hdmi->hdmi_data.enc_color_depth == 12) -- color_format = 0x12; -- else -- return; -- } -- -- val = HDMI_TX_INVID0_INTERNAL_DE_GENERATOR_DISABLE | -- ((color_format << HDMI_TX_INVID0_VIDEO_MAPPING_OFFSET) & -- HDMI_TX_INVID0_VIDEO_MAPPING_MASK); -- hdmi_writeb(hdmi, val, HDMI_TX_INVID0); -- -- /* Enable TX stuffing: When DE is inactive, fix the output data to 0 */ -- val = HDMI_TX_INSTUFFING_BDBDATA_STUFFING_ENABLE | -- HDMI_TX_INSTUFFING_RCRDATA_STUFFING_ENABLE | -- HDMI_TX_INSTUFFING_GYDATA_STUFFING_ENABLE; -- hdmi_writeb(hdmi, val, HDMI_TX_INSTUFFING); -- hdmi_writeb(hdmi, 0x0, HDMI_TX_GYDATA0); -- hdmi_writeb(hdmi, 0x0, HDMI_TX_GYDATA1); -- hdmi_writeb(hdmi, 0x0, HDMI_TX_RCRDATA0); -- hdmi_writeb(hdmi, 0x0, HDMI_TX_RCRDATA1); -- hdmi_writeb(hdmi, 0x0, HDMI_TX_BCBDATA0); -- hdmi_writeb(hdmi, 0x0, HDMI_TX_BCBDATA1); --} -- --static int is_color_space_conversion(struct dw_hdmi *hdmi) --{ -- return hdmi->hdmi_data.enc_in_format != hdmi->hdmi_data.enc_out_format; --} -- --static int is_color_space_decimation(struct dw_hdmi *hdmi) --{ -- if (hdmi->hdmi_data.enc_out_format != YCBCR422_8BITS) -- return 0; -- if (hdmi->hdmi_data.enc_in_format == RGB || -- hdmi->hdmi_data.enc_in_format == YCBCR444) -- return 1; -- return 0; --} -- --static int is_color_space_interpolation(struct dw_hdmi *hdmi) --{ -- if (hdmi->hdmi_data.enc_in_format != YCBCR422_8BITS) -- return 0; -- if (hdmi->hdmi_data.enc_out_format == RGB || -- hdmi->hdmi_data.enc_out_format == YCBCR444) -- return 1; -- return 0; --} -- --static void dw_hdmi_update_csc_coeffs(struct dw_hdmi *hdmi) --{ -- const u16 (*csc_coeff)[3][4] = &csc_coeff_default; -- unsigned i; -- u32 csc_scale = 1; -- -- if (is_color_space_conversion(hdmi)) { -- if (hdmi->hdmi_data.enc_out_format == RGB) { -- if (hdmi->hdmi_data.colorimetry == -- HDMI_COLORIMETRY_ITU_601) -- csc_coeff = &csc_coeff_rgb_out_eitu601; -- else -- csc_coeff = &csc_coeff_rgb_out_eitu709; -- } else if (hdmi->hdmi_data.enc_in_format == RGB) { -- if (hdmi->hdmi_data.colorimetry == -- HDMI_COLORIMETRY_ITU_601) -- csc_coeff = &csc_coeff_rgb_in_eitu601; -- else -- csc_coeff = &csc_coeff_rgb_in_eitu709; -- csc_scale = 0; -- } -- } -- -- /* The CSC registers are sequential, alternating MSB then LSB */ -- for (i = 0; i < ARRAY_SIZE(csc_coeff_default[0]); i++) { -- u16 coeff_a = (*csc_coeff)[0][i]; -- u16 coeff_b = (*csc_coeff)[1][i]; -- u16 coeff_c = (*csc_coeff)[2][i]; -- -- hdmi_writeb(hdmi, coeff_a & 0xff, HDMI_CSC_COEF_A1_LSB + i * 2); -- hdmi_writeb(hdmi, coeff_a >> 8, HDMI_CSC_COEF_A1_MSB + i * 2); -- hdmi_writeb(hdmi, coeff_b & 0xff, HDMI_CSC_COEF_B1_LSB + i * 2); -- hdmi_writeb(hdmi, coeff_b >> 8, HDMI_CSC_COEF_B1_MSB + i * 2); -- hdmi_writeb(hdmi, coeff_c & 0xff, HDMI_CSC_COEF_C1_LSB + i * 2); -- hdmi_writeb(hdmi, coeff_c >> 8, HDMI_CSC_COEF_C1_MSB + i * 2); -- } -- -- hdmi_modb(hdmi, csc_scale, HDMI_CSC_SCALE_CSCSCALE_MASK, -- HDMI_CSC_SCALE); --} -- --static void hdmi_video_csc(struct dw_hdmi *hdmi) --{ -- int color_depth = 0; -- int interpolation = HDMI_CSC_CFG_INTMODE_DISABLE; -- int decimation = 0; -- -- /* YCC422 interpolation to 444 mode */ -- if (is_color_space_interpolation(hdmi)) -- interpolation = HDMI_CSC_CFG_INTMODE_CHROMA_INT_FORMULA1; -- else if (is_color_space_decimation(hdmi)) -- decimation = HDMI_CSC_CFG_DECMODE_CHROMA_INT_FORMULA3; -- -- if (hdmi->hdmi_data.enc_color_depth == 8) -- color_depth = HDMI_CSC_SCALE_CSC_COLORDE_PTH_24BPP; -- else if (hdmi->hdmi_data.enc_color_depth == 10) -- color_depth = HDMI_CSC_SCALE_CSC_COLORDE_PTH_30BPP; -- else if (hdmi->hdmi_data.enc_color_depth == 12) -- color_depth = HDMI_CSC_SCALE_CSC_COLORDE_PTH_36BPP; -- else if (hdmi->hdmi_data.enc_color_depth == 16) -- color_depth = HDMI_CSC_SCALE_CSC_COLORDE_PTH_48BPP; -- else -- return; -- -- /* Configure the CSC registers */ -- hdmi_writeb(hdmi, interpolation | decimation, HDMI_CSC_CFG); -- hdmi_modb(hdmi, color_depth, HDMI_CSC_SCALE_CSC_COLORDE_PTH_MASK, -- HDMI_CSC_SCALE); -- -- dw_hdmi_update_csc_coeffs(hdmi); --} -- --/* -- * HDMI video packetizer is used to packetize the data. -- * for example, if input is YCC422 mode or repeater is used, -- * data should be repacked this module can be bypassed. -- */ --static void hdmi_video_packetize(struct dw_hdmi *hdmi) --{ -- unsigned int color_depth = 0; -- unsigned int remap_size = HDMI_VP_REMAP_YCC422_16bit; -- unsigned int output_select = HDMI_VP_CONF_OUTPUT_SELECTOR_PP; -- struct hdmi_data_info *hdmi_data = &hdmi->hdmi_data; -- u8 val, vp_conf; -- -- if (hdmi_data->enc_out_format == RGB || -- hdmi_data->enc_out_format == YCBCR444) { -- if (!hdmi_data->enc_color_depth) { -- output_select = HDMI_VP_CONF_OUTPUT_SELECTOR_BYPASS; -- } else if (hdmi_data->enc_color_depth == 8) { -- color_depth = 4; -- output_select = HDMI_VP_CONF_OUTPUT_SELECTOR_BYPASS; -- } else if (hdmi_data->enc_color_depth == 10) { -- color_depth = 5; -- } else if (hdmi_data->enc_color_depth == 12) { -- color_depth = 6; -- } else if (hdmi_data->enc_color_depth == 16) { -- color_depth = 7; -- } else { -- return; -- } -- } else if (hdmi_data->enc_out_format == YCBCR422_8BITS) { -- if (!hdmi_data->enc_color_depth || -- hdmi_data->enc_color_depth == 8) -- remap_size = HDMI_VP_REMAP_YCC422_16bit; -- else if (hdmi_data->enc_color_depth == 10) -- remap_size = HDMI_VP_REMAP_YCC422_20bit; -- else if (hdmi_data->enc_color_depth == 12) -- remap_size = HDMI_VP_REMAP_YCC422_24bit; -- else -- return; -- output_select = HDMI_VP_CONF_OUTPUT_SELECTOR_YCC422; -- } else { -- return; -- } -- -- /* set the packetizer registers */ -- val = ((color_depth << HDMI_VP_PR_CD_COLOR_DEPTH_OFFSET) & -- HDMI_VP_PR_CD_COLOR_DEPTH_MASK) | -- ((hdmi_data->pix_repet_factor << -- HDMI_VP_PR_CD_DESIRED_PR_FACTOR_OFFSET) & -- HDMI_VP_PR_CD_DESIRED_PR_FACTOR_MASK); -- hdmi_writeb(hdmi, val, HDMI_VP_PR_CD); -- -- hdmi_modb(hdmi, HDMI_VP_STUFF_PR_STUFFING_STUFFING_MODE, -- HDMI_VP_STUFF_PR_STUFFING_MASK, HDMI_VP_STUFF); -- -- /* Data from pixel repeater block */ -- if (hdmi_data->pix_repet_factor > 1) { -- vp_conf = HDMI_VP_CONF_PR_EN_ENABLE | -- HDMI_VP_CONF_BYPASS_SELECT_PIX_REPEATER; -- } else { /* data from packetizer block */ -- vp_conf = HDMI_VP_CONF_PR_EN_DISABLE | -- HDMI_VP_CONF_BYPASS_SELECT_VID_PACKETIZER; -- } -- -- hdmi_modb(hdmi, vp_conf, -- HDMI_VP_CONF_PR_EN_MASK | -- HDMI_VP_CONF_BYPASS_SELECT_MASK, HDMI_VP_CONF); -- -- hdmi_modb(hdmi, 1 << HDMI_VP_STUFF_IDEFAULT_PHASE_OFFSET, -- HDMI_VP_STUFF_IDEFAULT_PHASE_MASK, HDMI_VP_STUFF); -- -- hdmi_writeb(hdmi, remap_size, HDMI_VP_REMAP); -- -- if (output_select == HDMI_VP_CONF_OUTPUT_SELECTOR_PP) { -- vp_conf = HDMI_VP_CONF_BYPASS_EN_DISABLE | -- HDMI_VP_CONF_PP_EN_ENABLE | -- HDMI_VP_CONF_YCC422_EN_DISABLE; -- } else if (output_select == HDMI_VP_CONF_OUTPUT_SELECTOR_YCC422) { -- vp_conf = HDMI_VP_CONF_BYPASS_EN_DISABLE | -- HDMI_VP_CONF_PP_EN_DISABLE | -- HDMI_VP_CONF_YCC422_EN_ENABLE; -- } else if (output_select == HDMI_VP_CONF_OUTPUT_SELECTOR_BYPASS) { -- vp_conf = HDMI_VP_CONF_BYPASS_EN_ENABLE | -- HDMI_VP_CONF_PP_EN_DISABLE | -- HDMI_VP_CONF_YCC422_EN_DISABLE; -- } else { -- return; -- } -- -- hdmi_modb(hdmi, vp_conf, -- HDMI_VP_CONF_BYPASS_EN_MASK | HDMI_VP_CONF_PP_EN_ENMASK | -- HDMI_VP_CONF_YCC422_EN_MASK, HDMI_VP_CONF); -- -- hdmi_modb(hdmi, HDMI_VP_STUFF_PP_STUFFING_STUFFING_MODE | -- HDMI_VP_STUFF_YCC422_STUFFING_STUFFING_MODE, -- HDMI_VP_STUFF_PP_STUFFING_MASK | -- HDMI_VP_STUFF_YCC422_STUFFING_MASK, HDMI_VP_STUFF); -- -- hdmi_modb(hdmi, output_select, HDMI_VP_CONF_OUTPUT_SELECTOR_MASK, -- HDMI_VP_CONF); --} -- --/* ----------------------------------------------------------------------------- -- * Synopsys PHY Handling -- */ -- --static inline void hdmi_phy_test_clear(struct dw_hdmi *hdmi, -- unsigned char bit) --{ -- hdmi_modb(hdmi, bit << HDMI_PHY_TST0_TSTCLR_OFFSET, -- HDMI_PHY_TST0_TSTCLR_MASK, HDMI_PHY_TST0); --} -- --static bool hdmi_phy_wait_i2c_done(struct dw_hdmi *hdmi, int msec) --{ -- u32 val; -- -- while ((val = hdmi_readb(hdmi, HDMI_IH_I2CMPHY_STAT0) & 0x3) == 0) { -- if (msec-- == 0) -- return false; -- udelay(1000); -- } -- hdmi_writeb(hdmi, val, HDMI_IH_I2CMPHY_STAT0); -- -- return true; --} -- --void dw_hdmi_phy_i2c_write(struct dw_hdmi *hdmi, unsigned short data, -- unsigned char addr) --{ -- hdmi_writeb(hdmi, 0xFF, HDMI_IH_I2CMPHY_STAT0); -- hdmi_writeb(hdmi, addr, HDMI_PHY_I2CM_ADDRESS_ADDR); -- hdmi_writeb(hdmi, (unsigned char)(data >> 8), -- HDMI_PHY_I2CM_DATAO_1_ADDR); -- hdmi_writeb(hdmi, (unsigned char)(data >> 0), -- HDMI_PHY_I2CM_DATAO_0_ADDR); -- hdmi_writeb(hdmi, HDMI_PHY_I2CM_OPERATION_ADDR_WRITE, -- HDMI_PHY_I2CM_OPERATION_ADDR); -- hdmi_phy_wait_i2c_done(hdmi, 1000); --} --EXPORT_SYMBOL_GPL(dw_hdmi_phy_i2c_write); -- --static void dw_hdmi_phy_enable_powerdown(struct dw_hdmi *hdmi, bool enable) --{ -- hdmi_mask_writeb(hdmi, !enable, HDMI_PHY_CONF0, -- HDMI_PHY_CONF0_PDZ_OFFSET, -- HDMI_PHY_CONF0_PDZ_MASK); --} -- --static void dw_hdmi_phy_enable_tmds(struct dw_hdmi *hdmi, u8 enable) --{ -- hdmi_mask_writeb(hdmi, enable, HDMI_PHY_CONF0, -- HDMI_PHY_CONF0_ENTMDS_OFFSET, -- HDMI_PHY_CONF0_ENTMDS_MASK); --} -- --static void dw_hdmi_phy_enable_svsret(struct dw_hdmi *hdmi, u8 enable) --{ -- hdmi_mask_writeb(hdmi, enable, HDMI_PHY_CONF0, -- HDMI_PHY_CONF0_SVSRET_OFFSET, -- HDMI_PHY_CONF0_SVSRET_MASK); --} -- --static void dw_hdmi_phy_gen2_pddq(struct dw_hdmi *hdmi, u8 enable) --{ -- hdmi_mask_writeb(hdmi, enable, HDMI_PHY_CONF0, -- HDMI_PHY_CONF0_GEN2_PDDQ_OFFSET, -- HDMI_PHY_CONF0_GEN2_PDDQ_MASK); --} -- --static void dw_hdmi_phy_gen2_txpwron(struct dw_hdmi *hdmi, u8 enable) --{ -- hdmi_mask_writeb(hdmi, enable, HDMI_PHY_CONF0, -- HDMI_PHY_CONF0_GEN2_TXPWRON_OFFSET, -- HDMI_PHY_CONF0_GEN2_TXPWRON_MASK); --} -- --static void dw_hdmi_phy_sel_data_en_pol(struct dw_hdmi *hdmi, u8 enable) --{ -- hdmi_mask_writeb(hdmi, enable, HDMI_PHY_CONF0, -- HDMI_PHY_CONF0_SELDATAENPOL_OFFSET, -- HDMI_PHY_CONF0_SELDATAENPOL_MASK); --} -- --static void dw_hdmi_phy_sel_interface_control(struct dw_hdmi *hdmi, u8 enable) --{ -- hdmi_mask_writeb(hdmi, enable, HDMI_PHY_CONF0, -- HDMI_PHY_CONF0_SELDIPIF_OFFSET, -- HDMI_PHY_CONF0_SELDIPIF_MASK); --} -- --static void dw_hdmi_phy_power_off(struct dw_hdmi *hdmi) --{ -- const struct dw_hdmi_phy_data *phy = hdmi->phy.data; -- unsigned int i; -- u16 val; -- -- if (phy->gen == 1) { -- dw_hdmi_phy_enable_tmds(hdmi, 0); -- dw_hdmi_phy_enable_powerdown(hdmi, true); -- return; -- } -- -- dw_hdmi_phy_gen2_txpwron(hdmi, 0); -- -- /* -- * Wait for TX_PHY_LOCK to be deasserted to indicate that the PHY went -- * to low power mode. -- */ -- for (i = 0; i < 5; ++i) { -- val = hdmi_readb(hdmi, HDMI_PHY_STAT0); -- if (!(val & HDMI_PHY_TX_PHY_LOCK)) -- break; -- -- usleep_range(1000, 2000); -- } -- -- if (val & HDMI_PHY_TX_PHY_LOCK) -- dev_warn(hdmi->dev, "PHY failed to power down\n"); -- else -- dev_dbg(hdmi->dev, "PHY powered down in %u iterations\n", i); -- -- dw_hdmi_phy_gen2_pddq(hdmi, 1); --} -- --static int dw_hdmi_phy_power_on(struct dw_hdmi *hdmi) --{ -- const struct dw_hdmi_phy_data *phy = hdmi->phy.data; -- unsigned int i; -- u8 val; -- -- if (phy->gen == 1) { -- dw_hdmi_phy_enable_powerdown(hdmi, false); -- -- /* Toggle TMDS enable. */ -- dw_hdmi_phy_enable_tmds(hdmi, 0); -- dw_hdmi_phy_enable_tmds(hdmi, 1); -- return 0; -- } -- -- dw_hdmi_phy_gen2_txpwron(hdmi, 1); -- dw_hdmi_phy_gen2_pddq(hdmi, 0); -- -- /* Wait for PHY PLL lock */ -- for (i = 0; i < 5; ++i) { -- val = hdmi_readb(hdmi, HDMI_PHY_STAT0) & HDMI_PHY_TX_PHY_LOCK; -- if (val) -- break; -- -- usleep_range(1000, 2000); -- } -- -- if (!val) { -- dev_err(hdmi->dev, "PHY PLL failed to lock\n"); -- return -ETIMEDOUT; -- } -- -- dev_dbg(hdmi->dev, "PHY PLL locked %u iterations\n", i); -- return 0; --} -- --/* -- * PHY configuration function for the DWC HDMI 3D TX PHY. Based on the available -- * information the DWC MHL PHY has the same register layout and is thus also -- * supported by this function. -- */ --static int hdmi_phy_configure_dwc_hdmi_3d_tx(struct dw_hdmi *hdmi, -- const struct dw_hdmi_plat_data *pdata, -- unsigned long mpixelclock) --{ -- const struct dw_hdmi_mpll_config *mpll_config = pdata->mpll_cfg; -- const struct dw_hdmi_curr_ctrl *curr_ctrl = pdata->cur_ctr; -- const struct dw_hdmi_phy_config *phy_config = pdata->phy_config; -- -- /* PLL/MPLL Cfg - always match on final entry */ -- for (; mpll_config->mpixelclock != ~0UL; mpll_config++) -- if (mpixelclock <= mpll_config->mpixelclock) -- break; -- -- for (; curr_ctrl->mpixelclock != ~0UL; curr_ctrl++) -- if (mpixelclock <= curr_ctrl->mpixelclock) -- break; -- -- for (; phy_config->mpixelclock != ~0UL; phy_config++) -- if (mpixelclock <= phy_config->mpixelclock) -- break; -- -- if (mpll_config->mpixelclock == ~0UL || -- curr_ctrl->mpixelclock == ~0UL || -- phy_config->mpixelclock == ~0UL) -- return -EINVAL; -- -- dw_hdmi_phy_i2c_write(hdmi, mpll_config->res[0].cpce, -- HDMI_3D_TX_PHY_CPCE_CTRL); -- dw_hdmi_phy_i2c_write(hdmi, mpll_config->res[0].gmp, -- HDMI_3D_TX_PHY_GMPCTRL); -- dw_hdmi_phy_i2c_write(hdmi, curr_ctrl->curr[0], -- HDMI_3D_TX_PHY_CURRCTRL); -- -- dw_hdmi_phy_i2c_write(hdmi, 0, HDMI_3D_TX_PHY_PLLPHBYCTRL); -- dw_hdmi_phy_i2c_write(hdmi, HDMI_3D_TX_PHY_MSM_CTRL_CKO_SEL_FB_CLK, -- HDMI_3D_TX_PHY_MSM_CTRL); -- -- dw_hdmi_phy_i2c_write(hdmi, phy_config->term, HDMI_3D_TX_PHY_TXTERM); -- dw_hdmi_phy_i2c_write(hdmi, phy_config->sym_ctr, -- HDMI_3D_TX_PHY_CKSYMTXCTRL); -- dw_hdmi_phy_i2c_write(hdmi, phy_config->vlev_ctr, -- HDMI_3D_TX_PHY_VLEVCTRL); -- -- /* Override and disable clock termination. */ -- dw_hdmi_phy_i2c_write(hdmi, HDMI_3D_TX_PHY_CKCALCTRL_OVERRIDE, -- HDMI_3D_TX_PHY_CKCALCTRL); -- -- return 0; --} -- --static int hdmi_phy_configure(struct dw_hdmi *hdmi) --{ -- const struct dw_hdmi_phy_data *phy = hdmi->phy.data; -- const struct dw_hdmi_plat_data *pdata = hdmi->plat_data; -- unsigned long mpixelclock = hdmi->hdmi_data.video_mode.mpixelclock; -- int ret; -- -- dw_hdmi_phy_power_off(hdmi); -- -- /* Leave low power consumption mode by asserting SVSRET. */ -- if (phy->has_svsret) -- dw_hdmi_phy_enable_svsret(hdmi, 1); -- -- /* PHY reset. The reset signal is active high on Gen2 PHYs. */ -- hdmi_writeb(hdmi, HDMI_MC_PHYRSTZ_PHYRSTZ, HDMI_MC_PHYRSTZ); -- hdmi_writeb(hdmi, 0, HDMI_MC_PHYRSTZ); -- -- hdmi_writeb(hdmi, HDMI_MC_HEACPHY_RST_ASSERT, HDMI_MC_HEACPHY_RST); -- -- hdmi_phy_test_clear(hdmi, 1); -- hdmi_writeb(hdmi, HDMI_PHY_I2CM_SLAVE_ADDR_PHY_GEN2, -- HDMI_PHY_I2CM_SLAVE_ADDR); -- hdmi_phy_test_clear(hdmi, 0); -- -- /* Write to the PHY as configured by the platform */ -- if (pdata->configure_phy) -- ret = pdata->configure_phy(hdmi, pdata, mpixelclock); -- else -- ret = phy->configure(hdmi, pdata, mpixelclock); -- if (ret) { -- dev_err(hdmi->dev, "PHY configuration failed (clock %lu)\n", -- mpixelclock); -- return ret; -- } -- -- return dw_hdmi_phy_power_on(hdmi); --} -- --static int dw_hdmi_phy_init(struct dw_hdmi *hdmi, void *data, -- struct drm_display_mode *mode) --{ -- int i, ret; -- -- /* HDMI Phy spec says to do the phy initialization sequence twice */ -- for (i = 0; i < 2; i++) { -- dw_hdmi_phy_sel_data_en_pol(hdmi, 1); -- dw_hdmi_phy_sel_interface_control(hdmi, 0); -- -- ret = hdmi_phy_configure(hdmi); -- if (ret) -- return ret; -- } -- -- return 0; --} -- --static void dw_hdmi_phy_disable(struct dw_hdmi *hdmi, void *data) --{ -- dw_hdmi_phy_power_off(hdmi); --} -- --static enum drm_connector_status dw_hdmi_phy_read_hpd(struct dw_hdmi *hdmi, -- void *data) --{ -- return hdmi_readb(hdmi, HDMI_PHY_STAT0) & HDMI_PHY_HPD ? -- connector_status_connected : connector_status_disconnected; --} -- --static const struct dw_hdmi_phy_ops dw_hdmi_synopsys_phy_ops = { -- .init = dw_hdmi_phy_init, -- .disable = dw_hdmi_phy_disable, -- .read_hpd = dw_hdmi_phy_read_hpd, --}; -- --/* ----------------------------------------------------------------------------- -- * HDMI TX Setup -- */ -- --static void hdmi_tx_hdcp_config(struct dw_hdmi *hdmi) --{ -- u8 de; -- -- if (hdmi->hdmi_data.video_mode.mdataenablepolarity) -- de = HDMI_A_VIDPOLCFG_DATAENPOL_ACTIVE_HIGH; -- else -- de = HDMI_A_VIDPOLCFG_DATAENPOL_ACTIVE_LOW; -- -- /* disable rx detect */ -- hdmi_modb(hdmi, HDMI_A_HDCPCFG0_RXDETECT_DISABLE, -- HDMI_A_HDCPCFG0_RXDETECT_MASK, HDMI_A_HDCPCFG0); -- -- hdmi_modb(hdmi, de, HDMI_A_VIDPOLCFG_DATAENPOL_MASK, HDMI_A_VIDPOLCFG); -- -- hdmi_modb(hdmi, HDMI_A_HDCPCFG1_ENCRYPTIONDISABLE_DISABLE, -- HDMI_A_HDCPCFG1_ENCRYPTIONDISABLE_MASK, HDMI_A_HDCPCFG1); --} -- --static void hdmi_config_AVI(struct dw_hdmi *hdmi, struct drm_display_mode *mode) --{ -- struct hdmi_avi_infoframe frame; -- u8 val; -- -- /* Initialise info frame from DRM mode */ -- drm_hdmi_avi_infoframe_from_display_mode(&frame, mode); -- -- if (hdmi->hdmi_data.enc_out_format == YCBCR444) -- frame.colorspace = HDMI_COLORSPACE_YUV444; -- else if (hdmi->hdmi_data.enc_out_format == YCBCR422_8BITS) -- frame.colorspace = HDMI_COLORSPACE_YUV422; -- else -- frame.colorspace = HDMI_COLORSPACE_RGB; -- -- /* Set up colorimetry */ -- if (hdmi->hdmi_data.enc_out_format == XVYCC444) { -- frame.colorimetry = HDMI_COLORIMETRY_EXTENDED; -- if (hdmi->hdmi_data.colorimetry == HDMI_COLORIMETRY_ITU_601) -- frame.extended_colorimetry = -- HDMI_EXTENDED_COLORIMETRY_XV_YCC_601; -- else /*hdmi->hdmi_data.colorimetry == HDMI_COLORIMETRY_ITU_709*/ -- frame.extended_colorimetry = -- HDMI_EXTENDED_COLORIMETRY_XV_YCC_709; -- } else if (hdmi->hdmi_data.enc_out_format != RGB) { -- frame.colorimetry = hdmi->hdmi_data.colorimetry; -- frame.extended_colorimetry = HDMI_EXTENDED_COLORIMETRY_XV_YCC_601; -- } else { /* Carries no data */ -- frame.colorimetry = HDMI_COLORIMETRY_NONE; -- frame.extended_colorimetry = HDMI_EXTENDED_COLORIMETRY_XV_YCC_601; -- } -- -- frame.scan_mode = HDMI_SCAN_MODE_NONE; -- -- /* -- * The Designware IP uses a different byte format from standard -- * AVI info frames, though generally the bits are in the correct -- * bytes. -- */ -- -- /* -- * AVI data byte 1 differences: Colorspace in bits 0,1 rather than 5,6, -- * scan info in bits 4,5 rather than 0,1 and active aspect present in -- * bit 6 rather than 4. -- */ -- val = (frame.scan_mode & 3) << 4 | (frame.colorspace & 3); -- if (frame.active_aspect & 15) -- val |= HDMI_FC_AVICONF0_ACTIVE_FMT_INFO_PRESENT; -- if (frame.top_bar || frame.bottom_bar) -- val |= HDMI_FC_AVICONF0_BAR_DATA_HORIZ_BAR; -- if (frame.left_bar || frame.right_bar) -- val |= HDMI_FC_AVICONF0_BAR_DATA_VERT_BAR; -- hdmi_writeb(hdmi, val, HDMI_FC_AVICONF0); -- -- /* AVI data byte 2 differences: none */ -- val = ((frame.colorimetry & 0x3) << 6) | -- ((frame.picture_aspect & 0x3) << 4) | -- (frame.active_aspect & 0xf); -- hdmi_writeb(hdmi, val, HDMI_FC_AVICONF1); -- -- /* AVI data byte 3 differences: none */ -- val = ((frame.extended_colorimetry & 0x7) << 4) | -- ((frame.quantization_range & 0x3) << 2) | -- (frame.nups & 0x3); -- if (frame.itc) -- val |= HDMI_FC_AVICONF2_IT_CONTENT_VALID; -- hdmi_writeb(hdmi, val, HDMI_FC_AVICONF2); -- -- /* AVI data byte 4 differences: none */ -- val = frame.video_code & 0x7f; -- hdmi_writeb(hdmi, val, HDMI_FC_AVIVID); -- -- /* AVI Data Byte 5- set up input and output pixel repetition */ -- val = (((hdmi->hdmi_data.video_mode.mpixelrepetitioninput + 1) << -- HDMI_FC_PRCONF_INCOMING_PR_FACTOR_OFFSET) & -- HDMI_FC_PRCONF_INCOMING_PR_FACTOR_MASK) | -- ((hdmi->hdmi_data.video_mode.mpixelrepetitionoutput << -- HDMI_FC_PRCONF_OUTPUT_PR_FACTOR_OFFSET) & -- HDMI_FC_PRCONF_OUTPUT_PR_FACTOR_MASK); -- hdmi_writeb(hdmi, val, HDMI_FC_PRCONF); -- -- /* -- * AVI data byte 5 differences: content type in 0,1 rather than 4,5, -- * ycc range in bits 2,3 rather than 6,7 -- */ -- val = ((frame.ycc_quantization_range & 0x3) << 2) | -- (frame.content_type & 0x3); -- hdmi_writeb(hdmi, val, HDMI_FC_AVICONF3); -- -- /* AVI Data Bytes 6-13 */ -- hdmi_writeb(hdmi, frame.top_bar & 0xff, HDMI_FC_AVIETB0); -- hdmi_writeb(hdmi, (frame.top_bar >> 8) & 0xff, HDMI_FC_AVIETB1); -- hdmi_writeb(hdmi, frame.bottom_bar & 0xff, HDMI_FC_AVISBB0); -- hdmi_writeb(hdmi, (frame.bottom_bar >> 8) & 0xff, HDMI_FC_AVISBB1); -- hdmi_writeb(hdmi, frame.left_bar & 0xff, HDMI_FC_AVIELB0); -- hdmi_writeb(hdmi, (frame.left_bar >> 8) & 0xff, HDMI_FC_AVIELB1); -- hdmi_writeb(hdmi, frame.right_bar & 0xff, HDMI_FC_AVISRB0); -- hdmi_writeb(hdmi, (frame.right_bar >> 8) & 0xff, HDMI_FC_AVISRB1); --} -- --static void hdmi_av_composer(struct dw_hdmi *hdmi, -- const struct drm_display_mode *mode) --{ -- u8 inv_val; -- struct hdmi_vmode *vmode = &hdmi->hdmi_data.video_mode; -- int hblank, vblank, h_de_hs, v_de_vs, hsync_len, vsync_len; -- unsigned int vdisplay; -- -- vmode->mpixelclock = mode->clock * 1000; -- -- dev_dbg(hdmi->dev, "final pixclk = %d\n", vmode->mpixelclock); -- -- /* Set up HDMI_FC_INVIDCONF */ -- inv_val = (hdmi->hdmi_data.hdcp_enable ? -- HDMI_FC_INVIDCONF_HDCP_KEEPOUT_ACTIVE : -- HDMI_FC_INVIDCONF_HDCP_KEEPOUT_INACTIVE); -- -- inv_val |= mode->flags & DRM_MODE_FLAG_PVSYNC ? -- HDMI_FC_INVIDCONF_VSYNC_IN_POLARITY_ACTIVE_HIGH : -- HDMI_FC_INVIDCONF_VSYNC_IN_POLARITY_ACTIVE_LOW; -- -- inv_val |= mode->flags & DRM_MODE_FLAG_PHSYNC ? -- HDMI_FC_INVIDCONF_HSYNC_IN_POLARITY_ACTIVE_HIGH : -- HDMI_FC_INVIDCONF_HSYNC_IN_POLARITY_ACTIVE_LOW; -- -- inv_val |= (vmode->mdataenablepolarity ? -- HDMI_FC_INVIDCONF_DE_IN_POLARITY_ACTIVE_HIGH : -- HDMI_FC_INVIDCONF_DE_IN_POLARITY_ACTIVE_LOW); -- -- if (hdmi->vic == 39) -- inv_val |= HDMI_FC_INVIDCONF_R_V_BLANK_IN_OSC_ACTIVE_HIGH; -- else -- inv_val |= mode->flags & DRM_MODE_FLAG_INTERLACE ? -- HDMI_FC_INVIDCONF_R_V_BLANK_IN_OSC_ACTIVE_HIGH : -- HDMI_FC_INVIDCONF_R_V_BLANK_IN_OSC_ACTIVE_LOW; -- -- inv_val |= mode->flags & DRM_MODE_FLAG_INTERLACE ? -- HDMI_FC_INVIDCONF_IN_I_P_INTERLACED : -- HDMI_FC_INVIDCONF_IN_I_P_PROGRESSIVE; -- -- inv_val |= hdmi->sink_is_hdmi ? -- HDMI_FC_INVIDCONF_DVI_MODEZ_HDMI_MODE : -- HDMI_FC_INVIDCONF_DVI_MODEZ_DVI_MODE; -- -- hdmi_writeb(hdmi, inv_val, HDMI_FC_INVIDCONF); -- -- vdisplay = mode->vdisplay; -- vblank = mode->vtotal - mode->vdisplay; -- v_de_vs = mode->vsync_start - mode->vdisplay; -- vsync_len = mode->vsync_end - mode->vsync_start; -- -- /* -- * When we're setting an interlaced mode, we need -- * to adjust the vertical timing to suit. -- */ -- if (mode->flags & DRM_MODE_FLAG_INTERLACE) { -- vdisplay /= 2; -- vblank /= 2; -- v_de_vs /= 2; -- vsync_len /= 2; -- } -- -- /* Set up horizontal active pixel width */ -- hdmi_writeb(hdmi, mode->hdisplay >> 8, HDMI_FC_INHACTV1); -- hdmi_writeb(hdmi, mode->hdisplay, HDMI_FC_INHACTV0); -- -- /* Set up vertical active lines */ -- hdmi_writeb(hdmi, vdisplay >> 8, HDMI_FC_INVACTV1); -- hdmi_writeb(hdmi, vdisplay, HDMI_FC_INVACTV0); -- -- /* Set up horizontal blanking pixel region width */ -- hblank = mode->htotal - mode->hdisplay; -- hdmi_writeb(hdmi, hblank >> 8, HDMI_FC_INHBLANK1); -- hdmi_writeb(hdmi, hblank, HDMI_FC_INHBLANK0); -- -- /* Set up vertical blanking pixel region width */ -- hdmi_writeb(hdmi, vblank, HDMI_FC_INVBLANK); -- -- /* Set up HSYNC active edge delay width (in pixel clks) */ -- h_de_hs = mode->hsync_start - mode->hdisplay; -- hdmi_writeb(hdmi, h_de_hs >> 8, HDMI_FC_HSYNCINDELAY1); -- hdmi_writeb(hdmi, h_de_hs, HDMI_FC_HSYNCINDELAY0); -- -- /* Set up VSYNC active edge delay (in lines) */ -- hdmi_writeb(hdmi, v_de_vs, HDMI_FC_VSYNCINDELAY); -- -- /* Set up HSYNC active pulse width (in pixel clks) */ -- hsync_len = mode->hsync_end - mode->hsync_start; -- hdmi_writeb(hdmi, hsync_len >> 8, HDMI_FC_HSYNCINWIDTH1); -- hdmi_writeb(hdmi, hsync_len, HDMI_FC_HSYNCINWIDTH0); -- -- /* Set up VSYNC active edge delay (in lines) */ -- hdmi_writeb(hdmi, vsync_len, HDMI_FC_VSYNCINWIDTH); --} -- --/* HDMI Initialization Step B.4 */ --static void dw_hdmi_enable_video_path(struct dw_hdmi *hdmi) --{ -- u8 clkdis; -- -- /* control period minimum duration */ -- hdmi_writeb(hdmi, 12, HDMI_FC_CTRLDUR); -- hdmi_writeb(hdmi, 32, HDMI_FC_EXCTRLDUR); -- hdmi_writeb(hdmi, 1, HDMI_FC_EXCTRLSPAC); -- -- /* Set to fill TMDS data channels */ -- hdmi_writeb(hdmi, 0x0B, HDMI_FC_CH0PREAM); -- hdmi_writeb(hdmi, 0x16, HDMI_FC_CH1PREAM); -- hdmi_writeb(hdmi, 0x21, HDMI_FC_CH2PREAM); -- -- /* Enable pixel clock and tmds data path */ -- clkdis = 0x7F; -- clkdis &= ~HDMI_MC_CLKDIS_PIXELCLK_DISABLE; -- hdmi_writeb(hdmi, clkdis, HDMI_MC_CLKDIS); -- -- clkdis &= ~HDMI_MC_CLKDIS_TMDSCLK_DISABLE; -- hdmi_writeb(hdmi, clkdis, HDMI_MC_CLKDIS); -- -- /* Enable csc path */ -- if (is_color_space_conversion(hdmi)) { -- clkdis &= ~HDMI_MC_CLKDIS_CSCCLK_DISABLE; -- hdmi_writeb(hdmi, clkdis, HDMI_MC_CLKDIS); -- } -- -- /* Enable color space conversion if needed */ -- if (is_color_space_conversion(hdmi)) -- hdmi_writeb(hdmi, HDMI_MC_FLOWCTRL_FEED_THROUGH_OFF_CSC_IN_PATH, -- HDMI_MC_FLOWCTRL); -- else -- hdmi_writeb(hdmi, HDMI_MC_FLOWCTRL_FEED_THROUGH_OFF_CSC_BYPASS, -- HDMI_MC_FLOWCTRL); --} -- --static void hdmi_enable_audio_clk(struct dw_hdmi *hdmi) --{ -- hdmi_modb(hdmi, 0, HDMI_MC_CLKDIS_AUDCLK_DISABLE, HDMI_MC_CLKDIS); --} -- --/* Workaround to clear the overflow condition */ --static void dw_hdmi_clear_overflow(struct dw_hdmi *hdmi) --{ -- unsigned int count; -- unsigned int i; -- u8 val; -- -- /* -- * Under some circumstances the Frame Composer arithmetic unit can miss -- * an FC register write due to being busy processing the previous one. -- * The issue can be worked around by issuing a TMDS software reset and -- * then write one of the FC registers several times. -- * -- * The number of iterations matters and depends on the HDMI TX revision -- * (and possibly on the platform). So far only i.MX6Q (v1.30a) and -- * i.MX6DL (v1.31a) have been identified as needing the workaround, with -- * 4 and 1 iterations respectively. -- */ -- -- switch (hdmi->version) { -- case 0x130a: -- count = 4; -- break; -- case 0x131a: -- count = 1; -- break; -- default: -- return; -- } -- -- /* TMDS software reset */ -- hdmi_writeb(hdmi, (u8)~HDMI_MC_SWRSTZ_TMDSSWRST_REQ, HDMI_MC_SWRSTZ); -- -- val = hdmi_readb(hdmi, HDMI_FC_INVIDCONF); -- for (i = 0; i < count; i++) -- hdmi_writeb(hdmi, val, HDMI_FC_INVIDCONF); --} -- --static void hdmi_enable_overflow_interrupts(struct dw_hdmi *hdmi) --{ -- hdmi_writeb(hdmi, 0, HDMI_FC_MASK2); -- hdmi_writeb(hdmi, 0, HDMI_IH_MUTE_FC_STAT2); --} -- --static void hdmi_disable_overflow_interrupts(struct dw_hdmi *hdmi) --{ -- hdmi_writeb(hdmi, HDMI_IH_MUTE_FC_STAT2_OVERFLOW_MASK, -- HDMI_IH_MUTE_FC_STAT2); --} -- --static int dw_hdmi_setup(struct dw_hdmi *hdmi, struct drm_display_mode *mode) --{ -- int ret; -- -- hdmi_disable_overflow_interrupts(hdmi); -- -- hdmi->vic = drm_match_cea_mode(mode); -- -- if (!hdmi->vic) { -- dev_dbg(hdmi->dev, "Non-CEA mode used in HDMI\n"); -- } else { -- dev_dbg(hdmi->dev, "CEA mode used vic=%d\n", hdmi->vic); -- } -- -- if ((hdmi->vic == 6) || (hdmi->vic == 7) || -- (hdmi->vic == 21) || (hdmi->vic == 22) || -- (hdmi->vic == 2) || (hdmi->vic == 3) || -- (hdmi->vic == 17) || (hdmi->vic == 18)) -- hdmi->hdmi_data.colorimetry = HDMI_COLORIMETRY_ITU_601; -- else -- hdmi->hdmi_data.colorimetry = HDMI_COLORIMETRY_ITU_709; -- -- hdmi->hdmi_data.video_mode.mpixelrepetitionoutput = 0; -- hdmi->hdmi_data.video_mode.mpixelrepetitioninput = 0; -- -- /* TODO: Get input format from IPU (via FB driver interface) */ -- hdmi->hdmi_data.enc_in_format = RGB; -- -- hdmi->hdmi_data.enc_out_format = RGB; -- -- hdmi->hdmi_data.enc_color_depth = 8; -- hdmi->hdmi_data.pix_repet_factor = 0; -- hdmi->hdmi_data.hdcp_enable = 0; -- hdmi->hdmi_data.video_mode.mdataenablepolarity = true; -- -- /* HDMI Initialization Step B.1 */ -- hdmi_av_composer(hdmi, mode); -- -- /* HDMI Initializateion Step B.2 */ -- ret = hdmi->phy.ops->init(hdmi, hdmi->phy.data, &hdmi->previous_mode); -- if (ret) -- return ret; -- hdmi->phy.enabled = true; -- -- /* HDMI Initialization Step B.3 */ -- dw_hdmi_enable_video_path(hdmi); -- -- if (hdmi->sink_has_audio) { -- dev_dbg(hdmi->dev, "sink has audio support\n"); -- -- /* HDMI Initialization Step E - Configure audio */ -- hdmi_clk_regenerator_update_pixel_clock(hdmi); -- hdmi_enable_audio_clk(hdmi); -- } -- -- /* not for DVI mode */ -- if (hdmi->sink_is_hdmi) { -- dev_dbg(hdmi->dev, "%s HDMI mode\n", __func__); -- -- /* HDMI Initialization Step F - Configure AVI InfoFrame */ -- hdmi_config_AVI(hdmi, mode); -- } else { -- dev_dbg(hdmi->dev, "%s DVI mode\n", __func__); -- } -- -- hdmi_video_packetize(hdmi); -- hdmi_video_csc(hdmi); -- hdmi_video_sample(hdmi); -- hdmi_tx_hdcp_config(hdmi); -- -- dw_hdmi_clear_overflow(hdmi); -- if (hdmi->cable_plugin && hdmi->sink_is_hdmi) -- hdmi_enable_overflow_interrupts(hdmi); -- -- return 0; --} -- --/* Wait until we are registered to enable interrupts */ --static int dw_hdmi_fb_registered(struct dw_hdmi *hdmi) --{ -- hdmi_writeb(hdmi, HDMI_PHY_I2CM_INT_ADDR_DONE_POL, -- HDMI_PHY_I2CM_INT_ADDR); -- -- hdmi_writeb(hdmi, HDMI_PHY_I2CM_CTLINT_ADDR_NAC_POL | -- HDMI_PHY_I2CM_CTLINT_ADDR_ARBITRATION_POL, -- HDMI_PHY_I2CM_CTLINT_ADDR); -- -- /* enable cable hot plug irq */ -- hdmi_writeb(hdmi, hdmi->phy_mask, HDMI_PHY_MASK0); -- -- /* Clear Hotplug interrupts */ -- hdmi_writeb(hdmi, HDMI_IH_PHY_STAT0_HPD | HDMI_IH_PHY_STAT0_RX_SENSE, -- HDMI_IH_PHY_STAT0); -- -- return 0; --} -- --static void initialize_hdmi_ih_mutes(struct dw_hdmi *hdmi) --{ -- u8 ih_mute; -- -- /* -- * Boot up defaults are: -- * HDMI_IH_MUTE = 0x03 (disabled) -- * HDMI_IH_MUTE_* = 0x00 (enabled) -- * -- * Disable top level interrupt bits in HDMI block -- */ -- ih_mute = hdmi_readb(hdmi, HDMI_IH_MUTE) | -- HDMI_IH_MUTE_MUTE_WAKEUP_INTERRUPT | -- HDMI_IH_MUTE_MUTE_ALL_INTERRUPT; -- -- hdmi_writeb(hdmi, ih_mute, HDMI_IH_MUTE); -- -- /* by default mask all interrupts */ -- hdmi_writeb(hdmi, 0xff, HDMI_VP_MASK); -- hdmi_writeb(hdmi, 0xff, HDMI_FC_MASK0); -- hdmi_writeb(hdmi, 0xff, HDMI_FC_MASK1); -- hdmi_writeb(hdmi, 0xff, HDMI_FC_MASK2); -- hdmi_writeb(hdmi, 0xff, HDMI_PHY_MASK0); -- hdmi_writeb(hdmi, 0xff, HDMI_PHY_I2CM_INT_ADDR); -- hdmi_writeb(hdmi, 0xff, HDMI_PHY_I2CM_CTLINT_ADDR); -- hdmi_writeb(hdmi, 0xff, HDMI_AUD_INT); -- hdmi_writeb(hdmi, 0xff, HDMI_AUD_SPDIFINT); -- hdmi_writeb(hdmi, 0xff, HDMI_AUD_HBR_MASK); -- hdmi_writeb(hdmi, 0xff, HDMI_GP_MASK); -- hdmi_writeb(hdmi, 0xff, HDMI_A_APIINTMSK); -- hdmi_writeb(hdmi, 0xff, HDMI_CEC_MASK); -- hdmi_writeb(hdmi, 0xff, HDMI_I2CM_INT); -- hdmi_writeb(hdmi, 0xff, HDMI_I2CM_CTLINT); -- -- /* Disable interrupts in the IH_MUTE_* registers */ -- hdmi_writeb(hdmi, 0xff, HDMI_IH_MUTE_FC_STAT0); -- hdmi_writeb(hdmi, 0xff, HDMI_IH_MUTE_FC_STAT1); -- hdmi_writeb(hdmi, 0xff, HDMI_IH_MUTE_FC_STAT2); -- hdmi_writeb(hdmi, 0xff, HDMI_IH_MUTE_AS_STAT0); -- hdmi_writeb(hdmi, 0xff, HDMI_IH_MUTE_PHY_STAT0); -- hdmi_writeb(hdmi, 0xff, HDMI_IH_MUTE_I2CM_STAT0); -- hdmi_writeb(hdmi, 0xff, HDMI_IH_MUTE_CEC_STAT0); -- hdmi_writeb(hdmi, 0xff, HDMI_IH_MUTE_VP_STAT0); -- hdmi_writeb(hdmi, 0xff, HDMI_IH_MUTE_I2CMPHY_STAT0); -- hdmi_writeb(hdmi, 0xff, HDMI_IH_MUTE_AHBDMAAUD_STAT0); -- -- /* Enable top level interrupt bits in HDMI block */ -- ih_mute &= ~(HDMI_IH_MUTE_MUTE_WAKEUP_INTERRUPT | -- HDMI_IH_MUTE_MUTE_ALL_INTERRUPT); -- hdmi_writeb(hdmi, ih_mute, HDMI_IH_MUTE); --} -- --static void dw_hdmi_poweron(struct dw_hdmi *hdmi) --{ -- hdmi->bridge_is_on = true; -- dw_hdmi_setup(hdmi, &hdmi->previous_mode); --} -- --static void dw_hdmi_poweroff(struct dw_hdmi *hdmi) --{ -- if (hdmi->phy.enabled) { -- hdmi->phy.ops->disable(hdmi, hdmi->phy.data); -- hdmi->phy.enabled = false; -- } -- -- hdmi->bridge_is_on = false; --} -- --static void dw_hdmi_update_power(struct dw_hdmi *hdmi) --{ -- int force = hdmi->force; -- -- if (hdmi->disabled) { -- force = DRM_FORCE_OFF; -- } else if (force == DRM_FORCE_UNSPECIFIED) { -- if (hdmi->rxsense) -- force = DRM_FORCE_ON; -- else -- force = DRM_FORCE_OFF; -- } -- -- if (force == DRM_FORCE_OFF) { -- if (hdmi->bridge_is_on) -- dw_hdmi_poweroff(hdmi); -- } else { -- if (!hdmi->bridge_is_on) -- dw_hdmi_poweron(hdmi); -- } --} -- --/* -- * Adjust the detection of RXSENSE according to whether we have a forced -- * connection mode enabled, or whether we have been disabled. There is -- * no point processing RXSENSE interrupts if we have a forced connection -- * state, or DRM has us disabled. -- * -- * We also disable rxsense interrupts when we think we're disconnected -- * to avoid floating TDMS signals giving false rxsense interrupts. -- * -- * Note: we still need to listen for HPD interrupts even when DRM has us -- * disabled so that we can detect a connect event. -- */ --static void dw_hdmi_update_phy_mask(struct dw_hdmi *hdmi) --{ -- u8 old_mask = hdmi->phy_mask; -- -- if (hdmi->force || hdmi->disabled || !hdmi->rxsense) -- hdmi->phy_mask |= HDMI_PHY_RX_SENSE; -- else -- hdmi->phy_mask &= ~HDMI_PHY_RX_SENSE; -- -- if (old_mask != hdmi->phy_mask) -- hdmi_writeb(hdmi, hdmi->phy_mask, HDMI_PHY_MASK0); --} -- --static enum drm_connector_status --dw_hdmi_connector_detect(struct drm_connector *connector, bool force) --{ -- struct dw_hdmi *hdmi = container_of(connector, struct dw_hdmi, -- connector); -- -- mutex_lock(&hdmi->mutex); -- hdmi->force = DRM_FORCE_UNSPECIFIED; -- dw_hdmi_update_power(hdmi); -- dw_hdmi_update_phy_mask(hdmi); -- mutex_unlock(&hdmi->mutex); -- -- return hdmi->phy.ops->read_hpd(hdmi, hdmi->phy.data); --} -- --static int dw_hdmi_connector_get_modes(struct drm_connector *connector) --{ -- struct dw_hdmi *hdmi = container_of(connector, struct dw_hdmi, -- connector); -- struct edid *edid; -- int ret = 0; -- -- if (!hdmi->ddc) -- return 0; -- -- edid = drm_get_edid(connector, hdmi->ddc); -- if (edid) { -- dev_dbg(hdmi->dev, "got edid: width[%d] x height[%d]\n", -- edid->width_cm, edid->height_cm); -- -- hdmi->sink_is_hdmi = drm_detect_hdmi_monitor(edid); -- hdmi->sink_has_audio = drm_detect_monitor_audio(edid); -- drm_mode_connector_update_edid_property(connector, edid); -- ret = drm_add_edid_modes(connector, edid); -- /* Store the ELD */ -- drm_edid_to_eld(connector, edid); -- kfree(edid); -- } else { -- dev_dbg(hdmi->dev, "failed to get edid\n"); -- } -- -- return ret; --} -- --static enum drm_mode_status --dw_hdmi_connector_mode_valid(struct drm_connector *connector, -- struct drm_display_mode *mode) --{ -- struct dw_hdmi *hdmi = container_of(connector, -- struct dw_hdmi, connector); -- enum drm_mode_status mode_status = MODE_OK; -- -- /* We don't support double-clocked modes */ -- if (mode->flags & DRM_MODE_FLAG_DBLCLK) -- return MODE_BAD; -- -- if (hdmi->plat_data->mode_valid) -- mode_status = hdmi->plat_data->mode_valid(connector, mode); -- -- return mode_status; --} -- --static void dw_hdmi_connector_force(struct drm_connector *connector) --{ -- struct dw_hdmi *hdmi = container_of(connector, struct dw_hdmi, -- connector); -- -- mutex_lock(&hdmi->mutex); -- hdmi->force = connector->force; -- dw_hdmi_update_power(hdmi); -- dw_hdmi_update_phy_mask(hdmi); -- mutex_unlock(&hdmi->mutex); --} -- --static const struct drm_connector_funcs dw_hdmi_connector_funcs = { -- .dpms = drm_atomic_helper_connector_dpms, -- .fill_modes = drm_helper_probe_single_connector_modes, -- .detect = dw_hdmi_connector_detect, -- .destroy = drm_connector_cleanup, -- .force = dw_hdmi_connector_force, -- .reset = drm_atomic_helper_connector_reset, -- .atomic_duplicate_state = drm_atomic_helper_connector_duplicate_state, -- .atomic_destroy_state = drm_atomic_helper_connector_destroy_state, --}; -- --static const struct drm_connector_helper_funcs dw_hdmi_connector_helper_funcs = { -- .get_modes = dw_hdmi_connector_get_modes, -- .mode_valid = dw_hdmi_connector_mode_valid, -- .best_encoder = drm_atomic_helper_best_encoder, --}; -- --static int dw_hdmi_bridge_attach(struct drm_bridge *bridge) --{ -- struct dw_hdmi *hdmi = bridge->driver_private; -- struct drm_encoder *encoder = bridge->encoder; -- struct drm_connector *connector = &hdmi->connector; -- -- connector->interlace_allowed = 1; -- connector->polled = DRM_CONNECTOR_POLL_HPD; -- -- drm_connector_helper_add(connector, &dw_hdmi_connector_helper_funcs); -- -- drm_connector_init(bridge->dev, connector, &dw_hdmi_connector_funcs, -- DRM_MODE_CONNECTOR_HDMIA); -- -- drm_mode_connector_attach_encoder(connector, encoder); -- -- return 0; --} -- --static void dw_hdmi_bridge_mode_set(struct drm_bridge *bridge, -- struct drm_display_mode *orig_mode, -- struct drm_display_mode *mode) --{ -- struct dw_hdmi *hdmi = bridge->driver_private; -- -- mutex_lock(&hdmi->mutex); -- -- /* Store the display mode for plugin/DKMS poweron events */ -- memcpy(&hdmi->previous_mode, mode, sizeof(hdmi->previous_mode)); -- -- mutex_unlock(&hdmi->mutex); --} -- --static void dw_hdmi_bridge_disable(struct drm_bridge *bridge) --{ -- struct dw_hdmi *hdmi = bridge->driver_private; -- -- mutex_lock(&hdmi->mutex); -- hdmi->disabled = true; -- dw_hdmi_update_power(hdmi); -- dw_hdmi_update_phy_mask(hdmi); -- mutex_unlock(&hdmi->mutex); --} -- --static void dw_hdmi_bridge_enable(struct drm_bridge *bridge) --{ -- struct dw_hdmi *hdmi = bridge->driver_private; -- -- mutex_lock(&hdmi->mutex); -- hdmi->disabled = false; -- dw_hdmi_update_power(hdmi); -- dw_hdmi_update_phy_mask(hdmi); -- mutex_unlock(&hdmi->mutex); --} -- --static const struct drm_bridge_funcs dw_hdmi_bridge_funcs = { -- .attach = dw_hdmi_bridge_attach, -- .enable = dw_hdmi_bridge_enable, -- .disable = dw_hdmi_bridge_disable, -- .mode_set = dw_hdmi_bridge_mode_set, --}; -- --static irqreturn_t dw_hdmi_i2c_irq(struct dw_hdmi *hdmi) --{ -- struct dw_hdmi_i2c *i2c = hdmi->i2c; -- unsigned int stat; -- -- stat = hdmi_readb(hdmi, HDMI_IH_I2CM_STAT0); -- if (!stat) -- return IRQ_NONE; -- -- hdmi_writeb(hdmi, stat, HDMI_IH_I2CM_STAT0); -- -- i2c->stat = stat; -- -- complete(&i2c->cmp); -- -- return IRQ_HANDLED; --} -- --static irqreturn_t dw_hdmi_hardirq(int irq, void *dev_id) --{ -- struct dw_hdmi *hdmi = dev_id; -- u8 intr_stat; -- irqreturn_t ret = IRQ_NONE; -- -- if (hdmi->i2c) -- ret = dw_hdmi_i2c_irq(hdmi); -- -- intr_stat = hdmi_readb(hdmi, HDMI_IH_PHY_STAT0); -- if (intr_stat) { -- hdmi_writeb(hdmi, ~0, HDMI_IH_MUTE_PHY_STAT0); -- return IRQ_WAKE_THREAD; -- } -- -- return ret; --} -- --static irqreturn_t dw_hdmi_irq(int irq, void *dev_id) --{ -- struct dw_hdmi *hdmi = dev_id; -- u8 intr_stat, phy_int_pol, phy_pol_mask, phy_stat; -- -- intr_stat = hdmi_readb(hdmi, HDMI_IH_PHY_STAT0); -- phy_int_pol = hdmi_readb(hdmi, HDMI_PHY_POL0); -- phy_stat = hdmi_readb(hdmi, HDMI_PHY_STAT0); -- -- phy_pol_mask = 0; -- if (intr_stat & HDMI_IH_PHY_STAT0_HPD) -- phy_pol_mask |= HDMI_PHY_HPD; -- if (intr_stat & HDMI_IH_PHY_STAT0_RX_SENSE0) -- phy_pol_mask |= HDMI_PHY_RX_SENSE0; -- if (intr_stat & HDMI_IH_PHY_STAT0_RX_SENSE1) -- phy_pol_mask |= HDMI_PHY_RX_SENSE1; -- if (intr_stat & HDMI_IH_PHY_STAT0_RX_SENSE2) -- phy_pol_mask |= HDMI_PHY_RX_SENSE2; -- if (intr_stat & HDMI_IH_PHY_STAT0_RX_SENSE3) -- phy_pol_mask |= HDMI_PHY_RX_SENSE3; -- -- if (phy_pol_mask) -- hdmi_modb(hdmi, ~phy_int_pol, phy_pol_mask, HDMI_PHY_POL0); -- -- /* -- * RX sense tells us whether the TDMS transmitters are detecting -- * load - in other words, there's something listening on the -- * other end of the link. Use this to decide whether we should -- * power on the phy as HPD may be toggled by the sink to merely -- * ask the source to re-read the EDID. -- */ -- if (intr_stat & -- (HDMI_IH_PHY_STAT0_RX_SENSE | HDMI_IH_PHY_STAT0_HPD)) { -- mutex_lock(&hdmi->mutex); -- if (!hdmi->disabled && !hdmi->force) { -- /* -- * If the RX sense status indicates we're disconnected, -- * clear the software rxsense status. -- */ -- if (!(phy_stat & HDMI_PHY_RX_SENSE)) -- hdmi->rxsense = false; -- -- /* -- * Only set the software rxsense status when both -- * rxsense and hpd indicates we're connected. -- * This avoids what seems to be bad behaviour in -- * at least iMX6S versions of the phy. -- */ -- if (phy_stat & HDMI_PHY_HPD) -- hdmi->rxsense = true; -- -- dw_hdmi_update_power(hdmi); -- dw_hdmi_update_phy_mask(hdmi); -- } -- mutex_unlock(&hdmi->mutex); -- } -- -- if (intr_stat & HDMI_IH_PHY_STAT0_HPD) { -- dev_dbg(hdmi->dev, "EVENT=%s\n", -- phy_int_pol & HDMI_PHY_HPD ? "plugin" : "plugout"); -- if (hdmi->bridge.dev) -- drm_helper_hpd_irq_event(hdmi->bridge.dev); -- } -- -- hdmi_writeb(hdmi, intr_stat, HDMI_IH_PHY_STAT0); -- hdmi_writeb(hdmi, ~(HDMI_IH_PHY_STAT0_HPD | HDMI_IH_PHY_STAT0_RX_SENSE), -- HDMI_IH_MUTE_PHY_STAT0); -- -- return IRQ_HANDLED; --} -- --static const struct dw_hdmi_phy_data dw_hdmi_phys[] = { -- { -- .type = DW_HDMI_PHY_DWC_HDMI_TX_PHY, -- .name = "DWC HDMI TX PHY", -- .gen = 1, -- }, { -- .type = DW_HDMI_PHY_DWC_MHL_PHY_HEAC, -- .name = "DWC MHL PHY + HEAC PHY", -- .gen = 2, -- .has_svsret = true, -- .configure = hdmi_phy_configure_dwc_hdmi_3d_tx, -- }, { -- .type = DW_HDMI_PHY_DWC_MHL_PHY, -- .name = "DWC MHL PHY", -- .gen = 2, -- .has_svsret = true, -- .configure = hdmi_phy_configure_dwc_hdmi_3d_tx, -- }, { -- .type = DW_HDMI_PHY_DWC_HDMI_3D_TX_PHY_HEAC, -- .name = "DWC HDMI 3D TX PHY + HEAC PHY", -- .gen = 2, -- .configure = hdmi_phy_configure_dwc_hdmi_3d_tx, -- }, { -- .type = DW_HDMI_PHY_DWC_HDMI_3D_TX_PHY, -- .name = "DWC HDMI 3D TX PHY", -- .gen = 2, -- .configure = hdmi_phy_configure_dwc_hdmi_3d_tx, -- }, { -- .type = DW_HDMI_PHY_DWC_HDMI20_TX_PHY, -- .name = "DWC HDMI 2.0 TX PHY", -- .gen = 2, -- .has_svsret = true, -- }, { -- .type = DW_HDMI_PHY_VENDOR_PHY, -- .name = "Vendor PHY", -- } --}; -- --static int dw_hdmi_detect_phy(struct dw_hdmi *hdmi) --{ -- unsigned int i; -- u8 phy_type; -- -- phy_type = hdmi_readb(hdmi, HDMI_CONFIG2_ID); -- -- if (phy_type == DW_HDMI_PHY_VENDOR_PHY) { -- /* Vendor PHYs require support from the glue layer. */ -- if (!hdmi->plat_data->phy_ops || !hdmi->plat_data->phy_name) { -- dev_err(hdmi->dev, -- "Vendor HDMI PHY not supported by glue layer\n"); -- return -ENODEV; -- } -- -- hdmi->phy.ops = hdmi->plat_data->phy_ops; -- hdmi->phy.data = hdmi->plat_data->phy_data; -- hdmi->phy.name = hdmi->plat_data->phy_name; -- return 0; -- } -- -- /* Synopsys PHYs are handled internally. */ -- for (i = 0; i < ARRAY_SIZE(dw_hdmi_phys); ++i) { -- if (dw_hdmi_phys[i].type == phy_type) { -- hdmi->phy.ops = &dw_hdmi_synopsys_phy_ops; -- hdmi->phy.name = dw_hdmi_phys[i].name; -- hdmi->phy.data = (void *)&dw_hdmi_phys[i]; -- -- if (!dw_hdmi_phys[i].configure && -- !hdmi->plat_data->configure_phy) { -- dev_err(hdmi->dev, "%s requires platform support\n", -- hdmi->phy.name); -- return -ENODEV; -- } -- -- return 0; -- } -- } -- -- dev_err(hdmi->dev, "Unsupported HDMI PHY type (%02x)\n", phy_type); -- return -ENODEV; --} -- --static const struct regmap_config hdmi_regmap_8bit_config = { -- .reg_bits = 32, -- .val_bits = 8, -- .reg_stride = 1, -- .max_register = HDMI_I2CM_FS_SCL_LCNT_0_ADDR, --}; -- --static const struct regmap_config hdmi_regmap_32bit_config = { -- .reg_bits = 32, -- .val_bits = 32, -- .reg_stride = 4, -- .max_register = HDMI_I2CM_FS_SCL_LCNT_0_ADDR << 2, --}; -- --static struct dw_hdmi * --__dw_hdmi_probe(struct platform_device *pdev, -- const struct dw_hdmi_plat_data *plat_data) --{ -- struct device *dev = &pdev->dev; -- struct device_node *np = dev->of_node; -- struct platform_device_info pdevinfo; -- struct device_node *ddc_node; -- struct dw_hdmi *hdmi; -- struct resource *iores = NULL; -- int irq; -- int ret; -- u32 val = 1; -- u8 prod_id0; -- u8 prod_id1; -- u8 config0; -- u8 config3; -- -- hdmi = devm_kzalloc(dev, sizeof(*hdmi), GFP_KERNEL); -- if (!hdmi) -- return ERR_PTR(-ENOMEM); -- -- hdmi->plat_data = plat_data; -- hdmi->dev = dev; -- hdmi->sample_rate = 48000; -- hdmi->disabled = true; -- hdmi->rxsense = true; -- hdmi->phy_mask = (u8)~(HDMI_PHY_HPD | HDMI_PHY_RX_SENSE); -- -- mutex_init(&hdmi->mutex); -- mutex_init(&hdmi->audio_mutex); -- spin_lock_init(&hdmi->audio_lock); -- -- ddc_node = of_parse_phandle(np, "ddc-i2c-bus", 0); -- if (ddc_node) { -- hdmi->ddc = of_get_i2c_adapter_by_node(ddc_node); -- of_node_put(ddc_node); -- if (!hdmi->ddc) { -- dev_dbg(hdmi->dev, "failed to read ddc node\n"); -- return ERR_PTR(-EPROBE_DEFER); -- } -- -- } else { -- dev_dbg(hdmi->dev, "no ddc property found\n"); -- } -- -- if (!plat_data->regm) { -- const struct regmap_config *reg_config; -- -- of_property_read_u32(np, "reg-io-width", &val); -- switch (val) { -- case 4: -- reg_config = &hdmi_regmap_32bit_config; -- hdmi->reg_shift = 2; -- break; -- case 1: -- reg_config = &hdmi_regmap_8bit_config; -- break; -- default: -- dev_err(dev, "reg-io-width must be 1 or 4\n"); -- return ERR_PTR(-EINVAL); -- } -- -- iores = platform_get_resource(pdev, IORESOURCE_MEM, 0); -- hdmi->regs = devm_ioremap_resource(dev, iores); -- if (IS_ERR(hdmi->regs)) { -- ret = PTR_ERR(hdmi->regs); -- goto err_res; -- } -- -- hdmi->regm = devm_regmap_init_mmio(dev, hdmi->regs, reg_config); -- if (IS_ERR(hdmi->regm)) { -- dev_err(dev, "Failed to configure regmap\n"); -- ret = PTR_ERR(hdmi->regm); -- goto err_res; -- } -- } else { -- hdmi->regm = plat_data->regm; -- } -- -- hdmi->isfr_clk = devm_clk_get(hdmi->dev, "isfr"); -- if (IS_ERR(hdmi->isfr_clk)) { -- ret = PTR_ERR(hdmi->isfr_clk); -- dev_err(hdmi->dev, "Unable to get HDMI isfr clk: %d\n", ret); -- goto err_res; -- } -- -- ret = clk_prepare_enable(hdmi->isfr_clk); -- if (ret) { -- dev_err(hdmi->dev, "Cannot enable HDMI isfr clock: %d\n", ret); -- goto err_res; -- } -- -- hdmi->iahb_clk = devm_clk_get(hdmi->dev, "iahb"); -- if (IS_ERR(hdmi->iahb_clk)) { -- ret = PTR_ERR(hdmi->iahb_clk); -- dev_err(hdmi->dev, "Unable to get HDMI iahb clk: %d\n", ret); -- goto err_isfr; -- } -- -- ret = clk_prepare_enable(hdmi->iahb_clk); -- if (ret) { -- dev_err(hdmi->dev, "Cannot enable HDMI iahb clock: %d\n", ret); -- goto err_isfr; -- } -- -- /* Product and revision IDs */ -- hdmi->version = (hdmi_readb(hdmi, HDMI_DESIGN_ID) << 8) -- | (hdmi_readb(hdmi, HDMI_REVISION_ID) << 0); -- prod_id0 = hdmi_readb(hdmi, HDMI_PRODUCT_ID0); -- prod_id1 = hdmi_readb(hdmi, HDMI_PRODUCT_ID1); -- -- if (prod_id0 != HDMI_PRODUCT_ID0_HDMI_TX || -- (prod_id1 & ~HDMI_PRODUCT_ID1_HDCP) != HDMI_PRODUCT_ID1_HDMI_TX) { -- dev_err(dev, "Unsupported HDMI controller (%04x:%02x:%02x)\n", -- hdmi->version, prod_id0, prod_id1); -- ret = -ENODEV; -- goto err_iahb; -- } -- -- ret = dw_hdmi_detect_phy(hdmi); -- if (ret < 0) -- goto err_iahb; -- -- dev_info(dev, "Detected HDMI TX controller v%x.%03x %s HDCP (%s)\n", -- hdmi->version >> 12, hdmi->version & 0xfff, -- prod_id1 & HDMI_PRODUCT_ID1_HDCP ? "with" : "without", -- hdmi->phy.name); -- -- initialize_hdmi_ih_mutes(hdmi); -- -- irq = platform_get_irq(pdev, 0); -- if (irq < 0) { -- ret = irq; -- goto err_iahb; -- } -- -- ret = devm_request_threaded_irq(dev, irq, dw_hdmi_hardirq, -- dw_hdmi_irq, IRQF_SHARED, -- dev_name(dev), hdmi); -- if (ret) -- goto err_iahb; -- -- /* -- * To prevent overflows in HDMI_IH_FC_STAT2, set the clk regenerator -- * N and cts values before enabling phy -- */ -- hdmi_init_clk_regenerator(hdmi); -- -- /* If DDC bus is not specified, try to register HDMI I2C bus */ -- if (!hdmi->ddc) { -- hdmi->ddc = dw_hdmi_i2c_adapter(hdmi); -- if (IS_ERR(hdmi->ddc)) -- hdmi->ddc = NULL; -- } -- -- /* -- * Configure registers related to HDMI interrupt -- * generation before registering IRQ. -- */ -- hdmi_writeb(hdmi, HDMI_PHY_HPD | HDMI_PHY_RX_SENSE, HDMI_PHY_POL0); -- -- /* Clear Hotplug interrupts */ -- hdmi_writeb(hdmi, HDMI_IH_PHY_STAT0_HPD | HDMI_IH_PHY_STAT0_RX_SENSE, -- HDMI_IH_PHY_STAT0); -- -- hdmi->bridge.driver_private = hdmi; -- hdmi->bridge.funcs = &dw_hdmi_bridge_funcs; --#ifdef CONFIG_OF -- hdmi->bridge.of_node = pdev->dev.of_node; --#endif -- -- ret = dw_hdmi_fb_registered(hdmi); -- if (ret) -- goto err_iahb; -- -- /* Unmute interrupts */ -- hdmi_writeb(hdmi, ~(HDMI_IH_PHY_STAT0_HPD | HDMI_IH_PHY_STAT0_RX_SENSE), -- HDMI_IH_MUTE_PHY_STAT0); -- -- memset(&pdevinfo, 0, sizeof(pdevinfo)); -- pdevinfo.parent = dev; -- pdevinfo.id = PLATFORM_DEVID_AUTO; -- -- config0 = hdmi_readb(hdmi, HDMI_CONFIG0_ID); -- config3 = hdmi_readb(hdmi, HDMI_CONFIG3_ID); -- -- if (iores && config3 & HDMI_CONFIG3_AHBAUDDMA) { -- struct dw_hdmi_audio_data audio; -- -- audio.phys = iores->start; -- audio.base = hdmi->regs; -- audio.irq = irq; -- audio.hdmi = hdmi; -- audio.eld = hdmi->connector.eld; -- -- pdevinfo.name = "dw-hdmi-ahb-audio"; -- pdevinfo.data = &audio; -- pdevinfo.size_data = sizeof(audio); -- pdevinfo.dma_mask = DMA_BIT_MASK(32); -- hdmi->audio = platform_device_register_full(&pdevinfo); -- } else if (config0 & HDMI_CONFIG0_I2S) { -- struct dw_hdmi_i2s_audio_data audio; -- -- audio.hdmi = hdmi; -- audio.write = hdmi_writeb; -- audio.read = hdmi_readb; -- -- pdevinfo.name = "dw-hdmi-i2s-audio"; -- pdevinfo.data = &audio; -- pdevinfo.size_data = sizeof(audio); -- pdevinfo.dma_mask = DMA_BIT_MASK(32); -- hdmi->audio = platform_device_register_full(&pdevinfo); -- } -- -- /* Reset HDMI DDC I2C master controller and mute I2CM interrupts */ -- if (hdmi->i2c) -- dw_hdmi_i2c_init(hdmi); -- -- platform_set_drvdata(pdev, hdmi); -- -- return hdmi; -- --err_iahb: -- if (hdmi->i2c) { -- i2c_del_adapter(&hdmi->i2c->adap); -- hdmi->ddc = NULL; -- } -- -- clk_disable_unprepare(hdmi->iahb_clk); --err_isfr: -- clk_disable_unprepare(hdmi->isfr_clk); --err_res: -- i2c_put_adapter(hdmi->ddc); -- -- return ERR_PTR(ret); --} -- --static void __dw_hdmi_remove(struct dw_hdmi *hdmi) --{ -- if (hdmi->audio && !IS_ERR(hdmi->audio)) -- platform_device_unregister(hdmi->audio); -- -- /* Disable all interrupts */ -- hdmi_writeb(hdmi, ~0, HDMI_IH_MUTE_PHY_STAT0); -- -- clk_disable_unprepare(hdmi->iahb_clk); -- clk_disable_unprepare(hdmi->isfr_clk); -- -- if (hdmi->i2c) -- i2c_del_adapter(&hdmi->i2c->adap); -- else -- i2c_put_adapter(hdmi->ddc); --} -- --/* ----------------------------------------------------------------------------- -- * Probe/remove API, used from platforms based on the DRM bridge API. -- */ --int dw_hdmi_probe(struct platform_device *pdev, -- const struct dw_hdmi_plat_data *plat_data) --{ -- struct dw_hdmi *hdmi; -- int ret; -- -- hdmi = __dw_hdmi_probe(pdev, plat_data); -- if (IS_ERR(hdmi)) -- return PTR_ERR(hdmi); -- -- ret = drm_bridge_add(&hdmi->bridge); -- if (ret < 0) { -- __dw_hdmi_remove(hdmi); -- return ret; -- } -- -- return 0; --} --EXPORT_SYMBOL_GPL(dw_hdmi_probe); -- --void dw_hdmi_remove(struct platform_device *pdev) --{ -- struct dw_hdmi *hdmi = platform_get_drvdata(pdev); -- -- drm_bridge_remove(&hdmi->bridge); -- -- __dw_hdmi_remove(hdmi); --} --EXPORT_SYMBOL_GPL(dw_hdmi_remove); -- --/* ----------------------------------------------------------------------------- -- * Bind/unbind API, used from platforms based on the component framework. -- */ --int dw_hdmi_bind(struct platform_device *pdev, struct drm_encoder *encoder, -- const struct dw_hdmi_plat_data *plat_data) --{ -- struct dw_hdmi *hdmi; -- int ret; -- -- hdmi = __dw_hdmi_probe(pdev, plat_data); -- if (IS_ERR(hdmi)) -- return PTR_ERR(hdmi); -- -- ret = drm_bridge_attach(encoder, &hdmi->bridge, NULL); -- if (ret) { -- dw_hdmi_remove(pdev); -- DRM_ERROR("Failed to initialize bridge with drm\n"); -- return ret; -- } -- -- return 0; --} --EXPORT_SYMBOL_GPL(dw_hdmi_bind); -- --void dw_hdmi_unbind(struct device *dev) --{ -- struct dw_hdmi *hdmi = dev_get_drvdata(dev); -- -- __dw_hdmi_remove(hdmi); --} --EXPORT_SYMBOL_GPL(dw_hdmi_unbind); -- --MODULE_AUTHOR("Sascha Hauer "); --MODULE_AUTHOR("Andy Yan "); --MODULE_AUTHOR("Yakir Yang "); --MODULE_AUTHOR("Vladimir Zapolskiy "); --MODULE_DESCRIPTION("DW HDMI transmitter driver"); --MODULE_LICENSE("GPL"); --MODULE_ALIAS("platform:dw-hdmi"); -diff --git a/drivers/gpu/drm/bridge/dw-hdmi.h b/drivers/gpu/drm/bridge/dw-hdmi.h -deleted file mode 100644 -index 325b0b8..0000000 ---- a/drivers/gpu/drm/bridge/dw-hdmi.h -+++ /dev/null -@@ -1,1153 +0,0 @@ --/* -- * Copyright (C) 2011 Freescale Semiconductor, Inc. -- * -- * This program is free software; you can redistribute it and/or modify -- * it under the terms of the GNU General Public License as published by -- * the Free Software Foundation; either version 2 of the License, or -- * (at your option) any later version. -- */ -- --#ifndef __DW_HDMI_H__ --#define __DW_HDMI_H__ -- --/* Identification Registers */ --#define HDMI_DESIGN_ID 0x0000 --#define HDMI_REVISION_ID 0x0001 --#define HDMI_PRODUCT_ID0 0x0002 --#define HDMI_PRODUCT_ID1 0x0003 --#define HDMI_CONFIG0_ID 0x0004 --#define HDMI_CONFIG1_ID 0x0005 --#define HDMI_CONFIG2_ID 0x0006 --#define HDMI_CONFIG3_ID 0x0007 -- --/* Interrupt Registers */ --#define HDMI_IH_FC_STAT0 0x0100 --#define HDMI_IH_FC_STAT1 0x0101 --#define HDMI_IH_FC_STAT2 0x0102 --#define HDMI_IH_AS_STAT0 0x0103 --#define HDMI_IH_PHY_STAT0 0x0104 --#define HDMI_IH_I2CM_STAT0 0x0105 --#define HDMI_IH_CEC_STAT0 0x0106 --#define HDMI_IH_VP_STAT0 0x0107 --#define HDMI_IH_I2CMPHY_STAT0 0x0108 --#define HDMI_IH_AHBDMAAUD_STAT0 0x0109 -- --#define HDMI_IH_MUTE_FC_STAT0 0x0180 --#define HDMI_IH_MUTE_FC_STAT1 0x0181 --#define HDMI_IH_MUTE_FC_STAT2 0x0182 --#define HDMI_IH_MUTE_AS_STAT0 0x0183 --#define HDMI_IH_MUTE_PHY_STAT0 0x0184 --#define HDMI_IH_MUTE_I2CM_STAT0 0x0185 --#define HDMI_IH_MUTE_CEC_STAT0 0x0186 --#define HDMI_IH_MUTE_VP_STAT0 0x0187 --#define HDMI_IH_MUTE_I2CMPHY_STAT0 0x0188 --#define HDMI_IH_MUTE_AHBDMAAUD_STAT0 0x0189 --#define HDMI_IH_MUTE 0x01FF -- --/* Video Sample Registers */ --#define HDMI_TX_INVID0 0x0200 --#define HDMI_TX_INSTUFFING 0x0201 --#define HDMI_TX_GYDATA0 0x0202 --#define HDMI_TX_GYDATA1 0x0203 --#define HDMI_TX_RCRDATA0 0x0204 --#define HDMI_TX_RCRDATA1 0x0205 --#define HDMI_TX_BCBDATA0 0x0206 --#define HDMI_TX_BCBDATA1 0x0207 -- --/* Video Packetizer Registers */ --#define HDMI_VP_STATUS 0x0800 --#define HDMI_VP_PR_CD 0x0801 --#define HDMI_VP_STUFF 0x0802 --#define HDMI_VP_REMAP 0x0803 --#define HDMI_VP_CONF 0x0804 --#define HDMI_VP_STAT 0x0805 --#define HDMI_VP_INT 0x0806 --#define HDMI_VP_MASK 0x0807 --#define HDMI_VP_POL 0x0808 -- --/* Frame Composer Registers */ --#define HDMI_FC_INVIDCONF 0x1000 --#define HDMI_FC_INHACTV0 0x1001 --#define HDMI_FC_INHACTV1 0x1002 --#define HDMI_FC_INHBLANK0 0x1003 --#define HDMI_FC_INHBLANK1 0x1004 --#define HDMI_FC_INVACTV0 0x1005 --#define HDMI_FC_INVACTV1 0x1006 --#define HDMI_FC_INVBLANK 0x1007 --#define HDMI_FC_HSYNCINDELAY0 0x1008 --#define HDMI_FC_HSYNCINDELAY1 0x1009 --#define HDMI_FC_HSYNCINWIDTH0 0x100A --#define HDMI_FC_HSYNCINWIDTH1 0x100B --#define HDMI_FC_VSYNCINDELAY 0x100C --#define HDMI_FC_VSYNCINWIDTH 0x100D --#define HDMI_FC_INFREQ0 0x100E --#define HDMI_FC_INFREQ1 0x100F --#define HDMI_FC_INFREQ2 0x1010 --#define HDMI_FC_CTRLDUR 0x1011 --#define HDMI_FC_EXCTRLDUR 0x1012 --#define HDMI_FC_EXCTRLSPAC 0x1013 --#define HDMI_FC_CH0PREAM 0x1014 --#define HDMI_FC_CH1PREAM 0x1015 --#define HDMI_FC_CH2PREAM 0x1016 --#define HDMI_FC_AVICONF3 0x1017 --#define HDMI_FC_GCP 0x1018 --#define HDMI_FC_AVICONF0 0x1019 --#define HDMI_FC_AVICONF1 0x101A --#define HDMI_FC_AVICONF2 0x101B --#define HDMI_FC_AVIVID 0x101C --#define HDMI_FC_AVIETB0 0x101D --#define HDMI_FC_AVIETB1 0x101E --#define HDMI_FC_AVISBB0 0x101F --#define HDMI_FC_AVISBB1 0x1020 --#define HDMI_FC_AVIELB0 0x1021 --#define HDMI_FC_AVIELB1 0x1022 --#define HDMI_FC_AVISRB0 0x1023 --#define HDMI_FC_AVISRB1 0x1024 --#define HDMI_FC_AUDICONF0 0x1025 --#define HDMI_FC_AUDICONF1 0x1026 --#define HDMI_FC_AUDICONF2 0x1027 --#define HDMI_FC_AUDICONF3 0x1028 --#define HDMI_FC_VSDIEEEID0 0x1029 --#define HDMI_FC_VSDSIZE 0x102A --#define HDMI_FC_VSDIEEEID1 0x1030 --#define HDMI_FC_VSDIEEEID2 0x1031 --#define HDMI_FC_VSDPAYLOAD0 0x1032 --#define HDMI_FC_VSDPAYLOAD1 0x1033 --#define HDMI_FC_VSDPAYLOAD2 0x1034 --#define HDMI_FC_VSDPAYLOAD3 0x1035 --#define HDMI_FC_VSDPAYLOAD4 0x1036 --#define HDMI_FC_VSDPAYLOAD5 0x1037 --#define HDMI_FC_VSDPAYLOAD6 0x1038 --#define HDMI_FC_VSDPAYLOAD7 0x1039 --#define HDMI_FC_VSDPAYLOAD8 0x103A --#define HDMI_FC_VSDPAYLOAD9 0x103B --#define HDMI_FC_VSDPAYLOAD10 0x103C --#define HDMI_FC_VSDPAYLOAD11 0x103D --#define HDMI_FC_VSDPAYLOAD12 0x103E --#define HDMI_FC_VSDPAYLOAD13 0x103F --#define HDMI_FC_VSDPAYLOAD14 0x1040 --#define HDMI_FC_VSDPAYLOAD15 0x1041 --#define HDMI_FC_VSDPAYLOAD16 0x1042 --#define HDMI_FC_VSDPAYLOAD17 0x1043 --#define HDMI_FC_VSDPAYLOAD18 0x1044 --#define HDMI_FC_VSDPAYLOAD19 0x1045 --#define HDMI_FC_VSDPAYLOAD20 0x1046 --#define HDMI_FC_VSDPAYLOAD21 0x1047 --#define HDMI_FC_VSDPAYLOAD22 0x1048 --#define HDMI_FC_VSDPAYLOAD23 0x1049 --#define HDMI_FC_SPDVENDORNAME0 0x104A --#define HDMI_FC_SPDVENDORNAME1 0x104B --#define HDMI_FC_SPDVENDORNAME2 0x104C --#define HDMI_FC_SPDVENDORNAME3 0x104D --#define HDMI_FC_SPDVENDORNAME4 0x104E --#define HDMI_FC_SPDVENDORNAME5 0x104F --#define HDMI_FC_SPDVENDORNAME6 0x1050 --#define HDMI_FC_SPDVENDORNAME7 0x1051 --#define HDMI_FC_SDPPRODUCTNAME0 0x1052 --#define HDMI_FC_SDPPRODUCTNAME1 0x1053 --#define HDMI_FC_SDPPRODUCTNAME2 0x1054 --#define HDMI_FC_SDPPRODUCTNAME3 0x1055 --#define HDMI_FC_SDPPRODUCTNAME4 0x1056 --#define HDMI_FC_SDPPRODUCTNAME5 0x1057 --#define HDMI_FC_SDPPRODUCTNAME6 0x1058 --#define HDMI_FC_SDPPRODUCTNAME7 0x1059 --#define HDMI_FC_SDPPRODUCTNAME8 0x105A --#define HDMI_FC_SDPPRODUCTNAME9 0x105B --#define HDMI_FC_SDPPRODUCTNAME10 0x105C --#define HDMI_FC_SDPPRODUCTNAME11 0x105D --#define HDMI_FC_SDPPRODUCTNAME12 0x105E --#define HDMI_FC_SDPPRODUCTNAME13 0x105F --#define HDMI_FC_SDPPRODUCTNAME14 0x1060 --#define HDMI_FC_SPDPRODUCTNAME15 0x1061 --#define HDMI_FC_SPDDEVICEINF 0x1062 --#define HDMI_FC_AUDSCONF 0x1063 --#define HDMI_FC_AUDSSTAT 0x1064 --#define HDMI_FC_DATACH0FILL 0x1070 --#define HDMI_FC_DATACH1FILL 0x1071 --#define HDMI_FC_DATACH2FILL 0x1072 --#define HDMI_FC_CTRLQHIGH 0x1073 --#define HDMI_FC_CTRLQLOW 0x1074 --#define HDMI_FC_ACP0 0x1075 --#define HDMI_FC_ACP28 0x1076 --#define HDMI_FC_ACP27 0x1077 --#define HDMI_FC_ACP26 0x1078 --#define HDMI_FC_ACP25 0x1079 --#define HDMI_FC_ACP24 0x107A --#define HDMI_FC_ACP23 0x107B --#define HDMI_FC_ACP22 0x107C --#define HDMI_FC_ACP21 0x107D --#define HDMI_FC_ACP20 0x107E --#define HDMI_FC_ACP19 0x107F --#define HDMI_FC_ACP18 0x1080 --#define HDMI_FC_ACP17 0x1081 --#define HDMI_FC_ACP16 0x1082 --#define HDMI_FC_ACP15 0x1083 --#define HDMI_FC_ACP14 0x1084 --#define HDMI_FC_ACP13 0x1085 --#define HDMI_FC_ACP12 0x1086 --#define HDMI_FC_ACP11 0x1087 --#define HDMI_FC_ACP10 0x1088 --#define HDMI_FC_ACP9 0x1089 --#define HDMI_FC_ACP8 0x108A --#define HDMI_FC_ACP7 0x108B --#define HDMI_FC_ACP6 0x108C --#define HDMI_FC_ACP5 0x108D --#define HDMI_FC_ACP4 0x108E --#define HDMI_FC_ACP3 0x108F --#define HDMI_FC_ACP2 0x1090 --#define HDMI_FC_ACP1 0x1091 --#define HDMI_FC_ISCR1_0 0x1092 --#define HDMI_FC_ISCR1_16 0x1093 --#define HDMI_FC_ISCR1_15 0x1094 --#define HDMI_FC_ISCR1_14 0x1095 --#define HDMI_FC_ISCR1_13 0x1096 --#define HDMI_FC_ISCR1_12 0x1097 --#define HDMI_FC_ISCR1_11 0x1098 --#define HDMI_FC_ISCR1_10 0x1099 --#define HDMI_FC_ISCR1_9 0x109A --#define HDMI_FC_ISCR1_8 0x109B --#define HDMI_FC_ISCR1_7 0x109C --#define HDMI_FC_ISCR1_6 0x109D --#define HDMI_FC_ISCR1_5 0x109E --#define HDMI_FC_ISCR1_4 0x109F --#define HDMI_FC_ISCR1_3 0x10A0 --#define HDMI_FC_ISCR1_2 0x10A1 --#define HDMI_FC_ISCR1_1 0x10A2 --#define HDMI_FC_ISCR2_15 0x10A3 --#define HDMI_FC_ISCR2_14 0x10A4 --#define HDMI_FC_ISCR2_13 0x10A5 --#define HDMI_FC_ISCR2_12 0x10A6 --#define HDMI_FC_ISCR2_11 0x10A7 --#define HDMI_FC_ISCR2_10 0x10A8 --#define HDMI_FC_ISCR2_9 0x10A9 --#define HDMI_FC_ISCR2_8 0x10AA --#define HDMI_FC_ISCR2_7 0x10AB --#define HDMI_FC_ISCR2_6 0x10AC --#define HDMI_FC_ISCR2_5 0x10AD --#define HDMI_FC_ISCR2_4 0x10AE --#define HDMI_FC_ISCR2_3 0x10AF --#define HDMI_FC_ISCR2_2 0x10B0 --#define HDMI_FC_ISCR2_1 0x10B1 --#define HDMI_FC_ISCR2_0 0x10B2 --#define HDMI_FC_DATAUTO0 0x10B3 --#define HDMI_FC_DATAUTO1 0x10B4 --#define HDMI_FC_DATAUTO2 0x10B5 --#define HDMI_FC_DATMAN 0x10B6 --#define HDMI_FC_DATAUTO3 0x10B7 --#define HDMI_FC_RDRB0 0x10B8 --#define HDMI_FC_RDRB1 0x10B9 --#define HDMI_FC_RDRB2 0x10BA --#define HDMI_FC_RDRB3 0x10BB --#define HDMI_FC_RDRB4 0x10BC --#define HDMI_FC_RDRB5 0x10BD --#define HDMI_FC_RDRB6 0x10BE --#define HDMI_FC_RDRB7 0x10BF --#define HDMI_FC_STAT0 0x10D0 --#define HDMI_FC_INT0 0x10D1 --#define HDMI_FC_MASK0 0x10D2 --#define HDMI_FC_POL0 0x10D3 --#define HDMI_FC_STAT1 0x10D4 --#define HDMI_FC_INT1 0x10D5 --#define HDMI_FC_MASK1 0x10D6 --#define HDMI_FC_POL1 0x10D7 --#define HDMI_FC_STAT2 0x10D8 --#define HDMI_FC_INT2 0x10D9 --#define HDMI_FC_MASK2 0x10DA --#define HDMI_FC_POL2 0x10DB --#define HDMI_FC_PRCONF 0x10E0 -- --#define HDMI_FC_GMD_STAT 0x1100 --#define HDMI_FC_GMD_EN 0x1101 --#define HDMI_FC_GMD_UP 0x1102 --#define HDMI_FC_GMD_CONF 0x1103 --#define HDMI_FC_GMD_HB 0x1104 --#define HDMI_FC_GMD_PB0 0x1105 --#define HDMI_FC_GMD_PB1 0x1106 --#define HDMI_FC_GMD_PB2 0x1107 --#define HDMI_FC_GMD_PB3 0x1108 --#define HDMI_FC_GMD_PB4 0x1109 --#define HDMI_FC_GMD_PB5 0x110A --#define HDMI_FC_GMD_PB6 0x110B --#define HDMI_FC_GMD_PB7 0x110C --#define HDMI_FC_GMD_PB8 0x110D --#define HDMI_FC_GMD_PB9 0x110E --#define HDMI_FC_GMD_PB10 0x110F --#define HDMI_FC_GMD_PB11 0x1110 --#define HDMI_FC_GMD_PB12 0x1111 --#define HDMI_FC_GMD_PB13 0x1112 --#define HDMI_FC_GMD_PB14 0x1113 --#define HDMI_FC_GMD_PB15 0x1114 --#define HDMI_FC_GMD_PB16 0x1115 --#define HDMI_FC_GMD_PB17 0x1116 --#define HDMI_FC_GMD_PB18 0x1117 --#define HDMI_FC_GMD_PB19 0x1118 --#define HDMI_FC_GMD_PB20 0x1119 --#define HDMI_FC_GMD_PB21 0x111A --#define HDMI_FC_GMD_PB22 0x111B --#define HDMI_FC_GMD_PB23 0x111C --#define HDMI_FC_GMD_PB24 0x111D --#define HDMI_FC_GMD_PB25 0x111E --#define HDMI_FC_GMD_PB26 0x111F --#define HDMI_FC_GMD_PB27 0x1120 -- --#define HDMI_FC_DBGFORCE 0x1200 --#define HDMI_FC_DBGAUD0CH0 0x1201 --#define HDMI_FC_DBGAUD1CH0 0x1202 --#define HDMI_FC_DBGAUD2CH0 0x1203 --#define HDMI_FC_DBGAUD0CH1 0x1204 --#define HDMI_FC_DBGAUD1CH1 0x1205 --#define HDMI_FC_DBGAUD2CH1 0x1206 --#define HDMI_FC_DBGAUD0CH2 0x1207 --#define HDMI_FC_DBGAUD1CH2 0x1208 --#define HDMI_FC_DBGAUD2CH2 0x1209 --#define HDMI_FC_DBGAUD0CH3 0x120A --#define HDMI_FC_DBGAUD1CH3 0x120B --#define HDMI_FC_DBGAUD2CH3 0x120C --#define HDMI_FC_DBGAUD0CH4 0x120D --#define HDMI_FC_DBGAUD1CH4 0x120E --#define HDMI_FC_DBGAUD2CH4 0x120F --#define HDMI_FC_DBGAUD0CH5 0x1210 --#define HDMI_FC_DBGAUD1CH5 0x1211 --#define HDMI_FC_DBGAUD2CH5 0x1212 --#define HDMI_FC_DBGAUD0CH6 0x1213 --#define HDMI_FC_DBGAUD1CH6 0x1214 --#define HDMI_FC_DBGAUD2CH6 0x1215 --#define HDMI_FC_DBGAUD0CH7 0x1216 --#define HDMI_FC_DBGAUD1CH7 0x1217 --#define HDMI_FC_DBGAUD2CH7 0x1218 --#define HDMI_FC_DBGTMDS0 0x1219 --#define HDMI_FC_DBGTMDS1 0x121A --#define HDMI_FC_DBGTMDS2 0x121B -- --/* HDMI Source PHY Registers */ --#define HDMI_PHY_CONF0 0x3000 --#define HDMI_PHY_TST0 0x3001 --#define HDMI_PHY_TST1 0x3002 --#define HDMI_PHY_TST2 0x3003 --#define HDMI_PHY_STAT0 0x3004 --#define HDMI_PHY_INT0 0x3005 --#define HDMI_PHY_MASK0 0x3006 --#define HDMI_PHY_POL0 0x3007 -- --/* HDMI Master PHY Registers */ --#define HDMI_PHY_I2CM_SLAVE_ADDR 0x3020 --#define HDMI_PHY_I2CM_ADDRESS_ADDR 0x3021 --#define HDMI_PHY_I2CM_DATAO_1_ADDR 0x3022 --#define HDMI_PHY_I2CM_DATAO_0_ADDR 0x3023 --#define HDMI_PHY_I2CM_DATAI_1_ADDR 0x3024 --#define HDMI_PHY_I2CM_DATAI_0_ADDR 0x3025 --#define HDMI_PHY_I2CM_OPERATION_ADDR 0x3026 --#define HDMI_PHY_I2CM_INT_ADDR 0x3027 --#define HDMI_PHY_I2CM_CTLINT_ADDR 0x3028 --#define HDMI_PHY_I2CM_DIV_ADDR 0x3029 --#define HDMI_PHY_I2CM_SOFTRSTZ_ADDR 0x302a --#define HDMI_PHY_I2CM_SS_SCL_HCNT_1_ADDR 0x302b --#define HDMI_PHY_I2CM_SS_SCL_HCNT_0_ADDR 0x302c --#define HDMI_PHY_I2CM_SS_SCL_LCNT_1_ADDR 0x302d --#define HDMI_PHY_I2CM_SS_SCL_LCNT_0_ADDR 0x302e --#define HDMI_PHY_I2CM_FS_SCL_HCNT_1_ADDR 0x302f --#define HDMI_PHY_I2CM_FS_SCL_HCNT_0_ADDR 0x3030 --#define HDMI_PHY_I2CM_FS_SCL_LCNT_1_ADDR 0x3031 --#define HDMI_PHY_I2CM_FS_SCL_LCNT_0_ADDR 0x3032 -- --/* Audio Sampler Registers */ --#define HDMI_AUD_CONF0 0x3100 --#define HDMI_AUD_CONF1 0x3101 --#define HDMI_AUD_INT 0x3102 --#define HDMI_AUD_CONF2 0x3103 --#define HDMI_AUD_N1 0x3200 --#define HDMI_AUD_N2 0x3201 --#define HDMI_AUD_N3 0x3202 --#define HDMI_AUD_CTS1 0x3203 --#define HDMI_AUD_CTS2 0x3204 --#define HDMI_AUD_CTS3 0x3205 --#define HDMI_AUD_INPUTCLKFS 0x3206 --#define HDMI_AUD_SPDIFINT 0x3302 --#define HDMI_AUD_CONF0_HBR 0x3400 --#define HDMI_AUD_HBR_STATUS 0x3401 --#define HDMI_AUD_HBR_INT 0x3402 --#define HDMI_AUD_HBR_POL 0x3403 --#define HDMI_AUD_HBR_MASK 0x3404 -- --/* -- * Generic Parallel Audio Interface Registers -- * Not used as GPAUD interface is not enabled in hw -- */ --#define HDMI_GP_CONF0 0x3500 --#define HDMI_GP_CONF1 0x3501 --#define HDMI_GP_CONF2 0x3502 --#define HDMI_GP_STAT 0x3503 --#define HDMI_GP_INT 0x3504 --#define HDMI_GP_MASK 0x3505 --#define HDMI_GP_POL 0x3506 -- --/* Audio DMA Registers */ --#define HDMI_AHB_DMA_CONF0 0x3600 --#define HDMI_AHB_DMA_START 0x3601 --#define HDMI_AHB_DMA_STOP 0x3602 --#define HDMI_AHB_DMA_THRSLD 0x3603 --#define HDMI_AHB_DMA_STRADDR0 0x3604 --#define HDMI_AHB_DMA_STRADDR1 0x3605 --#define HDMI_AHB_DMA_STRADDR2 0x3606 --#define HDMI_AHB_DMA_STRADDR3 0x3607 --#define HDMI_AHB_DMA_STPADDR0 0x3608 --#define HDMI_AHB_DMA_STPADDR1 0x3609 --#define HDMI_AHB_DMA_STPADDR2 0x360a --#define HDMI_AHB_DMA_STPADDR3 0x360b --#define HDMI_AHB_DMA_BSTADDR0 0x360c --#define HDMI_AHB_DMA_BSTADDR1 0x360d --#define HDMI_AHB_DMA_BSTADDR2 0x360e --#define HDMI_AHB_DMA_BSTADDR3 0x360f --#define HDMI_AHB_DMA_MBLENGTH0 0x3610 --#define HDMI_AHB_DMA_MBLENGTH1 0x3611 --#define HDMI_AHB_DMA_STAT 0x3612 --#define HDMI_AHB_DMA_INT 0x3613 --#define HDMI_AHB_DMA_MASK 0x3614 --#define HDMI_AHB_DMA_POL 0x3615 --#define HDMI_AHB_DMA_CONF1 0x3616 --#define HDMI_AHB_DMA_BUFFSTAT 0x3617 --#define HDMI_AHB_DMA_BUFFINT 0x3618 --#define HDMI_AHB_DMA_BUFFMASK 0x3619 --#define HDMI_AHB_DMA_BUFFPOL 0x361a -- --/* Main Controller Registers */ --#define HDMI_MC_SFRDIV 0x4000 --#define HDMI_MC_CLKDIS 0x4001 --#define HDMI_MC_SWRSTZ 0x4002 --#define HDMI_MC_OPCTRL 0x4003 --#define HDMI_MC_FLOWCTRL 0x4004 --#define HDMI_MC_PHYRSTZ 0x4005 --#define HDMI_MC_LOCKONCLOCK 0x4006 --#define HDMI_MC_HEACPHY_RST 0x4007 -- --/* Color Space Converter Registers */ --#define HDMI_CSC_CFG 0x4100 --#define HDMI_CSC_SCALE 0x4101 --#define HDMI_CSC_COEF_A1_MSB 0x4102 --#define HDMI_CSC_COEF_A1_LSB 0x4103 --#define HDMI_CSC_COEF_A2_MSB 0x4104 --#define HDMI_CSC_COEF_A2_LSB 0x4105 --#define HDMI_CSC_COEF_A3_MSB 0x4106 --#define HDMI_CSC_COEF_A3_LSB 0x4107 --#define HDMI_CSC_COEF_A4_MSB 0x4108 --#define HDMI_CSC_COEF_A4_LSB 0x4109 --#define HDMI_CSC_COEF_B1_MSB 0x410A --#define HDMI_CSC_COEF_B1_LSB 0x410B --#define HDMI_CSC_COEF_B2_MSB 0x410C --#define HDMI_CSC_COEF_B2_LSB 0x410D --#define HDMI_CSC_COEF_B3_MSB 0x410E --#define HDMI_CSC_COEF_B3_LSB 0x410F --#define HDMI_CSC_COEF_B4_MSB 0x4110 --#define HDMI_CSC_COEF_B4_LSB 0x4111 --#define HDMI_CSC_COEF_C1_MSB 0x4112 --#define HDMI_CSC_COEF_C1_LSB 0x4113 --#define HDMI_CSC_COEF_C2_MSB 0x4114 --#define HDMI_CSC_COEF_C2_LSB 0x4115 --#define HDMI_CSC_COEF_C3_MSB 0x4116 --#define HDMI_CSC_COEF_C3_LSB 0x4117 --#define HDMI_CSC_COEF_C4_MSB 0x4118 --#define HDMI_CSC_COEF_C4_LSB 0x4119 -- --/* HDCP Encryption Engine Registers */ --#define HDMI_A_HDCPCFG0 0x5000 --#define HDMI_A_HDCPCFG1 0x5001 --#define HDMI_A_HDCPOBS0 0x5002 --#define HDMI_A_HDCPOBS1 0x5003 --#define HDMI_A_HDCPOBS2 0x5004 --#define HDMI_A_HDCPOBS3 0x5005 --#define HDMI_A_APIINTCLR 0x5006 --#define HDMI_A_APIINTSTAT 0x5007 --#define HDMI_A_APIINTMSK 0x5008 --#define HDMI_A_VIDPOLCFG 0x5009 --#define HDMI_A_OESSWCFG 0x500A --#define HDMI_A_TIMER1SETUP0 0x500B --#define HDMI_A_TIMER1SETUP1 0x500C --#define HDMI_A_TIMER2SETUP0 0x500D --#define HDMI_A_TIMER2SETUP1 0x500E --#define HDMI_A_100MSCFG 0x500F --#define HDMI_A_2SCFG0 0x5010 --#define HDMI_A_2SCFG1 0x5011 --#define HDMI_A_5SCFG0 0x5012 --#define HDMI_A_5SCFG1 0x5013 --#define HDMI_A_SRMVERLSB 0x5014 --#define HDMI_A_SRMVERMSB 0x5015 --#define HDMI_A_SRMCTRL 0x5016 --#define HDMI_A_SFRSETUP 0x5017 --#define HDMI_A_I2CHSETUP 0x5018 --#define HDMI_A_INTSETUP 0x5019 --#define HDMI_A_PRESETUP 0x501A --#define HDMI_A_SRM_BASE 0x5020 -- --/* CEC Engine Registers */ --#define HDMI_CEC_CTRL 0x7D00 --#define HDMI_CEC_STAT 0x7D01 --#define HDMI_CEC_MASK 0x7D02 --#define HDMI_CEC_POLARITY 0x7D03 --#define HDMI_CEC_INT 0x7D04 --#define HDMI_CEC_ADDR_L 0x7D05 --#define HDMI_CEC_ADDR_H 0x7D06 --#define HDMI_CEC_TX_CNT 0x7D07 --#define HDMI_CEC_RX_CNT 0x7D08 --#define HDMI_CEC_TX_DATA0 0x7D10 --#define HDMI_CEC_TX_DATA1 0x7D11 --#define HDMI_CEC_TX_DATA2 0x7D12 --#define HDMI_CEC_TX_DATA3 0x7D13 --#define HDMI_CEC_TX_DATA4 0x7D14 --#define HDMI_CEC_TX_DATA5 0x7D15 --#define HDMI_CEC_TX_DATA6 0x7D16 --#define HDMI_CEC_TX_DATA7 0x7D17 --#define HDMI_CEC_TX_DATA8 0x7D18 --#define HDMI_CEC_TX_DATA9 0x7D19 --#define HDMI_CEC_TX_DATA10 0x7D1a --#define HDMI_CEC_TX_DATA11 0x7D1b --#define HDMI_CEC_TX_DATA12 0x7D1c --#define HDMI_CEC_TX_DATA13 0x7D1d --#define HDMI_CEC_TX_DATA14 0x7D1e --#define HDMI_CEC_TX_DATA15 0x7D1f --#define HDMI_CEC_RX_DATA0 0x7D20 --#define HDMI_CEC_RX_DATA1 0x7D21 --#define HDMI_CEC_RX_DATA2 0x7D22 --#define HDMI_CEC_RX_DATA3 0x7D23 --#define HDMI_CEC_RX_DATA4 0x7D24 --#define HDMI_CEC_RX_DATA5 0x7D25 --#define HDMI_CEC_RX_DATA6 0x7D26 --#define HDMI_CEC_RX_DATA7 0x7D27 --#define HDMI_CEC_RX_DATA8 0x7D28 --#define HDMI_CEC_RX_DATA9 0x7D29 --#define HDMI_CEC_RX_DATA10 0x7D2a --#define HDMI_CEC_RX_DATA11 0x7D2b --#define HDMI_CEC_RX_DATA12 0x7D2c --#define HDMI_CEC_RX_DATA13 0x7D2d --#define HDMI_CEC_RX_DATA14 0x7D2e --#define HDMI_CEC_RX_DATA15 0x7D2f --#define HDMI_CEC_LOCK 0x7D30 --#define HDMI_CEC_WKUPCTRL 0x7D31 -- --/* I2C Master Registers (E-DDC) */ --#define HDMI_I2CM_SLAVE 0x7E00 --#define HDMI_I2CM_ADDRESS 0x7E01 --#define HDMI_I2CM_DATAO 0x7E02 --#define HDMI_I2CM_DATAI 0x7E03 --#define HDMI_I2CM_OPERATION 0x7E04 --#define HDMI_I2CM_INT 0x7E05 --#define HDMI_I2CM_CTLINT 0x7E06 --#define HDMI_I2CM_DIV 0x7E07 --#define HDMI_I2CM_SEGADDR 0x7E08 --#define HDMI_I2CM_SOFTRSTZ 0x7E09 --#define HDMI_I2CM_SEGPTR 0x7E0A --#define HDMI_I2CM_SS_SCL_HCNT_1_ADDR 0x7E0B --#define HDMI_I2CM_SS_SCL_HCNT_0_ADDR 0x7E0C --#define HDMI_I2CM_SS_SCL_LCNT_1_ADDR 0x7E0D --#define HDMI_I2CM_SS_SCL_LCNT_0_ADDR 0x7E0E --#define HDMI_I2CM_FS_SCL_HCNT_1_ADDR 0x7E0F --#define HDMI_I2CM_FS_SCL_HCNT_0_ADDR 0x7E10 --#define HDMI_I2CM_FS_SCL_LCNT_1_ADDR 0x7E11 --#define HDMI_I2CM_FS_SCL_LCNT_0_ADDR 0x7E12 -- --enum { --/* PRODUCT_ID0 field values */ -- HDMI_PRODUCT_ID0_HDMI_TX = 0xa0, -- --/* PRODUCT_ID1 field values */ -- HDMI_PRODUCT_ID1_HDCP = 0xc0, -- HDMI_PRODUCT_ID1_HDMI_RX = 0x02, -- HDMI_PRODUCT_ID1_HDMI_TX = 0x01, -- --/* CONFIG0_ID field values */ -- HDMI_CONFIG0_I2S = 0x10, -- --/* CONFIG1_ID field values */ -- HDMI_CONFIG1_AHB = 0x01, -- --/* CONFIG3_ID field values */ -- HDMI_CONFIG3_AHBAUDDMA = 0x02, -- HDMI_CONFIG3_GPAUD = 0x01, -- --/* IH_FC_INT2 field values */ -- HDMI_IH_FC_INT2_OVERFLOW_MASK = 0x03, -- HDMI_IH_FC_INT2_LOW_PRIORITY_OVERFLOW = 0x02, -- HDMI_IH_FC_INT2_HIGH_PRIORITY_OVERFLOW = 0x01, -- --/* IH_FC_STAT2 field values */ -- HDMI_IH_FC_STAT2_OVERFLOW_MASK = 0x03, -- HDMI_IH_FC_STAT2_LOW_PRIORITY_OVERFLOW = 0x02, -- HDMI_IH_FC_STAT2_HIGH_PRIORITY_OVERFLOW = 0x01, -- --/* IH_PHY_STAT0 field values */ -- HDMI_IH_PHY_STAT0_RX_SENSE3 = 0x20, -- HDMI_IH_PHY_STAT0_RX_SENSE2 = 0x10, -- HDMI_IH_PHY_STAT0_RX_SENSE1 = 0x8, -- HDMI_IH_PHY_STAT0_RX_SENSE0 = 0x4, -- HDMI_IH_PHY_STAT0_TX_PHY_LOCK = 0x2, -- HDMI_IH_PHY_STAT0_HPD = 0x1, -- --/* IH_I2CM_STAT0 and IH_MUTE_I2CM_STAT0 field values */ -- HDMI_IH_I2CM_STAT0_DONE = 0x2, -- HDMI_IH_I2CM_STAT0_ERROR = 0x1, -- --/* IH_MUTE_I2CMPHY_STAT0 field values */ -- HDMI_IH_MUTE_I2CMPHY_STAT0_I2CMPHYDONE = 0x2, -- HDMI_IH_MUTE_I2CMPHY_STAT0_I2CMPHYERROR = 0x1, -- --/* IH_AHBDMAAUD_STAT0 field values */ -- HDMI_IH_AHBDMAAUD_STAT0_ERROR = 0x20, -- HDMI_IH_AHBDMAAUD_STAT0_LOST = 0x10, -- HDMI_IH_AHBDMAAUD_STAT0_RETRY = 0x08, -- HDMI_IH_AHBDMAAUD_STAT0_DONE = 0x04, -- HDMI_IH_AHBDMAAUD_STAT0_BUFFFULL = 0x02, -- HDMI_IH_AHBDMAAUD_STAT0_BUFFEMPTY = 0x01, -- --/* IH_MUTE_FC_STAT2 field values */ -- HDMI_IH_MUTE_FC_STAT2_OVERFLOW_MASK = 0x03, -- HDMI_IH_MUTE_FC_STAT2_LOW_PRIORITY_OVERFLOW = 0x02, -- HDMI_IH_MUTE_FC_STAT2_HIGH_PRIORITY_OVERFLOW = 0x01, -- --/* IH_MUTE_AHBDMAAUD_STAT0 field values */ -- HDMI_IH_MUTE_AHBDMAAUD_STAT0_ERROR = 0x20, -- HDMI_IH_MUTE_AHBDMAAUD_STAT0_LOST = 0x10, -- HDMI_IH_MUTE_AHBDMAAUD_STAT0_RETRY = 0x08, -- HDMI_IH_MUTE_AHBDMAAUD_STAT0_DONE = 0x04, -- HDMI_IH_MUTE_AHBDMAAUD_STAT0_BUFFFULL = 0x02, -- HDMI_IH_MUTE_AHBDMAAUD_STAT0_BUFFEMPTY = 0x01, -- --/* IH_MUTE field values */ -- HDMI_IH_MUTE_MUTE_WAKEUP_INTERRUPT = 0x2, -- HDMI_IH_MUTE_MUTE_ALL_INTERRUPT = 0x1, -- --/* TX_INVID0 field values */ -- HDMI_TX_INVID0_INTERNAL_DE_GENERATOR_MASK = 0x80, -- HDMI_TX_INVID0_INTERNAL_DE_GENERATOR_ENABLE = 0x80, -- HDMI_TX_INVID0_INTERNAL_DE_GENERATOR_DISABLE = 0x00, -- HDMI_TX_INVID0_VIDEO_MAPPING_MASK = 0x1F, -- HDMI_TX_INVID0_VIDEO_MAPPING_OFFSET = 0, -- --/* TX_INSTUFFING field values */ -- HDMI_TX_INSTUFFING_BDBDATA_STUFFING_MASK = 0x4, -- HDMI_TX_INSTUFFING_BDBDATA_STUFFING_ENABLE = 0x4, -- HDMI_TX_INSTUFFING_BDBDATA_STUFFING_DISABLE = 0x0, -- HDMI_TX_INSTUFFING_RCRDATA_STUFFING_MASK = 0x2, -- HDMI_TX_INSTUFFING_RCRDATA_STUFFING_ENABLE = 0x2, -- HDMI_TX_INSTUFFING_RCRDATA_STUFFING_DISABLE = 0x0, -- HDMI_TX_INSTUFFING_GYDATA_STUFFING_MASK = 0x1, -- HDMI_TX_INSTUFFING_GYDATA_STUFFING_ENABLE = 0x1, -- HDMI_TX_INSTUFFING_GYDATA_STUFFING_DISABLE = 0x0, -- --/* VP_PR_CD field values */ -- HDMI_VP_PR_CD_COLOR_DEPTH_MASK = 0xF0, -- HDMI_VP_PR_CD_COLOR_DEPTH_OFFSET = 4, -- HDMI_VP_PR_CD_DESIRED_PR_FACTOR_MASK = 0x0F, -- HDMI_VP_PR_CD_DESIRED_PR_FACTOR_OFFSET = 0, -- --/* VP_STUFF field values */ -- HDMI_VP_STUFF_IDEFAULT_PHASE_MASK = 0x20, -- HDMI_VP_STUFF_IDEFAULT_PHASE_OFFSET = 5, -- HDMI_VP_STUFF_IFIX_PP_TO_LAST_MASK = 0x10, -- HDMI_VP_STUFF_IFIX_PP_TO_LAST_OFFSET = 4, -- HDMI_VP_STUFF_ICX_GOTO_P0_ST_MASK = 0x8, -- HDMI_VP_STUFF_ICX_GOTO_P0_ST_OFFSET = 3, -- HDMI_VP_STUFF_YCC422_STUFFING_MASK = 0x4, -- HDMI_VP_STUFF_YCC422_STUFFING_STUFFING_MODE = 0x4, -- HDMI_VP_STUFF_YCC422_STUFFING_DIRECT_MODE = 0x0, -- HDMI_VP_STUFF_PP_STUFFING_MASK = 0x2, -- HDMI_VP_STUFF_PP_STUFFING_STUFFING_MODE = 0x2, -- HDMI_VP_STUFF_PP_STUFFING_DIRECT_MODE = 0x0, -- HDMI_VP_STUFF_PR_STUFFING_MASK = 0x1, -- HDMI_VP_STUFF_PR_STUFFING_STUFFING_MODE = 0x1, -- HDMI_VP_STUFF_PR_STUFFING_DIRECT_MODE = 0x0, -- --/* VP_CONF field values */ -- HDMI_VP_CONF_BYPASS_EN_MASK = 0x40, -- HDMI_VP_CONF_BYPASS_EN_ENABLE = 0x40, -- HDMI_VP_CONF_BYPASS_EN_DISABLE = 0x00, -- HDMI_VP_CONF_PP_EN_ENMASK = 0x20, -- HDMI_VP_CONF_PP_EN_ENABLE = 0x20, -- HDMI_VP_CONF_PP_EN_DISABLE = 0x00, -- HDMI_VP_CONF_PR_EN_MASK = 0x10, -- HDMI_VP_CONF_PR_EN_ENABLE = 0x10, -- HDMI_VP_CONF_PR_EN_DISABLE = 0x00, -- HDMI_VP_CONF_YCC422_EN_MASK = 0x8, -- HDMI_VP_CONF_YCC422_EN_ENABLE = 0x8, -- HDMI_VP_CONF_YCC422_EN_DISABLE = 0x0, -- HDMI_VP_CONF_BYPASS_SELECT_MASK = 0x4, -- HDMI_VP_CONF_BYPASS_SELECT_VID_PACKETIZER = 0x4, -- HDMI_VP_CONF_BYPASS_SELECT_PIX_REPEATER = 0x0, -- HDMI_VP_CONF_OUTPUT_SELECTOR_MASK = 0x3, -- HDMI_VP_CONF_OUTPUT_SELECTOR_BYPASS = 0x3, -- HDMI_VP_CONF_OUTPUT_SELECTOR_YCC422 = 0x1, -- HDMI_VP_CONF_OUTPUT_SELECTOR_PP = 0x0, -- --/* VP_REMAP field values */ -- HDMI_VP_REMAP_MASK = 0x3, -- HDMI_VP_REMAP_YCC422_24bit = 0x2, -- HDMI_VP_REMAP_YCC422_20bit = 0x1, -- HDMI_VP_REMAP_YCC422_16bit = 0x0, -- --/* FC_INVIDCONF field values */ -- HDMI_FC_INVIDCONF_HDCP_KEEPOUT_MASK = 0x80, -- HDMI_FC_INVIDCONF_HDCP_KEEPOUT_ACTIVE = 0x80, -- HDMI_FC_INVIDCONF_HDCP_KEEPOUT_INACTIVE = 0x00, -- HDMI_FC_INVIDCONF_VSYNC_IN_POLARITY_MASK = 0x40, -- HDMI_FC_INVIDCONF_VSYNC_IN_POLARITY_ACTIVE_HIGH = 0x40, -- HDMI_FC_INVIDCONF_VSYNC_IN_POLARITY_ACTIVE_LOW = 0x00, -- HDMI_FC_INVIDCONF_HSYNC_IN_POLARITY_MASK = 0x20, -- HDMI_FC_INVIDCONF_HSYNC_IN_POLARITY_ACTIVE_HIGH = 0x20, -- HDMI_FC_INVIDCONF_HSYNC_IN_POLARITY_ACTIVE_LOW = 0x00, -- HDMI_FC_INVIDCONF_DE_IN_POLARITY_MASK = 0x10, -- HDMI_FC_INVIDCONF_DE_IN_POLARITY_ACTIVE_HIGH = 0x10, -- HDMI_FC_INVIDCONF_DE_IN_POLARITY_ACTIVE_LOW = 0x00, -- HDMI_FC_INVIDCONF_DVI_MODEZ_MASK = 0x8, -- HDMI_FC_INVIDCONF_DVI_MODEZ_HDMI_MODE = 0x8, -- HDMI_FC_INVIDCONF_DVI_MODEZ_DVI_MODE = 0x0, -- HDMI_FC_INVIDCONF_R_V_BLANK_IN_OSC_MASK = 0x2, -- HDMI_FC_INVIDCONF_R_V_BLANK_IN_OSC_ACTIVE_HIGH = 0x2, -- HDMI_FC_INVIDCONF_R_V_BLANK_IN_OSC_ACTIVE_LOW = 0x0, -- HDMI_FC_INVIDCONF_IN_I_P_MASK = 0x1, -- HDMI_FC_INVIDCONF_IN_I_P_INTERLACED = 0x1, -- HDMI_FC_INVIDCONF_IN_I_P_PROGRESSIVE = 0x0, -- --/* FC_AUDICONF0 field values */ -- HDMI_FC_AUDICONF0_CC_OFFSET = 4, -- HDMI_FC_AUDICONF0_CC_MASK = 0x70, -- HDMI_FC_AUDICONF0_CT_OFFSET = 0, -- HDMI_FC_AUDICONF0_CT_MASK = 0xF, -- --/* FC_AUDICONF1 field values */ -- HDMI_FC_AUDICONF1_SS_OFFSET = 3, -- HDMI_FC_AUDICONF1_SS_MASK = 0x18, -- HDMI_FC_AUDICONF1_SF_OFFSET = 0, -- HDMI_FC_AUDICONF1_SF_MASK = 0x7, -- --/* FC_AUDICONF3 field values */ -- HDMI_FC_AUDICONF3_LFEPBL_OFFSET = 5, -- HDMI_FC_AUDICONF3_LFEPBL_MASK = 0x60, -- HDMI_FC_AUDICONF3_DM_INH_OFFSET = 4, -- HDMI_FC_AUDICONF3_DM_INH_MASK = 0x10, -- HDMI_FC_AUDICONF3_LSV_OFFSET = 0, -- HDMI_FC_AUDICONF3_LSV_MASK = 0xF, -- --/* FC_AUDSCHNLS0 field values */ -- HDMI_FC_AUDSCHNLS0_CGMSA_OFFSET = 4, -- HDMI_FC_AUDSCHNLS0_CGMSA_MASK = 0x30, -- HDMI_FC_AUDSCHNLS0_COPYRIGHT_OFFSET = 0, -- HDMI_FC_AUDSCHNLS0_COPYRIGHT_MASK = 0x01, -- --/* FC_AUDSCHNLS3-6 field values */ -- HDMI_FC_AUDSCHNLS3_OIEC_CH0_OFFSET = 0, -- HDMI_FC_AUDSCHNLS3_OIEC_CH0_MASK = 0x0f, -- HDMI_FC_AUDSCHNLS3_OIEC_CH1_OFFSET = 4, -- HDMI_FC_AUDSCHNLS3_OIEC_CH1_MASK = 0xf0, -- HDMI_FC_AUDSCHNLS4_OIEC_CH2_OFFSET = 0, -- HDMI_FC_AUDSCHNLS4_OIEC_CH2_MASK = 0x0f, -- HDMI_FC_AUDSCHNLS4_OIEC_CH3_OFFSET = 4, -- HDMI_FC_AUDSCHNLS4_OIEC_CH3_MASK = 0xf0, -- -- HDMI_FC_AUDSCHNLS5_OIEC_CH0_OFFSET = 0, -- HDMI_FC_AUDSCHNLS5_OIEC_CH0_MASK = 0x0f, -- HDMI_FC_AUDSCHNLS5_OIEC_CH1_OFFSET = 4, -- HDMI_FC_AUDSCHNLS5_OIEC_CH1_MASK = 0xf0, -- HDMI_FC_AUDSCHNLS6_OIEC_CH2_OFFSET = 0, -- HDMI_FC_AUDSCHNLS6_OIEC_CH2_MASK = 0x0f, -- HDMI_FC_AUDSCHNLS6_OIEC_CH3_OFFSET = 4, -- HDMI_FC_AUDSCHNLS6_OIEC_CH3_MASK = 0xf0, -- --/* HDMI_FC_AUDSCHNLS7 field values */ -- HDMI_FC_AUDSCHNLS7_ACCURACY_OFFSET = 4, -- HDMI_FC_AUDSCHNLS7_ACCURACY_MASK = 0x30, -- --/* HDMI_FC_AUDSCHNLS8 field values */ -- HDMI_FC_AUDSCHNLS8_ORIGSAMPFREQ_MASK = 0xf0, -- HDMI_FC_AUDSCHNLS8_ORIGSAMPFREQ_OFFSET = 4, -- HDMI_FC_AUDSCHNLS8_WORDLEGNTH_MASK = 0x0f, -- HDMI_FC_AUDSCHNLS8_WORDLEGNTH_OFFSET = 0, -- --/* FC_AUDSCONF field values */ -- HDMI_FC_AUDSCONF_AUD_PACKET_SAMPFIT_MASK = 0xF0, -- HDMI_FC_AUDSCONF_AUD_PACKET_SAMPFIT_OFFSET = 4, -- HDMI_FC_AUDSCONF_AUD_PACKET_LAYOUT_MASK = 0x1, -- HDMI_FC_AUDSCONF_AUD_PACKET_LAYOUT_OFFSET = 0, -- HDMI_FC_AUDSCONF_AUD_PACKET_LAYOUT_LAYOUT1 = 0x1, -- HDMI_FC_AUDSCONF_AUD_PACKET_LAYOUT_LAYOUT0 = 0x0, -- --/* FC_STAT2 field values */ -- HDMI_FC_STAT2_OVERFLOW_MASK = 0x03, -- HDMI_FC_STAT2_LOW_PRIORITY_OVERFLOW = 0x02, -- HDMI_FC_STAT2_HIGH_PRIORITY_OVERFLOW = 0x01, -- --/* FC_INT2 field values */ -- HDMI_FC_INT2_OVERFLOW_MASK = 0x03, -- HDMI_FC_INT2_LOW_PRIORITY_OVERFLOW = 0x02, -- HDMI_FC_INT2_HIGH_PRIORITY_OVERFLOW = 0x01, -- --/* FC_MASK2 field values */ -- HDMI_FC_MASK2_OVERFLOW_MASK = 0x03, -- HDMI_FC_MASK2_LOW_PRIORITY_OVERFLOW = 0x02, -- HDMI_FC_MASK2_HIGH_PRIORITY_OVERFLOW = 0x01, -- --/* FC_PRCONF field values */ -- HDMI_FC_PRCONF_INCOMING_PR_FACTOR_MASK = 0xF0, -- HDMI_FC_PRCONF_INCOMING_PR_FACTOR_OFFSET = 4, -- HDMI_FC_PRCONF_OUTPUT_PR_FACTOR_MASK = 0x0F, -- HDMI_FC_PRCONF_OUTPUT_PR_FACTOR_OFFSET = 0, -- --/* FC_AVICONF0-FC_AVICONF3 field values */ -- HDMI_FC_AVICONF0_PIX_FMT_MASK = 0x03, -- HDMI_FC_AVICONF0_PIX_FMT_RGB = 0x00, -- HDMI_FC_AVICONF0_PIX_FMT_YCBCR422 = 0x01, -- HDMI_FC_AVICONF0_PIX_FMT_YCBCR444 = 0x02, -- HDMI_FC_AVICONF0_ACTIVE_FMT_MASK = 0x40, -- HDMI_FC_AVICONF0_ACTIVE_FMT_INFO_PRESENT = 0x40, -- HDMI_FC_AVICONF0_ACTIVE_FMT_NO_INFO = 0x00, -- HDMI_FC_AVICONF0_BAR_DATA_MASK = 0x0C, -- HDMI_FC_AVICONF0_BAR_DATA_NO_DATA = 0x00, -- HDMI_FC_AVICONF0_BAR_DATA_VERT_BAR = 0x04, -- HDMI_FC_AVICONF0_BAR_DATA_HORIZ_BAR = 0x08, -- HDMI_FC_AVICONF0_BAR_DATA_VERT_HORIZ_BAR = 0x0C, -- HDMI_FC_AVICONF0_SCAN_INFO_MASK = 0x30, -- HDMI_FC_AVICONF0_SCAN_INFO_OVERSCAN = 0x10, -- HDMI_FC_AVICONF0_SCAN_INFO_UNDERSCAN = 0x20, -- HDMI_FC_AVICONF0_SCAN_INFO_NODATA = 0x00, -- -- HDMI_FC_AVICONF1_ACTIVE_ASPECT_RATIO_MASK = 0x0F, -- HDMI_FC_AVICONF1_ACTIVE_ASPECT_RATIO_USE_CODED = 0x08, -- HDMI_FC_AVICONF1_ACTIVE_ASPECT_RATIO_4_3 = 0x09, -- HDMI_FC_AVICONF1_ACTIVE_ASPECT_RATIO_16_9 = 0x0A, -- HDMI_FC_AVICONF1_ACTIVE_ASPECT_RATIO_14_9 = 0x0B, -- HDMI_FC_AVICONF1_CODED_ASPECT_RATIO_MASK = 0x30, -- HDMI_FC_AVICONF1_CODED_ASPECT_RATIO_NO_DATA = 0x00, -- HDMI_FC_AVICONF1_CODED_ASPECT_RATIO_4_3 = 0x10, -- HDMI_FC_AVICONF1_CODED_ASPECT_RATIO_16_9 = 0x20, -- HDMI_FC_AVICONF1_COLORIMETRY_MASK = 0xC0, -- HDMI_FC_AVICONF1_COLORIMETRY_NO_DATA = 0x00, -- HDMI_FC_AVICONF1_COLORIMETRY_SMPTE = 0x40, -- HDMI_FC_AVICONF1_COLORIMETRY_ITUR = 0x80, -- HDMI_FC_AVICONF1_COLORIMETRY_EXTENDED_INFO = 0xC0, -- -- HDMI_FC_AVICONF2_SCALING_MASK = 0x03, -- HDMI_FC_AVICONF2_SCALING_NONE = 0x00, -- HDMI_FC_AVICONF2_SCALING_HORIZ = 0x01, -- HDMI_FC_AVICONF2_SCALING_VERT = 0x02, -- HDMI_FC_AVICONF2_SCALING_HORIZ_VERT = 0x03, -- HDMI_FC_AVICONF2_RGB_QUANT_MASK = 0x0C, -- HDMI_FC_AVICONF2_RGB_QUANT_DEFAULT = 0x00, -- HDMI_FC_AVICONF2_RGB_QUANT_LIMITED_RANGE = 0x04, -- HDMI_FC_AVICONF2_RGB_QUANT_FULL_RANGE = 0x08, -- HDMI_FC_AVICONF2_EXT_COLORIMETRY_MASK = 0x70, -- HDMI_FC_AVICONF2_EXT_COLORIMETRY_XVYCC601 = 0x00, -- HDMI_FC_AVICONF2_EXT_COLORIMETRY_XVYCC709 = 0x10, -- HDMI_FC_AVICONF2_EXT_COLORIMETRY_SYCC601 = 0x20, -- HDMI_FC_AVICONF2_EXT_COLORIMETRY_ADOBE_YCC601 = 0x30, -- HDMI_FC_AVICONF2_EXT_COLORIMETRY_ADOBE_RGB = 0x40, -- HDMI_FC_AVICONF2_IT_CONTENT_MASK = 0x80, -- HDMI_FC_AVICONF2_IT_CONTENT_NO_DATA = 0x00, -- HDMI_FC_AVICONF2_IT_CONTENT_VALID = 0x80, -- -- HDMI_FC_AVICONF3_IT_CONTENT_TYPE_MASK = 0x03, -- HDMI_FC_AVICONF3_IT_CONTENT_TYPE_GRAPHICS = 0x00, -- HDMI_FC_AVICONF3_IT_CONTENT_TYPE_PHOTO = 0x01, -- HDMI_FC_AVICONF3_IT_CONTENT_TYPE_CINEMA = 0x02, -- HDMI_FC_AVICONF3_IT_CONTENT_TYPE_GAME = 0x03, -- HDMI_FC_AVICONF3_QUANT_RANGE_MASK = 0x0C, -- HDMI_FC_AVICONF3_QUANT_RANGE_LIMITED = 0x00, -- HDMI_FC_AVICONF3_QUANT_RANGE_FULL = 0x04, -- --/* FC_DBGFORCE field values */ -- HDMI_FC_DBGFORCE_FORCEAUDIO = 0x10, -- HDMI_FC_DBGFORCE_FORCEVIDEO = 0x1, -- --/* PHY_CONF0 field values */ -- HDMI_PHY_CONF0_PDZ_MASK = 0x80, -- HDMI_PHY_CONF0_PDZ_OFFSET = 7, -- HDMI_PHY_CONF0_ENTMDS_MASK = 0x40, -- HDMI_PHY_CONF0_ENTMDS_OFFSET = 6, -- HDMI_PHY_CONF0_SVSRET_MASK = 0x20, -- HDMI_PHY_CONF0_SVSRET_OFFSET = 5, -- HDMI_PHY_CONF0_GEN2_PDDQ_MASK = 0x10, -- HDMI_PHY_CONF0_GEN2_PDDQ_OFFSET = 4, -- HDMI_PHY_CONF0_GEN2_TXPWRON_MASK = 0x8, -- HDMI_PHY_CONF0_GEN2_TXPWRON_OFFSET = 3, -- HDMI_PHY_CONF0_GEN2_ENHPDRXSENSE_MASK = 0x4, -- HDMI_PHY_CONF0_GEN2_ENHPDRXSENSE_OFFSET = 2, -- HDMI_PHY_CONF0_SELDATAENPOL_MASK = 0x2, -- HDMI_PHY_CONF0_SELDATAENPOL_OFFSET = 1, -- HDMI_PHY_CONF0_SELDIPIF_MASK = 0x1, -- HDMI_PHY_CONF0_SELDIPIF_OFFSET = 0, -- --/* PHY_TST0 field values */ -- HDMI_PHY_TST0_TSTCLR_MASK = 0x20, -- HDMI_PHY_TST0_TSTCLR_OFFSET = 5, -- HDMI_PHY_TST0_TSTEN_MASK = 0x10, -- HDMI_PHY_TST0_TSTEN_OFFSET = 4, -- HDMI_PHY_TST0_TSTCLK_MASK = 0x1, -- HDMI_PHY_TST0_TSTCLK_OFFSET = 0, -- --/* PHY_STAT0 field values */ -- HDMI_PHY_RX_SENSE3 = 0x80, -- HDMI_PHY_RX_SENSE2 = 0x40, -- HDMI_PHY_RX_SENSE1 = 0x20, -- HDMI_PHY_RX_SENSE0 = 0x10, -- HDMI_PHY_HPD = 0x02, -- HDMI_PHY_TX_PHY_LOCK = 0x01, -- --/* PHY_I2CM_SLAVE_ADDR field values */ -- HDMI_PHY_I2CM_SLAVE_ADDR_PHY_GEN2 = 0x69, -- HDMI_PHY_I2CM_SLAVE_ADDR_HEAC_PHY = 0x49, -- --/* PHY_I2CM_OPERATION_ADDR field values */ -- HDMI_PHY_I2CM_OPERATION_ADDR_WRITE = 0x10, -- HDMI_PHY_I2CM_OPERATION_ADDR_READ = 0x1, -- --/* HDMI_PHY_I2CM_INT_ADDR */ -- HDMI_PHY_I2CM_INT_ADDR_DONE_POL = 0x08, -- HDMI_PHY_I2CM_INT_ADDR_DONE_MASK = 0x04, -- --/* HDMI_PHY_I2CM_CTLINT_ADDR */ -- HDMI_PHY_I2CM_CTLINT_ADDR_NAC_POL = 0x80, -- HDMI_PHY_I2CM_CTLINT_ADDR_NAC_MASK = 0x40, -- HDMI_PHY_I2CM_CTLINT_ADDR_ARBITRATION_POL = 0x08, -- HDMI_PHY_I2CM_CTLINT_ADDR_ARBITRATION_MASK = 0x04, -- --/* AUD_CONF0 field values */ -- HDMI_AUD_CONF0_SW_RESET = 0x80, -- HDMI_AUD_CONF0_I2S_ALL_ENABLE = 0x2F, -- --/* AUD_CONF1 field values */ -- HDMI_AUD_CONF1_MODE_I2S = 0x00, -- HDMI_AUD_CONF1_MODE_RIGHT_J = 0x02, -- HDMI_AUD_CONF1_MODE_LEFT_J = 0x04, -- HDMI_AUD_CONF1_WIDTH_16 = 0x10, -- HDMI_AUD_CONF1_WIDTH_24 = 0x18, -- --/* AUD_CTS3 field values */ -- HDMI_AUD_CTS3_N_SHIFT_OFFSET = 5, -- HDMI_AUD_CTS3_N_SHIFT_MASK = 0xe0, -- HDMI_AUD_CTS3_N_SHIFT_1 = 0, -- HDMI_AUD_CTS3_N_SHIFT_16 = 0x20, -- HDMI_AUD_CTS3_N_SHIFT_32 = 0x40, -- HDMI_AUD_CTS3_N_SHIFT_64 = 0x60, -- HDMI_AUD_CTS3_N_SHIFT_128 = 0x80, -- HDMI_AUD_CTS3_N_SHIFT_256 = 0xa0, -- /* note that the CTS3 MANUAL bit has been removed -- from our part. Can't set it, will read as 0. */ -- HDMI_AUD_CTS3_CTS_MANUAL = 0x10, -- HDMI_AUD_CTS3_AUDCTS19_16_MASK = 0x0f, -- --/* HDMI_AUD_INPUTCLKFS field values */ -- HDMI_AUD_INPUTCLKFS_128FS = 0, -- HDMI_AUD_INPUTCLKFS_256FS = 1, -- HDMI_AUD_INPUTCLKFS_512FS = 2, -- HDMI_AUD_INPUTCLKFS_64FS = 4, -- --/* AHB_DMA_CONF0 field values */ -- HDMI_AHB_DMA_CONF0_SW_FIFO_RST_OFFSET = 7, -- HDMI_AHB_DMA_CONF0_SW_FIFO_RST_MASK = 0x80, -- HDMI_AHB_DMA_CONF0_HBR = 0x10, -- HDMI_AHB_DMA_CONF0_EN_HLOCK_OFFSET = 3, -- HDMI_AHB_DMA_CONF0_EN_HLOCK_MASK = 0x08, -- HDMI_AHB_DMA_CONF0_INCR_TYPE_OFFSET = 1, -- HDMI_AHB_DMA_CONF0_INCR_TYPE_MASK = 0x06, -- HDMI_AHB_DMA_CONF0_INCR4 = 0x0, -- HDMI_AHB_DMA_CONF0_INCR8 = 0x2, -- HDMI_AHB_DMA_CONF0_INCR16 = 0x4, -- HDMI_AHB_DMA_CONF0_BURST_MODE = 0x1, -- --/* HDMI_AHB_DMA_START field values */ -- HDMI_AHB_DMA_START_START_OFFSET = 0, -- HDMI_AHB_DMA_START_START_MASK = 0x01, -- --/* HDMI_AHB_DMA_STOP field values */ -- HDMI_AHB_DMA_STOP_STOP_OFFSET = 0, -- HDMI_AHB_DMA_STOP_STOP_MASK = 0x01, -- --/* AHB_DMA_STAT, AHB_DMA_INT, AHB_DMA_MASK, AHB_DMA_POL field values */ -- HDMI_AHB_DMA_DONE = 0x80, -- HDMI_AHB_DMA_RETRY_SPLIT = 0x40, -- HDMI_AHB_DMA_LOSTOWNERSHIP = 0x20, -- HDMI_AHB_DMA_ERROR = 0x10, -- HDMI_AHB_DMA_FIFO_THREMPTY = 0x04, -- HDMI_AHB_DMA_FIFO_FULL = 0x02, -- HDMI_AHB_DMA_FIFO_EMPTY = 0x01, -- --/* AHB_DMA_BUFFSTAT, AHB_DMA_BUFFINT,AHB_DMA_BUFFMASK,AHB_DMA_BUFFPOL values */ -- HDMI_AHB_DMA_BUFFSTAT_FULL = 0x02, -- HDMI_AHB_DMA_BUFFSTAT_EMPTY = 0x01, -- --/* MC_CLKDIS field values */ -- HDMI_MC_CLKDIS_HDCPCLK_DISABLE = 0x40, -- HDMI_MC_CLKDIS_CECCLK_DISABLE = 0x20, -- HDMI_MC_CLKDIS_CSCCLK_DISABLE = 0x10, -- HDMI_MC_CLKDIS_AUDCLK_DISABLE = 0x8, -- HDMI_MC_CLKDIS_PREPCLK_DISABLE = 0x4, -- HDMI_MC_CLKDIS_TMDSCLK_DISABLE = 0x2, -- HDMI_MC_CLKDIS_PIXELCLK_DISABLE = 0x1, -- --/* MC_SWRSTZ field values */ -- HDMI_MC_SWRSTZ_TMDSSWRST_REQ = 0x02, -- --/* MC_FLOWCTRL field values */ -- HDMI_MC_FLOWCTRL_FEED_THROUGH_OFF_MASK = 0x1, -- HDMI_MC_FLOWCTRL_FEED_THROUGH_OFF_CSC_IN_PATH = 0x1, -- HDMI_MC_FLOWCTRL_FEED_THROUGH_OFF_CSC_BYPASS = 0x0, -- --/* MC_PHYRSTZ field values */ -- HDMI_MC_PHYRSTZ_PHYRSTZ = 0x01, -- --/* MC_HEACPHY_RST field values */ -- HDMI_MC_HEACPHY_RST_ASSERT = 0x1, -- HDMI_MC_HEACPHY_RST_DEASSERT = 0x0, -- --/* CSC_CFG field values */ -- HDMI_CSC_CFG_INTMODE_MASK = 0x30, -- HDMI_CSC_CFG_INTMODE_OFFSET = 4, -- HDMI_CSC_CFG_INTMODE_DISABLE = 0x00, -- HDMI_CSC_CFG_INTMODE_CHROMA_INT_FORMULA1 = 0x10, -- HDMI_CSC_CFG_INTMODE_CHROMA_INT_FORMULA2 = 0x20, -- HDMI_CSC_CFG_DECMODE_MASK = 0x3, -- HDMI_CSC_CFG_DECMODE_OFFSET = 0, -- HDMI_CSC_CFG_DECMODE_DISABLE = 0x0, -- HDMI_CSC_CFG_DECMODE_CHROMA_INT_FORMULA1 = 0x1, -- HDMI_CSC_CFG_DECMODE_CHROMA_INT_FORMULA2 = 0x2, -- HDMI_CSC_CFG_DECMODE_CHROMA_INT_FORMULA3 = 0x3, -- --/* CSC_SCALE field values */ -- HDMI_CSC_SCALE_CSC_COLORDE_PTH_MASK = 0xF0, -- HDMI_CSC_SCALE_CSC_COLORDE_PTH_24BPP = 0x00, -- HDMI_CSC_SCALE_CSC_COLORDE_PTH_30BPP = 0x50, -- HDMI_CSC_SCALE_CSC_COLORDE_PTH_36BPP = 0x60, -- HDMI_CSC_SCALE_CSC_COLORDE_PTH_48BPP = 0x70, -- HDMI_CSC_SCALE_CSCSCALE_MASK = 0x03, -- --/* A_HDCPCFG0 field values */ -- HDMI_A_HDCPCFG0_ELVENA_MASK = 0x80, -- HDMI_A_HDCPCFG0_ELVENA_ENABLE = 0x80, -- HDMI_A_HDCPCFG0_ELVENA_DISABLE = 0x00, -- HDMI_A_HDCPCFG0_I2CFASTMODE_MASK = 0x40, -- HDMI_A_HDCPCFG0_I2CFASTMODE_ENABLE = 0x40, -- HDMI_A_HDCPCFG0_I2CFASTMODE_DISABLE = 0x00, -- HDMI_A_HDCPCFG0_BYPENCRYPTION_MASK = 0x20, -- HDMI_A_HDCPCFG0_BYPENCRYPTION_ENABLE = 0x20, -- HDMI_A_HDCPCFG0_BYPENCRYPTION_DISABLE = 0x00, -- HDMI_A_HDCPCFG0_SYNCRICHECK_MASK = 0x10, -- HDMI_A_HDCPCFG0_SYNCRICHECK_ENABLE = 0x10, -- HDMI_A_HDCPCFG0_SYNCRICHECK_DISABLE = 0x00, -- HDMI_A_HDCPCFG0_AVMUTE_MASK = 0x8, -- HDMI_A_HDCPCFG0_AVMUTE_ENABLE = 0x8, -- HDMI_A_HDCPCFG0_AVMUTE_DISABLE = 0x0, -- HDMI_A_HDCPCFG0_RXDETECT_MASK = 0x4, -- HDMI_A_HDCPCFG0_RXDETECT_ENABLE = 0x4, -- HDMI_A_HDCPCFG0_RXDETECT_DISABLE = 0x0, -- HDMI_A_HDCPCFG0_EN11FEATURE_MASK = 0x2, -- HDMI_A_HDCPCFG0_EN11FEATURE_ENABLE = 0x2, -- HDMI_A_HDCPCFG0_EN11FEATURE_DISABLE = 0x0, -- HDMI_A_HDCPCFG0_HDMIDVI_MASK = 0x1, -- HDMI_A_HDCPCFG0_HDMIDVI_HDMI = 0x1, -- HDMI_A_HDCPCFG0_HDMIDVI_DVI = 0x0, -- --/* A_HDCPCFG1 field values */ -- HDMI_A_HDCPCFG1_DISSHA1CHECK_MASK = 0x8, -- HDMI_A_HDCPCFG1_DISSHA1CHECK_DISABLE = 0x8, -- HDMI_A_HDCPCFG1_DISSHA1CHECK_ENABLE = 0x0, -- HDMI_A_HDCPCFG1_PH2UPSHFTENC_MASK = 0x4, -- HDMI_A_HDCPCFG1_PH2UPSHFTENC_ENABLE = 0x4, -- HDMI_A_HDCPCFG1_PH2UPSHFTENC_DISABLE = 0x0, -- HDMI_A_HDCPCFG1_ENCRYPTIONDISABLE_MASK = 0x2, -- HDMI_A_HDCPCFG1_ENCRYPTIONDISABLE_DISABLE = 0x2, -- HDMI_A_HDCPCFG1_ENCRYPTIONDISABLE_ENABLE = 0x0, -- HDMI_A_HDCPCFG1_SWRESET_MASK = 0x1, -- HDMI_A_HDCPCFG1_SWRESET_ASSERT = 0x0, -- --/* A_VIDPOLCFG field values */ -- HDMI_A_VIDPOLCFG_UNENCRYPTCONF_MASK = 0x60, -- HDMI_A_VIDPOLCFG_UNENCRYPTCONF_OFFSET = 5, -- HDMI_A_VIDPOLCFG_DATAENPOL_MASK = 0x10, -- HDMI_A_VIDPOLCFG_DATAENPOL_ACTIVE_HIGH = 0x10, -- HDMI_A_VIDPOLCFG_DATAENPOL_ACTIVE_LOW = 0x0, -- HDMI_A_VIDPOLCFG_VSYNCPOL_MASK = 0x8, -- HDMI_A_VIDPOLCFG_VSYNCPOL_ACTIVE_HIGH = 0x8, -- HDMI_A_VIDPOLCFG_VSYNCPOL_ACTIVE_LOW = 0x0, -- HDMI_A_VIDPOLCFG_HSYNCPOL_MASK = 0x2, -- HDMI_A_VIDPOLCFG_HSYNCPOL_ACTIVE_HIGH = 0x2, -- HDMI_A_VIDPOLCFG_HSYNCPOL_ACTIVE_LOW = 0x0, -- --/* I2CM_OPERATION field values */ -- HDMI_I2CM_OPERATION_WRITE = 0x10, -- HDMI_I2CM_OPERATION_READ_EXT = 0x2, -- HDMI_I2CM_OPERATION_READ = 0x1, -- --/* I2CM_INT field values */ -- HDMI_I2CM_INT_DONE_POL = 0x8, -- HDMI_I2CM_INT_DONE_MASK = 0x4, -- --/* I2CM_CTLINT field values */ -- HDMI_I2CM_CTLINT_NAC_POL = 0x80, -- HDMI_I2CM_CTLINT_NAC_MASK = 0x40, -- HDMI_I2CM_CTLINT_ARB_POL = 0x8, -- HDMI_I2CM_CTLINT_ARB_MASK = 0x4, --}; -- --/* -- * HDMI 3D TX PHY registers -- */ --#define HDMI_3D_TX_PHY_PWRCTRL 0x00 --#define HDMI_3D_TX_PHY_SERDIVCTRL 0x01 --#define HDMI_3D_TX_PHY_SERCKCTRL 0x02 --#define HDMI_3D_TX_PHY_SERCKKILLCTRL 0x03 --#define HDMI_3D_TX_PHY_TXRESCTRL 0x04 --#define HDMI_3D_TX_PHY_CKCALCTRL 0x05 --#define HDMI_3D_TX_PHY_CPCE_CTRL 0x06 --#define HDMI_3D_TX_PHY_TXCLKMEASCTRL 0x07 --#define HDMI_3D_TX_PHY_TXMEASCTRL 0x08 --#define HDMI_3D_TX_PHY_CKSYMTXCTRL 0x09 --#define HDMI_3D_TX_PHY_CMPSEQCTRL 0x0a --#define HDMI_3D_TX_PHY_CMPPWRCTRL 0x0b --#define HDMI_3D_TX_PHY_CMPMODECTRL 0x0c --#define HDMI_3D_TX_PHY_MEASCTRL 0x0d --#define HDMI_3D_TX_PHY_VLEVCTRL 0x0e --#define HDMI_3D_TX_PHY_D2ACTRL 0x0f --#define HDMI_3D_TX_PHY_CURRCTRL 0x10 --#define HDMI_3D_TX_PHY_DRVANACTRL 0x11 --#define HDMI_3D_TX_PHY_PLLMEASCTRL 0x12 --#define HDMI_3D_TX_PHY_PLLPHBYCTRL 0x13 --#define HDMI_3D_TX_PHY_GRP_CTRL 0x14 --#define HDMI_3D_TX_PHY_GMPCTRL 0x15 --#define HDMI_3D_TX_PHY_MPLLMEASCTRL 0x16 --#define HDMI_3D_TX_PHY_MSM_CTRL 0x17 --#define HDMI_3D_TX_PHY_SCRPB_STATUS 0x18 --#define HDMI_3D_TX_PHY_TXTERM 0x19 --#define HDMI_3D_TX_PHY_PTRPT_ENBL 0x1a --#define HDMI_3D_TX_PHY_PATTERNGEN 0x1b --#define HDMI_3D_TX_PHY_SDCAP_MODE 0x1c --#define HDMI_3D_TX_PHY_SCOPEMODE 0x1d --#define HDMI_3D_TX_PHY_DIGTXMODE 0x1e --#define HDMI_3D_TX_PHY_STR_STATUS 0x1f --#define HDMI_3D_TX_PHY_SCOPECNT0 0x20 --#define HDMI_3D_TX_PHY_SCOPECNT1 0x21 --#define HDMI_3D_TX_PHY_SCOPECNT2 0x22 --#define HDMI_3D_TX_PHY_SCOPECNTCLK 0x23 --#define HDMI_3D_TX_PHY_SCOPESAMPLE 0x24 --#define HDMI_3D_TX_PHY_SCOPECNTMSB01 0x25 --#define HDMI_3D_TX_PHY_SCOPECNTMSB2CK 0x26 -- --/* HDMI_3D_TX_PHY_CKCALCTRL values */ --#define HDMI_3D_TX_PHY_CKCALCTRL_OVERRIDE BIT(15) -- --/* HDMI_3D_TX_PHY_MSM_CTRL values */ --#define HDMI_3D_TX_PHY_MSM_CTRL_MPLL_PH_SEL_CK BIT(13) --#define HDMI_3D_TX_PHY_MSM_CTRL_CKO_SEL_CLK_REF_MPLL (0 << 1) --#define HDMI_3D_TX_PHY_MSM_CTRL_CKO_SEL_OFF (1 << 1) --#define HDMI_3D_TX_PHY_MSM_CTRL_CKO_SEL_PCLK (2 << 1) --#define HDMI_3D_TX_PHY_MSM_CTRL_CKO_SEL_FB_CLK (3 << 1) --#define HDMI_3D_TX_PHY_MSM_CTRL_SCOPE_CK_SEL BIT(0) -- --/* HDMI_3D_TX_PHY_PTRPT_ENBL values */ --#define HDMI_3D_TX_PHY_PTRPT_ENBL_OVERRIDE BIT(15) --#define HDMI_3D_TX_PHY_PTRPT_ENBL_PG_SKIP_BIT2 BIT(8) --#define HDMI_3D_TX_PHY_PTRPT_ENBL_PG_SKIP_BIT1 BIT(7) --#define HDMI_3D_TX_PHY_PTRPT_ENBL_PG_SKIP_BIT0 BIT(6) --#define HDMI_3D_TX_PHY_PTRPT_ENBL_CK_REF_ENB BIT(5) --#define HDMI_3D_TX_PHY_PTRPT_ENBL_RCAL_ENB BIT(4) --#define HDMI_3D_TX_PHY_PTRPT_ENBL_TX_CLK_ALIGN_ENB BIT(3) --#define HDMI_3D_TX_PHY_PTRPT_ENBL_TX_READY BIT(2) --#define HDMI_3D_TX_PHY_PTRPT_ENBL_CKO_WORD_ENB BIT(1) --#define HDMI_3D_TX_PHY_PTRPT_ENBL_REFCLK_ENB BIT(0) -- --#endif /* __DW_HDMI_H__ */ -diff --git a/drivers/gpu/drm/bridge/synopsys/Kconfig b/drivers/gpu/drm/bridge/synopsys/Kconfig -new file mode 100644 -index 0000000..40d2827 ---- /dev/null -+++ b/drivers/gpu/drm/bridge/synopsys/Kconfig -@@ -0,0 +1,23 @@ -+config DRM_DW_HDMI -+ tristate -+ select DRM_KMS_HELPER -+ -+config DRM_DW_HDMI_AHB_AUDIO -+ tristate "Synopsys Designware AHB Audio interface" -+ depends on DRM_DW_HDMI && SND -+ select SND_PCM -+ select SND_PCM_ELD -+ select SND_PCM_IEC958 -+ help -+ Support the AHB Audio interface which is part of the Synopsys -+ Designware HDMI block. This is used in conjunction with -+ the i.MX6 HDMI driver. -+ -+config DRM_DW_HDMI_I2S_AUDIO -+ tristate "Synopsys Designware I2S Audio interface" -+ depends on SND_SOC -+ depends on DRM_DW_HDMI -+ select SND_SOC_HDMI_CODEC -+ help -+ Support the I2S Audio interface which is part of the Synopsys -+ Designware HDMI block. -diff --git a/drivers/gpu/drm/bridge/synopsys/Makefile b/drivers/gpu/drm/bridge/synopsys/Makefile -new file mode 100644 -index 0000000..17aa7a6 ---- /dev/null -+++ b/drivers/gpu/drm/bridge/synopsys/Makefile -@@ -0,0 +1,5 @@ -+#ccflags-y := -Iinclude/drm -+ -+obj-$(CONFIG_DRM_DW_HDMI) += dw-hdmi.o -+obj-$(CONFIG_DRM_DW_HDMI_AHB_AUDIO) += dw-hdmi-ahb-audio.o -+obj-$(CONFIG_DRM_DW_HDMI_I2S_AUDIO) += dw-hdmi-i2s-audio.o -diff --git a/drivers/gpu/drm/bridge/synopsys/dw-hdmi-ahb-audio.c b/drivers/gpu/drm/bridge/synopsys/dw-hdmi-ahb-audio.c -new file mode 100644 -index 0000000..8f2d137 ---- /dev/null -+++ b/drivers/gpu/drm/bridge/synopsys/dw-hdmi-ahb-audio.c -@@ -0,0 +1,652 @@ -+/* -+ * DesignWare HDMI audio driver -+ * -+ * This program is free software; you can redistribute it and/or modify -+ * it under the terms of the GNU General Public License version 2 as -+ * published by the Free Software Foundation. -+ * -+ * Written and tested against the Designware HDMI Tx found in iMX6. -+ */ -+#include -+#include -+#include -+#include -+#include -+#include -+ -+#include -+#include -+#include -+#include -+#include -+#include -+ -+#include "dw-hdmi-audio.h" -+ -+#define DRIVER_NAME "dw-hdmi-ahb-audio" -+ -+/* Provide some bits rather than bit offsets */ -+enum { -+ HDMI_AHB_DMA_CONF0_SW_FIFO_RST = BIT(7), -+ HDMI_AHB_DMA_CONF0_EN_HLOCK = BIT(3), -+ HDMI_AHB_DMA_START_START = BIT(0), -+ HDMI_AHB_DMA_STOP_STOP = BIT(0), -+ HDMI_IH_MUTE_AHBDMAAUD_STAT0_ERROR = BIT(5), -+ HDMI_IH_MUTE_AHBDMAAUD_STAT0_LOST = BIT(4), -+ HDMI_IH_MUTE_AHBDMAAUD_STAT0_RETRY = BIT(3), -+ HDMI_IH_MUTE_AHBDMAAUD_STAT0_DONE = BIT(2), -+ HDMI_IH_MUTE_AHBDMAAUD_STAT0_BUFFFULL = BIT(1), -+ HDMI_IH_MUTE_AHBDMAAUD_STAT0_BUFFEMPTY = BIT(0), -+ HDMI_IH_MUTE_AHBDMAAUD_STAT0_ALL = -+ HDMI_IH_MUTE_AHBDMAAUD_STAT0_ERROR | -+ HDMI_IH_MUTE_AHBDMAAUD_STAT0_LOST | -+ HDMI_IH_MUTE_AHBDMAAUD_STAT0_RETRY | -+ HDMI_IH_MUTE_AHBDMAAUD_STAT0_DONE | -+ HDMI_IH_MUTE_AHBDMAAUD_STAT0_BUFFFULL | -+ HDMI_IH_MUTE_AHBDMAAUD_STAT0_BUFFEMPTY, -+ HDMI_IH_AHBDMAAUD_STAT0_ERROR = BIT(5), -+ HDMI_IH_AHBDMAAUD_STAT0_LOST = BIT(4), -+ HDMI_IH_AHBDMAAUD_STAT0_RETRY = BIT(3), -+ HDMI_IH_AHBDMAAUD_STAT0_DONE = BIT(2), -+ HDMI_IH_AHBDMAAUD_STAT0_BUFFFULL = BIT(1), -+ HDMI_IH_AHBDMAAUD_STAT0_BUFFEMPTY = BIT(0), -+ HDMI_IH_AHBDMAAUD_STAT0_ALL = -+ HDMI_IH_AHBDMAAUD_STAT0_ERROR | -+ HDMI_IH_AHBDMAAUD_STAT0_LOST | -+ HDMI_IH_AHBDMAAUD_STAT0_RETRY | -+ HDMI_IH_AHBDMAAUD_STAT0_DONE | -+ HDMI_IH_AHBDMAAUD_STAT0_BUFFFULL | -+ HDMI_IH_AHBDMAAUD_STAT0_BUFFEMPTY, -+ HDMI_AHB_DMA_CONF0_INCR16 = 2 << 1, -+ HDMI_AHB_DMA_CONF0_INCR8 = 1 << 1, -+ HDMI_AHB_DMA_CONF0_INCR4 = 0, -+ HDMI_AHB_DMA_CONF0_BURST_MODE = BIT(0), -+ HDMI_AHB_DMA_MASK_DONE = BIT(7), -+ -+ HDMI_REVISION_ID = 0x0001, -+ HDMI_IH_AHBDMAAUD_STAT0 = 0x0109, -+ HDMI_IH_MUTE_AHBDMAAUD_STAT0 = 0x0189, -+ HDMI_FC_AUDICONF2 = 0x1027, -+ HDMI_FC_AUDSCONF = 0x1063, -+ HDMI_FC_AUDSCONF_LAYOUT1 = 1 << 0, -+ HDMI_FC_AUDSCONF_LAYOUT0 = 0 << 0, -+ HDMI_AHB_DMA_CONF0 = 0x3600, -+ HDMI_AHB_DMA_START = 0x3601, -+ HDMI_AHB_DMA_STOP = 0x3602, -+ HDMI_AHB_DMA_THRSLD = 0x3603, -+ HDMI_AHB_DMA_STRADDR0 = 0x3604, -+ HDMI_AHB_DMA_STPADDR0 = 0x3608, -+ HDMI_AHB_DMA_MASK = 0x3614, -+ HDMI_AHB_DMA_POL = 0x3615, -+ HDMI_AHB_DMA_CONF1 = 0x3616, -+ HDMI_AHB_DMA_BUFFPOL = 0x361a, -+}; -+ -+struct dw_hdmi_channel_conf { -+ u8 conf1; -+ u8 ca; -+}; -+ -+/* -+ * The default mapping of ALSA channels to HDMI channels and speaker -+ * allocation bits. Note that we can't do channel remapping here - -+ * channels must be in the same order. -+ * -+ * Mappings for alsa-lib pcm/surround*.conf files: -+ * -+ * Front Sur4.0 Sur4.1 Sur5.0 Sur5.1 Sur7.1 -+ * Channels 2 4 6 6 6 8 -+ * -+ * Our mapping from ALSA channel to CEA686D speaker name and HDMI channel: -+ * -+ * Number of ALSA channels -+ * ALSA Channel 2 3 4 5 6 7 8 -+ * 0 FL:0 = = = = = = -+ * 1 FR:1 = = = = = = -+ * 2 FC:3 RL:4 LFE:2 = = = -+ * 3 RR:5 RL:4 FC:3 = = -+ * 4 RR:5 RL:4 = = -+ * 5 RR:5 = = -+ * 6 RC:6 = -+ * 7 RLC/FRC RLC/FRC -+ */ -+static struct dw_hdmi_channel_conf default_hdmi_channel_config[7] = { -+ { 0x03, 0x00 }, /* FL,FR */ -+ { 0x0b, 0x02 }, /* FL,FR,FC */ -+ { 0x33, 0x08 }, /* FL,FR,RL,RR */ -+ { 0x37, 0x09 }, /* FL,FR,LFE,RL,RR */ -+ { 0x3f, 0x0b }, /* FL,FR,LFE,FC,RL,RR */ -+ { 0x7f, 0x0f }, /* FL,FR,LFE,FC,RL,RR,RC */ -+ { 0xff, 0x13 }, /* FL,FR,LFE,FC,RL,RR,[FR]RC,[FR]LC */ -+}; -+ -+struct snd_dw_hdmi { -+ struct snd_card *card; -+ struct snd_pcm *pcm; -+ spinlock_t lock; -+ struct dw_hdmi_audio_data data; -+ struct snd_pcm_substream *substream; -+ void (*reformat)(struct snd_dw_hdmi *, size_t, size_t); -+ void *buf_src; -+ void *buf_dst; -+ dma_addr_t buf_addr; -+ unsigned buf_offset; -+ unsigned buf_period; -+ unsigned buf_size; -+ unsigned channels; -+ u8 revision; -+ u8 iec_offset; -+ u8 cs[192][8]; -+}; -+ -+static void dw_hdmi_writel(u32 val, void __iomem *ptr) -+{ -+ writeb_relaxed(val, ptr); -+ writeb_relaxed(val >> 8, ptr + 1); -+ writeb_relaxed(val >> 16, ptr + 2); -+ writeb_relaxed(val >> 24, ptr + 3); -+} -+ -+/* -+ * Convert to hardware format: The userspace buffer contains IEC958 samples, -+ * with the PCUV bits in bits 31..28 and audio samples in bits 27..4. We -+ * need these to be in bits 27..24, with the IEC B bit in bit 28, and audio -+ * samples in 23..0. -+ * -+ * Default preamble in bits 3..0: 8 = block start, 4 = even 2 = odd -+ * -+ * Ideally, we could do with having the data properly formatted in userspace. -+ */ -+static void dw_hdmi_reformat_iec958(struct snd_dw_hdmi *dw, -+ size_t offset, size_t bytes) -+{ -+ u32 *src = dw->buf_src + offset; -+ u32 *dst = dw->buf_dst + offset; -+ u32 *end = dw->buf_src + offset + bytes; -+ -+ do { -+ u32 b, sample = *src++; -+ -+ b = (sample & 8) << (28 - 3); -+ -+ sample >>= 4; -+ -+ *dst++ = sample | b; -+ } while (src < end); -+} -+ -+static u32 parity(u32 sample) -+{ -+ sample ^= sample >> 16; -+ sample ^= sample >> 8; -+ sample ^= sample >> 4; -+ sample ^= sample >> 2; -+ sample ^= sample >> 1; -+ return (sample & 1) << 27; -+} -+ -+static void dw_hdmi_reformat_s24(struct snd_dw_hdmi *dw, -+ size_t offset, size_t bytes) -+{ -+ u32 *src = dw->buf_src + offset; -+ u32 *dst = dw->buf_dst + offset; -+ u32 *end = dw->buf_src + offset + bytes; -+ -+ do { -+ unsigned i; -+ u8 *cs; -+ -+ cs = dw->cs[dw->iec_offset++]; -+ if (dw->iec_offset >= 192) -+ dw->iec_offset = 0; -+ -+ i = dw->channels; -+ do { -+ u32 sample = *src++; -+ -+ sample &= ~0xff000000; -+ sample |= *cs++ << 24; -+ sample |= parity(sample & ~0xf8000000); -+ -+ *dst++ = sample; -+ } while (--i); -+ } while (src < end); -+} -+ -+static void dw_hdmi_create_cs(struct snd_dw_hdmi *dw, -+ struct snd_pcm_runtime *runtime) -+{ -+ u8 cs[4]; -+ unsigned ch, i, j; -+ -+ snd_pcm_create_iec958_consumer(runtime, cs, sizeof(cs)); -+ -+ memset(dw->cs, 0, sizeof(dw->cs)); -+ -+ for (ch = 0; ch < 8; ch++) { -+ cs[2] &= ~IEC958_AES2_CON_CHANNEL; -+ cs[2] |= (ch + 1) << 4; -+ -+ for (i = 0; i < ARRAY_SIZE(cs); i++) { -+ unsigned c = cs[i]; -+ -+ for (j = 0; j < 8; j++, c >>= 1) -+ dw->cs[i * 8 + j][ch] = (c & 1) << 2; -+ } -+ } -+ dw->cs[0][0] |= BIT(4); -+} -+ -+static void dw_hdmi_start_dma(struct snd_dw_hdmi *dw) -+{ -+ void __iomem *base = dw->data.base; -+ unsigned offset = dw->buf_offset; -+ unsigned period = dw->buf_period; -+ u32 start, stop; -+ -+ dw->reformat(dw, offset, period); -+ -+ /* Clear all irqs before enabling irqs and starting DMA */ -+ writeb_relaxed(HDMI_IH_AHBDMAAUD_STAT0_ALL, -+ base + HDMI_IH_AHBDMAAUD_STAT0); -+ -+ start = dw->buf_addr + offset; -+ stop = start + period - 1; -+ -+ /* Setup the hardware start/stop addresses */ -+ dw_hdmi_writel(start, base + HDMI_AHB_DMA_STRADDR0); -+ dw_hdmi_writel(stop, base + HDMI_AHB_DMA_STPADDR0); -+ -+ writeb_relaxed((u8)~HDMI_AHB_DMA_MASK_DONE, base + HDMI_AHB_DMA_MASK); -+ writeb(HDMI_AHB_DMA_START_START, base + HDMI_AHB_DMA_START); -+ -+ offset += period; -+ if (offset >= dw->buf_size) -+ offset = 0; -+ dw->buf_offset = offset; -+} -+ -+static void dw_hdmi_stop_dma(struct snd_dw_hdmi *dw) -+{ -+ /* Disable interrupts before disabling DMA */ -+ writeb_relaxed(~0, dw->data.base + HDMI_AHB_DMA_MASK); -+ writeb_relaxed(HDMI_AHB_DMA_STOP_STOP, dw->data.base + HDMI_AHB_DMA_STOP); -+} -+ -+static irqreturn_t snd_dw_hdmi_irq(int irq, void *data) -+{ -+ struct snd_dw_hdmi *dw = data; -+ struct snd_pcm_substream *substream; -+ unsigned stat; -+ -+ stat = readb_relaxed(dw->data.base + HDMI_IH_AHBDMAAUD_STAT0); -+ if (!stat) -+ return IRQ_NONE; -+ -+ writeb_relaxed(stat, dw->data.base + HDMI_IH_AHBDMAAUD_STAT0); -+ -+ substream = dw->substream; -+ if (stat & HDMI_IH_AHBDMAAUD_STAT0_DONE && substream) { -+ snd_pcm_period_elapsed(substream); -+ -+ spin_lock(&dw->lock); -+ if (dw->substream) -+ dw_hdmi_start_dma(dw); -+ spin_unlock(&dw->lock); -+ } -+ -+ return IRQ_HANDLED; -+} -+ -+static struct snd_pcm_hardware dw_hdmi_hw = { -+ .info = SNDRV_PCM_INFO_INTERLEAVED | -+ SNDRV_PCM_INFO_BLOCK_TRANSFER | -+ SNDRV_PCM_INFO_MMAP | -+ SNDRV_PCM_INFO_MMAP_VALID, -+ .formats = SNDRV_PCM_FMTBIT_IEC958_SUBFRAME_LE | -+ SNDRV_PCM_FMTBIT_S24_LE, -+ .rates = SNDRV_PCM_RATE_32000 | -+ SNDRV_PCM_RATE_44100 | -+ SNDRV_PCM_RATE_48000 | -+ SNDRV_PCM_RATE_88200 | -+ SNDRV_PCM_RATE_96000 | -+ SNDRV_PCM_RATE_176400 | -+ SNDRV_PCM_RATE_192000, -+ .channels_min = 2, -+ .channels_max = 8, -+ .buffer_bytes_max = 1024 * 1024, -+ .period_bytes_min = 256, -+ .period_bytes_max = 8192, /* ERR004323: must limit to 8k */ -+ .periods_min = 2, -+ .periods_max = 16, -+ .fifo_size = 0, -+}; -+ -+static int dw_hdmi_open(struct snd_pcm_substream *substream) -+{ -+ struct snd_pcm_runtime *runtime = substream->runtime; -+ struct snd_dw_hdmi *dw = substream->private_data; -+ void __iomem *base = dw->data.base; -+ int ret; -+ -+ runtime->hw = dw_hdmi_hw; -+ -+ ret = snd_pcm_hw_constraint_eld(runtime, dw->data.eld); -+ if (ret < 0) -+ return ret; -+ -+ ret = snd_pcm_limit_hw_rates(runtime); -+ if (ret < 0) -+ return ret; -+ -+ ret = snd_pcm_hw_constraint_integer(runtime, -+ SNDRV_PCM_HW_PARAM_PERIODS); -+ if (ret < 0) -+ return ret; -+ -+ /* Limit the buffer size to the size of the preallocated buffer */ -+ ret = snd_pcm_hw_constraint_minmax(runtime, -+ SNDRV_PCM_HW_PARAM_BUFFER_SIZE, -+ 0, substream->dma_buffer.bytes); -+ if (ret < 0) -+ return ret; -+ -+ /* Clear FIFO */ -+ writeb_relaxed(HDMI_AHB_DMA_CONF0_SW_FIFO_RST, -+ base + HDMI_AHB_DMA_CONF0); -+ -+ /* Configure interrupt polarities */ -+ writeb_relaxed(~0, base + HDMI_AHB_DMA_POL); -+ writeb_relaxed(~0, base + HDMI_AHB_DMA_BUFFPOL); -+ -+ /* Keep interrupts masked, and clear any pending */ -+ writeb_relaxed(~0, base + HDMI_AHB_DMA_MASK); -+ writeb_relaxed(~0, base + HDMI_IH_AHBDMAAUD_STAT0); -+ -+ ret = request_irq(dw->data.irq, snd_dw_hdmi_irq, IRQF_SHARED, -+ "dw-hdmi-audio", dw); -+ if (ret) -+ return ret; -+ -+ /* Un-mute done interrupt */ -+ writeb_relaxed(HDMI_IH_MUTE_AHBDMAAUD_STAT0_ALL & -+ ~HDMI_IH_MUTE_AHBDMAAUD_STAT0_DONE, -+ base + HDMI_IH_MUTE_AHBDMAAUD_STAT0); -+ -+ return 0; -+} -+ -+static int dw_hdmi_close(struct snd_pcm_substream *substream) -+{ -+ struct snd_dw_hdmi *dw = substream->private_data; -+ -+ /* Mute all interrupts */ -+ writeb_relaxed(HDMI_IH_MUTE_AHBDMAAUD_STAT0_ALL, -+ dw->data.base + HDMI_IH_MUTE_AHBDMAAUD_STAT0); -+ -+ free_irq(dw->data.irq, dw); -+ -+ return 0; -+} -+ -+static int dw_hdmi_hw_free(struct snd_pcm_substream *substream) -+{ -+ return snd_pcm_lib_free_vmalloc_buffer(substream); -+} -+ -+static int dw_hdmi_hw_params(struct snd_pcm_substream *substream, -+ struct snd_pcm_hw_params *params) -+{ -+ /* Allocate the PCM runtime buffer, which is exposed to userspace. */ -+ return snd_pcm_lib_alloc_vmalloc_buffer(substream, -+ params_buffer_bytes(params)); -+} -+ -+static int dw_hdmi_prepare(struct snd_pcm_substream *substream) -+{ -+ struct snd_pcm_runtime *runtime = substream->runtime; -+ struct snd_dw_hdmi *dw = substream->private_data; -+ u8 threshold, conf0, conf1, layout, ca; -+ -+ /* Setup as per 3.0.5 FSL 4.1.0 BSP */ -+ switch (dw->revision) { -+ case 0x0a: -+ conf0 = HDMI_AHB_DMA_CONF0_BURST_MODE | -+ HDMI_AHB_DMA_CONF0_INCR4; -+ if (runtime->channels == 2) -+ threshold = 126; -+ else -+ threshold = 124; -+ break; -+ case 0x1a: -+ conf0 = HDMI_AHB_DMA_CONF0_BURST_MODE | -+ HDMI_AHB_DMA_CONF0_INCR8; -+ threshold = 128; -+ break; -+ default: -+ /* NOTREACHED */ -+ return -EINVAL; -+ } -+ -+ dw_hdmi_set_sample_rate(dw->data.hdmi, runtime->rate); -+ -+ /* Minimum number of bytes in the fifo. */ -+ runtime->hw.fifo_size = threshold * 32; -+ -+ conf0 |= HDMI_AHB_DMA_CONF0_EN_HLOCK; -+ conf1 = default_hdmi_channel_config[runtime->channels - 2].conf1; -+ ca = default_hdmi_channel_config[runtime->channels - 2].ca; -+ -+ /* -+ * For >2 channel PCM audio, we need to select layout 1 -+ * and set an appropriate channel map. -+ */ -+ if (runtime->channels > 2) -+ layout = HDMI_FC_AUDSCONF_LAYOUT1; -+ else -+ layout = HDMI_FC_AUDSCONF_LAYOUT0; -+ -+ writeb_relaxed(threshold, dw->data.base + HDMI_AHB_DMA_THRSLD); -+ writeb_relaxed(conf0, dw->data.base + HDMI_AHB_DMA_CONF0); -+ writeb_relaxed(conf1, dw->data.base + HDMI_AHB_DMA_CONF1); -+ writeb_relaxed(layout, dw->data.base + HDMI_FC_AUDSCONF); -+ writeb_relaxed(ca, dw->data.base + HDMI_FC_AUDICONF2); -+ -+ switch (runtime->format) { -+ case SNDRV_PCM_FORMAT_IEC958_SUBFRAME_LE: -+ dw->reformat = dw_hdmi_reformat_iec958; -+ break; -+ case SNDRV_PCM_FORMAT_S24_LE: -+ dw_hdmi_create_cs(dw, runtime); -+ dw->reformat = dw_hdmi_reformat_s24; -+ break; -+ } -+ dw->iec_offset = 0; -+ dw->channels = runtime->channels; -+ dw->buf_src = runtime->dma_area; -+ dw->buf_dst = substream->dma_buffer.area; -+ dw->buf_addr = substream->dma_buffer.addr; -+ dw->buf_period = snd_pcm_lib_period_bytes(substream); -+ dw->buf_size = snd_pcm_lib_buffer_bytes(substream); -+ -+ return 0; -+} -+ -+static int dw_hdmi_trigger(struct snd_pcm_substream *substream, int cmd) -+{ -+ struct snd_dw_hdmi *dw = substream->private_data; -+ unsigned long flags; -+ int ret = 0; -+ -+ switch (cmd) { -+ case SNDRV_PCM_TRIGGER_START: -+ spin_lock_irqsave(&dw->lock, flags); -+ dw->buf_offset = 0; -+ dw->substream = substream; -+ dw_hdmi_start_dma(dw); -+ dw_hdmi_audio_enable(dw->data.hdmi); -+ spin_unlock_irqrestore(&dw->lock, flags); -+ substream->runtime->delay = substream->runtime->period_size; -+ break; -+ -+ case SNDRV_PCM_TRIGGER_STOP: -+ spin_lock_irqsave(&dw->lock, flags); -+ dw->substream = NULL; -+ dw_hdmi_stop_dma(dw); -+ dw_hdmi_audio_disable(dw->data.hdmi); -+ spin_unlock_irqrestore(&dw->lock, flags); -+ break; -+ -+ default: -+ ret = -EINVAL; -+ break; -+ } -+ -+ return ret; -+} -+ -+static snd_pcm_uframes_t dw_hdmi_pointer(struct snd_pcm_substream *substream) -+{ -+ struct snd_pcm_runtime *runtime = substream->runtime; -+ struct snd_dw_hdmi *dw = substream->private_data; -+ -+ /* -+ * We are unable to report the exact hardware position as -+ * reading the 32-bit DMA position using 8-bit reads is racy. -+ */ -+ return bytes_to_frames(runtime, dw->buf_offset); -+} -+ -+static struct snd_pcm_ops snd_dw_hdmi_ops = { -+ .open = dw_hdmi_open, -+ .close = dw_hdmi_close, -+ .ioctl = snd_pcm_lib_ioctl, -+ .hw_params = dw_hdmi_hw_params, -+ .hw_free = dw_hdmi_hw_free, -+ .prepare = dw_hdmi_prepare, -+ .trigger = dw_hdmi_trigger, -+ .pointer = dw_hdmi_pointer, -+ .page = snd_pcm_lib_get_vmalloc_page, -+}; -+ -+static int snd_dw_hdmi_probe(struct platform_device *pdev) -+{ -+ const struct dw_hdmi_audio_data *data = pdev->dev.platform_data; -+ struct device *dev = pdev->dev.parent; -+ struct snd_dw_hdmi *dw; -+ struct snd_card *card; -+ struct snd_pcm *pcm; -+ unsigned revision; -+ int ret; -+ -+ writeb_relaxed(HDMI_IH_MUTE_AHBDMAAUD_STAT0_ALL, -+ data->base + HDMI_IH_MUTE_AHBDMAAUD_STAT0); -+ revision = readb_relaxed(data->base + HDMI_REVISION_ID); -+ if (revision != 0x0a && revision != 0x1a) { -+ dev_err(dev, "dw-hdmi-audio: unknown revision 0x%02x\n", -+ revision); -+ return -ENXIO; -+ } -+ -+ ret = snd_card_new(dev, SNDRV_DEFAULT_IDX1, SNDRV_DEFAULT_STR1, -+ THIS_MODULE, sizeof(struct snd_dw_hdmi), &card); -+ if (ret < 0) -+ return ret; -+ -+ strlcpy(card->driver, DRIVER_NAME, sizeof(card->driver)); -+ strlcpy(card->shortname, "DW-HDMI", sizeof(card->shortname)); -+ snprintf(card->longname, sizeof(card->longname), -+ "%s rev 0x%02x, irq %d", card->shortname, revision, -+ data->irq); -+ -+ dw = card->private_data; -+ dw->card = card; -+ dw->data = *data; -+ dw->revision = revision; -+ -+ spin_lock_init(&dw->lock); -+ -+ ret = snd_pcm_new(card, "DW HDMI", 0, 1, 0, &pcm); -+ if (ret < 0) -+ goto err; -+ -+ dw->pcm = pcm; -+ pcm->private_data = dw; -+ strlcpy(pcm->name, DRIVER_NAME, sizeof(pcm->name)); -+ snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK, &snd_dw_hdmi_ops); -+ -+ /* -+ * To support 8-channel 96kHz audio reliably, we need 512k -+ * to satisfy alsa with our restricted period (ERR004323). -+ */ -+ snd_pcm_lib_preallocate_pages_for_all(pcm, SNDRV_DMA_TYPE_DEV, -+ dev, 128 * 1024, 1024 * 1024); -+ -+ ret = snd_card_register(card); -+ if (ret < 0) -+ goto err; -+ -+ platform_set_drvdata(pdev, dw); -+ -+ return 0; -+ -+err: -+ snd_card_free(card); -+ return ret; -+} -+ -+static int snd_dw_hdmi_remove(struct platform_device *pdev) -+{ -+ struct snd_dw_hdmi *dw = platform_get_drvdata(pdev); -+ -+ snd_card_free(dw->card); -+ -+ return 0; -+} -+ -+#if defined(CONFIG_PM_SLEEP) && defined(IS_NOT_BROKEN) -+/* -+ * This code is fine, but requires implementation in the dw_hdmi_trigger() -+ * method which is currently missing as I have no way to test this. -+ */ -+static int snd_dw_hdmi_suspend(struct device *dev) -+{ -+ struct snd_dw_hdmi *dw = dev_get_drvdata(dev); -+ -+ snd_power_change_state(dw->card, SNDRV_CTL_POWER_D3cold); -+ snd_pcm_suspend_all(dw->pcm); -+ -+ return 0; -+} -+ -+static int snd_dw_hdmi_resume(struct device *dev) -+{ -+ struct snd_dw_hdmi *dw = dev_get_drvdata(dev); -+ -+ snd_power_change_state(dw->card, SNDRV_CTL_POWER_D0); -+ -+ return 0; -+} -+ -+static SIMPLE_DEV_PM_OPS(snd_dw_hdmi_pm, snd_dw_hdmi_suspend, -+ snd_dw_hdmi_resume); -+#define PM_OPS &snd_dw_hdmi_pm -+#else -+#define PM_OPS NULL -+#endif -+ -+static struct platform_driver snd_dw_hdmi_driver = { -+ .probe = snd_dw_hdmi_probe, -+ .remove = snd_dw_hdmi_remove, -+ .driver = { -+ .name = DRIVER_NAME, -+ .pm = PM_OPS, -+ }, -+}; -+ -+module_platform_driver(snd_dw_hdmi_driver); -+ -+MODULE_AUTHOR("Russell King "); -+MODULE_DESCRIPTION("Synopsis Designware HDMI AHB ALSA interface"); -+MODULE_LICENSE("GPL v2"); -+MODULE_ALIAS("platform:" DRIVER_NAME); -diff --git a/drivers/gpu/drm/bridge/synopsys/dw-hdmi-audio.h b/drivers/gpu/drm/bridge/synopsys/dw-hdmi-audio.h -new file mode 100644 -index 0000000..fd1f745 ---- /dev/null -+++ b/drivers/gpu/drm/bridge/synopsys/dw-hdmi-audio.h -@@ -0,0 +1,21 @@ -+#ifndef DW_HDMI_AUDIO_H -+#define DW_HDMI_AUDIO_H -+ -+struct dw_hdmi; -+ -+struct dw_hdmi_audio_data { -+ phys_addr_t phys; -+ void __iomem *base; -+ int irq; -+ struct dw_hdmi *hdmi; -+ u8 *eld; -+}; -+ -+struct dw_hdmi_i2s_audio_data { -+ struct dw_hdmi *hdmi; -+ -+ void (*write)(struct dw_hdmi *hdmi, u8 val, int offset); -+ u8 (*read)(struct dw_hdmi *hdmi, int offset); -+}; -+ -+#endif -diff --git a/drivers/gpu/drm/bridge/synopsys/dw-hdmi-i2s-audio.c b/drivers/gpu/drm/bridge/synopsys/dw-hdmi-i2s-audio.c -new file mode 100644 -index 0000000..aaf287d ---- /dev/null -+++ b/drivers/gpu/drm/bridge/synopsys/dw-hdmi-i2s-audio.c -@@ -0,0 +1,141 @@ -+/* -+ * dw-hdmi-i2s-audio.c -+ * -+ * Copyright (c) 2016 Kuninori Morimoto -+ * -+ * This program is free software; you can redistribute it and/or modify -+ * it under the terms of the GNU General Public License version 2 as -+ * published by the Free Software Foundation. -+ */ -+#include -+ -+#include -+ -+#include "dw-hdmi.h" -+#include "dw-hdmi-audio.h" -+ -+#define DRIVER_NAME "dw-hdmi-i2s-audio" -+ -+static inline void hdmi_write(struct dw_hdmi_i2s_audio_data *audio, -+ u8 val, int offset) -+{ -+ struct dw_hdmi *hdmi = audio->hdmi; -+ -+ audio->write(hdmi, val, offset); -+} -+ -+static inline u8 hdmi_read(struct dw_hdmi_i2s_audio_data *audio, int offset) -+{ -+ struct dw_hdmi *hdmi = audio->hdmi; -+ -+ return audio->read(hdmi, offset); -+} -+ -+static int dw_hdmi_i2s_hw_params(struct device *dev, void *data, -+ struct hdmi_codec_daifmt *fmt, -+ struct hdmi_codec_params *hparms) -+{ -+ struct dw_hdmi_i2s_audio_data *audio = data; -+ struct dw_hdmi *hdmi = audio->hdmi; -+ u8 conf0 = 0; -+ u8 conf1 = 0; -+ u8 inputclkfs = 0; -+ -+ /* it cares I2S only */ -+ if ((fmt->fmt != HDMI_I2S) || -+ (fmt->bit_clk_master | fmt->frame_clk_master)) { -+ dev_err(dev, "unsupported format/settings\n"); -+ return -EINVAL; -+ } -+ -+ inputclkfs = HDMI_AUD_INPUTCLKFS_64FS; -+ conf0 = HDMI_AUD_CONF0_I2S_ALL_ENABLE; -+ -+ switch (hparms->sample_width) { -+ case 16: -+ conf1 = HDMI_AUD_CONF1_WIDTH_16; -+ break; -+ case 24: -+ case 32: -+ conf1 = HDMI_AUD_CONF1_WIDTH_24; -+ break; -+ } -+ -+ dw_hdmi_set_sample_rate(hdmi, hparms->sample_rate); -+ -+ hdmi_write(audio, inputclkfs, HDMI_AUD_INPUTCLKFS); -+ hdmi_write(audio, conf0, HDMI_AUD_CONF0); -+ hdmi_write(audio, conf1, HDMI_AUD_CONF1); -+ -+ dw_hdmi_audio_enable(hdmi); -+ -+ return 0; -+} -+ -+static void dw_hdmi_i2s_audio_shutdown(struct device *dev, void *data) -+{ -+ struct dw_hdmi_i2s_audio_data *audio = data; -+ struct dw_hdmi *hdmi = audio->hdmi; -+ -+ dw_hdmi_audio_disable(hdmi); -+ -+ hdmi_write(audio, HDMI_AUD_CONF0_SW_RESET, HDMI_AUD_CONF0); -+} -+ -+static struct hdmi_codec_ops dw_hdmi_i2s_ops = { -+ .hw_params = dw_hdmi_i2s_hw_params, -+ .audio_shutdown = dw_hdmi_i2s_audio_shutdown, -+}; -+ -+static int snd_dw_hdmi_probe(struct platform_device *pdev) -+{ -+ struct dw_hdmi_i2s_audio_data *audio = pdev->dev.platform_data; -+ struct platform_device_info pdevinfo; -+ struct hdmi_codec_pdata pdata; -+ struct platform_device *platform; -+ -+ pdata.ops = &dw_hdmi_i2s_ops; -+ pdata.i2s = 1; -+ pdata.max_i2s_channels = 6; -+ pdata.data = audio; -+ -+ memset(&pdevinfo, 0, sizeof(pdevinfo)); -+ pdevinfo.parent = pdev->dev.parent; -+ pdevinfo.id = PLATFORM_DEVID_AUTO; -+ pdevinfo.name = HDMI_CODEC_DRV_NAME; -+ pdevinfo.data = &pdata; -+ pdevinfo.size_data = sizeof(pdata); -+ pdevinfo.dma_mask = DMA_BIT_MASK(32); -+ -+ platform = platform_device_register_full(&pdevinfo); -+ if (IS_ERR(platform)) -+ return PTR_ERR(platform); -+ -+ dev_set_drvdata(&pdev->dev, platform); -+ -+ return 0; -+} -+ -+static int snd_dw_hdmi_remove(struct platform_device *pdev) -+{ -+ struct platform_device *platform = dev_get_drvdata(&pdev->dev); -+ -+ platform_device_unregister(platform); -+ -+ return 0; -+} -+ -+static struct platform_driver snd_dw_hdmi_driver = { -+ .probe = snd_dw_hdmi_probe, -+ .remove = snd_dw_hdmi_remove, -+ .driver = { -+ .name = DRIVER_NAME, -+ .owner = THIS_MODULE, -+ }, -+}; -+module_platform_driver(snd_dw_hdmi_driver); -+ -+MODULE_AUTHOR("Kuninori Morimoto "); -+MODULE_DESCRIPTION("Synopsis Designware HDMI I2S ALSA SoC interface"); -+MODULE_LICENSE("GPL v2"); -+MODULE_ALIAS("platform:" DRIVER_NAME); -diff --git a/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c b/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c -new file mode 100644 -index 0000000..026a0dc ---- /dev/null -+++ b/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c -@@ -0,0 +1,2314 @@ -+/* -+ * DesignWare High-Definition Multimedia Interface (HDMI) driver -+ * -+ * Copyright (C) 2013-2015 Mentor Graphics Inc. -+ * Copyright (C) 2011-2013 Freescale Semiconductor, Inc. -+ * Copyright (C) 2010, Guennadi Liakhovetski -+ * -+ * This program is free software; you can redistribute it and/or modify -+ * it under the terms of the GNU General Public License as published by -+ * the Free Software Foundation; either version 2 of the License, or -+ * (at your option) any later version. -+ * -+ */ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+ -+#include "dw-hdmi.h" -+#include "dw-hdmi-audio.h" -+ -+#define HDMI_EDID_LEN 512 -+ -+#define RGB 0 -+#define YCBCR444 1 -+#define YCBCR422_16BITS 2 -+#define YCBCR422_8BITS 3 -+#define XVYCC444 4 -+ -+enum hdmi_datamap { -+ RGB444_8B = 0x01, -+ RGB444_10B = 0x03, -+ RGB444_12B = 0x05, -+ RGB444_16B = 0x07, -+ YCbCr444_8B = 0x09, -+ YCbCr444_10B = 0x0B, -+ YCbCr444_12B = 0x0D, -+ YCbCr444_16B = 0x0F, -+ YCbCr422_8B = 0x16, -+ YCbCr422_10B = 0x14, -+ YCbCr422_12B = 0x12, -+}; -+ -+static const u16 csc_coeff_default[3][4] = { -+ { 0x2000, 0x0000, 0x0000, 0x0000 }, -+ { 0x0000, 0x2000, 0x0000, 0x0000 }, -+ { 0x0000, 0x0000, 0x2000, 0x0000 } -+}; -+ -+static const u16 csc_coeff_rgb_out_eitu601[3][4] = { -+ { 0x2000, 0x6926, 0x74fd, 0x010e }, -+ { 0x2000, 0x2cdd, 0x0000, 0x7e9a }, -+ { 0x2000, 0x0000, 0x38b4, 0x7e3b } -+}; -+ -+static const u16 csc_coeff_rgb_out_eitu709[3][4] = { -+ { 0x2000, 0x7106, 0x7a02, 0x00a7 }, -+ { 0x2000, 0x3264, 0x0000, 0x7e6d }, -+ { 0x2000, 0x0000, 0x3b61, 0x7e25 } -+}; -+ -+static const u16 csc_coeff_rgb_in_eitu601[3][4] = { -+ { 0x2591, 0x1322, 0x074b, 0x0000 }, -+ { 0x6535, 0x2000, 0x7acc, 0x0200 }, -+ { 0x6acd, 0x7534, 0x2000, 0x0200 } -+}; -+ -+static const u16 csc_coeff_rgb_in_eitu709[3][4] = { -+ { 0x2dc5, 0x0d9b, 0x049e, 0x0000 }, -+ { 0x62f0, 0x2000, 0x7d11, 0x0200 }, -+ { 0x6756, 0x78ab, 0x2000, 0x0200 } -+}; -+ -+struct hdmi_vmode { -+ bool mdataenablepolarity; -+ -+ unsigned int mpixelclock; -+ unsigned int mpixelrepetitioninput; -+ unsigned int mpixelrepetitionoutput; -+}; -+ -+struct hdmi_data_info { -+ unsigned int enc_in_format; -+ unsigned int enc_out_format; -+ unsigned int enc_color_depth; -+ unsigned int colorimetry; -+ unsigned int pix_repet_factor; -+ unsigned int hdcp_enable; -+ struct hdmi_vmode video_mode; -+}; -+ -+struct dw_hdmi_i2c { -+ struct i2c_adapter adap; -+ -+ struct mutex lock; /* used to serialize data transfers */ -+ struct completion cmp; -+ u8 stat; -+ -+ u8 slave_reg; -+ bool is_regaddr; -+}; -+ -+struct dw_hdmi_phy_data { -+ enum dw_hdmi_phy_type type; -+ const char *name; -+ unsigned int gen; -+ bool has_svsret; -+ int (*configure)(struct dw_hdmi *hdmi, -+ const struct dw_hdmi_plat_data *pdata, -+ unsigned long mpixelclock); -+}; -+ -+struct dw_hdmi { -+ struct drm_connector connector; -+ struct drm_bridge bridge; -+ -+ unsigned int version; -+ -+ struct platform_device *audio; -+ struct device *dev; -+ struct clk *isfr_clk; -+ struct clk *iahb_clk; -+ struct dw_hdmi_i2c *i2c; -+ -+ struct hdmi_data_info hdmi_data; -+ const struct dw_hdmi_plat_data *plat_data; -+ -+ int vic; -+ -+ u8 edid[HDMI_EDID_LEN]; -+ bool cable_plugin; -+ -+ struct { -+ const struct dw_hdmi_phy_ops *ops; -+ const char *name; -+ void *data; -+ bool enabled; -+ } phy; -+ -+ struct drm_display_mode previous_mode; -+ -+ struct i2c_adapter *ddc; -+ void __iomem *regs; -+ bool sink_is_hdmi; -+ bool sink_has_audio; -+ -+ struct mutex mutex; /* for state below and previous_mode */ -+ enum drm_connector_force force; /* mutex-protected force state */ -+ bool disabled; /* DRM has disabled our bridge */ -+ bool bridge_is_on; /* indicates the bridge is on */ -+ bool rxsense; /* rxsense state */ -+ u8 phy_mask; /* desired phy int mask settings */ -+ -+ spinlock_t audio_lock; -+ struct mutex audio_mutex; -+ unsigned int sample_rate; -+ unsigned int audio_cts; -+ unsigned int audio_n; -+ bool audio_enable; -+ -+ unsigned int reg_shift; -+ struct regmap *regm; -+}; -+ -+#define HDMI_IH_PHY_STAT0_RX_SENSE \ -+ (HDMI_IH_PHY_STAT0_RX_SENSE0 | HDMI_IH_PHY_STAT0_RX_SENSE1 | \ -+ HDMI_IH_PHY_STAT0_RX_SENSE2 | HDMI_IH_PHY_STAT0_RX_SENSE3) -+ -+#define HDMI_PHY_RX_SENSE \ -+ (HDMI_PHY_RX_SENSE0 | HDMI_PHY_RX_SENSE1 | \ -+ HDMI_PHY_RX_SENSE2 | HDMI_PHY_RX_SENSE3) -+ -+static inline void hdmi_writeb(struct dw_hdmi *hdmi, u8 val, int offset) -+{ -+ regmap_write(hdmi->regm, offset << hdmi->reg_shift, val); -+} -+ -+static inline u8 hdmi_readb(struct dw_hdmi *hdmi, int offset) -+{ -+ unsigned int val = 0; -+ -+ regmap_read(hdmi->regm, offset << hdmi->reg_shift, &val); -+ -+ return val; -+} -+ -+static void hdmi_modb(struct dw_hdmi *hdmi, u8 data, u8 mask, unsigned reg) -+{ -+ regmap_update_bits(hdmi->regm, reg << hdmi->reg_shift, mask, data); -+} -+ -+static void hdmi_mask_writeb(struct dw_hdmi *hdmi, u8 data, unsigned int reg, -+ u8 shift, u8 mask) -+{ -+ hdmi_modb(hdmi, data << shift, mask, reg); -+} -+ -+static void dw_hdmi_i2c_init(struct dw_hdmi *hdmi) -+{ -+ /* Software reset */ -+ hdmi_writeb(hdmi, 0x00, HDMI_I2CM_SOFTRSTZ); -+ -+ /* Set Standard Mode speed (determined to be 100KHz on iMX6) */ -+ hdmi_writeb(hdmi, 0x00, HDMI_I2CM_DIV); -+ -+ /* Set done, not acknowledged and arbitration interrupt polarities */ -+ hdmi_writeb(hdmi, HDMI_I2CM_INT_DONE_POL, HDMI_I2CM_INT); -+ hdmi_writeb(hdmi, HDMI_I2CM_CTLINT_NAC_POL | HDMI_I2CM_CTLINT_ARB_POL, -+ HDMI_I2CM_CTLINT); -+ -+ /* Clear DONE and ERROR interrupts */ -+ hdmi_writeb(hdmi, HDMI_IH_I2CM_STAT0_ERROR | HDMI_IH_I2CM_STAT0_DONE, -+ HDMI_IH_I2CM_STAT0); -+ -+ /* Mute DONE and ERROR interrupts */ -+ hdmi_writeb(hdmi, HDMI_IH_I2CM_STAT0_ERROR | HDMI_IH_I2CM_STAT0_DONE, -+ HDMI_IH_MUTE_I2CM_STAT0); -+} -+ -+static int dw_hdmi_i2c_read(struct dw_hdmi *hdmi, -+ unsigned char *buf, unsigned int length) -+{ -+ struct dw_hdmi_i2c *i2c = hdmi->i2c; -+ int stat; -+ -+ if (!i2c->is_regaddr) { -+ dev_dbg(hdmi->dev, "set read register address to 0\n"); -+ i2c->slave_reg = 0x00; -+ i2c->is_regaddr = true; -+ } -+ -+ while (length--) { -+ reinit_completion(&i2c->cmp); -+ -+ hdmi_writeb(hdmi, i2c->slave_reg++, HDMI_I2CM_ADDRESS); -+ hdmi_writeb(hdmi, HDMI_I2CM_OPERATION_READ, -+ HDMI_I2CM_OPERATION); -+ -+ stat = wait_for_completion_timeout(&i2c->cmp, HZ / 10); -+ if (!stat) -+ return -EAGAIN; -+ -+ /* Check for error condition on the bus */ -+ if (i2c->stat & HDMI_IH_I2CM_STAT0_ERROR) -+ return -EIO; -+ -+ *buf++ = hdmi_readb(hdmi, HDMI_I2CM_DATAI); -+ } -+ -+ return 0; -+} -+ -+static int dw_hdmi_i2c_write(struct dw_hdmi *hdmi, -+ unsigned char *buf, unsigned int length) -+{ -+ struct dw_hdmi_i2c *i2c = hdmi->i2c; -+ int stat; -+ -+ if (!i2c->is_regaddr) { -+ /* Use the first write byte as register address */ -+ i2c->slave_reg = buf[0]; -+ length--; -+ buf++; -+ i2c->is_regaddr = true; -+ } -+ -+ while (length--) { -+ reinit_completion(&i2c->cmp); -+ -+ hdmi_writeb(hdmi, *buf++, HDMI_I2CM_DATAO); -+ hdmi_writeb(hdmi, i2c->slave_reg++, HDMI_I2CM_ADDRESS); -+ hdmi_writeb(hdmi, HDMI_I2CM_OPERATION_WRITE, -+ HDMI_I2CM_OPERATION); -+ -+ stat = wait_for_completion_timeout(&i2c->cmp, HZ / 10); -+ if (!stat) -+ return -EAGAIN; -+ -+ /* Check for error condition on the bus */ -+ if (i2c->stat & HDMI_IH_I2CM_STAT0_ERROR) -+ return -EIO; -+ } -+ -+ return 0; -+} -+ -+static int dw_hdmi_i2c_xfer(struct i2c_adapter *adap, -+ struct i2c_msg *msgs, int num) -+{ -+ struct dw_hdmi *hdmi = i2c_get_adapdata(adap); -+ struct dw_hdmi_i2c *i2c = hdmi->i2c; -+ u8 addr = msgs[0].addr; -+ int i, ret = 0; -+ -+ dev_dbg(hdmi->dev, "xfer: num: %d, addr: %#x\n", num, addr); -+ -+ for (i = 0; i < num; i++) { -+ if (msgs[i].addr != addr) { -+ dev_warn(hdmi->dev, -+ "unsupported transfer, changed slave address\n"); -+ return -EOPNOTSUPP; -+ } -+ -+ if (msgs[i].len == 0) { -+ dev_dbg(hdmi->dev, -+ "unsupported transfer %d/%d, no data\n", -+ i + 1, num); -+ return -EOPNOTSUPP; -+ } -+ } -+ -+ mutex_lock(&i2c->lock); -+ -+ /* Unmute DONE and ERROR interrupts */ -+ hdmi_writeb(hdmi, 0x00, HDMI_IH_MUTE_I2CM_STAT0); -+ -+ /* Set slave device address taken from the first I2C message */ -+ hdmi_writeb(hdmi, addr, HDMI_I2CM_SLAVE); -+ -+ /* Set slave device register address on transfer */ -+ i2c->is_regaddr = false; -+ -+ for (i = 0; i < num; i++) { -+ dev_dbg(hdmi->dev, "xfer: num: %d/%d, len: %d, flags: %#x\n", -+ i + 1, num, msgs[i].len, msgs[i].flags); -+ -+ if (msgs[i].flags & I2C_M_RD) -+ ret = dw_hdmi_i2c_read(hdmi, msgs[i].buf, msgs[i].len); -+ else -+ ret = dw_hdmi_i2c_write(hdmi, msgs[i].buf, msgs[i].len); -+ -+ if (ret < 0) -+ break; -+ } -+ -+ if (!ret) -+ ret = num; -+ -+ /* Mute DONE and ERROR interrupts */ -+ hdmi_writeb(hdmi, HDMI_IH_I2CM_STAT0_ERROR | HDMI_IH_I2CM_STAT0_DONE, -+ HDMI_IH_MUTE_I2CM_STAT0); -+ -+ mutex_unlock(&i2c->lock); -+ -+ return ret; -+} -+ -+static u32 dw_hdmi_i2c_func(struct i2c_adapter *adapter) -+{ -+ return I2C_FUNC_I2C | I2C_FUNC_SMBUS_EMUL; -+} -+ -+static const struct i2c_algorithm dw_hdmi_algorithm = { -+ .master_xfer = dw_hdmi_i2c_xfer, -+ .functionality = dw_hdmi_i2c_func, -+}; -+ -+static struct i2c_adapter *dw_hdmi_i2c_adapter(struct dw_hdmi *hdmi) -+{ -+ struct i2c_adapter *adap; -+ struct dw_hdmi_i2c *i2c; -+ int ret; -+ -+ i2c = devm_kzalloc(hdmi->dev, sizeof(*i2c), GFP_KERNEL); -+ if (!i2c) -+ return ERR_PTR(-ENOMEM); -+ -+ mutex_init(&i2c->lock); -+ init_completion(&i2c->cmp); -+ -+ adap = &i2c->adap; -+ adap->class = I2C_CLASS_DDC; -+ adap->owner = THIS_MODULE; -+ adap->dev.parent = hdmi->dev; -+ adap->algo = &dw_hdmi_algorithm; -+ strlcpy(adap->name, "DesignWare HDMI", sizeof(adap->name)); -+ i2c_set_adapdata(adap, hdmi); -+ -+ ret = i2c_add_adapter(adap); -+ if (ret) { -+ dev_warn(hdmi->dev, "cannot add %s I2C adapter\n", adap->name); -+ devm_kfree(hdmi->dev, i2c); -+ return ERR_PTR(ret); -+ } -+ -+ hdmi->i2c = i2c; -+ -+ dev_info(hdmi->dev, "registered %s I2C bus driver\n", adap->name); -+ -+ return adap; -+} -+ -+static void hdmi_set_cts_n(struct dw_hdmi *hdmi, unsigned int cts, -+ unsigned int n) -+{ -+ /* Must be set/cleared first */ -+ hdmi_modb(hdmi, 0, HDMI_AUD_CTS3_CTS_MANUAL, HDMI_AUD_CTS3); -+ -+ /* nshift factor = 0 */ -+ hdmi_modb(hdmi, 0, HDMI_AUD_CTS3_N_SHIFT_MASK, HDMI_AUD_CTS3); -+ -+ hdmi_writeb(hdmi, ((cts >> 16) & HDMI_AUD_CTS3_AUDCTS19_16_MASK) | -+ HDMI_AUD_CTS3_CTS_MANUAL, HDMI_AUD_CTS3); -+ hdmi_writeb(hdmi, (cts >> 8) & 0xff, HDMI_AUD_CTS2); -+ hdmi_writeb(hdmi, cts & 0xff, HDMI_AUD_CTS1); -+ -+ hdmi_writeb(hdmi, (n >> 16) & 0x0f, HDMI_AUD_N3); -+ hdmi_writeb(hdmi, (n >> 8) & 0xff, HDMI_AUD_N2); -+ hdmi_writeb(hdmi, n & 0xff, HDMI_AUD_N1); -+} -+ -+static unsigned int hdmi_compute_n(unsigned int freq, unsigned long pixel_clk) -+{ -+ unsigned int n = (128 * freq) / 1000; -+ unsigned int mult = 1; -+ -+ while (freq > 48000) { -+ mult *= 2; -+ freq /= 2; -+ } -+ -+ switch (freq) { -+ case 32000: -+ if (pixel_clk == 25175000) -+ n = 4576; -+ else if (pixel_clk == 27027000) -+ n = 4096; -+ else if (pixel_clk == 74176000 || pixel_clk == 148352000) -+ n = 11648; -+ else -+ n = 4096; -+ n *= mult; -+ break; -+ -+ case 44100: -+ if (pixel_clk == 25175000) -+ n = 7007; -+ else if (pixel_clk == 74176000) -+ n = 17836; -+ else if (pixel_clk == 148352000) -+ n = 8918; -+ else -+ n = 6272; -+ n *= mult; -+ break; -+ -+ case 48000: -+ if (pixel_clk == 25175000) -+ n = 6864; -+ else if (pixel_clk == 27027000) -+ n = 6144; -+ else if (pixel_clk == 74176000) -+ n = 11648; -+ else if (pixel_clk == 148352000) -+ n = 5824; -+ else -+ n = 6144; -+ n *= mult; -+ break; -+ -+ default: -+ break; -+ } -+ -+ return n; -+} -+ -+static void hdmi_set_clk_regenerator(struct dw_hdmi *hdmi, -+ unsigned long pixel_clk, unsigned int sample_rate) -+{ -+ unsigned long ftdms = pixel_clk; -+ unsigned int n, cts; -+ u64 tmp; -+ -+ n = hdmi_compute_n(sample_rate, pixel_clk); -+ -+ /* -+ * Compute the CTS value from the N value. Note that CTS and N -+ * can be up to 20 bits in total, so we need 64-bit math. Also -+ * note that our TDMS clock is not fully accurate; it is accurate -+ * to kHz. This can introduce an unnecessary remainder in the -+ * calculation below, so we don't try to warn about that. -+ */ -+ tmp = (u64)ftdms * n; -+ do_div(tmp, 128 * sample_rate); -+ cts = tmp; -+ -+ dev_dbg(hdmi->dev, "%s: fs=%uHz ftdms=%lu.%03luMHz N=%d cts=%d\n", -+ __func__, sample_rate, ftdms / 1000000, (ftdms / 1000) % 1000, -+ n, cts); -+ -+ spin_lock_irq(&hdmi->audio_lock); -+ hdmi->audio_n = n; -+ hdmi->audio_cts = cts; -+ hdmi_set_cts_n(hdmi, cts, hdmi->audio_enable ? n : 0); -+ spin_unlock_irq(&hdmi->audio_lock); -+} -+ -+static void hdmi_init_clk_regenerator(struct dw_hdmi *hdmi) -+{ -+ mutex_lock(&hdmi->audio_mutex); -+ hdmi_set_clk_regenerator(hdmi, 74250000, hdmi->sample_rate); -+ mutex_unlock(&hdmi->audio_mutex); -+} -+ -+static void hdmi_clk_regenerator_update_pixel_clock(struct dw_hdmi *hdmi) -+{ -+ mutex_lock(&hdmi->audio_mutex); -+ hdmi_set_clk_regenerator(hdmi, hdmi->hdmi_data.video_mode.mpixelclock, -+ hdmi->sample_rate); -+ mutex_unlock(&hdmi->audio_mutex); -+} -+ -+void dw_hdmi_set_sample_rate(struct dw_hdmi *hdmi, unsigned int rate) -+{ -+ mutex_lock(&hdmi->audio_mutex); -+ hdmi->sample_rate = rate; -+ hdmi_set_clk_regenerator(hdmi, hdmi->hdmi_data.video_mode.mpixelclock, -+ hdmi->sample_rate); -+ mutex_unlock(&hdmi->audio_mutex); -+} -+EXPORT_SYMBOL_GPL(dw_hdmi_set_sample_rate); -+ -+void dw_hdmi_audio_enable(struct dw_hdmi *hdmi) -+{ -+ unsigned long flags; -+ -+ spin_lock_irqsave(&hdmi->audio_lock, flags); -+ hdmi->audio_enable = true; -+ hdmi_set_cts_n(hdmi, hdmi->audio_cts, hdmi->audio_n); -+ spin_unlock_irqrestore(&hdmi->audio_lock, flags); -+} -+EXPORT_SYMBOL_GPL(dw_hdmi_audio_enable); -+ -+void dw_hdmi_audio_disable(struct dw_hdmi *hdmi) -+{ -+ unsigned long flags; -+ -+ spin_lock_irqsave(&hdmi->audio_lock, flags); -+ hdmi->audio_enable = false; -+ hdmi_set_cts_n(hdmi, hdmi->audio_cts, 0); -+ spin_unlock_irqrestore(&hdmi->audio_lock, flags); -+} -+EXPORT_SYMBOL_GPL(dw_hdmi_audio_disable); -+ -+/* -+ * this submodule is responsible for the video data synchronization. -+ * for example, for RGB 4:4:4 input, the data map is defined as -+ * pin{47~40} <==> R[7:0] -+ * pin{31~24} <==> G[7:0] -+ * pin{15~8} <==> B[7:0] -+ */ -+static void hdmi_video_sample(struct dw_hdmi *hdmi) -+{ -+ int color_format = 0; -+ u8 val; -+ -+ if (hdmi->hdmi_data.enc_in_format == RGB) { -+ if (hdmi->hdmi_data.enc_color_depth == 8) -+ color_format = 0x01; -+ else if (hdmi->hdmi_data.enc_color_depth == 10) -+ color_format = 0x03; -+ else if (hdmi->hdmi_data.enc_color_depth == 12) -+ color_format = 0x05; -+ else if (hdmi->hdmi_data.enc_color_depth == 16) -+ color_format = 0x07; -+ else -+ return; -+ } else if (hdmi->hdmi_data.enc_in_format == YCBCR444) { -+ if (hdmi->hdmi_data.enc_color_depth == 8) -+ color_format = 0x09; -+ else if (hdmi->hdmi_data.enc_color_depth == 10) -+ color_format = 0x0B; -+ else if (hdmi->hdmi_data.enc_color_depth == 12) -+ color_format = 0x0D; -+ else if (hdmi->hdmi_data.enc_color_depth == 16) -+ color_format = 0x0F; -+ else -+ return; -+ } else if (hdmi->hdmi_data.enc_in_format == YCBCR422_8BITS) { -+ if (hdmi->hdmi_data.enc_color_depth == 8) -+ color_format = 0x16; -+ else if (hdmi->hdmi_data.enc_color_depth == 10) -+ color_format = 0x14; -+ else if (hdmi->hdmi_data.enc_color_depth == 12) -+ color_format = 0x12; -+ else -+ return; -+ } -+ -+ val = HDMI_TX_INVID0_INTERNAL_DE_GENERATOR_DISABLE | -+ ((color_format << HDMI_TX_INVID0_VIDEO_MAPPING_OFFSET) & -+ HDMI_TX_INVID0_VIDEO_MAPPING_MASK); -+ hdmi_writeb(hdmi, val, HDMI_TX_INVID0); -+ -+ /* Enable TX stuffing: When DE is inactive, fix the output data to 0 */ -+ val = HDMI_TX_INSTUFFING_BDBDATA_STUFFING_ENABLE | -+ HDMI_TX_INSTUFFING_RCRDATA_STUFFING_ENABLE | -+ HDMI_TX_INSTUFFING_GYDATA_STUFFING_ENABLE; -+ hdmi_writeb(hdmi, val, HDMI_TX_INSTUFFING); -+ hdmi_writeb(hdmi, 0x0, HDMI_TX_GYDATA0); -+ hdmi_writeb(hdmi, 0x0, HDMI_TX_GYDATA1); -+ hdmi_writeb(hdmi, 0x0, HDMI_TX_RCRDATA0); -+ hdmi_writeb(hdmi, 0x0, HDMI_TX_RCRDATA1); -+ hdmi_writeb(hdmi, 0x0, HDMI_TX_BCBDATA0); -+ hdmi_writeb(hdmi, 0x0, HDMI_TX_BCBDATA1); -+} -+ -+static int is_color_space_conversion(struct dw_hdmi *hdmi) -+{ -+ return hdmi->hdmi_data.enc_in_format != hdmi->hdmi_data.enc_out_format; -+} -+ -+static int is_color_space_decimation(struct dw_hdmi *hdmi) -+{ -+ if (hdmi->hdmi_data.enc_out_format != YCBCR422_8BITS) -+ return 0; -+ if (hdmi->hdmi_data.enc_in_format == RGB || -+ hdmi->hdmi_data.enc_in_format == YCBCR444) -+ return 1; -+ return 0; -+} -+ -+static int is_color_space_interpolation(struct dw_hdmi *hdmi) -+{ -+ if (hdmi->hdmi_data.enc_in_format != YCBCR422_8BITS) -+ return 0; -+ if (hdmi->hdmi_data.enc_out_format == RGB || -+ hdmi->hdmi_data.enc_out_format == YCBCR444) -+ return 1; -+ return 0; -+} -+ -+static void dw_hdmi_update_csc_coeffs(struct dw_hdmi *hdmi) -+{ -+ const u16 (*csc_coeff)[3][4] = &csc_coeff_default; -+ unsigned i; -+ u32 csc_scale = 1; -+ -+ if (is_color_space_conversion(hdmi)) { -+ if (hdmi->hdmi_data.enc_out_format == RGB) { -+ if (hdmi->hdmi_data.colorimetry == -+ HDMI_COLORIMETRY_ITU_601) -+ csc_coeff = &csc_coeff_rgb_out_eitu601; -+ else -+ csc_coeff = &csc_coeff_rgb_out_eitu709; -+ } else if (hdmi->hdmi_data.enc_in_format == RGB) { -+ if (hdmi->hdmi_data.colorimetry == -+ HDMI_COLORIMETRY_ITU_601) -+ csc_coeff = &csc_coeff_rgb_in_eitu601; -+ else -+ csc_coeff = &csc_coeff_rgb_in_eitu709; -+ csc_scale = 0; -+ } -+ } -+ -+ /* The CSC registers are sequential, alternating MSB then LSB */ -+ for (i = 0; i < ARRAY_SIZE(csc_coeff_default[0]); i++) { -+ u16 coeff_a = (*csc_coeff)[0][i]; -+ u16 coeff_b = (*csc_coeff)[1][i]; -+ u16 coeff_c = (*csc_coeff)[2][i]; -+ -+ hdmi_writeb(hdmi, coeff_a & 0xff, HDMI_CSC_COEF_A1_LSB + i * 2); -+ hdmi_writeb(hdmi, coeff_a >> 8, HDMI_CSC_COEF_A1_MSB + i * 2); -+ hdmi_writeb(hdmi, coeff_b & 0xff, HDMI_CSC_COEF_B1_LSB + i * 2); -+ hdmi_writeb(hdmi, coeff_b >> 8, HDMI_CSC_COEF_B1_MSB + i * 2); -+ hdmi_writeb(hdmi, coeff_c & 0xff, HDMI_CSC_COEF_C1_LSB + i * 2); -+ hdmi_writeb(hdmi, coeff_c >> 8, HDMI_CSC_COEF_C1_MSB + i * 2); -+ } -+ -+ hdmi_modb(hdmi, csc_scale, HDMI_CSC_SCALE_CSCSCALE_MASK, -+ HDMI_CSC_SCALE); -+} -+ -+static void hdmi_video_csc(struct dw_hdmi *hdmi) -+{ -+ int color_depth = 0; -+ int interpolation = HDMI_CSC_CFG_INTMODE_DISABLE; -+ int decimation = 0; -+ -+ /* YCC422 interpolation to 444 mode */ -+ if (is_color_space_interpolation(hdmi)) -+ interpolation = HDMI_CSC_CFG_INTMODE_CHROMA_INT_FORMULA1; -+ else if (is_color_space_decimation(hdmi)) -+ decimation = HDMI_CSC_CFG_DECMODE_CHROMA_INT_FORMULA3; -+ -+ if (hdmi->hdmi_data.enc_color_depth == 8) -+ color_depth = HDMI_CSC_SCALE_CSC_COLORDE_PTH_24BPP; -+ else if (hdmi->hdmi_data.enc_color_depth == 10) -+ color_depth = HDMI_CSC_SCALE_CSC_COLORDE_PTH_30BPP; -+ else if (hdmi->hdmi_data.enc_color_depth == 12) -+ color_depth = HDMI_CSC_SCALE_CSC_COLORDE_PTH_36BPP; -+ else if (hdmi->hdmi_data.enc_color_depth == 16) -+ color_depth = HDMI_CSC_SCALE_CSC_COLORDE_PTH_48BPP; -+ else -+ return; -+ -+ /* Configure the CSC registers */ -+ hdmi_writeb(hdmi, interpolation | decimation, HDMI_CSC_CFG); -+ hdmi_modb(hdmi, color_depth, HDMI_CSC_SCALE_CSC_COLORDE_PTH_MASK, -+ HDMI_CSC_SCALE); -+ -+ dw_hdmi_update_csc_coeffs(hdmi); -+} -+ -+/* -+ * HDMI video packetizer is used to packetize the data. -+ * for example, if input is YCC422 mode or repeater is used, -+ * data should be repacked this module can be bypassed. -+ */ -+static void hdmi_video_packetize(struct dw_hdmi *hdmi) -+{ -+ unsigned int color_depth = 0; -+ unsigned int remap_size = HDMI_VP_REMAP_YCC422_16bit; -+ unsigned int output_select = HDMI_VP_CONF_OUTPUT_SELECTOR_PP; -+ struct hdmi_data_info *hdmi_data = &hdmi->hdmi_data; -+ u8 val, vp_conf; -+ -+ if (hdmi_data->enc_out_format == RGB || -+ hdmi_data->enc_out_format == YCBCR444) { -+ if (!hdmi_data->enc_color_depth) { -+ output_select = HDMI_VP_CONF_OUTPUT_SELECTOR_BYPASS; -+ } else if (hdmi_data->enc_color_depth == 8) { -+ color_depth = 4; -+ output_select = HDMI_VP_CONF_OUTPUT_SELECTOR_BYPASS; -+ } else if (hdmi_data->enc_color_depth == 10) { -+ color_depth = 5; -+ } else if (hdmi_data->enc_color_depth == 12) { -+ color_depth = 6; -+ } else if (hdmi_data->enc_color_depth == 16) { -+ color_depth = 7; -+ } else { -+ return; -+ } -+ } else if (hdmi_data->enc_out_format == YCBCR422_8BITS) { -+ if (!hdmi_data->enc_color_depth || -+ hdmi_data->enc_color_depth == 8) -+ remap_size = HDMI_VP_REMAP_YCC422_16bit; -+ else if (hdmi_data->enc_color_depth == 10) -+ remap_size = HDMI_VP_REMAP_YCC422_20bit; -+ else if (hdmi_data->enc_color_depth == 12) -+ remap_size = HDMI_VP_REMAP_YCC422_24bit; -+ else -+ return; -+ output_select = HDMI_VP_CONF_OUTPUT_SELECTOR_YCC422; -+ } else { -+ return; -+ } -+ -+ /* set the packetizer registers */ -+ val = ((color_depth << HDMI_VP_PR_CD_COLOR_DEPTH_OFFSET) & -+ HDMI_VP_PR_CD_COLOR_DEPTH_MASK) | -+ ((hdmi_data->pix_repet_factor << -+ HDMI_VP_PR_CD_DESIRED_PR_FACTOR_OFFSET) & -+ HDMI_VP_PR_CD_DESIRED_PR_FACTOR_MASK); -+ hdmi_writeb(hdmi, val, HDMI_VP_PR_CD); -+ -+ hdmi_modb(hdmi, HDMI_VP_STUFF_PR_STUFFING_STUFFING_MODE, -+ HDMI_VP_STUFF_PR_STUFFING_MASK, HDMI_VP_STUFF); -+ -+ /* Data from pixel repeater block */ -+ if (hdmi_data->pix_repet_factor > 1) { -+ vp_conf = HDMI_VP_CONF_PR_EN_ENABLE | -+ HDMI_VP_CONF_BYPASS_SELECT_PIX_REPEATER; -+ } else { /* data from packetizer block */ -+ vp_conf = HDMI_VP_CONF_PR_EN_DISABLE | -+ HDMI_VP_CONF_BYPASS_SELECT_VID_PACKETIZER; -+ } -+ -+ hdmi_modb(hdmi, vp_conf, -+ HDMI_VP_CONF_PR_EN_MASK | -+ HDMI_VP_CONF_BYPASS_SELECT_MASK, HDMI_VP_CONF); -+ -+ hdmi_modb(hdmi, 1 << HDMI_VP_STUFF_IDEFAULT_PHASE_OFFSET, -+ HDMI_VP_STUFF_IDEFAULT_PHASE_MASK, HDMI_VP_STUFF); -+ -+ hdmi_writeb(hdmi, remap_size, HDMI_VP_REMAP); -+ -+ if (output_select == HDMI_VP_CONF_OUTPUT_SELECTOR_PP) { -+ vp_conf = HDMI_VP_CONF_BYPASS_EN_DISABLE | -+ HDMI_VP_CONF_PP_EN_ENABLE | -+ HDMI_VP_CONF_YCC422_EN_DISABLE; -+ } else if (output_select == HDMI_VP_CONF_OUTPUT_SELECTOR_YCC422) { -+ vp_conf = HDMI_VP_CONF_BYPASS_EN_DISABLE | -+ HDMI_VP_CONF_PP_EN_DISABLE | -+ HDMI_VP_CONF_YCC422_EN_ENABLE; -+ } else if (output_select == HDMI_VP_CONF_OUTPUT_SELECTOR_BYPASS) { -+ vp_conf = HDMI_VP_CONF_BYPASS_EN_ENABLE | -+ HDMI_VP_CONF_PP_EN_DISABLE | -+ HDMI_VP_CONF_YCC422_EN_DISABLE; -+ } else { -+ return; -+ } -+ -+ hdmi_modb(hdmi, vp_conf, -+ HDMI_VP_CONF_BYPASS_EN_MASK | HDMI_VP_CONF_PP_EN_ENMASK | -+ HDMI_VP_CONF_YCC422_EN_MASK, HDMI_VP_CONF); -+ -+ hdmi_modb(hdmi, HDMI_VP_STUFF_PP_STUFFING_STUFFING_MODE | -+ HDMI_VP_STUFF_YCC422_STUFFING_STUFFING_MODE, -+ HDMI_VP_STUFF_PP_STUFFING_MASK | -+ HDMI_VP_STUFF_YCC422_STUFFING_MASK, HDMI_VP_STUFF); -+ -+ hdmi_modb(hdmi, output_select, HDMI_VP_CONF_OUTPUT_SELECTOR_MASK, -+ HDMI_VP_CONF); -+} -+ -+/* ----------------------------------------------------------------------------- -+ * Synopsys PHY Handling -+ */ -+ -+static inline void hdmi_phy_test_clear(struct dw_hdmi *hdmi, -+ unsigned char bit) -+{ -+ hdmi_modb(hdmi, bit << HDMI_PHY_TST0_TSTCLR_OFFSET, -+ HDMI_PHY_TST0_TSTCLR_MASK, HDMI_PHY_TST0); -+} -+ -+static bool hdmi_phy_wait_i2c_done(struct dw_hdmi *hdmi, int msec) -+{ -+ u32 val; -+ -+ while ((val = hdmi_readb(hdmi, HDMI_IH_I2CMPHY_STAT0) & 0x3) == 0) { -+ if (msec-- == 0) -+ return false; -+ udelay(1000); -+ } -+ hdmi_writeb(hdmi, val, HDMI_IH_I2CMPHY_STAT0); -+ -+ return true; -+} -+ -+void dw_hdmi_phy_i2c_write(struct dw_hdmi *hdmi, unsigned short data, -+ unsigned char addr) -+{ -+ hdmi_writeb(hdmi, 0xFF, HDMI_IH_I2CMPHY_STAT0); -+ hdmi_writeb(hdmi, addr, HDMI_PHY_I2CM_ADDRESS_ADDR); -+ hdmi_writeb(hdmi, (unsigned char)(data >> 8), -+ HDMI_PHY_I2CM_DATAO_1_ADDR); -+ hdmi_writeb(hdmi, (unsigned char)(data >> 0), -+ HDMI_PHY_I2CM_DATAO_0_ADDR); -+ hdmi_writeb(hdmi, HDMI_PHY_I2CM_OPERATION_ADDR_WRITE, -+ HDMI_PHY_I2CM_OPERATION_ADDR); -+ hdmi_phy_wait_i2c_done(hdmi, 1000); -+} -+EXPORT_SYMBOL_GPL(dw_hdmi_phy_i2c_write); -+ -+static void dw_hdmi_phy_enable_powerdown(struct dw_hdmi *hdmi, bool enable) -+{ -+ hdmi_mask_writeb(hdmi, !enable, HDMI_PHY_CONF0, -+ HDMI_PHY_CONF0_PDZ_OFFSET, -+ HDMI_PHY_CONF0_PDZ_MASK); -+} -+ -+static void dw_hdmi_phy_enable_tmds(struct dw_hdmi *hdmi, u8 enable) -+{ -+ hdmi_mask_writeb(hdmi, enable, HDMI_PHY_CONF0, -+ HDMI_PHY_CONF0_ENTMDS_OFFSET, -+ HDMI_PHY_CONF0_ENTMDS_MASK); -+} -+ -+static void dw_hdmi_phy_enable_svsret(struct dw_hdmi *hdmi, u8 enable) -+{ -+ hdmi_mask_writeb(hdmi, enable, HDMI_PHY_CONF0, -+ HDMI_PHY_CONF0_SVSRET_OFFSET, -+ HDMI_PHY_CONF0_SVSRET_MASK); -+} -+ -+static void dw_hdmi_phy_gen2_pddq(struct dw_hdmi *hdmi, u8 enable) -+{ -+ hdmi_mask_writeb(hdmi, enable, HDMI_PHY_CONF0, -+ HDMI_PHY_CONF0_GEN2_PDDQ_OFFSET, -+ HDMI_PHY_CONF0_GEN2_PDDQ_MASK); -+} -+ -+static void dw_hdmi_phy_gen2_txpwron(struct dw_hdmi *hdmi, u8 enable) -+{ -+ hdmi_mask_writeb(hdmi, enable, HDMI_PHY_CONF0, -+ HDMI_PHY_CONF0_GEN2_TXPWRON_OFFSET, -+ HDMI_PHY_CONF0_GEN2_TXPWRON_MASK); -+} -+ -+static void dw_hdmi_phy_sel_data_en_pol(struct dw_hdmi *hdmi, u8 enable) -+{ -+ hdmi_mask_writeb(hdmi, enable, HDMI_PHY_CONF0, -+ HDMI_PHY_CONF0_SELDATAENPOL_OFFSET, -+ HDMI_PHY_CONF0_SELDATAENPOL_MASK); -+} -+ -+static void dw_hdmi_phy_sel_interface_control(struct dw_hdmi *hdmi, u8 enable) -+{ -+ hdmi_mask_writeb(hdmi, enable, HDMI_PHY_CONF0, -+ HDMI_PHY_CONF0_SELDIPIF_OFFSET, -+ HDMI_PHY_CONF0_SELDIPIF_MASK); -+} -+ -+static void dw_hdmi_phy_power_off(struct dw_hdmi *hdmi) -+{ -+ const struct dw_hdmi_phy_data *phy = hdmi->phy.data; -+ unsigned int i; -+ u16 val; -+ -+ if (phy->gen == 1) { -+ dw_hdmi_phy_enable_tmds(hdmi, 0); -+ dw_hdmi_phy_enable_powerdown(hdmi, true); -+ return; -+ } -+ -+ dw_hdmi_phy_gen2_txpwron(hdmi, 0); -+ -+ /* -+ * Wait for TX_PHY_LOCK to be deasserted to indicate that the PHY went -+ * to low power mode. -+ */ -+ for (i = 0; i < 5; ++i) { -+ val = hdmi_readb(hdmi, HDMI_PHY_STAT0); -+ if (!(val & HDMI_PHY_TX_PHY_LOCK)) -+ break; -+ -+ usleep_range(1000, 2000); -+ } -+ -+ if (val & HDMI_PHY_TX_PHY_LOCK) -+ dev_warn(hdmi->dev, "PHY failed to power down\n"); -+ else -+ dev_dbg(hdmi->dev, "PHY powered down in %u iterations\n", i); -+ -+ dw_hdmi_phy_gen2_pddq(hdmi, 1); -+} -+ -+static int dw_hdmi_phy_power_on(struct dw_hdmi *hdmi) -+{ -+ const struct dw_hdmi_phy_data *phy = hdmi->phy.data; -+ unsigned int i; -+ u8 val; -+ -+ if (phy->gen == 1) { -+ dw_hdmi_phy_enable_powerdown(hdmi, false); -+ -+ /* Toggle TMDS enable. */ -+ dw_hdmi_phy_enable_tmds(hdmi, 0); -+ dw_hdmi_phy_enable_tmds(hdmi, 1); -+ return 0; -+ } -+ -+ dw_hdmi_phy_gen2_txpwron(hdmi, 1); -+ dw_hdmi_phy_gen2_pddq(hdmi, 0); -+ -+ /* Wait for PHY PLL lock */ -+ for (i = 0; i < 5; ++i) { -+ val = hdmi_readb(hdmi, HDMI_PHY_STAT0) & HDMI_PHY_TX_PHY_LOCK; -+ if (val) -+ break; -+ -+ usleep_range(1000, 2000); -+ } -+ -+ if (!val) { -+ dev_err(hdmi->dev, "PHY PLL failed to lock\n"); -+ return -ETIMEDOUT; -+ } -+ -+ dev_dbg(hdmi->dev, "PHY PLL locked %u iterations\n", i); -+ return 0; -+} -+ -+/* -+ * PHY configuration function for the DWC HDMI 3D TX PHY. Based on the available -+ * information the DWC MHL PHY has the same register layout and is thus also -+ * supported by this function. -+ */ -+static int hdmi_phy_configure_dwc_hdmi_3d_tx(struct dw_hdmi *hdmi, -+ const struct dw_hdmi_plat_data *pdata, -+ unsigned long mpixelclock) -+{ -+ const struct dw_hdmi_mpll_config *mpll_config = pdata->mpll_cfg; -+ const struct dw_hdmi_curr_ctrl *curr_ctrl = pdata->cur_ctr; -+ const struct dw_hdmi_phy_config *phy_config = pdata->phy_config; -+ -+ /* PLL/MPLL Cfg - always match on final entry */ -+ for (; mpll_config->mpixelclock != ~0UL; mpll_config++) -+ if (mpixelclock <= mpll_config->mpixelclock) -+ break; -+ -+ for (; curr_ctrl->mpixelclock != ~0UL; curr_ctrl++) -+ if (mpixelclock <= curr_ctrl->mpixelclock) -+ break; -+ -+ for (; phy_config->mpixelclock != ~0UL; phy_config++) -+ if (mpixelclock <= phy_config->mpixelclock) -+ break; -+ -+ if (mpll_config->mpixelclock == ~0UL || -+ curr_ctrl->mpixelclock == ~0UL || -+ phy_config->mpixelclock == ~0UL) -+ return -EINVAL; -+ -+ dw_hdmi_phy_i2c_write(hdmi, mpll_config->res[0].cpce, -+ HDMI_3D_TX_PHY_CPCE_CTRL); -+ dw_hdmi_phy_i2c_write(hdmi, mpll_config->res[0].gmp, -+ HDMI_3D_TX_PHY_GMPCTRL); -+ dw_hdmi_phy_i2c_write(hdmi, curr_ctrl->curr[0], -+ HDMI_3D_TX_PHY_CURRCTRL); -+ -+ dw_hdmi_phy_i2c_write(hdmi, 0, HDMI_3D_TX_PHY_PLLPHBYCTRL); -+ dw_hdmi_phy_i2c_write(hdmi, HDMI_3D_TX_PHY_MSM_CTRL_CKO_SEL_FB_CLK, -+ HDMI_3D_TX_PHY_MSM_CTRL); -+ -+ dw_hdmi_phy_i2c_write(hdmi, phy_config->term, HDMI_3D_TX_PHY_TXTERM); -+ dw_hdmi_phy_i2c_write(hdmi, phy_config->sym_ctr, -+ HDMI_3D_TX_PHY_CKSYMTXCTRL); -+ dw_hdmi_phy_i2c_write(hdmi, phy_config->vlev_ctr, -+ HDMI_3D_TX_PHY_VLEVCTRL); -+ -+ /* Override and disable clock termination. */ -+ dw_hdmi_phy_i2c_write(hdmi, HDMI_3D_TX_PHY_CKCALCTRL_OVERRIDE, -+ HDMI_3D_TX_PHY_CKCALCTRL); -+ -+ return 0; -+} -+ -+static int hdmi_phy_configure(struct dw_hdmi *hdmi) -+{ -+ const struct dw_hdmi_phy_data *phy = hdmi->phy.data; -+ const struct dw_hdmi_plat_data *pdata = hdmi->plat_data; -+ unsigned long mpixelclock = hdmi->hdmi_data.video_mode.mpixelclock; -+ int ret; -+ -+ dw_hdmi_phy_power_off(hdmi); -+ -+ /* Leave low power consumption mode by asserting SVSRET. */ -+ if (phy->has_svsret) -+ dw_hdmi_phy_enable_svsret(hdmi, 1); -+ -+ /* PHY reset. The reset signal is active high on Gen2 PHYs. */ -+ hdmi_writeb(hdmi, HDMI_MC_PHYRSTZ_PHYRSTZ, HDMI_MC_PHYRSTZ); -+ hdmi_writeb(hdmi, 0, HDMI_MC_PHYRSTZ); -+ -+ hdmi_writeb(hdmi, HDMI_MC_HEACPHY_RST_ASSERT, HDMI_MC_HEACPHY_RST); -+ -+ hdmi_phy_test_clear(hdmi, 1); -+ hdmi_writeb(hdmi, HDMI_PHY_I2CM_SLAVE_ADDR_PHY_GEN2, -+ HDMI_PHY_I2CM_SLAVE_ADDR); -+ hdmi_phy_test_clear(hdmi, 0); -+ -+ /* Write to the PHY as configured by the platform */ -+ if (pdata->configure_phy) -+ ret = pdata->configure_phy(hdmi, pdata, mpixelclock); -+ else -+ ret = phy->configure(hdmi, pdata, mpixelclock); -+ if (ret) { -+ dev_err(hdmi->dev, "PHY configuration failed (clock %lu)\n", -+ mpixelclock); -+ return ret; -+ } -+ -+ return dw_hdmi_phy_power_on(hdmi); -+} -+ -+static int dw_hdmi_phy_init(struct dw_hdmi *hdmi, void *data, -+ struct drm_display_mode *mode) -+{ -+ int i, ret; -+ -+ /* HDMI Phy spec says to do the phy initialization sequence twice */ -+ for (i = 0; i < 2; i++) { -+ dw_hdmi_phy_sel_data_en_pol(hdmi, 1); -+ dw_hdmi_phy_sel_interface_control(hdmi, 0); -+ -+ ret = hdmi_phy_configure(hdmi); -+ if (ret) -+ return ret; -+ } -+ -+ return 0; -+} -+ -+static void dw_hdmi_phy_disable(struct dw_hdmi *hdmi, void *data) -+{ -+ dw_hdmi_phy_power_off(hdmi); -+} -+ -+static enum drm_connector_status dw_hdmi_phy_read_hpd(struct dw_hdmi *hdmi, -+ void *data) -+{ -+ return hdmi_readb(hdmi, HDMI_PHY_STAT0) & HDMI_PHY_HPD ? -+ connector_status_connected : connector_status_disconnected; -+} -+ -+static const struct dw_hdmi_phy_ops dw_hdmi_synopsys_phy_ops = { -+ .init = dw_hdmi_phy_init, -+ .disable = dw_hdmi_phy_disable, -+ .read_hpd = dw_hdmi_phy_read_hpd, -+}; -+ -+/* ----------------------------------------------------------------------------- -+ * HDMI TX Setup -+ */ -+ -+static void hdmi_tx_hdcp_config(struct dw_hdmi *hdmi) -+{ -+ u8 de; -+ -+ if (hdmi->hdmi_data.video_mode.mdataenablepolarity) -+ de = HDMI_A_VIDPOLCFG_DATAENPOL_ACTIVE_HIGH; -+ else -+ de = HDMI_A_VIDPOLCFG_DATAENPOL_ACTIVE_LOW; -+ -+ /* disable rx detect */ -+ hdmi_modb(hdmi, HDMI_A_HDCPCFG0_RXDETECT_DISABLE, -+ HDMI_A_HDCPCFG0_RXDETECT_MASK, HDMI_A_HDCPCFG0); -+ -+ hdmi_modb(hdmi, de, HDMI_A_VIDPOLCFG_DATAENPOL_MASK, HDMI_A_VIDPOLCFG); -+ -+ hdmi_modb(hdmi, HDMI_A_HDCPCFG1_ENCRYPTIONDISABLE_DISABLE, -+ HDMI_A_HDCPCFG1_ENCRYPTIONDISABLE_MASK, HDMI_A_HDCPCFG1); -+} -+ -+static void hdmi_config_AVI(struct dw_hdmi *hdmi, struct drm_display_mode *mode) -+{ -+ struct hdmi_avi_infoframe frame; -+ u8 val; -+ -+ /* Initialise info frame from DRM mode */ -+ drm_hdmi_avi_infoframe_from_display_mode(&frame, mode); -+ -+ if (hdmi->hdmi_data.enc_out_format == YCBCR444) -+ frame.colorspace = HDMI_COLORSPACE_YUV444; -+ else if (hdmi->hdmi_data.enc_out_format == YCBCR422_8BITS) -+ frame.colorspace = HDMI_COLORSPACE_YUV422; -+ else -+ frame.colorspace = HDMI_COLORSPACE_RGB; -+ -+ /* Set up colorimetry */ -+ if (hdmi->hdmi_data.enc_out_format == XVYCC444) { -+ frame.colorimetry = HDMI_COLORIMETRY_EXTENDED; -+ if (hdmi->hdmi_data.colorimetry == HDMI_COLORIMETRY_ITU_601) -+ frame.extended_colorimetry = -+ HDMI_EXTENDED_COLORIMETRY_XV_YCC_601; -+ else /*hdmi->hdmi_data.colorimetry == HDMI_COLORIMETRY_ITU_709*/ -+ frame.extended_colorimetry = -+ HDMI_EXTENDED_COLORIMETRY_XV_YCC_709; -+ } else if (hdmi->hdmi_data.enc_out_format != RGB) { -+ frame.colorimetry = hdmi->hdmi_data.colorimetry; -+ frame.extended_colorimetry = HDMI_EXTENDED_COLORIMETRY_XV_YCC_601; -+ } else { /* Carries no data */ -+ frame.colorimetry = HDMI_COLORIMETRY_NONE; -+ frame.extended_colorimetry = HDMI_EXTENDED_COLORIMETRY_XV_YCC_601; -+ } -+ -+ frame.scan_mode = HDMI_SCAN_MODE_NONE; -+ -+ /* -+ * The Designware IP uses a different byte format from standard -+ * AVI info frames, though generally the bits are in the correct -+ * bytes. -+ */ -+ -+ /* -+ * AVI data byte 1 differences: Colorspace in bits 0,1 rather than 5,6, -+ * scan info in bits 4,5 rather than 0,1 and active aspect present in -+ * bit 6 rather than 4. -+ */ -+ val = (frame.scan_mode & 3) << 4 | (frame.colorspace & 3); -+ if (frame.active_aspect & 15) -+ val |= HDMI_FC_AVICONF0_ACTIVE_FMT_INFO_PRESENT; -+ if (frame.top_bar || frame.bottom_bar) -+ val |= HDMI_FC_AVICONF0_BAR_DATA_HORIZ_BAR; -+ if (frame.left_bar || frame.right_bar) -+ val |= HDMI_FC_AVICONF0_BAR_DATA_VERT_BAR; -+ hdmi_writeb(hdmi, val, HDMI_FC_AVICONF0); -+ -+ /* AVI data byte 2 differences: none */ -+ val = ((frame.colorimetry & 0x3) << 6) | -+ ((frame.picture_aspect & 0x3) << 4) | -+ (frame.active_aspect & 0xf); -+ hdmi_writeb(hdmi, val, HDMI_FC_AVICONF1); -+ -+ /* AVI data byte 3 differences: none */ -+ val = ((frame.extended_colorimetry & 0x7) << 4) | -+ ((frame.quantization_range & 0x3) << 2) | -+ (frame.nups & 0x3); -+ if (frame.itc) -+ val |= HDMI_FC_AVICONF2_IT_CONTENT_VALID; -+ hdmi_writeb(hdmi, val, HDMI_FC_AVICONF2); -+ -+ /* AVI data byte 4 differences: none */ -+ val = frame.video_code & 0x7f; -+ hdmi_writeb(hdmi, val, HDMI_FC_AVIVID); -+ -+ /* AVI Data Byte 5- set up input and output pixel repetition */ -+ val = (((hdmi->hdmi_data.video_mode.mpixelrepetitioninput + 1) << -+ HDMI_FC_PRCONF_INCOMING_PR_FACTOR_OFFSET) & -+ HDMI_FC_PRCONF_INCOMING_PR_FACTOR_MASK) | -+ ((hdmi->hdmi_data.video_mode.mpixelrepetitionoutput << -+ HDMI_FC_PRCONF_OUTPUT_PR_FACTOR_OFFSET) & -+ HDMI_FC_PRCONF_OUTPUT_PR_FACTOR_MASK); -+ hdmi_writeb(hdmi, val, HDMI_FC_PRCONF); -+ -+ /* -+ * AVI data byte 5 differences: content type in 0,1 rather than 4,5, -+ * ycc range in bits 2,3 rather than 6,7 -+ */ -+ val = ((frame.ycc_quantization_range & 0x3) << 2) | -+ (frame.content_type & 0x3); -+ hdmi_writeb(hdmi, val, HDMI_FC_AVICONF3); -+ -+ /* AVI Data Bytes 6-13 */ -+ hdmi_writeb(hdmi, frame.top_bar & 0xff, HDMI_FC_AVIETB0); -+ hdmi_writeb(hdmi, (frame.top_bar >> 8) & 0xff, HDMI_FC_AVIETB1); -+ hdmi_writeb(hdmi, frame.bottom_bar & 0xff, HDMI_FC_AVISBB0); -+ hdmi_writeb(hdmi, (frame.bottom_bar >> 8) & 0xff, HDMI_FC_AVISBB1); -+ hdmi_writeb(hdmi, frame.left_bar & 0xff, HDMI_FC_AVIELB0); -+ hdmi_writeb(hdmi, (frame.left_bar >> 8) & 0xff, HDMI_FC_AVIELB1); -+ hdmi_writeb(hdmi, frame.right_bar & 0xff, HDMI_FC_AVISRB0); -+ hdmi_writeb(hdmi, (frame.right_bar >> 8) & 0xff, HDMI_FC_AVISRB1); -+} -+ -+static void hdmi_av_composer(struct dw_hdmi *hdmi, -+ const struct drm_display_mode *mode) -+{ -+ u8 inv_val; -+ struct hdmi_vmode *vmode = &hdmi->hdmi_data.video_mode; -+ int hblank, vblank, h_de_hs, v_de_vs, hsync_len, vsync_len; -+ unsigned int vdisplay; -+ -+ vmode->mpixelclock = mode->clock * 1000; -+ -+ dev_dbg(hdmi->dev, "final pixclk = %d\n", vmode->mpixelclock); -+ -+ /* Set up HDMI_FC_INVIDCONF */ -+ inv_val = (hdmi->hdmi_data.hdcp_enable ? -+ HDMI_FC_INVIDCONF_HDCP_KEEPOUT_ACTIVE : -+ HDMI_FC_INVIDCONF_HDCP_KEEPOUT_INACTIVE); -+ -+ inv_val |= mode->flags & DRM_MODE_FLAG_PVSYNC ? -+ HDMI_FC_INVIDCONF_VSYNC_IN_POLARITY_ACTIVE_HIGH : -+ HDMI_FC_INVIDCONF_VSYNC_IN_POLARITY_ACTIVE_LOW; -+ -+ inv_val |= mode->flags & DRM_MODE_FLAG_PHSYNC ? -+ HDMI_FC_INVIDCONF_HSYNC_IN_POLARITY_ACTIVE_HIGH : -+ HDMI_FC_INVIDCONF_HSYNC_IN_POLARITY_ACTIVE_LOW; -+ -+ inv_val |= (vmode->mdataenablepolarity ? -+ HDMI_FC_INVIDCONF_DE_IN_POLARITY_ACTIVE_HIGH : -+ HDMI_FC_INVIDCONF_DE_IN_POLARITY_ACTIVE_LOW); -+ -+ if (hdmi->vic == 39) -+ inv_val |= HDMI_FC_INVIDCONF_R_V_BLANK_IN_OSC_ACTIVE_HIGH; -+ else -+ inv_val |= mode->flags & DRM_MODE_FLAG_INTERLACE ? -+ HDMI_FC_INVIDCONF_R_V_BLANK_IN_OSC_ACTIVE_HIGH : -+ HDMI_FC_INVIDCONF_R_V_BLANK_IN_OSC_ACTIVE_LOW; -+ -+ inv_val |= mode->flags & DRM_MODE_FLAG_INTERLACE ? -+ HDMI_FC_INVIDCONF_IN_I_P_INTERLACED : -+ HDMI_FC_INVIDCONF_IN_I_P_PROGRESSIVE; -+ -+ inv_val |= hdmi->sink_is_hdmi ? -+ HDMI_FC_INVIDCONF_DVI_MODEZ_HDMI_MODE : -+ HDMI_FC_INVIDCONF_DVI_MODEZ_DVI_MODE; -+ -+ hdmi_writeb(hdmi, inv_val, HDMI_FC_INVIDCONF); -+ -+ vdisplay = mode->vdisplay; -+ vblank = mode->vtotal - mode->vdisplay; -+ v_de_vs = mode->vsync_start - mode->vdisplay; -+ vsync_len = mode->vsync_end - mode->vsync_start; -+ -+ /* -+ * When we're setting an interlaced mode, we need -+ * to adjust the vertical timing to suit. -+ */ -+ if (mode->flags & DRM_MODE_FLAG_INTERLACE) { -+ vdisplay /= 2; -+ vblank /= 2; -+ v_de_vs /= 2; -+ vsync_len /= 2; -+ } -+ -+ /* Set up horizontal active pixel width */ -+ hdmi_writeb(hdmi, mode->hdisplay >> 8, HDMI_FC_INHACTV1); -+ hdmi_writeb(hdmi, mode->hdisplay, HDMI_FC_INHACTV0); -+ -+ /* Set up vertical active lines */ -+ hdmi_writeb(hdmi, vdisplay >> 8, HDMI_FC_INVACTV1); -+ hdmi_writeb(hdmi, vdisplay, HDMI_FC_INVACTV0); -+ -+ /* Set up horizontal blanking pixel region width */ -+ hblank = mode->htotal - mode->hdisplay; -+ hdmi_writeb(hdmi, hblank >> 8, HDMI_FC_INHBLANK1); -+ hdmi_writeb(hdmi, hblank, HDMI_FC_INHBLANK0); -+ -+ /* Set up vertical blanking pixel region width */ -+ hdmi_writeb(hdmi, vblank, HDMI_FC_INVBLANK); -+ -+ /* Set up HSYNC active edge delay width (in pixel clks) */ -+ h_de_hs = mode->hsync_start - mode->hdisplay; -+ hdmi_writeb(hdmi, h_de_hs >> 8, HDMI_FC_HSYNCINDELAY1); -+ hdmi_writeb(hdmi, h_de_hs, HDMI_FC_HSYNCINDELAY0); -+ -+ /* Set up VSYNC active edge delay (in lines) */ -+ hdmi_writeb(hdmi, v_de_vs, HDMI_FC_VSYNCINDELAY); -+ -+ /* Set up HSYNC active pulse width (in pixel clks) */ -+ hsync_len = mode->hsync_end - mode->hsync_start; -+ hdmi_writeb(hdmi, hsync_len >> 8, HDMI_FC_HSYNCINWIDTH1); -+ hdmi_writeb(hdmi, hsync_len, HDMI_FC_HSYNCINWIDTH0); -+ -+ /* Set up VSYNC active edge delay (in lines) */ -+ hdmi_writeb(hdmi, vsync_len, HDMI_FC_VSYNCINWIDTH); -+} -+ -+/* HDMI Initialization Step B.4 */ -+static void dw_hdmi_enable_video_path(struct dw_hdmi *hdmi) -+{ -+ u8 clkdis; -+ -+ /* control period minimum duration */ -+ hdmi_writeb(hdmi, 12, HDMI_FC_CTRLDUR); -+ hdmi_writeb(hdmi, 32, HDMI_FC_EXCTRLDUR); -+ hdmi_writeb(hdmi, 1, HDMI_FC_EXCTRLSPAC); -+ -+ /* Set to fill TMDS data channels */ -+ hdmi_writeb(hdmi, 0x0B, HDMI_FC_CH0PREAM); -+ hdmi_writeb(hdmi, 0x16, HDMI_FC_CH1PREAM); -+ hdmi_writeb(hdmi, 0x21, HDMI_FC_CH2PREAM); -+ -+ /* Enable pixel clock and tmds data path */ -+ clkdis = 0x7F; -+ clkdis &= ~HDMI_MC_CLKDIS_PIXELCLK_DISABLE; -+ hdmi_writeb(hdmi, clkdis, HDMI_MC_CLKDIS); -+ -+ clkdis &= ~HDMI_MC_CLKDIS_TMDSCLK_DISABLE; -+ hdmi_writeb(hdmi, clkdis, HDMI_MC_CLKDIS); -+ -+ /* Enable csc path */ -+ if (is_color_space_conversion(hdmi)) { -+ clkdis &= ~HDMI_MC_CLKDIS_CSCCLK_DISABLE; -+ hdmi_writeb(hdmi, clkdis, HDMI_MC_CLKDIS); -+ } -+ -+ /* Enable color space conversion if needed */ -+ if (is_color_space_conversion(hdmi)) -+ hdmi_writeb(hdmi, HDMI_MC_FLOWCTRL_FEED_THROUGH_OFF_CSC_IN_PATH, -+ HDMI_MC_FLOWCTRL); -+ else -+ hdmi_writeb(hdmi, HDMI_MC_FLOWCTRL_FEED_THROUGH_OFF_CSC_BYPASS, -+ HDMI_MC_FLOWCTRL); -+} -+ -+static void hdmi_enable_audio_clk(struct dw_hdmi *hdmi) -+{ -+ hdmi_modb(hdmi, 0, HDMI_MC_CLKDIS_AUDCLK_DISABLE, HDMI_MC_CLKDIS); -+} -+ -+/* Workaround to clear the overflow condition */ -+static void dw_hdmi_clear_overflow(struct dw_hdmi *hdmi) -+{ -+ unsigned int count; -+ unsigned int i; -+ u8 val; -+ -+ /* -+ * Under some circumstances the Frame Composer arithmetic unit can miss -+ * an FC register write due to being busy processing the previous one. -+ * The issue can be worked around by issuing a TMDS software reset and -+ * then write one of the FC registers several times. -+ * -+ * The number of iterations matters and depends on the HDMI TX revision -+ * (and possibly on the platform). So far only i.MX6Q (v1.30a) and -+ * i.MX6DL (v1.31a) have been identified as needing the workaround, with -+ * 4 and 1 iterations respectively. -+ */ -+ -+ switch (hdmi->version) { -+ case 0x130a: -+ count = 4; -+ break; -+ case 0x131a: -+ count = 1; -+ break; -+ default: -+ return; -+ } -+ -+ /* TMDS software reset */ -+ hdmi_writeb(hdmi, (u8)~HDMI_MC_SWRSTZ_TMDSSWRST_REQ, HDMI_MC_SWRSTZ); -+ -+ val = hdmi_readb(hdmi, HDMI_FC_INVIDCONF); -+ for (i = 0; i < count; i++) -+ hdmi_writeb(hdmi, val, HDMI_FC_INVIDCONF); -+} -+ -+static void hdmi_enable_overflow_interrupts(struct dw_hdmi *hdmi) -+{ -+ hdmi_writeb(hdmi, 0, HDMI_FC_MASK2); -+ hdmi_writeb(hdmi, 0, HDMI_IH_MUTE_FC_STAT2); -+} -+ -+static void hdmi_disable_overflow_interrupts(struct dw_hdmi *hdmi) -+{ -+ hdmi_writeb(hdmi, HDMI_IH_MUTE_FC_STAT2_OVERFLOW_MASK, -+ HDMI_IH_MUTE_FC_STAT2); -+} -+ -+static int dw_hdmi_setup(struct dw_hdmi *hdmi, struct drm_display_mode *mode) -+{ -+ int ret; -+ -+ hdmi_disable_overflow_interrupts(hdmi); -+ -+ hdmi->vic = drm_match_cea_mode(mode); -+ -+ if (!hdmi->vic) { -+ dev_dbg(hdmi->dev, "Non-CEA mode used in HDMI\n"); -+ } else { -+ dev_dbg(hdmi->dev, "CEA mode used vic=%d\n", hdmi->vic); -+ } -+ -+ if ((hdmi->vic == 6) || (hdmi->vic == 7) || -+ (hdmi->vic == 21) || (hdmi->vic == 22) || -+ (hdmi->vic == 2) || (hdmi->vic == 3) || -+ (hdmi->vic == 17) || (hdmi->vic == 18)) -+ hdmi->hdmi_data.colorimetry = HDMI_COLORIMETRY_ITU_601; -+ else -+ hdmi->hdmi_data.colorimetry = HDMI_COLORIMETRY_ITU_709; -+ -+ hdmi->hdmi_data.video_mode.mpixelrepetitionoutput = 0; -+ hdmi->hdmi_data.video_mode.mpixelrepetitioninput = 0; -+ -+ /* TODO: Get input format from IPU (via FB driver interface) */ -+ hdmi->hdmi_data.enc_in_format = RGB; -+ -+ hdmi->hdmi_data.enc_out_format = RGB; -+ -+ hdmi->hdmi_data.enc_color_depth = 8; -+ hdmi->hdmi_data.pix_repet_factor = 0; -+ hdmi->hdmi_data.hdcp_enable = 0; -+ hdmi->hdmi_data.video_mode.mdataenablepolarity = true; -+ -+ /* HDMI Initialization Step B.1 */ -+ hdmi_av_composer(hdmi, mode); -+ -+ /* HDMI Initializateion Step B.2 */ -+ ret = hdmi->phy.ops->init(hdmi, hdmi->phy.data, &hdmi->previous_mode); -+ if (ret) -+ return ret; -+ hdmi->phy.enabled = true; -+ -+ /* HDMI Initialization Step B.3 */ -+ dw_hdmi_enable_video_path(hdmi); -+ -+ if (hdmi->sink_has_audio) { -+ dev_dbg(hdmi->dev, "sink has audio support\n"); -+ -+ /* HDMI Initialization Step E - Configure audio */ -+ hdmi_clk_regenerator_update_pixel_clock(hdmi); -+ hdmi_enable_audio_clk(hdmi); -+ } -+ -+ /* not for DVI mode */ -+ if (hdmi->sink_is_hdmi) { -+ dev_dbg(hdmi->dev, "%s HDMI mode\n", __func__); -+ -+ /* HDMI Initialization Step F - Configure AVI InfoFrame */ -+ hdmi_config_AVI(hdmi, mode); -+ } else { -+ dev_dbg(hdmi->dev, "%s DVI mode\n", __func__); -+ } -+ -+ hdmi_video_packetize(hdmi); -+ hdmi_video_csc(hdmi); -+ hdmi_video_sample(hdmi); -+ hdmi_tx_hdcp_config(hdmi); -+ -+ dw_hdmi_clear_overflow(hdmi); -+ if (hdmi->cable_plugin && hdmi->sink_is_hdmi) -+ hdmi_enable_overflow_interrupts(hdmi); -+ -+ return 0; -+} -+ -+/* Wait until we are registered to enable interrupts */ -+static int dw_hdmi_fb_registered(struct dw_hdmi *hdmi) -+{ -+ hdmi_writeb(hdmi, HDMI_PHY_I2CM_INT_ADDR_DONE_POL, -+ HDMI_PHY_I2CM_INT_ADDR); -+ -+ hdmi_writeb(hdmi, HDMI_PHY_I2CM_CTLINT_ADDR_NAC_POL | -+ HDMI_PHY_I2CM_CTLINT_ADDR_ARBITRATION_POL, -+ HDMI_PHY_I2CM_CTLINT_ADDR); -+ -+ /* enable cable hot plug irq */ -+ hdmi_writeb(hdmi, hdmi->phy_mask, HDMI_PHY_MASK0); -+ -+ /* Clear Hotplug interrupts */ -+ hdmi_writeb(hdmi, HDMI_IH_PHY_STAT0_HPD | HDMI_IH_PHY_STAT0_RX_SENSE, -+ HDMI_IH_PHY_STAT0); -+ -+ return 0; -+} -+ -+static void initialize_hdmi_ih_mutes(struct dw_hdmi *hdmi) -+{ -+ u8 ih_mute; -+ -+ /* -+ * Boot up defaults are: -+ * HDMI_IH_MUTE = 0x03 (disabled) -+ * HDMI_IH_MUTE_* = 0x00 (enabled) -+ * -+ * Disable top level interrupt bits in HDMI block -+ */ -+ ih_mute = hdmi_readb(hdmi, HDMI_IH_MUTE) | -+ HDMI_IH_MUTE_MUTE_WAKEUP_INTERRUPT | -+ HDMI_IH_MUTE_MUTE_ALL_INTERRUPT; -+ -+ hdmi_writeb(hdmi, ih_mute, HDMI_IH_MUTE); -+ -+ /* by default mask all interrupts */ -+ hdmi_writeb(hdmi, 0xff, HDMI_VP_MASK); -+ hdmi_writeb(hdmi, 0xff, HDMI_FC_MASK0); -+ hdmi_writeb(hdmi, 0xff, HDMI_FC_MASK1); -+ hdmi_writeb(hdmi, 0xff, HDMI_FC_MASK2); -+ hdmi_writeb(hdmi, 0xff, HDMI_PHY_MASK0); -+ hdmi_writeb(hdmi, 0xff, HDMI_PHY_I2CM_INT_ADDR); -+ hdmi_writeb(hdmi, 0xff, HDMI_PHY_I2CM_CTLINT_ADDR); -+ hdmi_writeb(hdmi, 0xff, HDMI_AUD_INT); -+ hdmi_writeb(hdmi, 0xff, HDMI_AUD_SPDIFINT); -+ hdmi_writeb(hdmi, 0xff, HDMI_AUD_HBR_MASK); -+ hdmi_writeb(hdmi, 0xff, HDMI_GP_MASK); -+ hdmi_writeb(hdmi, 0xff, HDMI_A_APIINTMSK); -+ hdmi_writeb(hdmi, 0xff, HDMI_CEC_MASK); -+ hdmi_writeb(hdmi, 0xff, HDMI_I2CM_INT); -+ hdmi_writeb(hdmi, 0xff, HDMI_I2CM_CTLINT); -+ -+ /* Disable interrupts in the IH_MUTE_* registers */ -+ hdmi_writeb(hdmi, 0xff, HDMI_IH_MUTE_FC_STAT0); -+ hdmi_writeb(hdmi, 0xff, HDMI_IH_MUTE_FC_STAT1); -+ hdmi_writeb(hdmi, 0xff, HDMI_IH_MUTE_FC_STAT2); -+ hdmi_writeb(hdmi, 0xff, HDMI_IH_MUTE_AS_STAT0); -+ hdmi_writeb(hdmi, 0xff, HDMI_IH_MUTE_PHY_STAT0); -+ hdmi_writeb(hdmi, 0xff, HDMI_IH_MUTE_I2CM_STAT0); -+ hdmi_writeb(hdmi, 0xff, HDMI_IH_MUTE_CEC_STAT0); -+ hdmi_writeb(hdmi, 0xff, HDMI_IH_MUTE_VP_STAT0); -+ hdmi_writeb(hdmi, 0xff, HDMI_IH_MUTE_I2CMPHY_STAT0); -+ hdmi_writeb(hdmi, 0xff, HDMI_IH_MUTE_AHBDMAAUD_STAT0); -+ -+ /* Enable top level interrupt bits in HDMI block */ -+ ih_mute &= ~(HDMI_IH_MUTE_MUTE_WAKEUP_INTERRUPT | -+ HDMI_IH_MUTE_MUTE_ALL_INTERRUPT); -+ hdmi_writeb(hdmi, ih_mute, HDMI_IH_MUTE); -+} -+ -+static void dw_hdmi_poweron(struct dw_hdmi *hdmi) -+{ -+ hdmi->bridge_is_on = true; -+ dw_hdmi_setup(hdmi, &hdmi->previous_mode); -+} -+ -+static void dw_hdmi_poweroff(struct dw_hdmi *hdmi) -+{ -+ if (hdmi->phy.enabled) { -+ hdmi->phy.ops->disable(hdmi, hdmi->phy.data); -+ hdmi->phy.enabled = false; -+ } -+ -+ hdmi->bridge_is_on = false; -+} -+ -+static void dw_hdmi_update_power(struct dw_hdmi *hdmi) -+{ -+ int force = hdmi->force; -+ -+ if (hdmi->disabled) { -+ force = DRM_FORCE_OFF; -+ } else if (force == DRM_FORCE_UNSPECIFIED) { -+ if (hdmi->rxsense) -+ force = DRM_FORCE_ON; -+ else -+ force = DRM_FORCE_OFF; -+ } -+ -+ if (force == DRM_FORCE_OFF) { -+ if (hdmi->bridge_is_on) -+ dw_hdmi_poweroff(hdmi); -+ } else { -+ if (!hdmi->bridge_is_on) -+ dw_hdmi_poweron(hdmi); -+ } -+} -+ -+/* -+ * Adjust the detection of RXSENSE according to whether we have a forced -+ * connection mode enabled, or whether we have been disabled. There is -+ * no point processing RXSENSE interrupts if we have a forced connection -+ * state, or DRM has us disabled. -+ * -+ * We also disable rxsense interrupts when we think we're disconnected -+ * to avoid floating TDMS signals giving false rxsense interrupts. -+ * -+ * Note: we still need to listen for HPD interrupts even when DRM has us -+ * disabled so that we can detect a connect event. -+ */ -+static void dw_hdmi_update_phy_mask(struct dw_hdmi *hdmi) -+{ -+ u8 old_mask = hdmi->phy_mask; -+ -+ if (hdmi->force || hdmi->disabled || !hdmi->rxsense) -+ hdmi->phy_mask |= HDMI_PHY_RX_SENSE; -+ else -+ hdmi->phy_mask &= ~HDMI_PHY_RX_SENSE; -+ -+ if (old_mask != hdmi->phy_mask) -+ hdmi_writeb(hdmi, hdmi->phy_mask, HDMI_PHY_MASK0); -+} -+ -+static enum drm_connector_status -+dw_hdmi_connector_detect(struct drm_connector *connector, bool force) -+{ -+ struct dw_hdmi *hdmi = container_of(connector, struct dw_hdmi, -+ connector); -+ -+ mutex_lock(&hdmi->mutex); -+ hdmi->force = DRM_FORCE_UNSPECIFIED; -+ dw_hdmi_update_power(hdmi); -+ dw_hdmi_update_phy_mask(hdmi); -+ mutex_unlock(&hdmi->mutex); -+ -+ return hdmi->phy.ops->read_hpd(hdmi, hdmi->phy.data); -+} -+ -+static int dw_hdmi_connector_get_modes(struct drm_connector *connector) -+{ -+ struct dw_hdmi *hdmi = container_of(connector, struct dw_hdmi, -+ connector); -+ struct edid *edid; -+ int ret = 0; -+ -+ if (!hdmi->ddc) -+ return 0; -+ -+ edid = drm_get_edid(connector, hdmi->ddc); -+ if (edid) { -+ dev_dbg(hdmi->dev, "got edid: width[%d] x height[%d]\n", -+ edid->width_cm, edid->height_cm); -+ -+ hdmi->sink_is_hdmi = drm_detect_hdmi_monitor(edid); -+ hdmi->sink_has_audio = drm_detect_monitor_audio(edid); -+ drm_mode_connector_update_edid_property(connector, edid); -+ ret = drm_add_edid_modes(connector, edid); -+ /* Store the ELD */ -+ drm_edid_to_eld(connector, edid); -+ kfree(edid); -+ } else { -+ dev_dbg(hdmi->dev, "failed to get edid\n"); -+ } -+ -+ return ret; -+} -+ -+static enum drm_mode_status -+dw_hdmi_connector_mode_valid(struct drm_connector *connector, -+ struct drm_display_mode *mode) -+{ -+ struct dw_hdmi *hdmi = container_of(connector, -+ struct dw_hdmi, connector); -+ enum drm_mode_status mode_status = MODE_OK; -+ -+ /* We don't support double-clocked modes */ -+ if (mode->flags & DRM_MODE_FLAG_DBLCLK) -+ return MODE_BAD; -+ -+ if (hdmi->plat_data->mode_valid) -+ mode_status = hdmi->plat_data->mode_valid(connector, mode); -+ -+ return mode_status; -+} -+ -+static void dw_hdmi_connector_force(struct drm_connector *connector) -+{ -+ struct dw_hdmi *hdmi = container_of(connector, struct dw_hdmi, -+ connector); -+ -+ mutex_lock(&hdmi->mutex); -+ hdmi->force = connector->force; -+ dw_hdmi_update_power(hdmi); -+ dw_hdmi_update_phy_mask(hdmi); -+ mutex_unlock(&hdmi->mutex); -+} -+ -+static const struct drm_connector_funcs dw_hdmi_connector_funcs = { -+ .dpms = drm_atomic_helper_connector_dpms, -+ .fill_modes = drm_helper_probe_single_connector_modes, -+ .detect = dw_hdmi_connector_detect, -+ .destroy = drm_connector_cleanup, -+ .force = dw_hdmi_connector_force, -+ .reset = drm_atomic_helper_connector_reset, -+ .atomic_duplicate_state = drm_atomic_helper_connector_duplicate_state, -+ .atomic_destroy_state = drm_atomic_helper_connector_destroy_state, -+}; -+ -+static const struct drm_connector_helper_funcs dw_hdmi_connector_helper_funcs = { -+ .get_modes = dw_hdmi_connector_get_modes, -+ .mode_valid = dw_hdmi_connector_mode_valid, -+ .best_encoder = drm_atomic_helper_best_encoder, -+}; -+ -+static int dw_hdmi_bridge_attach(struct drm_bridge *bridge) -+{ -+ struct dw_hdmi *hdmi = bridge->driver_private; -+ struct drm_encoder *encoder = bridge->encoder; -+ struct drm_connector *connector = &hdmi->connector; -+ -+ connector->interlace_allowed = 1; -+ connector->polled = DRM_CONNECTOR_POLL_HPD; -+ -+ drm_connector_helper_add(connector, &dw_hdmi_connector_helper_funcs); -+ -+ drm_connector_init(bridge->dev, connector, &dw_hdmi_connector_funcs, -+ DRM_MODE_CONNECTOR_HDMIA); -+ -+ drm_mode_connector_attach_encoder(connector, encoder); -+ -+ return 0; -+} -+ -+static void dw_hdmi_bridge_mode_set(struct drm_bridge *bridge, -+ struct drm_display_mode *orig_mode, -+ struct drm_display_mode *mode) -+{ -+ struct dw_hdmi *hdmi = bridge->driver_private; -+ -+ mutex_lock(&hdmi->mutex); -+ -+ /* Store the display mode for plugin/DKMS poweron events */ -+ memcpy(&hdmi->previous_mode, mode, sizeof(hdmi->previous_mode)); -+ -+ mutex_unlock(&hdmi->mutex); -+} -+ -+static void dw_hdmi_bridge_disable(struct drm_bridge *bridge) -+{ -+ struct dw_hdmi *hdmi = bridge->driver_private; -+ -+ mutex_lock(&hdmi->mutex); -+ hdmi->disabled = true; -+ dw_hdmi_update_power(hdmi); -+ dw_hdmi_update_phy_mask(hdmi); -+ mutex_unlock(&hdmi->mutex); -+} -+ -+static void dw_hdmi_bridge_enable(struct drm_bridge *bridge) -+{ -+ struct dw_hdmi *hdmi = bridge->driver_private; -+ -+ mutex_lock(&hdmi->mutex); -+ hdmi->disabled = false; -+ dw_hdmi_update_power(hdmi); -+ dw_hdmi_update_phy_mask(hdmi); -+ mutex_unlock(&hdmi->mutex); -+} -+ -+static const struct drm_bridge_funcs dw_hdmi_bridge_funcs = { -+ .attach = dw_hdmi_bridge_attach, -+ .enable = dw_hdmi_bridge_enable, -+ .disable = dw_hdmi_bridge_disable, -+ .mode_set = dw_hdmi_bridge_mode_set, -+}; -+ -+static irqreturn_t dw_hdmi_i2c_irq(struct dw_hdmi *hdmi) -+{ -+ struct dw_hdmi_i2c *i2c = hdmi->i2c; -+ unsigned int stat; -+ -+ stat = hdmi_readb(hdmi, HDMI_IH_I2CM_STAT0); -+ if (!stat) -+ return IRQ_NONE; -+ -+ hdmi_writeb(hdmi, stat, HDMI_IH_I2CM_STAT0); -+ -+ i2c->stat = stat; -+ -+ complete(&i2c->cmp); -+ -+ return IRQ_HANDLED; -+} -+ -+static irqreturn_t dw_hdmi_hardirq(int irq, void *dev_id) -+{ -+ struct dw_hdmi *hdmi = dev_id; -+ u8 intr_stat; -+ irqreturn_t ret = IRQ_NONE; -+ -+ if (hdmi->i2c) -+ ret = dw_hdmi_i2c_irq(hdmi); -+ -+ intr_stat = hdmi_readb(hdmi, HDMI_IH_PHY_STAT0); -+ if (intr_stat) { -+ hdmi_writeb(hdmi, ~0, HDMI_IH_MUTE_PHY_STAT0); -+ return IRQ_WAKE_THREAD; -+ } -+ -+ return ret; -+} -+ -+static irqreturn_t dw_hdmi_irq(int irq, void *dev_id) -+{ -+ struct dw_hdmi *hdmi = dev_id; -+ u8 intr_stat, phy_int_pol, phy_pol_mask, phy_stat; -+ -+ intr_stat = hdmi_readb(hdmi, HDMI_IH_PHY_STAT0); -+ phy_int_pol = hdmi_readb(hdmi, HDMI_PHY_POL0); -+ phy_stat = hdmi_readb(hdmi, HDMI_PHY_STAT0); -+ -+ phy_pol_mask = 0; -+ if (intr_stat & HDMI_IH_PHY_STAT0_HPD) -+ phy_pol_mask |= HDMI_PHY_HPD; -+ if (intr_stat & HDMI_IH_PHY_STAT0_RX_SENSE0) -+ phy_pol_mask |= HDMI_PHY_RX_SENSE0; -+ if (intr_stat & HDMI_IH_PHY_STAT0_RX_SENSE1) -+ phy_pol_mask |= HDMI_PHY_RX_SENSE1; -+ if (intr_stat & HDMI_IH_PHY_STAT0_RX_SENSE2) -+ phy_pol_mask |= HDMI_PHY_RX_SENSE2; -+ if (intr_stat & HDMI_IH_PHY_STAT0_RX_SENSE3) -+ phy_pol_mask |= HDMI_PHY_RX_SENSE3; -+ -+ if (phy_pol_mask) -+ hdmi_modb(hdmi, ~phy_int_pol, phy_pol_mask, HDMI_PHY_POL0); -+ -+ /* -+ * RX sense tells us whether the TDMS transmitters are detecting -+ * load - in other words, there's something listening on the -+ * other end of the link. Use this to decide whether we should -+ * power on the phy as HPD may be toggled by the sink to merely -+ * ask the source to re-read the EDID. -+ */ -+ if (intr_stat & -+ (HDMI_IH_PHY_STAT0_RX_SENSE | HDMI_IH_PHY_STAT0_HPD)) { -+ mutex_lock(&hdmi->mutex); -+ if (!hdmi->disabled && !hdmi->force) { -+ /* -+ * If the RX sense status indicates we're disconnected, -+ * clear the software rxsense status. -+ */ -+ if (!(phy_stat & HDMI_PHY_RX_SENSE)) -+ hdmi->rxsense = false; -+ -+ /* -+ * Only set the software rxsense status when both -+ * rxsense and hpd indicates we're connected. -+ * This avoids what seems to be bad behaviour in -+ * at least iMX6S versions of the phy. -+ */ -+ if (phy_stat & HDMI_PHY_HPD) -+ hdmi->rxsense = true; -+ -+ dw_hdmi_update_power(hdmi); -+ dw_hdmi_update_phy_mask(hdmi); -+ } -+ mutex_unlock(&hdmi->mutex); -+ } -+ -+ if (intr_stat & HDMI_IH_PHY_STAT0_HPD) { -+ dev_dbg(hdmi->dev, "EVENT=%s\n", -+ phy_int_pol & HDMI_PHY_HPD ? "plugin" : "plugout"); -+ if (hdmi->bridge.dev) -+ drm_helper_hpd_irq_event(hdmi->bridge.dev); -+ } -+ -+ hdmi_writeb(hdmi, intr_stat, HDMI_IH_PHY_STAT0); -+ hdmi_writeb(hdmi, ~(HDMI_IH_PHY_STAT0_HPD | HDMI_IH_PHY_STAT0_RX_SENSE), -+ HDMI_IH_MUTE_PHY_STAT0); -+ -+ return IRQ_HANDLED; -+} -+ -+static const struct dw_hdmi_phy_data dw_hdmi_phys[] = { -+ { -+ .type = DW_HDMI_PHY_DWC_HDMI_TX_PHY, -+ .name = "DWC HDMI TX PHY", -+ .gen = 1, -+ }, { -+ .type = DW_HDMI_PHY_DWC_MHL_PHY_HEAC, -+ .name = "DWC MHL PHY + HEAC PHY", -+ .gen = 2, -+ .has_svsret = true, -+ .configure = hdmi_phy_configure_dwc_hdmi_3d_tx, -+ }, { -+ .type = DW_HDMI_PHY_DWC_MHL_PHY, -+ .name = "DWC MHL PHY", -+ .gen = 2, -+ .has_svsret = true, -+ .configure = hdmi_phy_configure_dwc_hdmi_3d_tx, -+ }, { -+ .type = DW_HDMI_PHY_DWC_HDMI_3D_TX_PHY_HEAC, -+ .name = "DWC HDMI 3D TX PHY + HEAC PHY", -+ .gen = 2, -+ .configure = hdmi_phy_configure_dwc_hdmi_3d_tx, -+ }, { -+ .type = DW_HDMI_PHY_DWC_HDMI_3D_TX_PHY, -+ .name = "DWC HDMI 3D TX PHY", -+ .gen = 2, -+ .configure = hdmi_phy_configure_dwc_hdmi_3d_tx, -+ }, { -+ .type = DW_HDMI_PHY_DWC_HDMI20_TX_PHY, -+ .name = "DWC HDMI 2.0 TX PHY", -+ .gen = 2, -+ .has_svsret = true, -+ }, { -+ .type = DW_HDMI_PHY_VENDOR_PHY, -+ .name = "Vendor PHY", -+ } -+}; -+ -+static int dw_hdmi_detect_phy(struct dw_hdmi *hdmi) -+{ -+ unsigned int i; -+ u8 phy_type; -+ -+ phy_type = hdmi_readb(hdmi, HDMI_CONFIG2_ID); -+ -+ if (phy_type == DW_HDMI_PHY_VENDOR_PHY) { -+ /* Vendor PHYs require support from the glue layer. */ -+ if (!hdmi->plat_data->phy_ops || !hdmi->plat_data->phy_name) { -+ dev_err(hdmi->dev, -+ "Vendor HDMI PHY not supported by glue layer\n"); -+ return -ENODEV; -+ } -+ -+ hdmi->phy.ops = hdmi->plat_data->phy_ops; -+ hdmi->phy.data = hdmi->plat_data->phy_data; -+ hdmi->phy.name = hdmi->plat_data->phy_name; -+ return 0; -+ } -+ -+ /* Synopsys PHYs are handled internally. */ -+ for (i = 0; i < ARRAY_SIZE(dw_hdmi_phys); ++i) { -+ if (dw_hdmi_phys[i].type == phy_type) { -+ hdmi->phy.ops = &dw_hdmi_synopsys_phy_ops; -+ hdmi->phy.name = dw_hdmi_phys[i].name; -+ hdmi->phy.data = (void *)&dw_hdmi_phys[i]; -+ -+ if (!dw_hdmi_phys[i].configure && -+ !hdmi->plat_data->configure_phy) { -+ dev_err(hdmi->dev, "%s requires platform support\n", -+ hdmi->phy.name); -+ return -ENODEV; -+ } -+ -+ return 0; -+ } -+ } -+ -+ dev_err(hdmi->dev, "Unsupported HDMI PHY type (%02x)\n", phy_type); -+ return -ENODEV; -+} -+ -+static const struct regmap_config hdmi_regmap_8bit_config = { -+ .reg_bits = 32, -+ .val_bits = 8, -+ .reg_stride = 1, -+ .max_register = HDMI_I2CM_FS_SCL_LCNT_0_ADDR, -+}; -+ -+static const struct regmap_config hdmi_regmap_32bit_config = { -+ .reg_bits = 32, -+ .val_bits = 32, -+ .reg_stride = 4, -+ .max_register = HDMI_I2CM_FS_SCL_LCNT_0_ADDR << 2, -+}; -+ -+static struct dw_hdmi * -+__dw_hdmi_probe(struct platform_device *pdev, -+ const struct dw_hdmi_plat_data *plat_data) -+{ -+ struct device *dev = &pdev->dev; -+ struct device_node *np = dev->of_node; -+ struct platform_device_info pdevinfo; -+ struct device_node *ddc_node; -+ struct dw_hdmi *hdmi; -+ struct resource *iores = NULL; -+ int irq; -+ int ret; -+ u32 val = 1; -+ u8 prod_id0; -+ u8 prod_id1; -+ u8 config0; -+ u8 config3; -+ -+ hdmi = devm_kzalloc(dev, sizeof(*hdmi), GFP_KERNEL); -+ if (!hdmi) -+ return ERR_PTR(-ENOMEM); -+ -+ hdmi->plat_data = plat_data; -+ hdmi->dev = dev; -+ hdmi->sample_rate = 48000; -+ hdmi->disabled = true; -+ hdmi->rxsense = true; -+ hdmi->phy_mask = (u8)~(HDMI_PHY_HPD | HDMI_PHY_RX_SENSE); -+ -+ mutex_init(&hdmi->mutex); -+ mutex_init(&hdmi->audio_mutex); -+ spin_lock_init(&hdmi->audio_lock); -+ -+ ddc_node = of_parse_phandle(np, "ddc-i2c-bus", 0); -+ if (ddc_node) { -+ hdmi->ddc = of_get_i2c_adapter_by_node(ddc_node); -+ of_node_put(ddc_node); -+ if (!hdmi->ddc) { -+ dev_dbg(hdmi->dev, "failed to read ddc node\n"); -+ return ERR_PTR(-EPROBE_DEFER); -+ } -+ -+ } else { -+ dev_dbg(hdmi->dev, "no ddc property found\n"); -+ } -+ -+ if (!plat_data->regm) { -+ const struct regmap_config *reg_config; -+ -+ of_property_read_u32(np, "reg-io-width", &val); -+ switch (val) { -+ case 4: -+ reg_config = &hdmi_regmap_32bit_config; -+ hdmi->reg_shift = 2; -+ break; -+ case 1: -+ reg_config = &hdmi_regmap_8bit_config; -+ break; -+ default: -+ dev_err(dev, "reg-io-width must be 1 or 4\n"); -+ return ERR_PTR(-EINVAL); -+ } -+ -+ iores = platform_get_resource(pdev, IORESOURCE_MEM, 0); -+ hdmi->regs = devm_ioremap_resource(dev, iores); -+ if (IS_ERR(hdmi->regs)) { -+ ret = PTR_ERR(hdmi->regs); -+ goto err_res; -+ } -+ -+ hdmi->regm = devm_regmap_init_mmio(dev, hdmi->regs, reg_config); -+ if (IS_ERR(hdmi->regm)) { -+ dev_err(dev, "Failed to configure regmap\n"); -+ ret = PTR_ERR(hdmi->regm); -+ goto err_res; -+ } -+ } else { -+ hdmi->regm = plat_data->regm; -+ } -+ -+ hdmi->isfr_clk = devm_clk_get(hdmi->dev, "isfr"); -+ if (IS_ERR(hdmi->isfr_clk)) { -+ ret = PTR_ERR(hdmi->isfr_clk); -+ dev_err(hdmi->dev, "Unable to get HDMI isfr clk: %d\n", ret); -+ goto err_res; -+ } -+ -+ ret = clk_prepare_enable(hdmi->isfr_clk); -+ if (ret) { -+ dev_err(hdmi->dev, "Cannot enable HDMI isfr clock: %d\n", ret); -+ goto err_res; -+ } -+ -+ hdmi->iahb_clk = devm_clk_get(hdmi->dev, "iahb"); -+ if (IS_ERR(hdmi->iahb_clk)) { -+ ret = PTR_ERR(hdmi->iahb_clk); -+ dev_err(hdmi->dev, "Unable to get HDMI iahb clk: %d\n", ret); -+ goto err_isfr; -+ } -+ -+ ret = clk_prepare_enable(hdmi->iahb_clk); -+ if (ret) { -+ dev_err(hdmi->dev, "Cannot enable HDMI iahb clock: %d\n", ret); -+ goto err_isfr; -+ } -+ -+ /* Product and revision IDs */ -+ hdmi->version = (hdmi_readb(hdmi, HDMI_DESIGN_ID) << 8) -+ | (hdmi_readb(hdmi, HDMI_REVISION_ID) << 0); -+ prod_id0 = hdmi_readb(hdmi, HDMI_PRODUCT_ID0); -+ prod_id1 = hdmi_readb(hdmi, HDMI_PRODUCT_ID1); -+ -+ if (prod_id0 != HDMI_PRODUCT_ID0_HDMI_TX || -+ (prod_id1 & ~HDMI_PRODUCT_ID1_HDCP) != HDMI_PRODUCT_ID1_HDMI_TX) { -+ dev_err(dev, "Unsupported HDMI controller (%04x:%02x:%02x)\n", -+ hdmi->version, prod_id0, prod_id1); -+ ret = -ENODEV; -+ goto err_iahb; -+ } -+ -+ ret = dw_hdmi_detect_phy(hdmi); -+ if (ret < 0) -+ goto err_iahb; -+ -+ dev_info(dev, "Detected HDMI TX controller v%x.%03x %s HDCP (%s)\n", -+ hdmi->version >> 12, hdmi->version & 0xfff, -+ prod_id1 & HDMI_PRODUCT_ID1_HDCP ? "with" : "without", -+ hdmi->phy.name); -+ -+ initialize_hdmi_ih_mutes(hdmi); -+ -+ irq = platform_get_irq(pdev, 0); -+ if (irq < 0) { -+ ret = irq; -+ goto err_iahb; -+ } -+ -+ ret = devm_request_threaded_irq(dev, irq, dw_hdmi_hardirq, -+ dw_hdmi_irq, IRQF_SHARED, -+ dev_name(dev), hdmi); -+ if (ret) -+ goto err_iahb; -+ -+ /* -+ * To prevent overflows in HDMI_IH_FC_STAT2, set the clk regenerator -+ * N and cts values before enabling phy -+ */ -+ hdmi_init_clk_regenerator(hdmi); -+ -+ /* If DDC bus is not specified, try to register HDMI I2C bus */ -+ if (!hdmi->ddc) { -+ hdmi->ddc = dw_hdmi_i2c_adapter(hdmi); -+ if (IS_ERR(hdmi->ddc)) -+ hdmi->ddc = NULL; -+ } -+ -+ /* -+ * Configure registers related to HDMI interrupt -+ * generation before registering IRQ. -+ */ -+ hdmi_writeb(hdmi, HDMI_PHY_HPD | HDMI_PHY_RX_SENSE, HDMI_PHY_POL0); -+ -+ /* Clear Hotplug interrupts */ -+ hdmi_writeb(hdmi, HDMI_IH_PHY_STAT0_HPD | HDMI_IH_PHY_STAT0_RX_SENSE, -+ HDMI_IH_PHY_STAT0); -+ -+ hdmi->bridge.driver_private = hdmi; -+ hdmi->bridge.funcs = &dw_hdmi_bridge_funcs; -+#ifdef CONFIG_OF -+ hdmi->bridge.of_node = pdev->dev.of_node; -+#endif -+ -+ ret = dw_hdmi_fb_registered(hdmi); -+ if (ret) -+ goto err_iahb; -+ -+ /* Unmute interrupts */ -+ hdmi_writeb(hdmi, ~(HDMI_IH_PHY_STAT0_HPD | HDMI_IH_PHY_STAT0_RX_SENSE), -+ HDMI_IH_MUTE_PHY_STAT0); -+ -+ memset(&pdevinfo, 0, sizeof(pdevinfo)); -+ pdevinfo.parent = dev; -+ pdevinfo.id = PLATFORM_DEVID_AUTO; -+ -+ config0 = hdmi_readb(hdmi, HDMI_CONFIG0_ID); -+ config3 = hdmi_readb(hdmi, HDMI_CONFIG3_ID); -+ -+ if (iores && config3 & HDMI_CONFIG3_AHBAUDDMA) { -+ struct dw_hdmi_audio_data audio; -+ -+ audio.phys = iores->start; -+ audio.base = hdmi->regs; -+ audio.irq = irq; -+ audio.hdmi = hdmi; -+ audio.eld = hdmi->connector.eld; -+ -+ pdevinfo.name = "dw-hdmi-ahb-audio"; -+ pdevinfo.data = &audio; -+ pdevinfo.size_data = sizeof(audio); -+ pdevinfo.dma_mask = DMA_BIT_MASK(32); -+ hdmi->audio = platform_device_register_full(&pdevinfo); -+ } else if (config0 & HDMI_CONFIG0_I2S) { -+ struct dw_hdmi_i2s_audio_data audio; -+ -+ audio.hdmi = hdmi; -+ audio.write = hdmi_writeb; -+ audio.read = hdmi_readb; -+ -+ pdevinfo.name = "dw-hdmi-i2s-audio"; -+ pdevinfo.data = &audio; -+ pdevinfo.size_data = sizeof(audio); -+ pdevinfo.dma_mask = DMA_BIT_MASK(32); -+ hdmi->audio = platform_device_register_full(&pdevinfo); -+ } -+ -+ /* Reset HDMI DDC I2C master controller and mute I2CM interrupts */ -+ if (hdmi->i2c) -+ dw_hdmi_i2c_init(hdmi); -+ -+ platform_set_drvdata(pdev, hdmi); -+ -+ return hdmi; -+ -+err_iahb: -+ if (hdmi->i2c) { -+ i2c_del_adapter(&hdmi->i2c->adap); -+ hdmi->ddc = NULL; -+ } -+ -+ clk_disable_unprepare(hdmi->iahb_clk); -+err_isfr: -+ clk_disable_unprepare(hdmi->isfr_clk); -+err_res: -+ i2c_put_adapter(hdmi->ddc); -+ -+ return ERR_PTR(ret); -+} -+ -+static void __dw_hdmi_remove(struct dw_hdmi *hdmi) -+{ -+ if (hdmi->audio && !IS_ERR(hdmi->audio)) -+ platform_device_unregister(hdmi->audio); -+ -+ /* Disable all interrupts */ -+ hdmi_writeb(hdmi, ~0, HDMI_IH_MUTE_PHY_STAT0); -+ -+ clk_disable_unprepare(hdmi->iahb_clk); -+ clk_disable_unprepare(hdmi->isfr_clk); -+ -+ if (hdmi->i2c) -+ i2c_del_adapter(&hdmi->i2c->adap); -+ else -+ i2c_put_adapter(hdmi->ddc); -+} -+ -+/* ----------------------------------------------------------------------------- -+ * Probe/remove API, used from platforms based on the DRM bridge API. -+ */ -+int dw_hdmi_probe(struct platform_device *pdev, -+ const struct dw_hdmi_plat_data *plat_data) -+{ -+ struct dw_hdmi *hdmi; -+ int ret; -+ -+ hdmi = __dw_hdmi_probe(pdev, plat_data); -+ if (IS_ERR(hdmi)) -+ return PTR_ERR(hdmi); -+ -+ ret = drm_bridge_add(&hdmi->bridge); -+ if (ret < 0) { -+ __dw_hdmi_remove(hdmi); -+ return ret; -+ } -+ -+ return 0; -+} -+EXPORT_SYMBOL_GPL(dw_hdmi_probe); -+ -+void dw_hdmi_remove(struct platform_device *pdev) -+{ -+ struct dw_hdmi *hdmi = platform_get_drvdata(pdev); -+ -+ drm_bridge_remove(&hdmi->bridge); -+ -+ __dw_hdmi_remove(hdmi); -+} -+EXPORT_SYMBOL_GPL(dw_hdmi_remove); -+ -+/* ----------------------------------------------------------------------------- -+ * Bind/unbind API, used from platforms based on the component framework. -+ */ -+int dw_hdmi_bind(struct platform_device *pdev, struct drm_encoder *encoder, -+ const struct dw_hdmi_plat_data *plat_data) -+{ -+ struct dw_hdmi *hdmi; -+ int ret; -+ -+ hdmi = __dw_hdmi_probe(pdev, plat_data); -+ if (IS_ERR(hdmi)) -+ return PTR_ERR(hdmi); -+ -+ ret = drm_bridge_attach(encoder, &hdmi->bridge, NULL); -+ if (ret) { -+ dw_hdmi_remove(pdev); -+ DRM_ERROR("Failed to initialize bridge with drm\n"); -+ return ret; -+ } -+ -+ return 0; -+} -+EXPORT_SYMBOL_GPL(dw_hdmi_bind); -+ -+void dw_hdmi_unbind(struct device *dev) -+{ -+ struct dw_hdmi *hdmi = dev_get_drvdata(dev); -+ -+ __dw_hdmi_remove(hdmi); -+} -+EXPORT_SYMBOL_GPL(dw_hdmi_unbind); -+ -+MODULE_AUTHOR("Sascha Hauer "); -+MODULE_AUTHOR("Andy Yan "); -+MODULE_AUTHOR("Yakir Yang "); -+MODULE_AUTHOR("Vladimir Zapolskiy "); -+MODULE_DESCRIPTION("DW HDMI transmitter driver"); -+MODULE_LICENSE("GPL"); -+MODULE_ALIAS("platform:dw-hdmi"); -diff --git a/drivers/gpu/drm/bridge/synopsys/dw-hdmi.h b/drivers/gpu/drm/bridge/synopsys/dw-hdmi.h -new file mode 100644 -index 0000000..325b0b8 ---- /dev/null -+++ b/drivers/gpu/drm/bridge/synopsys/dw-hdmi.h -@@ -0,0 +1,1153 @@ -+/* -+ * Copyright (C) 2011 Freescale Semiconductor, Inc. -+ * -+ * This program is free software; you can redistribute it and/or modify -+ * it under the terms of the GNU General Public License as published by -+ * the Free Software Foundation; either version 2 of the License, or -+ * (at your option) any later version. -+ */ -+ -+#ifndef __DW_HDMI_H__ -+#define __DW_HDMI_H__ -+ -+/* Identification Registers */ -+#define HDMI_DESIGN_ID 0x0000 -+#define HDMI_REVISION_ID 0x0001 -+#define HDMI_PRODUCT_ID0 0x0002 -+#define HDMI_PRODUCT_ID1 0x0003 -+#define HDMI_CONFIG0_ID 0x0004 -+#define HDMI_CONFIG1_ID 0x0005 -+#define HDMI_CONFIG2_ID 0x0006 -+#define HDMI_CONFIG3_ID 0x0007 -+ -+/* Interrupt Registers */ -+#define HDMI_IH_FC_STAT0 0x0100 -+#define HDMI_IH_FC_STAT1 0x0101 -+#define HDMI_IH_FC_STAT2 0x0102 -+#define HDMI_IH_AS_STAT0 0x0103 -+#define HDMI_IH_PHY_STAT0 0x0104 -+#define HDMI_IH_I2CM_STAT0 0x0105 -+#define HDMI_IH_CEC_STAT0 0x0106 -+#define HDMI_IH_VP_STAT0 0x0107 -+#define HDMI_IH_I2CMPHY_STAT0 0x0108 -+#define HDMI_IH_AHBDMAAUD_STAT0 0x0109 -+ -+#define HDMI_IH_MUTE_FC_STAT0 0x0180 -+#define HDMI_IH_MUTE_FC_STAT1 0x0181 -+#define HDMI_IH_MUTE_FC_STAT2 0x0182 -+#define HDMI_IH_MUTE_AS_STAT0 0x0183 -+#define HDMI_IH_MUTE_PHY_STAT0 0x0184 -+#define HDMI_IH_MUTE_I2CM_STAT0 0x0185 -+#define HDMI_IH_MUTE_CEC_STAT0 0x0186 -+#define HDMI_IH_MUTE_VP_STAT0 0x0187 -+#define HDMI_IH_MUTE_I2CMPHY_STAT0 0x0188 -+#define HDMI_IH_MUTE_AHBDMAAUD_STAT0 0x0189 -+#define HDMI_IH_MUTE 0x01FF -+ -+/* Video Sample Registers */ -+#define HDMI_TX_INVID0 0x0200 -+#define HDMI_TX_INSTUFFING 0x0201 -+#define HDMI_TX_GYDATA0 0x0202 -+#define HDMI_TX_GYDATA1 0x0203 -+#define HDMI_TX_RCRDATA0 0x0204 -+#define HDMI_TX_RCRDATA1 0x0205 -+#define HDMI_TX_BCBDATA0 0x0206 -+#define HDMI_TX_BCBDATA1 0x0207 -+ -+/* Video Packetizer Registers */ -+#define HDMI_VP_STATUS 0x0800 -+#define HDMI_VP_PR_CD 0x0801 -+#define HDMI_VP_STUFF 0x0802 -+#define HDMI_VP_REMAP 0x0803 -+#define HDMI_VP_CONF 0x0804 -+#define HDMI_VP_STAT 0x0805 -+#define HDMI_VP_INT 0x0806 -+#define HDMI_VP_MASK 0x0807 -+#define HDMI_VP_POL 0x0808 -+ -+/* Frame Composer Registers */ -+#define HDMI_FC_INVIDCONF 0x1000 -+#define HDMI_FC_INHACTV0 0x1001 -+#define HDMI_FC_INHACTV1 0x1002 -+#define HDMI_FC_INHBLANK0 0x1003 -+#define HDMI_FC_INHBLANK1 0x1004 -+#define HDMI_FC_INVACTV0 0x1005 -+#define HDMI_FC_INVACTV1 0x1006 -+#define HDMI_FC_INVBLANK 0x1007 -+#define HDMI_FC_HSYNCINDELAY0 0x1008 -+#define HDMI_FC_HSYNCINDELAY1 0x1009 -+#define HDMI_FC_HSYNCINWIDTH0 0x100A -+#define HDMI_FC_HSYNCINWIDTH1 0x100B -+#define HDMI_FC_VSYNCINDELAY 0x100C -+#define HDMI_FC_VSYNCINWIDTH 0x100D -+#define HDMI_FC_INFREQ0 0x100E -+#define HDMI_FC_INFREQ1 0x100F -+#define HDMI_FC_INFREQ2 0x1010 -+#define HDMI_FC_CTRLDUR 0x1011 -+#define HDMI_FC_EXCTRLDUR 0x1012 -+#define HDMI_FC_EXCTRLSPAC 0x1013 -+#define HDMI_FC_CH0PREAM 0x1014 -+#define HDMI_FC_CH1PREAM 0x1015 -+#define HDMI_FC_CH2PREAM 0x1016 -+#define HDMI_FC_AVICONF3 0x1017 -+#define HDMI_FC_GCP 0x1018 -+#define HDMI_FC_AVICONF0 0x1019 -+#define HDMI_FC_AVICONF1 0x101A -+#define HDMI_FC_AVICONF2 0x101B -+#define HDMI_FC_AVIVID 0x101C -+#define HDMI_FC_AVIETB0 0x101D -+#define HDMI_FC_AVIETB1 0x101E -+#define HDMI_FC_AVISBB0 0x101F -+#define HDMI_FC_AVISBB1 0x1020 -+#define HDMI_FC_AVIELB0 0x1021 -+#define HDMI_FC_AVIELB1 0x1022 -+#define HDMI_FC_AVISRB0 0x1023 -+#define HDMI_FC_AVISRB1 0x1024 -+#define HDMI_FC_AUDICONF0 0x1025 -+#define HDMI_FC_AUDICONF1 0x1026 -+#define HDMI_FC_AUDICONF2 0x1027 -+#define HDMI_FC_AUDICONF3 0x1028 -+#define HDMI_FC_VSDIEEEID0 0x1029 -+#define HDMI_FC_VSDSIZE 0x102A -+#define HDMI_FC_VSDIEEEID1 0x1030 -+#define HDMI_FC_VSDIEEEID2 0x1031 -+#define HDMI_FC_VSDPAYLOAD0 0x1032 -+#define HDMI_FC_VSDPAYLOAD1 0x1033 -+#define HDMI_FC_VSDPAYLOAD2 0x1034 -+#define HDMI_FC_VSDPAYLOAD3 0x1035 -+#define HDMI_FC_VSDPAYLOAD4 0x1036 -+#define HDMI_FC_VSDPAYLOAD5 0x1037 -+#define HDMI_FC_VSDPAYLOAD6 0x1038 -+#define HDMI_FC_VSDPAYLOAD7 0x1039 -+#define HDMI_FC_VSDPAYLOAD8 0x103A -+#define HDMI_FC_VSDPAYLOAD9 0x103B -+#define HDMI_FC_VSDPAYLOAD10 0x103C -+#define HDMI_FC_VSDPAYLOAD11 0x103D -+#define HDMI_FC_VSDPAYLOAD12 0x103E -+#define HDMI_FC_VSDPAYLOAD13 0x103F -+#define HDMI_FC_VSDPAYLOAD14 0x1040 -+#define HDMI_FC_VSDPAYLOAD15 0x1041 -+#define HDMI_FC_VSDPAYLOAD16 0x1042 -+#define HDMI_FC_VSDPAYLOAD17 0x1043 -+#define HDMI_FC_VSDPAYLOAD18 0x1044 -+#define HDMI_FC_VSDPAYLOAD19 0x1045 -+#define HDMI_FC_VSDPAYLOAD20 0x1046 -+#define HDMI_FC_VSDPAYLOAD21 0x1047 -+#define HDMI_FC_VSDPAYLOAD22 0x1048 -+#define HDMI_FC_VSDPAYLOAD23 0x1049 -+#define HDMI_FC_SPDVENDORNAME0 0x104A -+#define HDMI_FC_SPDVENDORNAME1 0x104B -+#define HDMI_FC_SPDVENDORNAME2 0x104C -+#define HDMI_FC_SPDVENDORNAME3 0x104D -+#define HDMI_FC_SPDVENDORNAME4 0x104E -+#define HDMI_FC_SPDVENDORNAME5 0x104F -+#define HDMI_FC_SPDVENDORNAME6 0x1050 -+#define HDMI_FC_SPDVENDORNAME7 0x1051 -+#define HDMI_FC_SDPPRODUCTNAME0 0x1052 -+#define HDMI_FC_SDPPRODUCTNAME1 0x1053 -+#define HDMI_FC_SDPPRODUCTNAME2 0x1054 -+#define HDMI_FC_SDPPRODUCTNAME3 0x1055 -+#define HDMI_FC_SDPPRODUCTNAME4 0x1056 -+#define HDMI_FC_SDPPRODUCTNAME5 0x1057 -+#define HDMI_FC_SDPPRODUCTNAME6 0x1058 -+#define HDMI_FC_SDPPRODUCTNAME7 0x1059 -+#define HDMI_FC_SDPPRODUCTNAME8 0x105A -+#define HDMI_FC_SDPPRODUCTNAME9 0x105B -+#define HDMI_FC_SDPPRODUCTNAME10 0x105C -+#define HDMI_FC_SDPPRODUCTNAME11 0x105D -+#define HDMI_FC_SDPPRODUCTNAME12 0x105E -+#define HDMI_FC_SDPPRODUCTNAME13 0x105F -+#define HDMI_FC_SDPPRODUCTNAME14 0x1060 -+#define HDMI_FC_SPDPRODUCTNAME15 0x1061 -+#define HDMI_FC_SPDDEVICEINF 0x1062 -+#define HDMI_FC_AUDSCONF 0x1063 -+#define HDMI_FC_AUDSSTAT 0x1064 -+#define HDMI_FC_DATACH0FILL 0x1070 -+#define HDMI_FC_DATACH1FILL 0x1071 -+#define HDMI_FC_DATACH2FILL 0x1072 -+#define HDMI_FC_CTRLQHIGH 0x1073 -+#define HDMI_FC_CTRLQLOW 0x1074 -+#define HDMI_FC_ACP0 0x1075 -+#define HDMI_FC_ACP28 0x1076 -+#define HDMI_FC_ACP27 0x1077 -+#define HDMI_FC_ACP26 0x1078 -+#define HDMI_FC_ACP25 0x1079 -+#define HDMI_FC_ACP24 0x107A -+#define HDMI_FC_ACP23 0x107B -+#define HDMI_FC_ACP22 0x107C -+#define HDMI_FC_ACP21 0x107D -+#define HDMI_FC_ACP20 0x107E -+#define HDMI_FC_ACP19 0x107F -+#define HDMI_FC_ACP18 0x1080 -+#define HDMI_FC_ACP17 0x1081 -+#define HDMI_FC_ACP16 0x1082 -+#define HDMI_FC_ACP15 0x1083 -+#define HDMI_FC_ACP14 0x1084 -+#define HDMI_FC_ACP13 0x1085 -+#define HDMI_FC_ACP12 0x1086 -+#define HDMI_FC_ACP11 0x1087 -+#define HDMI_FC_ACP10 0x1088 -+#define HDMI_FC_ACP9 0x1089 -+#define HDMI_FC_ACP8 0x108A -+#define HDMI_FC_ACP7 0x108B -+#define HDMI_FC_ACP6 0x108C -+#define HDMI_FC_ACP5 0x108D -+#define HDMI_FC_ACP4 0x108E -+#define HDMI_FC_ACP3 0x108F -+#define HDMI_FC_ACP2 0x1090 -+#define HDMI_FC_ACP1 0x1091 -+#define HDMI_FC_ISCR1_0 0x1092 -+#define HDMI_FC_ISCR1_16 0x1093 -+#define HDMI_FC_ISCR1_15 0x1094 -+#define HDMI_FC_ISCR1_14 0x1095 -+#define HDMI_FC_ISCR1_13 0x1096 -+#define HDMI_FC_ISCR1_12 0x1097 -+#define HDMI_FC_ISCR1_11 0x1098 -+#define HDMI_FC_ISCR1_10 0x1099 -+#define HDMI_FC_ISCR1_9 0x109A -+#define HDMI_FC_ISCR1_8 0x109B -+#define HDMI_FC_ISCR1_7 0x109C -+#define HDMI_FC_ISCR1_6 0x109D -+#define HDMI_FC_ISCR1_5 0x109E -+#define HDMI_FC_ISCR1_4 0x109F -+#define HDMI_FC_ISCR1_3 0x10A0 -+#define HDMI_FC_ISCR1_2 0x10A1 -+#define HDMI_FC_ISCR1_1 0x10A2 -+#define HDMI_FC_ISCR2_15 0x10A3 -+#define HDMI_FC_ISCR2_14 0x10A4 -+#define HDMI_FC_ISCR2_13 0x10A5 -+#define HDMI_FC_ISCR2_12 0x10A6 -+#define HDMI_FC_ISCR2_11 0x10A7 -+#define HDMI_FC_ISCR2_10 0x10A8 -+#define HDMI_FC_ISCR2_9 0x10A9 -+#define HDMI_FC_ISCR2_8 0x10AA -+#define HDMI_FC_ISCR2_7 0x10AB -+#define HDMI_FC_ISCR2_6 0x10AC -+#define HDMI_FC_ISCR2_5 0x10AD -+#define HDMI_FC_ISCR2_4 0x10AE -+#define HDMI_FC_ISCR2_3 0x10AF -+#define HDMI_FC_ISCR2_2 0x10B0 -+#define HDMI_FC_ISCR2_1 0x10B1 -+#define HDMI_FC_ISCR2_0 0x10B2 -+#define HDMI_FC_DATAUTO0 0x10B3 -+#define HDMI_FC_DATAUTO1 0x10B4 -+#define HDMI_FC_DATAUTO2 0x10B5 -+#define HDMI_FC_DATMAN 0x10B6 -+#define HDMI_FC_DATAUTO3 0x10B7 -+#define HDMI_FC_RDRB0 0x10B8 -+#define HDMI_FC_RDRB1 0x10B9 -+#define HDMI_FC_RDRB2 0x10BA -+#define HDMI_FC_RDRB3 0x10BB -+#define HDMI_FC_RDRB4 0x10BC -+#define HDMI_FC_RDRB5 0x10BD -+#define HDMI_FC_RDRB6 0x10BE -+#define HDMI_FC_RDRB7 0x10BF -+#define HDMI_FC_STAT0 0x10D0 -+#define HDMI_FC_INT0 0x10D1 -+#define HDMI_FC_MASK0 0x10D2 -+#define HDMI_FC_POL0 0x10D3 -+#define HDMI_FC_STAT1 0x10D4 -+#define HDMI_FC_INT1 0x10D5 -+#define HDMI_FC_MASK1 0x10D6 -+#define HDMI_FC_POL1 0x10D7 -+#define HDMI_FC_STAT2 0x10D8 -+#define HDMI_FC_INT2 0x10D9 -+#define HDMI_FC_MASK2 0x10DA -+#define HDMI_FC_POL2 0x10DB -+#define HDMI_FC_PRCONF 0x10E0 -+ -+#define HDMI_FC_GMD_STAT 0x1100 -+#define HDMI_FC_GMD_EN 0x1101 -+#define HDMI_FC_GMD_UP 0x1102 -+#define HDMI_FC_GMD_CONF 0x1103 -+#define HDMI_FC_GMD_HB 0x1104 -+#define HDMI_FC_GMD_PB0 0x1105 -+#define HDMI_FC_GMD_PB1 0x1106 -+#define HDMI_FC_GMD_PB2 0x1107 -+#define HDMI_FC_GMD_PB3 0x1108 -+#define HDMI_FC_GMD_PB4 0x1109 -+#define HDMI_FC_GMD_PB5 0x110A -+#define HDMI_FC_GMD_PB6 0x110B -+#define HDMI_FC_GMD_PB7 0x110C -+#define HDMI_FC_GMD_PB8 0x110D -+#define HDMI_FC_GMD_PB9 0x110E -+#define HDMI_FC_GMD_PB10 0x110F -+#define HDMI_FC_GMD_PB11 0x1110 -+#define HDMI_FC_GMD_PB12 0x1111 -+#define HDMI_FC_GMD_PB13 0x1112 -+#define HDMI_FC_GMD_PB14 0x1113 -+#define HDMI_FC_GMD_PB15 0x1114 -+#define HDMI_FC_GMD_PB16 0x1115 -+#define HDMI_FC_GMD_PB17 0x1116 -+#define HDMI_FC_GMD_PB18 0x1117 -+#define HDMI_FC_GMD_PB19 0x1118 -+#define HDMI_FC_GMD_PB20 0x1119 -+#define HDMI_FC_GMD_PB21 0x111A -+#define HDMI_FC_GMD_PB22 0x111B -+#define HDMI_FC_GMD_PB23 0x111C -+#define HDMI_FC_GMD_PB24 0x111D -+#define HDMI_FC_GMD_PB25 0x111E -+#define HDMI_FC_GMD_PB26 0x111F -+#define HDMI_FC_GMD_PB27 0x1120 -+ -+#define HDMI_FC_DBGFORCE 0x1200 -+#define HDMI_FC_DBGAUD0CH0 0x1201 -+#define HDMI_FC_DBGAUD1CH0 0x1202 -+#define HDMI_FC_DBGAUD2CH0 0x1203 -+#define HDMI_FC_DBGAUD0CH1 0x1204 -+#define HDMI_FC_DBGAUD1CH1 0x1205 -+#define HDMI_FC_DBGAUD2CH1 0x1206 -+#define HDMI_FC_DBGAUD0CH2 0x1207 -+#define HDMI_FC_DBGAUD1CH2 0x1208 -+#define HDMI_FC_DBGAUD2CH2 0x1209 -+#define HDMI_FC_DBGAUD0CH3 0x120A -+#define HDMI_FC_DBGAUD1CH3 0x120B -+#define HDMI_FC_DBGAUD2CH3 0x120C -+#define HDMI_FC_DBGAUD0CH4 0x120D -+#define HDMI_FC_DBGAUD1CH4 0x120E -+#define HDMI_FC_DBGAUD2CH4 0x120F -+#define HDMI_FC_DBGAUD0CH5 0x1210 -+#define HDMI_FC_DBGAUD1CH5 0x1211 -+#define HDMI_FC_DBGAUD2CH5 0x1212 -+#define HDMI_FC_DBGAUD0CH6 0x1213 -+#define HDMI_FC_DBGAUD1CH6 0x1214 -+#define HDMI_FC_DBGAUD2CH6 0x1215 -+#define HDMI_FC_DBGAUD0CH7 0x1216 -+#define HDMI_FC_DBGAUD1CH7 0x1217 -+#define HDMI_FC_DBGAUD2CH7 0x1218 -+#define HDMI_FC_DBGTMDS0 0x1219 -+#define HDMI_FC_DBGTMDS1 0x121A -+#define HDMI_FC_DBGTMDS2 0x121B -+ -+/* HDMI Source PHY Registers */ -+#define HDMI_PHY_CONF0 0x3000 -+#define HDMI_PHY_TST0 0x3001 -+#define HDMI_PHY_TST1 0x3002 -+#define HDMI_PHY_TST2 0x3003 -+#define HDMI_PHY_STAT0 0x3004 -+#define HDMI_PHY_INT0 0x3005 -+#define HDMI_PHY_MASK0 0x3006 -+#define HDMI_PHY_POL0 0x3007 -+ -+/* HDMI Master PHY Registers */ -+#define HDMI_PHY_I2CM_SLAVE_ADDR 0x3020 -+#define HDMI_PHY_I2CM_ADDRESS_ADDR 0x3021 -+#define HDMI_PHY_I2CM_DATAO_1_ADDR 0x3022 -+#define HDMI_PHY_I2CM_DATAO_0_ADDR 0x3023 -+#define HDMI_PHY_I2CM_DATAI_1_ADDR 0x3024 -+#define HDMI_PHY_I2CM_DATAI_0_ADDR 0x3025 -+#define HDMI_PHY_I2CM_OPERATION_ADDR 0x3026 -+#define HDMI_PHY_I2CM_INT_ADDR 0x3027 -+#define HDMI_PHY_I2CM_CTLINT_ADDR 0x3028 -+#define HDMI_PHY_I2CM_DIV_ADDR 0x3029 -+#define HDMI_PHY_I2CM_SOFTRSTZ_ADDR 0x302a -+#define HDMI_PHY_I2CM_SS_SCL_HCNT_1_ADDR 0x302b -+#define HDMI_PHY_I2CM_SS_SCL_HCNT_0_ADDR 0x302c -+#define HDMI_PHY_I2CM_SS_SCL_LCNT_1_ADDR 0x302d -+#define HDMI_PHY_I2CM_SS_SCL_LCNT_0_ADDR 0x302e -+#define HDMI_PHY_I2CM_FS_SCL_HCNT_1_ADDR 0x302f -+#define HDMI_PHY_I2CM_FS_SCL_HCNT_0_ADDR 0x3030 -+#define HDMI_PHY_I2CM_FS_SCL_LCNT_1_ADDR 0x3031 -+#define HDMI_PHY_I2CM_FS_SCL_LCNT_0_ADDR 0x3032 -+ -+/* Audio Sampler Registers */ -+#define HDMI_AUD_CONF0 0x3100 -+#define HDMI_AUD_CONF1 0x3101 -+#define HDMI_AUD_INT 0x3102 -+#define HDMI_AUD_CONF2 0x3103 -+#define HDMI_AUD_N1 0x3200 -+#define HDMI_AUD_N2 0x3201 -+#define HDMI_AUD_N3 0x3202 -+#define HDMI_AUD_CTS1 0x3203 -+#define HDMI_AUD_CTS2 0x3204 -+#define HDMI_AUD_CTS3 0x3205 -+#define HDMI_AUD_INPUTCLKFS 0x3206 -+#define HDMI_AUD_SPDIFINT 0x3302 -+#define HDMI_AUD_CONF0_HBR 0x3400 -+#define HDMI_AUD_HBR_STATUS 0x3401 -+#define HDMI_AUD_HBR_INT 0x3402 -+#define HDMI_AUD_HBR_POL 0x3403 -+#define HDMI_AUD_HBR_MASK 0x3404 -+ -+/* -+ * Generic Parallel Audio Interface Registers -+ * Not used as GPAUD interface is not enabled in hw -+ */ -+#define HDMI_GP_CONF0 0x3500 -+#define HDMI_GP_CONF1 0x3501 -+#define HDMI_GP_CONF2 0x3502 -+#define HDMI_GP_STAT 0x3503 -+#define HDMI_GP_INT 0x3504 -+#define HDMI_GP_MASK 0x3505 -+#define HDMI_GP_POL 0x3506 -+ -+/* Audio DMA Registers */ -+#define HDMI_AHB_DMA_CONF0 0x3600 -+#define HDMI_AHB_DMA_START 0x3601 -+#define HDMI_AHB_DMA_STOP 0x3602 -+#define HDMI_AHB_DMA_THRSLD 0x3603 -+#define HDMI_AHB_DMA_STRADDR0 0x3604 -+#define HDMI_AHB_DMA_STRADDR1 0x3605 -+#define HDMI_AHB_DMA_STRADDR2 0x3606 -+#define HDMI_AHB_DMA_STRADDR3 0x3607 -+#define HDMI_AHB_DMA_STPADDR0 0x3608 -+#define HDMI_AHB_DMA_STPADDR1 0x3609 -+#define HDMI_AHB_DMA_STPADDR2 0x360a -+#define HDMI_AHB_DMA_STPADDR3 0x360b -+#define HDMI_AHB_DMA_BSTADDR0 0x360c -+#define HDMI_AHB_DMA_BSTADDR1 0x360d -+#define HDMI_AHB_DMA_BSTADDR2 0x360e -+#define HDMI_AHB_DMA_BSTADDR3 0x360f -+#define HDMI_AHB_DMA_MBLENGTH0 0x3610 -+#define HDMI_AHB_DMA_MBLENGTH1 0x3611 -+#define HDMI_AHB_DMA_STAT 0x3612 -+#define HDMI_AHB_DMA_INT 0x3613 -+#define HDMI_AHB_DMA_MASK 0x3614 -+#define HDMI_AHB_DMA_POL 0x3615 -+#define HDMI_AHB_DMA_CONF1 0x3616 -+#define HDMI_AHB_DMA_BUFFSTAT 0x3617 -+#define HDMI_AHB_DMA_BUFFINT 0x3618 -+#define HDMI_AHB_DMA_BUFFMASK 0x3619 -+#define HDMI_AHB_DMA_BUFFPOL 0x361a -+ -+/* Main Controller Registers */ -+#define HDMI_MC_SFRDIV 0x4000 -+#define HDMI_MC_CLKDIS 0x4001 -+#define HDMI_MC_SWRSTZ 0x4002 -+#define HDMI_MC_OPCTRL 0x4003 -+#define HDMI_MC_FLOWCTRL 0x4004 -+#define HDMI_MC_PHYRSTZ 0x4005 -+#define HDMI_MC_LOCKONCLOCK 0x4006 -+#define HDMI_MC_HEACPHY_RST 0x4007 -+ -+/* Color Space Converter Registers */ -+#define HDMI_CSC_CFG 0x4100 -+#define HDMI_CSC_SCALE 0x4101 -+#define HDMI_CSC_COEF_A1_MSB 0x4102 -+#define HDMI_CSC_COEF_A1_LSB 0x4103 -+#define HDMI_CSC_COEF_A2_MSB 0x4104 -+#define HDMI_CSC_COEF_A2_LSB 0x4105 -+#define HDMI_CSC_COEF_A3_MSB 0x4106 -+#define HDMI_CSC_COEF_A3_LSB 0x4107 -+#define HDMI_CSC_COEF_A4_MSB 0x4108 -+#define HDMI_CSC_COEF_A4_LSB 0x4109 -+#define HDMI_CSC_COEF_B1_MSB 0x410A -+#define HDMI_CSC_COEF_B1_LSB 0x410B -+#define HDMI_CSC_COEF_B2_MSB 0x410C -+#define HDMI_CSC_COEF_B2_LSB 0x410D -+#define HDMI_CSC_COEF_B3_MSB 0x410E -+#define HDMI_CSC_COEF_B3_LSB 0x410F -+#define HDMI_CSC_COEF_B4_MSB 0x4110 -+#define HDMI_CSC_COEF_B4_LSB 0x4111 -+#define HDMI_CSC_COEF_C1_MSB 0x4112 -+#define HDMI_CSC_COEF_C1_LSB 0x4113 -+#define HDMI_CSC_COEF_C2_MSB 0x4114 -+#define HDMI_CSC_COEF_C2_LSB 0x4115 -+#define HDMI_CSC_COEF_C3_MSB 0x4116 -+#define HDMI_CSC_COEF_C3_LSB 0x4117 -+#define HDMI_CSC_COEF_C4_MSB 0x4118 -+#define HDMI_CSC_COEF_C4_LSB 0x4119 -+ -+/* HDCP Encryption Engine Registers */ -+#define HDMI_A_HDCPCFG0 0x5000 -+#define HDMI_A_HDCPCFG1 0x5001 -+#define HDMI_A_HDCPOBS0 0x5002 -+#define HDMI_A_HDCPOBS1 0x5003 -+#define HDMI_A_HDCPOBS2 0x5004 -+#define HDMI_A_HDCPOBS3 0x5005 -+#define HDMI_A_APIINTCLR 0x5006 -+#define HDMI_A_APIINTSTAT 0x5007 -+#define HDMI_A_APIINTMSK 0x5008 -+#define HDMI_A_VIDPOLCFG 0x5009 -+#define HDMI_A_OESSWCFG 0x500A -+#define HDMI_A_TIMER1SETUP0 0x500B -+#define HDMI_A_TIMER1SETUP1 0x500C -+#define HDMI_A_TIMER2SETUP0 0x500D -+#define HDMI_A_TIMER2SETUP1 0x500E -+#define HDMI_A_100MSCFG 0x500F -+#define HDMI_A_2SCFG0 0x5010 -+#define HDMI_A_2SCFG1 0x5011 -+#define HDMI_A_5SCFG0 0x5012 -+#define HDMI_A_5SCFG1 0x5013 -+#define HDMI_A_SRMVERLSB 0x5014 -+#define HDMI_A_SRMVERMSB 0x5015 -+#define HDMI_A_SRMCTRL 0x5016 -+#define HDMI_A_SFRSETUP 0x5017 -+#define HDMI_A_I2CHSETUP 0x5018 -+#define HDMI_A_INTSETUP 0x5019 -+#define HDMI_A_PRESETUP 0x501A -+#define HDMI_A_SRM_BASE 0x5020 -+ -+/* CEC Engine Registers */ -+#define HDMI_CEC_CTRL 0x7D00 -+#define HDMI_CEC_STAT 0x7D01 -+#define HDMI_CEC_MASK 0x7D02 -+#define HDMI_CEC_POLARITY 0x7D03 -+#define HDMI_CEC_INT 0x7D04 -+#define HDMI_CEC_ADDR_L 0x7D05 -+#define HDMI_CEC_ADDR_H 0x7D06 -+#define HDMI_CEC_TX_CNT 0x7D07 -+#define HDMI_CEC_RX_CNT 0x7D08 -+#define HDMI_CEC_TX_DATA0 0x7D10 -+#define HDMI_CEC_TX_DATA1 0x7D11 -+#define HDMI_CEC_TX_DATA2 0x7D12 -+#define HDMI_CEC_TX_DATA3 0x7D13 -+#define HDMI_CEC_TX_DATA4 0x7D14 -+#define HDMI_CEC_TX_DATA5 0x7D15 -+#define HDMI_CEC_TX_DATA6 0x7D16 -+#define HDMI_CEC_TX_DATA7 0x7D17 -+#define HDMI_CEC_TX_DATA8 0x7D18 -+#define HDMI_CEC_TX_DATA9 0x7D19 -+#define HDMI_CEC_TX_DATA10 0x7D1a -+#define HDMI_CEC_TX_DATA11 0x7D1b -+#define HDMI_CEC_TX_DATA12 0x7D1c -+#define HDMI_CEC_TX_DATA13 0x7D1d -+#define HDMI_CEC_TX_DATA14 0x7D1e -+#define HDMI_CEC_TX_DATA15 0x7D1f -+#define HDMI_CEC_RX_DATA0 0x7D20 -+#define HDMI_CEC_RX_DATA1 0x7D21 -+#define HDMI_CEC_RX_DATA2 0x7D22 -+#define HDMI_CEC_RX_DATA3 0x7D23 -+#define HDMI_CEC_RX_DATA4 0x7D24 -+#define HDMI_CEC_RX_DATA5 0x7D25 -+#define HDMI_CEC_RX_DATA6 0x7D26 -+#define HDMI_CEC_RX_DATA7 0x7D27 -+#define HDMI_CEC_RX_DATA8 0x7D28 -+#define HDMI_CEC_RX_DATA9 0x7D29 -+#define HDMI_CEC_RX_DATA10 0x7D2a -+#define HDMI_CEC_RX_DATA11 0x7D2b -+#define HDMI_CEC_RX_DATA12 0x7D2c -+#define HDMI_CEC_RX_DATA13 0x7D2d -+#define HDMI_CEC_RX_DATA14 0x7D2e -+#define HDMI_CEC_RX_DATA15 0x7D2f -+#define HDMI_CEC_LOCK 0x7D30 -+#define HDMI_CEC_WKUPCTRL 0x7D31 -+ -+/* I2C Master Registers (E-DDC) */ -+#define HDMI_I2CM_SLAVE 0x7E00 -+#define HDMI_I2CM_ADDRESS 0x7E01 -+#define HDMI_I2CM_DATAO 0x7E02 -+#define HDMI_I2CM_DATAI 0x7E03 -+#define HDMI_I2CM_OPERATION 0x7E04 -+#define HDMI_I2CM_INT 0x7E05 -+#define HDMI_I2CM_CTLINT 0x7E06 -+#define HDMI_I2CM_DIV 0x7E07 -+#define HDMI_I2CM_SEGADDR 0x7E08 -+#define HDMI_I2CM_SOFTRSTZ 0x7E09 -+#define HDMI_I2CM_SEGPTR 0x7E0A -+#define HDMI_I2CM_SS_SCL_HCNT_1_ADDR 0x7E0B -+#define HDMI_I2CM_SS_SCL_HCNT_0_ADDR 0x7E0C -+#define HDMI_I2CM_SS_SCL_LCNT_1_ADDR 0x7E0D -+#define HDMI_I2CM_SS_SCL_LCNT_0_ADDR 0x7E0E -+#define HDMI_I2CM_FS_SCL_HCNT_1_ADDR 0x7E0F -+#define HDMI_I2CM_FS_SCL_HCNT_0_ADDR 0x7E10 -+#define HDMI_I2CM_FS_SCL_LCNT_1_ADDR 0x7E11 -+#define HDMI_I2CM_FS_SCL_LCNT_0_ADDR 0x7E12 -+ -+enum { -+/* PRODUCT_ID0 field values */ -+ HDMI_PRODUCT_ID0_HDMI_TX = 0xa0, -+ -+/* PRODUCT_ID1 field values */ -+ HDMI_PRODUCT_ID1_HDCP = 0xc0, -+ HDMI_PRODUCT_ID1_HDMI_RX = 0x02, -+ HDMI_PRODUCT_ID1_HDMI_TX = 0x01, -+ -+/* CONFIG0_ID field values */ -+ HDMI_CONFIG0_I2S = 0x10, -+ -+/* CONFIG1_ID field values */ -+ HDMI_CONFIG1_AHB = 0x01, -+ -+/* CONFIG3_ID field values */ -+ HDMI_CONFIG3_AHBAUDDMA = 0x02, -+ HDMI_CONFIG3_GPAUD = 0x01, -+ -+/* IH_FC_INT2 field values */ -+ HDMI_IH_FC_INT2_OVERFLOW_MASK = 0x03, -+ HDMI_IH_FC_INT2_LOW_PRIORITY_OVERFLOW = 0x02, -+ HDMI_IH_FC_INT2_HIGH_PRIORITY_OVERFLOW = 0x01, -+ -+/* IH_FC_STAT2 field values */ -+ HDMI_IH_FC_STAT2_OVERFLOW_MASK = 0x03, -+ HDMI_IH_FC_STAT2_LOW_PRIORITY_OVERFLOW = 0x02, -+ HDMI_IH_FC_STAT2_HIGH_PRIORITY_OVERFLOW = 0x01, -+ -+/* IH_PHY_STAT0 field values */ -+ HDMI_IH_PHY_STAT0_RX_SENSE3 = 0x20, -+ HDMI_IH_PHY_STAT0_RX_SENSE2 = 0x10, -+ HDMI_IH_PHY_STAT0_RX_SENSE1 = 0x8, -+ HDMI_IH_PHY_STAT0_RX_SENSE0 = 0x4, -+ HDMI_IH_PHY_STAT0_TX_PHY_LOCK = 0x2, -+ HDMI_IH_PHY_STAT0_HPD = 0x1, -+ -+/* IH_I2CM_STAT0 and IH_MUTE_I2CM_STAT0 field values */ -+ HDMI_IH_I2CM_STAT0_DONE = 0x2, -+ HDMI_IH_I2CM_STAT0_ERROR = 0x1, -+ -+/* IH_MUTE_I2CMPHY_STAT0 field values */ -+ HDMI_IH_MUTE_I2CMPHY_STAT0_I2CMPHYDONE = 0x2, -+ HDMI_IH_MUTE_I2CMPHY_STAT0_I2CMPHYERROR = 0x1, -+ -+/* IH_AHBDMAAUD_STAT0 field values */ -+ HDMI_IH_AHBDMAAUD_STAT0_ERROR = 0x20, -+ HDMI_IH_AHBDMAAUD_STAT0_LOST = 0x10, -+ HDMI_IH_AHBDMAAUD_STAT0_RETRY = 0x08, -+ HDMI_IH_AHBDMAAUD_STAT0_DONE = 0x04, -+ HDMI_IH_AHBDMAAUD_STAT0_BUFFFULL = 0x02, -+ HDMI_IH_AHBDMAAUD_STAT0_BUFFEMPTY = 0x01, -+ -+/* IH_MUTE_FC_STAT2 field values */ -+ HDMI_IH_MUTE_FC_STAT2_OVERFLOW_MASK = 0x03, -+ HDMI_IH_MUTE_FC_STAT2_LOW_PRIORITY_OVERFLOW = 0x02, -+ HDMI_IH_MUTE_FC_STAT2_HIGH_PRIORITY_OVERFLOW = 0x01, -+ -+/* IH_MUTE_AHBDMAAUD_STAT0 field values */ -+ HDMI_IH_MUTE_AHBDMAAUD_STAT0_ERROR = 0x20, -+ HDMI_IH_MUTE_AHBDMAAUD_STAT0_LOST = 0x10, -+ HDMI_IH_MUTE_AHBDMAAUD_STAT0_RETRY = 0x08, -+ HDMI_IH_MUTE_AHBDMAAUD_STAT0_DONE = 0x04, -+ HDMI_IH_MUTE_AHBDMAAUD_STAT0_BUFFFULL = 0x02, -+ HDMI_IH_MUTE_AHBDMAAUD_STAT0_BUFFEMPTY = 0x01, -+ -+/* IH_MUTE field values */ -+ HDMI_IH_MUTE_MUTE_WAKEUP_INTERRUPT = 0x2, -+ HDMI_IH_MUTE_MUTE_ALL_INTERRUPT = 0x1, -+ -+/* TX_INVID0 field values */ -+ HDMI_TX_INVID0_INTERNAL_DE_GENERATOR_MASK = 0x80, -+ HDMI_TX_INVID0_INTERNAL_DE_GENERATOR_ENABLE = 0x80, -+ HDMI_TX_INVID0_INTERNAL_DE_GENERATOR_DISABLE = 0x00, -+ HDMI_TX_INVID0_VIDEO_MAPPING_MASK = 0x1F, -+ HDMI_TX_INVID0_VIDEO_MAPPING_OFFSET = 0, -+ -+/* TX_INSTUFFING field values */ -+ HDMI_TX_INSTUFFING_BDBDATA_STUFFING_MASK = 0x4, -+ HDMI_TX_INSTUFFING_BDBDATA_STUFFING_ENABLE = 0x4, -+ HDMI_TX_INSTUFFING_BDBDATA_STUFFING_DISABLE = 0x0, -+ HDMI_TX_INSTUFFING_RCRDATA_STUFFING_MASK = 0x2, -+ HDMI_TX_INSTUFFING_RCRDATA_STUFFING_ENABLE = 0x2, -+ HDMI_TX_INSTUFFING_RCRDATA_STUFFING_DISABLE = 0x0, -+ HDMI_TX_INSTUFFING_GYDATA_STUFFING_MASK = 0x1, -+ HDMI_TX_INSTUFFING_GYDATA_STUFFING_ENABLE = 0x1, -+ HDMI_TX_INSTUFFING_GYDATA_STUFFING_DISABLE = 0x0, -+ -+/* VP_PR_CD field values */ -+ HDMI_VP_PR_CD_COLOR_DEPTH_MASK = 0xF0, -+ HDMI_VP_PR_CD_COLOR_DEPTH_OFFSET = 4, -+ HDMI_VP_PR_CD_DESIRED_PR_FACTOR_MASK = 0x0F, -+ HDMI_VP_PR_CD_DESIRED_PR_FACTOR_OFFSET = 0, -+ -+/* VP_STUFF field values */ -+ HDMI_VP_STUFF_IDEFAULT_PHASE_MASK = 0x20, -+ HDMI_VP_STUFF_IDEFAULT_PHASE_OFFSET = 5, -+ HDMI_VP_STUFF_IFIX_PP_TO_LAST_MASK = 0x10, -+ HDMI_VP_STUFF_IFIX_PP_TO_LAST_OFFSET = 4, -+ HDMI_VP_STUFF_ICX_GOTO_P0_ST_MASK = 0x8, -+ HDMI_VP_STUFF_ICX_GOTO_P0_ST_OFFSET = 3, -+ HDMI_VP_STUFF_YCC422_STUFFING_MASK = 0x4, -+ HDMI_VP_STUFF_YCC422_STUFFING_STUFFING_MODE = 0x4, -+ HDMI_VP_STUFF_YCC422_STUFFING_DIRECT_MODE = 0x0, -+ HDMI_VP_STUFF_PP_STUFFING_MASK = 0x2, -+ HDMI_VP_STUFF_PP_STUFFING_STUFFING_MODE = 0x2, -+ HDMI_VP_STUFF_PP_STUFFING_DIRECT_MODE = 0x0, -+ HDMI_VP_STUFF_PR_STUFFING_MASK = 0x1, -+ HDMI_VP_STUFF_PR_STUFFING_STUFFING_MODE = 0x1, -+ HDMI_VP_STUFF_PR_STUFFING_DIRECT_MODE = 0x0, -+ -+/* VP_CONF field values */ -+ HDMI_VP_CONF_BYPASS_EN_MASK = 0x40, -+ HDMI_VP_CONF_BYPASS_EN_ENABLE = 0x40, -+ HDMI_VP_CONF_BYPASS_EN_DISABLE = 0x00, -+ HDMI_VP_CONF_PP_EN_ENMASK = 0x20, -+ HDMI_VP_CONF_PP_EN_ENABLE = 0x20, -+ HDMI_VP_CONF_PP_EN_DISABLE = 0x00, -+ HDMI_VP_CONF_PR_EN_MASK = 0x10, -+ HDMI_VP_CONF_PR_EN_ENABLE = 0x10, -+ HDMI_VP_CONF_PR_EN_DISABLE = 0x00, -+ HDMI_VP_CONF_YCC422_EN_MASK = 0x8, -+ HDMI_VP_CONF_YCC422_EN_ENABLE = 0x8, -+ HDMI_VP_CONF_YCC422_EN_DISABLE = 0x0, -+ HDMI_VP_CONF_BYPASS_SELECT_MASK = 0x4, -+ HDMI_VP_CONF_BYPASS_SELECT_VID_PACKETIZER = 0x4, -+ HDMI_VP_CONF_BYPASS_SELECT_PIX_REPEATER = 0x0, -+ HDMI_VP_CONF_OUTPUT_SELECTOR_MASK = 0x3, -+ HDMI_VP_CONF_OUTPUT_SELECTOR_BYPASS = 0x3, -+ HDMI_VP_CONF_OUTPUT_SELECTOR_YCC422 = 0x1, -+ HDMI_VP_CONF_OUTPUT_SELECTOR_PP = 0x0, -+ -+/* VP_REMAP field values */ -+ HDMI_VP_REMAP_MASK = 0x3, -+ HDMI_VP_REMAP_YCC422_24bit = 0x2, -+ HDMI_VP_REMAP_YCC422_20bit = 0x1, -+ HDMI_VP_REMAP_YCC422_16bit = 0x0, -+ -+/* FC_INVIDCONF field values */ -+ HDMI_FC_INVIDCONF_HDCP_KEEPOUT_MASK = 0x80, -+ HDMI_FC_INVIDCONF_HDCP_KEEPOUT_ACTIVE = 0x80, -+ HDMI_FC_INVIDCONF_HDCP_KEEPOUT_INACTIVE = 0x00, -+ HDMI_FC_INVIDCONF_VSYNC_IN_POLARITY_MASK = 0x40, -+ HDMI_FC_INVIDCONF_VSYNC_IN_POLARITY_ACTIVE_HIGH = 0x40, -+ HDMI_FC_INVIDCONF_VSYNC_IN_POLARITY_ACTIVE_LOW = 0x00, -+ HDMI_FC_INVIDCONF_HSYNC_IN_POLARITY_MASK = 0x20, -+ HDMI_FC_INVIDCONF_HSYNC_IN_POLARITY_ACTIVE_HIGH = 0x20, -+ HDMI_FC_INVIDCONF_HSYNC_IN_POLARITY_ACTIVE_LOW = 0x00, -+ HDMI_FC_INVIDCONF_DE_IN_POLARITY_MASK = 0x10, -+ HDMI_FC_INVIDCONF_DE_IN_POLARITY_ACTIVE_HIGH = 0x10, -+ HDMI_FC_INVIDCONF_DE_IN_POLARITY_ACTIVE_LOW = 0x00, -+ HDMI_FC_INVIDCONF_DVI_MODEZ_MASK = 0x8, -+ HDMI_FC_INVIDCONF_DVI_MODEZ_HDMI_MODE = 0x8, -+ HDMI_FC_INVIDCONF_DVI_MODEZ_DVI_MODE = 0x0, -+ HDMI_FC_INVIDCONF_R_V_BLANK_IN_OSC_MASK = 0x2, -+ HDMI_FC_INVIDCONF_R_V_BLANK_IN_OSC_ACTIVE_HIGH = 0x2, -+ HDMI_FC_INVIDCONF_R_V_BLANK_IN_OSC_ACTIVE_LOW = 0x0, -+ HDMI_FC_INVIDCONF_IN_I_P_MASK = 0x1, -+ HDMI_FC_INVIDCONF_IN_I_P_INTERLACED = 0x1, -+ HDMI_FC_INVIDCONF_IN_I_P_PROGRESSIVE = 0x0, -+ -+/* FC_AUDICONF0 field values */ -+ HDMI_FC_AUDICONF0_CC_OFFSET = 4, -+ HDMI_FC_AUDICONF0_CC_MASK = 0x70, -+ HDMI_FC_AUDICONF0_CT_OFFSET = 0, -+ HDMI_FC_AUDICONF0_CT_MASK = 0xF, -+ -+/* FC_AUDICONF1 field values */ -+ HDMI_FC_AUDICONF1_SS_OFFSET = 3, -+ HDMI_FC_AUDICONF1_SS_MASK = 0x18, -+ HDMI_FC_AUDICONF1_SF_OFFSET = 0, -+ HDMI_FC_AUDICONF1_SF_MASK = 0x7, -+ -+/* FC_AUDICONF3 field values */ -+ HDMI_FC_AUDICONF3_LFEPBL_OFFSET = 5, -+ HDMI_FC_AUDICONF3_LFEPBL_MASK = 0x60, -+ HDMI_FC_AUDICONF3_DM_INH_OFFSET = 4, -+ HDMI_FC_AUDICONF3_DM_INH_MASK = 0x10, -+ HDMI_FC_AUDICONF3_LSV_OFFSET = 0, -+ HDMI_FC_AUDICONF3_LSV_MASK = 0xF, -+ -+/* FC_AUDSCHNLS0 field values */ -+ HDMI_FC_AUDSCHNLS0_CGMSA_OFFSET = 4, -+ HDMI_FC_AUDSCHNLS0_CGMSA_MASK = 0x30, -+ HDMI_FC_AUDSCHNLS0_COPYRIGHT_OFFSET = 0, -+ HDMI_FC_AUDSCHNLS0_COPYRIGHT_MASK = 0x01, -+ -+/* FC_AUDSCHNLS3-6 field values */ -+ HDMI_FC_AUDSCHNLS3_OIEC_CH0_OFFSET = 0, -+ HDMI_FC_AUDSCHNLS3_OIEC_CH0_MASK = 0x0f, -+ HDMI_FC_AUDSCHNLS3_OIEC_CH1_OFFSET = 4, -+ HDMI_FC_AUDSCHNLS3_OIEC_CH1_MASK = 0xf0, -+ HDMI_FC_AUDSCHNLS4_OIEC_CH2_OFFSET = 0, -+ HDMI_FC_AUDSCHNLS4_OIEC_CH2_MASK = 0x0f, -+ HDMI_FC_AUDSCHNLS4_OIEC_CH3_OFFSET = 4, -+ HDMI_FC_AUDSCHNLS4_OIEC_CH3_MASK = 0xf0, -+ -+ HDMI_FC_AUDSCHNLS5_OIEC_CH0_OFFSET = 0, -+ HDMI_FC_AUDSCHNLS5_OIEC_CH0_MASK = 0x0f, -+ HDMI_FC_AUDSCHNLS5_OIEC_CH1_OFFSET = 4, -+ HDMI_FC_AUDSCHNLS5_OIEC_CH1_MASK = 0xf0, -+ HDMI_FC_AUDSCHNLS6_OIEC_CH2_OFFSET = 0, -+ HDMI_FC_AUDSCHNLS6_OIEC_CH2_MASK = 0x0f, -+ HDMI_FC_AUDSCHNLS6_OIEC_CH3_OFFSET = 4, -+ HDMI_FC_AUDSCHNLS6_OIEC_CH3_MASK = 0xf0, -+ -+/* HDMI_FC_AUDSCHNLS7 field values */ -+ HDMI_FC_AUDSCHNLS7_ACCURACY_OFFSET = 4, -+ HDMI_FC_AUDSCHNLS7_ACCURACY_MASK = 0x30, -+ -+/* HDMI_FC_AUDSCHNLS8 field values */ -+ HDMI_FC_AUDSCHNLS8_ORIGSAMPFREQ_MASK = 0xf0, -+ HDMI_FC_AUDSCHNLS8_ORIGSAMPFREQ_OFFSET = 4, -+ HDMI_FC_AUDSCHNLS8_WORDLEGNTH_MASK = 0x0f, -+ HDMI_FC_AUDSCHNLS8_WORDLEGNTH_OFFSET = 0, -+ -+/* FC_AUDSCONF field values */ -+ HDMI_FC_AUDSCONF_AUD_PACKET_SAMPFIT_MASK = 0xF0, -+ HDMI_FC_AUDSCONF_AUD_PACKET_SAMPFIT_OFFSET = 4, -+ HDMI_FC_AUDSCONF_AUD_PACKET_LAYOUT_MASK = 0x1, -+ HDMI_FC_AUDSCONF_AUD_PACKET_LAYOUT_OFFSET = 0, -+ HDMI_FC_AUDSCONF_AUD_PACKET_LAYOUT_LAYOUT1 = 0x1, -+ HDMI_FC_AUDSCONF_AUD_PACKET_LAYOUT_LAYOUT0 = 0x0, -+ -+/* FC_STAT2 field values */ -+ HDMI_FC_STAT2_OVERFLOW_MASK = 0x03, -+ HDMI_FC_STAT2_LOW_PRIORITY_OVERFLOW = 0x02, -+ HDMI_FC_STAT2_HIGH_PRIORITY_OVERFLOW = 0x01, -+ -+/* FC_INT2 field values */ -+ HDMI_FC_INT2_OVERFLOW_MASK = 0x03, -+ HDMI_FC_INT2_LOW_PRIORITY_OVERFLOW = 0x02, -+ HDMI_FC_INT2_HIGH_PRIORITY_OVERFLOW = 0x01, -+ -+/* FC_MASK2 field values */ -+ HDMI_FC_MASK2_OVERFLOW_MASK = 0x03, -+ HDMI_FC_MASK2_LOW_PRIORITY_OVERFLOW = 0x02, -+ HDMI_FC_MASK2_HIGH_PRIORITY_OVERFLOW = 0x01, -+ -+/* FC_PRCONF field values */ -+ HDMI_FC_PRCONF_INCOMING_PR_FACTOR_MASK = 0xF0, -+ HDMI_FC_PRCONF_INCOMING_PR_FACTOR_OFFSET = 4, -+ HDMI_FC_PRCONF_OUTPUT_PR_FACTOR_MASK = 0x0F, -+ HDMI_FC_PRCONF_OUTPUT_PR_FACTOR_OFFSET = 0, -+ -+/* FC_AVICONF0-FC_AVICONF3 field values */ -+ HDMI_FC_AVICONF0_PIX_FMT_MASK = 0x03, -+ HDMI_FC_AVICONF0_PIX_FMT_RGB = 0x00, -+ HDMI_FC_AVICONF0_PIX_FMT_YCBCR422 = 0x01, -+ HDMI_FC_AVICONF0_PIX_FMT_YCBCR444 = 0x02, -+ HDMI_FC_AVICONF0_ACTIVE_FMT_MASK = 0x40, -+ HDMI_FC_AVICONF0_ACTIVE_FMT_INFO_PRESENT = 0x40, -+ HDMI_FC_AVICONF0_ACTIVE_FMT_NO_INFO = 0x00, -+ HDMI_FC_AVICONF0_BAR_DATA_MASK = 0x0C, -+ HDMI_FC_AVICONF0_BAR_DATA_NO_DATA = 0x00, -+ HDMI_FC_AVICONF0_BAR_DATA_VERT_BAR = 0x04, -+ HDMI_FC_AVICONF0_BAR_DATA_HORIZ_BAR = 0x08, -+ HDMI_FC_AVICONF0_BAR_DATA_VERT_HORIZ_BAR = 0x0C, -+ HDMI_FC_AVICONF0_SCAN_INFO_MASK = 0x30, -+ HDMI_FC_AVICONF0_SCAN_INFO_OVERSCAN = 0x10, -+ HDMI_FC_AVICONF0_SCAN_INFO_UNDERSCAN = 0x20, -+ HDMI_FC_AVICONF0_SCAN_INFO_NODATA = 0x00, -+ -+ HDMI_FC_AVICONF1_ACTIVE_ASPECT_RATIO_MASK = 0x0F, -+ HDMI_FC_AVICONF1_ACTIVE_ASPECT_RATIO_USE_CODED = 0x08, -+ HDMI_FC_AVICONF1_ACTIVE_ASPECT_RATIO_4_3 = 0x09, -+ HDMI_FC_AVICONF1_ACTIVE_ASPECT_RATIO_16_9 = 0x0A, -+ HDMI_FC_AVICONF1_ACTIVE_ASPECT_RATIO_14_9 = 0x0B, -+ HDMI_FC_AVICONF1_CODED_ASPECT_RATIO_MASK = 0x30, -+ HDMI_FC_AVICONF1_CODED_ASPECT_RATIO_NO_DATA = 0x00, -+ HDMI_FC_AVICONF1_CODED_ASPECT_RATIO_4_3 = 0x10, -+ HDMI_FC_AVICONF1_CODED_ASPECT_RATIO_16_9 = 0x20, -+ HDMI_FC_AVICONF1_COLORIMETRY_MASK = 0xC0, -+ HDMI_FC_AVICONF1_COLORIMETRY_NO_DATA = 0x00, -+ HDMI_FC_AVICONF1_COLORIMETRY_SMPTE = 0x40, -+ HDMI_FC_AVICONF1_COLORIMETRY_ITUR = 0x80, -+ HDMI_FC_AVICONF1_COLORIMETRY_EXTENDED_INFO = 0xC0, -+ -+ HDMI_FC_AVICONF2_SCALING_MASK = 0x03, -+ HDMI_FC_AVICONF2_SCALING_NONE = 0x00, -+ HDMI_FC_AVICONF2_SCALING_HORIZ = 0x01, -+ HDMI_FC_AVICONF2_SCALING_VERT = 0x02, -+ HDMI_FC_AVICONF2_SCALING_HORIZ_VERT = 0x03, -+ HDMI_FC_AVICONF2_RGB_QUANT_MASK = 0x0C, -+ HDMI_FC_AVICONF2_RGB_QUANT_DEFAULT = 0x00, -+ HDMI_FC_AVICONF2_RGB_QUANT_LIMITED_RANGE = 0x04, -+ HDMI_FC_AVICONF2_RGB_QUANT_FULL_RANGE = 0x08, -+ HDMI_FC_AVICONF2_EXT_COLORIMETRY_MASK = 0x70, -+ HDMI_FC_AVICONF2_EXT_COLORIMETRY_XVYCC601 = 0x00, -+ HDMI_FC_AVICONF2_EXT_COLORIMETRY_XVYCC709 = 0x10, -+ HDMI_FC_AVICONF2_EXT_COLORIMETRY_SYCC601 = 0x20, -+ HDMI_FC_AVICONF2_EXT_COLORIMETRY_ADOBE_YCC601 = 0x30, -+ HDMI_FC_AVICONF2_EXT_COLORIMETRY_ADOBE_RGB = 0x40, -+ HDMI_FC_AVICONF2_IT_CONTENT_MASK = 0x80, -+ HDMI_FC_AVICONF2_IT_CONTENT_NO_DATA = 0x00, -+ HDMI_FC_AVICONF2_IT_CONTENT_VALID = 0x80, -+ -+ HDMI_FC_AVICONF3_IT_CONTENT_TYPE_MASK = 0x03, -+ HDMI_FC_AVICONF3_IT_CONTENT_TYPE_GRAPHICS = 0x00, -+ HDMI_FC_AVICONF3_IT_CONTENT_TYPE_PHOTO = 0x01, -+ HDMI_FC_AVICONF3_IT_CONTENT_TYPE_CINEMA = 0x02, -+ HDMI_FC_AVICONF3_IT_CONTENT_TYPE_GAME = 0x03, -+ HDMI_FC_AVICONF3_QUANT_RANGE_MASK = 0x0C, -+ HDMI_FC_AVICONF3_QUANT_RANGE_LIMITED = 0x00, -+ HDMI_FC_AVICONF3_QUANT_RANGE_FULL = 0x04, -+ -+/* FC_DBGFORCE field values */ -+ HDMI_FC_DBGFORCE_FORCEAUDIO = 0x10, -+ HDMI_FC_DBGFORCE_FORCEVIDEO = 0x1, -+ -+/* PHY_CONF0 field values */ -+ HDMI_PHY_CONF0_PDZ_MASK = 0x80, -+ HDMI_PHY_CONF0_PDZ_OFFSET = 7, -+ HDMI_PHY_CONF0_ENTMDS_MASK = 0x40, -+ HDMI_PHY_CONF0_ENTMDS_OFFSET = 6, -+ HDMI_PHY_CONF0_SVSRET_MASK = 0x20, -+ HDMI_PHY_CONF0_SVSRET_OFFSET = 5, -+ HDMI_PHY_CONF0_GEN2_PDDQ_MASK = 0x10, -+ HDMI_PHY_CONF0_GEN2_PDDQ_OFFSET = 4, -+ HDMI_PHY_CONF0_GEN2_TXPWRON_MASK = 0x8, -+ HDMI_PHY_CONF0_GEN2_TXPWRON_OFFSET = 3, -+ HDMI_PHY_CONF0_GEN2_ENHPDRXSENSE_MASK = 0x4, -+ HDMI_PHY_CONF0_GEN2_ENHPDRXSENSE_OFFSET = 2, -+ HDMI_PHY_CONF0_SELDATAENPOL_MASK = 0x2, -+ HDMI_PHY_CONF0_SELDATAENPOL_OFFSET = 1, -+ HDMI_PHY_CONF0_SELDIPIF_MASK = 0x1, -+ HDMI_PHY_CONF0_SELDIPIF_OFFSET = 0, -+ -+/* PHY_TST0 field values */ -+ HDMI_PHY_TST0_TSTCLR_MASK = 0x20, -+ HDMI_PHY_TST0_TSTCLR_OFFSET = 5, -+ HDMI_PHY_TST0_TSTEN_MASK = 0x10, -+ HDMI_PHY_TST0_TSTEN_OFFSET = 4, -+ HDMI_PHY_TST0_TSTCLK_MASK = 0x1, -+ HDMI_PHY_TST0_TSTCLK_OFFSET = 0, -+ -+/* PHY_STAT0 field values */ -+ HDMI_PHY_RX_SENSE3 = 0x80, -+ HDMI_PHY_RX_SENSE2 = 0x40, -+ HDMI_PHY_RX_SENSE1 = 0x20, -+ HDMI_PHY_RX_SENSE0 = 0x10, -+ HDMI_PHY_HPD = 0x02, -+ HDMI_PHY_TX_PHY_LOCK = 0x01, -+ -+/* PHY_I2CM_SLAVE_ADDR field values */ -+ HDMI_PHY_I2CM_SLAVE_ADDR_PHY_GEN2 = 0x69, -+ HDMI_PHY_I2CM_SLAVE_ADDR_HEAC_PHY = 0x49, -+ -+/* PHY_I2CM_OPERATION_ADDR field values */ -+ HDMI_PHY_I2CM_OPERATION_ADDR_WRITE = 0x10, -+ HDMI_PHY_I2CM_OPERATION_ADDR_READ = 0x1, -+ -+/* HDMI_PHY_I2CM_INT_ADDR */ -+ HDMI_PHY_I2CM_INT_ADDR_DONE_POL = 0x08, -+ HDMI_PHY_I2CM_INT_ADDR_DONE_MASK = 0x04, -+ -+/* HDMI_PHY_I2CM_CTLINT_ADDR */ -+ HDMI_PHY_I2CM_CTLINT_ADDR_NAC_POL = 0x80, -+ HDMI_PHY_I2CM_CTLINT_ADDR_NAC_MASK = 0x40, -+ HDMI_PHY_I2CM_CTLINT_ADDR_ARBITRATION_POL = 0x08, -+ HDMI_PHY_I2CM_CTLINT_ADDR_ARBITRATION_MASK = 0x04, -+ -+/* AUD_CONF0 field values */ -+ HDMI_AUD_CONF0_SW_RESET = 0x80, -+ HDMI_AUD_CONF0_I2S_ALL_ENABLE = 0x2F, -+ -+/* AUD_CONF1 field values */ -+ HDMI_AUD_CONF1_MODE_I2S = 0x00, -+ HDMI_AUD_CONF1_MODE_RIGHT_J = 0x02, -+ HDMI_AUD_CONF1_MODE_LEFT_J = 0x04, -+ HDMI_AUD_CONF1_WIDTH_16 = 0x10, -+ HDMI_AUD_CONF1_WIDTH_24 = 0x18, -+ -+/* AUD_CTS3 field values */ -+ HDMI_AUD_CTS3_N_SHIFT_OFFSET = 5, -+ HDMI_AUD_CTS3_N_SHIFT_MASK = 0xe0, -+ HDMI_AUD_CTS3_N_SHIFT_1 = 0, -+ HDMI_AUD_CTS3_N_SHIFT_16 = 0x20, -+ HDMI_AUD_CTS3_N_SHIFT_32 = 0x40, -+ HDMI_AUD_CTS3_N_SHIFT_64 = 0x60, -+ HDMI_AUD_CTS3_N_SHIFT_128 = 0x80, -+ HDMI_AUD_CTS3_N_SHIFT_256 = 0xa0, -+ /* note that the CTS3 MANUAL bit has been removed -+ from our part. Can't set it, will read as 0. */ -+ HDMI_AUD_CTS3_CTS_MANUAL = 0x10, -+ HDMI_AUD_CTS3_AUDCTS19_16_MASK = 0x0f, -+ -+/* HDMI_AUD_INPUTCLKFS field values */ -+ HDMI_AUD_INPUTCLKFS_128FS = 0, -+ HDMI_AUD_INPUTCLKFS_256FS = 1, -+ HDMI_AUD_INPUTCLKFS_512FS = 2, -+ HDMI_AUD_INPUTCLKFS_64FS = 4, -+ -+/* AHB_DMA_CONF0 field values */ -+ HDMI_AHB_DMA_CONF0_SW_FIFO_RST_OFFSET = 7, -+ HDMI_AHB_DMA_CONF0_SW_FIFO_RST_MASK = 0x80, -+ HDMI_AHB_DMA_CONF0_HBR = 0x10, -+ HDMI_AHB_DMA_CONF0_EN_HLOCK_OFFSET = 3, -+ HDMI_AHB_DMA_CONF0_EN_HLOCK_MASK = 0x08, -+ HDMI_AHB_DMA_CONF0_INCR_TYPE_OFFSET = 1, -+ HDMI_AHB_DMA_CONF0_INCR_TYPE_MASK = 0x06, -+ HDMI_AHB_DMA_CONF0_INCR4 = 0x0, -+ HDMI_AHB_DMA_CONF0_INCR8 = 0x2, -+ HDMI_AHB_DMA_CONF0_INCR16 = 0x4, -+ HDMI_AHB_DMA_CONF0_BURST_MODE = 0x1, -+ -+/* HDMI_AHB_DMA_START field values */ -+ HDMI_AHB_DMA_START_START_OFFSET = 0, -+ HDMI_AHB_DMA_START_START_MASK = 0x01, -+ -+/* HDMI_AHB_DMA_STOP field values */ -+ HDMI_AHB_DMA_STOP_STOP_OFFSET = 0, -+ HDMI_AHB_DMA_STOP_STOP_MASK = 0x01, -+ -+/* AHB_DMA_STAT, AHB_DMA_INT, AHB_DMA_MASK, AHB_DMA_POL field values */ -+ HDMI_AHB_DMA_DONE = 0x80, -+ HDMI_AHB_DMA_RETRY_SPLIT = 0x40, -+ HDMI_AHB_DMA_LOSTOWNERSHIP = 0x20, -+ HDMI_AHB_DMA_ERROR = 0x10, -+ HDMI_AHB_DMA_FIFO_THREMPTY = 0x04, -+ HDMI_AHB_DMA_FIFO_FULL = 0x02, -+ HDMI_AHB_DMA_FIFO_EMPTY = 0x01, -+ -+/* AHB_DMA_BUFFSTAT, AHB_DMA_BUFFINT,AHB_DMA_BUFFMASK,AHB_DMA_BUFFPOL values */ -+ HDMI_AHB_DMA_BUFFSTAT_FULL = 0x02, -+ HDMI_AHB_DMA_BUFFSTAT_EMPTY = 0x01, -+ -+/* MC_CLKDIS field values */ -+ HDMI_MC_CLKDIS_HDCPCLK_DISABLE = 0x40, -+ HDMI_MC_CLKDIS_CECCLK_DISABLE = 0x20, -+ HDMI_MC_CLKDIS_CSCCLK_DISABLE = 0x10, -+ HDMI_MC_CLKDIS_AUDCLK_DISABLE = 0x8, -+ HDMI_MC_CLKDIS_PREPCLK_DISABLE = 0x4, -+ HDMI_MC_CLKDIS_TMDSCLK_DISABLE = 0x2, -+ HDMI_MC_CLKDIS_PIXELCLK_DISABLE = 0x1, -+ -+/* MC_SWRSTZ field values */ -+ HDMI_MC_SWRSTZ_TMDSSWRST_REQ = 0x02, -+ -+/* MC_FLOWCTRL field values */ -+ HDMI_MC_FLOWCTRL_FEED_THROUGH_OFF_MASK = 0x1, -+ HDMI_MC_FLOWCTRL_FEED_THROUGH_OFF_CSC_IN_PATH = 0x1, -+ HDMI_MC_FLOWCTRL_FEED_THROUGH_OFF_CSC_BYPASS = 0x0, -+ -+/* MC_PHYRSTZ field values */ -+ HDMI_MC_PHYRSTZ_PHYRSTZ = 0x01, -+ -+/* MC_HEACPHY_RST field values */ -+ HDMI_MC_HEACPHY_RST_ASSERT = 0x1, -+ HDMI_MC_HEACPHY_RST_DEASSERT = 0x0, -+ -+/* CSC_CFG field values */ -+ HDMI_CSC_CFG_INTMODE_MASK = 0x30, -+ HDMI_CSC_CFG_INTMODE_OFFSET = 4, -+ HDMI_CSC_CFG_INTMODE_DISABLE = 0x00, -+ HDMI_CSC_CFG_INTMODE_CHROMA_INT_FORMULA1 = 0x10, -+ HDMI_CSC_CFG_INTMODE_CHROMA_INT_FORMULA2 = 0x20, -+ HDMI_CSC_CFG_DECMODE_MASK = 0x3, -+ HDMI_CSC_CFG_DECMODE_OFFSET = 0, -+ HDMI_CSC_CFG_DECMODE_DISABLE = 0x0, -+ HDMI_CSC_CFG_DECMODE_CHROMA_INT_FORMULA1 = 0x1, -+ HDMI_CSC_CFG_DECMODE_CHROMA_INT_FORMULA2 = 0x2, -+ HDMI_CSC_CFG_DECMODE_CHROMA_INT_FORMULA3 = 0x3, -+ -+/* CSC_SCALE field values */ -+ HDMI_CSC_SCALE_CSC_COLORDE_PTH_MASK = 0xF0, -+ HDMI_CSC_SCALE_CSC_COLORDE_PTH_24BPP = 0x00, -+ HDMI_CSC_SCALE_CSC_COLORDE_PTH_30BPP = 0x50, -+ HDMI_CSC_SCALE_CSC_COLORDE_PTH_36BPP = 0x60, -+ HDMI_CSC_SCALE_CSC_COLORDE_PTH_48BPP = 0x70, -+ HDMI_CSC_SCALE_CSCSCALE_MASK = 0x03, -+ -+/* A_HDCPCFG0 field values */ -+ HDMI_A_HDCPCFG0_ELVENA_MASK = 0x80, -+ HDMI_A_HDCPCFG0_ELVENA_ENABLE = 0x80, -+ HDMI_A_HDCPCFG0_ELVENA_DISABLE = 0x00, -+ HDMI_A_HDCPCFG0_I2CFASTMODE_MASK = 0x40, -+ HDMI_A_HDCPCFG0_I2CFASTMODE_ENABLE = 0x40, -+ HDMI_A_HDCPCFG0_I2CFASTMODE_DISABLE = 0x00, -+ HDMI_A_HDCPCFG0_BYPENCRYPTION_MASK = 0x20, -+ HDMI_A_HDCPCFG0_BYPENCRYPTION_ENABLE = 0x20, -+ HDMI_A_HDCPCFG0_BYPENCRYPTION_DISABLE = 0x00, -+ HDMI_A_HDCPCFG0_SYNCRICHECK_MASK = 0x10, -+ HDMI_A_HDCPCFG0_SYNCRICHECK_ENABLE = 0x10, -+ HDMI_A_HDCPCFG0_SYNCRICHECK_DISABLE = 0x00, -+ HDMI_A_HDCPCFG0_AVMUTE_MASK = 0x8, -+ HDMI_A_HDCPCFG0_AVMUTE_ENABLE = 0x8, -+ HDMI_A_HDCPCFG0_AVMUTE_DISABLE = 0x0, -+ HDMI_A_HDCPCFG0_RXDETECT_MASK = 0x4, -+ HDMI_A_HDCPCFG0_RXDETECT_ENABLE = 0x4, -+ HDMI_A_HDCPCFG0_RXDETECT_DISABLE = 0x0, -+ HDMI_A_HDCPCFG0_EN11FEATURE_MASK = 0x2, -+ HDMI_A_HDCPCFG0_EN11FEATURE_ENABLE = 0x2, -+ HDMI_A_HDCPCFG0_EN11FEATURE_DISABLE = 0x0, -+ HDMI_A_HDCPCFG0_HDMIDVI_MASK = 0x1, -+ HDMI_A_HDCPCFG0_HDMIDVI_HDMI = 0x1, -+ HDMI_A_HDCPCFG0_HDMIDVI_DVI = 0x0, -+ -+/* A_HDCPCFG1 field values */ -+ HDMI_A_HDCPCFG1_DISSHA1CHECK_MASK = 0x8, -+ HDMI_A_HDCPCFG1_DISSHA1CHECK_DISABLE = 0x8, -+ HDMI_A_HDCPCFG1_DISSHA1CHECK_ENABLE = 0x0, -+ HDMI_A_HDCPCFG1_PH2UPSHFTENC_MASK = 0x4, -+ HDMI_A_HDCPCFG1_PH2UPSHFTENC_ENABLE = 0x4, -+ HDMI_A_HDCPCFG1_PH2UPSHFTENC_DISABLE = 0x0, -+ HDMI_A_HDCPCFG1_ENCRYPTIONDISABLE_MASK = 0x2, -+ HDMI_A_HDCPCFG1_ENCRYPTIONDISABLE_DISABLE = 0x2, -+ HDMI_A_HDCPCFG1_ENCRYPTIONDISABLE_ENABLE = 0x0, -+ HDMI_A_HDCPCFG1_SWRESET_MASK = 0x1, -+ HDMI_A_HDCPCFG1_SWRESET_ASSERT = 0x0, -+ -+/* A_VIDPOLCFG field values */ -+ HDMI_A_VIDPOLCFG_UNENCRYPTCONF_MASK = 0x60, -+ HDMI_A_VIDPOLCFG_UNENCRYPTCONF_OFFSET = 5, -+ HDMI_A_VIDPOLCFG_DATAENPOL_MASK = 0x10, -+ HDMI_A_VIDPOLCFG_DATAENPOL_ACTIVE_HIGH = 0x10, -+ HDMI_A_VIDPOLCFG_DATAENPOL_ACTIVE_LOW = 0x0, -+ HDMI_A_VIDPOLCFG_VSYNCPOL_MASK = 0x8, -+ HDMI_A_VIDPOLCFG_VSYNCPOL_ACTIVE_HIGH = 0x8, -+ HDMI_A_VIDPOLCFG_VSYNCPOL_ACTIVE_LOW = 0x0, -+ HDMI_A_VIDPOLCFG_HSYNCPOL_MASK = 0x2, -+ HDMI_A_VIDPOLCFG_HSYNCPOL_ACTIVE_HIGH = 0x2, -+ HDMI_A_VIDPOLCFG_HSYNCPOL_ACTIVE_LOW = 0x0, -+ -+/* I2CM_OPERATION field values */ -+ HDMI_I2CM_OPERATION_WRITE = 0x10, -+ HDMI_I2CM_OPERATION_READ_EXT = 0x2, -+ HDMI_I2CM_OPERATION_READ = 0x1, -+ -+/* I2CM_INT field values */ -+ HDMI_I2CM_INT_DONE_POL = 0x8, -+ HDMI_I2CM_INT_DONE_MASK = 0x4, -+ -+/* I2CM_CTLINT field values */ -+ HDMI_I2CM_CTLINT_NAC_POL = 0x80, -+ HDMI_I2CM_CTLINT_NAC_MASK = 0x40, -+ HDMI_I2CM_CTLINT_ARB_POL = 0x8, -+ HDMI_I2CM_CTLINT_ARB_MASK = 0x4, -+}; -+ -+/* -+ * HDMI 3D TX PHY registers -+ */ -+#define HDMI_3D_TX_PHY_PWRCTRL 0x00 -+#define HDMI_3D_TX_PHY_SERDIVCTRL 0x01 -+#define HDMI_3D_TX_PHY_SERCKCTRL 0x02 -+#define HDMI_3D_TX_PHY_SERCKKILLCTRL 0x03 -+#define HDMI_3D_TX_PHY_TXRESCTRL 0x04 -+#define HDMI_3D_TX_PHY_CKCALCTRL 0x05 -+#define HDMI_3D_TX_PHY_CPCE_CTRL 0x06 -+#define HDMI_3D_TX_PHY_TXCLKMEASCTRL 0x07 -+#define HDMI_3D_TX_PHY_TXMEASCTRL 0x08 -+#define HDMI_3D_TX_PHY_CKSYMTXCTRL 0x09 -+#define HDMI_3D_TX_PHY_CMPSEQCTRL 0x0a -+#define HDMI_3D_TX_PHY_CMPPWRCTRL 0x0b -+#define HDMI_3D_TX_PHY_CMPMODECTRL 0x0c -+#define HDMI_3D_TX_PHY_MEASCTRL 0x0d -+#define HDMI_3D_TX_PHY_VLEVCTRL 0x0e -+#define HDMI_3D_TX_PHY_D2ACTRL 0x0f -+#define HDMI_3D_TX_PHY_CURRCTRL 0x10 -+#define HDMI_3D_TX_PHY_DRVANACTRL 0x11 -+#define HDMI_3D_TX_PHY_PLLMEASCTRL 0x12 -+#define HDMI_3D_TX_PHY_PLLPHBYCTRL 0x13 -+#define HDMI_3D_TX_PHY_GRP_CTRL 0x14 -+#define HDMI_3D_TX_PHY_GMPCTRL 0x15 -+#define HDMI_3D_TX_PHY_MPLLMEASCTRL 0x16 -+#define HDMI_3D_TX_PHY_MSM_CTRL 0x17 -+#define HDMI_3D_TX_PHY_SCRPB_STATUS 0x18 -+#define HDMI_3D_TX_PHY_TXTERM 0x19 -+#define HDMI_3D_TX_PHY_PTRPT_ENBL 0x1a -+#define HDMI_3D_TX_PHY_PATTERNGEN 0x1b -+#define HDMI_3D_TX_PHY_SDCAP_MODE 0x1c -+#define HDMI_3D_TX_PHY_SCOPEMODE 0x1d -+#define HDMI_3D_TX_PHY_DIGTXMODE 0x1e -+#define HDMI_3D_TX_PHY_STR_STATUS 0x1f -+#define HDMI_3D_TX_PHY_SCOPECNT0 0x20 -+#define HDMI_3D_TX_PHY_SCOPECNT1 0x21 -+#define HDMI_3D_TX_PHY_SCOPECNT2 0x22 -+#define HDMI_3D_TX_PHY_SCOPECNTCLK 0x23 -+#define HDMI_3D_TX_PHY_SCOPESAMPLE 0x24 -+#define HDMI_3D_TX_PHY_SCOPECNTMSB01 0x25 -+#define HDMI_3D_TX_PHY_SCOPECNTMSB2CK 0x26 -+ -+/* HDMI_3D_TX_PHY_CKCALCTRL values */ -+#define HDMI_3D_TX_PHY_CKCALCTRL_OVERRIDE BIT(15) -+ -+/* HDMI_3D_TX_PHY_MSM_CTRL values */ -+#define HDMI_3D_TX_PHY_MSM_CTRL_MPLL_PH_SEL_CK BIT(13) -+#define HDMI_3D_TX_PHY_MSM_CTRL_CKO_SEL_CLK_REF_MPLL (0 << 1) -+#define HDMI_3D_TX_PHY_MSM_CTRL_CKO_SEL_OFF (1 << 1) -+#define HDMI_3D_TX_PHY_MSM_CTRL_CKO_SEL_PCLK (2 << 1) -+#define HDMI_3D_TX_PHY_MSM_CTRL_CKO_SEL_FB_CLK (3 << 1) -+#define HDMI_3D_TX_PHY_MSM_CTRL_SCOPE_CK_SEL BIT(0) -+ -+/* HDMI_3D_TX_PHY_PTRPT_ENBL values */ -+#define HDMI_3D_TX_PHY_PTRPT_ENBL_OVERRIDE BIT(15) -+#define HDMI_3D_TX_PHY_PTRPT_ENBL_PG_SKIP_BIT2 BIT(8) -+#define HDMI_3D_TX_PHY_PTRPT_ENBL_PG_SKIP_BIT1 BIT(7) -+#define HDMI_3D_TX_PHY_PTRPT_ENBL_PG_SKIP_BIT0 BIT(6) -+#define HDMI_3D_TX_PHY_PTRPT_ENBL_CK_REF_ENB BIT(5) -+#define HDMI_3D_TX_PHY_PTRPT_ENBL_RCAL_ENB BIT(4) -+#define HDMI_3D_TX_PHY_PTRPT_ENBL_TX_CLK_ALIGN_ENB BIT(3) -+#define HDMI_3D_TX_PHY_PTRPT_ENBL_TX_READY BIT(2) -+#define HDMI_3D_TX_PHY_PTRPT_ENBL_CKO_WORD_ENB BIT(1) -+#define HDMI_3D_TX_PHY_PTRPT_ENBL_REFCLK_ENB BIT(0) -+ -+#endif /* __DW_HDMI_H__ */ --- -1.9.1 - diff --git a/patch/kernel/odroidc2-next/0041-ARM64-dts-meson-gxbb-p20x-add-i2s-and-spdif-output-i.patch b/patch/kernel/odroidc2-next/0041-ARM64-dts-meson-gxbb-p20x-add-i2s-and-spdif-output-i.patch new file mode 100644 index 000000000..196d17a26 --- /dev/null +++ b/patch/kernel/odroidc2-next/0041-ARM64-dts-meson-gxbb-p20x-add-i2s-and-spdif-output-i.patch @@ -0,0 +1,51 @@ +From 9f335bad0a74dc58e5450260dbfaa59911dfaa31 Mon Sep 17 00:00:00 2001 +From: Jerome Brunet +Date: Thu, 30 Mar 2017 15:40:20 +0200 +Subject: [PATCH 41/79] ARM64: dts: meson-gxbb-p20x: add i2s and spdif output + interfaces + +Add the necessary pins for the i2s and spdif audio interface output and +enable these interfaces + +Signed-off-by: Jerome Brunet +Signed-off-by: Neil Armstrong +--- + arch/arm64/boot/dts/amlogic/meson-gxbb-p20x.dtsi | 25 ++++++++++++++++++++++++ + 1 file changed, 25 insertions(+) + +diff --git a/arch/arm64/boot/dts/amlogic/meson-gxbb-p20x.dtsi b/arch/arm64/boot/dts/amlogic/meson-gxbb-p20x.dtsi +index c8559be..d36f82b0 100644 +--- a/arch/arm64/boot/dts/amlogic/meson-gxbb-p20x.dtsi ++++ b/arch/arm64/boot/dts/amlogic/meson-gxbb-p20x.dtsi +@@ -292,3 +292,28 @@ + remote-endpoint = <&hdmi_connector_in>; + }; + }; ++ ++&audio { ++ status = "okay"; ++}; ++ ++&aiu_i2s_dma { ++ status = "okay"; ++}; ++ ++&aiu_spdif_dma { ++ status = "okay"; ++}; ++ ++&i2s_dai { ++ pinctrl-0 = <&i2s_am_clk_pins>, <&i2s_out_ao_clk_pins>, ++ <&i2s_out_lr_clk_pins>, <&i2s_out_ch01_ao_pins>; ++ pinctrl-names = "default"; ++ status = "okay"; ++}; ++ ++&spdif_dai { ++ pinctrl-0 = <&spdif_out_ao_6_pins>; ++ pinctrl-names = "default"; ++ status = "okay"; ++}; +-- +1.9.1 + diff --git a/patch/kernel/odroidc2-next/0041-drm-bridge-dw_hdmi-support-i2c-extended-read-mode.patch b/patch/kernel/odroidc2-next/0041-drm-bridge-dw_hdmi-support-i2c-extended-read-mode.patch deleted file mode 100644 index a520f9751..000000000 --- a/patch/kernel/odroidc2-next/0041-drm-bridge-dw_hdmi-support-i2c-extended-read-mode.patch +++ /dev/null @@ -1,115 +0,0 @@ -From 8d012e114e251f5427cb46851ce47e43b745e6c3 Mon Sep 17 00:00:00 2001 -From: Nickey Yang -Date: Mon, 20 Mar 2017 10:57:31 +0800 -Subject: [PATCH 41/93] drm/bridge: dw_hdmi: support i2c extended read mode - -"I2C Master Interface Extended Read Mode" implements a segment -pointer-based read operation using the Special Register configuration. - -This patch fix https://patchwork.kernel.org/patch/7098101/ mentioned -"The current implementation does not support "I2C Master Interface -Extended Read Mode" to read data addressed by non-zero segment -pointer, this means that if EDID has more than 1 extension blocks, -EDID reading operation won't succeed" - -With this patch, dw-hdmi can read EDID data with 1/2/4 blocks. - -Signed-off-by: Nickey Yang -Reviewed-by: Douglas Anderson -Acked-by: Vladimir Zapolskiy -Signed-off-by: Archit Taneja -Link: http://patchwork.freedesktop.org/patch/msgid/1489978651-16647-1-git-send-email-nickey.yang@rock-chips.com ---- - drivers/gpu/drm/bridge/synopsys/dw-hdmi.c | 38 +++++++++++++++++++------------ - 1 file changed, 24 insertions(+), 14 deletions(-) - -diff --git a/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c b/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c -index 026a0dc..0d112cf 100644 ---- a/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c -+++ b/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c -@@ -33,6 +33,7 @@ - #include "dw-hdmi.h" - #include "dw-hdmi-audio.h" - -+#define DDC_SEGMENT_ADDR 0x30 - #define HDMI_EDID_LEN 512 - - #define RGB 0 -@@ -112,6 +113,7 @@ struct dw_hdmi_i2c { - - u8 slave_reg; - bool is_regaddr; -+ bool is_segment; - }; - - struct dw_hdmi_phy_data { -@@ -247,8 +249,12 @@ static int dw_hdmi_i2c_read(struct dw_hdmi *hdmi, - reinit_completion(&i2c->cmp); - - hdmi_writeb(hdmi, i2c->slave_reg++, HDMI_I2CM_ADDRESS); -- hdmi_writeb(hdmi, HDMI_I2CM_OPERATION_READ, -- HDMI_I2CM_OPERATION); -+ if (i2c->is_segment) -+ hdmi_writeb(hdmi, HDMI_I2CM_OPERATION_READ_EXT, -+ HDMI_I2CM_OPERATION); -+ else -+ hdmi_writeb(hdmi, HDMI_I2CM_OPERATION_READ, -+ HDMI_I2CM_OPERATION); - - stat = wait_for_completion_timeout(&i2c->cmp, HZ / 10); - if (!stat) -@@ -260,6 +266,7 @@ static int dw_hdmi_i2c_read(struct dw_hdmi *hdmi, - - *buf++ = hdmi_readb(hdmi, HDMI_I2CM_DATAI); - } -+ i2c->is_segment = false; - - return 0; - } -@@ -309,12 +316,6 @@ static int dw_hdmi_i2c_xfer(struct i2c_adapter *adap, - dev_dbg(hdmi->dev, "xfer: num: %d, addr: %#x\n", num, addr); - - for (i = 0; i < num; i++) { -- if (msgs[i].addr != addr) { -- dev_warn(hdmi->dev, -- "unsupported transfer, changed slave address\n"); -- return -EOPNOTSUPP; -- } -- - if (msgs[i].len == 0) { - dev_dbg(hdmi->dev, - "unsupported transfer %d/%d, no data\n", -@@ -334,15 +335,24 @@ static int dw_hdmi_i2c_xfer(struct i2c_adapter *adap, - /* Set slave device register address on transfer */ - i2c->is_regaddr = false; - -+ /* Set segment pointer for I2C extended read mode operation */ -+ i2c->is_segment = false; -+ - for (i = 0; i < num; i++) { - dev_dbg(hdmi->dev, "xfer: num: %d/%d, len: %d, flags: %#x\n", - i + 1, num, msgs[i].len, msgs[i].flags); -- -- if (msgs[i].flags & I2C_M_RD) -- ret = dw_hdmi_i2c_read(hdmi, msgs[i].buf, msgs[i].len); -- else -- ret = dw_hdmi_i2c_write(hdmi, msgs[i].buf, msgs[i].len); -- -+ if (msgs[i].addr == DDC_SEGMENT_ADDR && msgs[i].len == 1) { -+ i2c->is_segment = true; -+ hdmi_writeb(hdmi, DDC_SEGMENT_ADDR, HDMI_I2CM_SEGADDR); -+ hdmi_writeb(hdmi, *msgs[i].buf, HDMI_I2CM_SEGPTR); -+ } else { -+ if (msgs[i].flags & I2C_M_RD) -+ ret = dw_hdmi_i2c_read(hdmi, msgs[i].buf, -+ msgs[i].len); -+ else -+ ret = dw_hdmi_i2c_write(hdmi, msgs[i].buf, -+ msgs[i].len); -+ } - if (ret < 0) - break; - } --- -1.9.1 - diff --git a/patch/kernel/odroidc2-next/0042-ARM64-dts-meson-gxl-p230-add-spdif-codec-node.patch b/patch/kernel/odroidc2-next/0042-ARM64-dts-meson-gxl-p230-add-spdif-codec-node.patch new file mode 100644 index 000000000..26222009b --- /dev/null +++ b/patch/kernel/odroidc2-next/0042-ARM64-dts-meson-gxl-p230-add-spdif-codec-node.patch @@ -0,0 +1,33 @@ +From bb66443e46eab9d08082e98b1c53c4ed9699e8b4 Mon Sep 17 00:00:00 2001 +From: Jerome Brunet +Date: Thu, 30 Mar 2017 17:53:57 +0200 +Subject: [PATCH 42/79] ARM64: dts: meson-gxl-p230: add spdif codec node + +Add spdif-dit node to the meson gxl reference design + +Signed-off-by: Jerome Brunet +Signed-off-by: Neil Armstrong +--- + arch/arm64/boot/dts/amlogic/meson-gxl-s905d-p230.dts | 6 ++++++ + 1 file changed, 6 insertions(+) + +diff --git a/arch/arm64/boot/dts/amlogic/meson-gxl-s905d-p230.dts b/arch/arm64/boot/dts/amlogic/meson-gxl-s905d-p230.dts +index 49e19aa..3837560 100644 +--- a/arch/arm64/boot/dts/amlogic/meson-gxl-s905d-p230.dts ++++ b/arch/arm64/boot/dts/amlogic/meson-gxl-s905d-p230.dts +@@ -84,6 +84,12 @@ + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <1800000>; + }; ++ ++ spdif_out: spdif-out { ++ #sound-dai-cells = <0>; ++ compatible = "linux,spdif-dit"; ++ status = "okay"; ++ }; + }; + + &cec_AO { +-- +1.9.1 + diff --git a/patch/kernel/odroidc2-next/0042-drm-bridge-dw-hdmi-add-HDMI-vendor-specific-infofram.patch b/patch/kernel/odroidc2-next/0042-drm-bridge-dw-hdmi-add-HDMI-vendor-specific-infofram.patch deleted file mode 100644 index 61a6dbe00..000000000 --- a/patch/kernel/odroidc2-next/0042-drm-bridge-dw-hdmi-add-HDMI-vendor-specific-infofram.patch +++ /dev/null @@ -1,107 +0,0 @@ -From 7feb88b4b876148c48911d2c9733fcab0e877cd9 Mon Sep 17 00:00:00 2001 -From: Nickey Yang -Date: Tue, 21 Mar 2017 15:36:17 +0800 -Subject: [PATCH 42/93] drm: bridge: dw-hdmi: add HDMI vendor specific - infoframe config - -Vendor specific infoframe is mandatory for 4K2K resolution. -Without this, the HDMI protocol compliance fails. - -Signed-off-by: Nickey Yang -Reviewed-by: Jose Abreu -Signed-off-by: Archit Taneja -Link: http://patchwork.freedesktop.org/patch/msgid/1490081777-2232-1-git-send-email-nickey.yang@rock-chips.com ---- - drivers/gpu/drm/bridge/synopsys/dw-hdmi.c | 53 +++++++++++++++++++++++++++++++ - drivers/gpu/drm/bridge/synopsys/dw-hdmi.h | 4 +++ - 2 files changed, 57 insertions(+) - -diff --git a/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c b/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c -index 0d112cf..af93f7a 100644 ---- a/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c -+++ b/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c -@@ -1240,6 +1240,58 @@ static void hdmi_config_AVI(struct dw_hdmi *hdmi, struct drm_display_mode *mode) - hdmi_writeb(hdmi, (frame.right_bar >> 8) & 0xff, HDMI_FC_AVISRB1); - } - -+static void hdmi_config_vendor_specific_infoframe(struct dw_hdmi *hdmi, -+ struct drm_display_mode *mode) -+{ -+ struct hdmi_vendor_infoframe frame; -+ u8 buffer[10]; -+ ssize_t err; -+ -+ err = drm_hdmi_vendor_infoframe_from_display_mode(&frame, mode); -+ if (err < 0) -+ /* -+ * Going into that statement does not means vendor infoframe -+ * fails. It just informed us that vendor infoframe is not -+ * needed for the selected mode. Only 4k or stereoscopic 3D -+ * mode requires vendor infoframe. So just simply return. -+ */ -+ return; -+ -+ err = hdmi_vendor_infoframe_pack(&frame, buffer, sizeof(buffer)); -+ if (err < 0) { -+ dev_err(hdmi->dev, "Failed to pack vendor infoframe: %zd\n", -+ err); -+ return; -+ } -+ hdmi_mask_writeb(hdmi, 0, HDMI_FC_DATAUTO0, HDMI_FC_DATAUTO0_VSD_OFFSET, -+ HDMI_FC_DATAUTO0_VSD_MASK); -+ -+ /* Set the length of HDMI vendor specific InfoFrame payload */ -+ hdmi_writeb(hdmi, buffer[2], HDMI_FC_VSDSIZE); -+ -+ /* Set 24bit IEEE Registration Identifier */ -+ hdmi_writeb(hdmi, buffer[4], HDMI_FC_VSDIEEEID0); -+ hdmi_writeb(hdmi, buffer[5], HDMI_FC_VSDIEEEID1); -+ hdmi_writeb(hdmi, buffer[6], HDMI_FC_VSDIEEEID2); -+ -+ /* Set HDMI_Video_Format and HDMI_VIC/3D_Structure */ -+ hdmi_writeb(hdmi, buffer[7], HDMI_FC_VSDPAYLOAD0); -+ hdmi_writeb(hdmi, buffer[8], HDMI_FC_VSDPAYLOAD1); -+ -+ if (frame.s3d_struct >= HDMI_3D_STRUCTURE_SIDE_BY_SIDE_HALF) -+ hdmi_writeb(hdmi, buffer[9], HDMI_FC_VSDPAYLOAD2); -+ -+ /* Packet frame interpolation */ -+ hdmi_writeb(hdmi, 1, HDMI_FC_DATAUTO1); -+ -+ /* Auto packets per frame and line spacing */ -+ hdmi_writeb(hdmi, 0x11, HDMI_FC_DATAUTO2); -+ -+ /* Configures the Frame Composer On RDRB mode */ -+ hdmi_mask_writeb(hdmi, 1, HDMI_FC_DATAUTO0, HDMI_FC_DATAUTO0_VSD_OFFSET, -+ HDMI_FC_DATAUTO0_VSD_MASK); -+} -+ - static void hdmi_av_composer(struct dw_hdmi *hdmi, - const struct drm_display_mode *mode) - { -@@ -1489,6 +1541,7 @@ static int dw_hdmi_setup(struct dw_hdmi *hdmi, struct drm_display_mode *mode) - - /* HDMI Initialization Step F - Configure AVI InfoFrame */ - hdmi_config_AVI(hdmi, mode); -+ hdmi_config_vendor_specific_infoframe(hdmi, mode); - } else { - dev_dbg(hdmi->dev, "%s DVI mode\n", __func__); - } -diff --git a/drivers/gpu/drm/bridge/synopsys/dw-hdmi.h b/drivers/gpu/drm/bridge/synopsys/dw-hdmi.h -index 325b0b8..c59f87e 100644 ---- a/drivers/gpu/drm/bridge/synopsys/dw-hdmi.h -+++ b/drivers/gpu/drm/bridge/synopsys/dw-hdmi.h -@@ -854,6 +854,10 @@ enum { - HDMI_FC_DBGFORCE_FORCEAUDIO = 0x10, - HDMI_FC_DBGFORCE_FORCEVIDEO = 0x1, - -+/* FC_DATAUTO0 field values */ -+ HDMI_FC_DATAUTO0_VSD_MASK = 0x08, -+ HDMI_FC_DATAUTO0_VSD_OFFSET = 3, -+ - /* PHY_CONF0 field values */ - HDMI_PHY_CONF0_PDZ_MASK = 0x80, - HDMI_PHY_CONF0_PDZ_OFFSET = 7, --- -1.9.1 - diff --git a/patch/kernel/odroidc2-next/0043-ARM64-dts-meson-gxl-p230-add-spdif-output-interface.patch b/patch/kernel/odroidc2-next/0043-ARM64-dts-meson-gxl-p230-add-spdif-output-interface.patch new file mode 100644 index 000000000..f0aa0172e --- /dev/null +++ b/patch/kernel/odroidc2-next/0043-ARM64-dts-meson-gxl-p230-add-spdif-output-interface.patch @@ -0,0 +1,38 @@ +From 01ff36940e53cd410abec88ec2eb282c397a3a77 Mon Sep 17 00:00:00 2001 +From: Jerome Brunet +Date: Thu, 30 Mar 2017 16:04:39 +0200 +Subject: [PATCH 43/79] ARM64: dts: meson-gxl-p230: add spdif output interface + +Add the necessary pin for the spdif audio interface output and enable it + +Signed-off-by: Jerome Brunet +Signed-off-by: Neil Armstrong +--- + arch/arm64/boot/dts/amlogic/meson-gxl-s905d-p230.dts | 14 ++++++++++++++ + 1 file changed, 14 insertions(+) + +diff --git a/arch/arm64/boot/dts/amlogic/meson-gxl-s905d-p230.dts b/arch/arm64/boot/dts/amlogic/meson-gxl-s905d-p230.dts +index 3837560..770a332 100644 +--- a/arch/arm64/boot/dts/amlogic/meson-gxl-s905d-p230.dts ++++ b/arch/arm64/boot/dts/amlogic/meson-gxl-s905d-p230.dts +@@ -130,3 +130,17 @@ + status = "okay"; + vref-supply = <&vddio_ao18>; + }; ++ ++&audio { ++ status = "okay"; ++}; ++ ++&aiu_spdif_dma { ++ status = "okay"; ++}; ++ ++&spdif_dai { ++ pinctrl-0 = <&spdif_out_h_pins>; ++ pinctrl-names = "default"; ++ status = "okay"; ++}; +-- +1.9.1 + diff --git a/patch/kernel/odroidc2-next/0043-drm-bridge-dw-hdmi-Extract-PHY-interrupt-setup-to-a-.patch b/patch/kernel/odroidc2-next/0043-drm-bridge-dw-hdmi-Extract-PHY-interrupt-setup-to-a-.patch deleted file mode 100644 index c0bf42952..000000000 --- a/patch/kernel/odroidc2-next/0043-drm-bridge-dw-hdmi-Extract-PHY-interrupt-setup-to-a-.patch +++ /dev/null @@ -1,106 +0,0 @@ -From b880ce74954cefe49cfc101c684c4ce0b0063945 Mon Sep 17 00:00:00 2001 -From: Laurent Pinchart -Date: Fri, 3 Mar 2017 14:14:56 +0200 -Subject: [PATCH 43/93] drm: bridge: dw-hdmi: Extract PHY interrupt setup to a - function - -In preparation for adding PHY operations to handle RX SENSE and HPD, -group all the PHY interrupt setup code in a single location and extract -it to a separate function. - -Signed-off-by: Laurent Pinchart ---- - drivers/gpu/drm/bridge/synopsys/dw-hdmi.c | 50 ++++++++++++++----------------- - 1 file changed, 23 insertions(+), 27 deletions(-) - -diff --git a/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c b/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c -index af93f7a..f82750a 100644 ---- a/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c -+++ b/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c -@@ -1559,7 +1559,7 @@ static int dw_hdmi_setup(struct dw_hdmi *hdmi, struct drm_display_mode *mode) - } - - /* Wait until we are registered to enable interrupts */ --static int dw_hdmi_fb_registered(struct dw_hdmi *hdmi) -+static void dw_hdmi_fb_registered(struct dw_hdmi *hdmi) - { - hdmi_writeb(hdmi, HDMI_PHY_I2CM_INT_ADDR_DONE_POL, - HDMI_PHY_I2CM_INT_ADDR); -@@ -1567,15 +1567,6 @@ static int dw_hdmi_fb_registered(struct dw_hdmi *hdmi) - hdmi_writeb(hdmi, HDMI_PHY_I2CM_CTLINT_ADDR_NAC_POL | - HDMI_PHY_I2CM_CTLINT_ADDR_ARBITRATION_POL, - HDMI_PHY_I2CM_CTLINT_ADDR); -- -- /* enable cable hot plug irq */ -- hdmi_writeb(hdmi, hdmi->phy_mask, HDMI_PHY_MASK0); -- -- /* Clear Hotplug interrupts */ -- hdmi_writeb(hdmi, HDMI_IH_PHY_STAT0_HPD | HDMI_IH_PHY_STAT0_RX_SENSE, -- HDMI_IH_PHY_STAT0); -- -- return 0; - } - - static void initialize_hdmi_ih_mutes(struct dw_hdmi *hdmi) -@@ -1693,6 +1684,26 @@ static void dw_hdmi_update_phy_mask(struct dw_hdmi *hdmi) - hdmi_writeb(hdmi, hdmi->phy_mask, HDMI_PHY_MASK0); - } - -+static void dw_hdmi_phy_setup_hpd(struct dw_hdmi *hdmi) -+{ -+ /* -+ * Configure the PHY RX SENSE and HPD interrupts polarities and clear -+ * any pending interrupt. -+ */ -+ hdmi_writeb(hdmi, HDMI_PHY_HPD | HDMI_PHY_RX_SENSE, HDMI_PHY_POL0); -+ hdmi_writeb(hdmi, HDMI_IH_PHY_STAT0_HPD | HDMI_IH_PHY_STAT0_RX_SENSE, -+ HDMI_IH_PHY_STAT0); -+ -+ /* Enable cable hot plug irq. */ -+ hdmi_writeb(hdmi, hdmi->phy_mask, HDMI_PHY_MASK0); -+ -+ /* Clear and unmute interrupts. */ -+ hdmi_writeb(hdmi, HDMI_IH_PHY_STAT0_HPD | HDMI_IH_PHY_STAT0_RX_SENSE, -+ HDMI_IH_PHY_STAT0); -+ hdmi_writeb(hdmi, ~(HDMI_IH_PHY_STAT0_HPD | HDMI_IH_PHY_STAT0_RX_SENSE), -+ HDMI_IH_MUTE_PHY_STAT0); -+} -+ - static enum drm_connector_status - dw_hdmi_connector_detect(struct drm_connector *connector, bool force) - { -@@ -2204,29 +2215,14 @@ static int dw_hdmi_detect_phy(struct dw_hdmi *hdmi) - hdmi->ddc = NULL; - } - -- /* -- * Configure registers related to HDMI interrupt -- * generation before registering IRQ. -- */ -- hdmi_writeb(hdmi, HDMI_PHY_HPD | HDMI_PHY_RX_SENSE, HDMI_PHY_POL0); -- -- /* Clear Hotplug interrupts */ -- hdmi_writeb(hdmi, HDMI_IH_PHY_STAT0_HPD | HDMI_IH_PHY_STAT0_RX_SENSE, -- HDMI_IH_PHY_STAT0); -- - hdmi->bridge.driver_private = hdmi; - hdmi->bridge.funcs = &dw_hdmi_bridge_funcs; - #ifdef CONFIG_OF - hdmi->bridge.of_node = pdev->dev.of_node; - #endif - -- ret = dw_hdmi_fb_registered(hdmi); -- if (ret) -- goto err_iahb; -- -- /* Unmute interrupts */ -- hdmi_writeb(hdmi, ~(HDMI_IH_PHY_STAT0_HPD | HDMI_IH_PHY_STAT0_RX_SENSE), -- HDMI_IH_MUTE_PHY_STAT0); -+ dw_hdmi_fb_registered(hdmi); -+ dw_hdmi_phy_setup_hpd(hdmi); - - memset(&pdevinfo, 0, sizeof(pdevinfo)); - pdevinfo.parent = dev; --- -1.9.1 - diff --git a/patch/kernel/odroidc2-next/0044-WIP-ARM64-dts-meson-gxbb-p20x-add-sound-card-support.patch b/patch/kernel/odroidc2-next/0044-WIP-ARM64-dts-meson-gxbb-p20x-add-sound-card-support.patch new file mode 100644 index 000000000..d1af55853 --- /dev/null +++ b/patch/kernel/odroidc2-next/0044-WIP-ARM64-dts-meson-gxbb-p20x-add-sound-card-support.patch @@ -0,0 +1,84 @@ +From bb5cf409583f04045ea97c7a039cb0935bbd6bfc Mon Sep 17 00:00:00 2001 +From: Jerome Brunet +Date: Thu, 30 Mar 2017 15:53:47 +0200 +Subject: [PATCH 44/79] WIP: ARM64: dts: meson-gxbb-p20x: add sound card + support + +This commit add sound card support to the meson-gxbb-p20x +This patch is not intended to be merged upstream the architecture of +the sound card has not been determined yet. To handle the routing caps +of meson SoCs, we will probably have to make our own card. + +This implementation using simple-card is provided for testing purpose only + +Signed-off-by: Jerome Brunet +Signed-off-by: Neil Armstrong +--- + arch/arm64/boot/dts/amlogic/meson-gxbb-p20x.dtsi | 51 ++++++++++++++++++++++++ + 1 file changed, 51 insertions(+) + +diff --git a/arch/arm64/boot/dts/amlogic/meson-gxbb-p20x.dtsi b/arch/arm64/boot/dts/amlogic/meson-gxbb-p20x.dtsi +index d36f82b0..88e3713 100644 +--- a/arch/arm64/boot/dts/amlogic/meson-gxbb-p20x.dtsi ++++ b/arch/arm64/boot/dts/amlogic/meson-gxbb-p20x.dtsi +@@ -164,6 +164,57 @@ + compatible = "linux,spdif-dit"; + status = "okay"; + }; ++ ++ soc { ++ sound { ++ compatible = "simple-audio-card"; ++ simple-audio-card,name = "meson-gxbb-p20x"; ++ simple-audio-card,aux-devs = <&>; ++ simple-audio-card,widgets = ++ "Line", "Analog Left Output", ++ "Line", "Analog Right Output"; ++ simple-audio-card,routing = ++ "Analog Left Output", "OUTL", ++ "Analog Right Output", "OUTR", ++ "INL", "AOUTL", ++ "INR", "AOUTR"; ++ status = "okay"; ++ ++ simple-audio-card,dai-link@0 { ++ /* RCA Output */ ++ format = "i2s"; ++ mclk-fs = <256>; ++ bitclock-master = <&i2s_dai>; ++ frame-master = <&i2s_dai>; ++ ++ plat { ++ sound-dai = <&aiu_i2s_dma>; ++ }; ++ ++ cpu { ++ sound-dai = <&i2s_dai>; ++ }; ++ ++ codec { ++ sound-dai = <&i2s_codec>; ++ }; ++ }; ++ ++ simple-audio-card,dai-link@1 { ++ plat { ++ sound-dai = <&aiu_spdif_dma>; ++ }; ++ ++ cpu { ++ sound-dai = <&spdif_dai>; ++ }; ++ ++ codec { ++ sound-dai = <&spdif_out>; ++ }; ++ }; ++ }; ++ }; + }; + + /* This UART is brought out to the DB9 connector */ +-- +1.9.1 + diff --git a/patch/kernel/odroidc2-next/0044-drm-bridge-dw-hdmi-Switch-to-V4L-bus-format-and-enco.patch b/patch/kernel/odroidc2-next/0044-drm-bridge-dw-hdmi-Switch-to-V4L-bus-format-and-enco.patch deleted file mode 100644 index 29f20d3de..000000000 --- a/patch/kernel/odroidc2-next/0044-drm-bridge-dw-hdmi-Switch-to-V4L-bus-format-and-enco.patch +++ /dev/null @@ -1,551 +0,0 @@ -From 61801956e33a13e4682a8b52978d8f3c5d7f99e3 Mon Sep 17 00:00:00 2001 -From: Neil Armstrong -Date: Fri, 13 Jan 2017 16:07:42 +0100 -Subject: [PATCH 44/93] drm: bridge: dw-hdmi: Switch to V4L bus format and - encodings - -Some display pipelines can only provide non-RBG input pixels to the HDMI TX -Controller, this patch takes the pixel format from the plat_data if provided. - -Signed-off-by: Neil Armstrong ---- - drivers/gpu/drm/bridge/synopsys/dw-hdmi.c | 326 +++++++++++++++++++++--------- - include/drm/bridge/dw_hdmi.h | 63 ++++++ - 2 files changed, 294 insertions(+), 95 deletions(-) - -diff --git a/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c b/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c -index f82750a..fcb0a27 100644 ---- a/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c -+++ b/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c -@@ -30,18 +30,15 @@ - #include - #include - -+#include -+#include -+ - #include "dw-hdmi.h" - #include "dw-hdmi-audio.h" - - #define DDC_SEGMENT_ADDR 0x30 - #define HDMI_EDID_LEN 512 - --#define RGB 0 --#define YCBCR444 1 --#define YCBCR422_16BITS 2 --#define YCBCR422_8BITS 3 --#define XVYCC444 4 -- - enum hdmi_datamap { - RGB444_8B = 0x01, - RGB444_10B = 0x03, -@@ -95,10 +92,10 @@ struct hdmi_vmode { - }; - - struct hdmi_data_info { -- unsigned int enc_in_format; -- unsigned int enc_out_format; -- unsigned int enc_color_depth; -- unsigned int colorimetry; -+ unsigned int enc_in_bus_format; -+ unsigned int enc_out_bus_format; -+ unsigned int enc_in_encoding; -+ unsigned int enc_out_encoding; - unsigned int pix_repet_factor; - unsigned int hdcp_enable; - struct hdmi_vmode video_mode; -@@ -567,6 +564,92 @@ void dw_hdmi_audio_disable(struct dw_hdmi *hdmi) - } - EXPORT_SYMBOL_GPL(dw_hdmi_audio_disable); - -+static bool hdmi_bus_fmt_is_rgb(unsigned int bus_format) -+{ -+ switch (bus_format) { -+ case MEDIA_BUS_FMT_RGB888_1X24: -+ case MEDIA_BUS_FMT_RGB101010_1X30: -+ case MEDIA_BUS_FMT_RGB121212_1X36: -+ case MEDIA_BUS_FMT_RGB161616_1X48: -+ return true; -+ -+ default: -+ return false; -+ } -+} -+ -+static bool hdmi_bus_fmt_is_yuv444(unsigned int bus_format) -+{ -+ switch (bus_format) { -+ case MEDIA_BUS_FMT_YUV8_1X24: -+ case MEDIA_BUS_FMT_YUV10_1X30: -+ case MEDIA_BUS_FMT_YUV12_1X36: -+ case MEDIA_BUS_FMT_YUV16_1X48: -+ return true; -+ -+ default: -+ return false; -+ } -+} -+ -+static bool hdmi_bus_fmt_is_yuv422(unsigned int bus_format) -+{ -+ switch (bus_format) { -+ case MEDIA_BUS_FMT_UYVY8_1X16: -+ case MEDIA_BUS_FMT_UYVY10_1X20: -+ case MEDIA_BUS_FMT_UYVY12_1X24: -+ return true; -+ -+ default: -+ return false; -+ } -+} -+ -+static bool hdmi_bus_fmt_is_yuv420(unsigned int bus_format) -+{ -+ switch (bus_format) { -+ case MEDIA_BUS_FMT_UYYVYY8_1X24: -+ case MEDIA_BUS_FMT_UYYVYY10_1X30: -+ case MEDIA_BUS_FMT_UYYVYY12_1X36: -+ case MEDIA_BUS_FMT_UYYVYY16_1X48: -+ return true; -+ -+ default: -+ return false; -+ } -+} -+ -+static int hdmi_bus_fmt_color_depth(unsigned int bus_format) -+{ -+ switch (bus_format) { -+ case MEDIA_BUS_FMT_RGB888_1X24: -+ case MEDIA_BUS_FMT_YUV8_1X24: -+ case MEDIA_BUS_FMT_UYVY8_1X16: -+ case MEDIA_BUS_FMT_UYYVYY8_1X24: -+ return 8; -+ -+ case MEDIA_BUS_FMT_RGB101010_1X30: -+ case MEDIA_BUS_FMT_YUV10_1X30: -+ case MEDIA_BUS_FMT_UYVY10_1X20: -+ case MEDIA_BUS_FMT_UYYVYY10_1X30: -+ return 10; -+ -+ case MEDIA_BUS_FMT_RGB121212_1X36: -+ case MEDIA_BUS_FMT_YUV12_1X36: -+ case MEDIA_BUS_FMT_UYVY12_1X24: -+ case MEDIA_BUS_FMT_UYYVYY12_1X36: -+ return 12; -+ -+ case MEDIA_BUS_FMT_RGB161616_1X48: -+ case MEDIA_BUS_FMT_YUV16_1X48: -+ case MEDIA_BUS_FMT_UYYVYY16_1X48: -+ return 16; -+ -+ default: -+ return 0; -+ } -+} -+ - /* - * this submodule is responsible for the video data synchronization. - * for example, for RGB 4:4:4 input, the data map is defined as -@@ -579,37 +662,49 @@ static void hdmi_video_sample(struct dw_hdmi *hdmi) - int color_format = 0; - u8 val; - -- if (hdmi->hdmi_data.enc_in_format == RGB) { -- if (hdmi->hdmi_data.enc_color_depth == 8) -- color_format = 0x01; -- else if (hdmi->hdmi_data.enc_color_depth == 10) -- color_format = 0x03; -- else if (hdmi->hdmi_data.enc_color_depth == 12) -- color_format = 0x05; -- else if (hdmi->hdmi_data.enc_color_depth == 16) -- color_format = 0x07; -- else -- return; -- } else if (hdmi->hdmi_data.enc_in_format == YCBCR444) { -- if (hdmi->hdmi_data.enc_color_depth == 8) -- color_format = 0x09; -- else if (hdmi->hdmi_data.enc_color_depth == 10) -- color_format = 0x0B; -- else if (hdmi->hdmi_data.enc_color_depth == 12) -- color_format = 0x0D; -- else if (hdmi->hdmi_data.enc_color_depth == 16) -- color_format = 0x0F; -- else -- return; -- } else if (hdmi->hdmi_data.enc_in_format == YCBCR422_8BITS) { -- if (hdmi->hdmi_data.enc_color_depth == 8) -- color_format = 0x16; -- else if (hdmi->hdmi_data.enc_color_depth == 10) -- color_format = 0x14; -- else if (hdmi->hdmi_data.enc_color_depth == 12) -- color_format = 0x12; -- else -- return; -+ switch (hdmi->hdmi_data.enc_in_bus_format) { -+ case MEDIA_BUS_FMT_RGB888_1X24: -+ color_format = 0x01; -+ break; -+ case MEDIA_BUS_FMT_RGB101010_1X30: -+ color_format = 0x03; -+ break; -+ case MEDIA_BUS_FMT_RGB121212_1X36: -+ color_format = 0x05; -+ break; -+ case MEDIA_BUS_FMT_RGB161616_1X48: -+ color_format = 0x07; -+ break; -+ -+ case MEDIA_BUS_FMT_YUV8_1X24: -+ case MEDIA_BUS_FMT_UYYVYY8_1X24: -+ color_format = 0x09; -+ break; -+ case MEDIA_BUS_FMT_YUV10_1X30: -+ case MEDIA_BUS_FMT_UYYVYY10_1X30: -+ color_format = 0x0B; -+ break; -+ case MEDIA_BUS_FMT_YUV12_1X36: -+ case MEDIA_BUS_FMT_UYYVYY12_1X36: -+ color_format = 0x0D; -+ break; -+ case MEDIA_BUS_FMT_YUV16_1X48: -+ case MEDIA_BUS_FMT_UYYVYY16_1X48: -+ color_format = 0x0F; -+ break; -+ -+ case MEDIA_BUS_FMT_UYVY8_1X16: -+ color_format = 0x16; -+ break; -+ case MEDIA_BUS_FMT_UYVY10_1X20: -+ color_format = 0x14; -+ break; -+ case MEDIA_BUS_FMT_UYVY12_1X24: -+ color_format = 0x12; -+ break; -+ -+ default: -+ return; - } - - val = HDMI_TX_INVID0_INTERNAL_DE_GENERATOR_DISABLE | -@@ -632,26 +727,30 @@ static void hdmi_video_sample(struct dw_hdmi *hdmi) - - static int is_color_space_conversion(struct dw_hdmi *hdmi) - { -- return hdmi->hdmi_data.enc_in_format != hdmi->hdmi_data.enc_out_format; -+ return hdmi->hdmi_data.enc_in_bus_format != hdmi->hdmi_data.enc_out_bus_format; - } - - static int is_color_space_decimation(struct dw_hdmi *hdmi) - { -- if (hdmi->hdmi_data.enc_out_format != YCBCR422_8BITS) -+ if (!hdmi_bus_fmt_is_yuv422(hdmi->hdmi_data.enc_out_bus_format)) - return 0; -- if (hdmi->hdmi_data.enc_in_format == RGB || -- hdmi->hdmi_data.enc_in_format == YCBCR444) -+ -+ if (hdmi_bus_fmt_is_rgb(hdmi->hdmi_data.enc_in_bus_format) || -+ hdmi_bus_fmt_is_yuv444(hdmi->hdmi_data.enc_in_bus_format)) - return 1; -+ - return 0; - } - - static int is_color_space_interpolation(struct dw_hdmi *hdmi) - { -- if (hdmi->hdmi_data.enc_in_format != YCBCR422_8BITS) -+ if (!hdmi_bus_fmt_is_yuv422(hdmi->hdmi_data.enc_in_bus_format)) - return 0; -- if (hdmi->hdmi_data.enc_out_format == RGB || -- hdmi->hdmi_data.enc_out_format == YCBCR444) -+ -+ if (hdmi_bus_fmt_is_rgb(hdmi->hdmi_data.enc_out_bus_format) || -+ hdmi_bus_fmt_is_yuv444(hdmi->hdmi_data.enc_out_bus_format)) - return 1; -+ - return 0; - } - -@@ -662,15 +761,16 @@ static void dw_hdmi_update_csc_coeffs(struct dw_hdmi *hdmi) - u32 csc_scale = 1; - - if (is_color_space_conversion(hdmi)) { -- if (hdmi->hdmi_data.enc_out_format == RGB) { -- if (hdmi->hdmi_data.colorimetry == -- HDMI_COLORIMETRY_ITU_601) -+ if (hdmi_bus_fmt_is_rgb(hdmi->hdmi_data.enc_out_bus_format)) { -+ if (hdmi->hdmi_data.enc_out_encoding == -+ V4L2_YCBCR_ENC_601) - csc_coeff = &csc_coeff_rgb_out_eitu601; - else - csc_coeff = &csc_coeff_rgb_out_eitu709; -- } else if (hdmi->hdmi_data.enc_in_format == RGB) { -- if (hdmi->hdmi_data.colorimetry == -- HDMI_COLORIMETRY_ITU_601) -+ } else if (hdmi_bus_fmt_is_rgb( -+ hdmi->hdmi_data.enc_in_bus_format)) { -+ if (hdmi->hdmi_data.enc_out_encoding == -+ V4L2_YCBCR_ENC_601) - csc_coeff = &csc_coeff_rgb_in_eitu601; - else - csc_coeff = &csc_coeff_rgb_in_eitu709; -@@ -708,16 +808,23 @@ static void hdmi_video_csc(struct dw_hdmi *hdmi) - else if (is_color_space_decimation(hdmi)) - decimation = HDMI_CSC_CFG_DECMODE_CHROMA_INT_FORMULA3; - -- if (hdmi->hdmi_data.enc_color_depth == 8) -+ switch (hdmi_bus_fmt_color_depth(hdmi->hdmi_data.enc_out_bus_format)) { -+ case 8: - color_depth = HDMI_CSC_SCALE_CSC_COLORDE_PTH_24BPP; -- else if (hdmi->hdmi_data.enc_color_depth == 10) -+ break; -+ case 10: - color_depth = HDMI_CSC_SCALE_CSC_COLORDE_PTH_30BPP; -- else if (hdmi->hdmi_data.enc_color_depth == 12) -+ break; -+ case 12: - color_depth = HDMI_CSC_SCALE_CSC_COLORDE_PTH_36BPP; -- else if (hdmi->hdmi_data.enc_color_depth == 16) -+ break; -+ case 16: - color_depth = HDMI_CSC_SCALE_CSC_COLORDE_PTH_48BPP; -- else -+ break; -+ -+ default: - return; -+ } - - /* Configure the CSC registers */ - hdmi_writeb(hdmi, interpolation | decimation, HDMI_CSC_CFG); -@@ -740,32 +847,43 @@ static void hdmi_video_packetize(struct dw_hdmi *hdmi) - struct hdmi_data_info *hdmi_data = &hdmi->hdmi_data; - u8 val, vp_conf; - -- if (hdmi_data->enc_out_format == RGB || -- hdmi_data->enc_out_format == YCBCR444) { -- if (!hdmi_data->enc_color_depth) { -- output_select = HDMI_VP_CONF_OUTPUT_SELECTOR_BYPASS; -- } else if (hdmi_data->enc_color_depth == 8) { -+ if (hdmi_bus_fmt_is_rgb(hdmi->hdmi_data.enc_out_bus_format) || -+ hdmi_bus_fmt_is_yuv444(hdmi->hdmi_data.enc_out_bus_format)) { -+ switch (hdmi_bus_fmt_color_depth( -+ hdmi->hdmi_data.enc_out_bus_format)) { -+ case 8: - color_depth = 4; - output_select = HDMI_VP_CONF_OUTPUT_SELECTOR_BYPASS; -- } else if (hdmi_data->enc_color_depth == 10) { -+ break; -+ case 10: - color_depth = 5; -- } else if (hdmi_data->enc_color_depth == 12) { -+ break; -+ case 12: - color_depth = 6; -- } else if (hdmi_data->enc_color_depth == 16) { -+ break; -+ case 16: - color_depth = 7; -- } else { -- return; -+ break; -+ default: -+ output_select = HDMI_VP_CONF_OUTPUT_SELECTOR_BYPASS; - } -- } else if (hdmi_data->enc_out_format == YCBCR422_8BITS) { -- if (!hdmi_data->enc_color_depth || -- hdmi_data->enc_color_depth == 8) -+ } else if (hdmi_bus_fmt_is_yuv422(hdmi->hdmi_data.enc_out_bus_format)) { -+ switch (hdmi_bus_fmt_color_depth( -+ hdmi->hdmi_data.enc_out_bus_format)) { -+ case 0: -+ case 8: - remap_size = HDMI_VP_REMAP_YCC422_16bit; -- else if (hdmi_data->enc_color_depth == 10) -+ break; -+ case 10: - remap_size = HDMI_VP_REMAP_YCC422_20bit; -- else if (hdmi_data->enc_color_depth == 12) -+ break; -+ case 12: - remap_size = HDMI_VP_REMAP_YCC422_24bit; -- else -+ break; -+ -+ default: - return; -+ } - output_select = HDMI_VP_CONF_OUTPUT_SELECTOR_YCC422; - } else { - return; -@@ -1148,28 +1266,35 @@ static void hdmi_config_AVI(struct dw_hdmi *hdmi, struct drm_display_mode *mode) - /* Initialise info frame from DRM mode */ - drm_hdmi_avi_infoframe_from_display_mode(&frame, mode); - -- if (hdmi->hdmi_data.enc_out_format == YCBCR444) -+ if (hdmi_bus_fmt_is_yuv444(hdmi->hdmi_data.enc_out_bus_format)) - frame.colorspace = HDMI_COLORSPACE_YUV444; -- else if (hdmi->hdmi_data.enc_out_format == YCBCR422_8BITS) -+ else if (hdmi_bus_fmt_is_yuv422(hdmi->hdmi_data.enc_out_bus_format)) - frame.colorspace = HDMI_COLORSPACE_YUV422; - else - frame.colorspace = HDMI_COLORSPACE_RGB; - - /* Set up colorimetry */ -- if (hdmi->hdmi_data.enc_out_format == XVYCC444) { -- frame.colorimetry = HDMI_COLORIMETRY_EXTENDED; -- if (hdmi->hdmi_data.colorimetry == HDMI_COLORIMETRY_ITU_601) -- frame.extended_colorimetry = -+ switch (hdmi->hdmi_data.enc_out_encoding) { -+ case V4L2_YCBCR_ENC_601: -+ if (hdmi->hdmi_data.enc_in_encoding == V4L2_YCBCR_ENC_XV601) -+ frame.colorimetry = HDMI_COLORIMETRY_EXTENDED; -+ else -+ frame.colorimetry = HDMI_COLORIMETRY_ITU_601; -+ frame.extended_colorimetry = - HDMI_EXTENDED_COLORIMETRY_XV_YCC_601; -- else /*hdmi->hdmi_data.colorimetry == HDMI_COLORIMETRY_ITU_709*/ -- frame.extended_colorimetry = -+ case V4L2_YCBCR_ENC_709: -+ if (hdmi->hdmi_data.enc_in_encoding == V4L2_YCBCR_ENC_XV709) -+ frame.colorimetry = HDMI_COLORIMETRY_EXTENDED; -+ else -+ frame.colorimetry = HDMI_COLORIMETRY_ITU_709; -+ frame.extended_colorimetry = - HDMI_EXTENDED_COLORIMETRY_XV_YCC_709; -- } else if (hdmi->hdmi_data.enc_out_format != RGB) { -- frame.colorimetry = hdmi->hdmi_data.colorimetry; -- frame.extended_colorimetry = HDMI_EXTENDED_COLORIMETRY_XV_YCC_601; -- } else { /* Carries no data */ -- frame.colorimetry = HDMI_COLORIMETRY_NONE; -- frame.extended_colorimetry = HDMI_EXTENDED_COLORIMETRY_XV_YCC_601; -+ break; -+ default: /* Carries no data */ -+ frame.colorimetry = HDMI_COLORIMETRY_ITU_601; -+ frame.extended_colorimetry = -+ HDMI_EXTENDED_COLORIMETRY_XV_YCC_601; -+ break; - } - - frame.scan_mode = HDMI_SCAN_MODE_NONE; -@@ -1498,19 +1623,30 @@ static int dw_hdmi_setup(struct dw_hdmi *hdmi, struct drm_display_mode *mode) - (hdmi->vic == 21) || (hdmi->vic == 22) || - (hdmi->vic == 2) || (hdmi->vic == 3) || - (hdmi->vic == 17) || (hdmi->vic == 18)) -- hdmi->hdmi_data.colorimetry = HDMI_COLORIMETRY_ITU_601; -+ hdmi->hdmi_data.enc_out_encoding = V4L2_YCBCR_ENC_601; - else -- hdmi->hdmi_data.colorimetry = HDMI_COLORIMETRY_ITU_709; -+ hdmi->hdmi_data.enc_out_encoding = V4L2_YCBCR_ENC_709; - - hdmi->hdmi_data.video_mode.mpixelrepetitionoutput = 0; - hdmi->hdmi_data.video_mode.mpixelrepetitioninput = 0; - -- /* TODO: Get input format from IPU (via FB driver interface) */ -- hdmi->hdmi_data.enc_in_format = RGB; -+ /* TOFIX: Get input format from plat data or fallback to RGB888 */ -+ if (hdmi->plat_data->input_bus_format >= 0) -+ hdmi->hdmi_data.enc_in_bus_format = -+ hdmi->plat_data->input_bus_format; -+ else -+ hdmi->hdmi_data.enc_in_bus_format = MEDIA_BUS_FMT_RGB888_1X24; -+ -+ /* TOFIX: Get input encoding from plat data or fallback to none */ -+ if (hdmi->plat_data->input_bus_encoding >= 0) -+ hdmi->hdmi_data.enc_in_encoding = -+ hdmi->plat_data->input_bus_encoding; -+ else -+ hdmi->hdmi_data.enc_in_encoding = V4L2_YCBCR_ENC_DEFAULT; - -- hdmi->hdmi_data.enc_out_format = RGB; -+ /* TOFIX: Default to RGB888 output format */ -+ hdmi->hdmi_data.enc_out_bus_format = MEDIA_BUS_FMT_RGB888_1X24; - -- hdmi->hdmi_data.enc_color_depth = 8; - hdmi->hdmi_data.pix_repet_factor = 0; - hdmi->hdmi_data.hdcp_enable = 0; - hdmi->hdmi_data.video_mode.mdataenablepolarity = true; -diff --git a/include/drm/bridge/dw_hdmi.h b/include/drm/bridge/dw_hdmi.h -index bcceee8..0da74fb 100644 ---- a/include/drm/bridge/dw_hdmi.h -+++ b/include/drm/bridge/dw_hdmi.h -@@ -14,6 +14,67 @@ - - struct dw_hdmi; - -+/** -+ * DOC: Supported input formats and encodings -+ * -+ * Depending on the Hardware configuration of the Controller IP, it supports -+ * a subset of the following input formats and encodings on it's internal -+ * 48bit bus. -+ * -+ * +----------------------+---------------------------------+------------------------------+ -+ * + Format Name + Format Code + Encodings + -+ * +----------------------+---------------------------------+------------------------------+ -+ * + RGB 4:4:4 8bit + ``MEDIA_BUS_FMT_RGB888_1X24`` + ``V4L2_YCBCR_ENC_DEFAULT`` + -+ * +----------------------+---------------------------------+------------------------------+ -+ * + RGB 4:4:4 10bits + ``MEDIA_BUS_FMT_RGB101010_1X30``+ ``V4L2_YCBCR_ENC_DEFAULT`` + -+ * +----------------------+---------------------------------+------------------------------+ -+ * + RGB 4:4:4 12bits + ``MEDIA_BUS_FMT_RGB121212_1X36``+ ``V4L2_YCBCR_ENC_DEFAULT`` + -+ * +----------------------+---------------------------------+------------------------------+ -+ * + RGB 4:4:4 16bits + ``MEDIA_BUS_FMT_RGB161616_1X48``+ ``V4L2_YCBCR_ENC_DEFAULT`` + -+ * +----------------------+---------------------------------+------------------------------+ -+ * + YCbCr 4:4:4 8bit + ``MEDIA_BUS_FMT_YUV8_1X24`` + ``V4L2_YCBCR_ENC_601`` + -+ * + + + or ``V4L2_YCBCR_ENC_709`` + -+ * + + + or ``V4L2_YCBCR_ENC_XV601`` + -+ * + + + or ``V4L2_YCBCR_ENC_XV709`` + -+ * +----------------------+---------------------------------+------------------------------+ -+ * + YCbCr 4:4:4 10bits + ``MEDIA_BUS_FMT_YUV10_1X30`` + ``V4L2_YCBCR_ENC_601`` + -+ * + + + or ``V4L2_YCBCR_ENC_709`` + -+ * + + + or ``V4L2_YCBCR_ENC_XV601`` + -+ * + + + or ``V4L2_YCBCR_ENC_XV709`` + -+ * +----------------------+---------------------------------+------------------------------+ -+ * + YCbCr 4:4:4 12bits + ``MEDIA_BUS_FMT_YUV12_1X36`` + ``V4L2_YCBCR_ENC_601`` + -+ * + + + or ``V4L2_YCBCR_ENC_709`` + -+ * + + + or ``V4L2_YCBCR_ENC_XV601`` + -+ * + + + or ``V4L2_YCBCR_ENC_XV709`` + -+ * +----------------------+---------------------------------+------------------------------+ -+ * + YCbCr 4:4:4 16bits + ``MEDIA_BUS_FMT_YUV16_1X48`` + ``V4L2_YCBCR_ENC_601`` + -+ * + + + or ``V4L2_YCBCR_ENC_709`` + -+ * + + + or ``V4L2_YCBCR_ENC_XV601`` + -+ * + + + or ``V4L2_YCBCR_ENC_XV709`` + -+ * +----------------------+---------------------------------+------------------------------+ -+ * + YCbCr 4:2:2 8bit + ``MEDIA_BUS_FMT_UYVY8_1X16`` + ``V4L2_YCBCR_ENC_601`` + -+ * + + + or ``V4L2_YCBCR_ENC_709`` + -+ * +----------------------+---------------------------------+------------------------------+ -+ * + YCbCr 4:2:2 10bits + ``MEDIA_BUS_FMT_UYVY10_1X20`` + ``V4L2_YCBCR_ENC_601`` + -+ * + + + or ``V4L2_YCBCR_ENC_709`` + -+ * +----------------------+---------------------------------+------------------------------+ -+ * + YCbCr 4:2:2 12bits + ``MEDIA_BUS_FMT_UYVY12_1X24`` + ``V4L2_YCBCR_ENC_601`` + -+ * + + + or ``V4L2_YCBCR_ENC_709`` + -+ * +----------------------+---------------------------------+------------------------------+ -+ * + YCbCr 4:2:0 8bit + ``MEDIA_BUS_FMT_UYYVYY8_1X24`` + ``V4L2_YCBCR_ENC_601`` + -+ * + + + or ``V4L2_YCBCR_ENC_709`` + -+ * +----------------------+---------------------------------+------------------------------+ -+ * + YCbCr 4:2:0 10bits + ``MEDIA_BUS_FMT_UYYVYY10_1X30`` + ``V4L2_YCBCR_ENC_601`` + -+ * + + + or ``V4L2_YCBCR_ENC_709`` + -+ * +----------------------+---------------------------------+------------------------------+ -+ * + YCbCr 4:2:0 12bits + ``MEDIA_BUS_FMT_UYYVYY12_1X36`` + ``V4L2_YCBCR_ENC_601`` + -+ * + + + or ``V4L2_YCBCR_ENC_709`` + -+ * +----------------------+---------------------------------+------------------------------+ -+ * + YCbCr 4:2:0 16bits + ``MEDIA_BUS_FMT_UYYVYY16_1X48`` + ``V4L2_YCBCR_ENC_601`` + -+ * + + + or ``V4L2_YCBCR_ENC_709`` + -+ * +----------------------+---------------------------------+------------------------------+ -+ */ -+ - enum { - DW_HDMI_RES_8, - DW_HDMI_RES_10, -@@ -62,6 +123,8 @@ struct dw_hdmi_plat_data { - struct regmap *regm; - enum drm_mode_status (*mode_valid)(struct drm_connector *connector, - struct drm_display_mode *mode); -+ unsigned long input_bus_format; -+ unsigned long input_bus_encoding; - - /* Vendor PHY support */ - const struct dw_hdmi_phy_ops *phy_ops; --- -1.9.1 - diff --git a/patch/kernel/odroidc2-next/0045-WIP-ARM64-dts-meson-gxl-p230-add-sound-card-support.patch b/patch/kernel/odroidc2-next/0045-WIP-ARM64-dts-meson-gxl-p230-add-sound-card-support.patch new file mode 100644 index 000000000..c0d33e7a7 --- /dev/null +++ b/patch/kernel/odroidc2-next/0045-WIP-ARM64-dts-meson-gxl-p230-add-sound-card-support.patch @@ -0,0 +1,53 @@ +From 24739afc3e8549f7361dd2ac7f8f5368f8fe0f79 Mon Sep 17 00:00:00 2001 +From: Jerome Brunet +Date: Thu, 30 Mar 2017 16:06:10 +0200 +Subject: [PATCH 45/79] WIP: ARM64: dts: meson-gxl-p230: add sound card support + +This commit add sound card support to the meson-gxbb-p230 +his patch is not intended to be merged upstream. The architecture of +the sound card has not been determined yet. To handle the routing caps +of meson SoCs, we will probably have to make our own card. + +This implementation using simple-card is provided for testing purpose only + +Signed-off-by: Jerome Brunet +Signed-off-by: Neil Armstrong +--- + .../arm64/boot/dts/amlogic/meson-gxl-s905d-p230.dts | 21 +++++++++++++++++++++ + 1 file changed, 21 insertions(+) + +diff --git a/arch/arm64/boot/dts/amlogic/meson-gxl-s905d-p230.dts b/arch/arm64/boot/dts/amlogic/meson-gxl-s905d-p230.dts +index 770a332..5da5206 100644 +--- a/arch/arm64/boot/dts/amlogic/meson-gxl-s905d-p230.dts ++++ b/arch/arm64/boot/dts/amlogic/meson-gxl-s905d-p230.dts +@@ -90,6 +90,27 @@ + compatible = "linux,spdif-dit"; + status = "okay"; + }; ++ ++ soc { ++ sound { ++ compatible = "simple-audio-card"; ++ simple-audio-card,name = "meson-gxl-p230"; ++ ++ simple-audio-card,dai-link@0 { ++ plat { ++ sound-dai = <&aiu_spdif_dma>; ++ }; ++ ++ cpu { ++ sound-dai = <&spdif_dai>; ++ }; ++ ++ codec { ++ sound-dai = <&spdif_out>; ++ }; ++ }; ++ }; ++ }; + }; + + &cec_AO { +-- +1.9.1 + diff --git a/patch/kernel/odroidc2-next/0045-drm-bridge-dw-hdmi-Move-HPD-handling-to-PHY-operatio.patch b/patch/kernel/odroidc2-next/0045-drm-bridge-dw-hdmi-Move-HPD-handling-to-PHY-operatio.patch deleted file mode 100644 index 38c2a1977..000000000 --- a/patch/kernel/odroidc2-next/0045-drm-bridge-dw-hdmi-Move-HPD-handling-to-PHY-operatio.patch +++ /dev/null @@ -1,225 +0,0 @@ -From 5c5f665a2f6a9a8248bf38356f0958772d6d4ef6 Mon Sep 17 00:00:00 2001 -From: Neil Armstrong -Date: Wed, 8 Feb 2017 12:29:19 +0100 -Subject: [PATCH 45/93] drm: bridge: dw-hdmi: Move HPD handling to PHY - operations - -The HDMI TX controller support HPD and RXSENSE signaling from the PHY -via it's STAT0 PHY interface, but some vendor PHYs can manage these -signals independently from the controller, thus these STAT0 handling -should be moved to PHY specific operations and become optional. - -The existing STAT0 HPD and RXSENSE handling code is refactored into -a supplementaty set of default PHY operations that are used automatically -when the platform glue doesn't provide its own operations. - -Reviewed-by: Jose Abreu ---- - drivers/gpu/drm/bridge/synopsys/dw-hdmi.c | 135 ++++++++++++++++++------------ - include/drm/bridge/dw_hdmi.h | 5 ++ - 2 files changed, 86 insertions(+), 54 deletions(-) - -diff --git a/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c b/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c -index fcb0a27..910d579 100644 ---- a/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c -+++ b/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c -@@ -1229,10 +1229,46 @@ static enum drm_connector_status dw_hdmi_phy_read_hpd(struct dw_hdmi *hdmi, - connector_status_connected : connector_status_disconnected; - } - -+static void dw_hdmi_phy_update_hpd(struct dw_hdmi *hdmi, void *data, -+ bool force, bool disabled, bool rxsense) -+{ -+ u8 old_mask = hdmi->phy_mask; -+ -+ if (force || disabled || !rxsense) -+ hdmi->phy_mask |= HDMI_PHY_RX_SENSE; -+ else -+ hdmi->phy_mask &= ~HDMI_PHY_RX_SENSE; -+ -+ if (old_mask != hdmi->phy_mask) -+ hdmi_writeb(hdmi, hdmi->phy_mask, HDMI_PHY_MASK0); -+} -+ -+static void dw_hdmi_phy_setup_hpd(struct dw_hdmi *hdmi, void *data) -+{ -+ /* -+ * Configure the PHY RX SENSE and HPD interrupts polarities and clear -+ * any pending interrupt. -+ */ -+ hdmi_writeb(hdmi, HDMI_PHY_HPD | HDMI_PHY_RX_SENSE, HDMI_PHY_POL0); -+ hdmi_writeb(hdmi, HDMI_IH_PHY_STAT0_HPD | HDMI_IH_PHY_STAT0_RX_SENSE, -+ HDMI_IH_PHY_STAT0); -+ -+ /* Enable cable hot plug irq. */ -+ hdmi_writeb(hdmi, hdmi->phy_mask, HDMI_PHY_MASK0); -+ -+ /* Clear and unmute interrupts. */ -+ hdmi_writeb(hdmi, HDMI_IH_PHY_STAT0_HPD | HDMI_IH_PHY_STAT0_RX_SENSE, -+ HDMI_IH_PHY_STAT0); -+ hdmi_writeb(hdmi, ~(HDMI_IH_PHY_STAT0_HPD | HDMI_IH_PHY_STAT0_RX_SENSE), -+ HDMI_IH_MUTE_PHY_STAT0); -+} -+ - static const struct dw_hdmi_phy_ops dw_hdmi_synopsys_phy_ops = { - .init = dw_hdmi_phy_init, - .disable = dw_hdmi_phy_disable, - .read_hpd = dw_hdmi_phy_read_hpd, -+ .update_hpd = dw_hdmi_phy_update_hpd, -+ .setup_hpd = dw_hdmi_phy_setup_hpd, - }; - - /* ----------------------------------------------------------------------------- -@@ -1809,35 +1845,10 @@ static void dw_hdmi_update_power(struct dw_hdmi *hdmi) - */ - static void dw_hdmi_update_phy_mask(struct dw_hdmi *hdmi) - { -- u8 old_mask = hdmi->phy_mask; -- -- if (hdmi->force || hdmi->disabled || !hdmi->rxsense) -- hdmi->phy_mask |= HDMI_PHY_RX_SENSE; -- else -- hdmi->phy_mask &= ~HDMI_PHY_RX_SENSE; -- -- if (old_mask != hdmi->phy_mask) -- hdmi_writeb(hdmi, hdmi->phy_mask, HDMI_PHY_MASK0); --} -- --static void dw_hdmi_phy_setup_hpd(struct dw_hdmi *hdmi) --{ -- /* -- * Configure the PHY RX SENSE and HPD interrupts polarities and clear -- * any pending interrupt. -- */ -- hdmi_writeb(hdmi, HDMI_PHY_HPD | HDMI_PHY_RX_SENSE, HDMI_PHY_POL0); -- hdmi_writeb(hdmi, HDMI_IH_PHY_STAT0_HPD | HDMI_IH_PHY_STAT0_RX_SENSE, -- HDMI_IH_PHY_STAT0); -- -- /* Enable cable hot plug irq. */ -- hdmi_writeb(hdmi, hdmi->phy_mask, HDMI_PHY_MASK0); -- -- /* Clear and unmute interrupts. */ -- hdmi_writeb(hdmi, HDMI_IH_PHY_STAT0_HPD | HDMI_IH_PHY_STAT0_RX_SENSE, -- HDMI_IH_PHY_STAT0); -- hdmi_writeb(hdmi, ~(HDMI_IH_PHY_STAT0_HPD | HDMI_IH_PHY_STAT0_RX_SENSE), -- HDMI_IH_MUTE_PHY_STAT0); -+ if (hdmi->phy.ops->update_hpd) -+ hdmi->phy.ops->update_hpd(hdmi, hdmi->phy.data, -+ hdmi->force, hdmi->disabled, -+ hdmi->rxsense); - } - - static enum drm_connector_status -@@ -2029,6 +2040,41 @@ static irqreturn_t dw_hdmi_hardirq(int irq, void *dev_id) - return ret; - } - -+void __dw_hdmi_setup_rx_sense(struct dw_hdmi *hdmi, bool hpd, bool rx_sense) -+{ -+ mutex_lock(&hdmi->mutex); -+ -+ if (!hdmi->disabled && !hdmi->force) { -+ /* -+ * If the RX sense status indicates we're disconnected, -+ * clear the software rxsense status. -+ */ -+ if (!rx_sense) -+ hdmi->rxsense = false; -+ -+ /* -+ * Only set the software rxsense status when both -+ * rxsense and hpd indicates we're connected. -+ * This avoids what seems to be bad behaviour in -+ * at least iMX6S versions of the phy. -+ */ -+ if (hpd) -+ hdmi->rxsense = true; -+ -+ dw_hdmi_update_power(hdmi); -+ dw_hdmi_update_phy_mask(hdmi); -+ } -+ mutex_unlock(&hdmi->mutex); -+} -+ -+void dw_hdmi_setup_rx_sense(struct device *dev, bool hpd, bool rx_sense) -+{ -+ struct dw_hdmi *hdmi = dev_get_drvdata(dev); -+ -+ __dw_hdmi_setup_rx_sense(hdmi, hpd, rx_sense); -+} -+EXPORT_SYMBOL_GPL(dw_hdmi_setup_rx_sense); -+ - static irqreturn_t dw_hdmi_irq(int irq, void *dev_id) - { - struct dw_hdmi *hdmi = dev_id; -@@ -2061,30 +2107,10 @@ static irqreturn_t dw_hdmi_irq(int irq, void *dev_id) - * ask the source to re-read the EDID. - */ - if (intr_stat & -- (HDMI_IH_PHY_STAT0_RX_SENSE | HDMI_IH_PHY_STAT0_HPD)) { -- mutex_lock(&hdmi->mutex); -- if (!hdmi->disabled && !hdmi->force) { -- /* -- * If the RX sense status indicates we're disconnected, -- * clear the software rxsense status. -- */ -- if (!(phy_stat & HDMI_PHY_RX_SENSE)) -- hdmi->rxsense = false; -- -- /* -- * Only set the software rxsense status when both -- * rxsense and hpd indicates we're connected. -- * This avoids what seems to be bad behaviour in -- * at least iMX6S versions of the phy. -- */ -- if (phy_stat & HDMI_PHY_HPD) -- hdmi->rxsense = true; -- -- dw_hdmi_update_power(hdmi); -- dw_hdmi_update_phy_mask(hdmi); -- } -- mutex_unlock(&hdmi->mutex); -- } -+ (HDMI_IH_PHY_STAT0_RX_SENSE | HDMI_IH_PHY_STAT0_HPD)) -+ __dw_hdmi_setup_rx_sense(hdmi, -+ phy_stat & HDMI_PHY_HPD, -+ phy_stat & HDMI_PHY_RX_SENSE); - - if (intr_stat & HDMI_IH_PHY_STAT0_HPD) { - dev_dbg(hdmi->dev, "EVENT=%s\n", -@@ -2358,7 +2384,8 @@ static int dw_hdmi_detect_phy(struct dw_hdmi *hdmi) - #endif - - dw_hdmi_fb_registered(hdmi); -- dw_hdmi_phy_setup_hpd(hdmi); -+ if (hdmi->phy.ops->setup_hpd) -+ hdmi->phy.ops->setup_hpd(hdmi, hdmi->phy.data); - - memset(&pdevinfo, 0, sizeof(pdevinfo)); - pdevinfo.parent = dev; -diff --git a/include/drm/bridge/dw_hdmi.h b/include/drm/bridge/dw_hdmi.h -index 0da74fb..0668ae1 100644 ---- a/include/drm/bridge/dw_hdmi.h -+++ b/include/drm/bridge/dw_hdmi.h -@@ -117,6 +117,9 @@ struct dw_hdmi_phy_ops { - struct drm_display_mode *mode); - void (*disable)(struct dw_hdmi *hdmi, void *data); - enum drm_connector_status (*read_hpd)(struct dw_hdmi *hdmi, void *data); -+ void (*update_hpd)(struct dw_hdmi *hdmi, void *data, -+ bool force, bool disabled, bool rxsense); -+ void (*setup_hpd)(struct dw_hdmi *hdmi, void *data); - }; - - struct dw_hdmi_plat_data { -@@ -147,6 +150,8 @@ int dw_hdmi_probe(struct platform_device *pdev, - int dw_hdmi_bind(struct platform_device *pdev, struct drm_encoder *encoder, - const struct dw_hdmi_plat_data *plat_data); - -+void dw_hdmi_setup_rx_sense(struct device *dev, bool hpd, bool rx_sense); -+ - void dw_hdmi_set_sample_rate(struct dw_hdmi *hdmi, unsigned int rate); - void dw_hdmi_audio_enable(struct dw_hdmi *hdmi); - void dw_hdmi_audio_disable(struct dw_hdmi *hdmi); --- -1.9.1 - diff --git a/patch/kernel/odroidc2-next/0046-clk-take-the-prepare-lock-out-of-clk_core_set_parent.patch b/patch/kernel/odroidc2-next/0046-clk-take-the-prepare-lock-out-of-clk_core_set_parent.patch new file mode 100644 index 000000000..6c81b2811 --- /dev/null +++ b/patch/kernel/odroidc2-next/0046-clk-take-the-prepare-lock-out-of-clk_core_set_parent.patch @@ -0,0 +1,120 @@ +From 8fb6f1d768e64d2df3f4effdb90a953ba0080a76 Mon Sep 17 00:00:00 2001 +From: Jerome Brunet +Date: Mon, 20 Mar 2017 12:04:14 +0100 +Subject: [PATCH 46/79] clk: take the prepare lock out of clk_core_set_parent + +Rework set_parent core function so it can be called when the prepare lock +is already held by the caller. + +This rework is done to ease the integration of the "protected" clock +functionality. + +Signed-off-by: Jerome Brunet +Signed-off-by: Neil Armstrong +--- + drivers/clk/clk.c | 39 ++++++++++++++++++--------------------- + 1 file changed, 18 insertions(+), 21 deletions(-) + +diff --git a/drivers/clk/clk.c b/drivers/clk/clk.c +index fc58c52..f5c3715 100644 +--- a/drivers/clk/clk.c ++++ b/drivers/clk/clk.c +@@ -1787,7 +1787,8 @@ bool clk_has_parent(struct clk *clk, struct clk *parent) + } + EXPORT_SYMBOL_GPL(clk_has_parent); + +-static int clk_core_set_parent(struct clk_core *core, struct clk_core *parent) ++static int clk_core_set_parent_nolock(struct clk_core *core, ++ struct clk_core *parent) + { + int ret = 0; + int p_index = 0; +@@ -1796,23 +1797,16 @@ static int clk_core_set_parent(struct clk_core *core, struct clk_core *parent) + if (!core) + return 0; + +- /* prevent racing with updates to the clock topology */ +- clk_prepare_lock(); +- + if (core->parent == parent) +- goto out; ++ return 0; + + /* verify ops for for multi-parent clks */ +- if ((core->num_parents > 1) && (!core->ops->set_parent)) { +- ret = -ENOSYS; +- goto out; +- } ++ if ((core->num_parents > 1) && (!core->ops->set_parent)) ++ return -ENOSYS; + + /* check that we are allowed to re-parent if the clock is in use */ +- if ((core->flags & CLK_SET_PARENT_GATE) && core->prepare_count) { +- ret = -EBUSY; +- goto out; +- } ++ if ((core->flags & CLK_SET_PARENT_GATE) && core->prepare_count) ++ return -EBUSY; + + /* try finding the new parent index */ + if (parent) { +@@ -1820,8 +1814,7 @@ static int clk_core_set_parent(struct clk_core *core, struct clk_core *parent) + if (p_index < 0) { + pr_debug("%s: clk %s can not be parent of clk %s\n", + __func__, parent->name, core->name); +- ret = p_index; +- goto out; ++ return p_index; + } + p_rate = parent->rate; + } +@@ -1831,7 +1824,7 @@ static int clk_core_set_parent(struct clk_core *core, struct clk_core *parent) + + /* abort if a driver objects */ + if (ret & NOTIFY_STOP_MASK) +- goto out; ++ return ret; + + /* do the re-parent */ + ret = __clk_set_parent(core, parent, p_index); +@@ -1844,9 +1837,6 @@ static int clk_core_set_parent(struct clk_core *core, struct clk_core *parent) + __clk_recalc_accuracies(core); + } + +-out: +- clk_prepare_unlock(); +- + return ret; + } + +@@ -1869,10 +1859,17 @@ static int clk_core_set_parent(struct clk_core *core, struct clk_core *parent) + */ + int clk_set_parent(struct clk *clk, struct clk *parent) + { ++ int ret; ++ + if (!clk) + return 0; + +- return clk_core_set_parent(clk->core, parent ? parent->core : NULL); ++ clk_prepare_lock(); ++ ret = clk_core_set_parent_nolock(clk->core, ++ parent ? parent->core : NULL); ++ clk_prepare_unlock(); ++ ++ return ret; + } + EXPORT_SYMBOL_GPL(clk_set_parent); + +@@ -2753,7 +2750,7 @@ void clk_unregister(struct clk *clk) + /* Reparent all children to the orphan list. */ + hlist_for_each_entry_safe(child, t, &clk->core->children, + child_node) +- clk_core_set_parent(child, NULL); ++ clk_core_set_parent_nolock(child, NULL); + } + + hlist_del_init(&clk->core->child_node); +-- +1.9.1 + diff --git a/patch/kernel/odroidc2-next/0046-drm-meson-rename-module-name-to-meson-drm.patch b/patch/kernel/odroidc2-next/0046-drm-meson-rename-module-name-to-meson-drm.patch deleted file mode 100644 index f37c26c83..000000000 --- a/patch/kernel/odroidc2-next/0046-drm-meson-rename-module-name-to-meson-drm.patch +++ /dev/null @@ -1,30 +0,0 @@ -From 050ccc8152e10f6d8ae44cf6772a78331d8df19e Mon Sep 17 00:00:00 2001 -From: Neil Armstrong -Date: Thu, 2 Feb 2017 10:47:43 +0100 -Subject: [PATCH 46/93] drm: meson: rename module name to meson-drm - -The module is currently named "meson.ko" which can lead to some -confusion, this patches renames it "meson-drm.ko" - -Signed-off-by: Neil Armstrong -Acked-by: Daniel Vetter -Link: http://patchwork.freedesktop.org/patch/msgid/1486028864-19622-2-git-send-email-narmstrong@baylibre.com ---- - drivers/gpu/drm/meson/Makefile | 6 +++--- - 1 file changed, 3 insertions(+), 3 deletions(-) - -diff --git a/drivers/gpu/drm/meson/Makefile b/drivers/gpu/drm/meson/Makefile -index 2591978..92cf845 100644 ---- a/drivers/gpu/drm/meson/Makefile -+++ b/drivers/gpu/drm/meson/Makefile -@@ -1,4 +1,4 @@ --meson-y := meson_drv.o meson_plane.o meson_crtc.o meson_venc_cvbs.o --meson-y += meson_viu.o meson_vpp.o meson_venc.o meson_vclk.o meson_canvas.o -+meson-drm-y := meson_drv.o meson_plane.o meson_crtc.o meson_venc_cvbs.o -+meson-drm-y += meson_viu.o meson_vpp.o meson_venc.o meson_vclk.o meson_canvas.o - --obj-$(CONFIG_DRM_MESON) += meson.o -+obj-$(CONFIG_DRM_MESON) += meson-drm.o --- -1.9.1 - diff --git a/patch/kernel/odroidc2-next/0047-clk-add-clk_core_set_phase_nolock-function.patch b/patch/kernel/odroidc2-next/0047-clk-add-clk_core_set_phase_nolock-function.patch new file mode 100644 index 000000000..bf5f41c9f --- /dev/null +++ b/patch/kernel/odroidc2-next/0047-clk-add-clk_core_set_phase_nolock-function.patch @@ -0,0 +1,76 @@ +From 12e852dedde5d635713d095df5e83cc3ac54c64a Mon Sep 17 00:00:00 2001 +From: Jerome Brunet +Date: Mon, 20 Mar 2017 12:20:41 +0100 +Subject: [PATCH 47/79] clk: add clk_core_set_phase_nolock function + +Create a core function for set_phase, as it is done for set_rate and +set_parent. + +This rework is done to ease the integration of "protected" clock +functionality. + +Signed-off-by: Jerome Brunet +Signed-off-by: Neil Armstrong +--- + drivers/clk/clk.c | 31 +++++++++++++++++++------------ + 1 file changed, 19 insertions(+), 12 deletions(-) + +diff --git a/drivers/clk/clk.c b/drivers/clk/clk.c +index f5c3715..dceaf0f 100644 +--- a/drivers/clk/clk.c ++++ b/drivers/clk/clk.c +@@ -1873,6 +1873,23 @@ int clk_set_parent(struct clk *clk, struct clk *parent) + } + EXPORT_SYMBOL_GPL(clk_set_parent); + ++static int clk_core_set_phase_nolock(struct clk_core *core, int degrees) ++{ ++ int ret = -EINVAL; ++ ++ if (!core) ++ return 0; ++ ++ trace_clk_set_phase(core, degrees); ++ ++ if (core->ops->set_phase) ++ ret = core->ops->set_phase(core->hw, degrees); ++ ++ trace_clk_set_phase_complete(core, degrees); ++ ++ return ret; ++} ++ + /** + * clk_set_phase - adjust the phase shift of a clock signal + * @clk: clock signal source +@@ -1895,7 +1912,7 @@ int clk_set_parent(struct clk *clk, struct clk *parent) + */ + int clk_set_phase(struct clk *clk, int degrees) + { +- int ret = -EINVAL; ++ int ret; + + if (!clk) + return 0; +@@ -1906,17 +1923,7 @@ int clk_set_phase(struct clk *clk, int degrees) + degrees += 360; + + clk_prepare_lock(); +- +- trace_clk_set_phase(clk->core, degrees); +- +- if (clk->core->ops->set_phase) +- ret = clk->core->ops->set_phase(clk->core->hw, degrees); +- +- trace_clk_set_phase_complete(clk->core, degrees); +- +- if (!ret) +- clk->core->phase = degrees; +- ++ ret = clk_core_set_phase_nolock(clk->core, degrees); + clk_prepare_unlock(); + + return ret; +-- +1.9.1 + diff --git a/patch/kernel/odroidc2-next/0047-drm-meson-rename-driver-name-to-meson-drm.patch b/patch/kernel/odroidc2-next/0047-drm-meson-rename-driver-name-to-meson-drm.patch deleted file mode 100644 index 9a3023e34..000000000 --- a/patch/kernel/odroidc2-next/0047-drm-meson-rename-driver-name-to-meson-drm.patch +++ /dev/null @@ -1,34 +0,0 @@ -From e0f2204f17c247d5e9384d8a57835b480ff16115 Mon Sep 17 00:00:00 2001 -From: Neil Armstrong -Date: Thu, 2 Feb 2017 10:47:44 +0100 -Subject: [PATCH 47/93] drm: meson: rename driver name to meson-drm - -The platform driver name is currently "meson" which can lead to some -confusion, this patch renames it to "meson-drm" and removes the owner -attribute since is always added by __platform_driver_register called by the -module_platform_driver() macro. - -Signed-off-by: Neil Armstrong -Acked-by: Daniel Vetter -Link: http://patchwork.freedesktop.org/patch/msgid/1486028864-19622-3-git-send-email-narmstrong@baylibre.com ---- - drivers/gpu/drm/meson/meson_drv.c | 3 +-- - 1 file changed, 1 insertion(+), 2 deletions(-) - -diff --git a/drivers/gpu/drm/meson/meson_drv.c b/drivers/gpu/drm/meson/meson_drv.c -index ff1f601..380bde7 100644 ---- a/drivers/gpu/drm/meson/meson_drv.c -+++ b/drivers/gpu/drm/meson/meson_drv.c -@@ -329,8 +329,7 @@ static int meson_drv_remove(struct platform_device *pdev) - .probe = meson_drv_probe, - .remove = meson_drv_remove, - .driver = { -- .owner = THIS_MODULE, -- .name = DRIVER_NAME, -+ .name = "meson-drm", - .of_match_table = dt_match, - }, - }; --- -1.9.1 - diff --git a/patch/kernel/odroidc2-next/0048-clk-rework-calls-to-round-and-determine-rate-callbac.patch b/patch/kernel/odroidc2-next/0048-clk-rework-calls-to-round-and-determine-rate-callbac.patch new file mode 100644 index 000000000..888b79bc5 --- /dev/null +++ b/patch/kernel/odroidc2-next/0048-clk-rework-calls-to-round-and-determine-rate-callbac.patch @@ -0,0 +1,146 @@ +From c87711484070e9fb733330662a19f7fc1de9b368 Mon Sep 17 00:00:00 2001 +From: Jerome Brunet +Date: Mon, 20 Mar 2017 14:35:47 +0100 +Subject: [PATCH 48/79] clk: rework calls to round and determine rate callbacks + +Rework the way the callbacks round_rate and determine_rate are called. The +goal is to do this at a single point and make it easier to add conditions +before calling them. + +This rework is done to ease the integration of "protected" clock +functionality. + +Signed-off-by: Jerome Brunet +Signed-off-by: Neil Armstrong +--- + drivers/clk/clk.c | 78 +++++++++++++++++++++++++++++++------------------------ + 1 file changed, 44 insertions(+), 34 deletions(-) + +diff --git a/drivers/clk/clk.c b/drivers/clk/clk.c +index dceaf0f..8cc4672 100644 +--- a/drivers/clk/clk.c ++++ b/drivers/clk/clk.c +@@ -833,16 +833,34 @@ static int clk_disable_unused(void) + } + late_initcall_sync(clk_disable_unused); + +-static int clk_core_round_rate_nolock(struct clk_core *core, +- struct clk_rate_request *req) ++static int clk_core_determine_round(struct clk_core *core, ++ struct clk_rate_request *req) + { +- struct clk_core *parent; + long rate; + +- lockdep_assert_held(&prepare_lock); ++ if (core->ops->determine_rate) { ++ return core->ops->determine_rate(core->hw, req); ++ } else if (core->ops->round_rate) { ++ rate = core->ops->round_rate(core->hw, req->rate, ++ &req->best_parent_rate); ++ if (rate < 0) ++ return rate; + +- if (!core) +- return 0; ++ req->rate = rate; ++ } else { ++ return -EINVAL; ++ } ++ ++ return 0; ++} ++ ++static void clk_core_init_rate_req(struct clk_core *core, ++ struct clk_rate_request *req) ++{ ++ struct clk_core *parent; ++ ++ if (WARN_ON(!core || !req)) ++ return; + + parent = core->parent; + if (parent) { +@@ -852,22 +870,24 @@ static int clk_core_round_rate_nolock(struct clk_core *core, + req->best_parent_hw = NULL; + req->best_parent_rate = 0; + } ++} + +- if (core->ops->determine_rate) { +- return core->ops->determine_rate(core->hw, req); +- } else if (core->ops->round_rate) { +- rate = core->ops->round_rate(core->hw, req->rate, +- &req->best_parent_rate); +- if (rate < 0) +- return rate; ++static int clk_core_round_rate_nolock(struct clk_core *core, ++ struct clk_rate_request *req) ++{ ++ lockdep_assert_held(&prepare_lock); + +- req->rate = rate; +- } else if (core->flags & CLK_SET_RATE_PARENT) { +- return clk_core_round_rate_nolock(parent, req); +- } else { +- req->rate = core->rate; +- } ++ if (!core) ++ return 0; ++ ++ clk_core_init_rate_req(core, req); ++ ++ if (core->ops->determine_rate || core->ops->round_rate) ++ return clk_core_determine_round(core, req); ++ else if (core->flags & CLK_SET_RATE_PARENT) ++ return clk_core_round_rate_nolock(core->parent, req); + ++ req->rate = core->rate; + return 0; + } + +@@ -1356,36 +1376,26 @@ static struct clk_core *clk_calc_new_rates(struct clk_core *core, + clk_core_get_boundaries(core, &min_rate, &max_rate); + + /* find the closest rate and parent clk/rate */ +- if (core->ops->determine_rate) { ++ if (core->ops->determine_rate || core->ops->round_rate) { + struct clk_rate_request req; + + req.rate = rate; + req.min_rate = min_rate; + req.max_rate = max_rate; +- if (parent) { +- req.best_parent_hw = parent->hw; +- req.best_parent_rate = parent->rate; +- } else { +- req.best_parent_hw = NULL; +- req.best_parent_rate = 0; +- } + +- ret = core->ops->determine_rate(core->hw, &req); ++ clk_core_init_rate_req(core, &req); ++ ++ ret = clk_core_determine_round(core, &req); + if (ret < 0) + return NULL; + + best_parent_rate = req.best_parent_rate; + new_rate = req.rate; + parent = req.best_parent_hw ? req.best_parent_hw->core : NULL; +- } else if (core->ops->round_rate) { +- ret = core->ops->round_rate(core->hw, rate, +- &best_parent_rate); +- if (ret < 0) +- return NULL; + +- new_rate = ret; + if (new_rate < min_rate || new_rate > max_rate) + return NULL; ++ + } else if (!parent || !(core->flags & CLK_SET_RATE_PARENT)) { + /* pass-through clock without adjustable parent */ + core->new_rate = core->rate; +-- +1.9.1 + diff --git a/patch/kernel/odroidc2-next/0048-drm-meson-Use-crtc_state-for-hdisplay-and-fix-atomic.patch b/patch/kernel/odroidc2-next/0048-drm-meson-Use-crtc_state-for-hdisplay-and-fix-atomic.patch deleted file mode 100644 index 6baf4a017..000000000 --- a/patch/kernel/odroidc2-next/0048-drm-meson-Use-crtc_state-for-hdisplay-and-fix-atomic.patch +++ /dev/null @@ -1,61 +0,0 @@ -From 1f82a2baa3b5935ed41738f38cf486872aa8a9f7 Mon Sep 17 00:00:00 2001 -From: Neil Armstrong -Date: Fri, 13 Jan 2017 15:57:10 +0100 -Subject: [PATCH 48/93] drm/meson: Use crtc_state for hdisplay and fix atomic - flush/enable sync for vsync commit - -Clean the crtc_enable by using the proper crtc_state instead of the state -of the primary plane state data. - -Also fix the dependency to commit the plane changes even if enable is called -after the flush. ---- - drivers/gpu/drm/meson/meson_crtc.c | 15 +++++++++++---- - 1 file changed, 11 insertions(+), 4 deletions(-) - -diff --git a/drivers/gpu/drm/meson/meson_crtc.c b/drivers/gpu/drm/meson/meson_crtc.c -index 749770e..d4b114d 100644 ---- a/drivers/gpu/drm/meson/meson_crtc.c -+++ b/drivers/gpu/drm/meson/meson_crtc.c -@@ -60,11 +60,18 @@ struct meson_crtc { - static void meson_crtc_enable(struct drm_crtc *crtc) - { - struct meson_crtc *meson_crtc = to_meson_crtc(crtc); -- struct drm_plane *plane = meson_crtc->priv->primary_plane; -+ struct drm_crtc_state *crtc_state = crtc->state; - struct meson_drm *priv = meson_crtc->priv; - -+ DRM_DEBUG_DRIVER("\n"); -+ -+ if (!crtc_state) { -+ DRM_ERROR("Invalid crtc_state\n"); -+ return; -+ } -+ - /* Enable VPP Postblend */ -- writel(plane->state->crtc_w, -+ writel(crtc_state->mode.hdisplay, - priv->io_base + _REG(VPP_POSTBLEND_H_SIZE)); - - writel_bits_relaxed(VPP_POSTBLEND_ENABLE, VPP_POSTBLEND_ENABLE, -@@ -79,6 +86,7 @@ static void meson_crtc_disable(struct drm_crtc *crtc) - struct meson_drm *priv = meson_crtc->priv; - - priv->viu.osd1_enabled = false; -+ priv->viu.osd1_commit = false; - - /* Disable VPP Postblend */ - writel_bits_relaxed(VPP_POSTBLEND_ENABLE, 0, -@@ -115,8 +123,7 @@ static void meson_crtc_atomic_flush(struct drm_crtc *crtc, - struct meson_crtc *meson_crtc = to_meson_crtc(crtc); - struct meson_drm *priv = meson_crtc->priv; - -- if (priv->viu.osd1_enabled) -- priv->viu.osd1_commit = true; -+ priv->viu.osd1_commit = true; - } - - static const struct drm_crtc_helper_funcs meson_crtc_helper_funcs = { --- -1.9.1 - diff --git a/patch/kernel/odroidc2-next/0049-clk-use-round-rate-to-bail-out-early-in-set_rate.patch b/patch/kernel/odroidc2-next/0049-clk-use-round-rate-to-bail-out-early-in-set_rate.patch new file mode 100644 index 000000000..f5a1a7ccd --- /dev/null +++ b/patch/kernel/odroidc2-next/0049-clk-use-round-rate-to-bail-out-early-in-set_rate.patch @@ -0,0 +1,77 @@ +From 0e588289da294fb71f7873c2781758a7ba19dc7f Mon Sep 17 00:00:00 2001 +From: Jerome Brunet +Date: Fri, 19 May 2017 11:44:22 +0200 +Subject: [PATCH 49/79] clk: use round rate to bail out early in set_rate + +The current implementation of clk_core_set_rate_nolock bails out early if +the requested rate is exactly the same as the one set. It should bail out +if the request would not result in rate a change. This important when rate +is not exactly what is requested, which is fairly common with PLLs. + +Ex: provider able to give any rate with steps of 100Hz + - 1st consumer request 48000Hz and gets it. + - 2nd consumer request 48010Hz as well. If we were to perform the usual + mechanism, we would get 48000Hz as well. The clock would not change so + there is no point performing any checks to make sure the clock can change, + we know it won't. + +This is important to prepare the addition of the clock protection mechanism + +Signed-off-by: Jerome Brunet +Signed-off-by: Neil Armstrong +--- + drivers/clk/clk.c | 23 +++++++++++++++++++++-- + 1 file changed, 21 insertions(+), 2 deletions(-) + +diff --git a/drivers/clk/clk.c b/drivers/clk/clk.c +index 8cc4672..163cb98 100644 +--- a/drivers/clk/clk.c ++++ b/drivers/clk/clk.c +@@ -1570,15 +1570,34 @@ static void clk_change_rate(struct clk_core *core) + clk_change_rate(core->new_child); + } + ++static unsigned long clk_core_req_round_rate_nolock(struct clk_core *core, ++ unsigned long req_rate) ++{ ++ int ret; ++ struct clk_rate_request req; ++ ++ if (!core) ++ return 0; ++ ++ clk_core_get_boundaries(core, &req.min_rate, &req.max_rate); ++ req.rate = req_rate; ++ ++ ret = clk_core_round_rate_nolock(core, &req); ++ ++ return ret ? 0 : req.rate; ++} ++ + static int clk_core_set_rate_nolock(struct clk_core *core, + unsigned long req_rate) + { + struct clk_core *top, *fail_clk; +- unsigned long rate = req_rate; ++ unsigned long rate; + + if (!core) + return 0; + ++ rate = clk_core_req_round_rate_nolock(core, req_rate); ++ + /* bail early if nothing to do */ + if (rate == clk_core_get_rate_nolock(core)) + return 0; +@@ -1587,7 +1606,7 @@ static int clk_core_set_rate_nolock(struct clk_core *core, + return -EBUSY; + + /* calculate new rates and get the topmost changed clock */ +- top = clk_calc_new_rates(core, rate); ++ top = clk_calc_new_rates(core, req_rate); + if (!top) + return -EINVAL; + +-- +1.9.1 + diff --git a/patch/kernel/odroidc2-next/0049-drm-meson-Add-missing-HDMI-register.patch b/patch/kernel/odroidc2-next/0049-drm-meson-Add-missing-HDMI-register.patch deleted file mode 100644 index cbe50e0b3..000000000 --- a/patch/kernel/odroidc2-next/0049-drm-meson-Add-missing-HDMI-register.patch +++ /dev/null @@ -1,25 +0,0 @@ -From aff67758d0ff7e376229fbdc6dc1f92d8e7da770 Mon Sep 17 00:00:00 2001 -From: Neil Armstrong -Date: Fri, 13 Jan 2017 15:57:38 +0100 -Subject: [PATCH 49/93] drm/meson: Add missing HDMI register - -Add missing VPU HDMI register. ---- - drivers/gpu/drm/meson/meson_registers.h | 1 + - 1 file changed, 1 insertion(+) - -diff --git a/drivers/gpu/drm/meson/meson_registers.h b/drivers/gpu/drm/meson/meson_registers.h -index 6adf9c1..2847381 100644 ---- a/drivers/gpu/drm/meson/meson_registers.h -+++ b/drivers/gpu/drm/meson/meson_registers.h -@@ -1319,6 +1319,7 @@ - #define VPU_MISC_CTRL 0x2740 - #define VPU_ISP_GCLK_CTRL0 0x2741 - #define VPU_ISP_GCLK_CTRL1 0x2742 -+#define VPU_HDMI_FMT_CTRL 0x2743 - #define VPU_VDIN_ASYNC_HOLD_CTRL 0x2743 - #define VPU_VDISP_ASYNC_HOLD_CTRL 0x2744 - #define VPU_VPUARB2_ASYNC_HOLD_CTRL 0x2745 --- -1.9.1 - diff --git a/patch/kernel/odroidc2-next/0050-clk-add-support-for-clock-protection.patch b/patch/kernel/odroidc2-next/0050-clk-add-support-for-clock-protection.patch new file mode 100644 index 000000000..38a115c63 --- /dev/null +++ b/patch/kernel/odroidc2-next/0050-clk-add-support-for-clock-protection.patch @@ -0,0 +1,462 @@ +From ae5671893c76164ddbc7b9b0f6ea4361a121090f Mon Sep 17 00:00:00 2001 +From: Jerome Brunet +Date: Mon, 20 Mar 2017 16:48:17 +0100 +Subject: [PATCH 50/79] clk: add support for clock protection + +The patch adds clk_protect and clk_unprotect to the CCF API. These +functions allow a consumer to inform the system that the rate of clock is +critical to for its operations and it can't tolerate other consumers +changing the rate or introducing glitches while the clock is protected. + +Signed-off-by: Jerome Brunet +Signed-off-by: Neil Armstrong +--- + drivers/clk/clk.c | 205 +++++++++++++++++++++++++++++++++++++++++-- + include/linux/clk-provider.h | 1 + + include/linux/clk.h | 29 ++++++ + 3 files changed, 229 insertions(+), 6 deletions(-) + +diff --git a/drivers/clk/clk.c b/drivers/clk/clk.c +index 163cb98..d688b8f 100644 +--- a/drivers/clk/clk.c ++++ b/drivers/clk/clk.c +@@ -60,6 +60,7 @@ struct clk_core { + bool orphan; + unsigned int enable_count; + unsigned int prepare_count; ++ unsigned int protect_count; + unsigned long min_rate; + unsigned long max_rate; + unsigned long accuracy; +@@ -84,6 +85,7 @@ struct clk { + const char *con_id; + unsigned long min_rate; + unsigned long max_rate; ++ unsigned long protect_count; + struct hlist_node clks_node; + }; + +@@ -148,6 +150,11 @@ static void clk_enable_unlock(unsigned long flags) + spin_unlock_irqrestore(&enable_lock, flags); + } + ++static bool clk_core_rate_is_protected(struct clk_core *core) ++{ ++ return core->protect_count; ++} ++ + static bool clk_core_is_prepared(struct clk_core *core) + { + /* +@@ -328,6 +335,11 @@ bool clk_hw_is_prepared(const struct clk_hw *hw) + return clk_core_is_prepared(hw->core); + } + ++bool clk_hw_rate_is_protected(const struct clk_hw *hw) ++{ ++ return clk_core_rate_is_protected(hw->core); ++} ++ + bool clk_hw_is_enabled(const struct clk_hw *hw) + { + return clk_core_is_enabled(hw->core); +@@ -466,6 +478,102 @@ int __clk_mux_determine_rate_closest(struct clk_hw *hw, + + /*** clk api ***/ + ++static void clk_core_rate_unprotect(struct clk_core *core) ++{ ++ lockdep_assert_held(&prepare_lock); ++ ++ if (!core) ++ return; ++ ++ if (WARN_ON(core->protect_count == 0)) ++ return; ++ ++ if (--core->protect_count > 0) ++ return; ++ ++ clk_core_rate_unprotect(core->parent); ++} ++ ++/** ++ * clk_rate_unprotect - unprotect the rate of a clock source ++ * @clk: the clk being unprotected ++ * ++ * clk_unprotect completes a critical section during which the clock ++ * consumer cannot tolerate any change to the clock rate. If no other clock ++ * consumers have protected clocks in the parent chain, then calls to this ++ * function will allow the clocks in the parent chain to change rates ++ * freely. ++ * ++ * Unlike the clk_set_rate_range method, which allows the rate to change ++ * within a given range, protected clocks cannot have their rate changed, ++ * either directly or indirectly due to changes further up the parent chain ++ * of clocks. ++ * ++ * Calls to clk_unprotect must be balanced with calls to clk_protect. Calls ++ * to this function may sleep, and do not return error status. ++ */ ++void clk_rate_unprotect(struct clk *clk) ++{ ++ if (!clk) ++ return; ++ ++ clk_prepare_lock(); ++ ++ /* ++ * if there is something wrong with this consumer protect count, stop ++ * here before messing with the provider ++ */ ++ if (WARN_ON(clk->protect_count <= 0)) ++ goto out; ++ ++ clk_core_rate_unprotect(clk->core); ++ clk->protect_count--; ++out: ++ clk_prepare_unlock(); ++} ++EXPORT_SYMBOL_GPL(clk_rate_unprotect); ++ ++static void clk_core_rate_protect(struct clk_core *core) ++{ ++ lockdep_assert_held(&prepare_lock); ++ ++ if (!core) ++ return; ++ ++ if (core->protect_count == 0) ++ clk_core_rate_protect(core->parent); ++ ++ core->protect_count++; ++} ++ ++/** ++ * clk_rate_protect - protect a clock source ++ * @clk: the clk being protected ++ * ++ * clk_protect begins a critical section during which the clock consumer ++ * cannot tolerate any change to the clock rate. This results in all clocks ++ * up the parent chain to also be rate-protected. ++ * ++ * Unlike the clk_set_rate_range method, which allows the rate to change ++ * within a given range, protected clocks cannot have their rate changed, ++ * either directly or indirectly due to changes further up the parent chain ++ * of clocks. ++ * ++ * Calls to clk_protect should be balanced with calls to clk_unprotect. ++ * Calls to this function may sleep, and do not return error status. ++ */ ++void clk_rate_protect(struct clk *clk) ++{ ++ if (!clk) ++ return; ++ ++ clk_prepare_lock(); ++ clk_core_rate_protect(clk->core); ++ clk->protect_count++; ++ clk_prepare_unlock(); ++} ++EXPORT_SYMBOL_GPL(clk_rate_protect); ++ + static void clk_core_unprepare(struct clk_core *core) + { + lockdep_assert_held(&prepare_lock); +@@ -838,7 +946,15 @@ static int clk_core_determine_round(struct clk_core *core, + { + long rate; + +- if (core->ops->determine_rate) { ++ /* ++ * At this point, core protection will be disabled if ++ * - if the provider is not protected at all ++ * - if the calling consumer is the only one protecting the ++ * provider (and only once) ++ */ ++ if (clk_core_rate_is_protected(core)) { ++ req->rate = core->rate; ++ } else if (core->ops->determine_rate) { + return core->ops->determine_rate(core->hw, req); + } else if (core->ops->round_rate) { + rate = core->ops->round_rate(core->hw, req->rate, +@@ -944,10 +1060,17 @@ long clk_round_rate(struct clk *clk, unsigned long rate) + + clk_prepare_lock(); + ++ if (clk->protect_count) ++ clk_core_rate_unprotect(clk->core); ++ + clk_core_get_boundaries(clk->core, &req.min_rate, &req.max_rate); + req.rate = rate; + + ret = clk_core_round_rate_nolock(clk->core, &req); ++ ++ if (clk->protect_count) ++ clk_core_rate_protect(clk->core); ++ + clk_prepare_unlock(); + + if (ret) +@@ -1575,15 +1698,24 @@ static unsigned long clk_core_req_round_rate_nolock(struct clk_core *core, + { + int ret; + struct clk_rate_request req; ++ unsigned int cnt = core->protect_count; + + if (!core) + return 0; + ++ /* simulate what the rate would be if it could be freely set */ ++ while (core->protect_count) ++ clk_core_rate_unprotect(core); ++ + clk_core_get_boundaries(core, &req.min_rate, &req.max_rate); + req.rate = req_rate; + + ret = clk_core_round_rate_nolock(core, &req); + ++ /* restore the protection */ ++ while (core->protect_count < cnt) ++ clk_core_rate_protect(core); ++ + return ret ? 0 : req.rate; + } + +@@ -1602,6 +1734,10 @@ static int clk_core_set_rate_nolock(struct clk_core *core, + if (rate == clk_core_get_rate_nolock(core)) + return 0; + ++ /* fail on a direct rate set of a protected provider */ ++ if (clk_core_rate_is_protected(core)) ++ return -EBUSY; ++ + if ((core->flags & CLK_SET_RATE_GATE) && core->prepare_count) + return -EBUSY; + +@@ -1658,8 +1794,14 @@ int clk_set_rate(struct clk *clk, unsigned long rate) + /* prevent racing with updates to the clock topology */ + clk_prepare_lock(); + ++ if (clk->protect_count) ++ clk_core_rate_unprotect(clk->core); ++ + ret = clk_core_set_rate_nolock(clk->core, rate); + ++ if (clk->protect_count) ++ clk_core_rate_protect(clk->core); ++ + clk_prepare_unlock(); + + return ret; +@@ -1690,12 +1832,18 @@ int clk_set_rate_range(struct clk *clk, unsigned long min, unsigned long max) + + clk_prepare_lock(); + ++ if (clk->protect_count) ++ clk_core_rate_unprotect(clk->core); ++ + if (min != clk->min_rate || max != clk->max_rate) { + clk->min_rate = min; + clk->max_rate = max; + ret = clk_core_set_rate_nolock(clk->core, clk->core->req_rate); + } + ++ if (clk->protect_count) ++ clk_core_rate_protect(clk->core); ++ + clk_prepare_unlock(); + + return ret; +@@ -1837,6 +1985,9 @@ static int clk_core_set_parent_nolock(struct clk_core *core, + if ((core->flags & CLK_SET_PARENT_GATE) && core->prepare_count) + return -EBUSY; + ++ if (clk_core_rate_is_protected(core)) ++ return -EBUSY; ++ + /* try finding the new parent index */ + if (parent) { + p_index = clk_fetch_parent_index(core, parent); +@@ -1894,8 +2045,16 @@ int clk_set_parent(struct clk *clk, struct clk *parent) + return 0; + + clk_prepare_lock(); ++ ++ if (clk->protect_count) ++ clk_core_rate_unprotect(clk->core); ++ + ret = clk_core_set_parent_nolock(clk->core, + parent ? parent->core : NULL); ++ ++ if (clk->protect_count) ++ clk_core_rate_protect(clk->core); ++ + clk_prepare_unlock(); + + return ret; +@@ -1909,6 +2068,9 @@ static int clk_core_set_phase_nolock(struct clk_core *core, int degrees) + if (!core) + return 0; + ++ if (clk_core_rate_is_protected(core)) ++ return -EBUSY; ++ + trace_clk_set_phase(core, degrees); + + if (core->ops->set_phase) +@@ -1952,7 +2114,15 @@ int clk_set_phase(struct clk *clk, int degrees) + degrees += 360; + + clk_prepare_lock(); ++ ++ if (clk->protect_count) ++ clk_core_rate_unprotect(clk->core); ++ + ret = clk_core_set_phase_nolock(clk->core, degrees); ++ ++ if (clk->protect_count) ++ clk_core_rate_protect(clk->core); ++ + clk_prepare_unlock(); + + return ret; +@@ -2039,11 +2209,12 @@ static void clk_summary_show_one(struct seq_file *s, struct clk_core *c, + if (!c) + return; + +- seq_printf(s, "%*s%-*s %11d %12d %11lu %10lu %-3d\n", ++ seq_printf(s, "%*s%-*s %11d %12d %12d %11lu %10lu %-3d\n", + level * 3 + 1, "", + 30 - level * 3, c->name, +- c->enable_count, c->prepare_count, clk_core_get_rate(c), +- clk_core_get_accuracy(c), clk_core_get_phase(c)); ++ c->enable_count, c->prepare_count, c->protect_count, ++ clk_core_get_rate(c), clk_core_get_accuracy(c), ++ clk_core_get_phase(c)); + } + + static void clk_summary_show_subtree(struct seq_file *s, struct clk_core *c, +@@ -2065,8 +2236,8 @@ static int clk_summary_show(struct seq_file *s, void *data) + struct clk_core *c; + struct hlist_head **lists = (struct hlist_head **)s->private; + +- seq_puts(s, " clock enable_cnt prepare_cnt rate accuracy phase\n"); +- seq_puts(s, "----------------------------------------------------------------------------------------\n"); ++ seq_puts(s, " clock enable_cnt prepare_cnt protect_cnt rate accuracy phase\n"); ++ seq_puts(s, "----------------------------------------------------------------------------------------------------\n"); + + clk_prepare_lock(); + +@@ -2101,6 +2272,7 @@ static void clk_dump_one(struct seq_file *s, struct clk_core *c, int level) + seq_printf(s, "\"%s\": { ", c->name); + seq_printf(s, "\"enable_count\": %d,", c->enable_count); + seq_printf(s, "\"prepare_count\": %d,", c->prepare_count); ++ seq_printf(s, "\"protect_count\": %d,", c->protect_count); + seq_printf(s, "\"rate\": %lu,", clk_core_get_rate(c)); + seq_printf(s, "\"accuracy\": %lu,", clk_core_get_accuracy(c)); + seq_printf(s, "\"phase\": %d", clk_core_get_phase(c)); +@@ -2231,6 +2403,11 @@ static int clk_debug_create_one(struct clk_core *core, struct dentry *pdentry) + if (!d) + goto err_out; + ++ d = debugfs_create_u32("clk_protect_count", S_IRUGO, core->dentry, ++ (u32 *)&core->protect_count); ++ if (!d) ++ goto err_out; ++ + d = debugfs_create_u32("clk_notifier_count", S_IRUGO, core->dentry, + (u32 *)&core->notifier_count); + if (!d) +@@ -2794,6 +2971,11 @@ void clk_unregister(struct clk *clk) + if (clk->core->prepare_count) + pr_warn("%s: unregistering prepared clock: %s\n", + __func__, clk->core->name); ++ ++ if (clk->core->protect_count) ++ pr_warn("%s: unregistering protected clock: %s\n", ++ __func__, clk->core->name); ++ + kref_put(&clk->core->ref, __clk_release); + unlock: + clk_prepare_unlock(); +@@ -2952,6 +3134,17 @@ void __clk_put(struct clk *clk) + + clk_prepare_lock(); + ++ /* ++ * Before calling clk_put, all calls to clk_rate_protect from a given ++ * user must be balanced with calls to clk_rate_unprotect and by that ++ * same user ++ */ ++ WARN_ON(clk->protect_count); ++ ++ /* We voiced our concern, let's sanitize the situation */ ++ for (; clk->protect_count; clk->protect_count--) ++ clk_core_rate_unprotect(clk->core); ++ + hlist_del(&clk->clks_node); + if (clk->min_rate > clk->core->req_rate || + clk->max_rate < clk->core->req_rate) +diff --git a/include/linux/clk-provider.h b/include/linux/clk-provider.h +index a428aec..ebd7df5 100644 +--- a/include/linux/clk-provider.h ++++ b/include/linux/clk-provider.h +@@ -739,6 +739,7 @@ struct clk_hw *clk_hw_get_parent_by_index(const struct clk_hw *hw, + unsigned long __clk_get_flags(struct clk *clk); + unsigned long clk_hw_get_flags(const struct clk_hw *hw); + bool clk_hw_is_prepared(const struct clk_hw *hw); ++bool clk_hw_rate_is_protected(const struct clk_hw *hw); + bool clk_hw_is_enabled(const struct clk_hw *hw); + bool __clk_is_enabled(struct clk *clk); + struct clk *__clk_lookup(const char *name); +diff --git a/include/linux/clk.h b/include/linux/clk.h +index 024cd07..85d73e0 100644 +--- a/include/linux/clk.h ++++ b/include/linux/clk.h +@@ -265,6 +265,30 @@ static inline void clk_unprepare(struct clk *clk) + */ + struct clk *devm_get_clk_from_child(struct device *dev, + struct device_node *np, const char *con_id); ++/** ++ * clk_rate_protect - inform the system when the clock rate must be protected. ++ * @clk: clock source ++ * ++ * This function informs the system that the consumer protecting the clock ++ * depends on the rate of the clock source and can't tolerate any glitches ++ * introduced by further clock rate change or re-parenting of the clock source. ++ * ++ * Must not be called from within atomic context. ++ */ ++void clk_rate_protect(struct clk *clk); ++ ++/** ++ * clk_rate_unprotect - release the protection of the clock source. ++ * @clk: clock source ++ * ++ * This function informs the system that the consumer previously protecting the ++ * clock rate can now deal with other consumer altering the clock source rate ++ * ++ * The caller must balance the number of rate_protect and rate_unprotect calls. ++ * ++ * Must not be called from within atomic context. ++ */ ++void clk_rate_unprotect(struct clk *clk); + + /** + * clk_enable - inform the system when the clock source should be running. +@@ -460,6 +484,11 @@ static inline void clk_put(struct clk *clk) {} + + static inline void devm_clk_put(struct device *dev, struct clk *clk) {} + ++ ++static inline void clk_protect(struct clk *clk) {} ++ ++static inline void clk_unprotect(struct clk *clk) {} ++ + static inline int clk_enable(struct clk *clk) + { + return 0; +-- +1.9.1 + diff --git a/patch/kernel/odroidc2-next/0050-drm-meson-Add-support-for-components.patch b/patch/kernel/odroidc2-next/0050-drm-meson-Add-support-for-components.patch deleted file mode 100644 index 7c348ca3a..000000000 --- a/patch/kernel/odroidc2-next/0050-drm-meson-Add-support-for-components.patch +++ /dev/null @@ -1,191 +0,0 @@ -From 5e358cdbdb00b0733e51f29a3f235a3cf3efe159 Mon Sep 17 00:00:00 2001 -From: Neil Armstrong -Date: Mon, 9 Jan 2017 14:16:44 +0100 -Subject: [PATCH 50/93] drm/meson: Add support for components - -This patch adds support for optional components connected through the -Device Tree endpoints scheme. ---- - drivers/gpu/drm/meson/meson_drv.c | 113 +++++++++++++++++++++++++++++++++----- - 1 file changed, 99 insertions(+), 14 deletions(-) - -diff --git a/drivers/gpu/drm/meson/meson_drv.c b/drivers/gpu/drm/meson/meson_drv.c -index 380bde7..4b506d0 100644 ---- a/drivers/gpu/drm/meson/meson_drv.c -+++ b/drivers/gpu/drm/meson/meson_drv.c -@@ -24,6 +24,7 @@ - #include - #include - #include -+#include - #include - - #include -@@ -183,9 +184,9 @@ static bool meson_vpu_has_available_connectors(struct device *dev) - .max_register = 0x1000, - }; - --static int meson_drv_probe(struct platform_device *pdev) -+static int meson_drv_bind(struct device *dev) - { -- struct device *dev = &pdev->dev; -+ struct platform_device *pdev = to_platform_device(dev); - struct meson_drm *priv; - struct drm_device *drm; - struct resource *res; -@@ -248,6 +249,15 @@ static int meson_drv_probe(struct platform_device *pdev) - - drm_vblank_init(drm, 1); - drm_mode_config_init(drm); -+ drm->mode_config.max_width = 3840; -+ drm->mode_config.max_height = 2160; -+ drm->mode_config.funcs = &meson_mode_config_funcs; -+ -+ /* Hardware Initialization */ -+ -+ meson_venc_init(priv); -+ meson_vpp_init(priv); -+ meson_viu_init(priv); - - /* Encoder Initialization */ - -@@ -255,11 +265,11 @@ static int meson_drv_probe(struct platform_device *pdev) - if (ret) - goto free_drm; - -- /* Hardware Initialization */ -- -- meson_venc_init(priv); -- meson_vpp_init(priv); -- meson_viu_init(priv); -+ ret = component_bind_all(drm->dev, drm); -+ if (ret) { -+ dev_err(drm->dev, "Couldn't bind all components\n"); -+ goto free_drm; -+ } - - ret = meson_plane_create(priv); - if (ret) -@@ -274,9 +284,6 @@ static int meson_drv_probe(struct platform_device *pdev) - goto free_drm; - - drm_mode_config_reset(drm); -- drm->mode_config.max_width = 8192; -- drm->mode_config.max_height = 8192; -- drm->mode_config.funcs = &meson_mode_config_funcs; - - priv->fbdev = drm_fbdev_cma_init(drm, 32, - drm->mode_config.num_crtc, -@@ -302,9 +309,9 @@ static int meson_drv_probe(struct platform_device *pdev) - return ret; - } - --static int meson_drv_remove(struct platform_device *pdev) -+static void meson_drv_unbind(struct device *dev) - { -- struct drm_device *drm = dev_get_drvdata(&pdev->dev); -+ struct drm_device *drm = dev_get_drvdata(dev); - struct meson_drm *priv = drm->dev_private; - - drm_dev_unregister(drm); -@@ -314,9 +321,88 @@ static int meson_drv_remove(struct platform_device *pdev) - drm_vblank_cleanup(drm); - drm_dev_unref(drm); - -- return 0; - } - -+static const struct component_master_ops meson_drv_master_ops = { -+ .bind = meson_drv_bind, -+ .unbind = meson_drv_unbind, -+}; -+ -+static int compare_of(struct device *dev, void *data) -+{ -+ DRM_DEBUG_DRIVER("Comparing of node %s with %s\n", -+ of_node_full_name(dev->of_node), -+ of_node_full_name(data)); -+ -+ return dev->of_node == data; -+} -+ -+/* Possible connectors nodes to ignore */ -+static const struct of_device_id connectors_match[] = { -+ { .compatible = "composite-video-connector" }, -+ { .compatible = "svideo-connector" }, -+ { .compatible = "hdmi-connector" }, -+ { .compatible = "dvi-connector" }, -+ {} -+}; -+ -+static int meson_probe_remote(struct platform_device *pdev, -+ struct component_match **match, -+ struct device_node *parent, -+ struct device_node *remote) -+{ -+ struct device_node *ep, *remote_node; -+ int count = 1; -+ -+ /* If node is a connector, return and do not add to match table */ -+ if (of_match_node(connectors_match, remote)) -+ return 1; -+ -+ component_match_add(&pdev->dev, match, compare_of, remote); -+ -+ for_each_endpoint_of_node(remote, ep) { -+ remote_node = of_graph_get_remote_port_parent(ep); -+ if (!remote_node || -+ remote_node == parent || /* Ignore parent endpoint */ -+ !of_device_is_available(remote_node)) -+ continue; -+ -+ count += meson_probe_remote(pdev, match, remote, remote_node); -+ -+ of_node_put(remote_node); -+ } -+ -+ return count; -+} -+ -+static int meson_drv_probe(struct platform_device *pdev) -+{ -+ struct component_match *match = NULL; -+ struct device_node *np = pdev->dev.of_node; -+ struct device_node *ep, *remote; -+ int count = 0; -+ -+ for_each_endpoint_of_node(np, ep) { -+ remote = of_graph_get_remote_port_parent(ep); -+ if (!remote || !of_device_is_available(remote)) -+ continue; -+ -+ count += meson_probe_remote(pdev, &match, np, remote); -+ } -+ -+ /* If some endpoints were found, initialize the nodes */ -+ if (count) { -+ dev_info(&pdev->dev, "Queued %d outputs on vpu\n", count); -+ -+ return component_master_add_with_match(&pdev->dev, -+ &meson_drv_master_ops, -+ match); -+ } -+ -+ /* If no output endpoints were available, simply bail out */ -+ return 0; -+}; -+ - static const struct of_device_id dt_match[] = { - { .compatible = "amlogic,meson-gxbb-vpu" }, - { .compatible = "amlogic,meson-gxl-vpu" }, -@@ -327,7 +413,6 @@ static int meson_drv_remove(struct platform_device *pdev) - - static struct platform_driver meson_drm_platform_driver = { - .probe = meson_drv_probe, -- .remove = meson_drv_remove, - .driver = { - .name = "meson-drm", - .of_match_table = dt_match, --- -1.9.1 - diff --git a/patch/kernel/odroidc2-next/0051-clk-add-clk_set_rate_protect.patch b/patch/kernel/odroidc2-next/0051-clk-add-clk_set_rate_protect.patch new file mode 100644 index 000000000..d82245948 --- /dev/null +++ b/patch/kernel/odroidc2-next/0051-clk-add-clk_set_rate_protect.patch @@ -0,0 +1,112 @@ +From 88cb11f99ca3a209274faa0da15ac27bcda99959 Mon Sep 17 00:00:00 2001 +From: Jerome Brunet +Date: Thu, 18 May 2017 13:42:12 +0200 +Subject: [PATCH 51/79] clk: add clk_set_rate_protect + +clk_set_rate_protect is a combination of clk_set_rate and clk_rate_protect +within a critical section. In case where several protecting consumers +compete to set the rate of the same provider, it provides a way to make +sure that at least one of them will be satisfied before the resource is +locked. + +This is to avoid the unlikely situation where several consumers protect a +clock provider and none actually get a rate it can work with. + +Signed-off-by: Jerome Brunet +Signed-off-by: Neil Armstrong +--- + drivers/clk/clk.c | 45 +++++++++++++++++++++++++++++++++++++++++++++ + include/linux/clk.h | 14 ++++++++++++++ + 2 files changed, 59 insertions(+) + +diff --git a/drivers/clk/clk.c b/drivers/clk/clk.c +index d688b8f..d91236e 100644 +--- a/drivers/clk/clk.c ++++ b/drivers/clk/clk.c +@@ -1809,6 +1809,51 @@ int clk_set_rate(struct clk *clk, unsigned long rate) + EXPORT_SYMBOL_GPL(clk_set_rate); + + /** ++ * clk_set_rate_protect - specify a new rate and protect it ++ * @clk: the clk whose rate is being changed ++ * @rate: the new rate for clk ++ * ++ * This is a combination of clk_set_rate and clk_rate_protect within ++ * a critical section ++ * ++ * This can be used initially to ensure that at least 1 consumers is ++ * statisfied when several protecting consummers are competing for the ++ * same clock provider. ++ * ++ * The protection is not applied if setting the rate failed. ++ * ++ * Returns 0 on success, -EERROR otherwise. ++ */ ++int clk_set_rate_protect(struct clk *clk, unsigned long rate) ++{ ++ int ret; ++ ++ if (!clk) ++ return 0; ++ ++ /* prevent racing with updates to the clock topology */ ++ clk_prepare_lock(); ++ ++ /* ++ * The temporary protection removal is not here, on purpose ++ * This function is meant to be used in instead of clk_rate_protect, ++ * so before the consumer code path protect the clock provider ++ */ ++ ++ ret = clk_core_set_rate_nolock(clk->core, rate); ++ ++ if (!ret) { ++ clk_core_rate_protect(clk->core); ++ clk->protect_count++; ++ } ++ ++ clk_prepare_unlock(); ++ ++ return ret; ++} ++EXPORT_SYMBOL_GPL(clk_set_rate_protect); ++ ++/** + * clk_set_rate_range - set a rate range for a clock source + * @clk: clock source + * @min: desired minimum clock rate in Hz, inclusive +diff --git a/include/linux/clk.h b/include/linux/clk.h +index 85d73e0..d3c299d 100644 +--- a/include/linux/clk.h ++++ b/include/linux/clk.h +@@ -388,6 +388,15 @@ struct clk *devm_get_clk_from_child(struct device *dev, + int clk_set_rate(struct clk *clk, unsigned long rate); + + /** ++ * clk_set_rate_protect - set and protect the clock rate for a clock source ++ * @clk: clock source ++ * @rate: desired clock rate in Hz ++ * ++ * Returns success (0) or negative errno. ++ */ ++int clk_set_rate_protect(struct clk *clk, unsigned long rate); ++ ++/** + * clk_has_parent - check if a clock is a possible parent for another + * @clk: clock source + * @parent: parent clock source +@@ -506,6 +515,11 @@ static inline int clk_set_rate(struct clk *clk, unsigned long rate) + return 0; + } + ++static inline int clk_set_rate_protect(struct clk *clk, unsigned long rate) ++{ ++ return 0; ++} ++ + static inline long clk_round_rate(struct clk *clk, unsigned long rate) + { + return 0; +-- +1.9.1 + diff --git a/patch/kernel/odroidc2-next/0051-drm-meson-venc_cvbs-no-more-return-ENODEV-if-CVBS-is.patch b/patch/kernel/odroidc2-next/0051-drm-meson-venc_cvbs-no-more-return-ENODEV-if-CVBS-is.patch deleted file mode 100644 index a5039ae49..000000000 --- a/patch/kernel/odroidc2-next/0051-drm-meson-venc_cvbs-no-more-return-ENODEV-if-CVBS-is.patch +++ /dev/null @@ -1,28 +0,0 @@ -From 59e092e2793539ce5fe61e4e8a40732e9c76f744 Mon Sep 17 00:00:00 2001 -From: Neil Armstrong -Date: Thu, 9 Feb 2017 11:37:27 +0100 -Subject: [PATCH 51/93] drm/meson: venc_cvbs: no more return -ENODEV if CVBS is - not available - -Since this is managed now by the components code, if CVBS is not available -and HDMI neither, the drm driver won't bind anyway. ---- - drivers/gpu/drm/meson/meson_venc_cvbs.c | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/drivers/gpu/drm/meson/meson_venc_cvbs.c b/drivers/gpu/drm/meson/meson_venc_cvbs.c -index a2bcc70..a96fcb4 100644 ---- a/drivers/gpu/drm/meson/meson_venc_cvbs.c -+++ b/drivers/gpu/drm/meson/meson_venc_cvbs.c -@@ -248,7 +248,7 @@ int meson_venc_cvbs_create(struct meson_drm *priv) - - if (!meson_venc_cvbs_connector_is_available(priv)) { - dev_info(drm->dev, "CVBS Output connector not available\n"); -- return -ENODEV; -+ return 0; - } - - meson_venc_cvbs = devm_kzalloc(priv->dev, sizeof(*meson_venc_cvbs), --- -1.9.1 - diff --git a/patch/kernel/odroidc2-next/0052-clk-rollback-set_rate_range-changes-on-failure.patch b/patch/kernel/odroidc2-next/0052-clk-rollback-set_rate_range-changes-on-failure.patch new file mode 100644 index 000000000..724cc9ae2 --- /dev/null +++ b/patch/kernel/odroidc2-next/0052-clk-rollback-set_rate_range-changes-on-failure.patch @@ -0,0 +1,43 @@ +From fe7933da09cfadd75af72256a1d11f41ea5e46f0 Mon Sep 17 00:00:00 2001 +From: Jerome Brunet +Date: Mon, 20 Mar 2017 15:02:19 +0100 +Subject: [PATCH 52/79] clk: rollback set_rate_range changes on failure + +Signed-off-by: Jerome Brunet +Signed-off-by: Neil Armstrong +--- + drivers/clk/clk.c | 8 ++++++++ + 1 file changed, 8 insertions(+) + +diff --git a/drivers/clk/clk.c b/drivers/clk/clk.c +index d91236e..253f1d3 100644 +--- a/drivers/clk/clk.c ++++ b/drivers/clk/clk.c +@@ -1864,6 +1864,7 @@ int clk_set_rate_protect(struct clk *clk, unsigned long rate) + int clk_set_rate_range(struct clk *clk, unsigned long min, unsigned long max) + { + int ret = 0; ++ unsigned int old_min, old_max; + + if (!clk) + return 0; +@@ -1881,9 +1882,16 @@ int clk_set_rate_range(struct clk *clk, unsigned long min, unsigned long max) + clk_core_rate_unprotect(clk->core); + + if (min != clk->min_rate || max != clk->max_rate) { ++ old_min = clk->min_rate; ++ old_max = clk->max_rate; + clk->min_rate = min; + clk->max_rate = max; + ret = clk_core_set_rate_nolock(clk->core, clk->core->req_rate); ++ if (ret) { ++ /* undo changes */ ++ clk->min_rate = old_min; ++ clk->max_rate = old_max; ++ } + } + + if (clk->protect_count) +-- +1.9.1 + diff --git a/patch/kernel/odroidc2-next/0052-drm-meson-add-support-for-HDMI-clock-support.patch b/patch/kernel/odroidc2-next/0052-drm-meson-add-support-for-HDMI-clock-support.patch deleted file mode 100644 index a8d87dee4..000000000 --- a/patch/kernel/odroidc2-next/0052-drm-meson-add-support-for-HDMI-clock-support.patch +++ /dev/null @@ -1,740 +0,0 @@ -From 336d370ab9227e29eedd829e7f88a7ace9241298 Mon Sep 17 00:00:00 2001 -From: Neil Armstrong -Date: Mon, 9 Jan 2017 14:18:36 +0100 -Subject: [PATCH 52/93] drm/meson: add support for HDMI clock support - -This patchs adds support for the supported HDMI modes clocks frequencies. ---- - drivers/gpu/drm/meson/meson_vclk.c | 624 +++++++++++++++++++++++++++++++- - drivers/gpu/drm/meson/meson_vclk.h | 6 +- - drivers/gpu/drm/meson/meson_venc_cvbs.c | 9 +- - 3 files changed, 623 insertions(+), 16 deletions(-) - -diff --git a/drivers/gpu/drm/meson/meson_vclk.c b/drivers/gpu/drm/meson/meson_vclk.c -index 252cfd4..3731479 100644 ---- a/drivers/gpu/drm/meson/meson_vclk.c -+++ b/drivers/gpu/drm/meson/meson_vclk.c -@@ -27,9 +27,26 @@ - * VCLK is the "Pixel Clock" frequency generator from a dedicated PLL. - * We handle the following encodings : - * - CVBS 27MHz generator via the VCLK2 to the VENCI and VDAC blocks -- * -- * What is missing : - * - HDMI Pixel Clocks generation -+ * What is missing : -+ * - Genenate Pixel clocks for 2K/4K 10bit formats -+ * -+ * Clock generator scheme : -+ * __________ _________ _____ -+ * | | | | | |--ENCI -+ * | HDMI PLL |-| PLL_DIV |--- VCLK--| |--ENCL -+ * |__________| |_________| \ | MUX |--ENCP -+ * --VCLK2-| |--VDAC -+ * |_____|--HDMI-TX -+ * -+ * Final clocks can take input for either VCLK or VCLK2, but -+ * VCLK is the preferred path for HDMI clocking and VCLK2 is the -+ * preferred path for CVBS VDAC clocking. -+ * -+ * VCLK and VCLK2 have fixed divided clocks paths for /1, /2, /4, /6 or /12. -+ * -+ * The PLL_DIV can achieve an additional fractional dividing like -+ * 1.5, 3.5, 3.75... to generate special 2K and 4K 10bit clocks. - */ - - /* HHI Registers */ -@@ -50,11 +67,34 @@ - #define VCLK2_SOFT_RESET BIT(15) - #define VCLK2_DIV1_EN BIT(0) - #define HHI_VID_CLK_DIV 0x164 /* 0x59 offset in data sheet */ -+#define VCLK_DIV_MASK 0xff -+#define VCLK_DIV_EN BIT(16) -+#define VCLK_DIV_RESET BIT(17) -+#define CTS_ENCP_SEL_MASK (0xf << 24) -+#define CTS_ENCP_SEL_SHIFT 24 - #define CTS_ENCI_SEL_MASK (0xf << 28) - #define CTS_ENCI_SEL_SHIFT 28 -+#define HHI_VID_CLK_CNTL 0x17c /* 0x5f offset in data sheet */ -+#define VCLK_EN BIT(19) -+#define VCLK_SEL_MASK (0x7 << 16) -+#define VCLK_SEL_SHIFT 16 -+#define VCLK_SOFT_RESET BIT(15) -+#define VCLK_DIV1_EN BIT(0) -+#define VCLK_DIV2_EN BIT(1) -+#define VCLK_DIV4_EN BIT(2) -+#define VCLK_DIV6_EN BIT(3) -+#define VCLK_DIV12_EN BIT(4) - #define HHI_VID_CLK_CNTL2 0x194 /* 0x65 offset in data sheet */ - #define CTS_ENCI_EN BIT(0) -+#define CTS_ENCP_EN BIT(2) - #define CTS_VDAC_EN BIT(4) -+#define HDMI_TX_PIXEL_EN BIT(5) -+#define HHI_HDMI_CLK_CNTL 0x1cc /* 0x73 offset in data sheet */ -+#define HDMI_TX_PIXEL_SEL_MASK (0xf << 16) -+#define HDMI_TX_PIXEL_SEL_SHIFT 16 -+#define CTS_HDMI_SYS_SEL_MASK (0x7 << 9) -+#define CTS_HDMI_SYS_DIV_MASK (0x7f) -+#define CTS_HDMI_SYS_EN BIT(8) - - #define HHI_VDAC_CNTL0 0x2F4 /* 0xbd offset in data sheet */ - #define HHI_VDAC_CNTL1 0x2F8 /* 0xbe offset in data sheet */ -@@ -69,6 +109,126 @@ - #define HDMI_PLL_RESET BIT(28) - #define HDMI_PLL_LOCK BIT(31) - -+/* VID PLL Dividers */ -+enum { -+ VID_PLL_DIV_1 = 0, -+ VID_PLL_DIV_2, -+ VID_PLL_DIV_2p5, -+ VID_PLL_DIV_3, -+ VID_PLL_DIV_3p5, -+ VID_PLL_DIV_3p75, -+ VID_PLL_DIV_4, -+ VID_PLL_DIV_5, -+ VID_PLL_DIV_6, -+ VID_PLL_DIV_6p25, -+ VID_PLL_DIV_7, -+ VID_PLL_DIV_7p5, -+ VID_PLL_DIV_12, -+ VID_PLL_DIV_14, -+ VID_PLL_DIV_15, -+}; -+ -+void meson_vid_pll_set(struct meson_drm *priv, unsigned int div) -+{ -+ unsigned int shift_val = 0; -+ unsigned int shift_sel = 0; -+ -+ /* Disable vid_pll output clock */ -+ regmap_update_bits(priv->hhi, HHI_VID_PLL_CLK_DIV, VID_PLL_EN, 0); -+ regmap_update_bits(priv->hhi, HHI_VID_PLL_CLK_DIV, VID_PLL_PRESET, 0); -+ -+ switch (div) { -+ case VID_PLL_DIV_2: -+ shift_val = 0x0aaa; -+ shift_sel = 0; -+ break; -+ case VID_PLL_DIV_2p5: -+ shift_val = 0x5294; -+ shift_sel = 2; -+ break; -+ case VID_PLL_DIV_3: -+ shift_val = 0x0db6; -+ shift_sel = 0; -+ break; -+ case VID_PLL_DIV_3p5: -+ shift_val = 0x36cc; -+ shift_sel = 1; -+ break; -+ case VID_PLL_DIV_3p75: -+ shift_val = 0x6666; -+ shift_sel = 2; -+ break; -+ case VID_PLL_DIV_4: -+ shift_val = 0x0ccc; -+ shift_sel = 0; -+ break; -+ case VID_PLL_DIV_5: -+ shift_val = 0x739c; -+ shift_sel = 2; -+ break; -+ case VID_PLL_DIV_6: -+ shift_val = 0x0e38; -+ shift_sel = 0; -+ break; -+ case VID_PLL_DIV_6p25: -+ shift_val = 0x0000; -+ shift_sel = 3; -+ break; -+ case VID_PLL_DIV_7: -+ shift_val = 0x3c78; -+ shift_sel = 1; -+ break; -+ case VID_PLL_DIV_7p5: -+ shift_val = 0x78f0; -+ shift_sel = 2; -+ break; -+ case VID_PLL_DIV_12: -+ shift_val = 0x0fc0; -+ shift_sel = 0; -+ break; -+ case VID_PLL_DIV_14: -+ shift_val = 0x3f80; -+ shift_sel = 1; -+ break; -+ case VID_PLL_DIV_15: -+ shift_val = 0x7f80; -+ shift_sel = 2; -+ break; -+ } -+ -+ if (div == VID_PLL_DIV_1) -+ /* Enable vid_pll bypass to HDMI pll */ -+ regmap_update_bits(priv->hhi, HHI_VID_PLL_CLK_DIV, -+ VID_PLL_BYPASS, VID_PLL_BYPASS); -+ else { -+ /* Disable Bypass */ -+ regmap_update_bits(priv->hhi, HHI_VID_PLL_CLK_DIV, -+ VID_PLL_BYPASS, 0); -+ /* Clear sel */ -+ regmap_update_bits(priv->hhi, HHI_VID_PLL_CLK_DIV, -+ 3 << 16, 0); -+ regmap_update_bits(priv->hhi, HHI_VID_PLL_CLK_DIV, -+ VID_PLL_PRESET, 0); -+ regmap_update_bits(priv->hhi, HHI_VID_PLL_CLK_DIV, -+ 0x7fff, 0); -+ -+ /* Setup sel and val */ -+ regmap_update_bits(priv->hhi, HHI_VID_PLL_CLK_DIV, -+ 3 << 16, shift_sel << 16); -+ regmap_update_bits(priv->hhi, HHI_VID_PLL_CLK_DIV, -+ VID_PLL_PRESET, VID_PLL_PRESET); -+ regmap_update_bits(priv->hhi, HHI_VID_PLL_CLK_DIV, -+ 0x7fff, shift_val); -+ -+ regmap_update_bits(priv->hhi, HHI_VID_PLL_CLK_DIV, -+ VID_PLL_PRESET, 0); -+ } -+ -+ /* Enable the vid_pll output clock */ -+ regmap_update_bits(priv->hhi, HHI_VID_PLL_CLK_DIV, -+ VID_PLL_EN, VID_PLL_EN); -+} -+ - /* - * Setup VCLK2 for 27MHz, and enable clocks for ENCI and VDAC - * -@@ -110,15 +270,8 @@ static void meson_venci_cvbs_clock_config(struct meson_drm *priv) - /* Disable VCLK2 */ - regmap_update_bits(priv->hhi, HHI_VIID_CLK_CNTL, VCLK2_EN, 0); - -- /* Disable vid_pll output clock */ -- regmap_update_bits(priv->hhi, HHI_VID_PLL_CLK_DIV, VID_PLL_EN, 0); -- regmap_update_bits(priv->hhi, HHI_VID_PLL_CLK_DIV, VID_PLL_PRESET, 0); -- /* Enable vid_pll bypass to HDMI pll */ -- regmap_update_bits(priv->hhi, HHI_VID_PLL_CLK_DIV, -- VID_PLL_BYPASS, VID_PLL_BYPASS); -- /* Enable the vid_pll output clock */ -- regmap_update_bits(priv->hhi, HHI_VID_PLL_CLK_DIV, -- VID_PLL_EN, VID_PLL_EN); -+ /* Setup vid_pll to /1 */ -+ meson_vid_pll_set(priv, VID_PLL_DIV_1); - - /* Setup the VCLK2 divider value to achieve 27MHz */ - regmap_update_bits(priv->hhi, HHI_VIID_CLK_DIV, -@@ -159,9 +312,454 @@ static void meson_venci_cvbs_clock_config(struct meson_drm *priv) - CTS_VDAC_EN, CTS_VDAC_EN); - } - -+ -+/* PLL O1 O2 O3 VP DV EN TX */ -+/* 4320 /4 /4 /1 /5 /1 => /2 /2 */ -+#define MESON_VCLK_HDMI_ENCI_54000 1 -+/* 4320 /4 /4 /1 /5 /1 => /1 /2 */ -+#define MESON_VCLK_HDMI_DDR_54000 2 -+/* 2970 /4 /1 /1 /5 /1 => /1 /2 */ -+#define MESON_VCLK_HDMI_DDR_148500 3 -+/* 2970 /2 /2 /2 /5 /1 => /1 /1 */ -+#define MESON_VCLK_HDMI_74250 4 -+/* 2970 /1 /2 /2 /5 /1 => /1 /1 */ -+#define MESON_VCLK_HDMI_148500 5 -+/* 2970 /1 /1 /1 /5 /2 => /1 /1 */ -+#define MESON_VCLK_HDMI_297000 6 -+/* 5940 /1 /1 /2 /5 /1 => /1 /1 */ -+#define MESON_VCLK_HDMI_594000 7 -+ -+struct meson_vclk_params { -+ unsigned int pll_base_freq; -+ unsigned int pll_od1; -+ unsigned int pll_od2; -+ unsigned int pll_od3; -+ unsigned int vid_pll_div; -+ unsigned int vclk_div; -+} params[] = { -+ [MESON_VCLK_HDMI_ENCI_54000] = { -+ .pll_base_freq = 4320000, -+ .pll_od1 = 4, -+ .pll_od2 = 4, -+ .pll_od3 = 1, -+ .vid_pll_div = VID_PLL_DIV_5, -+ .vclk_div = 1, -+ }, -+ [MESON_VCLK_HDMI_DDR_54000] = { -+ .pll_base_freq = 4320000, -+ .pll_od1 = 4, -+ .pll_od2 = 4, -+ .pll_od3 = 1, -+ .vid_pll_div = VID_PLL_DIV_5, -+ .vclk_div = 1, -+ }, -+ [MESON_VCLK_HDMI_DDR_148500] = { -+ .pll_base_freq = 2970000, -+ .pll_od1 = 4, -+ .pll_od2 = 1, -+ .pll_od3 = 1, -+ .vid_pll_div = VID_PLL_DIV_5, -+ .vclk_div = 1, -+ }, -+ [MESON_VCLK_HDMI_74250] = { -+ .pll_base_freq = 2970000, -+ .pll_od1 = 2, -+ .pll_od2 = 2, -+ .pll_od3 = 2, -+ .vid_pll_div = VID_PLL_DIV_5, -+ .vclk_div = 1, -+ }, -+ [MESON_VCLK_HDMI_148500] = { -+ .pll_base_freq = 2970000, -+ .pll_od1 = 1, -+ .pll_od2 = 2, -+ .pll_od3 = 2, -+ .vid_pll_div = VID_PLL_DIV_5, -+ .vclk_div = 1, -+ }, -+ [MESON_VCLK_HDMI_297000] = { -+ .pll_base_freq = 2970000, -+ .pll_od1 = 1, -+ .pll_od2 = 1, -+ .pll_od3 = 1, -+ .vid_pll_div = VID_PLL_DIV_5, -+ .vclk_div = 2, -+ }, -+ [MESON_VCLK_HDMI_594000] = { -+ .pll_base_freq = 5940000, -+ .pll_od1 = 1, -+ .pll_od2 = 1, -+ .pll_od3 = 2, -+ .vid_pll_div = VID_PLL_DIV_5, -+ .vclk_div = 1, -+ }, -+}; -+ -+static inline unsigned int pll_od_to_reg(unsigned int od) -+{ -+ switch (od) { -+ case 1: -+ return 0; -+ case 2: -+ return 1; -+ case 4: -+ return 2; -+ case 8: -+ return 3; -+ } -+ -+ /* Invalid */ -+ return 0; -+} -+ -+void meson_hdmi_pll_set(struct meson_drm *priv, -+ unsigned int base, -+ unsigned int od1, -+ unsigned int od2, -+ unsigned int od3) -+{ -+ unsigned int val; -+ -+ if (meson_vpu_is_compatible(priv, "amlogic,meson-gxbb-vpu")) { -+ switch (base) { -+ case 2970000: -+ regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL, 0x5800023d); -+ regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL2, 0x00000000); -+ regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL3, 0x0d5c5091); -+ regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL4, 0x801da72c); -+ regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL5, 0x71486980); -+ regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL6, 0x00000e55); -+ -+ /* Enable and unreset */ -+ regmap_update_bits(priv->hhi, HHI_HDMI_PLL_CNTL, -+ 0x7 << 28, 0x4 << 28); -+ -+ /* Poll for lock bit */ -+ regmap_read_poll_timeout(priv->hhi, HHI_HDMI_PLL_CNTL, -+ val, (val & HDMI_PLL_LOCK), 10, 0); -+ -+ /* div_frac */ -+ regmap_update_bits(priv->hhi, HHI_HDMI_PLL_CNTL2, -+ 0xFFFF, 0x4e00); -+ break; -+ -+ case 4320000: -+ regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL, 0x5800025a); -+ regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL2, 0x00000000); -+ regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL3, 0x0d5c5091); -+ regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL4, 0x801da72c); -+ regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL5, 0x71486980); -+ regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL6, 0x00000e55); -+ -+ /* unreset */ -+ regmap_update_bits(priv->hhi, HHI_HDMI_PLL_CNTL, -+ BIT(28), 0); -+ -+ /* Poll for lock bit */ -+ regmap_read_poll_timeout(priv->hhi, HHI_HDMI_PLL_CNTL, -+ val, (val & HDMI_PLL_LOCK), 10, 0); -+ break; -+ -+ case 5940000: -+ regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL, 0x5800027b); -+ regmap_update_bits(priv->hhi, HHI_HDMI_PLL_CNTL2, -+ 0xFFFF, 0x4c00); -+ regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL3, 0x135c5091); -+ regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL4, 0x801da72c); -+ regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL5, 0x71486980); -+ regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL6, 0x00000e55); -+ -+ /* unreset */ -+ regmap_update_bits(priv->hhi, HHI_HDMI_PLL_CNTL, -+ BIT(28), 0); -+ -+ /* Poll for lock bit */ -+ regmap_read_poll_timeout(priv->hhi, HHI_HDMI_PLL_CNTL, -+ val, (val & HDMI_PLL_LOCK), 10, 0); -+ break; -+ }; -+ } else if (meson_vpu_is_compatible(priv, "amlogic,meson-gxm-vpu") || -+ meson_vpu_is_compatible(priv, "amlogic,meson-gxl-vpu")) { -+ switch (base) { -+ case 2970000: -+ regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL, 0x4000027b); -+ regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL2, 0x800cb300); -+ regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL3, 0x860f30c4); -+ regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL4, 0x0c8e0000); -+ regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL5, 0x001fa729); -+ regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL6, 0x01a31500); -+ break; -+ -+ case 4320000: -+ regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL, 0x400002b4); -+ regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL2, 0x800cb000); -+ regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL3, 0x860f30c4); -+ regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL4, 0x0c8e0000); -+ regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL5, 0x001fa729); -+ regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL6, 0x01a31500); -+ break; -+ -+ case 5940000: -+ regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL, 0x400002f7); -+ regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL2, 0x800cb200); -+ regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL3, 0x860f30c4); -+ regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL4, 0x0c8e0000); -+ regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL5, 0x001fa729); -+ regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL6, 0x01a31500); -+ break; -+ -+ }; -+ -+ /* Reset PLL */ -+ regmap_update_bits(priv->hhi, HHI_HDMI_PLL_CNTL, -+ HDMI_PLL_RESET, HDMI_PLL_RESET); -+ regmap_update_bits(priv->hhi, HHI_HDMI_PLL_CNTL, -+ HDMI_PLL_RESET, 0); -+ -+ /* Poll for lock bit */ -+ regmap_read_poll_timeout(priv->hhi, HHI_HDMI_PLL_CNTL, val, -+ (val & HDMI_PLL_LOCK), 10, 0); -+ }; -+ -+ if (meson_vpu_is_compatible(priv, "amlogic,meson-gxbb-vpu")) -+ regmap_update_bits(priv->hhi, HHI_HDMI_PLL_CNTL2, -+ 3 << 16, pll_od_to_reg(od1) << 16); -+ else if (meson_vpu_is_compatible(priv, "amlogic,meson-gxm-vpu") || -+ meson_vpu_is_compatible(priv, "amlogic,meson-gxl-vpu")) -+ regmap_update_bits(priv->hhi, HHI_HDMI_PLL_CNTL3, -+ 3 << 21, pll_od_to_reg(od1) << 21); -+ -+ if (meson_vpu_is_compatible(priv, "amlogic,meson-gxbb-vpu")) -+ regmap_update_bits(priv->hhi, HHI_HDMI_PLL_CNTL2, -+ 3 << 22, pll_od_to_reg(od2) << 22); -+ else if (meson_vpu_is_compatible(priv, "amlogic,meson-gxm-vpu") || -+ meson_vpu_is_compatible(priv, "amlogic,meson-gxl-vpu")) -+ regmap_update_bits(priv->hhi, HHI_HDMI_PLL_CNTL3, -+ 3 << 23, pll_od_to_reg(od2) << 23); -+ -+ if (meson_vpu_is_compatible(priv, "amlogic,meson-gxbb-vpu")) -+ regmap_update_bits(priv->hhi, HHI_HDMI_PLL_CNTL2, -+ 3 << 18, pll_od_to_reg(od3) << 18); -+ else if (meson_vpu_is_compatible(priv, "amlogic,meson-gxm-vpu") || -+ meson_vpu_is_compatible(priv, "amlogic,meson-gxl-vpu")) -+ regmap_update_bits(priv->hhi, HHI_HDMI_PLL_CNTL3, -+ 3 << 19, pll_od_to_reg(od3) << 19); -+} -+ - void meson_vclk_setup(struct meson_drm *priv, unsigned int target, -- unsigned int freq) -+ unsigned int vclk_freq, unsigned int venc_freq, -+ unsigned int dac_freq, bool hdmi_use_enci) - { -- if (target == MESON_VCLK_TARGET_CVBS && freq == MESON_VCLK_CVBS) -+ unsigned int freq; -+ unsigned int hdmi_tx_div; -+ unsigned int venc_div; -+ -+ if (target == MESON_VCLK_TARGET_CVBS) { - meson_venci_cvbs_clock_config(priv); -+ return; -+ } -+ -+ hdmi_tx_div = vclk_freq / dac_freq; -+ -+ if (hdmi_tx_div == 0) { -+ pr_err("Fatal Error, invalid HDMI-TX freq %d\n", -+ dac_freq); -+ return; -+ } -+ -+ venc_div = vclk_freq / venc_freq; -+ -+ if (venc_div == 0) { -+ pr_err("Fatal Error, invalid HDMI venc freq %d\n", -+ venc_freq); -+ return; -+ } -+ -+ switch (vclk_freq) { -+ case 54000: -+ if (hdmi_use_enci) -+ freq = MESON_VCLK_HDMI_ENCI_54000; -+ else -+ freq = MESON_VCLK_HDMI_DDR_54000; -+ break; -+ case 74250: -+ freq = MESON_VCLK_HDMI_74250; -+ break; -+ case 148500: -+ if (dac_freq != 148500) -+ freq = MESON_VCLK_HDMI_DDR_148500; -+ else -+ freq = MESON_VCLK_HDMI_148500; -+ break; -+ case 297000: -+ freq = MESON_VCLK_HDMI_297000; -+ break; -+ case 594000: -+ freq = MESON_VCLK_HDMI_594000; -+ break; -+ default: -+ pr_err("Fatal Error, invalid HDMI vclk freq %d\n", -+ vclk_freq); -+ return; -+ } -+ -+ /* Set HDMI-TX sys clock */ -+ regmap_update_bits(priv->hhi, HHI_HDMI_CLK_CNTL, -+ CTS_HDMI_SYS_SEL_MASK, 0); -+ regmap_update_bits(priv->hhi, HHI_HDMI_CLK_CNTL, -+ CTS_HDMI_SYS_DIV_MASK, 0); -+ regmap_update_bits(priv->hhi, HHI_HDMI_CLK_CNTL, -+ CTS_HDMI_SYS_EN, CTS_HDMI_SYS_EN); -+ -+ /* Set HDMI PLL rate */ -+ meson_hdmi_pll_set(priv, params[freq].pll_base_freq, -+ params[freq].pll_od1, -+ params[freq].pll_od2, -+ params[freq].pll_od3); -+ -+ /* Setup vid_pll divider */ -+ meson_vid_pll_set(priv, params[freq].vid_pll_div); -+ -+ /* Set VCLK div */ -+ regmap_update_bits(priv->hhi, HHI_VID_CLK_CNTL, -+ VCLK_SEL_MASK, 0); -+ regmap_update_bits(priv->hhi, HHI_VID_CLK_DIV, -+ VCLK_DIV_MASK, params[freq].vclk_div - 1); -+ -+ /* Set HDMI-TX source */ -+ switch (hdmi_tx_div) { -+ case 1: -+ /* enable vclk_div1 gate */ -+ regmap_update_bits(priv->hhi, HHI_VID_CLK_CNTL, -+ VCLK_DIV1_EN, VCLK_DIV1_EN); -+ -+ /* select vclk_div1 for HDMI-TX */ -+ regmap_update_bits(priv->hhi, HHI_HDMI_CLK_CNTL, -+ HDMI_TX_PIXEL_SEL_MASK, 0); -+ break; -+ case 2: -+ /* enable vclk_div2 gate */ -+ regmap_update_bits(priv->hhi, HHI_VID_CLK_CNTL, -+ VCLK_DIV2_EN, VCLK_DIV2_EN); -+ -+ /* select vclk_div2 for HDMI-TX */ -+ regmap_update_bits(priv->hhi, HHI_HDMI_CLK_CNTL, -+ HDMI_TX_PIXEL_SEL_MASK, 1 << HDMI_TX_PIXEL_SEL_SHIFT); -+ break; -+ case 4: -+ /* enable vclk_div4 gate */ -+ regmap_update_bits(priv->hhi, HHI_VID_CLK_CNTL, -+ VCLK_DIV4_EN, VCLK_DIV4_EN); -+ -+ /* select vclk_div4 for HDMI-TX */ -+ regmap_update_bits(priv->hhi, HHI_HDMI_CLK_CNTL, -+ HDMI_TX_PIXEL_SEL_MASK, 2 << HDMI_TX_PIXEL_SEL_SHIFT); -+ break; -+ case 6: -+ /* enable vclk_div6 gate */ -+ regmap_update_bits(priv->hhi, HHI_VID_CLK_CNTL, -+ VCLK_DIV6_EN, VCLK_DIV6_EN); -+ -+ /* select vclk_div6 for HDMI-TX */ -+ regmap_update_bits(priv->hhi, HHI_HDMI_CLK_CNTL, -+ HDMI_TX_PIXEL_SEL_MASK, 3 << HDMI_TX_PIXEL_SEL_SHIFT); -+ break; -+ case 12: -+ /* enable vclk_div12 gate */ -+ regmap_update_bits(priv->hhi, HHI_VID_CLK_CNTL, -+ VCLK_DIV12_EN, VCLK_DIV12_EN); -+ -+ /* select vclk_div12 for HDMI-TX */ -+ regmap_update_bits(priv->hhi, HHI_HDMI_CLK_CNTL, -+ HDMI_TX_PIXEL_SEL_MASK, 4 << HDMI_TX_PIXEL_SEL_SHIFT); -+ break; -+ } -+ regmap_update_bits(priv->hhi, HHI_VID_CLK_CNTL2, -+ HDMI_TX_PIXEL_EN, HDMI_TX_PIXEL_EN); -+ -+ /* Set ENCI/ENCP Source */ -+ switch (venc_div) { -+ case 1: -+ /* enable vclk_div1 gate */ -+ regmap_update_bits(priv->hhi, HHI_VID_CLK_CNTL, -+ VCLK_DIV1_EN, VCLK_DIV1_EN); -+ -+ if (hdmi_use_enci) -+ /* select vclk_div1 for enci */ -+ regmap_update_bits(priv->hhi, HHI_VID_CLK_DIV, -+ CTS_ENCI_SEL_MASK, 0); -+ else -+ /* select vclk_div1 for encp */ -+ regmap_update_bits(priv->hhi, HHI_VID_CLK_DIV, -+ CTS_ENCP_SEL_MASK, 0); -+ break; -+ case 2: -+ /* enable vclk_div2 gate */ -+ regmap_update_bits(priv->hhi, HHI_VID_CLK_CNTL, -+ VCLK_DIV2_EN, VCLK_DIV2_EN); -+ -+ if (hdmi_use_enci) -+ /* select vclk_div2 for enci */ -+ regmap_update_bits(priv->hhi, HHI_VID_CLK_DIV, -+ CTS_ENCI_SEL_MASK, 1 << CTS_ENCI_SEL_SHIFT); -+ else -+ /* select vclk_div2 for encp */ -+ regmap_update_bits(priv->hhi, HHI_VID_CLK_DIV, -+ CTS_ENCP_SEL_MASK, 1 << CTS_ENCP_SEL_SHIFT); -+ break; -+ case 4: -+ /* enable vclk_div4 gate */ -+ regmap_update_bits(priv->hhi, HHI_VID_CLK_CNTL, -+ VCLK_DIV4_EN, VCLK_DIV4_EN); -+ -+ if (hdmi_use_enci) -+ /* select vclk_div4 for enci */ -+ regmap_update_bits(priv->hhi, HHI_VID_CLK_DIV, -+ CTS_ENCI_SEL_MASK, 2 << CTS_ENCI_SEL_SHIFT); -+ else -+ /* select vclk_div4 for encp */ -+ regmap_update_bits(priv->hhi, HHI_VID_CLK_DIV, -+ CTS_ENCP_SEL_MASK, 2 << CTS_ENCP_SEL_SHIFT); -+ break; -+ case 6: -+ /* enable vclk_div6 gate */ -+ regmap_update_bits(priv->hhi, HHI_VID_CLK_CNTL, -+ VCLK_DIV6_EN, VCLK_DIV6_EN); -+ -+ if (hdmi_use_enci) -+ /* select vclk_div6 for enci */ -+ regmap_update_bits(priv->hhi, HHI_VID_CLK_DIV, -+ CTS_ENCI_SEL_MASK, 3 << CTS_ENCI_SEL_SHIFT); -+ else -+ /* select vclk_div6 for encp */ -+ regmap_update_bits(priv->hhi, HHI_VID_CLK_DIV, -+ CTS_ENCP_SEL_MASK, 3 << CTS_ENCP_SEL_SHIFT); -+ break; -+ case 12: -+ /* enable vclk_div12 gate */ -+ regmap_update_bits(priv->hhi, HHI_VID_CLK_CNTL, -+ VCLK_DIV12_EN, VCLK_DIV12_EN); -+ -+ if (hdmi_use_enci) -+ /* select vclk_div12 for enci */ -+ regmap_update_bits(priv->hhi, HHI_VID_CLK_DIV, -+ CTS_ENCI_SEL_MASK, 4 << CTS_ENCI_SEL_SHIFT); -+ else -+ /* select vclk_div12 for encp */ -+ regmap_update_bits(priv->hhi, HHI_VID_CLK_DIV, -+ CTS_ENCP_SEL_MASK, 4 << CTS_ENCP_SEL_SHIFT); -+ break; -+ } -+ -+ if (hdmi_use_enci) -+ /* Enable ENCI clock gate */ -+ regmap_update_bits(priv->hhi, HHI_VID_CLK_CNTL2, -+ CTS_ENCI_EN, CTS_ENCI_EN); -+ else -+ /* Enable ENCP clock gate */ -+ regmap_update_bits(priv->hhi, HHI_VID_CLK_CNTL2, -+ CTS_ENCP_EN, CTS_ENCP_EN); -+ -+ regmap_update_bits(priv->hhi, HHI_VID_CLK_CNTL, VCLK_EN, VCLK_EN); - } -+EXPORT_SYMBOL_GPL(meson_vclk_setup); -diff --git a/drivers/gpu/drm/meson/meson_vclk.h b/drivers/gpu/drm/meson/meson_vclk.h -index ec62735..0401b52 100644 ---- a/drivers/gpu/drm/meson/meson_vclk.h -+++ b/drivers/gpu/drm/meson/meson_vclk.h -@@ -23,12 +23,14 @@ - - enum { - MESON_VCLK_TARGET_CVBS = 0, -+ MESON_VCLK_TARGET_HDMI = 1, - }; - - /* 27MHz is the CVBS Pixel Clock */ --#define MESON_VCLK_CVBS 27000 -+#define MESON_VCLK_CVBS 27000 - - void meson_vclk_setup(struct meson_drm *priv, unsigned int target, -- unsigned int freq); -+ unsigned int vclk_freq, unsigned int venc_freq, -+ unsigned int dac_freq, bool hdmi_use_enci); - - #endif /* __MESON_VCLK_H */ -diff --git a/drivers/gpu/drm/meson/meson_venc_cvbs.c b/drivers/gpu/drm/meson/meson_venc_cvbs.c -index a96fcb4..5d4f19a 100644 ---- a/drivers/gpu/drm/meson/meson_venc_cvbs.c -+++ b/drivers/gpu/drm/meson/meson_venc_cvbs.c -@@ -32,6 +32,7 @@ - - #include "meson_venc_cvbs.h" - #include "meson_venc.h" -+#include "meson_vclk.h" - #include "meson_registers.h" - - /* HHI VDAC Registers */ -@@ -194,14 +195,20 @@ static void meson_venc_cvbs_encoder_mode_set(struct drm_encoder *encoder, - { - struct meson_venc_cvbs *meson_venc_cvbs = - encoder_to_meson_venc_cvbs(encoder); -+ struct meson_drm *priv = meson_venc_cvbs->priv; - int i; - - for (i = 0; i < MESON_CVBS_MODES_COUNT; ++i) { - struct meson_cvbs_mode *meson_mode = &meson_cvbs_modes[i]; - - if (drm_mode_equal(mode, &meson_mode->mode)) { -- meson_venci_cvbs_mode_set(meson_venc_cvbs->priv, -+ meson_venci_cvbs_mode_set(priv, - meson_mode->enci); -+ -+ /* Setup 27MHz vclk2 for ENCI and VDAC */ -+ meson_vclk_setup(priv, MESON_VCLK_TARGET_CVBS, -+ MESON_VCLK_CVBS, MESON_VCLK_CVBS, -+ MESON_VCLK_CVBS, true); - break; - } - } --- -1.9.1 - diff --git a/patch/kernel/odroidc2-next/0053-clk-cosmetic-changes-to-clk_summary-debugfs-entry.patch b/patch/kernel/odroidc2-next/0053-clk-cosmetic-changes-to-clk_summary-debugfs-entry.patch new file mode 100644 index 000000000..7a7e6f564 --- /dev/null +++ b/patch/kernel/odroidc2-next/0053-clk-cosmetic-changes-to-clk_summary-debugfs-entry.patch @@ -0,0 +1,43 @@ +From 29c6ab33e59640b8e09619be779091efc5953dc5 Mon Sep 17 00:00:00 2001 +From: Jerome Brunet +Date: Tue, 21 Mar 2017 19:24:35 +0100 +Subject: [PATCH 53/79] clk: cosmetic changes to clk_summary debugfs entry + +clk_summary debugfs entry was already well over the traditional 80 +characters per line limit but it grew even larger with the addition of +clock protection. + +Signed-off-by: Jerome Brunet +Signed-off-by: Neil Armstrong +--- + drivers/clk/clk.c | 7 ++++--- + 1 file changed, 4 insertions(+), 3 deletions(-) + +diff --git a/drivers/clk/clk.c b/drivers/clk/clk.c +index 253f1d3..8d57e13 100644 +--- a/drivers/clk/clk.c ++++ b/drivers/clk/clk.c +@@ -2262,7 +2262,7 @@ static void clk_summary_show_one(struct seq_file *s, struct clk_core *c, + if (!c) + return; + +- seq_printf(s, "%*s%-*s %11d %12d %12d %11lu %10lu %-3d\n", ++ seq_printf(s, "%*s%-*s %7d %8d %8d %11lu %10lu %-3d\n", + level * 3 + 1, "", + 30 - level * 3, c->name, + c->enable_count, c->prepare_count, c->protect_count, +@@ -2289,8 +2289,9 @@ static int clk_summary_show(struct seq_file *s, void *data) + struct clk_core *c; + struct hlist_head **lists = (struct hlist_head **)s->private; + +- seq_puts(s, " clock enable_cnt prepare_cnt protect_cnt rate accuracy phase\n"); +- seq_puts(s, "----------------------------------------------------------------------------------------------------\n"); ++ seq_puts(s, " enable prepare protect \n"); ++ seq_puts(s, " clock count count count rate accuracy phase\n"); ++ seq_puts(s, "----------------------------------------------------------------------------------------\n"); + + clk_prepare_lock(); + +-- +1.9.1 + diff --git a/patch/kernel/odroidc2-next/0053-drm-meson-Add-support-for-HDMI-venc-modes-and-settin.patch b/patch/kernel/odroidc2-next/0053-drm-meson-Add-support-for-HDMI-venc-modes-and-settin.patch deleted file mode 100644 index 96928072b..000000000 --- a/patch/kernel/odroidc2-next/0053-drm-meson-Add-support-for-HDMI-venc-modes-and-settin.patch +++ /dev/null @@ -1,1334 +0,0 @@ -From 15ecbffe7a32a2668c3ea87e785e9e34b06911eb Mon Sep 17 00:00:00 2001 -From: Neil Armstrong -Date: Mon, 9 Jan 2017 14:19:54 +0100 -Subject: [PATCH 53/93] drm/meson: Add support for HDMI venc modes and settings - -This patch adds support for the supported HDMI Venc modes and add the VPP mux -value to switch to ENCP encoder. ---- - drivers/gpu/drm/meson/meson_venc.c | 1245 +++++++++++++++++++++++++++++++++++- - drivers/gpu/drm/meson/meson_venc.h | 7 + - drivers/gpu/drm/meson/meson_vpp.h | 2 + - 3 files changed, 1249 insertions(+), 5 deletions(-) - -diff --git a/drivers/gpu/drm/meson/meson_venc.c b/drivers/gpu/drm/meson/meson_venc.c -index f7c87017..31dc275 100644 ---- a/drivers/gpu/drm/meson/meson_venc.c -+++ b/drivers/gpu/drm/meson/meson_venc.c -@@ -30,12 +30,37 @@ - * VENC Handle the pixels encoding to the output formats. - * We handle the following encodings : - * - CVBS Encoding via the ENCI encoder and VDAC digital to analog converter -- * -- * What is missing : - * - TMDS/HDMI Encoding via ENCI_DIV and ENCP - * - Setup of more clock rates for HDMI modes -+ * -+ * What is missing : - * - LCD Panel encoding via ENCL - * - TV Panel encoding via ENCT -+ * -+ * VENC paths : -+ * _____ _____ ____________________ -+ * vd1---| |-| | | VENC /---------|----VDAC -+ * vd2---| VIU |-| VPP |-|-----ENCI/-ENCI_DVI-|\ -+ * osd1--| |-| | | \ | X--HDMI-TX -+ * osd2--|_____|-|_____| | |\-ENCP--ENCP_DVI-|/ -+ * | | | -+ * | \--ENCL-----------|----LVDS -+ * |____________________| -+ * -+ * The ENCI is designed for PAl or NTSC encoding and can go through the VDAC -+ * directly for CVBS encoding or through the ENCI_DVI encoder for HDMI. -+ * The ENCP is designed for Progressive encoding but can also generate -+ * 1080i interlaced pixels, and was initialy desined to encode pixels for -+ * VDAC to output RGB ou YUV analog outputs. -+ * It's output is only used through the ENCP_DVI encoder for HDMI. -+ * The ENCL LVDS encoder is not implemented. -+ * -+ * The ENCI and ENCP encoders needs specially defined parameters for each -+ * supported mode and thus cannot be determined from standard video timings. -+ * -+ * The ENCI end ENCP DVI encoders are more generic and can generate any timings -+ * from the pixel data generated by ENCI or ENCP, so can use the standard video -+ * timings are source for HW parameters. - */ - - /* HHI Registers */ -@@ -91,6 +116,1219 @@ struct meson_cvbs_enci_mode meson_cvbs_enci_ntsc = { - .analog_sync_adj = 0x9c00, - }; - -+union meson_hdmi_venc_mode { -+ struct { -+ unsigned int mode_tag; -+ unsigned int hso_begin; -+ unsigned int hso_end; -+ unsigned int vso_even; -+ unsigned int vso_odd; -+ unsigned int macv_max_amp; -+ unsigned int video_prog_mode; -+ unsigned int video_mode; -+ unsigned int sch_adjust; -+ unsigned int yc_delay; -+ unsigned int pixel_start; -+ unsigned int pixel_end; -+ unsigned int top_field_line_start; -+ unsigned int top_field_line_end; -+ unsigned int bottom_field_line_start; -+ unsigned int bottom_field_line_end; -+ } enci; -+ struct { -+ unsigned int dvi_settings; -+ unsigned int video_mode; -+ unsigned int video_mode_adv; -+ unsigned int video_prog_mode; -+ bool video_prog_mode_present; -+ unsigned int video_sync_mode; -+ bool video_sync_mode_present; -+ unsigned int video_yc_dly; -+ bool video_yc_dly_present; -+ unsigned int video_rgb_ctrl; -+ bool video_rgb_ctrl_present; -+ unsigned int video_filt_ctrl; -+ bool video_filt_ctrl_present; -+ unsigned int video_ofld_voav_ofst; -+ bool video_ofld_voav_ofst_present; -+ unsigned int yfp1_htime; -+ unsigned int yfp2_htime; -+ unsigned int max_pxcnt; -+ unsigned int hspuls_begin; -+ unsigned int hspuls_end; -+ unsigned int hspuls_switch; -+ unsigned int vspuls_begin; -+ unsigned int vspuls_end; -+ unsigned int vspuls_bline; -+ unsigned int vspuls_eline; -+ unsigned int eqpuls_begin; -+ bool eqpuls_begin_present; -+ unsigned int eqpuls_end; -+ bool eqpuls_end_present; -+ unsigned int eqpuls_bline; -+ bool eqpuls_bline_present; -+ unsigned int eqpuls_eline; -+ bool eqpuls_eline_present; -+ unsigned int havon_begin; -+ unsigned int havon_end; -+ unsigned int vavon_bline; -+ unsigned int vavon_eline; -+ unsigned int hso_begin; -+ unsigned int hso_end; -+ unsigned int vso_begin; -+ unsigned int vso_end; -+ unsigned int vso_bline; -+ unsigned int vso_eline; -+ bool vso_eline_present; -+ unsigned int sy_val; -+ bool sy_val_present; -+ unsigned int sy2_val; -+ bool sy2_val_present; -+ unsigned int max_lncnt; -+ } encp; -+}; -+ -+union meson_hdmi_venc_mode meson_hdmi_enci_mode_480i = { -+ .enci = { -+ .hso_begin = 5, -+ .hso_end = 129, -+ .vso_even = 3, -+ .vso_odd = 260, -+ .macv_max_amp = 0x810b, -+ .video_prog_mode = 0xf0, -+ .video_mode = 0x8, -+ .sch_adjust = 0x20, -+ .yc_delay = 0, -+ .pixel_start = 227, -+ .pixel_end = 1667, -+ .top_field_line_start = 18, -+ .top_field_line_end = 258, -+ .bottom_field_line_start = 19, -+ .bottom_field_line_end = 259, -+ }, -+}; -+ -+union meson_hdmi_venc_mode meson_hdmi_enci_mode_576i = { -+ .enci = { -+ .hso_begin = 3, -+ .hso_end = 129, -+ .vso_even = 3, -+ .vso_odd = 260, -+ .macv_max_amp = 8107, -+ .video_prog_mode = 0xff, -+ .video_mode = 0x13, -+ .sch_adjust = 0x28, -+ .yc_delay = 0x333, -+ .pixel_start = 251, -+ .pixel_end = 1691, -+ .top_field_line_start = 22, -+ .top_field_line_end = 310, -+ .bottom_field_line_start = 23, -+ .bottom_field_line_end = 311, -+ }, -+}; -+ -+union meson_hdmi_venc_mode meson_hdmi_encp_mode_480p = { -+ .encp = { -+ .dvi_settings = 0x21, -+ .video_mode = 0x4000, -+ .video_mode_adv = 0x9, -+ .video_prog_mode = 0, -+ .video_prog_mode_present = true, -+ .video_sync_mode = 7, -+ .video_sync_mode_present = true, -+ /* video_yc_dly */ -+ /* video_rgb_ctrl */ -+ .video_filt_ctrl = 0x2052, -+ .video_filt_ctrl_present = true, -+ /* video_ofld_voav_ofst */ -+ .yfp1_htime = 244, -+ .yfp2_htime = 1630, -+ .max_pxcnt = 1715, -+ .hspuls_begin = 0x22, -+ .hspuls_end = 0xa0, -+ .hspuls_switch = 88, -+ .vspuls_begin = 0, -+ .vspuls_end = 1589, -+ .vspuls_bline = 0, -+ .vspuls_eline = 5, -+ .havon_begin = 249, -+ .havon_end = 1689, -+ .vavon_bline = 42, -+ .vavon_eline = 521, -+ /* eqpuls_begin */ -+ /* eqpuls_end */ -+ /* eqpuls_bline */ -+ /* eqpuls_eline */ -+ .hso_begin = 3, -+ .hso_end = 5, -+ .vso_begin = 3, -+ .vso_end = 5, -+ .vso_bline = 0, -+ /* vso_eline */ -+ .sy_val = 8, -+ .sy_val_present = true, -+ .sy2_val = 0x1d8, -+ .sy2_val_present = true, -+ .max_lncnt = 524, -+ }, -+}; -+ -+union meson_hdmi_venc_mode meson_hdmi_encp_mode_576p = { -+ .encp = { -+ .dvi_settings = 0x21, -+ .video_mode = 0x4000, -+ .video_mode_adv = 0x9, -+ .video_prog_mode = 0, -+ .video_prog_mode_present = true, -+ .video_sync_mode = 7, -+ .video_sync_mode_present = true, -+ /* video_yc_dly */ -+ /* video_rgb_ctrl */ -+ .video_filt_ctrl = 0x52, -+ .video_filt_ctrl_present = true, -+ /* video_ofld_voav_ofst */ -+ .yfp1_htime = 235, -+ .yfp2_htime = 1674, -+ .max_pxcnt = 1727, -+ .hspuls_begin = 0, -+ .hspuls_end = 0x80, -+ .hspuls_switch = 88, -+ .vspuls_begin = 0, -+ .vspuls_end = 1599, -+ .vspuls_bline = 0, -+ .vspuls_eline = 4, -+ .havon_begin = 235, -+ .havon_end = 1674, -+ .vavon_bline = 44, -+ .vavon_eline = 619, -+ /* eqpuls_begin */ -+ /* eqpuls_end */ -+ /* eqpuls_bline */ -+ /* eqpuls_eline */ -+ .hso_begin = 0x80, -+ .hso_end = 0, -+ .vso_begin = 0, -+ .vso_end = 5, -+ .vso_bline = 0, -+ /* vso_eline */ -+ .sy_val = 8, -+ .sy_val_present = true, -+ .sy2_val = 0x1d8, -+ .sy2_val_present = true, -+ .max_lncnt = 624, -+ }, -+}; -+ -+union meson_hdmi_venc_mode meson_hdmi_encp_mode_720p60 = { -+ .encp = { -+ .dvi_settings = 0x2029, -+ .video_mode = 0x4040, -+ .video_mode_adv = 0x19, -+ /* video_prog_mode */ -+ /* video_sync_mode */ -+ /* video_yc_dly */ -+ /* video_rgb_ctrl */ -+ /* video_filt_ctrl */ -+ /* video_ofld_voav_ofst */ -+ .yfp1_htime = 648, -+ .yfp2_htime = 3207, -+ .max_pxcnt = 3299, -+ .hspuls_begin = 80, -+ .hspuls_end = 240, -+ .hspuls_switch = 80, -+ .vspuls_begin = 688, -+ .vspuls_end = 3248, -+ .vspuls_bline = 4, -+ .vspuls_eline = 8, -+ .havon_begin = 648, -+ .havon_end = 3207, -+ .vavon_bline = 29, -+ .vavon_eline = 748, -+ /* eqpuls_begin */ -+ /* eqpuls_end */ -+ /* eqpuls_bline */ -+ /* eqpuls_eline */ -+ .hso_begin = 256, -+ .hso_end = 168, -+ .vso_begin = 168, -+ .vso_end = 256, -+ .vso_bline = 0, -+ .vso_eline = 5, -+ .vso_eline_present = true, -+ /* sy_val */ -+ /* sy2_val */ -+ .max_lncnt = 749, -+ }, -+}; -+ -+union meson_hdmi_venc_mode meson_hdmi_encp_mode_720p50 = { -+ .encp = { -+ .dvi_settings = 0x202d, -+ .video_mode = 0x4040, -+ .video_mode_adv = 0x19, -+ .video_prog_mode = 0x100, -+ .video_prog_mode_present = true, -+ .video_sync_mode = 0x407, -+ .video_sync_mode_present = true, -+ .video_yc_dly = 0, -+ .video_yc_dly_present = true, -+ /* video_rgb_ctrl */ -+ /* video_filt_ctrl */ -+ /* video_ofld_voav_ofst */ -+ .yfp1_htime = 648, -+ .yfp2_htime = 3207, -+ .max_pxcnt = 3959, -+ .hspuls_begin = 80, -+ .hspuls_end = 240, -+ .hspuls_switch = 80, -+ .vspuls_begin = 688, -+ .vspuls_end = 3248, -+ .vspuls_bline = 4, -+ .vspuls_eline = 8, -+ .havon_begin = 648, -+ .havon_end = 3207, -+ .vavon_bline = 29, -+ .vavon_eline = 748, -+ /* eqpuls_begin */ -+ /* eqpuls_end */ -+ /* eqpuls_bline */ -+ /* eqpuls_eline */ -+ .hso_begin = 128, -+ .hso_end = 208, -+ .vso_begin = 128, -+ .vso_end = 128, -+ .vso_bline = 0, -+ .vso_eline = 5, -+ .vso_eline_present = true, -+ /* sy_val */ -+ /* sy2_val */ -+ .max_lncnt = 749, -+ }, -+}; -+ -+union meson_hdmi_venc_mode meson_hdmi_encp_mode_1080i60 = { -+ .encp = { -+ .dvi_settings = 0x2029, -+ .video_mode = 0x5ffc, -+ .video_mode_adv = 0x19, -+ .video_prog_mode = 0x100, -+ .video_prog_mode_present = true, -+ .video_sync_mode = 0x207, -+ .video_sync_mode_present = true, -+ /* video_yc_dly */ -+ /* video_rgb_ctrl */ -+ /* video_filt_ctrl */ -+ .video_ofld_voav_ofst = 0x11, -+ .video_ofld_voav_ofst_present = true, -+ .yfp1_htime = 516, -+ .yfp2_htime = 4355, -+ .max_pxcnt = 4399, -+ .hspuls_begin = 88, -+ .hspuls_end = 264, -+ .hspuls_switch = 88, -+ .vspuls_begin = 440, -+ .vspuls_end = 2200, -+ .vspuls_bline = 0, -+ .vspuls_eline = 4, -+ .havon_begin = 516, -+ .havon_end = 4355, -+ .vavon_bline = 20, -+ .vavon_eline = 559, -+ .eqpuls_begin = 2288, -+ .eqpuls_begin_present = true, -+ .eqpuls_end = 2464, -+ .eqpuls_end_present = true, -+ .eqpuls_bline = 0, -+ .eqpuls_bline_present = true, -+ .eqpuls_eline = 4, -+ .eqpuls_eline_present = true, -+ .hso_begin = 264, -+ .hso_end = 176, -+ .vso_begin = 88, -+ .vso_end = 88, -+ .vso_bline = 0, -+ .vso_eline = 5, -+ .vso_eline_present = true, -+ /* sy_val */ -+ /* sy2_val */ -+ .max_lncnt = 1124, -+ }, -+}; -+ -+union meson_hdmi_venc_mode meson_hdmi_encp_mode_1080i50 = { -+ .encp = { -+ .dvi_settings = 0x202d, -+ .video_mode = 0x5ffc, -+ .video_mode_adv = 0x19, -+ .video_prog_mode = 0x100, -+ .video_prog_mode_present = true, -+ .video_sync_mode = 0x7, -+ .video_sync_mode_present = true, -+ /* video_yc_dly */ -+ /* video_rgb_ctrl */ -+ /* video_filt_ctrl */ -+ .video_ofld_voav_ofst = 0x11, -+ .video_ofld_voav_ofst_present = true, -+ .yfp1_htime = 526, -+ .yfp2_htime = 4365, -+ .max_pxcnt = 5279, -+ .hspuls_begin = 88, -+ .hspuls_end = 264, -+ .hspuls_switch = 88, -+ .vspuls_begin = 440, -+ .vspuls_end = 2200, -+ .vspuls_bline = 0, -+ .vspuls_eline = 4, -+ .havon_begin = 526, -+ .havon_end = 4365, -+ .vavon_bline = 20, -+ .vavon_eline = 559, -+ .eqpuls_begin = 2288, -+ .eqpuls_begin_present = true, -+ .eqpuls_end = 2464, -+ .eqpuls_end_present = true, -+ .eqpuls_bline = 0, -+ .eqpuls_bline_present = true, -+ .eqpuls_eline = 4, -+ .eqpuls_eline_present = true, -+ .hso_begin = 142, -+ .hso_end = 230, -+ .vso_begin = 142, -+ .vso_end = 142, -+ .vso_bline = 0, -+ .vso_eline = 5, -+ .vso_eline_present = true, -+ /* sy_val */ -+ /* sy2_val */ -+ .max_lncnt = 1124, -+ }, -+}; -+ -+union meson_hdmi_venc_mode meson_hdmi_encp_mode_1080p24 = { -+ .encp = { -+ .dvi_settings = 0xd, -+ .video_mode = 0x4040, -+ .video_mode_adv = 0x18, -+ .video_prog_mode = 0x100, -+ .video_prog_mode_present = true, -+ .video_sync_mode = 0x7, -+ .video_sync_mode_present = true, -+ .video_yc_dly = 0, -+ .video_yc_dly_present = true, -+ .video_rgb_ctrl = 2, -+ .video_rgb_ctrl_present = true, -+ .video_filt_ctrl = 0x1052, -+ .video_filt_ctrl_present = true, -+ /* video_ofld_voav_ofst */ -+ .yfp1_htime = 271, -+ .yfp2_htime = 2190, -+ .max_pxcnt = 2749, -+ .hspuls_begin = 44, -+ .hspuls_end = 132, -+ .hspuls_switch = 44, -+ .vspuls_begin = 220, -+ .vspuls_end = 2140, -+ .vspuls_bline = 0, -+ .vspuls_eline = 4, -+ .havon_begin = 271, -+ .havon_end = 2190, -+ .vavon_bline = 41, -+ .vavon_eline = 1120, -+ /* eqpuls_begin */ -+ /* eqpuls_end */ -+ .eqpuls_bline = 0, -+ .eqpuls_bline_present = true, -+ .eqpuls_eline = 4, -+ .eqpuls_eline_present = true, -+ .hso_begin = 79, -+ .hso_end = 123, -+ .vso_begin = 79, -+ .vso_end = 79, -+ .vso_bline = 0, -+ .vso_eline = 5, -+ .vso_eline_present = true, -+ /* sy_val */ -+ /* sy2_val */ -+ .max_lncnt = 1124, -+ }, -+}; -+ -+union meson_hdmi_venc_mode meson_hdmi_encp_mode_1080p30 = { -+ .encp = { -+ .dvi_settings = 0x1, -+ .video_mode = 0x4040, -+ .video_mode_adv = 0x18, -+ .video_prog_mode = 0x100, -+ .video_prog_mode_present = true, -+ /* video_sync_mode */ -+ /* video_yc_dly */ -+ /* video_rgb_ctrl */ -+ .video_filt_ctrl = 0x1052, -+ .video_filt_ctrl_present = true, -+ /* video_ofld_voav_ofst */ -+ .yfp1_htime = 140, -+ .yfp2_htime = 2060, -+ .max_pxcnt = 2199, -+ .hspuls_begin = 2156, -+ .hspuls_end = 44, -+ .hspuls_switch = 44, -+ .vspuls_begin = 140, -+ .vspuls_end = 2059, -+ .vspuls_bline = 0, -+ .vspuls_eline = 4, -+ .havon_begin = 148, -+ .havon_end = 2067, -+ .vavon_bline = 41, -+ .vavon_eline = 1120, -+ /* eqpuls_begin */ -+ /* eqpuls_end */ -+ /* eqpuls_bline */ -+ /* eqpuls_eline */ -+ .hso_begin = 44, -+ .hso_end = 2156, -+ .vso_begin = 2100, -+ .vso_end = 2164, -+ .vso_bline = 0, -+ .vso_eline = 5, -+ .vso_eline_present = true, -+ /* sy_val */ -+ /* sy2_val */ -+ .max_lncnt = 1124, -+ }, -+}; -+ -+union meson_hdmi_venc_mode meson_hdmi_encp_mode_1080p50 = { -+ .encp = { -+ .dvi_settings = 0xd, -+ .video_mode = 0x4040, -+ .video_mode_adv = 0x18, -+ .video_prog_mode = 0x100, -+ .video_prog_mode_present = true, -+ .video_sync_mode = 0x7, -+ .video_sync_mode_present = true, -+ .video_yc_dly = 0, -+ .video_yc_dly_present = true, -+ .video_rgb_ctrl = 2, -+ .video_rgb_ctrl_present = true, -+ /* video_filt_ctrl */ -+ /* video_ofld_voav_ofst */ -+ .yfp1_htime = 271, -+ .yfp2_htime = 2190, -+ .max_pxcnt = 2639, -+ .hspuls_begin = 44, -+ .hspuls_end = 132, -+ .hspuls_switch = 44, -+ .vspuls_begin = 220, -+ .vspuls_end = 2140, -+ .vspuls_bline = 0, -+ .vspuls_eline = 4, -+ .havon_begin = 271, -+ .havon_end = 2190, -+ .vavon_bline = 41, -+ .vavon_eline = 1120, -+ /* eqpuls_begin */ -+ /* eqpuls_end */ -+ .eqpuls_bline = 0, -+ .eqpuls_bline_present = true, -+ .eqpuls_eline = 4, -+ .eqpuls_eline_present = true, -+ .hso_begin = 79, -+ .hso_end = 123, -+ .vso_begin = 79, -+ .vso_end = 79, -+ .vso_bline = 0, -+ .vso_eline = 5, -+ .vso_eline_present = true, -+ /* sy_val */ -+ /* sy2_val */ -+ .max_lncnt = 1124, -+ }, -+}; -+ -+union meson_hdmi_venc_mode meson_hdmi_encp_mode_1080p60 = { -+ .encp = { -+ .dvi_settings = 0x1, -+ .video_mode = 0x4040, -+ .video_mode_adv = 0x18, -+ .video_prog_mode = 0x100, -+ .video_prog_mode_present = true, -+ /* video_sync_mode */ -+ /* video_yc_dly */ -+ /* video_rgb_ctrl */ -+ .video_filt_ctrl = 0x1052, -+ .video_filt_ctrl_present = true, -+ /* video_ofld_voav_ofst */ -+ .yfp1_htime = 140, -+ .yfp2_htime = 2060, -+ .max_pxcnt = 2199, -+ .hspuls_begin = 2156, -+ .hspuls_end = 44, -+ .hspuls_switch = 44, -+ .vspuls_begin = 140, -+ .vspuls_end = 2059, -+ .vspuls_bline = 0, -+ .vspuls_eline = 4, -+ .havon_begin = 148, -+ .havon_end = 2067, -+ .vavon_bline = 41, -+ .vavon_eline = 1120, -+ /* eqpuls_begin */ -+ /* eqpuls_end */ -+ /* eqpuls_bline */ -+ /* eqpuls_eline */ -+ .hso_begin = 44, -+ .hso_end = 2156, -+ .vso_begin = 2100, -+ .vso_end = 2164, -+ .vso_bline = 0, -+ .vso_eline = 5, -+ .vso_eline_present = true, -+ /* sy_val */ -+ /* sy2_val */ -+ .max_lncnt = 1124, -+ }, -+}; -+ -+struct meson_hdmi_venc_vic_mode { -+ unsigned int vic; -+ union meson_hdmi_venc_mode *mode; -+} meson_hdmi_venc_vic_modes[] = { -+ { 6, &meson_hdmi_enci_mode_480i }, -+ { 7, &meson_hdmi_enci_mode_480i }, -+ { 21, &meson_hdmi_enci_mode_576i }, -+ { 22, &meson_hdmi_enci_mode_576i }, -+ { 2, &meson_hdmi_encp_mode_480p }, -+ { 3, &meson_hdmi_encp_mode_480p }, -+ { 17, &meson_hdmi_encp_mode_576p }, -+ { 18, &meson_hdmi_encp_mode_576p }, -+ { 4, &meson_hdmi_encp_mode_720p60 }, -+ { 19, &meson_hdmi_encp_mode_720p50 }, -+ { 5, &meson_hdmi_encp_mode_1080i60 }, -+ { 20, &meson_hdmi_encp_mode_1080i50 }, -+ { 32, &meson_hdmi_encp_mode_1080p24 }, -+ { 34, &meson_hdmi_encp_mode_1080p30 }, -+ { 31, &meson_hdmi_encp_mode_1080p50 }, -+ { 16, &meson_hdmi_encp_mode_1080p60 }, -+ { 0, NULL}, /* sentinel */ -+}; -+ -+static signed int to_signed(unsigned int a) -+{ -+ if (a <= 7) -+ return a; -+ else -+ return a - 16; -+} -+ -+static unsigned long modulo(unsigned long a, unsigned long b) -+{ -+ if (a >= b) -+ return a - b; -+ else -+ return a; -+} -+ -+bool meson_venc_hdmi_supported_vic(int vic) -+{ -+ struct meson_hdmi_venc_vic_mode *vmode = meson_hdmi_venc_vic_modes; -+ -+ while (vmode->vic && vmode->mode) { -+ if (vmode->vic == vic) -+ return true; -+ vmode++; -+ } -+ -+ return false; -+} -+EXPORT_SYMBOL_GPL(meson_venc_hdmi_supported_vic); -+ -+static union meson_hdmi_venc_mode *meson_venc_hdmi_get_vic_vmode(int vic) -+{ -+ struct meson_hdmi_venc_vic_mode *vmode = meson_hdmi_venc_vic_modes; -+ -+ while (vmode->vic && vmode->mode) { -+ if (vmode->vic == vic) -+ return vmode->mode; -+ vmode++; -+ } -+ -+ return NULL; -+} -+ -+bool meson_venc_hdmi_venc_repeat(int vic) -+{ -+ /* Repeat VENC pixels for 480/576i/p, 720p50/60 and 1080p50/60 */ -+ if (vic == 6 || vic == 7 || /* 480i */ -+ vic == 21 || vic == 22 || /* 576i */ -+ vic == 17 || vic == 18 || /* 576p */ -+ vic == 2 || vic == 3 || /* 480p */ -+ vic == 4 || /* 720p60 */ -+ vic == 19 || /* 720p50 */ -+ vic == 5 || /* 1080i60 */ -+ vic == 20) /* 1080i50 */ -+ return true; -+ -+ return false; -+} -+EXPORT_SYMBOL_GPL(meson_venc_hdmi_venc_repeat); -+ -+void meson_venc_hdmi_mode_set(struct meson_drm *priv, int vic, -+ struct drm_display_mode *mode) -+{ -+ union meson_hdmi_venc_mode *vmode = NULL; -+ bool use_enci = false; -+ bool venc_repeat = false; -+ bool hdmi_repeat = false; -+ unsigned int venc_hdmi_latency = 2; -+ unsigned long total_pixels_venc = 0; -+ unsigned long active_pixels_venc = 0; -+ unsigned long front_porch_venc = 0; -+ unsigned long hsync_pixels_venc = 0; -+ unsigned long de_h_begin = 0; -+ unsigned long de_h_end = 0; -+ unsigned long de_v_begin_even = 0; -+ unsigned long de_v_end_even = 0; -+ unsigned long de_v_begin_odd = 0; -+ unsigned long de_v_end_odd = 0; -+ unsigned long hs_begin = 0; -+ unsigned long hs_end = 0; -+ unsigned long vs_adjust = 0; -+ unsigned long vs_bline_evn = 0; -+ unsigned long vs_eline_evn = 0; -+ unsigned long vs_bline_odd = 0; -+ unsigned long vs_eline_odd = 0; -+ unsigned long vso_begin_evn = 0; -+ unsigned long vso_begin_odd = 0; -+ unsigned int eof_lines; -+ unsigned int sof_lines; -+ unsigned int vsync_lines; -+ -+ vmode = meson_venc_hdmi_get_vic_vmode(vic); -+ if (!vmode) { -+ dev_err(priv->dev, "%s: Fatal Error, unsupported vic %d\n", -+ __func__, vic); -+ return; -+ } -+ -+ /* Use VENCI for 480i and 576i and double HDMI pixels */ -+ if (mode->flags & DRM_MODE_FLAG_DBLCLK) { -+ hdmi_repeat = true; -+ use_enci = true; -+ venc_hdmi_latency = 1; -+ } -+ -+ /* Repeat VENC pixels for 480/576i/p, 720p50/60 and 1080p50/60 */ -+ if (meson_venc_hdmi_venc_repeat(vic)) -+ venc_repeat = true; -+ -+ eof_lines = mode->vsync_start - mode->vdisplay; -+ if (mode->flags & DRM_MODE_FLAG_INTERLACE) -+ eof_lines /= 2; -+ sof_lines = mode->vtotal - mode->vsync_end; -+ if (mode->flags & DRM_MODE_FLAG_INTERLACE) -+ sof_lines /= 2; -+ vsync_lines = mode->vsync_end - mode->vsync_start; -+ if (mode->flags & DRM_MODE_FLAG_INTERLACE) -+ vsync_lines /= 2; -+ -+ total_pixels_venc = mode->htotal; -+ if (hdmi_repeat) -+ total_pixels_venc /= 2; -+ if (venc_repeat) -+ total_pixels_venc *= 2; -+ -+ active_pixels_venc = mode->hdisplay; -+ if (hdmi_repeat) -+ active_pixels_venc /= 2; -+ if (venc_repeat) -+ active_pixels_venc *= 2; -+ -+ front_porch_venc = (mode->hsync_start - mode->hdisplay); -+ if (hdmi_repeat) -+ front_porch_venc /= 2; -+ if (venc_repeat) -+ front_porch_venc *= 2; -+ -+ hsync_pixels_venc = (mode->hsync_end - mode->hsync_start); -+ if (hdmi_repeat) -+ hsync_pixels_venc /= 2; -+ if (venc_repeat) -+ hsync_pixels_venc *= 2; -+ -+ /* Disable VDACs */ -+ writel_bits_relaxed(0x1f, 0x1f, -+ priv->io_base + _REG(VENC_VDAC_SETTING)); -+ -+ writel_relaxed(0, priv->io_base + _REG(ENCI_VIDEO_EN)); -+ writel_relaxed(0, priv->io_base + _REG(ENCP_VIDEO_EN)); -+ -+ if (use_enci) { -+ unsigned int lines_f0; -+ unsigned int lines_f1; -+ -+ /* CVBS Filter settings */ -+ writel_relaxed(0x12, priv->io_base + _REG(ENCI_CFILT_CTRL)); -+ writel_relaxed(0x12, priv->io_base + _REG(ENCI_CFILT_CTRL2)); -+ -+ /* Digital Video Select : Interlace, clk27 clk, external */ -+ writel_relaxed(0, priv->io_base + _REG(VENC_DVI_SETTING)); -+ -+ /* Reset Video Mode */ -+ writel_relaxed(0, priv->io_base + _REG(ENCI_VIDEO_MODE)); -+ writel_relaxed(0, priv->io_base + _REG(ENCI_VIDEO_MODE_ADV)); -+ -+ /* Horizontal sync signal output */ -+ writel_relaxed(vmode->enci.hso_begin, -+ priv->io_base + _REG(ENCI_SYNC_HSO_BEGIN)); -+ writel_relaxed(vmode->enci.hso_end, -+ priv->io_base + _REG(ENCI_SYNC_HSO_END)); -+ -+ /* Vertical Sync lines */ -+ writel_relaxed(vmode->enci.vso_even, -+ priv->io_base + _REG(ENCI_SYNC_VSO_EVNLN)); -+ writel_relaxed(vmode->enci.vso_odd, -+ priv->io_base + _REG(ENCI_SYNC_VSO_ODDLN)); -+ -+ /* Macrovision max amplitude change */ -+ writel_relaxed(vmode->enci.macv_max_amp, -+ priv->io_base + _REG(ENCI_MACV_MAX_AMP)); -+ -+ /* Video mode */ -+ writel_relaxed(vmode->enci.video_prog_mode, -+ priv->io_base + _REG(VENC_VIDEO_PROG_MODE)); -+ writel_relaxed(vmode->enci.video_mode, -+ priv->io_base + _REG(ENCI_VIDEO_MODE)); -+ -+ /* Advanced Video Mode : -+ * Demux shifting 0x2 -+ * Blank line end at line17/22 -+ * High bandwidth Luma Filter -+ * Low bandwidth Chroma Filter -+ * Bypass luma low pass filter -+ * No macrovision on CSYNC -+ */ -+ writel_relaxed(0x26, priv->io_base + _REG(ENCI_VIDEO_MODE_ADV)); -+ -+ writel(vmode->enci.sch_adjust, -+ priv->io_base + _REG(ENCI_VIDEO_SCH)); -+ -+ /* Sync mode : MASTER Master mode, free run, send HSO/VSO out */ -+ writel_relaxed(0x07, priv->io_base + _REG(ENCI_SYNC_MODE)); -+ -+ if (vmode->enci.yc_delay) -+ writel_relaxed(vmode->enci.yc_delay, -+ priv->io_base + _REG(ENCI_YC_DELAY)); -+ -+ -+ /* UNreset Interlaced TV Encoder */ -+ writel_relaxed(0, priv->io_base + _REG(ENCI_DBG_PX_RST)); -+ -+ /* Enable Vfifo2vd, Y_Cb_Y_Cr select */ -+ writel_relaxed(0x4e01, priv->io_base + _REG(ENCI_VFIFO2VD_CTL)); -+ -+ /* Timings */ -+ writel_relaxed(vmode->enci.pixel_start, -+ priv->io_base + _REG(ENCI_VFIFO2VD_PIXEL_START)); -+ writel_relaxed(vmode->enci.pixel_end, -+ priv->io_base + _REG(ENCI_VFIFO2VD_PIXEL_END)); -+ -+ writel_relaxed(vmode->enci.top_field_line_start, -+ priv->io_base + _REG(ENCI_VFIFO2VD_LINE_TOP_START)); -+ writel_relaxed(vmode->enci.top_field_line_end, -+ priv->io_base + _REG(ENCI_VFIFO2VD_LINE_TOP_END)); -+ -+ writel_relaxed(vmode->enci.bottom_field_line_start, -+ priv->io_base + _REG(ENCI_VFIFO2VD_LINE_BOT_START)); -+ writel_relaxed(vmode->enci.bottom_field_line_end, -+ priv->io_base + _REG(ENCI_VFIFO2VD_LINE_BOT_END)); -+ -+ /* Select ENCI for VIU */ -+ meson_vpp_setup_mux(priv, MESON_VIU_VPP_MUX_ENCI); -+ -+ /* Interlace video enable */ -+ writel_relaxed(1, priv->io_base + _REG(ENCI_VIDEO_EN)); -+ -+ lines_f0 = mode->vtotal >> 1; -+ lines_f1 = lines_f0 + 1; -+ -+ de_h_begin = modulo(readl_relaxed(priv->io_base + -+ _REG(ENCI_VFIFO2VD_PIXEL_START)) -+ + venc_hdmi_latency, -+ total_pixels_venc); -+ de_h_end = modulo(de_h_begin + active_pixels_venc, -+ total_pixels_venc); -+ -+ writel_relaxed(de_h_begin, -+ priv->io_base + _REG(ENCI_DE_H_BEGIN)); -+ writel_relaxed(de_h_end, -+ priv->io_base + _REG(ENCI_DE_H_END)); -+ -+ de_v_begin_even = readl_relaxed(priv->io_base + -+ _REG(ENCI_VFIFO2VD_LINE_TOP_START)); -+ de_v_end_even = de_v_begin_even + mode->vdisplay; -+ de_v_begin_odd = readl_relaxed(priv->io_base + -+ _REG(ENCI_VFIFO2VD_LINE_BOT_START)); -+ de_v_end_odd = de_v_begin_odd + mode->vdisplay; -+ -+ writel_relaxed(de_v_begin_even, -+ priv->io_base + _REG(ENCI_DE_V_BEGIN_EVEN)); -+ writel_relaxed(de_v_end_even, -+ priv->io_base + _REG(ENCI_DE_V_END_EVEN)); -+ writel_relaxed(de_v_begin_odd, -+ priv->io_base + _REG(ENCI_DE_V_BEGIN_ODD)); -+ writel_relaxed(de_v_end_odd, -+ priv->io_base + _REG(ENCI_DE_V_END_ODD)); -+ -+ /* Program Hsync timing */ -+ hs_begin = de_h_end + front_porch_venc; -+ if (de_h_end + front_porch_venc >= total_pixels_venc) { -+ hs_begin -= total_pixels_venc; -+ vs_adjust = 1; -+ } else { -+ hs_begin = de_h_end + front_porch_venc; -+ vs_adjust = 0; -+ } -+ -+ hs_end = modulo(hs_begin + hsync_pixels_venc, -+ total_pixels_venc); -+ writel_relaxed(hs_begin, -+ priv->io_base + _REG(ENCI_DVI_HSO_BEGIN)); -+ writel_relaxed(hs_end, -+ priv->io_base + _REG(ENCI_DVI_HSO_END)); -+ -+ /* Program Vsync timing for even field */ -+ if (((de_v_end_odd - 1) + eof_lines + vs_adjust) >= lines_f1) { -+ vs_bline_evn = (de_v_end_odd - 1) -+ + eof_lines -+ + vs_adjust -+ - lines_f1; -+ vs_eline_evn = vs_bline_evn + vsync_lines; -+ -+ writel_relaxed(vs_bline_evn, -+ priv->io_base + _REG(ENCI_DVI_VSO_BLINE_EVN)); -+ -+ writel_relaxed(vs_eline_evn, -+ priv->io_base + _REG(ENCI_DVI_VSO_ELINE_EVN)); -+ -+ writel_relaxed(hs_begin, -+ priv->io_base + _REG(ENCI_DVI_VSO_BEGIN_EVN)); -+ writel_relaxed(hs_begin, -+ priv->io_base + _REG(ENCI_DVI_VSO_END_EVN)); -+ } else { -+ vs_bline_odd = (de_v_end_odd - 1) -+ + eof_lines -+ + vs_adjust; -+ -+ writel_relaxed(vs_bline_odd, -+ priv->io_base + _REG(ENCI_DVI_VSO_BLINE_ODD)); -+ -+ writel_relaxed(hs_begin, -+ priv->io_base + _REG(ENCI_DVI_VSO_BEGIN_ODD)); -+ -+ if ((vs_bline_odd + vsync_lines) >= lines_f1) { -+ vs_eline_evn = vs_bline_odd -+ + vsync_lines -+ - lines_f1; -+ -+ writel_relaxed(vs_eline_evn, priv->io_base -+ + _REG(ENCI_DVI_VSO_ELINE_EVN)); -+ -+ writel_relaxed(hs_begin, priv->io_base -+ + _REG(ENCI_DVI_VSO_END_EVN)); -+ } else { -+ vs_eline_odd = vs_bline_odd -+ + vsync_lines; -+ -+ writel_relaxed(vs_eline_odd, priv->io_base -+ + _REG(ENCI_DVI_VSO_ELINE_ODD)); -+ -+ writel_relaxed(hs_begin, priv->io_base -+ + _REG(ENCI_DVI_VSO_END_ODD)); -+ } -+ } -+ -+ /* Program Vsync timing for odd field */ -+ if (((de_v_end_even - 1) + (eof_lines + 1)) >= lines_f0) { -+ vs_bline_odd = (de_v_end_even - 1) -+ + (eof_lines + 1) -+ - lines_f0; -+ vs_eline_odd = vs_bline_odd + vsync_lines; -+ -+ writel_relaxed(vs_bline_odd, -+ priv->io_base + _REG(ENCI_DVI_VSO_BLINE_ODD)); -+ -+ writel_relaxed(vs_eline_odd, -+ priv->io_base + _REG(ENCI_DVI_VSO_ELINE_ODD)); -+ -+ vso_begin_odd = modulo(hs_begin -+ + (total_pixels_venc >> 1), -+ total_pixels_venc); -+ -+ writel_relaxed(vso_begin_odd, -+ priv->io_base + _REG(ENCI_DVI_VSO_BEGIN_ODD)); -+ writel_relaxed(vso_begin_odd, -+ priv->io_base + _REG(ENCI_DVI_VSO_END_ODD)); -+ } else { -+ vs_bline_evn = (de_v_end_even - 1) -+ + (eof_lines + 1); -+ -+ writel_relaxed(vs_bline_evn, -+ priv->io_base + _REG(ENCI_DVI_VSO_BLINE_EVN)); -+ -+ vso_begin_evn = modulo(hs_begin -+ + (total_pixels_venc >> 1), -+ total_pixels_venc); -+ -+ writel_relaxed(vso_begin_evn, priv->io_base -+ + _REG(ENCI_DVI_VSO_BEGIN_EVN)); -+ -+ if (vs_bline_evn + vsync_lines >= lines_f0) { -+ vs_eline_odd = vs_bline_evn -+ + vsync_lines -+ - lines_f0; -+ -+ writel_relaxed(vs_eline_odd, priv->io_base -+ + _REG(ENCI_DVI_VSO_ELINE_ODD)); -+ -+ writel_relaxed(vso_begin_evn, priv->io_base -+ + _REG(ENCI_DVI_VSO_END_ODD)); -+ } else { -+ vs_eline_evn = vs_bline_evn + vsync_lines; -+ -+ writel_relaxed(vs_eline_evn, priv->io_base -+ + _REG(ENCI_DVI_VSO_ELINE_EVN)); -+ -+ writel_relaxed(vso_begin_evn, priv->io_base -+ + _REG(ENCI_DVI_VSO_END_EVN)); -+ } -+ } -+ } else { -+ writel_relaxed(vmode->encp.dvi_settings, -+ priv->io_base + _REG(VENC_DVI_SETTING)); -+ writel_relaxed(vmode->encp.video_mode, -+ priv->io_base + _REG(ENCP_VIDEO_MODE)); -+ writel_relaxed(vmode->encp.video_mode_adv, -+ priv->io_base + _REG(ENCP_VIDEO_MODE_ADV)); -+ if (vmode->encp.video_prog_mode_present) -+ writel_relaxed(vmode->encp.video_prog_mode, -+ priv->io_base + _REG(VENC_VIDEO_PROG_MODE)); -+ if (vmode->encp.video_sync_mode_present) -+ writel_relaxed(vmode->encp.video_sync_mode, -+ priv->io_base + _REG(ENCP_VIDEO_SYNC_MODE)); -+ if (vmode->encp.video_yc_dly_present) -+ writel_relaxed(vmode->encp.video_yc_dly, -+ priv->io_base + _REG(ENCP_VIDEO_YC_DLY)); -+ if (vmode->encp.video_rgb_ctrl_present) -+ writel_relaxed(vmode->encp.video_rgb_ctrl, -+ priv->io_base + _REG(ENCP_VIDEO_RGB_CTRL)); -+ if (vmode->encp.video_filt_ctrl_present) -+ writel_relaxed(vmode->encp.video_filt_ctrl, -+ priv->io_base + _REG(ENCP_VIDEO_FILT_CTRL)); -+ if (vmode->encp.video_ofld_voav_ofst_present) -+ writel_relaxed(vmode->encp.video_ofld_voav_ofst, -+ priv->io_base -+ + _REG(ENCP_VIDEO_OFLD_VOAV_OFST)); -+ writel_relaxed(vmode->encp.yfp1_htime, -+ priv->io_base + _REG(ENCP_VIDEO_YFP1_HTIME)); -+ writel_relaxed(vmode->encp.yfp2_htime, -+ priv->io_base + _REG(ENCP_VIDEO_YFP2_HTIME)); -+ writel_relaxed(vmode->encp.max_pxcnt, -+ priv->io_base + _REG(ENCP_VIDEO_MAX_PXCNT)); -+ writel_relaxed(vmode->encp.hspuls_begin, -+ priv->io_base + _REG(ENCP_VIDEO_HSPULS_BEGIN)); -+ writel_relaxed(vmode->encp.hspuls_end, -+ priv->io_base + _REG(ENCP_VIDEO_HSPULS_END)); -+ writel_relaxed(vmode->encp.hspuls_switch, -+ priv->io_base + _REG(ENCP_VIDEO_HSPULS_SWITCH)); -+ writel_relaxed(vmode->encp.vspuls_begin, -+ priv->io_base + _REG(ENCP_VIDEO_VSPULS_BEGIN)); -+ writel_relaxed(vmode->encp.vspuls_end, -+ priv->io_base + _REG(ENCP_VIDEO_VSPULS_END)); -+ writel_relaxed(vmode->encp.vspuls_bline, -+ priv->io_base + _REG(ENCP_VIDEO_VSPULS_BLINE)); -+ writel_relaxed(vmode->encp.vspuls_eline, -+ priv->io_base + _REG(ENCP_VIDEO_VSPULS_ELINE)); -+ if (vmode->encp.eqpuls_begin_present) -+ writel_relaxed(vmode->encp.eqpuls_begin, -+ priv->io_base + _REG(ENCP_VIDEO_EQPULS_BEGIN)); -+ if (vmode->encp.eqpuls_end_present) -+ writel_relaxed(vmode->encp.eqpuls_end, -+ priv->io_base + _REG(ENCP_VIDEO_EQPULS_END)); -+ if (vmode->encp.eqpuls_bline_present) -+ writel_relaxed(vmode->encp.eqpuls_bline, -+ priv->io_base + _REG(ENCP_VIDEO_EQPULS_BLINE)); -+ if (vmode->encp.eqpuls_eline_present) -+ writel_relaxed(vmode->encp.eqpuls_eline, -+ priv->io_base + _REG(ENCP_VIDEO_EQPULS_ELINE)); -+ writel_relaxed(vmode->encp.havon_begin, -+ priv->io_base + _REG(ENCP_VIDEO_HAVON_BEGIN)); -+ writel_relaxed(vmode->encp.havon_end, -+ priv->io_base + _REG(ENCP_VIDEO_HAVON_END)); -+ writel_relaxed(vmode->encp.vavon_bline, -+ priv->io_base + _REG(ENCP_VIDEO_VAVON_BLINE)); -+ writel_relaxed(vmode->encp.vavon_eline, -+ priv->io_base + _REG(ENCP_VIDEO_VAVON_ELINE)); -+ writel_relaxed(vmode->encp.hso_begin, -+ priv->io_base + _REG(ENCP_VIDEO_HSO_BEGIN)); -+ writel_relaxed(vmode->encp.hso_end, -+ priv->io_base + _REG(ENCP_VIDEO_HSO_END)); -+ writel_relaxed(vmode->encp.vso_begin, -+ priv->io_base + _REG(ENCP_VIDEO_VSO_BEGIN)); -+ writel_relaxed(vmode->encp.vso_end, -+ priv->io_base + _REG(ENCP_VIDEO_VSO_END)); -+ writel_relaxed(vmode->encp.vso_bline, -+ priv->io_base + _REG(ENCP_VIDEO_VSO_BLINE)); -+ if (vmode->encp.vso_eline_present) -+ writel_relaxed(vmode->encp.vso_eline, -+ priv->io_base + _REG(ENCP_VIDEO_VSO_ELINE)); -+ if (vmode->encp.sy_val_present) -+ writel_relaxed(vmode->encp.sy_val, -+ priv->io_base + _REG(ENCP_VIDEO_SY_VAL)); -+ if (vmode->encp.sy2_val_present) -+ writel_relaxed(vmode->encp.sy2_val, -+ priv->io_base + _REG(ENCP_VIDEO_SY2_VAL)); -+ writel_relaxed(vmode->encp.max_lncnt, -+ priv->io_base + _REG(ENCP_VIDEO_MAX_LNCNT)); -+ -+ writel_relaxed(1, priv->io_base + _REG(ENCP_VIDEO_EN)); -+ -+ /* Set DE signal’s polarity is active high */ -+ writel_bits_relaxed(BIT(14), BIT(14), -+ priv->io_base + _REG(ENCP_VIDEO_MODE)); -+ -+ /* Program DE timing */ -+ de_h_begin = modulo(readl_relaxed(priv->io_base + -+ _REG(ENCP_VIDEO_HAVON_BEGIN)) -+ + venc_hdmi_latency, -+ total_pixels_venc); -+ de_h_end = modulo(de_h_begin + active_pixels_venc, -+ total_pixels_venc); -+ -+ writel_relaxed(de_h_begin, -+ priv->io_base + _REG(ENCP_DE_H_BEGIN)); -+ writel_relaxed(de_h_end, -+ priv->io_base + _REG(ENCP_DE_H_END)); -+ -+ /* Program DE timing for even field */ -+ de_v_begin_even = readl_relaxed(priv->io_base -+ + _REG(ENCP_VIDEO_VAVON_BLINE)); -+ if (mode->flags & DRM_MODE_FLAG_INTERLACE) -+ de_v_end_even = de_v_begin_even + -+ (mode->vdisplay / 2); -+ else -+ de_v_end_even = de_v_begin_even + mode->vdisplay; -+ -+ writel_relaxed(de_v_begin_even, -+ priv->io_base + _REG(ENCP_DE_V_BEGIN_EVEN)); -+ writel_relaxed(de_v_end_even, -+ priv->io_base + _REG(ENCP_DE_V_END_EVEN)); -+ -+ /* Program DE timing for odd field if needed */ -+ if (mode->flags & DRM_MODE_FLAG_INTERLACE) { -+ unsigned int ofld_voav_ofst = -+ readl_relaxed(priv->io_base + -+ _REG(ENCP_VIDEO_OFLD_VOAV_OFST)); -+ de_v_begin_odd = to_signed((ofld_voav_ofst & 0xf0) >> 4) -+ + de_v_begin_even -+ + ((mode->vtotal - 1) / 2); -+ de_v_end_odd = de_v_begin_odd + (mode->vdisplay / 2); -+ -+ writel_relaxed(de_v_begin_odd, -+ priv->io_base + _REG(ENCP_DE_V_BEGIN_ODD)); -+ writel_relaxed(de_v_end_odd, -+ priv->io_base + _REG(ENCP_DE_V_END_ODD)); -+ } -+ -+ /* Program Hsync timing */ -+ if ((de_h_end + front_porch_venc) >= total_pixels_venc) { -+ hs_begin = de_h_end -+ + front_porch_venc -+ - total_pixels_venc; -+ vs_adjust = 1; -+ } else { -+ hs_begin = de_h_end -+ + front_porch_venc; -+ vs_adjust = 0; -+ } -+ -+ hs_end = modulo(hs_begin + hsync_pixels_venc, -+ total_pixels_venc); -+ -+ writel_relaxed(hs_begin, -+ priv->io_base + _REG(ENCP_DVI_HSO_BEGIN)); -+ writel_relaxed(hs_end, -+ priv->io_base + _REG(ENCP_DVI_HSO_END)); -+ -+ /* Program Vsync timing for even field */ -+ if (de_v_begin_even >= -+ (sof_lines + vsync_lines + (1 - vs_adjust))) -+ vs_bline_evn = de_v_begin_even -+ - sof_lines -+ - vsync_lines -+ - (1 - vs_adjust); -+ else -+ vs_bline_evn = mode->vtotal -+ + de_v_begin_even -+ - sof_lines -+ - vsync_lines -+ - (1 - vs_adjust); -+ -+ vs_eline_evn = modulo(vs_bline_evn + vsync_lines, -+ mode->vtotal); -+ -+ writel_relaxed(vs_bline_evn, -+ priv->io_base + _REG(ENCP_DVI_VSO_BLINE_EVN)); -+ writel_relaxed(vs_eline_evn, -+ priv->io_base + _REG(ENCP_DVI_VSO_ELINE_EVN)); -+ -+ vso_begin_evn = hs_begin; -+ writel_relaxed(vso_begin_evn, -+ priv->io_base + _REG(ENCP_DVI_VSO_BEGIN_EVN)); -+ writel_relaxed(vso_begin_evn, -+ priv->io_base + _REG(ENCP_DVI_VSO_END_EVN)); -+ -+ /* Program Vsync timing for odd field if needed */ -+ if (mode->flags & DRM_MODE_FLAG_INTERLACE) { -+ vs_bline_odd = (de_v_begin_odd - 1) -+ - sof_lines -+ - vsync_lines; -+ vs_eline_odd = (de_v_begin_odd - 1) -+ - vsync_lines; -+ vso_begin_odd = modulo(hs_begin -+ + (total_pixels_venc >> 1), -+ total_pixels_venc); -+ -+ writel_relaxed(vs_bline_odd, -+ priv->io_base + _REG(ENCP_DVI_VSO_BLINE_ODD)); -+ writel_relaxed(vs_eline_odd, -+ priv->io_base + _REG(ENCP_DVI_VSO_ELINE_ODD)); -+ writel_relaxed(vso_begin_odd, -+ priv->io_base + _REG(ENCP_DVI_VSO_BEGIN_ODD)); -+ writel_relaxed(vso_begin_odd, -+ priv->io_base + _REG(ENCP_DVI_VSO_END_ODD)); -+ } -+ -+ /* Select ENCP for VIU */ -+ meson_vpp_setup_mux(priv, MESON_VIU_VPP_MUX_ENCP); -+ } -+ -+ writel_relaxed((use_enci ? 1 : 2) | -+ (mode->flags & DRM_MODE_FLAG_PHSYNC ? 1 << 2 : 0) | -+ (mode->flags & DRM_MODE_FLAG_PVSYNC ? 1 << 3 : 0) | -+ 4 << 5 | -+ (venc_repeat ? 1 << 8 : 0) | -+ (hdmi_repeat ? 1 << 12 : 0), -+ priv->io_base + _REG(VPU_HDMI_SETTING)); -+ -+ priv->venc.hdmi_repeat = hdmi_repeat; -+ priv->venc.venc_repeat = venc_repeat; -+ priv->venc.hdmi_use_enci = use_enci; -+ -+ priv->venc.current_mode = MESON_VENC_MODE_HDMI; -+} -+EXPORT_SYMBOL_GPL(meson_venc_hdmi_mode_set); -+ - void meson_venci_cvbs_mode_set(struct meson_drm *priv, - struct meson_cvbs_enci_mode *mode) - { -@@ -223,9 +1461,6 @@ void meson_venci_cvbs_mode_set(struct meson_drm *priv, - writel_relaxed(mode->analog_sync_adj, - priv->io_base + _REG(ENCI_SYNC_ADJ)); - -- /* Setup 27MHz vclk2 for ENCI and VDAC */ -- meson_vclk_setup(priv, MESON_VCLK_TARGET_CVBS, MESON_VCLK_CVBS); -- - priv->venc.current_mode = mode->mode_tag; - } - -diff --git a/drivers/gpu/drm/meson/meson_venc.h b/drivers/gpu/drm/meson/meson_venc.h -index 77d4a7d..a1b96e8 100644 ---- a/drivers/gpu/drm/meson/meson_venc.h -+++ b/drivers/gpu/drm/meson/meson_venc.h -@@ -30,6 +30,7 @@ enum { - MESON_VENC_MODE_NONE = 0, - MESON_VENC_MODE_CVBS_PAL, - MESON_VENC_MODE_CVBS_NTSC, -+ MESON_VENC_MODE_HDMI, - }; - - struct meson_cvbs_enci_mode { -@@ -56,12 +57,18 @@ struct meson_cvbs_enci_mode { - unsigned int analog_sync_adj; - }; - -+/* HDMI Clock parameters */ -+bool meson_venc_hdmi_supported_vic(int vic); -+bool meson_venc_hdmi_venc_repeat(int vic); -+ - /* CVBS Timings and Parameters */ - extern struct meson_cvbs_enci_mode meson_cvbs_enci_pal; - extern struct meson_cvbs_enci_mode meson_cvbs_enci_ntsc; - - void meson_venci_cvbs_mode_set(struct meson_drm *priv, - struct meson_cvbs_enci_mode *mode); -+void meson_venc_hdmi_mode_set(struct meson_drm *priv, int vic, -+ struct drm_display_mode *mode); - unsigned int meson_venci_get_field(struct meson_drm *priv); - - void meson_venc_enable_vsync(struct meson_drm *priv); -diff --git a/drivers/gpu/drm/meson/meson_vpp.h b/drivers/gpu/drm/meson/meson_vpp.h -index ede3b26..815177c 100644 ---- a/drivers/gpu/drm/meson/meson_vpp.h -+++ b/drivers/gpu/drm/meson/meson_vpp.h -@@ -23,6 +23,8 @@ - - /* Mux VIU/VPP to ENCI */ - #define MESON_VIU_VPP_MUX_ENCI 0x5 -+/* Mux VIU/VPP to ENCP */ -+#define MESON_VIU_VPP_MUX_ENCP 0xA - - void meson_vpp_setup_mux(struct meson_drm *priv, unsigned int mux); - --- -1.9.1 - diff --git a/patch/kernel/odroidc2-next/0054-clk-fix-incorrect-usage-of-ENOSYS.patch b/patch/kernel/odroidc2-next/0054-clk-fix-incorrect-usage-of-ENOSYS.patch new file mode 100644 index 000000000..67f18cea6 --- /dev/null +++ b/patch/kernel/odroidc2-next/0054-clk-fix-incorrect-usage-of-ENOSYS.patch @@ -0,0 +1,32 @@ +From 71696c295bdbc1624d6204c01070518cba0451b5 Mon Sep 17 00:00:00 2001 +From: Jerome Brunet +Date: Tue, 21 Mar 2017 16:03:55 +0100 +Subject: [PATCH 54/79] clk: fix incorrect usage of ENOSYS + +ENOSYS is special and should only be used for incorrect syscall number. +It does not seem to be the case here. + +Reported by checkpatch.pl while working on clock protection. + +Signed-off-by: Jerome Brunet +Signed-off-by: Neil Armstrong +--- + drivers/clk/clk.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/drivers/clk/clk.c b/drivers/clk/clk.c +index 8d57e13..5d54595 100644 +--- a/drivers/clk/clk.c ++++ b/drivers/clk/clk.c +@@ -2032,7 +2032,7 @@ static int clk_core_set_parent_nolock(struct clk_core *core, + + /* verify ops for for multi-parent clks */ + if ((core->num_parents > 1) && (!core->ops->set_parent)) +- return -ENOSYS; ++ return -EPERM; + + /* check that we are allowed to re-parent if the clock is in use */ + if ((core->flags & CLK_SET_PARENT_GATE) && core->prepare_count) +-- +1.9.1 + diff --git a/patch/kernel/odroidc2-next/0054-drm-meson-Add-support-for-HDMI-encoder-and-DW-HDMI-b.patch b/patch/kernel/odroidc2-next/0054-drm-meson-Add-support-for-HDMI-encoder-and-DW-HDMI-b.patch deleted file mode 100644 index 6f41951f5..000000000 --- a/patch/kernel/odroidc2-next/0054-drm-meson-Add-support-for-HDMI-encoder-and-DW-HDMI-b.patch +++ /dev/null @@ -1,1129 +0,0 @@ -From 818b416aa08d29cabd798d0278fd538731753eff Mon Sep 17 00:00:00 2001 -From: Neil Armstrong -Date: Mon, 9 Jan 2017 14:20:24 +0100 -Subject: [PATCH 54/93] drm/meson: Add support for HDMI encoder and DW-HDMI - bridge + PHY - -The Amlogic Meson GXBB/GXL/GXM SoCs embeds a Synopsys DesignWare HDMI TX -Controller with a custom Bridge + PHY around the Controller. - -This driver makes uses of all the custom PHY plat data callbacks and enables -the compatible HDMI modes to be configured as a drm_encoder instance. ---- - drivers/gpu/drm/meson/Kconfig | 6 + - drivers/gpu/drm/meson/Makefile | 1 + - drivers/gpu/drm/meson/meson_drv.h | 3 + - drivers/gpu/drm/meson/meson_dw_hdmi.c | 910 ++++++++++++++++++++++++++++++++++ - drivers/gpu/drm/meson/meson_dw_hdmi.h | 146 ++++++ - 5 files changed, 1066 insertions(+) - create mode 100644 drivers/gpu/drm/meson/meson_dw_hdmi.c - create mode 100644 drivers/gpu/drm/meson/meson_dw_hdmi.h - -diff --git a/drivers/gpu/drm/meson/Kconfig b/drivers/gpu/drm/meson/Kconfig -index 99719af..3ce51d8 100644 ---- a/drivers/gpu/drm/meson/Kconfig -+++ b/drivers/gpu/drm/meson/Kconfig -@@ -7,3 +7,9 @@ config DRM_MESON - select DRM_GEM_CMA_HELPER - select VIDEOMODE_HELPERS - select REGMAP_MMIO -+ -+config DRM_MESON_DW_HDMI -+ tristate "HDMI Synopsys Controller support for Amlogic Meson Display" -+ depends on DRM_MESON -+ default y if DRM_MESON -+ select DRM_DW_HDMI -diff --git a/drivers/gpu/drm/meson/Makefile b/drivers/gpu/drm/meson/Makefile -index 92cf845..c5c4cc3 100644 ---- a/drivers/gpu/drm/meson/Makefile -+++ b/drivers/gpu/drm/meson/Makefile -@@ -2,3 +2,4 @@ meson-drm-y := meson_drv.o meson_plane.o meson_crtc.o meson_venc_cvbs.o - meson-drm-y += meson_viu.o meson_vpp.o meson_venc.o meson_vclk.o meson_canvas.o - - obj-$(CONFIG_DRM_MESON) += meson-drm.o -+obj-$(CONFIG_DRM_MESON_DW_HDMI) += meson_dw_hdmi.o -diff --git a/drivers/gpu/drm/meson/meson_drv.h b/drivers/gpu/drm/meson/meson_drv.h -index 6195327..5e8b392 100644 ---- a/drivers/gpu/drm/meson/meson_drv.h -+++ b/drivers/gpu/drm/meson/meson_drv.h -@@ -47,6 +47,9 @@ struct meson_drm { - - struct { - unsigned int current_mode; -+ bool hdmi_repeat; -+ bool venc_repeat; -+ bool hdmi_use_enci; - } venc; - }; - -diff --git a/drivers/gpu/drm/meson/meson_dw_hdmi.c b/drivers/gpu/drm/meson/meson_dw_hdmi.c -new file mode 100644 -index 0000000..8851dcb ---- /dev/null -+++ b/drivers/gpu/drm/meson/meson_dw_hdmi.c -@@ -0,0 +1,910 @@ -+/* -+ * Copyright (C) 2016 BayLibre, SAS -+ * Author: Neil Armstrong -+ * Copyright (C) 2015 Amlogic, Inc. All rights reserved. -+ * -+ * This program is free software; you can redistribute it and/or -+ * modify it under the terms of the GNU General Public License as -+ * published by the Free Software Foundation; either version 2 of the -+ * License, or (at your option) any later version. -+ * -+ * This program is distributed in the hope that it will be useful, but -+ * WITHOUT ANY WARRANTY; without even the implied warranty of -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -+ * General Public License for more details. -+ * -+ * You should have received a copy of the GNU General Public License -+ * along with this program; if not, see . -+ */ -+ -+#include -+#include -+#include -+#include -+#include -+#include -+ -+#include -+#include -+#include -+#include -+#include -+ -+#include -+#include -+ -+#include "meson_drv.h" -+#include "meson_venc.h" -+#include "meson_vclk.h" -+#include "meson_dw_hdmi.h" -+#include "meson_registers.h" -+ -+#define DRIVER_NAME "meson-dw-hdmi" -+#define DRIVER_DESC "Amlogic Meson HDMI-TX DRM driver" -+ -+/* -+ * HDMI Output is composed of : -+ * - A Synopsys DesignWare HDMI Controller IP -+ * - A TOP control block controlling the Clocks and PHY -+ * - A custom HDMI PHY in order convert video to TMDS signal -+ * ___________________________________ -+ * | HDMI TOP |<= HPD -+ * |___________________________________| -+ * | | | -+ * | Synopsys HDMI | HDMI PHY |=> TMDS -+ * | Controller |________________| -+ * |___________________________________|<=> DDC -+ * -+ * The HDMI TOP block only supports HPD sensing. -+ * The Synopsys HDMI Controller interrupt is routed -+ * through the TOP Block interrupt. -+ * Communication to the TOP Block and the Synopsys -+ * HDMI Controller is done a pair of addr+read/write -+ * registers. -+ * The HDMI PHY is configured by registers in the -+ * HHI register block. -+ * -+ * Pixel data arrives in 4:4:4 format from the VENC -+ * block and the VPU HDMI mux selects either the ENCI -+ * encoder for the 576i or 480i formats or the ENCP -+ * encoder for all the other formats including -+ * interlaced HD formats. -+ * The VENC uses a DVI encoder on top of the ENCI -+ * or ENCP encoders to generate DVI timings for the -+ * HDMI controller. -+ * -+ * GXBB, GXL and GXM embeds the Synopsys DesignWare -+ * HDMI TX IP version 2.01a with HDCP and I2C & S/PDIF -+ * audio source interfaces. -+ * -+ * We handle the following features : -+ * - HPD Rise & Fall interrupt -+ * - HDMI Controller Interrupt -+ * - HDMI PHY Init for 480i to 1080p60 -+ * - VENC & HDMI Clock setup for 480i to 1080p60 -+ * - VENC Mode setup for 480i to 1080p60 -+ * -+ * What is missing : -+ * - PHY, Clock and Mode setup for 2k && 4k modes -+ * - SDDC Scrambling mode for HDMI 2.0a -+ * - HDCP Setup -+ * - CEC Management -+ */ -+ -+/* TOP Block Communication Channel */ -+#define HDMITX_TOP_ADDR_REG 0x0 -+#define HDMITX_TOP_DATA_REG 0x4 -+#define HDMITX_TOP_CTRL_REG 0x8 -+ -+/* Controller Communication Channel */ -+#define HDMITX_DWC_ADDR_REG 0x10 -+#define HDMITX_DWC_DATA_REG 0x14 -+#define HDMITX_DWC_CTRL_REG 0x18 -+ -+/* HHI Registers */ -+#define HHI_MEM_PD_REG0 0x100 /* 0x40 */ -+#define HHI_HDMI_CLK_CNTL 0x1cc /* 0x73 */ -+#define HHI_HDMI_PHY_CNTL0 0x3a0 /* 0xe8 */ -+#define HHI_HDMI_PHY_CNTL1 0x3a4 /* 0xe9 */ -+#define HHI_HDMI_PHY_CNTL2 0x3a8 /* 0xea */ -+#define HHI_HDMI_PHY_CNTL3 0x3ac /* 0xeb */ -+ -+static DEFINE_SPINLOCK(reg_lock); -+ -+enum meson_venc_source { -+ MESON_VENC_SOURCE_NONE = 0, -+ MESON_VENC_SOURCE_ENCI = 1, -+ MESON_VENC_SOURCE_ENCP = 2, -+}; -+ -+struct meson_dw_hdmi { -+ struct drm_encoder encoder; -+ struct dw_hdmi_plat_data dw_plat_data; -+ struct meson_drm *priv; -+ struct device *dev; -+ void __iomem *hdmitx; -+ struct reset_control *hdmitx_apb; -+ struct reset_control *hdmitx_ctrl; -+ struct reset_control *hdmitx_phy; -+ struct clk *hdmi_pclk; -+ struct clk *venci_clk; -+ u32 irq_stat; -+}; -+#define encoder_to_meson_dw_hdmi(x) \ -+ container_of(x, struct meson_dw_hdmi, encoder) -+ -+static inline int dw_hdmi_is_compatible(struct meson_dw_hdmi *dw_hdmi, -+ const char *compat) -+{ -+ return of_device_is_compatible(dw_hdmi->dev->of_node, compat); -+} -+ -+/* PHY (via TOP bridge) and Controller dedicated register interface */ -+ -+static unsigned int dw_hdmi_top_read(struct meson_dw_hdmi *dw_hdmi, -+ unsigned int addr) -+{ -+ unsigned long flags; -+ unsigned int data; -+ -+ spin_lock_irqsave(®_lock, flags); -+ -+ /* ADDR must be written twice */ -+ writel(addr & 0xffff, dw_hdmi->hdmitx + HDMITX_TOP_ADDR_REG); -+ writel(addr & 0xffff, dw_hdmi->hdmitx + HDMITX_TOP_ADDR_REG); -+ -+ /* Read needs a second DATA read */ -+ data = readl(dw_hdmi->hdmitx + HDMITX_TOP_DATA_REG); -+ data = readl(dw_hdmi->hdmitx + HDMITX_TOP_DATA_REG); -+ -+ spin_unlock_irqrestore(®_lock, flags); -+ -+ return data; -+} -+ -+static inline void dw_hdmi_top_write(struct meson_dw_hdmi *dw_hdmi, -+ unsigned int addr, unsigned int data) -+{ -+ unsigned long flags; -+ -+ spin_lock_irqsave(®_lock, flags); -+ -+ /* ADDR must be written twice */ -+ writel(addr & 0xffff, dw_hdmi->hdmitx + HDMITX_TOP_ADDR_REG); -+ writel(addr & 0xffff, dw_hdmi->hdmitx + HDMITX_TOP_ADDR_REG); -+ -+ /* Write needs single DATA write */ -+ writel(data, dw_hdmi->hdmitx + HDMITX_TOP_DATA_REG); -+ -+ spin_unlock_irqrestore(®_lock, flags); -+} -+ -+/* Helper to change specific bits in PHY registers */ -+static inline void dw_hdmi_top_write_bits(struct meson_dw_hdmi *dw_hdmi, -+ unsigned int addr, -+ unsigned int mask, -+ unsigned int val) -+{ -+ unsigned int data = dw_hdmi_top_read(dw_hdmi, addr); -+ -+ data &= ~mask; -+ data |= val; -+ -+ dw_hdmi_top_write(dw_hdmi, addr, data); -+} -+ -+static unsigned int dw_hdmi_dwc_read(struct meson_dw_hdmi *dw_hdmi, -+ unsigned int addr) -+{ -+ unsigned long flags; -+ unsigned int data; -+ -+ spin_lock_irqsave(®_lock, flags); -+ -+ /* ADDR must be written twice */ -+ writel(addr & 0xffff, dw_hdmi->hdmitx + HDMITX_DWC_ADDR_REG); -+ writel(addr & 0xffff, dw_hdmi->hdmitx + HDMITX_DWC_ADDR_REG); -+ -+ /* Read needs a second DATA read */ -+ data = readl(dw_hdmi->hdmitx + HDMITX_DWC_DATA_REG); -+ data = readl(dw_hdmi->hdmitx + HDMITX_DWC_DATA_REG); -+ -+ spin_unlock_irqrestore(®_lock, flags); -+ -+ return data; -+} -+ -+static inline void dw_hdmi_dwc_write(struct meson_dw_hdmi *dw_hdmi, -+ unsigned int addr, unsigned int data) -+{ -+ unsigned long flags; -+ -+ spin_lock_irqsave(®_lock, flags); -+ -+ /* ADDR must be written twice */ -+ writel(addr & 0xffff, dw_hdmi->hdmitx + HDMITX_DWC_ADDR_REG); -+ writel(addr & 0xffff, dw_hdmi->hdmitx + HDMITX_DWC_ADDR_REG); -+ -+ /* Write needs single DATA write */ -+ writel(data, dw_hdmi->hdmitx + HDMITX_DWC_DATA_REG); -+ -+ spin_unlock_irqrestore(®_lock, flags); -+} -+ -+/* Helper to change specific bits in controller registers */ -+static inline void dw_hdmi_dwc_write_bits(struct meson_dw_hdmi *dw_hdmi, -+ unsigned int addr, -+ unsigned int mask, -+ unsigned int val) -+{ -+ unsigned int data = dw_hdmi_dwc_read(dw_hdmi, addr); -+ -+ data &= ~mask; -+ data |= val; -+ -+ dw_hdmi_dwc_write(dw_hdmi, addr, data); -+} -+ -+/* Bridge */ -+ -+/* Setup PHY bandwidth modes */ -+static void meson_hdmi_phy_setup_mode(struct meson_dw_hdmi *dw_hdmi, -+ struct drm_display_mode *mode) -+{ -+ struct meson_drm *priv = dw_hdmi->priv; -+ unsigned int pixel_clock = mode->clock; -+ -+ if (dw_hdmi_is_compatible(dw_hdmi, "amlogic,meson-gxl-dw-hdmi") || -+ dw_hdmi_is_compatible(dw_hdmi, "amlogic,meson-gxm-dw-hdmi")) { -+ if (pixel_clock >= 371250) { -+ /* 5.94Gbps, 3.7125Gbps */ -+ regmap_write(priv->hhi, HHI_HDMI_PHY_CNTL0, 0x333d3282); -+ regmap_write(priv->hhi, HHI_HDMI_PHY_CNTL3, 0x2136315b); -+ } else if (pixel_clock >= 297000) { -+ /* 2.97Gbps */ -+ regmap_write(priv->hhi, HHI_HDMI_PHY_CNTL0, 0x33303382); -+ regmap_write(priv->hhi, HHI_HDMI_PHY_CNTL3, 0x2036315b); -+ } else if (pixel_clock >= 148500) { -+ /* 1.485Gbps */ -+ regmap_write(priv->hhi, HHI_HDMI_PHY_CNTL0, 0x33303362); -+ regmap_write(priv->hhi, HHI_HDMI_PHY_CNTL3, 0x2016315b); -+ } else { -+ /* 742.5Mbps, and below */ -+ regmap_write(priv->hhi, HHI_HDMI_PHY_CNTL0, 0x33604142); -+ regmap_write(priv->hhi, HHI_HDMI_PHY_CNTL3, 0x0016315b); -+ } -+ } else if (dw_hdmi_is_compatible(dw_hdmi, -+ "amlogic,meson-gxbb-dw-hdmi")) { -+ if (pixel_clock >= 371250) { -+ /* 5.94Gbps, 3.7125Gbps */ -+ regmap_write(priv->hhi, HHI_HDMI_PHY_CNTL0, 0x33353245); -+ regmap_write(priv->hhi, HHI_HDMI_PHY_CNTL3, 0x2100115b); -+ } else if (pixel_clock >= 297000) { -+ /* 2.97Gbps */ -+ regmap_write(priv->hhi, HHI_HDMI_PHY_CNTL0, 0x33634283); -+ regmap_write(priv->hhi, HHI_HDMI_PHY_CNTL3, 0xb000115b); -+ } else { -+ /* 1.485Gbps, and below */ -+ regmap_write(priv->hhi, HHI_HDMI_PHY_CNTL0, 0x33632122); -+ regmap_write(priv->hhi, HHI_HDMI_PHY_CNTL3, 0x2000115b); -+ } -+ } -+} -+ -+static inline void dw_hdmi_phy_reset(struct meson_dw_hdmi *dw_hdmi) -+{ -+ struct meson_drm *priv = dw_hdmi->priv; -+ -+ /* Enable and software reset */ -+ regmap_update_bits(priv->hhi, HHI_HDMI_PHY_CNTL1, 0xf, 0xf); -+ -+ mdelay(2); -+ -+ /* Enable and unreset */ -+ regmap_update_bits(priv->hhi, HHI_HDMI_PHY_CNTL1, 0xf, 0xe); -+ -+ mdelay(2); -+} -+ -+static void dw_hdmi_set_vclk(struct meson_dw_hdmi *dw_hdmi, -+ struct drm_display_mode *mode) -+{ -+ struct meson_drm *priv = dw_hdmi->priv; -+ int vic = drm_match_cea_mode(mode); -+ unsigned int vclk_freq; -+ unsigned int venc_freq; -+ unsigned int hdmi_freq; -+ -+ vclk_freq = mode->clock; -+ -+ if (mode->flags & DRM_MODE_FLAG_DBLCLK) -+ vclk_freq *= 2; -+ -+ venc_freq = vclk_freq; -+ hdmi_freq = vclk_freq; -+ -+ if (meson_venc_hdmi_venc_repeat(vic)) -+ venc_freq *= 2; -+ -+ vclk_freq = max(venc_freq, hdmi_freq); -+ -+ if (mode->flags & DRM_MODE_FLAG_DBLCLK) -+ venc_freq /= 2; -+ -+ DRM_DEBUG_DRIVER("vclk:%d venc=%d hdmi=%d enci=%d\n", -+ vclk_freq, venc_freq, hdmi_freq, -+ priv->venc.hdmi_use_enci); -+ -+ meson_vclk_setup(priv, MESON_VCLK_TARGET_HDMI, vclk_freq, -+ venc_freq, hdmi_freq, priv->venc.hdmi_use_enci); -+} -+ -+static int dw_hdmi_phy_init(struct dw_hdmi *hdmi, void *data, -+ struct drm_display_mode *mode) -+{ -+ struct meson_dw_hdmi *dw_hdmi = (struct meson_dw_hdmi *)data; -+ struct meson_drm *priv = dw_hdmi->priv; -+ unsigned int wr_clk = -+ readl_relaxed(priv->io_base + _REG(VPU_HDMI_SETTING)); -+ -+ DRM_DEBUG_DRIVER("%d:\"%s\"\n", mode->base.id, mode->name); -+ -+ /* Enable clocks */ -+ regmap_update_bits(priv->hhi, HHI_HDMI_CLK_CNTL, 0xffff, 0x100); -+ -+ /* Bring HDMITX MEM output of power down */ -+ regmap_update_bits(priv->hhi, HHI_MEM_PD_REG0, 0xff << 8, 0); -+ -+ /* Bring out of reset */ -+ dw_hdmi_top_write(dw_hdmi, HDMITX_TOP_SW_RESET, 0); -+ -+ /* Enable internal pixclk, tmds_clk, spdif_clk, i2s_clk, cecclk */ -+ dw_hdmi_top_write_bits(dw_hdmi, HDMITX_TOP_CLK_CNTL, -+ 0x3, 0x3); -+ dw_hdmi_top_write_bits(dw_hdmi, HDMITX_TOP_CLK_CNTL, -+ 0x3 << 4, 0x3 << 4); -+ -+ /* Enable normal output to PHY */ -+ dw_hdmi_top_write(dw_hdmi, HDMITX_TOP_BIST_CNTL, BIT(12)); -+ -+ /* TMDS pattern setup (TOFIX pattern for 4k2k scrambling) */ -+ dw_hdmi_top_write(dw_hdmi, HDMITX_TOP_TMDS_CLK_PTTN_01, 0x001f001f); -+ dw_hdmi_top_write(dw_hdmi, HDMITX_TOP_TMDS_CLK_PTTN_23, 0x001f001f); -+ -+ /* Load TMDS pattern */ -+ dw_hdmi_top_write(dw_hdmi, HDMITX_TOP_TMDS_CLK_PTTN_CNTL, 0x1); -+ msleep(20); -+ dw_hdmi_top_write(dw_hdmi, HDMITX_TOP_TMDS_CLK_PTTN_CNTL, 0x2); -+ -+ /* Setup PHY parameters */ -+ meson_hdmi_phy_setup_mode(dw_hdmi, mode); -+ -+ /* Setup PHY */ -+ regmap_update_bits(priv->hhi, HHI_HDMI_PHY_CNTL1, -+ 0xffff << 16, 0x0390 << 16); -+ -+ /* BIT_INVERT */ -+ if (dw_hdmi_is_compatible(dw_hdmi, "amlogic,meson-gxl-dw-hdmi") || -+ dw_hdmi_is_compatible(dw_hdmi, "amlogic,meson-gxm-dw-hdmi")) -+ regmap_update_bits(priv->hhi, HHI_HDMI_PHY_CNTL1, -+ BIT(17), 0); -+ else -+ regmap_update_bits(priv->hhi, HHI_HDMI_PHY_CNTL1, -+ BIT(17), BIT(17)); -+ -+ /* Disable clock, fifo, fifo_wr */ -+ regmap_update_bits(priv->hhi, HHI_HDMI_PHY_CNTL1, 0xf, 0); -+ -+ msleep(100); -+ -+ /* Reset PHY 3 times in a row */ -+ dw_hdmi_phy_reset(dw_hdmi); -+ dw_hdmi_phy_reset(dw_hdmi); -+ dw_hdmi_phy_reset(dw_hdmi); -+ -+ /* Temporary Disable VENC video stream */ -+ if (priv->venc.hdmi_use_enci) -+ writel_relaxed(0, priv->io_base + _REG(ENCI_VIDEO_EN)); -+ else -+ writel_relaxed(0, priv->io_base + _REG(ENCP_VIDEO_EN)); -+ -+ /* Temporary Disable HDMI video stream to HDMI-TX */ -+ writel_bits_relaxed(0x3, 0, -+ priv->io_base + _REG(VPU_HDMI_SETTING)); -+ writel_bits_relaxed(0xf << 8, 0, -+ priv->io_base + _REG(VPU_HDMI_SETTING)); -+ -+ /* Re-Enable VENC video stream */ -+ if (priv->venc.hdmi_use_enci) -+ writel_relaxed(1, priv->io_base + _REG(ENCI_VIDEO_EN)); -+ else -+ writel_relaxed(1, priv->io_base + _REG(ENCP_VIDEO_EN)); -+ -+ /* Push back HDMI clock settings */ -+ writel_bits_relaxed(0xf << 8, wr_clk & (0xf << 8), -+ priv->io_base + _REG(VPU_HDMI_SETTING)); -+ -+ /* Enable and Select HDMI video source for HDMI-TX */ -+ if (priv->venc.hdmi_use_enci) -+ writel_bits_relaxed(0x3, MESON_VENC_SOURCE_ENCI, -+ priv->io_base + _REG(VPU_HDMI_SETTING)); -+ else -+ writel_bits_relaxed(0x3, MESON_VENC_SOURCE_ENCP, -+ priv->io_base + _REG(VPU_HDMI_SETTING)); -+ -+ return 0; -+} -+ -+static void dw_hdmi_phy_disable(struct dw_hdmi *hdmi, -+ void *data) -+{ -+ struct meson_dw_hdmi *dw_hdmi = (struct meson_dw_hdmi *)data; -+ struct meson_drm *priv = dw_hdmi->priv; -+ -+ DRM_DEBUG_DRIVER("\n"); -+ -+ regmap_write(priv->hhi, HHI_HDMI_PHY_CNTL0, 0); -+} -+ -+static enum drm_connector_status dw_hdmi_read_hpd(struct dw_hdmi *hdmi, -+ void *data) -+{ -+ struct meson_dw_hdmi *dw_hdmi = (struct meson_dw_hdmi *)data; -+ -+ return !!dw_hdmi_top_read(dw_hdmi, HDMITX_TOP_STAT0) ? -+ connector_status_connected : connector_status_disconnected; -+} -+ -+static void dw_hdmi_setup_hpd(struct dw_hdmi *hdmi, -+ void *data) -+{ -+ struct meson_dw_hdmi *dw_hdmi = (struct meson_dw_hdmi *)data; -+ -+ /* Setup HPD Filter */ -+ dw_hdmi_top_write(dw_hdmi, HDMITX_TOP_HPD_FILTER, -+ (0xa << 12) | 0xa0); -+ -+ /* Clear interrupts */ -+ dw_hdmi_top_write(dw_hdmi, HDMITX_TOP_INTR_STAT_CLR, -+ HDMITX_TOP_INTR_HPD_RISE | HDMITX_TOP_INTR_HPD_FALL); -+ -+ /* Unmask interrupts */ -+ dw_hdmi_top_write_bits(dw_hdmi, HDMITX_TOP_INTR_MASKN, -+ HDMITX_TOP_INTR_HPD_RISE | HDMITX_TOP_INTR_HPD_FALL, -+ HDMITX_TOP_INTR_HPD_RISE | HDMITX_TOP_INTR_HPD_FALL); -+} -+ -+static const struct dw_hdmi_phy_ops meson_dw_hdmi_phy_ops = { -+ .init = dw_hdmi_phy_init, -+ .disable = dw_hdmi_phy_disable, -+ .read_hpd = dw_hdmi_read_hpd, -+ .setup_hpd = dw_hdmi_setup_hpd, -+}; -+ -+static irqreturn_t dw_hdmi_top_irq(int irq, void *dev_id) -+{ -+ struct meson_dw_hdmi *dw_hdmi = dev_id; -+ u32 stat; -+ -+ stat = dw_hdmi_top_read(dw_hdmi, HDMITX_TOP_INTR_STAT); -+ dw_hdmi_top_write(dw_hdmi, HDMITX_TOP_INTR_STAT_CLR, stat); -+ -+ /* HPD Events, handle in the threaded interrupt handler */ -+ if (stat & (HDMITX_TOP_INTR_HPD_RISE | HDMITX_TOP_INTR_HPD_FALL)) { -+ dw_hdmi->irq_stat = stat; -+ return IRQ_WAKE_THREAD; -+ } -+ -+ /* HDMI Controller Interrupt */ -+ if (stat & 1) -+ return IRQ_NONE; -+ -+ /* TOFIX Handle HDCP Interrupts */ -+ -+ return IRQ_HANDLED; -+} -+ -+/* Threaded interrupt handler to manage HPD events */ -+static irqreturn_t dw_hdmi_top_thread_irq(int irq, void *dev_id) -+{ -+ struct meson_dw_hdmi *dw_hdmi = dev_id; -+ u32 stat = dw_hdmi->irq_stat; -+ -+ /* HPD Events */ -+ if (stat & (HDMITX_TOP_INTR_HPD_RISE | HDMITX_TOP_INTR_HPD_FALL)) { -+ bool hpd_connected = false; -+ -+ if (stat & HDMITX_TOP_INTR_HPD_RISE) -+ hpd_connected = true; -+ -+ dw_hdmi_setup_rx_sense(dw_hdmi->dev, hpd_connected, -+ hpd_connected); -+ -+ drm_helper_hpd_irq_event(dw_hdmi->encoder.dev); -+ } -+ -+ return IRQ_HANDLED; -+} -+ -+/* TOFIX Enable support for non-vic modes */ -+static enum drm_mode_status dw_hdmi_mode_valid(struct drm_connector *connector, -+ struct drm_display_mode *mode) -+{ -+ unsigned int vclk_freq; -+ unsigned int venc_freq; -+ unsigned int hdmi_freq; -+ int vic = drm_match_cea_mode(mode); -+ -+ DRM_DEBUG_DRIVER("Modeline %d:\"%s\" %d %d %d %d %d %d %d %d %d %d 0x%x 0x%x\n", -+ mode->base.id, mode->name, mode->vrefresh, mode->clock, -+ mode->hdisplay, mode->hsync_start, -+ mode->hsync_end, mode->htotal, -+ mode->vdisplay, mode->vsync_start, -+ mode->vsync_end, mode->vtotal, mode->type, mode->flags); -+ -+ /* For now, only accept VIC modes */ -+ if (!vic) -+ return MODE_BAD; -+ -+ /* For now, filter by supported VIC modes */ -+ if (!meson_venc_hdmi_supported_vic(vic)) -+ return MODE_BAD; -+ -+ vclk_freq = mode->clock; -+ -+ /* 480i/576i needs global pixel doubling */ -+ if (mode->flags & DRM_MODE_FLAG_DBLCLK) -+ vclk_freq *= 2; -+ -+ venc_freq = vclk_freq; -+ hdmi_freq = vclk_freq; -+ -+ /* VENC double pixels for 1080i and 720p modes */ -+ if (meson_venc_hdmi_venc_repeat(vic)) -+ venc_freq *= 2; -+ -+ vclk_freq = max(venc_freq, hdmi_freq); -+ -+ if (mode->flags & DRM_MODE_FLAG_DBLCLK) -+ venc_freq /= 2; -+ -+ dev_dbg(connector->dev->dev, "%s: vclk:%d venc=%d hdmi=%d\n", __func__, -+ vclk_freq, venc_freq, hdmi_freq); -+ -+ /* Finally filter by configurable vclk frequencies */ -+ switch (vclk_freq) { -+ case 54000: -+ case 74250: -+ case 148500: -+ case 297000: -+ case 594000: -+ return MODE_OK; -+ } -+ -+ return MODE_CLOCK_RANGE; -+} -+ -+/* Encoder */ -+ -+static void meson_venc_hdmi_encoder_destroy(struct drm_encoder *encoder) -+{ -+ drm_encoder_cleanup(encoder); -+} -+ -+static const struct drm_encoder_funcs meson_venc_hdmi_encoder_funcs = { -+ .destroy = meson_venc_hdmi_encoder_destroy, -+}; -+ -+static int meson_venc_hdmi_encoder_atomic_check(struct drm_encoder *encoder, -+ struct drm_crtc_state *crtc_state, -+ struct drm_connector_state *conn_state) -+{ -+ return 0; -+} -+ -+static void meson_venc_hdmi_encoder_disable(struct drm_encoder *encoder) -+{ -+ struct meson_dw_hdmi *dw_hdmi = encoder_to_meson_dw_hdmi(encoder); -+ struct meson_drm *priv = dw_hdmi->priv; -+ -+ DRM_DEBUG_DRIVER("\n"); -+ -+ writel_bits_relaxed(0x3, 0, -+ priv->io_base + _REG(VPU_HDMI_SETTING)); -+ -+ writel_relaxed(0, priv->io_base + _REG(ENCI_VIDEO_EN)); -+ writel_relaxed(0, priv->io_base + _REG(ENCP_VIDEO_EN)); -+} -+ -+static void meson_venc_hdmi_encoder_enable(struct drm_encoder *encoder) -+{ -+ struct meson_dw_hdmi *dw_hdmi = encoder_to_meson_dw_hdmi(encoder); -+ struct meson_drm *priv = dw_hdmi->priv; -+ -+ DRM_DEBUG_DRIVER("%s\n", priv->venc.hdmi_use_enci ? "VENCI" : "VENCP"); -+ -+ if (priv->venc.hdmi_use_enci) -+ writel_relaxed(1, priv->io_base + _REG(ENCI_VIDEO_EN)); -+ else -+ writel_relaxed(1, priv->io_base + _REG(ENCP_VIDEO_EN)); -+} -+ -+static void meson_venc_hdmi_encoder_mode_set(struct drm_encoder *encoder, -+ struct drm_display_mode *mode, -+ struct drm_display_mode *adjusted_mode) -+{ -+ struct meson_dw_hdmi *dw_hdmi = encoder_to_meson_dw_hdmi(encoder); -+ struct meson_drm *priv = dw_hdmi->priv; -+ int vic = drm_match_cea_mode(mode); -+ -+ DRM_DEBUG_DRIVER("%d:\"%s\" vic %d\n", -+ mode->base.id, mode->name, vic); -+ -+ /* Should have been filtered */ -+ if (!vic) -+ return; -+ -+ /* VENC + VENC-DVI Mode setup */ -+ meson_venc_hdmi_mode_set(priv, vic, mode); -+ -+ /* VCLK Set clock */ -+ dw_hdmi_set_vclk(dw_hdmi, mode); -+ -+ /* Setup YUV444 to HDMI-TX, no 10bit diphering */ -+ writel_relaxed(0, priv->io_base + _REG(VPU_HDMI_FMT_CTRL)); -+} -+ -+static const struct drm_encoder_helper_funcs -+ meson_venc_hdmi_encoder_helper_funcs = { -+ .atomic_check = meson_venc_hdmi_encoder_atomic_check, -+ .disable = meson_venc_hdmi_encoder_disable, -+ .enable = meson_venc_hdmi_encoder_enable, -+ .mode_set = meson_venc_hdmi_encoder_mode_set, -+}; -+ -+/* DW HDMI Regmap */ -+ -+static int meson_dw_hdmi_reg_read(void *context, unsigned int reg, -+ unsigned int *result) -+{ -+ *result = dw_hdmi_dwc_read(context, reg); -+ -+ return 0; -+ -+} -+ -+static int meson_dw_hdmi_reg_write(void *context, unsigned int reg, -+ unsigned int val) -+{ -+ dw_hdmi_dwc_write(context, reg, val); -+ -+ return 0; -+} -+ -+static const struct regmap_config meson_dw_hdmi_regmap_config = { -+ .reg_bits = 32, -+ .val_bits = 8, -+ .reg_read = meson_dw_hdmi_reg_read, -+ .reg_write = meson_dw_hdmi_reg_write, -+ .max_register = 0x10000, -+}; -+ -+static bool meson_hdmi_connector_is_available(struct device *dev) -+{ -+ struct device_node *ep, *remote; -+ -+ /* HDMI Connector is on the second port, first endpoint */ -+ ep = of_graph_get_endpoint_by_regs(dev->of_node, 1, 0); -+ if (!ep) -+ return false; -+ -+ /* If the endpoint node exists, consider it enabled */ -+ remote = of_graph_get_remote_port(ep); -+ if (remote) { -+ of_node_put(ep); -+ return true; -+ } -+ -+ of_node_put(ep); -+ of_node_put(remote); -+ -+ return false; -+} -+ -+static int meson_dw_hdmi_bind(struct device *dev, struct device *master, -+ void *data) -+{ -+ struct platform_device *pdev = to_platform_device(dev); -+ struct meson_dw_hdmi *meson_dw_hdmi; -+ struct drm_device *drm = data; -+ struct meson_drm *priv = drm->dev_private; -+ struct dw_hdmi_plat_data *dw_plat_data; -+ struct drm_encoder *encoder; -+ struct resource *res; -+ int irq; -+ int ret; -+ -+ DRM_DEBUG_DRIVER("\n"); -+ -+ if (!meson_hdmi_connector_is_available(dev)) { -+ dev_info(drm->dev, "HDMI Output connector not available\n"); -+ return -ENODEV; -+ } -+ -+ meson_dw_hdmi = devm_kzalloc(dev, sizeof(*meson_dw_hdmi), -+ GFP_KERNEL); -+ if (!meson_dw_hdmi) -+ return -ENOMEM; -+ -+ meson_dw_hdmi->priv = priv; -+ meson_dw_hdmi->dev = dev; -+ dw_plat_data = &meson_dw_hdmi->dw_plat_data; -+ encoder = &meson_dw_hdmi->encoder; -+ -+ meson_dw_hdmi->hdmitx_apb = devm_reset_control_get_exclusive(dev, -+ "hdmitx_apb"); -+ if (IS_ERR(meson_dw_hdmi->hdmitx_apb)) { -+ dev_err(dev, "Failed to get hdmitx_apb reset\n"); -+ return PTR_ERR(meson_dw_hdmi->hdmitx_apb); -+ } -+ -+ meson_dw_hdmi->hdmitx_ctrl = devm_reset_control_get_exclusive(dev, -+ "hdmitx"); -+ if (IS_ERR(meson_dw_hdmi->hdmitx_ctrl)) { -+ dev_err(dev, "Failed to get hdmitx reset\n"); -+ return PTR_ERR(meson_dw_hdmi->hdmitx_ctrl); -+ } -+ -+ meson_dw_hdmi->hdmitx_phy = devm_reset_control_get_exclusive(dev, -+ "hdmitx_phy"); -+ if (IS_ERR(meson_dw_hdmi->hdmitx_phy)) { -+ dev_err(dev, "Failed to get hdmitx_phy reset\n"); -+ return PTR_ERR(meson_dw_hdmi->hdmitx_phy); -+ } -+ -+ res = platform_get_resource(pdev, IORESOURCE_MEM, 0); -+ meson_dw_hdmi->hdmitx = devm_ioremap_resource(dev, res); -+ if (IS_ERR(meson_dw_hdmi->hdmitx)) -+ return PTR_ERR(meson_dw_hdmi->hdmitx); -+ -+ meson_dw_hdmi->hdmi_pclk = devm_clk_get(dev, "isfr"); -+ if (IS_ERR(meson_dw_hdmi->hdmi_pclk)) { -+ dev_err(dev, "Unable to get HDMI pclk\n"); -+ return PTR_ERR(meson_dw_hdmi->hdmi_pclk); -+ } -+ clk_prepare_enable(meson_dw_hdmi->hdmi_pclk); -+ -+ meson_dw_hdmi->venci_clk = devm_clk_get(dev, "venci"); -+ if (IS_ERR(meson_dw_hdmi->venci_clk)) { -+ dev_err(dev, "Unable to get venci clk\n"); -+ return PTR_ERR(meson_dw_hdmi->venci_clk); -+ } -+ clk_prepare_enable(meson_dw_hdmi->venci_clk); -+ -+ dw_plat_data->regm = devm_regmap_init(dev, NULL, meson_dw_hdmi, -+ &meson_dw_hdmi_regmap_config); -+ if (IS_ERR(dw_plat_data->regm)) -+ return PTR_ERR(dw_plat_data->regm); -+ -+ irq = platform_get_irq(pdev, 0); -+ if (irq < 0) { -+ dev_err(dev, "Failed to get hdmi top irq\n"); -+ return irq; -+ } -+ -+ ret = devm_request_threaded_irq(dev, irq, dw_hdmi_top_irq, -+ dw_hdmi_top_thread_irq, IRQF_SHARED, -+ "dw_hdmi_top_irq", meson_dw_hdmi); -+ if (ret) { -+ dev_err(dev, "Failed to request hdmi top irq\n"); -+ return ret; -+ } -+ -+ /* Encoder */ -+ -+ drm_encoder_helper_add(encoder, &meson_venc_hdmi_encoder_helper_funcs); -+ -+ ret = drm_encoder_init(drm, encoder, &meson_venc_hdmi_encoder_funcs, -+ DRM_MODE_ENCODER_TMDS, "meson_hdmi"); -+ if (ret) { -+ dev_err(priv->dev, "Failed to init HDMI encoder\n"); -+ return ret; -+ } -+ -+ encoder->possible_crtcs = BIT(0); -+ -+ DRM_DEBUG_DRIVER("encoder initialized\n"); -+ -+ /* Enable clocks */ -+ regmap_update_bits(priv->hhi, HHI_HDMI_CLK_CNTL, 0xffff, 0x100); -+ -+ /* Bring HDMITX MEM output of power down */ -+ regmap_update_bits(priv->hhi, HHI_MEM_PD_REG0, 0xff << 8, 0); -+ -+ /* Reset HDMITX APB & TX & PHY */ -+ reset_control_reset(meson_dw_hdmi->hdmitx_apb); -+ reset_control_reset(meson_dw_hdmi->hdmitx_ctrl); -+ reset_control_reset(meson_dw_hdmi->hdmitx_phy); -+ -+ /* Enable APB3 fail on error */ -+ writel_bits_relaxed(BIT(15), BIT(15), -+ meson_dw_hdmi->hdmitx + HDMITX_TOP_CTRL_REG); -+ writel_bits_relaxed(BIT(15), BIT(15), -+ meson_dw_hdmi->hdmitx + HDMITX_DWC_CTRL_REG); -+ -+ /* Bring out of reset */ -+ dw_hdmi_top_write(meson_dw_hdmi, HDMITX_TOP_SW_RESET, 0); -+ -+ msleep(20); -+ -+ dw_hdmi_top_write(meson_dw_hdmi, HDMITX_TOP_CLK_CNTL, 0xff); -+ -+ /* Enable HDMI-TX Interrupt */ -+ dw_hdmi_top_write(meson_dw_hdmi, HDMITX_TOP_INTR_STAT_CLR, -+ HDMITX_TOP_INTR_CORE); -+ -+ dw_hdmi_top_write(meson_dw_hdmi, HDMITX_TOP_INTR_MASKN, -+ HDMITX_TOP_INTR_CORE); -+ -+ /* Bridge / Connector */ -+ -+ dw_plat_data->mode_valid = dw_hdmi_mode_valid; -+ dw_plat_data->phy_ops = &meson_dw_hdmi_phy_ops; -+ dw_plat_data->phy_name = "meson_dw_hdmi_phy"; -+ dw_plat_data->phy_data = meson_dw_hdmi; -+ dw_plat_data->input_bus_format = MEDIA_BUS_FMT_YUV8_1X24; -+ dw_plat_data->input_bus_encoding = V4L2_YCBCR_ENC_709; -+ -+ ret = dw_hdmi_bind(pdev, encoder, &meson_dw_hdmi->dw_plat_data); -+ if (ret) -+ return ret; -+ -+ DRM_DEBUG_DRIVER("HDMI controller initialized\n"); -+ -+ return 0; -+} -+ -+static void meson_dw_hdmi_unbind(struct device *dev, struct device *master, -+ void *data) -+{ -+ dw_hdmi_unbind(dev); -+} -+ -+static const struct component_ops meson_dw_hdmi_ops = { -+ .bind = meson_dw_hdmi_bind, -+ .unbind = meson_dw_hdmi_unbind, -+}; -+ -+static int meson_dw_hdmi_probe(struct platform_device *pdev) -+{ -+ return component_add(&pdev->dev, &meson_dw_hdmi_ops); -+} -+ -+static int meson_dw_hdmi_remove(struct platform_device *pdev) -+{ -+ component_del(&pdev->dev, &meson_dw_hdmi_ops); -+ -+ return 0; -+} -+ -+static const struct of_device_id meson_dw_hdmi_of_table[] = { -+ { .compatible = "amlogic,meson-gxbb-dw-hdmi" }, -+ { .compatible = "amlogic,meson-gxl-dw-hdmi" }, -+ { .compatible = "amlogic,meson-gxm-dw-hdmi" }, -+ { } -+}; -+MODULE_DEVICE_TABLE(of, meson_dw_hdmi_of_table); -+ -+static struct platform_driver meson_dw_hdmi_platform_driver = { -+ .probe = meson_dw_hdmi_probe, -+ .remove = meson_dw_hdmi_remove, -+ .driver = { -+ .name = DRIVER_NAME, -+ .of_match_table = meson_dw_hdmi_of_table, -+ }, -+}; -+module_platform_driver(meson_dw_hdmi_platform_driver); -+ -+MODULE_AUTHOR("Neil Armstrong "); -+MODULE_DESCRIPTION(DRIVER_DESC); -+MODULE_LICENSE("GPL"); -diff --git a/drivers/gpu/drm/meson/meson_dw_hdmi.h b/drivers/gpu/drm/meson/meson_dw_hdmi.h -new file mode 100644 -index 0000000..0b81183 ---- /dev/null -+++ b/drivers/gpu/drm/meson/meson_dw_hdmi.h -@@ -0,0 +1,146 @@ -+/* -+ * Copyright (C) 2016 BayLibre, SAS -+ * Author: Neil Armstrong -+ * Copyright (C) 2015 Amlogic, Inc. All rights reserved. -+ * -+ * This program is free software; you can redistribute it and/or -+ * modify it under the terms of the GNU General Public License as -+ * published by the Free Software Foundation; either version 2 of the -+ * License, or (at your option) any later version. -+ * -+ * This program is distributed in the hope that it will be useful, but -+ * WITHOUT ANY WARRANTY; without even the implied warranty of -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -+ * General Public License for more details. -+ * -+ * You should have received a copy of the GNU General Public License -+ * along with this program; if not, see . -+ */ -+ -+#ifndef __MESON_DW_HDMI_H -+#define __MESON_DW_HDMI_H -+ -+/* -+ * Bit 7 RW Reserved. Default 1. -+ * Bit 6 RW Reserved. Default 1. -+ * Bit 5 RW Reserved. Default 1. -+ * Bit 4 RW sw_reset_phyif: PHY interface. 1=Apply reset; 0=Release from reset. -+ * Default 1. -+ * Bit 3 RW sw_reset_intr: interrupt module. 1=Apply reset; -+ * 0=Release from reset. -+ * Default 1. -+ * Bit 2 RW sw_reset_mem: KSV/REVOC mem. 1=Apply reset; 0=Release from reset. -+ * Default 1. -+ * Bit 1 RW sw_reset_rnd: random number interface to HDCP. 1=Apply reset; -+ * 0=Release from reset. Default 1. -+ * Bit 0 RW sw_reset_core: connects to IP's ~irstz. 1=Apply reset; -+ * 0=Release from reset. Default 1. -+ */ -+#define HDMITX_TOP_SW_RESET (0x000) -+ -+/* -+ * Bit 12 RW i2s_ws_inv:1=Invert i2s_ws; 0=No invert. Default 0. -+ * Bit 11 RW i2s_clk_inv: 1=Invert i2s_clk; 0=No invert. Default 0. -+ * Bit 10 RW spdif_clk_inv: 1=Invert spdif_clk; 0=No invert. Default 0. -+ * Bit 9 RW tmds_clk_inv: 1=Invert tmds_clk; 0=No invert. Default 0. -+ * Bit 8 RW pixel_clk_inv: 1=Invert pixel_clk; 0=No invert. Default 0. -+ * Bit 4 RW cec_clk_en: 1=enable cec_clk; 0=disable. Default 0. -+ * Bit 3 RW i2s_clk_en: 1=enable i2s_clk; 0=disable. Default 0. -+ * Bit 2 RW spdif_clk_en: 1=enable spdif_clk; 0=disable. Default 0. -+ * Bit 1 RW tmds_clk_en: 1=enable tmds_clk; 0=disable. Default 0. -+ * Bit 0 RW pixel_clk_en: 1=enable pixel_clk; 0=disable. Default 0. -+ */ -+#define HDMITX_TOP_CLK_CNTL (0x001) -+ -+/* -+ * Bit 11: 0 RW hpd_valid_width: filter out width <= M*1024. Default 0. -+ * Bit 15:12 RW hpd_glitch_width: filter out glitch <= N. Default 0. -+ */ -+#define HDMITX_TOP_HPD_FILTER (0x002) -+ -+/* -+ * intr_maskn: MASK_N, one bit per interrupt source. -+ * 1=Enable interrupt source; 0=Disable interrupt source. Default 0. -+ * [ 4] hdcp22_rndnum_err -+ * [ 3] nonce_rfrsh_rise -+ * [ 2] hpd_fall_intr -+ * [ 1] hpd_rise_intr -+ * [ 0] core_intr -+ */ -+#define HDMITX_TOP_INTR_MASKN (0x003) -+ -+/* -+ * Bit 30: 0 RW intr_stat: For each bit, write 1 to manually set the interrupt -+ * bit, read back the interrupt status. -+ * Bit 31 R IP interrupt status -+ * Bit 2 RW hpd_fall -+ * Bit 1 RW hpd_rise -+ * Bit 0 RW IP interrupt -+ */ -+#define HDMITX_TOP_INTR_STAT (0x004) -+ -+/* -+ * [4] hdcp22_rndnum_err -+ * [3] nonce_rfrsh_rise -+ * [2] hpd_fall -+ * [1] hpd_rise -+ * [0] core_intr_rise -+ */ -+#define HDMITX_TOP_INTR_STAT_CLR (0x005) -+ -+#define HDMITX_TOP_INTR_CORE BIT(0) -+#define HDMITX_TOP_INTR_HPD_RISE BIT(1) -+#define HDMITX_TOP_INTR_HPD_FALL BIT(2) -+ -+/* Bit 14:12 RW tmds_sel: 3'b000=Output zero; 3'b001=Output normal TMDS data; -+ * 3'b010=Output PRBS data; 3'b100=Output shift pattern. Default 0. -+ * Bit 11: 9 RW shift_pttn_repeat: 0=New pattern every clk cycle; 1=New pattern -+ * every 2 clk cycles; ...; 7=New pattern every 8 clk cycles. Default 0. -+ * Bit 8 RW shift_pttn_en: 1= Enable shift pattern generator; 0=Disable. -+ * Default 0. -+ * Bit 4: 3 RW prbs_pttn_mode: 0=PRBS11; 1=PRBS15; 2=PRBS7; 3=PRBS31. Default 0. -+ * Bit 2: 1 RW prbs_pttn_width: 0=idle; 1=output 8-bit pattern; -+ * 2=Output 1-bit pattern; 3=output 10-bit pattern. Default 0. -+ * Bit 0 RW prbs_pttn_en: 1=Enable PRBS generator; 0=Disable. Default 0. -+ */ -+#define HDMITX_TOP_BIST_CNTL (0x006) -+ -+/* Bit 29:20 RW shift_pttn_data[59:50]. Default 0. */ -+/* Bit 19:10 RW shift_pttn_data[69:60]. Default 0. */ -+/* Bit 9: 0 RW shift_pttn_data[79:70]. Default 0. */ -+#define HDMITX_TOP_SHIFT_PTTN_012 (0x007) -+ -+/* Bit 29:20 RW shift_pttn_data[29:20]. Default 0. */ -+/* Bit 19:10 RW shift_pttn_data[39:30]. Default 0. */ -+/* Bit 9: 0 RW shift_pttn_data[49:40]. Default 0. */ -+#define HDMITX_TOP_SHIFT_PTTN_345 (0x008) -+ -+/* Bit 19:10 RW shift_pttn_data[ 9: 0]. Default 0. */ -+/* Bit 9: 0 RW shift_pttn_data[19:10]. Default 0. */ -+#define HDMITX_TOP_SHIFT_PTTN_67 (0x009) -+ -+/* Bit 25:16 RW tmds_clk_pttn[19:10]. Default 0. */ -+/* Bit 9: 0 RW tmds_clk_pttn[ 9: 0]. Default 0. */ -+#define HDMITX_TOP_TMDS_CLK_PTTN_01 (0x00A) -+ -+/* Bit 25:16 RW tmds_clk_pttn[39:30]. Default 0. */ -+/* Bit 9: 0 RW tmds_clk_pttn[29:20]. Default 0. */ -+#define HDMITX_TOP_TMDS_CLK_PTTN_23 (0x00B) -+ -+/* Bit 1 RW shift_tmds_clk_pttn:1=Enable shifting clk pattern, -+ * used when TMDS CLK rate = TMDS character rate /4. Default 0. -+ * Bit 0 R Reserved. Default 0. -+ * [ 1] shift_tmds_clk_pttn -+ * [ 0] load_tmds_clk_pttn -+ */ -+#define HDMITX_TOP_TMDS_CLK_PTTN_CNTL (0x00C) -+ -+/* Bit 0 RW revocmem_wr_fail: Read back 1 to indicate Host write REVOC MEM -+ * failure, write 1 to clear the failure flag. Default 0. -+ */ -+#define HDMITX_TOP_REVOCMEM_STAT (0x00D) -+ -+/* Bit 0 R filtered HPD status. */ -+#define HDMITX_TOP_STAT0 (0x00E) -+ -+#endif /* __MESON_DW_HDMI_H */ --- -1.9.1 - diff --git a/patch/kernel/odroidc2-next/0055-clk-fix-CLK_SET_RATE_GATE-with-clock-rate-protection.patch b/patch/kernel/odroidc2-next/0055-clk-fix-CLK_SET_RATE_GATE-with-clock-rate-protection.patch new file mode 100644 index 000000000..8d4309b8c --- /dev/null +++ b/patch/kernel/odroidc2-next/0055-clk-fix-CLK_SET_RATE_GATE-with-clock-rate-protection.patch @@ -0,0 +1,56 @@ +From 62400daae8f31d68035f4c8e3ead19962b9ecde9 Mon Sep 17 00:00:00 2001 +From: Jerome Brunet +Date: Thu, 18 May 2017 15:36:38 +0200 +Subject: [PATCH 55/79] clk: fix CLK_SET_RATE_GATE with clock rate protection + +Using clock rate protection, we can now enforce CLK_SET_RATE_GATE along the +clock tree + +Signed-off-by: Jerome Brunet +Signed-off-by: Neil Armstrong +--- + drivers/clk/clk.c | 14 +++++++++++--- + 1 file changed, 11 insertions(+), 3 deletions(-) + +diff --git a/drivers/clk/clk.c b/drivers/clk/clk.c +index 5d54595..971f39d 100644 +--- a/drivers/clk/clk.c ++++ b/drivers/clk/clk.c +@@ -587,6 +587,9 @@ static void clk_core_unprepare(struct clk_core *core) + if (WARN_ON(core->prepare_count == 1 && core->flags & CLK_IS_CRITICAL)) + return; + ++ if (core->flags & CLK_SET_RATE_GATE) ++ clk_core_rate_unprotect(core); ++ + if (--core->prepare_count > 0) + return; + +@@ -657,6 +660,14 @@ static int clk_core_prepare(struct clk_core *core) + + core->prepare_count++; + ++ /* ++ * CLK_SET_RATE_GATE is a special case of clock protection ++ * Instead of a consumer protection, the provider is protecting ++ * itself when prepared ++ */ ++ if (core->flags & CLK_SET_RATE_GATE) ++ clk_core_rate_protect(core); ++ + return 0; + } + +@@ -1738,9 +1749,6 @@ static int clk_core_set_rate_nolock(struct clk_core *core, + if (clk_core_rate_is_protected(core)) + return -EBUSY; + +- if ((core->flags & CLK_SET_RATE_GATE) && core->prepare_count) +- return -EBUSY; +- + /* calculate new rates and get the topmost changed clock */ + top = clk_calc_new_rates(core, req_rate); + if (!top) +-- +1.9.1 + diff --git a/patch/kernel/odroidc2-next/0055-drm-meson-Convert-existing-documentation-to-actual-k.patch b/patch/kernel/odroidc2-next/0055-drm-meson-Convert-existing-documentation-to-actual-k.patch deleted file mode 100644 index 22e5beffe..000000000 --- a/patch/kernel/odroidc2-next/0055-drm-meson-Convert-existing-documentation-to-actual-k.patch +++ /dev/null @@ -1,250 +0,0 @@ -From f2dfb958c4d11d201619c9f5568de783c87d7ea0 Mon Sep 17 00:00:00 2001 -From: Neil Armstrong -Date: Fri, 3 Mar 2017 11:02:40 +0100 -Subject: [PATCH 55/93] drm/meson: Convert existing documentation to actual - kerneldoc - ---- - drivers/gpu/drm/meson/meson_canvas.c | 4 +++- - drivers/gpu/drm/meson/meson_drv.c | 5 +++-- - drivers/gpu/drm/meson/meson_dw_hdmi.c | 25 +++++++++++++++++-------- - drivers/gpu/drm/meson/meson_vclk.c | 22 +++++++++++++++------- - drivers/gpu/drm/meson/meson_venc.c | 25 ++++++++++++++++--------- - drivers/gpu/drm/meson/meson_viu.c | 6 +++++- - drivers/gpu/drm/meson/meson_vpp.c | 8 ++++++-- - 7 files changed, 65 insertions(+), 30 deletions(-) - -diff --git a/drivers/gpu/drm/meson/meson_canvas.c b/drivers/gpu/drm/meson/meson_canvas.c -index 4109e36..08f6073 100644 ---- a/drivers/gpu/drm/meson/meson_canvas.c -+++ b/drivers/gpu/drm/meson/meson_canvas.c -@@ -24,7 +24,9 @@ - #include "meson_canvas.h" - #include "meson_registers.h" - --/* -+/** -+ * DOC: Canvas -+ * - * CANVAS is a memory zone where physical memory frames information - * are stored for the VIU to scanout. - */ -diff --git a/drivers/gpu/drm/meson/meson_drv.c b/drivers/gpu/drm/meson/meson_drv.c -index 4b506d0..4c3422e 100644 ---- a/drivers/gpu/drm/meson/meson_drv.c -+++ b/drivers/gpu/drm/meson/meson_drv.c -@@ -52,13 +52,14 @@ - #define DRIVER_NAME "meson" - #define DRIVER_DESC "Amlogic Meson DRM driver" - --/* -- * Video Processing Unit -+/** -+ * DOC: Video Processing Unit - * - * VPU Handles the Global Video Processing, it includes management of the - * clocks gates, blocks reset lines and power domains. - * - * What is missing : -+ * - * - Full reset of entire video processing HW blocks - * - Scaling and setup of the VPU clock - * - Bus clock gates -diff --git a/drivers/gpu/drm/meson/meson_dw_hdmi.c b/drivers/gpu/drm/meson/meson_dw_hdmi.c -index 8851dcb..7b86eb7 100644 ---- a/drivers/gpu/drm/meson/meson_dw_hdmi.c -+++ b/drivers/gpu/drm/meson/meson_dw_hdmi.c -@@ -42,18 +42,25 @@ - #define DRIVER_NAME "meson-dw-hdmi" - #define DRIVER_DESC "Amlogic Meson HDMI-TX DRM driver" - --/* -+/** -+ * DOC: HDMI Output -+ * - * HDMI Output is composed of : -+ * - * - A Synopsys DesignWare HDMI Controller IP - * - A TOP control block controlling the Clocks and PHY - * - A custom HDMI PHY in order convert video to TMDS signal -- * ___________________________________ -- * | HDMI TOP |<= HPD -- * |___________________________________| -- * | | | -- * | Synopsys HDMI | HDMI PHY |=> TMDS -- * | Controller |________________| -- * |___________________________________|<=> DDC -+ * -+ * .. code:: -+ * -+ * ___________________________________ -+ * | HDMI TOP |<= HPD -+ * |___________________________________| -+ * | | | -+ * | Synopsys HDMI | HDMI PHY |=> TMDS -+ * | Controller |________________| -+ * |___________________________________|<=> DDC -+ * - * - * The HDMI TOP block only supports HPD sensing. - * The Synopsys HDMI Controller interrupt is routed -@@ -78,6 +85,7 @@ - * audio source interfaces. - * - * We handle the following features : -+ * - * - HPD Rise & Fall interrupt - * - HDMI Controller Interrupt - * - HDMI PHY Init for 480i to 1080p60 -@@ -85,6 +93,7 @@ - * - VENC Mode setup for 480i to 1080p60 - * - * What is missing : -+ * - * - PHY, Clock and Mode setup for 2k && 4k modes - * - SDDC Scrambling mode for HDMI 2.0a - * - HDCP Setup -diff --git a/drivers/gpu/drm/meson/meson_vclk.c b/drivers/gpu/drm/meson/meson_vclk.c -index 3731479..4767704 100644 ---- a/drivers/gpu/drm/meson/meson_vclk.c -+++ b/drivers/gpu/drm/meson/meson_vclk.c -@@ -23,21 +23,29 @@ - #include "meson_drv.h" - #include "meson_vclk.h" - --/* -+/** -+ * DOC: Video Clocks -+ * - * VCLK is the "Pixel Clock" frequency generator from a dedicated PLL. - * We handle the following encodings : -+ * - * - CVBS 27MHz generator via the VCLK2 to the VENCI and VDAC blocks - * - HDMI Pixel Clocks generation -+ * - * What is missing : -+ * - * - Genenate Pixel clocks for 2K/4K 10bit formats - * - * Clock generator scheme : -- * __________ _________ _____ -- * | | | | | |--ENCI -- * | HDMI PLL |-| PLL_DIV |--- VCLK--| |--ENCL -- * |__________| |_________| \ | MUX |--ENCP -- * --VCLK2-| |--VDAC -- * |_____|--HDMI-TX -+ * -+ * .. code:: -+ * -+ * __________ _________ _____ -+ * | | | | | |--ENCI -+ * | HDMI PLL |-| PLL_DIV |--- VCLK--| |--ENCL -+ * |__________| |_________| \ | MUX |--ENCP -+ * --VCLK2-| |--VDAC -+ * |_____|--HDMI-TX - * - * Final clocks can take input for either VCLK or VCLK2, but - * VCLK is the preferred path for HDMI clocking and VCLK2 is the -diff --git a/drivers/gpu/drm/meson/meson_venc.c b/drivers/gpu/drm/meson/meson_venc.c -index 31dc275..9509017 100644 ---- a/drivers/gpu/drm/meson/meson_venc.c -+++ b/drivers/gpu/drm/meson/meson_venc.c -@@ -26,26 +26,33 @@ - #include "meson_vclk.h" - #include "meson_registers.h" - --/* -+/** -+ * DOC: Video Encoder -+ * - * VENC Handle the pixels encoding to the output formats. - * We handle the following encodings : -+ * - * - CVBS Encoding via the ENCI encoder and VDAC digital to analog converter - * - TMDS/HDMI Encoding via ENCI_DIV and ENCP - * - Setup of more clock rates for HDMI modes - * - * What is missing : -+ * - * - LCD Panel encoding via ENCL - * - TV Panel encoding via ENCT - * - * VENC paths : -- * _____ _____ ____________________ -- * vd1---| |-| | | VENC /---------|----VDAC -- * vd2---| VIU |-| VPP |-|-----ENCI/-ENCI_DVI-|\ -- * osd1--| |-| | | \ | X--HDMI-TX -- * osd2--|_____|-|_____| | |\-ENCP--ENCP_DVI-|/ -- * | | | -- * | \--ENCL-----------|----LVDS -- * |____________________| -+ * -+ * .. code:: -+ * -+ * _____ _____ ____________________ -+ * vd1---| |-| | | VENC /---------|----VDAC -+ * vd2---| VIU |-| VPP |-|-----ENCI/-ENCI_DVI-|-| -+ * osd1--| |-| | | \ | X--HDMI-TX -+ * osd2--|_____|-|_____| | |\-ENCP--ENCP_DVI-|-| -+ * | | | -+ * | \--ENCL-----------|----LVDS -+ * |____________________| - * - * The ENCI is designed for PAl or NTSC encoding and can go through the VDAC - * directly for CVBS encoding or through the ENCI_DVI encoder for HDMI. -diff --git a/drivers/gpu/drm/meson/meson_viu.c b/drivers/gpu/drm/meson/meson_viu.c -index a6de8ba..6bcfa52 100644 ---- a/drivers/gpu/drm/meson/meson_viu.c -+++ b/drivers/gpu/drm/meson/meson_viu.c -@@ -28,9 +28,12 @@ - #include "meson_canvas.h" - #include "meson_registers.h" - --/* -+/** -+ * DOC: Video Input Unit -+ * - * VIU Handles the Pixel scanout and the basic Colorspace conversions - * We handle the following features : -+ * - * - OSD1 RGB565/RGB888/xRGB8888 scanout - * - RGB conversion to x/cb/cr - * - Progressive or Interlace buffer scanout -@@ -38,6 +41,7 @@ - * - HDR OSD matrix for GXL/GXM - * - * What is missing : -+ * - * - BGR888/xBGR8888/BGRx8888/BGRx8888 modes - * - YUV4:2:2 Y0CbY1Cr scanout - * - Conversion to YUV 4:4:4 from 4:2:2 input -diff --git a/drivers/gpu/drm/meson/meson_vpp.c b/drivers/gpu/drm/meson/meson_vpp.c -index 671909d..27356f8 100644 ---- a/drivers/gpu/drm/meson/meson_vpp.c -+++ b/drivers/gpu/drm/meson/meson_vpp.c -@@ -25,16 +25,20 @@ - #include "meson_vpp.h" - #include "meson_registers.h" - --/* -+/** -+ * DOC: Video Post Processing -+ * - * VPP Handles all the Post Processing after the Scanout from the VIU - * We handle the following post processings : -- * - Postblend : Blends the OSD1 only -+ * -+ * - Postblend, Blends the OSD1 only - * We exclude OSD2, VS1, VS1 and Preblend output - * - Vertical OSD Scaler for OSD1 only, we disable vertical scaler and - * use it only for interlace scanout - * - Intermediate FIFO with default Amlogic values - * - * What is missing : -+ * - * - Preblend for video overlay pre-scaling - * - OSD2 support for cursor framebuffer - * - Video pre-scaling before postblend --- -1.9.1 - diff --git a/patch/kernel/odroidc2-next/0056-ASoC-meson-protect-dai-output-clock-rates.patch b/patch/kernel/odroidc2-next/0056-ASoC-meson-protect-dai-output-clock-rates.patch new file mode 100644 index 000000000..06c2c3629 --- /dev/null +++ b/patch/kernel/odroidc2-next/0056-ASoC-meson-protect-dai-output-clock-rates.patch @@ -0,0 +1,59 @@ +From 73fcf1ce438f0952253ceee84e8a99510332a064 Mon Sep 17 00:00:00 2001 +From: Jerome Brunet +Date: Thu, 23 Mar 2017 12:00:17 +0100 +Subject: [PATCH 56/79] ASoC: meson: protect dai output clock rates + +Signed-off-by: Jerome Brunet +Signed-off-by: Neil Armstrong +--- + sound/soc/meson/i2s-dai.c | 4 ++++ + sound/soc/meson/spdif-dai.c | 4 ++++ + 2 files changed, 8 insertions(+) + +diff --git a/sound/soc/meson/i2s-dai.c b/sound/soc/meson/i2s-dai.c +index 1008af8..d698aa0 100644 +--- a/sound/soc/meson/i2s-dai.c ++++ b/sound/soc/meson/i2s-dai.c +@@ -351,6 +351,9 @@ static int meson_i2s_dai_startup(struct snd_pcm_substream *substream, + AIU_I2S_SOURCE_DESC_MODE_SPLIT, + AIU_I2S_SOURCE_DESC_MODE_SPLIT); + ++ /* We can't tolerate glitches or rate change on this clock */ ++ clk_rate_protect(priv->mclk); ++ + return 0; + + out_bclks: +@@ -368,6 +371,7 @@ static void meson_i2s_dai_shutdown(struct snd_pcm_substream *substream, + { + struct meson_i2s_dai *priv = snd_soc_dai_get_drvdata(dai); + ++ clk_rate_unprotect(priv->mclk); + clk_disable_unprepare(priv->bclks); + clk_disable_unprepare(priv->mclk); + clk_disable_unprepare(priv->iface); +diff --git a/sound/soc/meson/spdif-dai.c b/sound/soc/meson/spdif-dai.c +index e763000..1d27f19 100644 +--- a/sound/soc/meson/spdif-dai.c ++++ b/sound/soc/meson/spdif-dai.c +@@ -253,6 +253,9 @@ static int meson_spdif_dai_startup(struct snd_pcm_substream *substream, + AIU_MEM_IEC958_CONTROL_MODE_LINEAR, + AIU_MEM_IEC958_CONTROL_MODE_LINEAR); + ++ /* We can't tolerate glitches or rate change on this clock */ ++ clk_rate_protect(priv->mclk); ++ + return 0; + + out_mclk: +@@ -268,6 +271,7 @@ static void meson_spdif_dai_shutdown(struct snd_pcm_substream *substream, + { + struct meson_spdif_dai *priv = snd_soc_dai_get_drvdata(dai); + ++ clk_rate_unprotect(priv->mclk); + clk_disable_unprepare(priv->iface); + clk_disable_unprepare(priv->mclk); + clk_disable_unprepare(priv->fast); +-- +1.9.1 + diff --git a/patch/kernel/odroidc2-next/0056-media-uapi-Add-RGB-and-YUV-bus-formats-for-Synopsys-.patch b/patch/kernel/odroidc2-next/0056-media-uapi-Add-RGB-and-YUV-bus-formats-for-Synopsys-.patch deleted file mode 100644 index 72c3d04f9..000000000 --- a/patch/kernel/odroidc2-next/0056-media-uapi-Add-RGB-and-YUV-bus-formats-for-Synopsys-.patch +++ /dev/null @@ -1,66 +0,0 @@ -From e67e63eb718b887790d05491ee42da0bff571460 Mon Sep 17 00:00:00 2001 -From: Neil Armstrong -Date: Mon, 6 Mar 2017 12:06:35 +0100 -Subject: [PATCH 56/93] media: uapi: Add RGB and YUV bus formats for Synopsys - HDMI TX Controller - -In order to describe the RGB and YUV bus formats used to feed the -Synopsys DesignWare HDMI TX Controller, add missing formats to the -list of Bus Formats. - -Documentation for these formats is added in a separate patch. - -Reviewed-by: Archit Taneja -Signed-off-by: Neil Armstrong ---- - include/uapi/linux/media-bus-format.h | 13 +++++++++++-- - 1 file changed, 11 insertions(+), 2 deletions(-) - -diff --git a/include/uapi/linux/media-bus-format.h b/include/uapi/linux/media-bus-format.h -index 2168759..6c8f31c 100644 ---- a/include/uapi/linux/media-bus-format.h -+++ b/include/uapi/linux/media-bus-format.h -@@ -33,7 +33,7 @@ - - #define MEDIA_BUS_FMT_FIXED 0x0001 - --/* RGB - next is 0x1018 */ -+/* RGB - next is 0x101b */ - #define MEDIA_BUS_FMT_RGB444_1X12 0x1016 - #define MEDIA_BUS_FMT_RGB444_2X8_PADHI_BE 0x1001 - #define MEDIA_BUS_FMT_RGB444_2X8_PADHI_LE 0x1002 -@@ -57,8 +57,11 @@ - #define MEDIA_BUS_FMT_RGB888_1X7X4_JEIDA 0x1012 - #define MEDIA_BUS_FMT_ARGB8888_1X32 0x100d - #define MEDIA_BUS_FMT_RGB888_1X32_PADHI 0x100f -+#define MEDIA_BUS_FMT_RGB101010_1X30 0x1018 -+#define MEDIA_BUS_FMT_RGB121212_1X36 0x1019 -+#define MEDIA_BUS_FMT_RGB161616_1X48 0x101a - --/* YUV (including grey) - next is 0x2026 */ -+/* YUV (including grey) - next is 0x202c */ - #define MEDIA_BUS_FMT_Y8_1X8 0x2001 - #define MEDIA_BUS_FMT_UV8_1X8 0x2015 - #define MEDIA_BUS_FMT_UYVY8_1_5X8 0x2002 -@@ -90,12 +93,18 @@ - #define MEDIA_BUS_FMT_YVYU10_1X20 0x200e - #define MEDIA_BUS_FMT_VUY8_1X24 0x2024 - #define MEDIA_BUS_FMT_YUV8_1X24 0x2025 -+#define MEDIA_BUS_FMT_UYYVYY8_1X24 0x2026 - #define MEDIA_BUS_FMT_UYVY12_1X24 0x2020 - #define MEDIA_BUS_FMT_VYUY12_1X24 0x2021 - #define MEDIA_BUS_FMT_YUYV12_1X24 0x2022 - #define MEDIA_BUS_FMT_YVYU12_1X24 0x2023 - #define MEDIA_BUS_FMT_YUV10_1X30 0x2016 -+#define MEDIA_BUS_FMT_UYYVYY10_1X30 0x2027 - #define MEDIA_BUS_FMT_AYUV8_1X32 0x2017 -+#define MEDIA_BUS_FMT_UYYVYY12_1X36 0x2028 -+#define MEDIA_BUS_FMT_YUV12_1X36 0x2029 -+#define MEDIA_BUS_FMT_YUV16_1X48 0x202a -+#define MEDIA_BUS_FMT_UYYVYY16_1X48 0x202b - - /* Bayer - next is 0x3021 */ - #define MEDIA_BUS_FMT_SBGGR8_1X8 0x3001 --- -1.9.1 - diff --git a/patch/kernel/odroidc2-next/0084-snd-meson-add-hdmi-control-bits.patch b/patch/kernel/odroidc2-next/0057-snd-meson-add-hdmi-control-bits.patch similarity index 61% rename from patch/kernel/odroidc2-next/0084-snd-meson-add-hdmi-control-bits.patch rename to patch/kernel/odroidc2-next/0057-snd-meson-add-hdmi-control-bits.patch index e8dfd99f6..ba53a4a61 100644 --- a/patch/kernel/odroidc2-next/0084-snd-meson-add-hdmi-control-bits.patch +++ b/patch/kernel/odroidc2-next/0057-snd-meson-add-hdmi-control-bits.patch @@ -1,28 +1,26 @@ -From 613430ff3230d0aef2ea415c4b526f3c9521e492 Mon Sep 17 00:00:00 2001 +From a1619e301a0bdc1c90d505c740aeada54d229eaf Mon Sep 17 00:00:00 2001 From: Jerome Brunet -Date: Tue, 14 Feb 2017 19:09:24 +0100 -Subject: [PATCH 84/93] snd: meson: add hdmi control bits +Date: Fri, 7 Jul 2017 17:38:21 +0200 +Subject: [PATCH 57/79] snd: meson: add hdmi control bits -NOT READY FOR ML - -Signed-off-by: Jerome Brunet +Signed-off-by: Neil Armstrong --- - sound/soc/meson/aiu-i2s-dai.c | 11 +++++++++++ + sound/soc/meson/i2s-dai.c | 11 +++++++++++ 1 file changed, 11 insertions(+) -diff --git a/sound/soc/meson/aiu-i2s-dai.c b/sound/soc/meson/aiu-i2s-dai.c -index 6756848..1f9f3bf 100644 ---- a/sound/soc/meson/aiu-i2s-dai.c -+++ b/sound/soc/meson/aiu-i2s-dai.c -@@ -55,8 +55,19 @@ struct aiu_i2s_dai { +diff --git a/sound/soc/meson/i2s-dai.c b/sound/soc/meson/i2s-dai.c +index d698aa0..271bc14 100644 +--- a/sound/soc/meson/i2s-dai.c ++++ b/sound/soc/meson/i2s-dai.c +@@ -56,8 +56,19 @@ struct meson_i2s_dai { #define AIU_CLK_CTRL_ALRCLK_RIGHT_J (2 << 8) #define AIU_CLK_CTRL_MORE_I2S_DIV_MASK GENMASK(5, 0) - #define AIU_CLK_CTRL_MORE_I2S_DIV(div) ((div - 1) << 0) + #define AIU_CLK_CTRL_MORE_I2S_DIV(div) (((div) - 1) << 0) +#define AIU_CLK_CTRL_MORE_HDMI_TX_SEL_MASK BIT(6) +#define AIU_CLK_CTRL_MORE_HDMI_TX_I958_CLK (0 << 6) +#define AIU_CLK_CTRL_MORE_HDMI_TX_INT_CLK (1 << 6) #define AIU_CODEC_DAC_LRCLK_CTRL_DIV_MASK GENMASK(11, 0) - #define AIU_CODEC_DAC_LRCLK_CTRL_DIV(div) ((div - 1) << 0) + #define AIU_CODEC_DAC_LRCLK_CTRL_DIV(div) (((div) - 1) << 0) +#define AIU_HDMI_CLK_DATA_CTRL_CLK_SEL_MASK GENMASK(1, 0) +#define AIU_HDMI_CLK_DATA_CTRL_CLK_DISABLE (0 << 0) +#define AIU_HDMI_CLK_DATA_CTRL_CLK_PCM (1 << 0) diff --git a/patch/kernel/odroidc2-next/0058-pinctrl-meson-Add-HDMI-HPD-DDC-pins-functions.patch b/patch/kernel/odroidc2-next/0058-pinctrl-meson-Add-HDMI-HPD-DDC-pins-functions.patch deleted file mode 100644 index ccafc83d2..000000000 --- a/patch/kernel/odroidc2-next/0058-pinctrl-meson-Add-HDMI-HPD-DDC-pins-functions.patch +++ /dev/null @@ -1,117 +0,0 @@ -From 81da4e20eecc0e1f4447ebd245047d2683e34f2c Mon Sep 17 00:00:00 2001 -From: Neil Armstrong -Date: Mon, 9 Jan 2017 12:29:59 +0100 -Subject: [PATCH 58/93] pinctrl: meson: Add HDMI HPD/DDC pins functions - -Add pinctrl functions for HDMI HPD pin and DDC pins on Amlogic Meson -GXL and GXBB SoCs. ---- - drivers/pinctrl/meson/pinctrl-meson-gxbb.c | 19 +++++++++++++++++++ - drivers/pinctrl/meson/pinctrl-meson-gxl.c | 19 +++++++++++++++++++ - 2 files changed, 38 insertions(+) - -diff --git a/drivers/pinctrl/meson/pinctrl-meson-gxbb.c b/drivers/pinctrl/meson/pinctrl-meson-gxbb.c -index e0bca4d..7671424 100644 ---- a/drivers/pinctrl/meson/pinctrl-meson-gxbb.c -+++ b/drivers/pinctrl/meson/pinctrl-meson-gxbb.c -@@ -232,6 +232,10 @@ - static const unsigned int pwm_f_x_pins[] = { PIN(GPIOX_7, EE_OFF) }; - static const unsigned int pwm_f_y_pins[] = { PIN(GPIOY_15, EE_OFF) }; - -+static const unsigned int hdmi_hpd_pins[] = { PIN(GPIOH_0, EE_OFF) }; -+static const unsigned int hdmi_sda_pins[] = { PIN(GPIOH_1, EE_OFF) }; -+static const unsigned int hdmi_scl_pins[] = { PIN(GPIOH_2, EE_OFF) }; -+ - static const struct pinctrl_pin_desc meson_gxbb_aobus_pins[] = { - MESON_PIN(GPIOAO_0, 0), - MESON_PIN(GPIOAO_1, 0), -@@ -439,6 +443,11 @@ - GROUP(eth_txd2, 6, 3), - GROUP(eth_txd3, 6, 2), - -+ /* Bank H */ -+ GROUP(hdmi_hpd, 1, 26), -+ GROUP(hdmi_sda, 1, 25), -+ GROUP(hdmi_scl, 1, 24), -+ - /* Bank DV */ - GROUP(uart_tx_b, 2, 29), - GROUP(uart_rx_b, 2, 28), -@@ -635,6 +644,14 @@ - "pwm_f_y", - }; - -+static const char * const hdmi_hpd_groups[] = { -+ "hdmi_hpd", -+}; -+ -+static const char * const hdmi_i2c_groups[] = { -+ "hdmi_sda", "hdmi_scl", -+}; -+ - static const char * const gpio_aobus_groups[] = { - "GPIOAO_0", "GPIOAO_1", "GPIOAO_2", "GPIOAO_3", "GPIOAO_4", - "GPIOAO_5", "GPIOAO_6", "GPIOAO_7", "GPIOAO_8", "GPIOAO_9", -@@ -698,6 +715,8 @@ - FUNCTION(pwm_e), - FUNCTION(pwm_f_x), - FUNCTION(pwm_f_y), -+ FUNCTION(hdmi_hpd), -+ FUNCTION(hdmi_i2c), - }; - - static struct meson_pmx_func meson_gxbb_aobus_functions[] = { -diff --git a/drivers/pinctrl/meson/pinctrl-meson-gxl.c b/drivers/pinctrl/meson/pinctrl-meson-gxl.c -index b69743b..56b9324 100644 ---- a/drivers/pinctrl/meson/pinctrl-meson-gxl.c -+++ b/drivers/pinctrl/meson/pinctrl-meson-gxl.c -@@ -197,6 +197,10 @@ - - static const unsigned int pwm_e_pins[] = { PIN(GPIOX_16, EE_OFF) }; - -+static const unsigned int hdmi_hpd_pins[] = { PIN(GPIOH_0, EE_OFF) }; -+static const unsigned int hdmi_sda_pins[] = { PIN(GPIOH_1, EE_OFF) }; -+static const unsigned int hdmi_scl_pins[] = { PIN(GPIOH_2, EE_OFF) }; -+ - static const struct pinctrl_pin_desc meson_gxl_aobus_pins[] = { - MESON_PIN(GPIOAO_0, 0), - MESON_PIN(GPIOAO_1, 0), -@@ -362,6 +366,11 @@ - GROUP(eth_txd2, 4, 11), - GROUP(eth_txd3, 4, 10), - -+ /* Bank H */ -+ GROUP(hdmi_hpd, 6, 31), -+ GROUP(hdmi_sda, 6, 30), -+ GROUP(hdmi_scl, 6, 29), -+ - /* Bank DV */ - GROUP(uart_tx_b, 2, 16), - GROUP(uart_rx_b, 2, 15), -@@ -505,6 +514,14 @@ - "pwm_e", - }; - -+static const char * const hdmi_hpd_groups[] = { -+ "hdmi_hpd", -+}; -+ -+static const char * const hdmi_i2c_groups[] = { -+ "hdmi_sda", "hdmi_scl", -+}; -+ - static const char * const gpio_aobus_groups[] = { - "GPIOAO_0", "GPIOAO_1", "GPIOAO_2", "GPIOAO_3", "GPIOAO_4", - "GPIOAO_5", "GPIOAO_6", "GPIOAO_7", "GPIOAO_8", "GPIOAO_9", -@@ -536,6 +553,8 @@ - FUNCTION(i2c_c), - FUNCTION(eth), - FUNCTION(pwm_e), -+ FUNCTION(hdmi_hpd), -+ FUNCTION(hdmi_i2c), - }; - - static struct meson_pmx_func meson_gxl_aobus_functions[] = { --- -1.9.1 - diff --git a/patch/kernel/odroidc2-next/0058-snd-meson-activate-HDMI-audio-path.patch b/patch/kernel/odroidc2-next/0058-snd-meson-activate-HDMI-audio-path.patch new file mode 100644 index 000000000..ec93066c1 --- /dev/null +++ b/patch/kernel/odroidc2-next/0058-snd-meson-activate-HDMI-audio-path.patch @@ -0,0 +1,35 @@ +From 967a58cb6eeb223553058ea15083d755df70b5ec Mon Sep 17 00:00:00 2001 +From: Jerome Brunet +Date: Fri, 7 Jul 2017 17:39:21 +0200 +Subject: [PATCH 58/79] snd: meson: activate HDMI audio path + +Signed-off-by: Neil Armstrong +--- + sound/soc/meson/i2s-dai.c | 11 +++++++++++ + 1 file changed, 11 insertions(+) + +diff --git a/sound/soc/meson/i2s-dai.c b/sound/soc/meson/i2s-dai.c +index 271bc14..85a5023 100644 +--- a/sound/soc/meson/i2s-dai.c ++++ b/sound/soc/meson/i2s-dai.c +@@ -232,6 +232,17 @@ static int meson_i2s_dai_hw_params(struct snd_pcm_substream *substream, + return ret; + } + ++ /* Quick and dirty hack for HDMI */ ++ regmap_update_bits(priv->core->aiu, AIU_HDMI_CLK_DATA_CTRL, ++ AIU_HDMI_CLK_DATA_CTRL_CLK_SEL_MASK | ++ AIU_HDMI_CLK_DATA_CTRL_DATA_SEL_MASK, ++ AIU_HDMI_CLK_DATA_CTRL_CLK_I2S | ++ AIU_HDMI_CLK_DATA_CTRL_DATA_I2S); ++ ++ regmap_update_bits(priv->core->aiu, AIU_CLK_CTRL_MORE, ++ AIU_CLK_CTRL_MORE_HDMI_TX_SEL_MASK, ++ AIU_CLK_CTRL_MORE_HDMI_TX_INT_CLK); ++ + return 0; + } + +-- +1.9.1 + diff --git a/patch/kernel/odroidc2-next/0059-ARM64-dts-meson-gx-Add-HDMI-HPD-DDC-pinctrl-nodes.patch b/patch/kernel/odroidc2-next/0059-ARM64-dts-meson-gx-Add-HDMI-HPD-DDC-pinctrl-nodes.patch deleted file mode 100644 index 6853b0d1a..000000000 --- a/patch/kernel/odroidc2-next/0059-ARM64-dts-meson-gx-Add-HDMI-HPD-DDC-pinctrl-nodes.patch +++ /dev/null @@ -1,65 +0,0 @@ -From 408bb76cae9d0dbd03cbee0bc374010b3ddadf83 Mon Sep 17 00:00:00 2001 -From: Neil Armstrong -Date: Fri, 13 Jan 2017 16:23:34 +0100 -Subject: [PATCH 59/93] ARM64: dts: meson-gx: Add HDMI HPD/DDC pinctrl nodes - -Add pinctrl nodes for HDMI HPD and DDC pins modes for Amlogic Meson GXL -and GXBB SoCs. ---- - arch/arm64/boot/dts/amlogic/meson-gxbb.dtsi | 14 ++++++++++++++ - arch/arm64/boot/dts/amlogic/meson-gxl.dtsi | 14 ++++++++++++++ - 2 files changed, 28 insertions(+) - -diff --git a/arch/arm64/boot/dts/amlogic/meson-gxbb.dtsi b/arch/arm64/boot/dts/amlogic/meson-gxbb.dtsi -index bbb034d..ccbbdbc 100644 ---- a/arch/arm64/boot/dts/amlogic/meson-gxbb.dtsi -+++ b/arch/arm64/boot/dts/amlogic/meson-gxbb.dtsi -@@ -465,6 +465,20 @@ - function = "pwm_f_y"; - }; - }; -+ -+ hdmi_hpd_pins: hdmi_hpd { -+ mux { -+ groups = "hdmi_hpd"; -+ function = "hdmi_hpd"; -+ }; -+ }; -+ -+ hdmi_i2c_pins: hdmi_i2c { -+ mux { -+ groups = "hdmi_sda", "hdmi_scl"; -+ function = "hdmi_i2c"; -+ }; -+ }; - }; - }; - -diff --git a/arch/arm64/boot/dts/amlogic/meson-gxl.dtsi b/arch/arm64/boot/dts/amlogic/meson-gxl.dtsi -index 6921624..17dbcf6 100644 ---- a/arch/arm64/boot/dts/amlogic/meson-gxl.dtsi -+++ b/arch/arm64/boot/dts/amlogic/meson-gxl.dtsi -@@ -229,6 +229,20 @@ - function = "pwm_e"; - }; - }; -+ -+ hdmi_hpd_pins: hdmi_hpd { -+ mux { -+ groups = "hdmi_hpd"; -+ function = "hdmi_hpd"; -+ }; -+ }; -+ -+ hdmi_i2c_pins: hdmi_i2c { -+ mux { -+ groups = "hdmi_sda", "hdmi_scl"; -+ function = "hdmi_i2c"; -+ }; -+ }; - }; - - eth-phy-mux { --- -1.9.1 - diff --git a/patch/kernel/odroidc2-next/0059-ARM64-dts-meson-gx-Switch-p20x-and-p230-to-HDMI-outp.patch b/patch/kernel/odroidc2-next/0059-ARM64-dts-meson-gx-Switch-p20x-and-p230-to-HDMI-outp.patch new file mode 100644 index 000000000..74d5e2e94 --- /dev/null +++ b/patch/kernel/odroidc2-next/0059-ARM64-dts-meson-gx-Switch-p20x-and-p230-to-HDMI-outp.patch @@ -0,0 +1,153 @@ +From 47ca3bb9f820024cc182e0f46db659e59e3f6318 Mon Sep 17 00:00:00 2001 +From: Neil Armstrong +Date: Fri, 7 Jul 2017 17:47:31 +0200 +Subject: [PATCH 59/79] ARM64: dts: meson-gx: Switch p20x and p230 to HDMI + output only + +Signed-off-by: Neil Armstrong +--- + arch/arm64/boot/dts/amlogic/meson-gxbb-p20x.dtsi | 47 +--------------------- + .../boot/dts/amlogic/meson-gxl-s905d-p230.dts | 25 ++++++------ + 2 files changed, 14 insertions(+), 58 deletions(-) + +diff --git a/arch/arm64/boot/dts/amlogic/meson-gxbb-p20x.dtsi b/arch/arm64/boot/dts/amlogic/meson-gxbb-p20x.dtsi +index 88e3713..4ff313a 100644 +--- a/arch/arm64/boot/dts/amlogic/meson-gxbb-p20x.dtsi ++++ b/arch/arm64/boot/dts/amlogic/meson-gxbb-p20x.dtsi +@@ -153,31 +153,10 @@ + status = "okay"; + }; + +- amp: analog-amplifier { +- compatible = "dioo,dio2125"; +- enable-gpios = <&gpio GPIOH_3 0>; +- status = "okay"; +- }; +- +- spdif_out: spdif-out { +- #sound-dai-cells = <0>; +- compatible = "linux,spdif-dit"; +- status = "okay"; +- }; +- + soc { + sound { + compatible = "simple-audio-card"; + simple-audio-card,name = "meson-gxbb-p20x"; +- simple-audio-card,aux-devs = <&>; +- simple-audio-card,widgets = +- "Line", "Analog Left Output", +- "Line", "Analog Right Output"; +- simple-audio-card,routing = +- "Analog Left Output", "OUTL", +- "Analog Right Output", "OUTR", +- "INL", "AOUTL", +- "INR", "AOUTR"; + status = "okay"; + + simple-audio-card,dai-link@0 { +@@ -196,21 +175,7 @@ + }; + + codec { +- sound-dai = <&i2s_codec>; +- }; +- }; +- +- simple-audio-card,dai-link@1 { +- plat { +- sound-dai = <&aiu_spdif_dma>; +- }; +- +- cpu { +- sound-dai = <&spdif_dai>; +- }; +- +- codec { +- sound-dai = <&spdif_out>; ++ sound-dai = <&hdmi_tx>; + }; + }; + }; +@@ -352,19 +317,9 @@ + status = "okay"; + }; + +-&aiu_spdif_dma { +- status = "okay"; +-}; +- + &i2s_dai { + pinctrl-0 = <&i2s_am_clk_pins>, <&i2s_out_ao_clk_pins>, + <&i2s_out_lr_clk_pins>, <&i2s_out_ch01_ao_pins>; + pinctrl-names = "default"; + status = "okay"; + }; +- +-&spdif_dai { +- pinctrl-0 = <&spdif_out_ao_6_pins>; +- pinctrl-names = "default"; +- status = "okay"; +-}; +diff --git a/arch/arm64/boot/dts/amlogic/meson-gxl-s905d-p230.dts b/arch/arm64/boot/dts/amlogic/meson-gxl-s905d-p230.dts +index 5da5206..f95978c 100644 +--- a/arch/arm64/boot/dts/amlogic/meson-gxl-s905d-p230.dts ++++ b/arch/arm64/boot/dts/amlogic/meson-gxl-s905d-p230.dts +@@ -85,28 +85,28 @@ + regulator-max-microvolt = <1800000>; + }; + +- spdif_out: spdif-out { +- #sound-dai-cells = <0>; +- compatible = "linux,spdif-dit"; +- status = "okay"; +- }; +- + soc { + sound { + compatible = "simple-audio-card"; + simple-audio-card,name = "meson-gxl-p230"; + + simple-audio-card,dai-link@0 { ++ /* RCA Output */ ++ format = "i2s"; ++ mclk-fs = <256>; ++ bitclock-master = <&i2s_dai>; ++ frame-master = <&i2s_dai>; ++ + plat { +- sound-dai = <&aiu_spdif_dma>; ++ sound-dai = <&aiu_i2s_dma>; + }; + + cpu { +- sound-dai = <&spdif_dai>; ++ sound-dai = <&i2s_dai>; + }; + + codec { +- sound-dai = <&spdif_out>; ++ sound-dai = <&hdmi_tx>; + }; + }; + }; +@@ -156,12 +156,13 @@ + status = "okay"; + }; + +-&aiu_spdif_dma { ++&aiu_i2s_dma { + status = "okay"; + }; + +-&spdif_dai { +- pinctrl-0 = <&spdif_out_h_pins>; ++&i2s_dai { ++ pinctrl-0 = <&i2s_am_clk_pins>, <&i2s_out_ao_clk_pins>, ++ <&i2s_out_lr_clk_pins>, <&i2s_out_ch01_pins>; + pinctrl-names = "default"; + status = "okay"; + }; +-- +1.9.1 + diff --git a/patch/kernel/odroidc2-next/0060-ARM64-dts-meson-gxbb-odroic2-Add-HDMI-audio-output-n.patch b/patch/kernel/odroidc2-next/0060-ARM64-dts-meson-gxbb-odroic2-Add-HDMI-audio-output-n.patch new file mode 100644 index 000000000..4cf5b472b --- /dev/null +++ b/patch/kernel/odroidc2-next/0060-ARM64-dts-meson-gxbb-odroic2-Add-HDMI-audio-output-n.patch @@ -0,0 +1,71 @@ +From 2836b35f50d8027974c9fc9d258911243f4815e9 Mon Sep 17 00:00:00 2001 +From: Neil Armstrong +Date: Fri, 7 Jul 2017 17:47:47 +0200 +Subject: [PATCH 60/79] ARM64: dts: meson-gxbb-odroic2: Add HDMI audio output + nodes + +Signed-off-by: Neil Armstrong +--- + .../arm64/boot/dts/amlogic/meson-gxbb-odroidc2.dts | 42 ++++++++++++++++++++++ + 1 file changed, 42 insertions(+) + +diff --git a/arch/arm64/boot/dts/amlogic/meson-gxbb-odroidc2.dts b/arch/arm64/boot/dts/amlogic/meson-gxbb-odroidc2.dts +index 0066b1a..6c09bf7 100644 +--- a/arch/arm64/boot/dts/amlogic/meson-gxbb-odroidc2.dts ++++ b/arch/arm64/boot/dts/amlogic/meson-gxbb-odroidc2.dts +@@ -146,6 +146,33 @@ + }; + }; + }; ++ ++ soc { ++ sound { ++ compatible = "simple-audio-card"; ++ simple-audio-card,name = "meson-gxbb-odroidc2"; ++ status = "okay"; ++ ++ simple-audio-card,dai-link@0 { ++ format = "i2s"; ++ mclk-fs = <256>; ++ bitclock-master = <&i2s_dai>; ++ frame-master = <&i2s_dai>; ++ ++ plat { ++ sound-dai = <&aiu_i2s_dma>; ++ }; ++ ++ cpu { ++ sound-dai = <&i2s_dai>; ++ }; ++ ++ codec { ++ sound-dai = <&hdmi_tx>; ++ }; ++ }; ++ }; ++ }; + }; + + &scpi_clocks { +@@ -332,3 +359,18 @@ + remote-endpoint = <&hdmi_connector_in>; + }; + }; ++ ++&audio { ++ status = "okay"; ++}; ++ ++&aiu_i2s_dma { ++ status = "okay"; ++}; ++ ++&i2s_dai { ++ pinctrl-0 = <&i2s_am_clk_pins>, <&i2s_out_ao_clk_pins>, ++ <&i2s_out_lr_clk_pins>, <&i2s_out_ch01_ao_pins>; ++ pinctrl-names = "default"; ++ status = "okay"; ++}; +-- +1.9.1 + diff --git a/patch/kernel/odroidc2-next/0060-clk-meson-gxbb-Export-HDMI-clocks.patch b/patch/kernel/odroidc2-next/0060-clk-meson-gxbb-Export-HDMI-clocks.patch deleted file mode 100644 index 376f37159..000000000 --- a/patch/kernel/odroidc2-next/0060-clk-meson-gxbb-Export-HDMI-clocks.patch +++ /dev/null @@ -1,51 +0,0 @@ -From 0a0c298ca6a5ec9cfef16b7d2553adc1afdf5eb7 Mon Sep 17 00:00:00 2001 -From: Neil Armstrong -Date: Fri, 13 Jan 2017 16:03:43 +0100 -Subject: [PATCH 60/93] clk: meson-gxbb: Export HDMI clocks - -Export HDMI clock from internal to dt-bindings. ---- - drivers/clk/meson/gxbb.h | 4 ++-- - include/dt-bindings/clock/gxbb-clkc.h | 2 ++ - 2 files changed, 4 insertions(+), 2 deletions(-) - -diff --git a/drivers/clk/meson/gxbb.h b/drivers/clk/meson/gxbb.h -index f79ab57..15705d3 100644 ---- a/drivers/clk/meson/gxbb.h -+++ b/drivers/clk/meson/gxbb.h -@@ -231,7 +231,7 @@ - #define CLKID_AHB_DATA_BUS 60 - #define CLKID_AHB_CTRL_BUS 61 - #define CLKID_HDMI_INTR_SYNC 62 --#define CLKID_HDMI_PCLK 63 -+/* CLKID_HDMI_PCLK */ - /* CLKID_USB1_DDR_BRIDGE */ - /* CLKID_USB0_DDR_BRIDGE */ - #define CLKID_MMC_PCLK 66 -@@ -245,7 +245,7 @@ - #define CLKID_VCLK2_VENCI1 74 - #define CLKID_VCLK2_VENCP0 75 - #define CLKID_VCLK2_VENCP1 76 --#define CLKID_GCLK_VENCI_INT0 77 -+/* CLKID_GCLK_VENCI_INT0 */ - #define CLKID_GCLK_VENCI_INT 78 - #define CLKID_DAC_CLK 79 - #define CLKID_AOCLK_GATE 80 -diff --git a/include/dt-bindings/clock/gxbb-clkc.h b/include/dt-bindings/clock/gxbb-clkc.h -index 7bbc1d0..cfd7558 100644 ---- a/include/dt-bindings/clock/gxbb-clkc.h -+++ b/include/dt-bindings/clock/gxbb-clkc.h -@@ -19,8 +19,10 @@ - #define CLKID_USB0 50 - #define CLKID_USB1 51 - #define CLKID_USB 55 -+#define CLKID_HDMI_PCLK 63 - #define CLKID_USB1_DDR_BRIDGE 64 - #define CLKID_USB0_DDR_BRIDGE 65 -+#define CLKID_GCLK_VENCI_INT0 77 - #define CLKID_AO_I2C 93 - #define CLKID_SD_EMMC_A 94 - #define CLKID_SD_EMMC_B 95 --- -1.9.1 - diff --git a/patch/kernel/odroidc2-next/0061-ARM64-dts-meson-add-sound-dai-cells-to-HDMI-node.patch b/patch/kernel/odroidc2-next/0061-ARM64-dts-meson-add-sound-dai-cells-to-HDMI-node.patch new file mode 100644 index 000000000..1eb2c9f13 --- /dev/null +++ b/patch/kernel/odroidc2-next/0061-ARM64-dts-meson-add-sound-dai-cells-to-HDMI-node.patch @@ -0,0 +1,36 @@ +From 48620a0b478fbf467f86b7bf019e6a53a8eed08e Mon Sep 17 00:00:00 2001 +From: Neil Armstrong +Date: Fri, 7 Jul 2017 17:49:19 +0200 +Subject: [PATCH 61/79] ARM64: dts: meson: add sound-dai-cells to HDMI node + +Signed-off-by: Neil Armstrong +--- + arch/arm64/boot/dts/amlogic/meson-gxbb.dtsi | 1 + + arch/arm64/boot/dts/amlogic/meson-gxl.dtsi | 3 ++- + 2 files changed, 3 insertions(+), 1 deletion(-) + +diff --git a/arch/arm64/boot/dts/amlogic/meson-gxbb.dtsi b/arch/arm64/boot/dts/amlogic/meson-gxbb.dtsi +index 92d2b91..dc0eb44 100644 +--- a/arch/arm64/boot/dts/amlogic/meson-gxbb.dtsi ++++ b/arch/arm64/boot/dts/amlogic/meson-gxbb.dtsi +@@ -710,4 +710,5 @@ + <&clkc CLKID_CLK81>, + <&clkc CLKID_GCLK_VENCI_INT0>; + clock-names = "isfr", "iahb", "venci"; ++ #sound-dai-cells = <0>; + }; +diff --git a/arch/arm64/boot/dts/amlogic/meson-gxl.dtsi b/arch/arm64/boot/dts/amlogic/meson-gxl.dtsi +index de0a26b..1e65b0f 100644 +--- a/arch/arm64/boot/dts/amlogic/meson-gxl.dtsi ++++ b/arch/arm64/boot/dts/amlogic/meson-gxl.dtsi +@@ -660,5 +660,6 @@ + clocks = <&clkc CLKID_HDMI_PCLK>, + <&clkc CLKID_CLK81>, + <&clkc CLKID_GCLK_VENCI_INT0>; +- clock-names = "isfr", "iahb", "venci"; ++ clock-names = "isfr", "iahb", "venci", "iahb", "venci"; ++ #sound-dai-cells = <0>; + }; +-- +1.9.1 + diff --git a/patch/kernel/odroidc2-next/0061-ARM64-dts-meson-gx-Add-shared-CMA-dma-memory-pool.patch b/patch/kernel/odroidc2-next/0061-ARM64-dts-meson-gx-Add-shared-CMA-dma-memory-pool.patch deleted file mode 100644 index db3e3c0d9..000000000 --- a/patch/kernel/odroidc2-next/0061-ARM64-dts-meson-gx-Add-shared-CMA-dma-memory-pool.patch +++ /dev/null @@ -1,35 +0,0 @@ -From 366f348606cdabe13ccd20c34a6bded2463b925e Mon Sep 17 00:00:00 2001 -From: Neil Armstrong -Date: Fri, 13 Jan 2017 16:09:58 +0100 -Subject: [PATCH 61/93] ARM64: dts: meson-gx: Add shared CMA dma memory pool - -The HDMI modes needs more CMA memory to be reserved at boot-time. - -Conflicts: - arch/arm64/boot/dts/amlogic/meson-gx.dtsi ---- - arch/arm64/boot/dts/amlogic/meson-gx.dtsi | 8 ++++++++ - 1 file changed, 8 insertions(+) - -diff --git a/arch/arm64/boot/dts/amlogic/meson-gx.dtsi b/arch/arm64/boot/dts/amlogic/meson-gx.dtsi -index 0cbe24b..fc03f0e 100644 ---- a/arch/arm64/boot/dts/amlogic/meson-gx.dtsi -+++ b/arch/arm64/boot/dts/amlogic/meson-gx.dtsi -@@ -71,6 +71,14 @@ - reg = <0x0 0x10000000 0x0 0x200000>; - no-map; - }; -+ -+ linux,cma { -+ compatible = "shared-dma-pool"; -+ reusable; -+ size = <0x0 0xbc00000>; -+ alignment = <0x0 0x400000>; -+ linux,cma-default; -+ }; - }; - - cpus { --- -1.9.1 - diff --git a/patch/kernel/odroidc2-next/0062-ARM64-dts-meson-gx-Add-support-for-HDMI-output.patch b/patch/kernel/odroidc2-next/0062-ARM64-dts-meson-gx-Add-support-for-HDMI-output.patch deleted file mode 100644 index 8f91b3bb8..000000000 --- a/patch/kernel/odroidc2-next/0062-ARM64-dts-meson-gx-Add-support-for-HDMI-output.patch +++ /dev/null @@ -1,330 +0,0 @@ -From 19d55f4941ae9c08450cf891c7e1588616a54f17 Mon Sep 17 00:00:00 2001 -From: Neil Armstrong -Date: Mon, 9 Jan 2017 14:21:34 +0100 -Subject: [PATCH 62/93] ARM64: dts: meson-gx: Add support for HDMI output - -Add HDMI output and connector nodes. ---- - .../arm64/boot/dts/amlogic/meson-gx-p23x-q20x.dtsi | 39 ++++++++++++++++++++++ - arch/arm64/boot/dts/amlogic/meson-gx.dtsi | 32 ++++++++++++++++++ - .../boot/dts/amlogic/meson-gxbb-nexbox-a95x.dts | 23 +++++++++++++ - arch/arm64/boot/dts/amlogic/meson-gxbb-p20x.dtsi | 23 +++++++++++++ - arch/arm64/boot/dts/amlogic/meson-gxbb.dtsi | 12 +++++++ - .../boot/dts/amlogic/meson-gxl-nexbox-a95x.dts | 23 +++++++++++++ - arch/arm64/boot/dts/amlogic/meson-gxl.dtsi | 13 ++++++++ - .../arm64/boot/dts/amlogic/meson-gxm-nexbox-a1.dts | 23 +++++++++++++ - arch/arm64/boot/dts/amlogic/meson-gxm.dtsi | 4 +++ - 9 files changed, 192 insertions(+) - -diff --git a/arch/arm64/boot/dts/amlogic/meson-gx-p23x-q20x.dtsi b/arch/arm64/boot/dts/amlogic/meson-gx-p23x-q20x.dtsi -index 7a078be..a84e276 100644 ---- a/arch/arm64/boot/dts/amlogic/meson-gx-p23x-q20x.dtsi -+++ b/arch/arm64/boot/dts/amlogic/meson-gx-p23x-q20x.dtsi -@@ -98,6 +98,27 @@ - clocks = <&wifi32k>; - clock-names = "ext_clock"; - }; -+ -+ cvbs-connector { -+ compatible = "composite-video-connector"; -+ -+ port { -+ cvbs_connector_in: endpoint { -+ remote-endpoint = <&cvbs_vdac_out>; -+ }; -+ }; -+ }; -+ -+ hdmi-connector { -+ compatible = "hdmi-connector"; -+ type = "a"; -+ -+ port { -+ hdmi_connector_in: endpoint { -+ remote-endpoint = <&hdmi_tx_tmds_out>; -+ }; -+ }; -+ }; - }; - - /* This UART is brought out to the DB9 connector */ -@@ -188,3 +209,21 @@ - ðmac { - status = "okay"; - }; -+ -+&cvbs_vdac_port { -+ cvbs_vdac_out: endpoint { -+ remote-endpoint = <&cvbs_connector_in>; -+ }; -+}; -+ -+&hdmi_tx { -+ status = "okay"; -+ pinctrl-0 = <&hdmi_hpd_pins>, <&hdmi_i2c_pins>; -+ pinctrl-names = "default"; -+}; -+ -+&hdmi_tx_tmds_port { -+ hdmi_tx_tmds_out: endpoint { -+ remote-endpoint = <&hdmi_connector_in>; -+ }; -+}; -diff --git a/arch/arm64/boot/dts/amlogic/meson-gx.dtsi b/arch/arm64/boot/dts/amlogic/meson-gx.dtsi -index fc03f0e..ef0b17c 100644 ---- a/arch/arm64/boot/dts/amlogic/meson-gx.dtsi -+++ b/arch/arm64/boot/dts/amlogic/meson-gx.dtsi -@@ -397,6 +397,38 @@ - cvbs_vdac_port: port@0 { - reg = <0>; - }; -+ -+ /* HDMI-TX output port */ -+ hdmi_tx_port: port@1 { -+ reg = <1>; -+ -+ hdmi_tx_out: endpoint { -+ remote-endpoint = <&hdmi_tx_in>; -+ }; -+ }; -+ }; -+ -+ hdmi_tx: hdmi-tx@c883a000 { -+ compatible = "amlogic,meson-gx-dw-hdmi"; -+ reg = <0x0 0xc883a000 0x0 0x1c>; -+ interrupts = ; -+ #address-cells = <1>; -+ #size-cells = <0>; -+ status = "disabled"; -+ -+ /* VPU VENC Input */ -+ hdmi_tx_venc_port: port@0 { -+ reg = <0>; -+ -+ hdmi_tx_in: endpoint { -+ remote-endpoint = <&hdmi_tx_out>; -+ }; -+ }; -+ -+ /* TMDS Output */ -+ hdmi_tx_tmds_port: port@1 { -+ reg = <1>; -+ }; - }; - }; - }; -diff --git a/arch/arm64/boot/dts/amlogic/meson-gxbb-nexbox-a95x.dts b/arch/arm64/boot/dts/amlogic/meson-gxbb-nexbox-a95x.dts -index 4cbd626..a2c999f 100644 ---- a/arch/arm64/boot/dts/amlogic/meson-gxbb-nexbox-a95x.dts -+++ b/arch/arm64/boot/dts/amlogic/meson-gxbb-nexbox-a95x.dts -@@ -152,6 +152,17 @@ - }; - }; - }; -+ -+ hdmi-connector { -+ compatible = "hdmi-connector"; -+ type = "a"; -+ -+ port { -+ hdmi_connector_in: endpoint { -+ remote-endpoint = <&hdmi_tx_tmds_out>; -+ }; -+ }; -+ }; - }; - - &uart_AO { -@@ -245,3 +256,15 @@ - remote-endpoint = <&cvbs_connector_in>; - }; - }; -+ -+&hdmi_tx { -+ status = "okay"; -+ pinctrl-0 = <&hdmi_hpd_pins>, <&hdmi_i2c_pins>; -+ pinctrl-names = "default"; -+}; -+ -+&hdmi_tx_tmds_port { -+ hdmi_tx_tmds_out: endpoint { -+ remote-endpoint = <&hdmi_connector_in>; -+ }; -+}; -diff --git a/arch/arm64/boot/dts/amlogic/meson-gxbb-p20x.dtsi b/arch/arm64/boot/dts/amlogic/meson-gxbb-p20x.dtsi -index 4a96e0f..1c96fc8 100644 ---- a/arch/arm64/boot/dts/amlogic/meson-gxbb-p20x.dtsi -+++ b/arch/arm64/boot/dts/amlogic/meson-gxbb-p20x.dtsi -@@ -135,6 +135,17 @@ - }; - }; - }; -+ -+ hdmi-connector { -+ compatible = "hdmi-connector"; -+ type = "a"; -+ -+ port { -+ hdmi_connector_in: endpoint { -+ remote-endpoint = <&hdmi_tx_tmds_out>; -+ }; -+ }; -+ }; - }; - - /* This UART is brought out to the DB9 connector */ -@@ -250,3 +261,15 @@ - remote-endpoint = <&cvbs_connector_in>; - }; - }; -+ -+&hdmi_tx { -+ status = "okay"; -+ pinctrl-0 = <&hdmi_hpd_pins>, <&hdmi_i2c_pins>; -+ pinctrl-names = "default"; -+}; -+ -+&hdmi_tx_tmds_port { -+ hdmi_tx_tmds_out: endpoint { -+ remote-endpoint = <&hdmi_connector_in>; -+ }; -+}; -diff --git a/arch/arm64/boot/dts/amlogic/meson-gxbb.dtsi b/arch/arm64/boot/dts/amlogic/meson-gxbb.dtsi -index ccbbdbc..b897ad6 100644 ---- a/arch/arm64/boot/dts/amlogic/meson-gxbb.dtsi -+++ b/arch/arm64/boot/dts/amlogic/meson-gxbb.dtsi -@@ -563,3 +563,15 @@ - &vpu { - compatible = "amlogic,meson-gxbb-vpu", "amlogic,meson-gx-vpu"; - }; -+ -+&hdmi_tx { -+ compatible = "amlogic,meson-gxbb-dw-hdmi", "amlogic,meson-gx-dw-hdmi"; -+ resets = <&reset RESET_HDMITX_CAPB3>, -+ <&reset RESET_HDMI_SYSTEM_RESET>, -+ <&reset RESET_HDMI_TX>; -+ reset-names = "hdmitx_apb", "hdmitx", "hdmitx_phy"; -+ clocks = <&clkc CLKID_HDMI_PCLK>, -+ <&clkc CLKID_CLK81>, -+ <&clkc CLKID_GCLK_VENCI_INT0>; -+ clock-names = "isfr", "iahb", "venci"; -+}; -diff --git a/arch/arm64/boot/dts/amlogic/meson-gxl-nexbox-a95x.dts b/arch/arm64/boot/dts/amlogic/meson-gxl-nexbox-a95x.dts -index cea4a3e..8873c05 100644 ---- a/arch/arm64/boot/dts/amlogic/meson-gxl-nexbox-a95x.dts -+++ b/arch/arm64/boot/dts/amlogic/meson-gxl-nexbox-a95x.dts -@@ -127,6 +127,17 @@ - }; - }; - }; -+ -+ hdmi-connector { -+ compatible = "hdmi-connector"; -+ type = "a"; -+ -+ port { -+ hdmi_connector_in: endpoint { -+ remote-endpoint = <&hdmi_tx_tmds_out>; -+ }; -+ }; -+ }; - }; - - &uart_AO { -@@ -219,3 +230,15 @@ - remote-endpoint = <&cvbs_connector_in>; - }; - }; -+ -+&hdmi_tx { -+ status = "okay"; -+ pinctrl-0 = <&hdmi_hpd_pins>, <&hdmi_i2c_pins>; -+ pinctrl-names = "default"; -+}; -+ -+&hdmi_tx_tmds_port { -+ hdmi_tx_tmds_out: endpoint { -+ remote-endpoint = <&hdmi_connector_in>; -+ }; -+}; -diff --git a/arch/arm64/boot/dts/amlogic/meson-gxl.dtsi b/arch/arm64/boot/dts/amlogic/meson-gxl.dtsi -index 17dbcf6..bf26974 100644 ---- a/arch/arm64/boot/dts/amlogic/meson-gxl.dtsi -+++ b/arch/arm64/boot/dts/amlogic/meson-gxl.dtsi -@@ -44,6 +44,7 @@ - #include "meson-gx.dtsi" - #include - #include -+#include - - / { - compatible = "amlogic,meson-gxl"; -@@ -317,3 +318,15 @@ - &vpu { - compatible = "amlogic,meson-gxl-vpu", "amlogic,meson-gx-vpu"; - }; -+ -+&hdmi_tx { -+ compatible = "amlogic,meson-gxl-dw-hdmi", "amlogic,meson-gx-dw-hdmi"; -+ resets = <&reset RESET_HDMITX_CAPB3>, -+ <&reset RESET_HDMI_SYSTEM_RESET>, -+ <&reset RESET_HDMI_TX>; -+ reset-names = "hdmitx_apb", "hdmitx", "hdmitx_phy"; -+ clocks = <&clkc CLKID_HDMI_PCLK>, -+ <&clkc CLKID_CLK81>, -+ <&clkc CLKID_GCLK_VENCI_INT0>; -+ clock-names = "isfr", "iahb", "venci"; -+}; -diff --git a/arch/arm64/boot/dts/amlogic/meson-gxm-nexbox-a1.dts b/arch/arm64/boot/dts/amlogic/meson-gxm-nexbox-a1.dts -index 5a337d3..0e68c62e 100644 ---- a/arch/arm64/boot/dts/amlogic/meson-gxm-nexbox-a1.dts -+++ b/arch/arm64/boot/dts/amlogic/meson-gxm-nexbox-a1.dts -@@ -100,6 +100,17 @@ - }; - }; - }; -+ -+ hdmi-connector { -+ compatible = "hdmi-connector"; -+ type = "a"; -+ -+ port { -+ hdmi_connector_in: endpoint { -+ remote-endpoint = <&hdmi_tx_tmds_out>; -+ }; -+ }; -+ }; - }; - - /* This UART is brought out to the DB9 connector */ -@@ -183,3 +194,15 @@ - remote-endpoint = <&cvbs_connector_in>; - }; - }; -+ -+&hdmi_tx { -+ status = "okay"; -+ pinctrl-0 = <&hdmi_hpd_pins>, <&hdmi_i2c_pins>; -+ pinctrl-names = "default"; -+}; -+ -+&hdmi_tx_tmds_port { -+ hdmi_tx_tmds_out: endpoint { -+ remote-endpoint = <&hdmi_connector_in>; -+ }; -+}; -diff --git a/arch/arm64/boot/dts/amlogic/meson-gxm.dtsi b/arch/arm64/boot/dts/amlogic/meson-gxm.dtsi -index eb2f0c3..ac0fc02 100644 ---- a/arch/arm64/boot/dts/amlogic/meson-gxm.dtsi -+++ b/arch/arm64/boot/dts/amlogic/meson-gxm.dtsi -@@ -116,3 +116,7 @@ - &vpu { - compatible = "amlogic,meson-gxm-vpu", "amlogic,meson-gx-vpu"; - }; -+ -+&hdmi_tx { -+ compatible = "amlogic,meson-gxm-dw-hdmi", "amlogic,meson-gx-dw-hdmi"; -+}; --- -1.9.1 - diff --git a/patch/kernel/odroidc2-next/0062-clk-meson-gxbb-expose-spdif-clock-gates.patch b/patch/kernel/odroidc2-next/0062-clk-meson-gxbb-expose-spdif-clock-gates.patch new file mode 100644 index 000000000..da3996aac --- /dev/null +++ b/patch/kernel/odroidc2-next/0062-clk-meson-gxbb-expose-spdif-clock-gates.patch @@ -0,0 +1,60 @@ +From d3055f9a76aa28ac74515c802e25972c56ef00a7 Mon Sep 17 00:00:00 2001 +From: Jerome Brunet +Date: Thu, 2 Mar 2017 15:22:29 +0100 +Subject: [PATCH 62/79] clk: meson-gxbb: expose spdif clock gates + +Expose the clock gates required for the spdif output + +Acked-by: Michael Turquette +Signed-off-by: Jerome Brunet +Signed-off-by: Neil Armstrong +--- + drivers/clk/meson/gxbb.h | 4 ++-- + include/dt-bindings/clock/gxbb-clkc.h | 2 ++ + 2 files changed, 4 insertions(+), 2 deletions(-) + +diff --git a/drivers/clk/meson/gxbb.h b/drivers/clk/meson/gxbb.h +index 5c24285..53cf2cd 100644 +--- a/drivers/clk/meson/gxbb.h ++++ b/drivers/clk/meson/gxbb.h +@@ -209,7 +209,7 @@ + /* CLKID_ETH */ + #define CLKID_DEMUX 37 + /* CLKID_AIU_GLUE */ +-#define CLKID_IEC958 39 ++/* CLKID_IEC958 */ + /* CLKID_I2S_OUT */ + #define CLKID_AMCLK 41 + #define CLKID_AIFIFO2 42 +@@ -251,7 +251,7 @@ + #define CLKID_GCLK_VENCI_INT 78 + #define CLKID_DAC_CLK 79 + /* CLKID_AOCLK_GATE */ +-#define CLKID_IEC958_GATE 81 ++/* CLKID_IEC958_GATE */ + #define CLKID_ENC480P 82 + #define CLKID_RNG1 83 + #define CLKID_GCLK_VENCI_INT1 84 +diff --git a/include/dt-bindings/clock/gxbb-clkc.h b/include/dt-bindings/clock/gxbb-clkc.h +index ba8a9be..f195591 100644 +--- a/include/dt-bindings/clock/gxbb-clkc.h ++++ b/include/dt-bindings/clock/gxbb-clkc.h +@@ -20,6 +20,7 @@ + #define CLKID_I2S_SPDIF 35 + #define CLKID_ETH 36 + #define CLKID_AIU_GLUE 38 ++#define CLKID_IEC958 39 + #define CLKID_I2S_OUT 40 + #define CLKID_MIXER_IFACE 44 + #define CLKID_AIU 47 +@@ -32,6 +33,7 @@ + #define CLKID_SANA 69 + #define CLKID_GCLK_VENCI_INT0 77 + #define CLKID_AOCLK_GATE 80 ++#define CLKID_IEC958_GATE 81 + #define CLKID_AO_I2C 93 + #define CLKID_SD_EMMC_A 94 + #define CLKID_SD_EMMC_B 95 +-- +1.9.1 + diff --git a/patch/kernel/odroidc2-next/0063-clk-gxbb-put-dividers-and-muxes-in-tables.patch b/patch/kernel/odroidc2-next/0063-clk-gxbb-put-dividers-and-muxes-in-tables.patch deleted file mode 100644 index 605586850..000000000 --- a/patch/kernel/odroidc2-next/0063-clk-gxbb-put-dividers-and-muxes-in-tables.patch +++ /dev/null @@ -1,42 +0,0 @@ -From 411eb0d0f105ae0289753e0243a97410d4be9748 Mon Sep 17 00:00:00 2001 -From: Jerome Brunet -Date: Tue, 24 Jan 2017 15:12:31 +0100 -Subject: [PATCH 63/93] clk: gxbb: put dividers and muxes in tables - -Until now, there was only 1 divider and 1 mux declared for the gxbb -platform. With the ongoing work on audio this is about to change -Use the same approach as gates for dividers and muxes, putting them -in tables to fix the register address at runtime. - -Signed-off-by: Jerome Brunet - -Conflicts: - drivers/clk/meson/gxbb.c ---- - drivers/clk/meson/gxbb.c | 4 ++++ - 1 file changed, 4 insertions(+) - -diff --git a/drivers/clk/meson/gxbb.c b/drivers/clk/meson/gxbb.c -index d1dac0f..e17903b 100644 ---- a/drivers/clk/meson/gxbb.c -+++ b/drivers/clk/meson/gxbb.c -@@ -954,12 +954,16 @@ - &gxbb_mali_0_sel, - &gxbb_mali_1_sel, - &gxbb_mali, -+ &gxbb_mpeg_clk_sel, -+ &gxbb_sar_adc_clk_sel, - }; - - static struct clk_divider *gxbb_clk_dividers[] = { - &gxbb_mpeg_clk_div, - &gxbb_mali_0_div, - &gxbb_mali_1_div, -+ &gxbb_mpeg_clk_div, -+ &gxbb_sar_adc_clk_div, - }; - - struct gxbb_composite_clk { --- -1.9.1 - diff --git a/patch/kernel/odroidc2-next/0063-clk-meson-gxbb-expose-i2s-master-clock.patch b/patch/kernel/odroidc2-next/0063-clk-meson-gxbb-expose-i2s-master-clock.patch new file mode 100644 index 000000000..4e7e525e8 --- /dev/null +++ b/patch/kernel/odroidc2-next/0063-clk-meson-gxbb-expose-i2s-master-clock.patch @@ -0,0 +1,42 @@ +From 42e15ecdbae54a5dbc8f437b8fee24a54a4dfa2e Mon Sep 17 00:00:00 2001 +From: Jerome Brunet +Date: Thu, 26 Jan 2017 11:12:52 +0100 +Subject: [PATCH 63/79] clk: meson-gxbb: expose i2s master clock + +Expose cts_amclk in the device tree bindings + +Acked-by: Michael Turquette +Signed-off-by: Jerome Brunet +Signed-off-by: Neil Armstrong +--- + drivers/clk/meson/gxbb.h | 2 +- + include/dt-bindings/clock/gxbb-clkc.h | 1 + + 2 files changed, 2 insertions(+), 1 deletion(-) + +diff --git a/drivers/clk/meson/gxbb.h b/drivers/clk/meson/gxbb.h +index 53cf2cd..1673356 100644 +--- a/drivers/clk/meson/gxbb.h ++++ b/drivers/clk/meson/gxbb.h +@@ -277,7 +277,7 @@ + #define CLKID_MALI_1_DIV 104 + /* CLKID_MALI_1 */ + /* CLKID_MALI */ +-#define CLKID_CTS_AMCLK 107 ++/* CLKID_CTS_AMCLK */ + #define CLKID_CTS_AMCLK_SEL 108 + #define CLKID_CTS_AMCLK_DIV 109 + #define CLKID_CTS_MCLK_I958 110 +diff --git a/include/dt-bindings/clock/gxbb-clkc.h b/include/dt-bindings/clock/gxbb-clkc.h +index f195591..3ea941e 100644 +--- a/include/dt-bindings/clock/gxbb-clkc.h ++++ b/include/dt-bindings/clock/gxbb-clkc.h +@@ -45,5 +45,6 @@ + #define CLKID_MALI_1_SEL 103 + #define CLKID_MALI_1 105 + #define CLKID_MALI 106 ++#define CLKID_CTS_AMCLK 107 + + #endif /* __GXBB_CLKC_H */ +-- +1.9.1 + diff --git a/patch/kernel/odroidc2-next/0064-clk-meson-fix-SET_PARAM-macro.patch b/patch/kernel/odroidc2-next/0064-clk-meson-fix-SET_PARAM-macro.patch deleted file mode 100644 index 225e296d1..000000000 --- a/patch/kernel/odroidc2-next/0064-clk-meson-fix-SET_PARAM-macro.patch +++ /dev/null @@ -1,29 +0,0 @@ -From e372a783aeeb501b21a5d3d5a0a5d230395d09e1 Mon Sep 17 00:00:00 2001 -From: Jerome Brunet -Date: Mon, 13 Feb 2017 23:56:13 +0100 -Subject: [PATCH 64/93] clk: meson: fix SET_PARAM macro - -param val is not enclosed in parathesis which is buggy when given an -expression instead of simple value - -Signed-off-by: Jerome Brunet ---- - drivers/clk/meson/clkc.h | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/drivers/clk/meson/clkc.h b/drivers/clk/meson/clkc.h -index 22a6335..153b111 100644 ---- a/drivers/clk/meson/clkc.h -+++ b/drivers/clk/meson/clkc.h -@@ -25,7 +25,7 @@ - #define PARM_GET(width, shift, reg) \ - (((reg) & SETPMASK(width, shift)) >> (shift)) - #define PARM_SET(width, shift, reg, val) \ -- (((reg) & CLRPMASK(width, shift)) | (val << (shift))) -+ (((reg) & CLRPMASK(width, shift)) | ((val) << (shift))) - - #define MESON_PARM_APPLICABLE(p) (!!((p)->width)) - --- -1.9.1 - diff --git a/patch/kernel/odroidc2-next/0064-clk-meson-gxbb-expose-spdif-master-clock.patch b/patch/kernel/odroidc2-next/0064-clk-meson-gxbb-expose-spdif-master-clock.patch new file mode 100644 index 000000000..67f2c28f0 --- /dev/null +++ b/patch/kernel/odroidc2-next/0064-clk-meson-gxbb-expose-spdif-master-clock.patch @@ -0,0 +1,48 @@ +From ddb7ac031821c633bc4c3991b3b32a9111d0d412 Mon Sep 17 00:00:00 2001 +From: Jerome Brunet +Date: Thu, 2 Mar 2017 15:23:38 +0100 +Subject: [PATCH 64/79] clk: meson-gxbb: expose spdif master clock + +Expose the spdif master clock and the mux to select the appropriate spdif +clock parent depending on the data source. + +Acked-by: Michael Turquette +Signed-off-by: Jerome Brunet +Signed-off-by: Neil Armstrong +--- + drivers/clk/meson/gxbb.h | 4 ++-- + include/dt-bindings/clock/gxbb-clkc.h | 2 ++ + 2 files changed, 4 insertions(+), 2 deletions(-) + +diff --git a/drivers/clk/meson/gxbb.h b/drivers/clk/meson/gxbb.h +index 1673356..6ffa5d7 100644 +--- a/drivers/clk/meson/gxbb.h ++++ b/drivers/clk/meson/gxbb.h +@@ -280,10 +280,10 @@ + /* CLKID_CTS_AMCLK */ + #define CLKID_CTS_AMCLK_SEL 108 + #define CLKID_CTS_AMCLK_DIV 109 +-#define CLKID_CTS_MCLK_I958 110 ++/* CLKID_CTS_MCLK_I958 */ + #define CLKID_CTS_MCLK_I958_SEL 111 + #define CLKID_CTS_MCLK_I958_DIV 112 +-#define CLKID_CTS_I958 113 ++/* CLKID_CTS_I958 */ + + #define NR_CLKS 114 + +diff --git a/include/dt-bindings/clock/gxbb-clkc.h b/include/dt-bindings/clock/gxbb-clkc.h +index 3ea941e..855e518 100644 +--- a/include/dt-bindings/clock/gxbb-clkc.h ++++ b/include/dt-bindings/clock/gxbb-clkc.h +@@ -46,5 +46,7 @@ + #define CLKID_MALI_1 105 + #define CLKID_MALI 106 + #define CLKID_CTS_AMCLK 107 ++#define CLKID_CTS_MCLK_I958 110 ++#define CLKID_CTS_I958 113 + + #endif /* __GXBB_CLKC_H */ +-- +1.9.1 + diff --git a/patch/kernel/odroidc2-next/0065-Add-CEC-support-for-Odroid-C2.patch b/patch/kernel/odroidc2-next/0065-Add-CEC-support-for-Odroid-C2.patch new file mode 100644 index 000000000..4ac22e930 --- /dev/null +++ b/patch/kernel/odroidc2-next/0065-Add-CEC-support-for-Odroid-C2.patch @@ -0,0 +1,31 @@ +From b2e9388561f99c5ac8abc8de8b282f755fa43376 Mon Sep 17 00:00:00 2001 +From: Neil Armstrong +Date: Fri, 7 Jul 2017 18:08:36 +0200 +Subject: [PATCH 65/79] Add CEC support for Odroid-C2 + +Signed-off-by: Neil Armstrong +--- + arch/arm64/boot/dts/amlogic/meson-gxbb-odroidc2.dts | 7 +++++++ + 1 file changed, 7 insertions(+) + +diff --git a/arch/arm64/boot/dts/amlogic/meson-gxbb-odroidc2.dts b/arch/arm64/boot/dts/amlogic/meson-gxbb-odroidc2.dts +index 6c09bf7..b4f21d1 100644 +--- a/arch/arm64/boot/dts/amlogic/meson-gxbb-odroidc2.dts ++++ b/arch/arm64/boot/dts/amlogic/meson-gxbb-odroidc2.dts +@@ -348,6 +348,13 @@ + vqmmc-supply = <&vcc1v8>; + }; + ++&cec_AO { ++ status = "okay"; ++ pinctrl-0 = <&ao_cec_pins>; ++ pinctrl-names = "default"; ++ hdmi-phandle = <&hdmi_tx>; ++}; ++ + &hdmi_tx { + status = "okay"; + pinctrl-0 = <&hdmi_hpd_pins>, <&hdmi_i2c_pins>; +-- +1.9.1 + diff --git a/patch/kernel/odroidc2-next/0065-clk-meson-mpll-add-rw-operation.patch b/patch/kernel/odroidc2-next/0065-clk-meson-mpll-add-rw-operation.patch deleted file mode 100644 index 2c1859e09..000000000 --- a/patch/kernel/odroidc2-next/0065-clk-meson-mpll-add-rw-operation.patch +++ /dev/null @@ -1,291 +0,0 @@ -From ea9502e463beb9084ba48b6b47f5a95cf6eb50d1 Mon Sep 17 00:00:00 2001 -From: Jerome Brunet -Date: Wed, 18 Jan 2017 12:17:01 +0100 -Subject: [PATCH 65/93] clk: meson: mpll: add rw operation - -This patch adds the new callbacks to the meson-mpll driver to control -and set the pll rate. For this, we also need to the enable and sdm -enable bit, which are added to mpll data structure. - -Signed-off-by: Jerome Brunet ---- - drivers/clk/meson/clk-mpll.c | 152 +++++++++++++++++++++++++++++++++++++++++-- - drivers/clk/meson/clkc.h | 4 +- - drivers/clk/meson/gxbb.c | 30 +++++++++ - 3 files changed, 180 insertions(+), 6 deletions(-) - -diff --git a/drivers/clk/meson/clk-mpll.c b/drivers/clk/meson/clk-mpll.c -index 03af790..d4ba8cd 100644 ---- a/drivers/clk/meson/clk-mpll.c -+++ b/drivers/clk/meson/clk-mpll.c -@@ -64,16 +64,50 @@ - #include - #include "clkc.h" - --#define SDM_MAX 16384 -+#define SDM_DEN 16384 -+#define SDM_MIN 1 -+#define SDM_MAX 16383 -+#define N2_MIN 4 -+#define N2_MAX 127 - - #define to_meson_clk_mpll(_hw) container_of(_hw, struct meson_clk_mpll, hw) - -+static unsigned long rate_from_params(unsigned long parent_rate, -+ unsigned long sdm, -+ unsigned long n2) -+{ -+ return (parent_rate * SDM_DEN) / ((SDM_DEN * n2) + sdm); -+} -+ -+static void params_from_rate(unsigned long requested_rate, -+ unsigned long parent_rate, -+ unsigned long *sdm, -+ unsigned long *n2) -+{ -+ uint64_t div = parent_rate; -+ unsigned long rem = do_div(div, requested_rate); -+ -+ if(div < N2_MIN) { -+ *n2 = N2_MIN; -+ *sdm = SDM_MIN; -+ } else if (div > N2_MAX) { -+ *n2 = N2_MAX; -+ *sdm = SDM_MAX; -+ } else { -+ *n2 = div; -+ *sdm = DIV_ROUND_UP(rem * SDM_DEN, requested_rate); -+ if (*sdm < SDM_MIN) -+ *sdm = SDM_MIN; -+ else if (*sdm > SDM_MAX) -+ *sdm = SDM_MAX; -+ } -+} -+ - static unsigned long mpll_recalc_rate(struct clk_hw *hw, - unsigned long parent_rate) - { - struct meson_clk_mpll *mpll = to_meson_clk_mpll(hw); - struct parm *p; -- unsigned long rate = 0; - unsigned long reg, sdm, n2; - - p = &mpll->sdm; -@@ -84,11 +118,119 @@ static unsigned long mpll_recalc_rate(struct clk_hw *hw, - reg = readl(mpll->base + p->reg_off); - n2 = PARM_GET(p->width, p->shift, reg); - -- rate = (parent_rate * SDM_MAX) / ((SDM_MAX * n2) + sdm); -+ return rate_from_params(parent_rate, sdm, n2); -+} -+ -+static long mpll_round_rate(struct clk_hw *hw, -+ unsigned long rate, -+ unsigned long *parent_rate) -+{ -+ unsigned long sdm, n2; -+ -+ params_from_rate(rate, *parent_rate, &sdm, &n2); -+ return rate_from_params(*parent_rate, sdm, n2); -+} -+ -+static int mpll_set_rate(struct clk_hw *hw, -+ unsigned long rate, -+ unsigned long parent_rate) -+{ -+ struct meson_clk_mpll *mpll = to_meson_clk_mpll(hw); -+ struct parm *p; -+ unsigned long reg, sdm, n2; -+ unsigned long flags = 0; -+ -+ params_from_rate(rate, parent_rate, &sdm, &n2); -+ -+ if (mpll->lock) -+ spin_lock_irqsave(mpll->lock, flags); -+ else -+ __acquire(mpll->lock); -+ -+ p = &mpll->sdm; -+ reg = readl(mpll->base + p->reg_off); -+ reg = PARM_SET(p->width, p->shift, reg, sdm); -+ writel(reg, mpll->base + p->reg_off); -+ -+ p = &mpll->sdm_en; -+ reg = readl(mpll->base + p->reg_off); -+ reg = PARM_SET(p->width, p->shift, reg, 1); -+ writel(reg, mpll->base + p->reg_off); -+ -+ p = &mpll->n2; -+ reg = readl(mpll->base + p->reg_off); -+ reg = PARM_SET(p->width, p->shift, reg, n2); -+ writel(reg, mpll->base + p->reg_off); -+ -+ if (mpll->lock) -+ spin_unlock_irqrestore(mpll->lock, flags); -+ else -+ __release(mpll->lock); - -- return rate; -+ return 0; -+} -+ -+static void mpll_enable_core(struct clk_hw *hw, int enable) -+{ -+ struct meson_clk_mpll *mpll = to_meson_clk_mpll(hw); -+ struct parm *p; -+ unsigned long reg; -+ unsigned long flags = 0; -+ -+ if (mpll->lock) -+ spin_lock_irqsave(mpll->lock, flags); -+ else -+ __acquire(mpll->lock); -+ -+ p = &mpll->en; -+ reg = readl(mpll->base + p->reg_off); -+ reg = PARM_SET(p->width, p->shift, reg, enable ? 1 : 0); -+ writel(reg, mpll->base + p->reg_off); -+ -+ if (mpll->lock) -+ spin_unlock_irqrestore(mpll->lock, flags); -+ else -+ __release(mpll->lock); -+} -+ -+ -+static int mpll_enable(struct clk_hw *hw) -+{ -+ mpll_enable_core(hw, 1); -+ -+ return 0; -+} -+ -+static void mpll_disable(struct clk_hw *hw) -+{ -+ mpll_enable_core(hw, 0); -+} -+ -+static int mpll_is_enabled(struct clk_hw *hw) -+{ -+ struct meson_clk_mpll *mpll = to_meson_clk_mpll(hw); -+ struct parm *p; -+ unsigned long reg; -+ int en; -+ -+ p = &mpll->en; -+ reg = readl(mpll->base + p->reg_off); -+ en = PARM_GET(p->width, p->shift, reg); -+ -+ return en; - } - - const struct clk_ops meson_clk_mpll_ro_ops = { -- .recalc_rate = mpll_recalc_rate, -+ .recalc_rate = mpll_recalc_rate, -+ .round_rate = mpll_round_rate, -+ .is_enabled = mpll_is_enabled, -+}; -+ -+const struct clk_ops meson_clk_mpll_ops = { -+ .recalc_rate = mpll_recalc_rate, -+ .round_rate = mpll_round_rate, -+ .set_rate = mpll_set_rate, -+ .enable = mpll_enable, -+ .disable = mpll_disable, -+ .is_enabled = mpll_is_enabled, - }; -diff --git a/drivers/clk/meson/clkc.h b/drivers/clk/meson/clkc.h -index 153b111..ae38d69 100644 ---- a/drivers/clk/meson/clkc.h -+++ b/drivers/clk/meson/clkc.h -@@ -95,8 +95,9 @@ struct meson_clk_mpll { - struct clk_hw hw; - void __iomem *base; - struct parm sdm; -+ struct parm sdm_en; - struct parm n2; -- /* FIXME ssen gate control? */ -+ struct parm en; - spinlock_t *lock; - }; - -@@ -119,5 +120,6 @@ struct clk_gate _name = { \ - extern const struct clk_ops meson_clk_pll_ops; - extern const struct clk_ops meson_clk_cpu_ops; - extern const struct clk_ops meson_clk_mpll_ro_ops; -+extern const struct clk_ops meson_clk_mpll_ops; - - #endif /* __CLKC_H */ -diff --git a/drivers/clk/meson/gxbb.c b/drivers/clk/meson/gxbb.c -index e17903b..2f50a57 100644 ---- a/drivers/clk/meson/gxbb.c -+++ b/drivers/clk/meson/gxbb.c -@@ -458,11 +458,21 @@ - .shift = 0, - .width = 14, - }, -+ .sdm_en = { -+ .reg_off = HHI_MPLL_CNTL7, -+ .shift = 15, -+ .width = 1, -+ }, - .n2 = { - .reg_off = HHI_MPLL_CNTL7, - .shift = 16, - .width = 9, - }, -+ .en = { -+ .reg_off = HHI_MPLL_CNTL7, -+ .shift = 14, -+ .width = 1, -+ }, - .lock = &clk_lock, - .hw.init = &(struct clk_init_data){ - .name = "mpll0", -@@ -478,11 +488,21 @@ - .shift = 0, - .width = 14, - }, -+ .sdm_en = { -+ .reg_off = HHI_MPLL_CNTL8, -+ .shift = 15, -+ .width = 1, -+ }, - .n2 = { - .reg_off = HHI_MPLL_CNTL8, - .shift = 16, - .width = 9, - }, -+ .en = { -+ .reg_off = HHI_MPLL_CNTL8, -+ .shift = 14, -+ .width = 1, -+ }, - .lock = &clk_lock, - .hw.init = &(struct clk_init_data){ - .name = "mpll1", -@@ -498,11 +518,21 @@ - .shift = 0, - .width = 14, - }, -+ .sdm_en = { -+ .reg_off = HHI_MPLL_CNTL9, -+ .shift = 15, -+ .width = 1, -+ }, - .n2 = { - .reg_off = HHI_MPLL_CNTL9, - .shift = 16, - .width = 9, - }, -+ .en = { -+ .reg_off = HHI_MPLL_CNTL9, -+ .shift = 14, -+ .width = 1, -+ }, - .lock = &clk_lock, - .hw.init = &(struct clk_init_data){ - .name = "mpll2", --- -1.9.1 - diff --git a/patch/kernel/odroidc2-next/0066-ARM64-dts-meson-gxbb-wetek-play2-Add-HDMI-and-CVBS-N.patch b/patch/kernel/odroidc2-next/0066-ARM64-dts-meson-gxbb-wetek-play2-Add-HDMI-and-CVBS-N.patch new file mode 100644 index 000000000..be4f93100 --- /dev/null +++ b/patch/kernel/odroidc2-next/0066-ARM64-dts-meson-gxbb-wetek-play2-Add-HDMI-and-CVBS-N.patch @@ -0,0 +1,74 @@ +From c9e29370a25d38cce87f404328c2b47d5cda7ad7 Mon Sep 17 00:00:00 2001 +From: Neil Armstrong +Date: Thu, 8 Jun 2017 17:20:46 +0200 +Subject: [PATCH 66/79] ARM64: dts: meson-gxbb-wetek-play2: Add HDMI and CVBS + Nodes + +Add HDMI and CVBS nodes for the Wetek Play2 board. + +Signed-off-by: Neil Armstrong +--- + .../boot/dts/amlogic/meson-gxbb-wetek-play2.dts | 40 ++++++++++++++++++++++ + 1 file changed, 40 insertions(+) + +diff --git a/arch/arm64/boot/dts/amlogic/meson-gxbb-wetek-play2.dts b/arch/arm64/boot/dts/amlogic/meson-gxbb-wetek-play2.dts +index 743acb5..e76ac31 100644 +--- a/arch/arm64/boot/dts/amlogic/meson-gxbb-wetek-play2.dts ++++ b/arch/arm64/boot/dts/amlogic/meson-gxbb-wetek-play2.dts +@@ -85,6 +85,34 @@ + gpios = <&gpio_ao GPIOAO_3 GPIO_ACTIVE_LOW>; + }; + }; ++ ++ cvbs-connector { ++ compatible = "composite-video-connector"; ++ ++ port { ++ cvbs_connector_in: endpoint { ++ remote-endpoint = <&cvbs_vdac_out>; ++ }; ++ }; ++ }; ++ ++ hdmi-connector { ++ compatible = "hdmi-connector"; ++ type = "a"; ++ ++ port { ++ hdmi_connector_in: endpoint { ++ remote-endpoint = <&hdmi_tx_tmds_out>; ++ }; ++ }; ++ }; ++}; ++ ++ ++&cvbs_vdac_port { ++ cvbs_vdac_out: endpoint { ++ remote-endpoint = <&cvbs_connector_in>; ++ }; + }; + + ðmac { +@@ -113,6 +141,18 @@ + }; + }; + ++&hdmi_tx { ++ status = "okay"; ++ pinctrl-0 = <&hdmi_hpd_pins>, <&hdmi_i2c_pins>; ++ pinctrl-names = "default"; ++}; ++ ++&hdmi_tx_tmds_port { ++ hdmi_tx_tmds_out: endpoint { ++ remote-endpoint = <&hdmi_connector_in>; ++ }; ++}; ++ + &i2c_A { + status = "okay"; + pinctrl-0 = <&i2c_a_pins>; +-- +1.9.1 + diff --git a/patch/kernel/odroidc2-next/0066-clk-meson-gxbb-mpll-use-rw-operation.patch b/patch/kernel/odroidc2-next/0066-clk-meson-gxbb-mpll-use-rw-operation.patch deleted file mode 100644 index 3de9acbb2..000000000 --- a/patch/kernel/odroidc2-next/0066-clk-meson-gxbb-mpll-use-rw-operation.patch +++ /dev/null @@ -1,47 +0,0 @@ -From e3d1a6396f339506d2dd84a276dc8df37da5dcd5 Mon Sep 17 00:00:00 2001 -From: Jerome Brunet -Date: Wed, 18 Jan 2017 12:19:22 +0100 -Subject: [PATCH 66/93] clk: meson: gxbb: mpll: use rw operation - -Use read/write operation for the mpll clocks instead of the -read-only ones. - -Signed-off-by: Jerome Brunet ---- - drivers/clk/meson/gxbb.c | 6 +++--- - 1 file changed, 3 insertions(+), 3 deletions(-) - -diff --git a/drivers/clk/meson/gxbb.c b/drivers/clk/meson/gxbb.c -index 2f50a57..1f31933 100644 ---- a/drivers/clk/meson/gxbb.c -+++ b/drivers/clk/meson/gxbb.c -@@ -476,7 +476,7 @@ - .lock = &clk_lock, - .hw.init = &(struct clk_init_data){ - .name = "mpll0", -- .ops = &meson_clk_mpll_ro_ops, -+ .ops = &meson_clk_mpll_ops, - .parent_names = (const char *[]){ "fixed_pll" }, - .num_parents = 1, - }, -@@ -506,7 +506,7 @@ - .lock = &clk_lock, - .hw.init = &(struct clk_init_data){ - .name = "mpll1", -- .ops = &meson_clk_mpll_ro_ops, -+ .ops = &meson_clk_mpll_ops, - .parent_names = (const char *[]){ "fixed_pll" }, - .num_parents = 1, - }, -@@ -536,7 +536,7 @@ - .lock = &clk_lock, - .hw.init = &(struct clk_init_data){ - .name = "mpll2", -- .ops = &meson_clk_mpll_ro_ops, -+ .ops = &meson_clk_mpll_ops, - .parent_names = (const char *[]){ "fixed_pll" }, - .num_parents = 1, - }, --- -1.9.1 - diff --git a/patch/kernel/odroidc2-next/0067-ARM64-dts-meson-gxl-s905d-p230-Add-HDMI-nodes.patch b/patch/kernel/odroidc2-next/0067-ARM64-dts-meson-gxl-s905d-p230-Add-HDMI-nodes.patch new file mode 100644 index 000000000..3582de68a --- /dev/null +++ b/patch/kernel/odroidc2-next/0067-ARM64-dts-meson-gxl-s905d-p230-Add-HDMI-nodes.patch @@ -0,0 +1,57 @@ +From 13df956e16be2e1a645f01ba589c4a9af25fc5cf Mon Sep 17 00:00:00 2001 +From: Neil Armstrong +Date: Thu, 8 Jun 2017 17:21:44 +0200 +Subject: [PATCH 67/79] ARM64: dts: meson-gxl-s905d-p230: Add HDMI nodes + +Add HDMI nodes for the Amlogic P230 board. + +Signed-off-by: Neil Armstrong +--- + .../boot/dts/amlogic/meson-gxl-s905d-p230.dts | 24 ++++++++++++++++++++++ + 1 file changed, 24 insertions(+) + +diff --git a/arch/arm64/boot/dts/amlogic/meson-gxl-s905d-p230.dts b/arch/arm64/boot/dts/amlogic/meson-gxl-s905d-p230.dts +index f95978c..5aed4e6 100644 +--- a/arch/arm64/boot/dts/amlogic/meson-gxl-s905d-p230.dts ++++ b/arch/arm64/boot/dts/amlogic/meson-gxl-s905d-p230.dts +@@ -111,6 +111,17 @@ + }; + }; + }; ++ ++ hdmi-connector { ++ compatible = "hdmi-connector"; ++ type = "a"; ++ ++ port { ++ hdmi_connector_in: endpoint { ++ remote-endpoint = <&hdmi_tx_tmds_out>; ++ }; ++ }; ++ }; + }; + + &cec_AO { +@@ -147,6 +158,19 @@ + }; + }; + ++ ++&hdmi_tx { ++ status = "okay"; ++ pinctrl-0 = <&hdmi_hpd_pins>, <&hdmi_i2c_pins>; ++ pinctrl-names = "default"; ++}; ++ ++&hdmi_tx_tmds_port { ++ hdmi_tx_tmds_out: endpoint { ++ remote-endpoint = <&hdmi_connector_in>; ++ }; ++}; ++ + &saradc { + status = "okay"; + vref-supply = <&vddio_ao18>; +-- +1.9.1 + diff --git a/patch/kernel/odroidc2-next/0067-clk-gxbb-add-mpll0-enable-support.patch b/patch/kernel/odroidc2-next/0067-clk-gxbb-add-mpll0-enable-support.patch deleted file mode 100644 index 310ea196e..000000000 --- a/patch/kernel/odroidc2-next/0067-clk-gxbb-add-mpll0-enable-support.patch +++ /dev/null @@ -1,116 +0,0 @@ -From 3adc15dbb8f2b91f8b447397fdbd55650d51c3f7 Mon Sep 17 00:00:00 2001 -From: Jerome Brunet -Date: Tue, 24 Jan 2017 10:50:40 +0100 -Subject: [PATCH 67/93] clk: gxbb: add mpll0 enable support - -Unlike mpll1 and mpll2, mpll0 has an additional enable / disable bit in -HHI_MPLL_CNTL. Model this oddity by adding a gate at the output of the -actual pll. - -To make this transparent to the clock consumer, the existing CLKID_MPLL0 -id is given to the gate. The actual pll is transfered to CLKID_MPLL0_PLL. - -Fixes: 738f66d3211d ("clk: gxbb: add AmLogic GXBB clk controller driver") -Signed-off-by: Jerome Brunet - -Conflicts: - drivers/clk/meson/gxbb.c - drivers/clk/meson/gxbb.h ---- - drivers/clk/meson/gxbb.c | 27 ++++++++++++++++++++++++--- - drivers/clk/meson/gxbb.h | 3 ++- - 2 files changed, 26 insertions(+), 4 deletions(-) - -diff --git a/drivers/clk/meson/gxbb.c b/drivers/clk/meson/gxbb.c -index 1f31933..4379a62 100644 ---- a/drivers/clk/meson/gxbb.c -+++ b/drivers/clk/meson/gxbb.c -@@ -452,7 +452,13 @@ - }, - }; - --static struct meson_clk_mpll gxbb_mpll0 = { -+/* -+ * Unlike mpll1 and mpll2, mpll0 has an additional enable / disable bit. Let's -+ * model this using a clock gate. To make this oddity transparent to the clock -+ * consumer, let's give the CLKID_MPLL0 id to the gate and let the rate -+ * propagate to the pll itself. -+ */ -+static struct meson_clk_mpll gxbb_mpll0_pll = { - .sdm = { - .reg_off = HHI_MPLL_CNTL7, - .shift = 0, -@@ -475,13 +481,26 @@ - }, - .lock = &clk_lock, - .hw.init = &(struct clk_init_data){ -- .name = "mpll0", -+ .name = "mpll0_pll", - .ops = &meson_clk_mpll_ops, - .parent_names = (const char *[]){ "fixed_pll" }, - .num_parents = 1, - }, - }; - -+static struct clk_gate gxbb_mpll0 = { -+ .reg = (void *)HHI_MPLL_CNTL, -+ .bit_idx = 25, -+ .lock = &clk_lock, -+ .hw.init = &(struct clk_init_data){ -+ .name = "mpll0", -+ .ops = &clk_gate_ops, -+ .parent_names = (const char *[]){ "mpll0_pll" }, -+ .num_parents = 1, -+ .flags = (CLK_SET_RATE_PARENT | CLK_IGNORE_UNUSED), -+ }, -+}; -+ - static struct meson_clk_mpll gxbb_mpll1 = { - .sdm = { - .reg_off = HHI_MPLL_CNTL8, -@@ -870,6 +889,7 @@ - [CLKID_SD_EMMC_A] = &gxbb_emmc_a.hw, - [CLKID_SD_EMMC_B] = &gxbb_emmc_b.hw, - [CLKID_SD_EMMC_C] = &gxbb_emmc_c.hw, -+ [CLKID_MPLL0_PLL] = &gxbb_mpll0_pll.hw, - [CLKID_MALI] = &gxbb_mali.hw, - /* This sentinel entry makes sure the table is large enough */ - [NR_CLKS] = NULL, /* Sentinel */ -@@ -887,7 +907,7 @@ - }; - - static struct meson_clk_mpll *const gxbb_clk_mplls[] = { -- &gxbb_mpll0, -+ &gxbb_mpll0_pll, - &gxbb_mpll1, - &gxbb_mpll2, - }; -@@ -977,6 +997,7 @@ - &gxbb_emmc_c, - &gxbb_mali_0_en, - &gxbb_mali_1_en, -+ &gxbb_mpll0, - }; - - static struct clk_mux *gxbb_clk_muxes[] = { -diff --git a/drivers/clk/meson/gxbb.h b/drivers/clk/meson/gxbb.h -index 15705d3..366b766 100644 ---- a/drivers/clk/meson/gxbb.h -+++ b/drivers/clk/meson/gxbb.h -@@ -265,11 +265,12 @@ - /* CLKID_SD_EMMC_A */ - /* CLKID_SD_EMMC_B */ - /* CLKID_SD_EMMC_C */ -+#define CLKID_MPLL0_PLL 97 - /* CLKID_MALI_0 */ - /* CLKID_MALI_1 */ - /* CLKID_MALI */ - --#define NR_CLKS 100 -+#define NR_CLKS 101 - - /* include the CLKIDs that have been made part of the stable DT binding */ - #include --- -1.9.1 - diff --git a/patch/kernel/odroidc2-next/0068-ARM64-dts-meson-gxl-s905x-khadas-vim-Add-HDMI-nodes.patch b/patch/kernel/odroidc2-next/0068-ARM64-dts-meson-gxl-s905x-khadas-vim-Add-HDMI-nodes.patch new file mode 100644 index 000000000..cc7c2912b --- /dev/null +++ b/patch/kernel/odroidc2-next/0068-ARM64-dts-meson-gxl-s905x-khadas-vim-Add-HDMI-nodes.patch @@ -0,0 +1,49 @@ +From 0def24ea0426898c2b43bba814a135fbe13b00b1 Mon Sep 17 00:00:00 2001 +From: Neil Armstrong +Date: Thu, 8 Jun 2017 17:23:06 +0200 +Subject: [PATCH 68/79] ARM64: dts: meson-gxl-s905x-khadas-vim: Add HDMI nodes + +Add HDMI nodes for the Khadas Vim board. + +Signed-off-by: Neil Armstrong +--- + .../dts/amlogic/meson-gxl-s905x-khadas-vim.dts | 23 ++++++++++++++++++++++ + 1 file changed, 23 insertions(+) + +diff --git a/arch/arm64/boot/dts/amlogic/meson-gxl-s905x-khadas-vim.dts b/arch/arm64/boot/dts/amlogic/meson-gxl-s905x-khadas-vim.dts +index 3c8b0b5..a133ed8 100644 +--- a/arch/arm64/boot/dts/amlogic/meson-gxl-s905x-khadas-vim.dts ++++ b/arch/arm64/boot/dts/amlogic/meson-gxl-s905x-khadas-vim.dts +@@ -54,6 +54,29 @@ + linux,default-trigger = "default-on"; + }; + }; ++ ++ hdmi-connector { ++ compatible = "hdmi-connector"; ++ type = "a"; ++ ++ port { ++ hdmi_connector_in: endpoint { ++ remote-endpoint = <&hdmi_tx_tmds_out>; ++ }; ++ }; ++ }; ++}; ++ ++&hdmi_tx { ++ status = "okay"; ++ pinctrl-0 = <&hdmi_hpd_pins>, <&hdmi_i2c_pins>; ++ pinctrl-names = "default"; ++}; ++ ++&hdmi_tx_tmds_port { ++ hdmi_tx_tmds_out: endpoint { ++ remote-endpoint = <&hdmi_connector_in>; ++ }; + }; + + &i2c_A { +-- +1.9.1 + diff --git a/patch/kernel/odroidc2-next/0068-clk-meson8b-add-mplls-clocks.patch b/patch/kernel/odroidc2-next/0068-clk-meson8b-add-mplls-clocks.patch deleted file mode 100644 index 63f21b9ea..000000000 --- a/patch/kernel/odroidc2-next/0068-clk-meson8b-add-mplls-clocks.patch +++ /dev/null @@ -1,209 +0,0 @@ -From af43b8d8c91eda0e1cb78e758690a4a282656d48 Mon Sep 17 00:00:00 2001 -From: Jerome Brunet -Date: Mon, 30 Jan 2017 11:34:32 +0100 -Subject: [PATCH 68/93] clk: meson8b: add mplls clocks - -Signed-off-by: Jerome Brunet ---- - drivers/clk/meson/meson8b.c | 123 ++++++++++++++++++++++++++++++++++++++++++++ - drivers/clk/meson/meson8b.h | 21 +++++++- - 2 files changed, 143 insertions(+), 1 deletion(-) - -diff --git a/drivers/clk/meson/meson8b.c b/drivers/clk/meson/meson8b.c -index 3f1be46..08644fb 100644 ---- a/drivers/clk/meson/meson8b.c -+++ b/drivers/clk/meson/meson8b.c -@@ -246,6 +246,115 @@ - }; - - /* -+ * Unlike mpll1 and mpll2, mpll0 has an additional enable / disable bit. Let's -+ * model this using a clock gate. To make this oddity transparent to the clock -+ * consumer, let's give the CLKID_MPLL0 id to the gate and let the rate -+ * propagate to the pll itself. -+ */ -+static struct meson_clk_mpll meson8b_mpll0_pll = { -+ .sdm = { -+ .reg_off = HHI_MPLL_CNTL7, -+ .shift = 0, -+ .width = 14, -+ }, -+ .sdm_en = { -+ .reg_off = HHI_MPLL_CNTL7, -+ .shift = 15, -+ .width = 1, -+ }, -+ .n2 = { -+ .reg_off = HHI_MPLL_CNTL7, -+ .shift = 16, -+ .width = 9, -+ }, -+ .en = { -+ .reg_off = HHI_MPLL_CNTL7, -+ .shift = 14, -+ .width = 1, -+ }, -+ .lock = &clk_lock, -+ .hw.init = &(struct clk_init_data){ -+ .name = "mpll0_pll", -+ .ops = &meson_clk_mpll_ops, -+ .parent_names = (const char *[]){ "fixed_pll" }, -+ .num_parents = 1, -+ }, -+}; -+ -+static struct clk_gate meson8b_mpll0 = { -+ .reg = (void *)HHI_MPLL_CNTL, -+ .bit_idx = 25, -+ .lock = &clk_lock, -+ .hw.init = &(struct clk_init_data){ -+ .name = "mpll0", -+ .ops = &clk_gate_ops, -+ .parent_names = (const char *[]){ "mpll0_pll" }, -+ .num_parents = 1, -+ .flags = (CLK_SET_RATE_PARENT | CLK_IGNORE_UNUSED), -+ }, -+}; -+ -+static struct meson_clk_mpll meson8b_mpll1 = { -+ .sdm = { -+ .reg_off = HHI_MPLL_CNTL8, -+ .shift = 0, -+ .width = 14, -+ }, -+ .sdm_en = { -+ .reg_off = HHI_MPLL_CNTL8, -+ .shift = 15, -+ .width = 1, -+ }, -+ .n2 = { -+ .reg_off = HHI_MPLL_CNTL8, -+ .shift = 16, -+ .width = 9, -+ }, -+ .en = { -+ .reg_off = HHI_MPLL_CNTL8, -+ .shift = 14, -+ .width = 1, -+ }, -+ .lock = &clk_lock, -+ .hw.init = &(struct clk_init_data){ -+ .name = "mpll1", -+ .ops = &meson_clk_mpll_ops, -+ .parent_names = (const char *[]){ "fixed_pll" }, -+ .num_parents = 1, -+ }, -+}; -+ -+static struct meson_clk_mpll meson8b_mpll2 = { -+ .sdm = { -+ .reg_off = HHI_MPLL_CNTL9, -+ .shift = 0, -+ .width = 14, -+ }, -+ .sdm_en = { -+ .reg_off = HHI_MPLL_CNTL9, -+ .shift = 15, -+ .width = 1, -+ }, -+ .n2 = { -+ .reg_off = HHI_MPLL_CNTL9, -+ .shift = 16, -+ .width = 9, -+ }, -+ .en = { -+ .reg_off = HHI_MPLL_CNTL9, -+ .shift = 14, -+ .width = 1, -+ }, -+ .lock = &clk_lock, -+ .hw.init = &(struct clk_init_data){ -+ .name = "mpll2", -+ .ops = &meson_clk_mpll_ops, -+ .parent_names = (const char *[]){ "fixed_pll" }, -+ .num_parents = 1, -+ }, -+}; -+ -+/* - * FIXME cpu clocks and the legacy composite clocks (e.g. clk81) are both PLL - * post-dividers and should be modeled with their respective PLLs via the - * forthcoming coordinated clock rates feature -@@ -491,6 +600,10 @@ struct clk_gate meson8b_clk81 = { - [CLKID_AO_AHB_SRAM] = &meson8b_ao_ahb_sram.hw, - [CLKID_AO_AHB_BUS] = &meson8b_ao_ahb_bus.hw, - [CLKID_AO_IFACE] = &meson8b_ao_iface.hw, -+ [CLKID_MPLL0_PLL] = &meson8b_mpll0_pll.hw, -+ [CLKID_MPLL0] = &meson8b_mpll0.hw, -+ [CLKID_MPLL1] = &meson8b_mpll1.hw, -+ [CLKID_MPLL2] = &meson8b_mpll2.hw, - }, - .num = CLK_NR_CLKS, - }; -@@ -501,6 +614,12 @@ struct clk_gate meson8b_clk81 = { - &meson8b_sys_pll, - }; - -+static struct meson_clk_mpll *const meson8b_clk_mplls[] = { -+ &meson8b_mpll0_pll, -+ &meson8b_mpll1, -+ &meson8b_mpll2, -+}; -+ - static struct clk_gate *meson8b_clk_gates[] = { - &meson8b_clk81, - &meson8b_ddr, -@@ -601,6 +720,10 @@ static int meson8b_clkc_probe(struct platform_device *pdev) - for (i = 0; i < ARRAY_SIZE(meson8b_clk_plls); i++) - meson8b_clk_plls[i]->base = clk_base; - -+ /* Populate base address for MPLLs */ -+ for (i = 0; i < ARRAY_SIZE(meson8b_clk_mplls); i++) -+ meson8b_clk_mplls[i]->base = clk_base; -+ - /* Populate the base address for CPU clk */ - meson8b_cpu_clk.base = clk_base; - -diff --git a/drivers/clk/meson/meson8b.h b/drivers/clk/meson/meson8b.h -index 010e958..0f1f05b 100644 ---- a/drivers/clk/meson/meson8b.h -+++ b/drivers/clk/meson/meson8b.h -@@ -42,6 +42,21 @@ - #define HHI_VID_PLL_CNTL 0x320 /* 0xc8 offset in data sheet */ - - /* -+ * MPLL register offeset taken from the S905 datasheet. Vendor kernel source -+ * confirm these are the same for the S805. -+ */ -+#define HHI_MPLL_CNTL 0x280 /* 0xa0 offset in data sheet */ -+#define HHI_MPLL_CNTL2 0x284 /* 0xa1 offset in data sheet */ -+#define HHI_MPLL_CNTL3 0x288 /* 0xa2 offset in data sheet */ -+#define HHI_MPLL_CNTL4 0x28C /* 0xa3 offset in data sheet */ -+#define HHI_MPLL_CNTL5 0x290 /* 0xa4 offset in data sheet */ -+#define HHI_MPLL_CNTL6 0x294 /* 0xa5 offset in data sheet */ -+#define HHI_MPLL_CNTL7 0x298 /* MP0, 0xa6 offset in data sheet */ -+#define HHI_MPLL_CNTL8 0x29C /* MP1, 0xa7 offset in data sheet */ -+#define HHI_MPLL_CNTL9 0x2A0 /* MP2, 0xa8 offset in data sheet */ -+#define HHI_MPLL_CNTL10 0x2A4 /* MP2, 0xa9 offset in data sheet */ -+ -+/* - * CLKID index values - * - * These indices are entirely contrived and do not map onto the hardware. -@@ -142,8 +157,12 @@ - #define CLKID_AO_AHB_SRAM 90 - #define CLKID_AO_AHB_BUS 91 - #define CLKID_AO_IFACE 92 -+#define CLKID_MPLL0_PLL 93 -+#define CLKID_MPLL0 94 -+#define CLKID_MPLL1 95 -+#define CLKID_MPLL2 96 - --#define CLK_NR_CLKS 93 -+#define CLK_NR_CLKS 97 - - /* include the CLKIDs that have been made part of the stable DT binding */ - #include --- -1.9.1 - diff --git a/patch/kernel/odroidc2-next/0069-ARM64-dts-meson-gxl-s905x-p212-Add-HDMI-and-CVBS-nod.patch b/patch/kernel/odroidc2-next/0069-ARM64-dts-meson-gxl-s905x-p212-Add-HDMI-and-CVBS-nod.patch new file mode 100644 index 000000000..e8627b2d8 --- /dev/null +++ b/patch/kernel/odroidc2-next/0069-ARM64-dts-meson-gxl-s905x-p212-Add-HDMI-and-CVBS-nod.patch @@ -0,0 +1,57 @@ +From 4fc4090651c1d5450283935e4b0e674bd36abeb7 Mon Sep 17 00:00:00 2001 +From: Neil Armstrong +Date: Thu, 8 Jun 2017 17:23:46 +0200 +Subject: [PATCH 69/79] ARM64: dts: meson-gxl-s905x-p212: Add HDMI and CVBS + nodes + +Add HDMI and CVBS nodes for the Amlogic P212 reference board. + +Signed-off-by: Neil Armstrong +--- + .../boot/dts/amlogic/meson-gxl-s905x-p212.dts | 23 ++++++++++++++++++++++ + 1 file changed, 23 insertions(+) + +diff --git a/arch/arm64/boot/dts/amlogic/meson-gxl-s905x-p212.dts b/arch/arm64/boot/dts/amlogic/meson-gxl-s905x-p212.dts +index 99a01ff..6e2bf85 100644 +--- a/arch/arm64/boot/dts/amlogic/meson-gxl-s905x-p212.dts ++++ b/arch/arm64/boot/dts/amlogic/meson-gxl-s905x-p212.dts +@@ -58,6 +58,17 @@ + }; + }; + }; ++ ++ hdmi-connector { ++ compatible = "hdmi-connector"; ++ type = "a"; ++ ++ port { ++ hdmi_connector_in: endpoint { ++ remote-endpoint = <&hdmi_tx_tmds_out>; ++ }; ++ }; ++ }; + }; + + &cec_AO { +@@ -73,6 +84,18 @@ + }; + }; + ++&hdmi_tx { ++ status = "okay"; ++ pinctrl-0 = <&hdmi_hpd_pins>, <&hdmi_i2c_pins>; ++ pinctrl-names = "default"; ++}; ++ ++&hdmi_tx_tmds_port { ++ hdmi_tx_tmds_out: endpoint { ++ remote-endpoint = <&hdmi_connector_in>; ++ }; ++}; ++ + /* This UART is brought out to the DB9 connector */ + &uart_AO { + status = "okay"; +-- +1.9.1 + diff --git a/patch/kernel/odroidc2-next/0069-clk-meson-mpll-correct-N2-maximum-value.patch b/patch/kernel/odroidc2-next/0069-clk-meson-mpll-correct-N2-maximum-value.patch deleted file mode 100644 index c947c1396..000000000 --- a/patch/kernel/odroidc2-next/0069-clk-meson-mpll-correct-N2-maximum-value.patch +++ /dev/null @@ -1,31 +0,0 @@ -From 0eb5b137e2cc8daeef7bb3a56c42e104510953a7 Mon Sep 17 00:00:00 2001 -From: Jerome Brunet -Date: Tue, 14 Feb 2017 14:09:48 +0100 -Subject: [PATCH 69/93] clk: meson: mpll: correct N2 maximum value - -Documentation say N2 maximum value is 127 but the register field -is 9 bits wide, the maximum value should 511. - -Test shows value greater than 127 works well - -Signed-off-by: Jerome Brunet ---- - drivers/clk/meson/clk-mpll.c | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/drivers/clk/meson/clk-mpll.c b/drivers/clk/meson/clk-mpll.c -index d4ba8cd..ce48f65 100644 ---- a/drivers/clk/meson/clk-mpll.c -+++ b/drivers/clk/meson/clk-mpll.c -@@ -68,7 +68,7 @@ - #define SDM_MIN 1 - #define SDM_MAX 16383 - #define N2_MIN 4 --#define N2_MAX 127 -+#define N2_MAX 511 - - #define to_meson_clk_mpll(_hw) container_of(_hw, struct meson_clk_mpll, hw) - --- -1.9.1 - diff --git a/patch/kernel/odroidc2-next/0070-ARM64-dts-meson-gx-Add-CEC-support-for-Wetek-Play2-a.patch b/patch/kernel/odroidc2-next/0070-ARM64-dts-meson-gx-Add-CEC-support-for-Wetek-Play2-a.patch new file mode 100644 index 000000000..533ad1ac2 --- /dev/null +++ b/patch/kernel/odroidc2-next/0070-ARM64-dts-meson-gx-Add-CEC-support-for-Wetek-Play2-a.patch @@ -0,0 +1,50 @@ +From 41c79ce5a32601b5853f97a0186fbc2406d14f06 Mon Sep 17 00:00:00 2001 +From: Neil Armstrong +Date: Mon, 10 Jul 2017 12:24:14 +0200 +Subject: [PATCH 70/79] ARM64: dts: meson-gx: Add CEC support for Wetek Play2 + and Khadas Vim + +Signed-off-by: Neil Armstrong +--- + arch/arm64/boot/dts/amlogic/meson-gxbb-wetek-play2.dts | 6 ++++++ + arch/arm64/boot/dts/amlogic/meson-gxl-s905x-khadas-vim.dts | 7 +++++++ + 2 files changed, 13 insertions(+) + +diff --git a/arch/arm64/boot/dts/amlogic/meson-gxbb-wetek-play2.dts b/arch/arm64/boot/dts/amlogic/meson-gxbb-wetek-play2.dts +index e76ac31..f7144fd 100644 +--- a/arch/arm64/boot/dts/amlogic/meson-gxbb-wetek-play2.dts ++++ b/arch/arm64/boot/dts/amlogic/meson-gxbb-wetek-play2.dts +@@ -108,6 +108,12 @@ + }; + }; + ++&cec_AO { ++ status = "okay"; ++ pinctrl-0 = <&ao_cec_pins>; ++ pinctrl-names = "default"; ++ hdmi-phandle = <&hdmi_tx>; ++}; + + &cvbs_vdac_port { + cvbs_vdac_out: endpoint { +diff --git a/arch/arm64/boot/dts/amlogic/meson-gxl-s905x-khadas-vim.dts b/arch/arm64/boot/dts/amlogic/meson-gxl-s905x-khadas-vim.dts +index a133ed8..da12721 100644 +--- a/arch/arm64/boot/dts/amlogic/meson-gxl-s905x-khadas-vim.dts ++++ b/arch/arm64/boot/dts/amlogic/meson-gxl-s905x-khadas-vim.dts +@@ -67,6 +67,13 @@ + }; + }; + ++&cec_AO { ++ status = "okay"; ++ pinctrl-0 = <&ao_cec_pins>; ++ pinctrl-names = "default"; ++ hdmi-phandle = <&hdmi_tx>; ++}; ++ + &hdmi_tx { + status = "okay"; + pinctrl-0 = <&hdmi_hpd_pins>, <&hdmi_i2c_pins>; +-- +1.9.1 + diff --git a/patch/kernel/odroidc2-next/0070-clk-meson-add-audio-clock-divider-support.patch b/patch/kernel/odroidc2-next/0070-clk-meson-add-audio-clock-divider-support.patch deleted file mode 100644 index 7bebca5d2..000000000 --- a/patch/kernel/odroidc2-next/0070-clk-meson-add-audio-clock-divider-support.patch +++ /dev/null @@ -1,257 +0,0 @@ -From 293cec787c3f707d468e62a09d3d5a461717a3a8 Mon Sep 17 00:00:00 2001 -From: Jerome Brunet -Date: Tue, 14 Feb 2017 00:13:55 +0100 -Subject: [PATCH 70/93] clk: meson: add audio clock divider support - -The audio divider needs a specific clock divider driver. -With am mpll parent clock, which is able to provide fairly precise rate, -the generic divider tends to select low value of the divider. In such case -the quality of the clock is very poor. For the same final rate, maximizing -the audio clock divider value and selecting the corresponding mpll rate -gives better results. This is what this driver aims to acheive. So far, so -good. - -Signed-off-by: Jerome Brunet ---- - drivers/clk/meson/Makefile | 2 +- - drivers/clk/meson/clk-audio-divider.c | 188 ++++++++++++++++++++++++++++++++++ - drivers/clk/meson/clkc.h | 10 ++ - 3 files changed, 199 insertions(+), 1 deletion(-) - create mode 100644 drivers/clk/meson/clk-audio-divider.c - -diff --git a/drivers/clk/meson/Makefile b/drivers/clk/meson/Makefile -index 3495834..83b6d9d 100644 ---- a/drivers/clk/meson/Makefile -+++ b/drivers/clk/meson/Makefile -@@ -2,6 +2,6 @@ - # Makefile for Meson specific clk - # - --obj-$(CONFIG_COMMON_CLK_AMLOGIC) += clk-pll.o clk-cpu.o clk-mpll.o -+obj-$(CONFIG_COMMON_CLK_AMLOGIC) += clk-pll.o clk-cpu.o clk-mpll.o clk-audio-divider.o - obj-$(CONFIG_COMMON_CLK_MESON8B) += meson8b.o - obj-$(CONFIG_COMMON_CLK_GXBB) += gxbb.o gxbb-aoclk.o -diff --git a/drivers/clk/meson/clk-audio-divider.c b/drivers/clk/meson/clk-audio-divider.c -new file mode 100644 -index 0000000..2263214 ---- /dev/null -+++ b/drivers/clk/meson/clk-audio-divider.c -@@ -0,0 +1,188 @@ -+/* -+ * This file is provided under a dual BSD/GPLv2 license. When using or -+ * redistributing this file, you may do so under either license. -+ * -+ * GPL LICENSE SUMMARY -+ * -+ * Copyright (c) 2017 AmLogic, Inc. -+ * Author: Jerome Brunet -+ * -+ * This program is free software; you can redistribute it and/or modify -+ * it under the terms of version 2 of the GNU General Public License as -+ * published by the Free Software Foundation. -+ * -+ * This program is distributed in the hope that it will be useful, but -+ * WITHOUT ANY WARRANTY; without even the implied warranty of -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -+ * General Public License for more details. -+ * -+ * You should have received a copy of the GNU General Public License -+ * along with this program; if not, write to the Free Software -+ * Foundation, Inc., 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. -+ * The full GNU General Public License is included in this distribution -+ * in the file called COPYING -+ * -+ * BSD LICENSE -+ * -+ * Copyright (c) 2017 AmLogic, Inc. -+ * Author: Jerome Brunet -+ * -+ * Redistribution and use in source and binary forms, with or without -+ * modification, are permitted provided that the following conditions -+ * are met: -+ * -+ * * Redistributions of source code must retain the above copyright -+ * notice, this list of conditions and the following disclaimer. -+ * * Redistributions in binary form must reproduce the above copyright -+ * notice, this list of conditions and the following disclaimer in -+ * the documentation and/or other materials provided with the -+ * distribution. -+ * * Neither the name of Baylibre nor the names of its -+ * contributors may be used to endorse or promote products derived -+ * from this software without specific prior written permission. -+ * -+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -+ */ -+ -+/* -+ * Audio clock divider: The algorythm of clk-divider used with a very precise -+ * source clock such as the mpll tends to select low divider factor. This gives -+ * very poor results with this particular divider especially with high -+ * frequencies ( > 100 MHz) -+ * -+ * This driver try to select the maximum possible divider with the rate the mpll -+ * can provide. -+ */ -+ -+#include -+#include "clkc.h" -+ -+#define to_meson_clk_audio_divider(_hw) container_of(_hw, \ -+ struct meson_clk_audio_divider, hw) -+ -+static int _div_round(unsigned long parent_rate, unsigned long rate, -+ unsigned long flags) -+{ -+ if (flags & CLK_DIVIDER_ROUND_CLOSEST) -+ return DIV_ROUND_CLOSEST_ULL((u64)parent_rate, rate); -+ -+ return DIV_ROUND_UP_ULL((u64)parent_rate, rate); -+} -+ -+static int _get_val(unsigned long parent_rate, unsigned long rate) -+{ -+ return DIV_ROUND_UP_ULL((u64)parent_rate, rate) - 1; -+} -+ -+static int _valid_divider(struct clk_hw *hw, int divider) -+{ -+ struct meson_clk_audio_divider *adiv = -+ to_meson_clk_audio_divider(hw); -+ int max_divider; -+ u8 width; -+ -+ width = adiv->div.width; -+ max_divider = 1 << width; -+ -+ if (divider < 1) -+ return 1; -+ else if (divider > max_divider) -+ return max_divider; -+ -+ return divider; -+} -+ -+static unsigned long audio_divider_recalc_rate(struct clk_hw *hw, -+ unsigned long parent_rate) -+{ -+ struct meson_clk_audio_divider *adiv = -+ to_meson_clk_audio_divider(hw); -+ struct parm *p; -+ unsigned long reg, divider; -+ -+ p = &adiv->div; -+ reg = readl(adiv->base + p->reg_off); -+ divider = PARM_GET(p->width, p->shift, reg) + 1; -+ -+ return DIV_ROUND_UP_ULL((u64)parent_rate, divider); -+} -+ -+static long audio_divider_round_rate(struct clk_hw *hw, -+ unsigned long rate, -+ unsigned long *parent_rate) -+{ -+ struct meson_clk_audio_divider *adiv = -+ to_meson_clk_audio_divider(hw); -+ unsigned long max_prate; -+ int divider; -+ -+ if (!(clk_hw_get_flags(hw) & CLK_SET_RATE_PARENT)) { -+ divider = _div_round(*parent_rate, rate, adiv->flags); -+ divider = _valid_divider(hw, divider); -+ return DIV_ROUND_UP_ULL((u64)*parent_rate, divider); -+ } -+ -+ /* Get the maximum parent rate */ -+ max_prate = clk_hw_round_rate(clk_hw_get_parent(hw), ULONG_MAX); -+ -+ /* Get the corresponding rounded down divider */ -+ divider = max_prate / rate; -+ divider = _valid_divider(hw, divider); -+ -+ /* Get actual rate of the parent */ -+ *parent_rate = clk_hw_round_rate(clk_hw_get_parent(hw), -+ divider * rate); -+ -+ return DIV_ROUND_UP_ULL((u64)*parent_rate, divider); -+} -+ -+static int audio_divider_set_rate(struct clk_hw *hw, -+ unsigned long rate, -+ unsigned long parent_rate) -+{ -+ struct meson_clk_audio_divider *adiv = -+ to_meson_clk_audio_divider(hw); -+ struct parm *p; -+ unsigned long reg, flags = 0; -+ int val; -+ -+ val = _get_val(parent_rate, rate); -+ -+ if (adiv->lock) -+ spin_lock_irqsave(adiv->lock, flags); -+ else -+ __acquire(adiv->lock); -+ -+ p = &adiv->div; -+ reg = readl(adiv->base + p->reg_off); -+ reg = PARM_SET(p->width, p->shift, reg, val); -+ writel(reg, adiv->base + p->reg_off); -+ -+ if (adiv->lock) -+ spin_unlock_irqrestore(adiv->lock, flags); -+ else -+ __release(adiv->lock); -+ -+ return 0; -+} -+ -+const struct clk_ops meson_clk_audio_divider_ro_ops = { -+ .recalc_rate = audio_divider_recalc_rate, -+ .round_rate = audio_divider_round_rate, -+}; -+ -+const struct clk_ops meson_clk_audio_divider_ops = { -+ .recalc_rate = audio_divider_recalc_rate, -+ .round_rate = audio_divider_round_rate, -+ .set_rate = audio_divider_set_rate, -+}; -diff --git a/drivers/clk/meson/clkc.h b/drivers/clk/meson/clkc.h -index ae38d69..3d4a5bc 100644 ---- a/drivers/clk/meson/clkc.h -+++ b/drivers/clk/meson/clkc.h -@@ -101,6 +101,14 @@ struct meson_clk_mpll { - spinlock_t *lock; - }; - -+struct meson_clk_audio_divider { -+ struct clk_hw hw; -+ void __iomem *base; -+ struct parm div; -+ u8 flags; -+ spinlock_t *lock; -+}; -+ - #define MESON_GATE(_name, _reg, _bit) \ - struct clk_gate _name = { \ - .reg = (void __iomem *) _reg, \ -@@ -121,5 +129,7 @@ struct clk_gate _name = { \ - extern const struct clk_ops meson_clk_cpu_ops; - extern const struct clk_ops meson_clk_mpll_ro_ops; - extern const struct clk_ops meson_clk_mpll_ops; -+extern const struct clk_ops meson_clk_audio_divider_ro_ops; -+extern const struct clk_ops meson_clk_audio_divider_ops; - - #endif /* __CLKC_H */ --- -1.9.1 - diff --git a/patch/kernel/odroidc2-next/0071-ARM64-dts-meson-gxbb-allow-child-devices-on-the-USB-.patch b/patch/kernel/odroidc2-next/0071-ARM64-dts-meson-gxbb-allow-child-devices-on-the-USB-.patch new file mode 100644 index 000000000..416ff348f --- /dev/null +++ b/patch/kernel/odroidc2-next/0071-ARM64-dts-meson-gxbb-allow-child-devices-on-the-USB-.patch @@ -0,0 +1,41 @@ +From 40979f4df1a3bbe110b3fe2ace1524dc559ad4e8 Mon Sep 17 00:00:00 2001 +From: Martin Blumenstingl +Date: Thu, 12 Jan 2017 01:38:26 +0100 +Subject: [PATCH 71/79] ARM64: dts: meson-gxbb: allow child devices on the USB + controller + +Add the size and adress cells to the USB controllers to allow specifying +child devices (for example the USB hub on the Odroid-C2 which must be +taken out of reset to work). + +Signed-off-by: Martin Blumenstingl +Signed-off-by: Neil Armstrong +--- + arch/arm64/boot/dts/amlogic/meson-gxbb.dtsi | 4 ++++ + 1 file changed, 4 insertions(+) + +diff --git a/arch/arm64/boot/dts/amlogic/meson-gxbb.dtsi b/arch/arm64/boot/dts/amlogic/meson-gxbb.dtsi +index dc0eb44..912c4dc 100644 +--- a/arch/arm64/boot/dts/amlogic/meson-gxbb.dtsi ++++ b/arch/arm64/boot/dts/amlogic/meson-gxbb.dtsi +@@ -73,6 +73,8 @@ + + usb0: usb@c9000000 { + compatible = "amlogic,meson-gxbb-usb", "snps,dwc2"; ++ #address-cells = <1>; ++ #size-cells = <0>; + reg = <0x0 0xc9000000 0x0 0x40000>; + interrupts = ; + clocks = <&clkc CLKID_USB0_DDR_BRIDGE>; +@@ -85,6 +87,8 @@ + + usb1: usb@c9100000 { + compatible = "amlogic,meson-gxbb-usb", "snps,dwc2"; ++ #address-cells = <1>; ++ #size-cells = <0>; + reg = <0x0 0xc9100000 0x0 0x40000>; + interrupts = ; + clocks = <&clkc CLKID_USB1_DDR_BRIDGE>; +-- +1.9.1 + diff --git a/patch/kernel/odroidc2-next/0071-clk-gxbb-add-cts_amclk.patch b/patch/kernel/odroidc2-next/0071-clk-gxbb-add-cts_amclk.patch deleted file mode 100644 index 4e85e04bd..000000000 --- a/patch/kernel/odroidc2-next/0071-clk-gxbb-add-cts_amclk.patch +++ /dev/null @@ -1,132 +0,0 @@ -From a47430e7903c2c9f68568b5f33ea4d508718df28 Mon Sep 17 00:00:00 2001 -From: Jerome Brunet -Date: Tue, 24 Jan 2017 18:35:23 +0100 -Subject: [PATCH 71/93] clk: gxbb: add cts_amclk - -Add the i2s master clock also referred as cts_amclk - -Signed-off-by: Jerome Brunet - -Conflicts: - drivers/clk/meson/gxbb.c - drivers/clk/meson/gxbb.h ---- - drivers/clk/meson/gxbb.c | 53 ++++++++++++++++++++++++++++++++++++++++++++++++ - drivers/clk/meson/gxbb.h | 5 ++++- - 2 files changed, 57 insertions(+), 1 deletion(-) - -diff --git a/drivers/clk/meson/gxbb.c b/drivers/clk/meson/gxbb.c -index 4379a62..9e2e407 100644 ---- a/drivers/clk/meson/gxbb.c -+++ b/drivers/clk/meson/gxbb.c -@@ -699,6 +699,51 @@ - }, - }; - -+static struct clk_mux gxbb_cts_amclk_sel = { -+ .reg = (void *) HHI_AUD_CLK_CNTL, -+ .mask = 0x3, -+ .shift = 9, -+ /* Default parent unknown (register reset value: 0) */ -+ .table = (u32[]){ 1, 2, 3 }, -+ .lock = &clk_lock, -+ .hw.init = &(struct clk_init_data){ -+ .name = "cts_amclk_sel", -+ .ops = &clk_mux_ops, -+ .parent_names = (const char *[]){ "mpll0", "mpll1", "mpll2" }, -+ .num_parents = 2, -+ .flags = CLK_SET_RATE_PARENT, -+ }, -+}; -+ -+static struct meson_clk_audio_divider gxbb_cts_amclk_div = { -+ .div = { -+ .reg_off = HHI_AUD_CLK_CNTL, -+ .shift = 0, -+ .width = 8, -+ }, -+ .lock = &clk_lock, -+ .hw.init = &(struct clk_init_data){ -+ .name = "cts_amclk_div", -+ .ops = &meson_clk_audio_divider_ops, -+ .parent_names = (const char *[]){ "cts_amclk_sel" }, -+ .num_parents = 1, -+ .flags = CLK_SET_RATE_PARENT | CLK_DIVIDER_ROUND_CLOSEST, -+ }, -+}; -+ -+static struct clk_gate gxbb_cts_amclk = { -+ .reg = (void *) HHI_AUD_CLK_CNTL, -+ .bit_idx = 8, -+ .lock = &clk_lock, -+ .hw.init = &(struct clk_init_data){ -+ .name = "cts_amclk", -+ .ops = &clk_gate_ops, -+ .parent_names = (const char *[]){ "cts_amclk_div" }, -+ .num_parents = 1, -+ .flags = CLK_SET_RATE_PARENT, -+ }, -+}; -+ - /* Everything Else (EE) domain gates */ - static MESON_GATE(gxbb_ddr, HHI_GCLK_MPEG0, 0); - static MESON_GATE(gxbb_dos, HHI_GCLK_MPEG0, 1); -@@ -890,6 +935,9 @@ - [CLKID_SD_EMMC_B] = &gxbb_emmc_b.hw, - [CLKID_SD_EMMC_C] = &gxbb_emmc_c.hw, - [CLKID_MPLL0_PLL] = &gxbb_mpll0_pll.hw, -+ [CLKID_CTS_AMCLK] = &gxbb_cts_amclk.hw, -+ [CLKID_CTS_AMCLK_SEL] = &gxbb_cts_amclk_sel.hw, -+ [CLKID_CTS_AMCLK_DIV] = &gxbb_cts_amclk_div.hw, - [CLKID_MALI] = &gxbb_mali.hw, - /* This sentinel entry makes sure the table is large enough */ - [NR_CLKS] = NULL, /* Sentinel */ -@@ -998,6 +1046,7 @@ - &gxbb_mali_0_en, - &gxbb_mali_1_en, - &gxbb_mpll0, -+ &gxbb_cts_amclk, - }; - - static struct clk_mux *gxbb_clk_muxes[] = { -@@ -1007,6 +1056,7 @@ - &gxbb_mali, - &gxbb_mpeg_clk_sel, - &gxbb_sar_adc_clk_sel, -+ &gxbb_cts_amclk_sel, - }; - - static struct clk_divider *gxbb_clk_dividers[] = { -@@ -1108,6 +1158,9 @@ static int gxbb_clkc_probe(struct platform_device *pdev) - gxbb_gp0_init_regs[i] = clk_base + - (u64)gxbb_gp0_init_regs[i]; - -+ /* Populate base address for the audio divider */ -+ gxbb_cts_amclk_div.base = clk_base; -+ - /* - * register all clks - */ -diff --git a/drivers/clk/meson/gxbb.h b/drivers/clk/meson/gxbb.h -index 366b766..298bfa5 100644 ---- a/drivers/clk/meson/gxbb.h -+++ b/drivers/clk/meson/gxbb.h -@@ -266,11 +266,14 @@ - /* CLKID_SD_EMMC_B */ - /* CLKID_SD_EMMC_C */ - #define CLKID_MPLL0_PLL 97 -+#define CLKID_CTS_AMCLK 98 -+#define CLKID_CTS_AMCLK_SEL 99 -+#define CLKID_CTS_AMCLK_DIV 100 - /* CLKID_MALI_0 */ - /* CLKID_MALI_1 */ - /* CLKID_MALI */ - --#define NR_CLKS 101 -+#define NR_CLKS 104 - - /* include the CLKIDs that have been made part of the stable DT binding */ - #include --- -1.9.1 - diff --git a/patch/kernel/odroidc2-next/0072-ARM64-dts-meson-gxbb-odroidc2-take-USB-hub-out-of-re.patch b/patch/kernel/odroidc2-next/0072-ARM64-dts-meson-gxbb-odroidc2-take-USB-hub-out-of-re.patch new file mode 100644 index 000000000..f9c944c5b --- /dev/null +++ b/patch/kernel/odroidc2-next/0072-ARM64-dts-meson-gxbb-odroidc2-take-USB-hub-out-of-re.patch @@ -0,0 +1,36 @@ +From ce69e6bd727706aacc7fd5fa3d79b92c552fad79 Mon Sep 17 00:00:00 2001 +From: Martin Blumenstingl +Date: Thu, 12 Jan 2017 01:39:20 +0100 +Subject: [PATCH 72/79] ARM64: dts: meson-gxbb-odroidc2: take USB hub out of + reset + +This takes the USB hub out of reset, otherwise the hub is not working. + +Fixes: 5a0803bd5ae ("ARM64: dts: meson-gxbb-odroidc2: Enable USB Nodes") +Signed-off-by: Martin Blumenstingl +Signed-off-by: Neil Armstrong +--- + arch/arm64/boot/dts/amlogic/meson-gxbb-odroidc2.dts | 7 +++++++ + 1 file changed, 7 insertions(+) + +diff --git a/arch/arm64/boot/dts/amlogic/meson-gxbb-odroidc2.dts b/arch/arm64/boot/dts/amlogic/meson-gxbb-odroidc2.dts +index b4f21d1..e5e5300 100644 +--- a/arch/arm64/boot/dts/amlogic/meson-gxbb-odroidc2.dts ++++ b/arch/arm64/boot/dts/amlogic/meson-gxbb-odroidc2.dts +@@ -303,6 +303,13 @@ + + &usb1 { + status = "okay"; ++ ++ hub@1 { ++ compatible = "usb5e3,610"; ++ reg = <1>; ++ reset-gpios = <&gpio GPIOAO_4 GPIO_ACTIVE_LOW>; ++ reset-duration-us = <3000>; ++ }; + }; + + &saradc { +-- +1.9.1 + diff --git a/patch/kernel/odroidc2-next/0072-pinctrl-meson-add-i2s-output-pins.patch b/patch/kernel/odroidc2-next/0072-pinctrl-meson-add-i2s-output-pins.patch deleted file mode 100644 index 66ee1c147..000000000 --- a/patch/kernel/odroidc2-next/0072-pinctrl-meson-add-i2s-output-pins.patch +++ /dev/null @@ -1,104 +0,0 @@ -From b6e925eebfd802b2dd592c634db24f8cf6202461 Mon Sep 17 00:00:00 2001 -From: Jerome Brunet -Date: Thu, 26 Jan 2017 11:07:13 +0100 -Subject: [PATCH 72/93] pinctrl: meson: add i2s output pins - -Signed-off-by: Jerome Brunet ---- - drivers/pinctrl/meson/pinctrl-meson-gxbb.c | 31 ++++++++++++++++++++++++++++++ - 1 file changed, 31 insertions(+) - -diff --git a/drivers/pinctrl/meson/pinctrl-meson-gxbb.c b/drivers/pinctrl/meson/pinctrl-meson-gxbb.c -index 7671424..1ed61d7 100644 ---- a/drivers/pinctrl/meson/pinctrl-meson-gxbb.c -+++ b/drivers/pinctrl/meson/pinctrl-meson-gxbb.c -@@ -236,6 +236,10 @@ - static const unsigned int hdmi_sda_pins[] = { PIN(GPIOH_1, EE_OFF) }; - static const unsigned int hdmi_scl_pins[] = { PIN(GPIOH_2, EE_OFF) }; - -+static const unsigned int i2s_out_ch23_y_pins[] = { PIN(GPIOY_8, EE_OFF) }; -+static const unsigned int i2s_out_ch45_y_pins[] = { PIN(GPIOY_9, EE_OFF) }; -+static const unsigned int i2s_out_ch67_y_pins[] = { PIN(GPIOY_10, EE_OFF) }; -+ - static const struct pinctrl_pin_desc meson_gxbb_aobus_pins[] = { - MESON_PIN(GPIOAO_0, 0), - MESON_PIN(GPIOAO_1, 0), -@@ -274,6 +278,13 @@ - static const unsigned int pwm_ao_a_12_pins[] = { PIN(GPIOAO_12, 0) }; - static const unsigned int pwm_ao_b_pins[] = { PIN(GPIOAO_13, 0) }; - -+static const unsigned int i2s_am_clk_pins[] = { PIN(GPIOAO_8, 0) }; -+static const unsigned int i2s_out_ao_clk_pins[] = { PIN(GPIOAO_9, 0) }; -+static const unsigned int i2s_out_lr_clk_pins[] = { PIN(GPIOAO_10, 0) }; -+static const unsigned int i2s_out_ch01_ao_pins[] = { PIN(GPIOAO_11, 0) }; -+static const unsigned int i2s_out_ch23_ao_pins[] = { PIN(GPIOAO_12, 0) }; -+static const unsigned int i2s_out_ch45_ao_pins[] = { PIN(GPIOAO_13, 0) }; -+ - static struct meson_pmx_group meson_gxbb_periphs_groups[] = { - GPIO_GROUP(GPIOZ_0, EE_OFF), - GPIO_GROUP(GPIOZ_1, EE_OFF), -@@ -426,6 +437,9 @@ - GROUP(uart_rx_c, 1, 16), - GROUP(pwm_a_y, 1, 21), - GROUP(pwm_f_y, 1, 20), -+ GROUP(i2s_out_ch23_y, 1, 5), -+ GROUP(i2s_out_ch45_y, 1, 6), -+ GROUP(i2s_out_ch67_y, 1, 7), - - /* Bank Z */ - GROUP(eth_mdio, 6, 1), -@@ -523,6 +537,12 @@ - GROUP(pwm_ao_a_6, 0, 18), - GROUP(pwm_ao_a_12, 0, 17), - GROUP(pwm_ao_b, 0, 3), -+ GROUP(i2s_am_clk, 0, 30), -+ GROUP(i2s_out_ao_clk, 0, 29), -+ GROUP(i2s_out_lr_clk, 0, 28), -+ GROUP(i2s_out_ch01_ao, 0, 27), -+ GROUP(i2s_out_ch23_ao, 1, 0), -+ GROUP(i2s_out_ch45_ao, 1, 1), - }; - - static const char * const gpio_periphs_groups[] = { -@@ -652,6 +672,10 @@ - "hdmi_sda", "hdmi_scl", - }; - -+static const char* const i2s_out_y_groups[] = { -+ "i2s_out_ch23_y", "i2s_out_ch45_y", "i2s_out_ch67_y", -+}; -+ - static const char * const gpio_aobus_groups[] = { - "GPIOAO_0", "GPIOAO_1", "GPIOAO_2", "GPIOAO_3", "GPIOAO_4", - "GPIOAO_5", "GPIOAO_6", "GPIOAO_7", "GPIOAO_8", "GPIOAO_9", -@@ -694,6 +718,11 @@ - "pwm_ao_b", - }; - -+static const char* const i2s_out_ao_groups[] = { -+ "i2s_am_clk", "i2s_out_ao_clk", "i2s_out_lr_clk", -+ "i2s_out_ch01_ao", "i2s_out_ch23_ao", "i2s_out_ch45_ao", -+}; -+ - static struct meson_pmx_func meson_gxbb_periphs_functions[] = { - FUNCTION(gpio_periphs), - FUNCTION(emmc), -@@ -717,6 +746,7 @@ - FUNCTION(pwm_f_y), - FUNCTION(hdmi_hpd), - FUNCTION(hdmi_i2c), -+ FUNCTION(i2s_out_y), - }; - - static struct meson_pmx_func meson_gxbb_aobus_functions[] = { -@@ -730,6 +760,7 @@ - FUNCTION(pwm_ao_a_6), - FUNCTION(pwm_ao_a_12), - FUNCTION(pwm_ao_b), -+ FUNCTION(i2s_out_ao), - }; - - static struct meson_bank meson_gxbb_periphs_banks[] = { --- -1.9.1 - diff --git a/patch/kernel/odroidc2-next/0073-ARM64-dts-meson-gxl-add-USB-host-support.patch b/patch/kernel/odroidc2-next/0073-ARM64-dts-meson-gxl-add-USB-host-support.patch new file mode 100644 index 000000000..c97fd1ddd --- /dev/null +++ b/patch/kernel/odroidc2-next/0073-ARM64-dts-meson-gxl-add-USB-host-support.patch @@ -0,0 +1,90 @@ +From 6006726ba262f50d61f3a001cc87fbc82dd8318a Mon Sep 17 00:00:00 2001 +From: Martin Blumenstingl +Date: Sun, 20 Nov 2016 00:23:52 +0100 +Subject: [PATCH 73/79] ARM64: dts: meson-gxl: add USB host support + +This adds USB host support to the Meson GXL SoC. A dwc3 controller is +used for host-mode, while a dwc2 controller is used for device-mode only. +The dwc3 controller's internal roothub has two USB2 ports enabled but no +USB3 port. Each of the ports is supplied by a separate PHY. The USB pins +are connected to the SoC's USBHOST_A and USBOTG_B pins. +Due to the way the roothub works internally the USB PHYs are left +enabled. When the dwc3 controller is disabled the PHY is never powered on +so it does not draw any extra power. However, when the dwc3 host +controller is enabled then all PHYs also have to be enabled, otherwise +USB devices will not be detected (regardless of whether they are plugged +into an enabled port or not). This means that only the dwc3 controller +has to be enabled on boards with USB support (instead of requiring all +boards to enable the PHYs additionally with the chance of forgetting to +enable one and breaking all other ports with that as well). + +Signed-off-by: Martin Blumenstingl +Signed-off-by: Neil Armstrong +--- + arch/arm64/boot/dts/amlogic/meson-gxl.dtsi | 50 ++++++++++++++++++++++++++++++ + 1 file changed, 50 insertions(+) + +diff --git a/arch/arm64/boot/dts/amlogic/meson-gxl.dtsi b/arch/arm64/boot/dts/amlogic/meson-gxl.dtsi +index 1e65b0f..c33c29f 100644 +--- a/arch/arm64/boot/dts/amlogic/meson-gxl.dtsi ++++ b/arch/arm64/boot/dts/amlogic/meson-gxl.dtsi +@@ -49,6 +49,56 @@ + + / { + compatible = "amlogic,meson-gxl"; ++ ++ soc { ++ ++ usb0: usb@c9000000 { ++ compatible = "snps,dwc3"; ++ #address-cells = <1>; ++ #size-cells = <0>; ++ reg = <0x0 0xc9000000 0x0 0x100000>; ++ interrupts = ; ++ dr_mode = "host"; ++ maximum-speed = "high-speed"; ++ snps,dis_u2_susphy_quirk; ++ status = "disabled"; ++ ++ dwc3_roothub: roothub@0 { ++ compatible = "usb1d6b,3", "usb1d6b,2"; ++ #address-cells = <1>; ++ #size-cells = <0>; ++ reg = <0>; ++ ++ port@1 { ++ reg = <1>; ++ phys = <&usb2_phy0>; ++ phy-names = "usb2-phy"; ++ }; ++ ++ port@2 { ++ reg = <2>; ++ phys = <&usb2_phy1>; ++ phy-names = "usb2-phy"; ++ }; ++ }; ++ }; ++ }; ++}; ++ ++&apb { ++ usb2_phy0: phy@78000 { ++ compatible = "amlogic,meson-gxl-usb2-phy"; ++ #phy-cells = <0>; ++ reg = <0x0 0x78000 0x0 0x20>; ++ status = "okay"; ++ }; ++ ++ usb2_phy1: phy@78020 { ++ compatible = "amlogic,meson-gxl-usb2-phy"; ++ #phy-cells = <0>; ++ reg = <0x0 0x78020 0x0 0x20>; ++ status = "okay"; ++ }; + }; + + ðmac { +-- +1.9.1 + diff --git a/patch/kernel/odroidc2-next/0073-ARM64-meson-gxbb-add-i2s-output-pins.patch b/patch/kernel/odroidc2-next/0073-ARM64-meson-gxbb-add-i2s-output-pins.patch deleted file mode 100644 index 77db91af9..000000000 --- a/patch/kernel/odroidc2-next/0073-ARM64-meson-gxbb-add-i2s-output-pins.patch +++ /dev/null @@ -1,88 +0,0 @@ -From b5471e9b3a9700b023c9ee1b9eb4b0a10af72427 Mon Sep 17 00:00:00 2001 -From: Jerome Brunet -Date: Thu, 26 Jan 2017 11:09:54 +0100 -Subject: [PATCH 73/93] ARM64: meson: gxbb: add i2s output pins - -Signed-off-by: Jerome Brunet ---- - arch/arm64/boot/dts/amlogic/meson-gxbb.dtsi | 57 +++++++++++++++++++++++++++++ - 1 file changed, 57 insertions(+) - -diff --git a/arch/arm64/boot/dts/amlogic/meson-gxbb.dtsi b/arch/arm64/boot/dts/amlogic/meson-gxbb.dtsi -index b897ad6..ea111a2 100644 ---- a/arch/arm64/boot/dts/amlogic/meson-gxbb.dtsi -+++ b/arch/arm64/boot/dts/amlogic/meson-gxbb.dtsi -@@ -238,6 +238,42 @@ - function = "pwm_ao_b"; - }; - }; -+ -+ i2s_am_clk_pins: i2s_am_clk { -+ mux { -+ groups = "i2s_am_clk"; -+ function = "i2s_out_ao"; -+ }; -+ }; -+ -+ i2s_out_bclks_pins: i2s_out_bclks { -+ mux { -+ groups = "i2s_out_ao_clk", -+ "i2s_out_lr_clk"; -+ function = "i2s_out_ao"; -+ }; -+ }; -+ -+ i2s_out_ch01_ao_pins: i2s_out_ch01_ao { -+ mux { -+ groups = "i2s_out_ch01_ao"; -+ function = "i2s_out_ao"; -+ }; -+ }; -+ -+ i2s_out_ch23_ao_pins: i2s_out_ch23_ao { -+ mux { -+ groups = "i2s_out_ch23_ao"; -+ function = "i2s_out_ao"; -+ }; -+ }; -+ -+ i2s_out_ch45_ao_pins: i2s_out_ch45_ao { -+ mux { -+ groups = "i2s_out_ch45_ao"; -+ function = "i2s_out_ao"; -+ }; -+ }; - }; - - clkc_AO: clock-controller@040 { -@@ -479,6 +515,27 @@ - function = "hdmi_i2c"; - }; - }; -+ -+ i2sout_ch23_y_pins: i2sout_ch23_y { -+ mux { -+ groups = "i2sout_ch23_y"; -+ function = "i2s_out_y"; -+ }; -+ }; -+ -+ i2sout_ch45_y_pins: i2sout_ch45_y { -+ mux { -+ groups = "i2sout_ch45_y"; -+ function = "i2s_out_y"; -+ }; -+ }; -+ -+ i2sout_ch67_y_pins: i2sout_ch67_y { -+ mux { -+ groups = "i2sout_ch67_y"; -+ function = "i2s_out_y"; -+ }; -+ }; - }; - }; - --- -1.9.1 - diff --git a/patch/kernel/odroidc2-next/0074-ARM64-dts-meson-gxm-add-GXM-specific-USB-host-config.patch b/patch/kernel/odroidc2-next/0074-ARM64-dts-meson-gxm-add-GXM-specific-USB-host-config.patch new file mode 100644 index 000000000..51845ea61 --- /dev/null +++ b/patch/kernel/odroidc2-next/0074-ARM64-dts-meson-gxm-add-GXM-specific-USB-host-config.patch @@ -0,0 +1,49 @@ +From c6b2bca6dbd55fbdd2c5cdf3d214c982a215e6a7 Mon Sep 17 00:00:00 2001 +From: Martin Blumenstingl +Date: Sat, 26 Nov 2016 00:17:22 +0100 +Subject: [PATCH 74/79] ARM64: dts: meson-gxm: add GXM specific USB host + configuration + +The USB configuration on GXM is slightly different than on GXL. The dwc3 +controller's internal hub has three USB2 ports (instead of 2 on GXL) +along with a dedicated USB2 PHY for this port. However, it seems that +there are no pins on GXM which would allow connecting the third port to +a physical USB port. + +Signed-off-by: Martin Blumenstingl +Signed-off-by: Neil Armstrong +--- + arch/arm64/boot/dts/amlogic/meson-gxm.dtsi | 17 +++++++++++++++++ + 1 file changed, 17 insertions(+) + +diff --git a/arch/arm64/boot/dts/amlogic/meson-gxm.dtsi b/arch/arm64/boot/dts/amlogic/meson-gxm.dtsi +index fe451cc..4089f04 100644 +--- a/arch/arm64/boot/dts/amlogic/meson-gxm.dtsi ++++ b/arch/arm64/boot/dts/amlogic/meson-gxm.dtsi +@@ -117,6 +117,23 @@ + }; + }; + ++&apb { ++ usb2_phy2: phy@78040 { ++ compatible = "amlogic,meson-gxl-usb2-phy"; ++ #phy-cells = <0>; ++ reg = <0x0 0x78040 0x0 0x20>; ++ status = "disabled"; ++ }; ++}; ++ ++&dwc3_roothub { ++ port@3 { ++ reg = <3>; ++ phys = <&usb2_phy2>; ++ phy-names = "usb2-phy"; ++ }; ++}; ++ + &saradc { + compatible = "amlogic,meson-gxm-saradc", "amlogic,meson-saradc"; + }; +-- +1.9.1 + diff --git a/patch/kernel/odroidc2-next/0075-snd-meson-add-audin-register-definitions.patch b/patch/kernel/odroidc2-next/0075-snd-meson-add-audin-register-definitions.patch deleted file mode 100644 index f80a47a6e..000000000 --- a/patch/kernel/odroidc2-next/0075-snd-meson-add-audin-register-definitions.patch +++ /dev/null @@ -1,172 +0,0 @@ -From 788001e5eb1bab1464a9f6e97e5619f3994ff5ba Mon Sep 17 00:00:00 2001 -From: Jerome Brunet -Date: Thu, 19 Jan 2017 15:49:39 +0100 -Subject: [PATCH 75/93] snd: meson: add audin register definitions - -Signed-off-by: Jerome Brunet ---- - sound/soc/meson/audin-regs.h | 152 +++++++++++++++++++++++++++++++++++++++++++ - 1 file changed, 152 insertions(+) - create mode 100644 sound/soc/meson/audin-regs.h - -diff --git a/sound/soc/meson/audin-regs.h b/sound/soc/meson/audin-regs.h -new file mode 100644 -index 0000000..f6f3203 ---- /dev/null -+++ b/sound/soc/meson/audin-regs.h -@@ -0,0 +1,152 @@ -+/* -+ * Copyright (C) 2017 BayLibre, SAS -+ * Author: Jerome Brunet -+ * Copyright (C) 2017 Amlogic, Inc. All rights reserved. -+ * -+ * This program is free software; you can redistribute it and/or -+ * modify it under the terms of the GNU General Public License as -+ * published by the Free Software Foundation; either version 2 of the -+ * License, or (at your option) any later version. -+ * -+ * This program is distributed in the hope that it will be useful, but -+ * WITHOUT ANY WARRANTY; without even the implied warranty of -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -+ * General Public License for more details. -+ * -+ * You should have received a copy of the GNU General Public License -+ * along with this program; if not, see . -+ */ -+ -+#ifndef _AUDIN_REGS_H_ -+#define _AUDIN_REGS_H_ -+ -+/* Base address of Audio In module in Cbus */ -+#define AUDIN_CBUS_BASE 0xA000 /* REALLY USEFUL ??? */ -+ -+/* -+ * Note : -+ * Datasheet issue page 196 -+ * AUDIN_MUTE_VAL 0x35 => impossible: Already assigned to AUDIN_FIFO1_PTR -+ * AUDIN_FIFO1_PTR is more likely to be correct since surrounding registers -+ * also deal with AUDIN_FIFO1 -+ * -+ * Clarification needed from Amlogic -+ */ -+ -+/* Audin module registers */ -+#define AUDIN_SPDIF_MODE 0x000 -+#define AUDIN_SPDIF_FS_CLK_RLTN 0x004 -+#define AUDIN_SPDIF_CHNL_STS_A 0x008 -+#define AUDIN_SPDIF_CHNL_STS_B 0x00C -+#define AUDIN_SPDIF_MISC 0x010 -+#define AUDIN_SPDIF_NPCM_PCPD 0x014 -+#define AUDIN_SPDIF_END 0x03C /* Unknown */ -+#define AUDIN_I2SIN_CTRL 0x040 -+#define AUDIN_SOURCE_SEL 0x044 -+#define AUDIN_DECODE_FORMAT 0x048 -+#define AUDIN_DECODE_CONTROL_STATUS 0x04C -+#define AUDIN_DECODE_CHANNEL_STATUS_A_0 0x050 -+#define AUDIN_DECODE_CHANNEL_STATUS_A_1 0x054 -+#define AUDIN_DECODE_CHANNEL_STATUS_A_2 0x058 -+#define AUDIN_DECODE_CHANNEL_STATUS_A_3 0x05C -+#define AUDIN_DECODE_CHANNEL_STATUS_A_4 0x060 -+#define AUDIN_DECODE_CHANNEL_STATUS_A_5 0x064 -+#define AUDIN_FIFO0_START 0x080 -+#define AUDIN_FIFO0_END 0x084 -+#define AUDIN_FIFO0_PTR 0x088 -+#define AUDIN_FIFO0_INTR 0x08C -+#define AUDIN_FIFO0_RDPTR 0x090 -+#define AUDIN_FIFO0_CTRL 0x094 -+#define AUDIN_FIFO0_CTRL1 0x098 -+#define AUDIN_FIFO0_LVL0 0x09C -+#define AUDIN_FIFO0_LVL1 0x0A0 -+#define AUDIN_FIFO0_LVL2 0x0A4 -+#define AUDIN_FIFO0_REQID 0x0C0 -+#define AUDIN_FIFO0_WRAP 0x0C4 -+#define AUDIN_FIFO1_START 0x0CC -+#define AUDIN_FIFO1_END 0x0D0 -+#define AUDIN_FIFO1_PTR 0x0D4 -+#define AUDIN_FIFO1_INTR 0x0D8 -+#define AUDIN_FIFO1_RDPTR 0x0DC -+#define AUDIN_FIFO1_CTRL 0x0E0 -+#define AUDIN_FIFO1_CTRL1 0x0E4 -+#define AUDIN_FIFO1_LVL0 0x100 -+#define AUDIN_FIFO1_LVL1 0x104 -+#define AUDIN_FIFO1_LVL2 0x108 -+#define AUDIN_FIFO1_REQID 0x10C -+#define AUDIN_FIFO1_WRAP 0x110 -+#define AUDIN_FIFO2_START 0x114 -+#define AUDIN_FIFO2_END 0x118 -+#define AUDIN_FIFO2_PTR 0x11C -+#define AUDIN_FIFO2_INTR 0x120 -+#define AUDIN_FIFO2_RDPTR 0x124 -+#define AUDIN_FIFO2_CTRL 0x128 -+#define AUDIN_FIFO2_CTRL1 0x12C -+#define AUDIN_FIFO2_LVL0 0x130 -+#define AUDIN_FIFO2_LVL1 0x134 -+#define AUDIN_FIFO2_LVL2 0x138 -+#define AUDIN_FIFO2_REQID 0x13C -+#define AUDIN_FIFO2_WRAP 0x140 -+#define AUDIN_INT_CTRL 0x144 -+#define AUDIN_FIFO_INT 0x148 -+#define PCMIN_CTRL0 0x180 -+#define PCMIN_CTRL1 0x184 -+#define PCMIN1_CTRL0 0x188 -+#define PCMIN1_CTRL1 0x18C -+#define PCMOUT_CTRL0 0x1C0 -+#define PCMOUT_CTRL1 0x1C4 -+#define PCMOUT_CTRL2 0x1C8 -+#define PCMOUT_CTRL3 0x1CC -+#define PCMOUT1_CTRL0 0x1D0 -+#define PCMOUT1_CTRL1 0x1D4 -+#define PCMOUT1_CTRL2 0x1D8 -+#define PCMOUT1_CTRL3 0x1DC -+#define AUDOUT_CTRL 0x200 -+#define AUDOUT_CTRL1 0x204 -+#define AUDOUT_BUF0_STA 0x208 -+#define AUDOUT_BUF0_EDA 0x20C -+#define AUDOUT_BUF0_WPTR 0x210 -+#define AUDOUT_BUF1_STA 0x214 -+#define AUDOUT_BUF1_EDA 0x218 -+#define AUDOUT_BUF1_WPTR 0x21C -+#define AUDOUT_FIFO_RPTR 0x220 -+#define AUDOUT_INTR_PTR 0x224 -+#define AUDOUT_FIFO_STS 0x228 -+#define AUDOUT1_CTRL 0x240 -+#define AUDOUT1_CTRL1 0x244 -+#define AUDOUT1_BUF0_STA 0x248 -+#define AUDOUT1_BUF0_EDA 0x24C -+#define AUDOUT1_BUF0_WPTR 0x250 -+#define AUDOUT1_BUF1_STA 0x254 -+#define AUDOUT1_BUF1_EDA 0x258 -+#define AUDOUT1_BUF1_WPTR 0x25C -+#define AUDOUT1_FIFO_RPTR 0x260 -+#define AUDOUT1_INTR_PTR 0x264 -+#define AUDOUT1_FIFO_STS 0x268 -+#define AUDIN_HDMI_MEAS_CTRL 0x280 -+#define AUDIN_HDMI_MEAS_CYCLES_M1 0x284 -+#define AUDIN_HDMI_MEAS_INTR_MASKN 0x288 -+#define AUDIN_HDMI_MEAS_INTR_STAT 0x28C -+#define AUDIN_HDMI_REF_CYCLES_STAT_0 0x290 -+#define AUDIN_HDMI_REF_CYCLES_STAT_1 0x294 -+#define AUDIN_HDMIRX_AFIFO_STAT 0x298 -+#define AUDIN_FIFO0_PIO_STS 0x2C0 -+#define AUDIN_FIFO0_PIO_RDL 0x2C4 -+#define AUDIN_FIFO0_PIO_RDH 0x2C8 -+#define AUDIN_FIFO1_PIO_STS 0x2CC -+#define AUDIN_FIFO1_PIO_RDL 0x2D0 -+#define AUDIN_FIFO1_PIO_RDH 0x2D4 -+#define AUDIN_FIFO2_PIO_STS 0x2D8 -+#define AUDIN_FIFO2_PIO_RDL 0x2DC -+#define AUDIN_FIFO2_PIO_RDH 0x2E0 -+#define AUDOUT_FIFO_PIO_STS 0x2E4 -+#define AUDOUT_FIFO_PIO_WRL 0x2E8 -+#define AUDOUT_FIFO_PIO_WRH 0x2EC -+#define AUDOUT1_FIFO_PIO_STS 0x2F0 /* Unknown */ -+#define AUDOUT1_FIFO_PIO_WRL 0x2F4 /* Unknown */ -+#define AUDOUT1_FIFO_PIO_WRH 0x2F8 /* Unknown */ -+#define AUD_RESAMPLE_CTRL0 0x2FC -+#define AUD_RESAMPLE_CTRL1 0x300 -+#define AUD_RESAMPLE_STATUS 0x304 -+ -+#endif /* _AUDIN_REGS_H_ */ --- -1.9.1 - diff --git a/patch/kernel/odroidc2-next/0075-usb-host-add-a-generic-platform-USB-roothub-driver.patch b/patch/kernel/odroidc2-next/0075-usb-host-add-a-generic-platform-USB-roothub-driver.patch new file mode 100644 index 000000000..7cfb43b43 --- /dev/null +++ b/patch/kernel/odroidc2-next/0075-usb-host-add-a-generic-platform-USB-roothub-driver.patch @@ -0,0 +1,293 @@ +From acfe799c4e00a726cdb0bbd37aaaa123070ed59e Mon Sep 17 00:00:00 2001 +From: Martin Blumenstingl +Date: Tue, 10 Jan 2017 18:59:43 +0100 +Subject: [PATCH 75/79] usb: host: add a generic platform USB roothub driver + +Many SoC platforms have separate devices for the USB PHY which are +registered through the generic PHY framework. These PHYs have to be +enabled to make the USB controller actually work. They also have to be +disabled again on shutdown/suspend. + +Currently (at least) the following HCI platform drivers are using custom +code to obtain all PHYs via devicetree for the roothub/controller and +disable/enable them when required: +- ehci-platform.c has ehci_platform_power_{on,off} +- xhci-mtk.c has xhci_mtk_phy_{init,exit,power_on,power_off} +- ohci-platform.c has ohci_platform_power_{on,off} + +These drivers are not using the generic devicetree USB device bindings +yet which were only introduced recently (documentation is available in +devicetree/bindings/usb/usb-device.txt). +With this new driver the usb2-phy and usb3-phy can be specified directly +in the child-node of the corresponding port of the roothub via +devicetree. This can be extended by not just parsing PHYs (some of the +other drivers listed above are for example also parsing a list of clocks +as well) when required. + +Signed-off-by: Martin Blumenstingl +Signed-off-by: Neil Armstrong +--- + .../devicetree/bindings/usb/usb-roothub.txt | 46 +++++++ + drivers/usb/host/Kconfig | 3 + + drivers/usb/host/Makefile | 2 + + drivers/usb/host/platform-roothub.c | 146 +++++++++++++++++++++ + drivers/usb/host/platform-roothub.h | 14 ++ + 5 files changed, 211 insertions(+) + create mode 100644 Documentation/devicetree/bindings/usb/usb-roothub.txt + create mode 100644 drivers/usb/host/platform-roothub.c + create mode 100644 drivers/usb/host/platform-roothub.h + +diff --git a/Documentation/devicetree/bindings/usb/usb-roothub.txt b/Documentation/devicetree/bindings/usb/usb-roothub.txt +new file mode 100644 +index 0000000..23b24b6 +--- /dev/null ++++ b/Documentation/devicetree/bindings/usb/usb-roothub.txt +@@ -0,0 +1,46 @@ ++Generic USB root-hub Properties ++ ++similar to the USB device bindings (documented in usb-device.txt from the ++current directory) this provides support for configuring the root-hub. ++ ++Required properties: ++- compatible: should be at least one of "usb1d6b,3", "usb1d6b,2" ++- reg: must be 0. ++- address-cells: must be 1 ++- size-cells: must be 0 ++ ++Required sub-nodes: ++a sub-node per actual USB port is required. each sub-node supports the ++following properties: ++ Required properties: ++ - reg: the port number on the root-hub (mandatory) ++ Optional properties: ++ - phys: optional, from the *Generic PHY* bindings (mandatory needed ++ when phy-names is given) ++ - phy-names: optional, from the *Generic PHY* bindings; supported names ++ are "usb2-phy" or "usb3-phy" ++ ++Example: ++ &usb1 { ++ #address-cells = <1>; ++ #size-cells = <0>; ++ ++ roothub@0 { ++ compatible = "usb1d6b,3", "usb1d6b,2"; ++ #address-cells = <1>; ++ #size-cells = <0>; ++ reg = <0>; ++ ++ port@1 { ++ reg = <1>; ++ usb-phy = <&usb2_phy1>, <&usb3_phy1>; ++ phy-names = "usb2-phy", "usb3-phy"; ++ }; ++ ++ port@2 { ++ reg = <2>; ++ usb-phy = <&usb2_phy2>, <&usb3_phy2>; ++ phy-names = "usb2-phy", "usb3-phy"; ++ }; ++ }; ++ } +diff --git a/drivers/usb/host/Kconfig b/drivers/usb/host/Kconfig +index ababb91..3f450e0 100644 +--- a/drivers/usb/host/Kconfig ++++ b/drivers/usb/host/Kconfig +@@ -797,6 +797,9 @@ config USB_HCD_SSB + + If unsure, say N. + ++config USB_PLATFORM_ROOTHUB ++ bool ++ + config USB_HCD_TEST_MODE + bool "HCD test mode support" + ---help--- +diff --git a/drivers/usb/host/Makefile b/drivers/usb/host/Makefile +index c77b0a3..93f0dd2 100644 +--- a/drivers/usb/host/Makefile ++++ b/drivers/usb/host/Makefile +@@ -29,6 +29,8 @@ obj-$(CONFIG_USB_WHCI_HCD) += whci/ + + obj-$(CONFIG_USB_PCI) += pci-quirks.o + ++obj-$(CONFIG_USB_PLATFORM_ROOTHUB) += platform-roothub.o ++ + obj-$(CONFIG_USB_EHCI_HCD) += ehci-hcd.o + obj-$(CONFIG_USB_EHCI_PCI) += ehci-pci.o + obj-$(CONFIG_USB_EHCI_HCD_PLATFORM) += ehci-platform.o +diff --git a/drivers/usb/host/platform-roothub.c b/drivers/usb/host/platform-roothub.c +new file mode 100644 +index 0000000..84837e4 +--- /dev/null ++++ b/drivers/usb/host/platform-roothub.c +@@ -0,0 +1,146 @@ ++/* ++ * platform roothub driver - a virtual PHY device which passes all phy_* ++ * function calls to multiple (actual) PHY devices. This is comes handy when ++ * initializing all PHYs on a root-hub (to keep them all in the same state). ++ * ++ * Copyright (C) 2017 Martin Blumenstingl ++ * ++ * This program is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License version 2 as ++ * published by the Free Software Foundation. ++ * ++ * You should have received a copy of the GNU General Public License ++ * along with this program. If not, see . ++ */ ++ ++#include ++#include ++#include ++#include ++#include ++ ++#include "platform-roothub.h" ++ ++#define ROOTHUB_PORTNUM 0 ++ ++struct platform_roothub { ++ struct phy *phy; ++ struct list_head list; ++}; ++ ++static struct platform_roothub *platform_roothub_alloc(struct device *dev) ++{ ++ struct platform_roothub *roothub_entry; ++ ++ roothub_entry = devm_kzalloc(dev, sizeof(*roothub_entry), GFP_KERNEL); ++ if (!roothub_entry) ++ return ERR_PTR(-ENOMEM); ++ ++ INIT_LIST_HEAD(&roothub_entry->list); ++ ++ return roothub_entry; ++} ++ ++static int platform_roothub_add_phy(struct device *dev, ++ struct device_node *port_np, ++ const char *con_id, struct list_head *list) ++{ ++ struct platform_roothub *roothub_entry; ++ struct phy *phy = devm_of_phy_get(dev, port_np, con_id); ++ ++ if (IS_ERR_OR_NULL(phy)) { ++ if (!phy || PTR_ERR(phy) == -ENODEV) ++ return 0; ++ else ++ return PTR_ERR(phy); ++ } ++ ++ roothub_entry = platform_roothub_alloc(dev); ++ if (IS_ERR(roothub_entry)) ++ return PTR_ERR(roothub_entry); ++ ++ roothub_entry->phy = phy; ++ ++ list_add_tail(&roothub_entry->list, list); ++ ++ return 0; ++} ++ ++struct platform_roothub *platform_roothub_init(struct device *dev) ++{ ++ struct device_node *roothub_np, *port_np; ++ struct platform_roothub *plat_roothub; ++ int err; ++ ++ roothub_np = usb_of_get_child_node(dev->of_node, ROOTHUB_PORTNUM); ++ if (!of_device_is_available(roothub_np)) ++ return NULL; ++ ++ plat_roothub = platform_roothub_alloc(dev); ++ if (IS_ERR(plat_roothub)) ++ return plat_roothub; ++ ++ for_each_available_child_of_node(roothub_np, port_np) { ++ err = platform_roothub_add_phy(dev, port_np, "usb2-phy", ++ &plat_roothub->list); ++ if (err) ++ return ERR_PTR(err); ++ ++ err = platform_roothub_add_phy(dev, port_np, "usb3-phy", ++ &plat_roothub->list); ++ if (err) ++ return ERR_PTR(err); ++ } ++ ++ return plat_roothub; ++} ++EXPORT_SYMBOL_GPL(platform_roothub_init); ++ ++int platform_roothub_power_on(struct platform_roothub *plat_roothub) ++{ ++ struct platform_roothub *roothub_entry; ++ struct list_head *head; ++ int err; ++ ++ if (!plat_roothub) ++ return 0; ++ ++ head = &plat_roothub->list; ++ ++ list_for_each_entry(roothub_entry, head, list) { ++ err = phy_init(roothub_entry->phy); ++ if (err) ++ goto err_out; ++ ++ err = phy_power_on(roothub_entry->phy); ++ if (err) { ++ phy_exit(roothub_entry->phy); ++ goto err_out; ++ } ++ } ++ ++ return 0; ++ ++err_out: ++ list_for_each_entry_continue_reverse(roothub_entry, head, list) { ++ phy_power_off(roothub_entry->phy); ++ phy_exit(roothub_entry->phy); ++ } ++ ++ return err; ++} ++EXPORT_SYMBOL_GPL(platform_roothub_power_on); ++ ++void platform_roothub_power_off(struct platform_roothub *plat_roothub) ++{ ++ struct platform_roothub *roothub_entry; ++ ++ if (!plat_roothub) ++ return; ++ ++ list_for_each_entry_reverse(roothub_entry, &plat_roothub->list, list) { ++ phy_power_off(roothub_entry->phy); ++ phy_exit(roothub_entry->phy); ++ } ++} ++EXPORT_SYMBOL_GPL(platform_roothub_power_off); +diff --git a/drivers/usb/host/platform-roothub.h b/drivers/usb/host/platform-roothub.h +new file mode 100644 +index 0000000..bde0bf2 +--- /dev/null ++++ b/drivers/usb/host/platform-roothub.h +@@ -0,0 +1,14 @@ ++#ifndef USB_HOST_PLATFORM_ROOTHUB_H ++#define USB_HOST_PLATFORM_ROOTHUB_H ++ ++struct phy; ++struct device_node; ++ ++struct platform_roothub; ++ ++struct platform_roothub *platform_roothub_init(struct device *dev); ++ ++int platform_roothub_power_on(struct platform_roothub *plat_roothub); ++void platform_roothub_power_off(struct platform_roothub *plat_roothub); ++ ++#endif /* USB_HOST_PLATFORM_ROOTHUB_H */ +-- +1.9.1 + diff --git a/patch/kernel/odroidc2-next/0076-usb-host-xhci-plat-integrate-the-platform-roothub.patch b/patch/kernel/odroidc2-next/0076-usb-host-xhci-plat-integrate-the-platform-roothub.patch new file mode 100644 index 000000000..09e4f6af3 --- /dev/null +++ b/patch/kernel/odroidc2-next/0076-usb-host-xhci-plat-integrate-the-platform-roothub.patch @@ -0,0 +1,146 @@ +From 9dfd5d48fbcd31b12825e81d532aca76c2b769f8 Mon Sep 17 00:00:00 2001 +From: Martin Blumenstingl +Date: Wed, 11 Jan 2017 11:34:59 +0100 +Subject: [PATCH 76/79] usb: host: xhci: plat: integrate the platform-roothub + +This enables the platform-roothub for the xhci-plat driver. This allows +specifying a PHY for each port via devicetree. All PHYs will then be +enabled/disabled by the platform-roothub driver. + +One example where this is required is the Amlogic GXL and GXM SoCs: +They are using a dwc3 USB controller with up to three ports enabled on +the internal roothub. Using only the top-level "phy" properties does not +work here since one can only specify one "usb2-phy" and one "usb3-phy", +while actually at least two "usb2-phy" have to be specified. + +Signed-off-by: Martin Blumenstingl +Signed-off-by: Neil Armstrong +--- + Documentation/devicetree/bindings/usb/usb-xhci.txt | 7 ++++++ + drivers/usb/host/Kconfig | 1 + + drivers/usb/host/xhci-plat.c | 26 +++++++++++++++++++++- + drivers/usb/host/xhci.h | 3 +++ + 4 files changed, 36 insertions(+), 1 deletion(-) + +diff --git a/Documentation/devicetree/bindings/usb/usb-xhci.txt b/Documentation/devicetree/bindings/usb/usb-xhci.txt +index 2d80b60..31b4f68 100644 +--- a/Documentation/devicetree/bindings/usb/usb-xhci.txt ++++ b/Documentation/devicetree/bindings/usb/usb-xhci.txt +@@ -29,6 +29,13 @@ Optional properties: + - usb3-lpm-capable: determines if platform is USB3 LPM capable + - quirk-broken-port-ped: set if the controller has broken port disable mechanism + ++sub-nodes: ++- optionally there can be a node for the root-hub, see usb-roothub.txt in the ++ current directory ++- one or more nodes with reg 1-31 for each port to which a device is connected. ++ See usb-device.txt in the current directory for more information. ++ ++ + Example: + usb@f0931000 { + compatible = "generic-xhci"; +diff --git a/drivers/usb/host/Kconfig b/drivers/usb/host/Kconfig +index 3f450e0..d6279d7 100644 +--- a/drivers/usb/host/Kconfig ++++ b/drivers/usb/host/Kconfig +@@ -36,6 +36,7 @@ config USB_XHCI_PCI + config USB_XHCI_PLATFORM + tristate "Generic xHCI driver for a platform device" + select USB_XHCI_RCAR if ARCH_RENESAS ++ select USB_PLATFORM_ROOTHUB + ---help--- + Adds an xHCI host driver for a generic platform device, which + provides a memory space and an irq. +diff --git a/drivers/usb/host/xhci-plat.c b/drivers/usb/host/xhci-plat.c +index c04144b..4de20b5 100644 +--- a/drivers/usb/host/xhci-plat.c ++++ b/drivers/usb/host/xhci-plat.c +@@ -285,10 +285,20 @@ static int xhci_plat_probe(struct platform_device *pdev) + goto put_usb3_hcd; + } + +- ret = usb_add_hcd(hcd, irq, IRQF_SHARED); ++ xhci->platform_roothub = platform_roothub_init(sysdev); ++ if (IS_ERR(xhci->platform_roothub)) { ++ ret = PTR_ERR(xhci->platform_roothub); ++ goto disable_clk; ++ } ++ ++ ret = platform_roothub_power_on(xhci->platform_roothub); + if (ret) + goto disable_usb_phy; + ++ ret = usb_add_hcd(hcd, irq, IRQF_SHARED); ++ if (ret) ++ goto disable_platform_roothub; ++ + if (HCC_MAX_PSA(xhci->hcc_params) >= 4) + xhci->shared_hcd->can_do_streams = 1; + +@@ -311,6 +321,9 @@ static int xhci_plat_probe(struct platform_device *pdev) + dealloc_usb2_hcd: + usb_remove_hcd(hcd); + ++disable_platform_roothub: ++ platform_roothub_power_off(xhci->platform_roothub); ++ + disable_usb_phy: + usb_phy_shutdown(hcd->usb_phy); + +@@ -342,6 +355,8 @@ static int xhci_plat_remove(struct platform_device *dev) + usb_remove_hcd(xhci->shared_hcd); + usb_phy_shutdown(hcd->usb_phy); + ++ platform_roothub_power_off(xhci->platform_roothub); ++ + usb_remove_hcd(hcd); + usb_put_hcd(xhci->shared_hcd); + +@@ -374,6 +389,11 @@ static int __maybe_unused xhci_plat_suspend(struct device *dev) + if (!device_may_wakeup(dev) && !IS_ERR(xhci->clk)) + clk_disable_unprepare(xhci->clk); + ++ if (ret) ++ return ret; ++ ++ platform_roothub_power_off(xhci->platform_roothub); ++ + return ret; + } + +@@ -386,6 +406,10 @@ static int __maybe_unused xhci_plat_resume(struct device *dev) + if (!device_may_wakeup(dev) && !IS_ERR(xhci->clk)) + clk_prepare_enable(xhci->clk); + ++ ret = platform_roothub_power_on(xhci->platform_roothub); ++ if (ret) ++ return ret; ++ + ret = xhci_priv_resume_quirk(hcd); + if (ret) + return ret; +diff --git a/drivers/usb/host/xhci.h b/drivers/usb/host/xhci.h +index 73a28a9..7f3d15e 100644 +--- a/drivers/usb/host/xhci.h ++++ b/drivers/usb/host/xhci.h +@@ -34,6 +34,8 @@ + #include "xhci-ext-caps.h" + #include "pci-quirks.h" + ++#include "platform-roothub.h" ++ + /* xHCI PCI Configuration Registers */ + #define XHCI_SBRN_OFFSET (0x60) + +@@ -1725,6 +1727,7 @@ struct xhci_hcd { + int msix_count; + /* optional clock */ + struct clk *clk; ++ struct platform_roothub *platform_roothub; + /* data structures */ + struct xhci_device_context_array *dcbaa; + struct xhci_ring *cmd_ring; +-- +1.9.1 + diff --git a/patch/kernel/odroidc2-next/0077-ARM64-dts-meson-gx-Enable-USB-on-GXL-and-GXM-boards.patch b/patch/kernel/odroidc2-next/0077-ARM64-dts-meson-gx-Enable-USB-on-GXL-and-GXM-boards.patch new file mode 100644 index 000000000..600e80f2c --- /dev/null +++ b/patch/kernel/odroidc2-next/0077-ARM64-dts-meson-gx-Enable-USB-on-GXL-and-GXM-boards.patch @@ -0,0 +1,64 @@ +From 7079f88717e54f9ea48c1cbfba09b53cc8b9aefd Mon Sep 17 00:00:00 2001 +From: Neil Armstrong +Date: Thu, 13 Jul 2017 15:02:33 +0200 +Subject: [PATCH 77/79] ARM64: dts: meson-gx: Enable USB on GXL and GXM boards + +Signed-off-by: Neil Armstrong +--- + arch/arm64/boot/dts/amlogic/meson-gx-p23x-q20x.dtsi | 4 ++++ + arch/arm64/boot/dts/amlogic/meson-gxl-s905x-nexbox-a95x.dts | 4 ++++ + arch/arm64/boot/dts/amlogic/meson-gxl-s905x-p212.dtsi | 4 ++++ + arch/arm64/boot/dts/amlogic/meson-gxm-nexbox-a1.dts | 4 ++++ + 4 files changed, 16 insertions(+) + +diff --git a/arch/arm64/boot/dts/amlogic/meson-gx-p23x-q20x.dtsi b/arch/arm64/boot/dts/amlogic/meson-gx-p23x-q20x.dtsi +index 54718ee..bf49f6f 100644 +--- a/arch/arm64/boot/dts/amlogic/meson-gx-p23x-q20x.dtsi ++++ b/arch/arm64/boot/dts/amlogic/meson-gx-p23x-q20x.dtsi +@@ -234,3 +234,7 @@ + remote-endpoint = <&hdmi_connector_in>; + }; + }; ++ ++&usb0 { ++ status = "okay"; ++}; +diff --git a/arch/arm64/boot/dts/amlogic/meson-gxl-s905x-nexbox-a95x.dts b/arch/arm64/boot/dts/amlogic/meson-gxl-s905x-nexbox-a95x.dts +index 55ec11a..19bb39b 100644 +--- a/arch/arm64/boot/dts/amlogic/meson-gxl-s905x-nexbox-a95x.dts ++++ b/arch/arm64/boot/dts/amlogic/meson-gxl-s905x-nexbox-a95x.dts +@@ -249,3 +249,7 @@ + remote-endpoint = <&hdmi_connector_in>; + }; + }; ++ ++&usb0 { ++ status = "okay"; ++}; +diff --git a/arch/arm64/boot/dts/amlogic/meson-gxl-s905x-p212.dtsi b/arch/arm64/boot/dts/amlogic/meson-gxl-s905x-p212.dtsi +index f3eea8e..a07c34d 100644 +--- a/arch/arm64/boot/dts/amlogic/meson-gxl-s905x-p212.dtsi ++++ b/arch/arm64/boot/dts/amlogic/meson-gxl-s905x-p212.dtsi +@@ -171,3 +171,7 @@ + pinctrl-0 = <&uart_ao_a_pins>; + pinctrl-names = "default"; + }; ++ ++&usb0 { ++ status = "okay"; ++}; +diff --git a/arch/arm64/boot/dts/amlogic/meson-gxm-nexbox-a1.dts b/arch/arm64/boot/dts/amlogic/meson-gxm-nexbox-a1.dts +index 3a327dd..1b7038d 100644 +--- a/arch/arm64/boot/dts/amlogic/meson-gxm-nexbox-a1.dts ++++ b/arch/arm64/boot/dts/amlogic/meson-gxm-nexbox-a1.dts +@@ -215,3 +215,7 @@ + remote-endpoint = <&hdmi_connector_in>; + }; + }; ++ ++&usb0 { ++ status = "okay"; ++}; +-- +1.9.1 + diff --git a/patch/kernel/odroidc2-next/0077-snd-soc-meson-support-for-aiu-i2s-dai.patch b/patch/kernel/odroidc2-next/0077-snd-soc-meson-support-for-aiu-i2s-dai.patch deleted file mode 100644 index ca3d3fb73..000000000 --- a/patch/kernel/odroidc2-next/0077-snd-soc-meson-support-for-aiu-i2s-dai.patch +++ /dev/null @@ -1,480 +0,0 @@ -From e5e1644671e95c258a854506bf1937a1f5e1dbe1 Mon Sep 17 00:00:00 2001 -From: Jerome Brunet -Date: Sun, 12 Feb 2017 00:53:08 +0100 -Subject: [PATCH 77/93] snd: soc: meson: support for aiu i2s dai - -Initial support for meson aiu i2s dai -TO BE COMPLETED... - -Signed-off-by: Jerome Brunet ---- - sound/soc/meson/Kconfig | 8 + - sound/soc/meson/Makefile | 1 + - sound/soc/meson/aiu-i2s-dai.c | 428 ++++++++++++++++++++++++++++++++++++++++++ - 3 files changed, 437 insertions(+) - create mode 100644 sound/soc/meson/aiu-i2s-dai.c - -diff --git a/sound/soc/meson/Kconfig b/sound/soc/meson/Kconfig -index f2504c6..796eff0 100644 ---- a/sound/soc/meson/Kconfig -+++ b/sound/soc/meson/Kconfig -@@ -1,6 +1,14 @@ - menu "Amlogic SoC Audio Support" - depends on ARCH_MESON || COMPILE_TEST - -+config SND_MESON_AIU_I2S_DAI -+ tristate "Meson I2S Output DAI Support" -+ select MFD_SYSCON -+ select SND_MESON_AIU_COMMON -+ help -+ This adds ASoC driver the Amlogic Meson i2s DAI -+ If unsure select "N". -+ - config SND_MESON_AIU_I2S_DMA - tristate "Meson I2S Output DMA Support" - select MFD_SYSCON -diff --git a/sound/soc/meson/Makefile b/sound/soc/meson/Makefile -index b237894..0fea1c1 100644 ---- a/sound/soc/meson/Makefile -+++ b/sound/soc/meson/Makefile -@@ -1,2 +1,3 @@ - obj-$(CONFIG_SND_MESON_AIU_COMMON) += aiu-common.o -+obj-$(CONFIG_SND_MESON_AIU_I2S_DAI) += aiu-i2s-dai.o - obj-$(CONFIG_SND_MESON_AIU_I2S_DMA) += aiu-i2s-dma.o -diff --git a/sound/soc/meson/aiu-i2s-dai.c b/sound/soc/meson/aiu-i2s-dai.c -new file mode 100644 -index 0000000..6756848 ---- /dev/null -+++ b/sound/soc/meson/aiu-i2s-dai.c -@@ -0,0 +1,428 @@ -+/* -+ * Copyright (C) 2017 BayLibre, SAS -+ * Author: Jerome Brunet -+ * Copyright (C) 2017 Amlogic, Inc. All rights reserved. -+ * -+ * This program is free software; you can redistribute it and/or -+ * modify it under the terms of the GNU General Public License as -+ * published by the Free Software Foundation; either version 2 of the -+ * License, or (at your option) any later version. -+ * -+ * This program is distributed in the hope that it will be useful, but -+ * WITHOUT ANY WARRANTY; without even the implied warranty of -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -+ * General Public License for more details. -+ * -+ * You should have received a copy of the GNU General Public License -+ * along with this program; if not, see . -+ */ -+ -+#include -+#include -+#include -+#include -+#include -+#include -+ -+#include -+#include -+#include -+ -+#include "aiu.h" -+#include "aiu-regs.h" -+ -+#define DRV_NAME "meson-aiu-i2s-dai" -+ -+struct aiu_i2s_dai { -+ struct regmap *regmap; -+ struct clk *amclk; -+ struct clk *aoclk; -+ struct clk *mixer_if; -+ bool bclks_idle; -+}; -+ -+#define AIU_CLK_CTRL_I2S_DIV_EN BIT(0) -+#define AIU_CLK_CTRL_I2S_DIV_MASK GENMASK(3, 2) -+#define AIU_CLK_CTRL_AOCLK_POLARITY_MASK BIT(6) -+#define AIU_CLK_CTRL_AOCLK_POLARITY_NORMAL (0 << 6) -+#define AIU_CLK_CTRL_AOCLK_POLARITY_INVERTED (1 << 6) -+#define AIU_CLK_CTRL_ALRCLK_POLARITY_MASK BIT(7) -+#define AIU_CLK_CTRL_ALRCLK_POLARITY_NORMAL (0 << 7) -+#define AIU_CLK_CTRL_ALRCLK_POLARITY_INVERTED (1 << 7) -+#define AIU_CLK_CTRL_ALRCLK_SKEW_MASK GENMASK(9, 8) -+#define AIU_CLK_CTRL_ALRCLK_LEFT_J (0 << 8) -+#define AIU_CLK_CTRL_ALRCLK_I2S (1 << 8) -+#define AIU_CLK_CTRL_ALRCLK_RIGHT_J (2 << 8) -+#define AIU_CLK_CTRL_MORE_I2S_DIV_MASK GENMASK(5, 0) -+#define AIU_CLK_CTRL_MORE_I2S_DIV(div) ((div - 1) << 0) -+#define AIU_CODEC_DAC_LRCLK_CTRL_DIV_MASK GENMASK(11, 0) -+#define AIU_CODEC_DAC_LRCLK_CTRL_DIV(div) ((div - 1) << 0) -+#define AIU_I2S_DAC_CFG_PAYLOAD_SIZE_MASK GENMASK(1, 0) -+#define AIU_I2S_DAC_CFG_AOCLK_32 (0 << 0) -+#define AIU_I2S_DAC_CFG_AOCLK_48 (2 << 0) -+#define AIU_I2S_DAC_CFG_AOCLK_64 (3 << 0) -+#define AIU_I2S_MISC_HOLD_EN BIT(2) -+#define AIU_I2S_MISC_FORCE_LR BIT(4) -+ -+static void __hold(struct aiu_i2s_dai *priv, bool enable) -+{ -+ regmap_update_bits(priv->regmap, AIU_I2S_MISC, -+ AIU_I2S_MISC_HOLD_EN, -+ enable ? AIU_I2S_MISC_HOLD_EN : 0); -+} -+ -+static void __playback_start(struct aiu_i2s_dai *priv) -+{ -+ regmap_update_bits(priv->regmap, AIU_CLK_CTRL, -+ AIU_CLK_CTRL_I2S_DIV_EN, -+ AIU_CLK_CTRL_I2S_DIV_EN); -+ __hold(priv, false); -+} -+ -+static void __playback_stop(struct aiu_i2s_dai *priv, bool clk_force) -+{ -+ __hold(priv, true); -+ /* Disable the bit clks if necessary */ -+ if (clk_force || !priv->bclks_idle) -+ regmap_update_bits(priv->regmap, AIU_CLK_CTRL, -+ AIU_CLK_CTRL_I2S_DIV_EN, -+ 0); -+ -+} -+ -+static int aiu_i2s_dai_trigger(struct snd_pcm_substream *substream, int cmd, -+ struct snd_soc_dai *dai) -+{ -+ struct aiu_i2s_dai *priv = snd_soc_dai_get_drvdata(dai); -+ bool clk_force_stop = false; -+ -+ switch (cmd) { -+ case SNDRV_PCM_TRIGGER_START: -+ case SNDRV_PCM_TRIGGER_RESUME: -+ case SNDRV_PCM_TRIGGER_PAUSE_RELEASE: -+ __playback_start(priv); -+ return 0; -+ -+ case SNDRV_PCM_TRIGGER_STOP: -+ case SNDRV_PCM_TRIGGER_SUSPEND: -+ clk_force_stop = true; -+ case SNDRV_PCM_TRIGGER_PAUSE_PUSH: -+ __playback_stop(priv, clk_force_stop); -+ return 0; -+ -+ default: -+ return -EINVAL; -+ } -+} -+ -+static int __get_lrclk_div(unsigned int os, unsigned int width) -+{ -+ if (((os % 48) == 0) && (width == 24)) -+ return 48; -+ else if (((os % 64) == 0) && (width == 24)) -+ return 64; -+ else if (((os % 32) == 0) && (width == 16)) -+ return 32; -+ -+ return -EINVAL; -+} -+ -+/* -+ * FIXME: Most of this stuff should be done using CCF when the support of -+ * regmap based clocks is added -+ */ -+static int __bclks_set_rate(struct aiu_i2s_dai *priv, unsigned int srate, -+ unsigned int width) -+{ -+ int div_lrclk, div_bclk; -+ unsigned int os; -+ u32 val; -+ -+ /* Get the oversampling factor */ -+ os = DIV_ROUND_CLOSEST(clk_get_rate(priv->amclk), srate); -+ -+ /* Get the divider between bclk and lrclk */ -+ div_lrclk = __get_lrclk_div(os, width); -+ -+ switch (div_lrclk) { -+ case 32: -+ val = AIU_I2S_DAC_CFG_AOCLK_32; -+ break; -+ case 48: -+ val = AIU_I2S_DAC_CFG_AOCLK_48; -+ break; -+ case 64: -+ val = AIU_I2S_DAC_CFG_AOCLK_64; -+ break; -+ default: -+ return -EINVAL; -+ } -+ -+ /* Set the divider between lrclk and bclk */ -+ regmap_update_bits(priv->regmap, AIU_I2S_DAC_CFG, -+ AIU_I2S_DAC_CFG_PAYLOAD_SIZE_MASK, -+ val); -+ -+ regmap_update_bits(priv->regmap, AIU_CODEC_DAC_LRCLK_CTRL, -+ AIU_CODEC_DAC_LRCLK_CTRL_DIV_MASK, -+ AIU_CODEC_DAC_LRCLK_CTRL_DIV(div_lrclk)); -+ -+ /* Set the divider between blclk and amclk */ -+ div_bclk = os / div_lrclk; -+ -+ /* Use CLK_MORE for the i2s divider */ -+ regmap_update_bits(priv->regmap, AIU_CLK_CTRL, -+ AIU_CLK_CTRL_I2S_DIV_MASK, -+ 0); -+ -+ regmap_update_bits(priv->regmap, AIU_CLK_CTRL_MORE, -+ AIU_CLK_CTRL_MORE_I2S_DIV_MASK, -+ AIU_CLK_CTRL_MORE_I2S_DIV(div_bclk)); -+ -+ return 0; -+} -+ -+static int aiu_i2s_dai_hw_params(struct snd_pcm_substream *substream, -+ struct snd_pcm_hw_params *params, -+ struct snd_soc_dai *dai) -+{ -+ struct aiu_i2s_dai *priv = snd_soc_dai_get_drvdata(dai); -+ int ret; -+ -+ ret = __bclks_set_rate(priv, params_rate(params), params_width(params)); -+ if (ret) { -+ dev_err(dai->dev, "Unable set to the i2s clock rates\n"); -+ return ret; -+ } -+ -+ return 0; -+} -+ -+static int aiu_i2s_dai_set_fmt(struct snd_soc_dai *dai, unsigned int fmt) -+{ -+ struct aiu_i2s_dai *priv = snd_soc_dai_get_drvdata(dai); -+ u32 val; -+ -+ if ((fmt & SND_SOC_DAIFMT_MASTER_MASK) != SND_SOC_DAIFMT_CBS_CFS) -+ return -EINVAL; -+ -+ /* DAI output mode */ -+ switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) { -+ case SND_SOC_DAIFMT_I2S: -+ val = AIU_CLK_CTRL_ALRCLK_I2S; -+ break; -+ case SND_SOC_DAIFMT_LEFT_J: /* !TBC! */ -+ val = AIU_CLK_CTRL_ALRCLK_LEFT_J; -+ break; -+ case SND_SOC_DAIFMT_RIGHT_J: /* !TBC! */ -+ val = AIU_CLK_CTRL_ALRCLK_RIGHT_J; -+ break; -+ default: -+ return -EINVAL; -+ } -+ -+ regmap_update_bits(priv->regmap, AIU_CLK_CTRL, -+ AIU_CLK_CTRL_ALRCLK_SKEW_MASK, -+ val); -+ -+ /* DAI clock polarity */ -+ switch (fmt & SND_SOC_DAIFMT_INV_MASK) { -+ case SND_SOC_DAIFMT_IB_IF: -+ /* Invert both clocks */ -+ val = AIU_CLK_CTRL_ALRCLK_POLARITY_INVERTED | -+ AIU_CLK_CTRL_AOCLK_POLARITY_INVERTED; -+ break; -+ case SND_SOC_DAIFMT_IB_NF: -+ /* Invert bit clock */ -+ val = AIU_CLK_CTRL_ALRCLK_POLARITY_NORMAL | -+ AIU_CLK_CTRL_AOCLK_POLARITY_INVERTED; -+ break; -+ case SND_SOC_DAIFMT_NB_IF: -+ /* Invert frame clock */ -+ val = AIU_CLK_CTRL_ALRCLK_POLARITY_INVERTED | -+ AIU_CLK_CTRL_AOCLK_POLARITY_NORMAL; -+ break; -+ case SND_SOC_DAIFMT_NB_NF: -+ /* Normal clocks */ -+ val = AIU_CLK_CTRL_ALRCLK_POLARITY_NORMAL | -+ AIU_CLK_CTRL_AOCLK_POLARITY_NORMAL; -+ break; -+ default: -+ return -EINVAL; -+ } -+ -+ regmap_update_bits(priv->regmap, AIU_CLK_CTRL, -+ AIU_CLK_CTRL_ALRCLK_POLARITY_MASK | -+ AIU_CLK_CTRL_AOCLK_POLARITY_MASK, -+ val); -+ -+ switch (fmt & SND_SOC_DAIFMT_CLOCK_MASK) { -+ case SND_SOC_DAIFMT_CONT: -+ priv->bclks_idle = true; -+ break; -+ case SND_SOC_DAIFMT_GATED: -+ priv->bclks_idle = false; -+ break; -+ default: -+ return -EINVAL; -+ } -+ -+ return 0; -+} -+ -+static int aiu_i2s_dai_set_sysclk(struct snd_soc_dai *dai, int clk_id, -+ unsigned int freq, int dir) -+{ -+ struct aiu_i2s_dai *priv = snd_soc_dai_get_drvdata(dai); -+ int ret; -+ -+ if (WARN_ON(clk_id != 0)) -+ return -EINVAL; -+ -+ if (dir == SND_SOC_CLOCK_IN) -+ return 0; -+ -+ ret = clk_set_rate(priv->amclk, freq); -+ if (ret) { -+ dev_err(dai->dev, "Failed to set sysclk to %uHz", freq); -+ return ret; -+ } -+ -+ dev_dbg(dai->dev, "sysclk set to %luHz\n", clk_get_rate(priv->amclk)); -+ -+ return 0; -+} -+ -+static int aiu_i2s_dai_startup(struct snd_pcm_substream *substream, -+ struct snd_soc_dai *dai) -+{ -+ struct aiu_i2s_dai *priv = snd_soc_dai_get_drvdata(dai); -+ int ret; -+ -+ /* Make sure nothing gets out of the DAI yet*/ -+ __hold(priv, true); -+ -+ /* I2S encoder needs the mixer interface gate */ -+ ret = clk_prepare_enable(priv->mixer_if); -+ if (ret) -+ goto err_mixer_if; -+ -+ /* Enable the i2s master clock */ -+ ret = clk_prepare_enable(priv->amclk); -+ if (ret) -+ goto err_amclk; -+ -+ /* Enable the bits clock gate */ -+ ret = clk_prepare_enable(priv->aoclk); -+ if (ret) -+ goto err_aoclk; -+ -+ return 0; -+ -+err_aoclk: -+ clk_disable_unprepare(priv->amclk); -+err_amclk: -+ clk_disable_unprepare(priv->mixer_if); -+err_mixer_if: -+ return ret; -+} -+ -+static void aiu_i2s_dai_shutdown(struct snd_pcm_substream *substream, -+ struct snd_soc_dai *dai) -+{ -+ struct aiu_i2s_dai *priv = snd_soc_dai_get_drvdata(dai); -+ -+ clk_disable_unprepare(priv->aoclk); -+ clk_disable_unprepare(priv->amclk); -+ clk_disable_unprepare(priv->mixer_if); -+} -+ -+static const struct snd_soc_dai_ops aiu_i2s_dai_ops = { -+ .startup = aiu_i2s_dai_startup, -+ .shutdown = aiu_i2s_dai_shutdown, -+ .trigger = aiu_i2s_dai_trigger, -+ .hw_params = aiu_i2s_dai_hw_params, -+ .set_fmt = aiu_i2s_dai_set_fmt, -+ .set_sysclk = aiu_i2s_dai_set_sysclk, -+}; -+ -+static struct snd_soc_dai_driver aiu_i2s_dai = { -+ .playback = { -+ .stream_name = "Playback", -+ .channels_min = 2, -+ .channels_max = 8, -+ .rates = SNDRV_PCM_RATE_8000_192000, -+ .formats = (SNDRV_PCM_FMTBIT_S16_LE | -+ SNDRV_PCM_FMTBIT_S24_LE ) -+ }, -+ .ops = &aiu_i2s_dai_ops, -+}; -+ -+static const struct snd_soc_component_driver aiu_i2s_dai_component = { -+ .name = DRV_NAME, -+}; -+ -+static int aiu_i2s_dai_probe(struct platform_device *pdev) -+{ -+ struct device *dev = &pdev->dev; -+ struct aiu_i2s_dai *priv; -+ int ret; -+ -+ priv = devm_kzalloc(&pdev->dev, sizeof(*priv), GFP_KERNEL); -+ if(!priv) -+ return -ENOMEM; -+ platform_set_drvdata(pdev, priv); -+ -+ ret = aiu_common_register(pdev); -+ if (ret) -+ return ret; -+ -+ priv->regmap = syscon_node_to_regmap(dev->parent->of_node); -+ if (IS_ERR(priv->regmap)) { -+ dev_err(dev, "failed to get our regmap\n"); -+ return PTR_ERR(priv->regmap); -+ } -+ -+ priv->mixer_if = devm_clk_get(dev, "mixer_if"); -+ if (IS_ERR(priv->mixer_if)) { -+ if(PTR_ERR(priv->mixer_if) != -EPROBE_DEFER) -+ dev_err(dev, "failed to get mixer interface gate\n"); -+ return PTR_ERR(priv->mixer_if); -+ } -+ -+ priv->aoclk = devm_clk_get(dev, "aoclk"); -+ if (IS_ERR(priv->aoclk)) { -+ if(PTR_ERR(priv->aoclk) != -EPROBE_DEFER) -+ dev_err(dev, "failed to get bit clocks gate\n"); -+ return PTR_ERR(priv->aoclk); -+ } -+ -+ priv->amclk = devm_clk_get(dev, "amclk"); -+ if (IS_ERR(priv->amclk)) { -+ if(PTR_ERR(priv->amclk) != -EPROBE_DEFER) -+ dev_err(dev, "failed to get the i2s master clock\n"); -+ return PTR_ERR(priv->amclk); -+ } -+ -+ return devm_snd_soc_register_component(dev, &aiu_i2s_dai_component, -+ &aiu_i2s_dai, 1); -+} -+ -+static const struct of_device_id aiu_i2s_dai_match[] = { -+ { .compatible = "amlogic,meson-aiu-i2s-dai", }, -+ {} -+}; -+MODULE_DEVICE_TABLE(of, aiu_i2s_dai_match); -+ -+static struct platform_driver aiu_i2s_dai_pdrv = { -+ .probe = aiu_i2s_dai_probe, -+ .driver = { -+ .name = DRV_NAME, -+ .of_match_table = aiu_i2s_dai_match, -+ }, -+}; -+module_platform_driver(aiu_i2s_dai_pdrv); -+ -+MODULE_DESCRIPTION("Meson AIU i2s DAI ASoC Driver"); -+MODULE_AUTHOR("Jerome Brunet "); -+MODULE_LICENSE("GPL v2"); --- -1.9.1 - diff --git a/patch/kernel/odroidc2-next/0078-ARM64-dts-meson-gxl-Enable-HDMI-audio-on-p212-based-.patch b/patch/kernel/odroidc2-next/0078-ARM64-dts-meson-gxl-Enable-HDMI-audio-on-p212-based-.patch new file mode 100644 index 000000000..11f51ecdc --- /dev/null +++ b/patch/kernel/odroidc2-next/0078-ARM64-dts-meson-gxl-Enable-HDMI-audio-on-p212-based-.patch @@ -0,0 +1,66 @@ +From 8718f9cf5d8df7fd800d4f7692eb1982cfa88a17 Mon Sep 17 00:00:00 2001 +From: Neil Armstrong +Date: Thu, 13 Jul 2017 15:08:22 +0200 +Subject: [PATCH 78/79] ARM64: dts: meson-gxl: Enable HDMI audio on p212 based + boards + +Signed-off-by: Neil Armstrong +--- + .../boot/dts/amlogic/meson-gxl-s905x-p212.dtsi | 41 ++++++++++++++++++++++ + 1 file changed, 41 insertions(+) + +diff --git a/arch/arm64/boot/dts/amlogic/meson-gxl-s905x-p212.dtsi b/arch/arm64/boot/dts/amlogic/meson-gxl-s905x-p212.dtsi +index a07c34d..1372ea2 100644 +--- a/arch/arm64/boot/dts/amlogic/meson-gxl-s905x-p212.dtsi ++++ b/arch/arm64/boot/dts/amlogic/meson-gxl-s905x-p212.dtsi +@@ -74,6 +74,47 @@ + clocks = <&wifi32k>; + clock-names = "ext_clock"; + }; ++ ++ soc { ++ sound { ++ compatible = "simple-audio-card"; ++ simple-audio-card,name = "meson-gxl"; ++ ++ simple-audio-card,dai-link@0 { ++ format = "i2s"; ++ mclk-fs = <256>; ++ bitclock-master = <&i2s_dai>; ++ frame-master = <&i2s_dai>; ++ ++ plat { ++ sound-dai = <&aiu_i2s_dma>; ++ }; ++ ++ cpu { ++ sound-dai = <&i2s_dai>; ++ }; ++ ++ codec { ++ sound-dai = <&hdmi_tx>; ++ }; ++ }; ++ }; ++ }; ++}; ++ ++&audio { ++ status = "okay"; ++}; ++ ++&aiu_i2s_dma { ++ status = "okay"; ++}; ++ ++&i2s_dai { ++ pinctrl-0 = <&i2s_am_clk_pins>, <&i2s_out_ao_clk_pins>, ++ <&i2s_out_lr_clk_pins>, <&i2s_out_ch01_pins>; ++ pinctrl-names = "default"; ++ status = "okay"; + }; + + ðmac { +-- +1.9.1 + diff --git a/patch/kernel/odroidc2-next/0078-snd-soc-codec-add-es7134lv-dac-support.patch b/patch/kernel/odroidc2-next/0078-snd-soc-codec-add-es7134lv-dac-support.patch deleted file mode 100644 index 7e9b7cbd6..000000000 --- a/patch/kernel/odroidc2-next/0078-snd-soc-codec-add-es7134lv-dac-support.patch +++ /dev/null @@ -1,161 +0,0 @@ -From 564a578e7c4b2bc120ad735058d22a0d1780fc01 Mon Sep 17 00:00:00 2001 -From: Jerome Brunet -Date: Sun, 12 Feb 2017 00:42:18 +0100 -Subject: [PATCH 78/93] snd: soc: codec: add es7134lv dac support - -TO BE COMPLETED ... - -Signed-off-by: Jerome Brunet ---- - sound/soc/codecs/Kconfig | 4 ++ - sound/soc/codecs/Makefile | 2 + - sound/soc/codecs/es7134lv.c | 95 +++++++++++++++++++++++++++++++++++++++++++++ - 3 files changed, 101 insertions(+) - create mode 100644 sound/soc/codecs/es7134lv.c - -diff --git a/sound/soc/codecs/Kconfig b/sound/soc/codecs/Kconfig -index 9e1718a..dc933b4 100644 ---- a/sound/soc/codecs/Kconfig -+++ b/sound/soc/codecs/Kconfig -@@ -72,6 +72,7 @@ config SND_SOC_ALL_CODECS - select SND_SOC_DMIC - select SND_SOC_ES8328_SPI if SPI_MASTER - select SND_SOC_ES8328_I2C if I2C -+ select SND_SOC_ES7134LV - select SND_SOC_GTM601 - select SND_SOC_HDAC_HDMI - select SND_SOC_ICS43432 -@@ -535,6 +536,9 @@ config SND_SOC_ES8328_SPI - tristate - select SND_SOC_ES8328 - -+config SND_SOC_ES7134LV -+ tristate "Everest ES7134LV CODEC" -+ - config SND_SOC_GTM601 - tristate 'GTM601 UMTS modem audio codec' - -diff --git a/sound/soc/codecs/Makefile b/sound/soc/codecs/Makefile -index 7e1dad7..a217310 100644 ---- a/sound/soc/codecs/Makefile -+++ b/sound/soc/codecs/Makefile -@@ -66,6 +66,7 @@ snd-soc-dmic-objs := dmic.o - snd-soc-es8328-objs := es8328.o - snd-soc-es8328-i2c-objs := es8328-i2c.o - snd-soc-es8328-spi-objs := es8328-spi.o -+snd-soc-es7134lv-objs := es7134lv.o - snd-soc-gtm601-objs := gtm601.o - snd-soc-hdac-hdmi-objs := hdac_hdmi.o - snd-soc-ics43432-objs := ics43432.o -@@ -295,6 +296,7 @@ obj-$(CONFIG_SND_SOC_DMIC) += snd-soc-dmic.o - obj-$(CONFIG_SND_SOC_ES8328) += snd-soc-es8328.o - obj-$(CONFIG_SND_SOC_ES8328_I2C)+= snd-soc-es8328-i2c.o - obj-$(CONFIG_SND_SOC_ES8328_SPI)+= snd-soc-es8328-spi.o -+obj-$(CONFIG_SND_SOC_ES7134LV) += snd-soc-es7134lv.o - obj-$(CONFIG_SND_SOC_GTM601) += snd-soc-gtm601.o - obj-$(CONFIG_SND_SOC_HDAC_HDMI) += snd-soc-hdac-hdmi.o - obj-$(CONFIG_SND_SOC_ICS43432) += snd-soc-ics43432.o -diff --git a/sound/soc/codecs/es7134lv.c b/sound/soc/codecs/es7134lv.c -new file mode 100644 -index 0000000..a24d555 ---- /dev/null -+++ b/sound/soc/codecs/es7134lv.c -@@ -0,0 +1,95 @@ -+/* -+ * Copyright (c) 2017 BayLibre, SAS. -+ * Author: Jerome Brunet -+ * -+ * This program is free software; you can redistribute it and/or modify -+ * it under the terms of version 2 of the GNU General Public License as -+ * published by the Free Software Foundation. -+ * -+ * This program is distributed in the hope that it will be useful, but -+ * WITHOUT ANY WARRANTY; without even the implied warranty of -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -+ * General Public License for more details. -+ * -+ * You should have received a copy of the GNU General Public License -+ * along with this program; if not, see . -+ * The full GNU General Public License is included in this distribution -+ * in the file called COPYING. -+ */ -+ -+#include -+#include -+ -+/* -+ * The everest 7134lv is a very simple DA converter with no register -+ */ -+ -+static const struct snd_soc_dapm_widget es7134lv_dapm_widgets[] = { -+ SND_SOC_DAPM_OUTPUT("AOUTL"), -+ SND_SOC_DAPM_OUTPUT("AOUTR"), -+}; -+ -+static const struct snd_soc_dapm_route es7134lv_dapm_routes[] = { -+ { "AOUTL", NULL, "Playback" }, -+ { "AOUTR", NULL, "Playback" }, -+}; -+ -+static struct snd_soc_dai_driver es7134lv_dai = { -+ .name = "es7134lv-hifi", -+ .playback = { -+ .stream_name = "Playback", -+ .channels_min = 2, -+ .channels_max = 2, -+ .rates = SNDRV_PCM_RATE_8000_192000, -+ .formats = (SNDRV_PCM_FMTBIT_S16_LE | -+ SNDRV_PCM_FMTBIT_S18_3LE | -+ SNDRV_PCM_FMTBIT_S20_3LE | -+ SNDRV_PCM_FMTBIT_S24_3LE | -+ SNDRV_PCM_FMTBIT_S24_LE), -+ }, -+}; -+ -+static struct snd_soc_codec_driver es7134lv_codec_driver = { -+ .component_driver = { -+ .dapm_widgets = es7134lv_dapm_widgets, -+ .num_dapm_widgets = ARRAY_SIZE(es7134lv_dapm_widgets), -+ .dapm_routes = es7134lv_dapm_routes, -+ .num_dapm_routes = ARRAY_SIZE(es7134lv_dapm_routes), -+ }, -+}; -+ -+static int es7134lv_probe(struct platform_device *pdev) -+{ -+ return snd_soc_register_codec(&pdev->dev, -+ &es7134lv_codec_driver, -+ &es7134lv_dai, 1); -+} -+ -+static int es7134lv_remove(struct platform_device *pdev) -+{ -+ snd_soc_unregister_codec(&pdev->dev); -+ return 0; -+} -+ -+#ifdef CONFIG_OF -+static const struct of_device_id es7134lv_ids[] = { -+ { .compatible = "everest,es7134lv", }, -+ { } -+}; -+MODULE_DEVICE_TABLE(of, es7134lv_ids); -+#endif -+ -+static struct platform_driver es7134lv_driver = { -+ .driver = { -+ .name = "es7134lv", -+ .of_match_table = of_match_ptr(es7134lv_ids), -+ }, -+ .probe = es7134lv_probe, -+ .remove = es7134lv_remove, -+}; -+ -+module_platform_driver(es7134lv_driver); -+ -+MODULE_DESCRIPTION("ASoC ES7134LV audio codec driver"); -+MODULE_AUTHOR("Jerome Brunet "); -+MODULE_LICENSE("GPL"); --- -1.9.1 - diff --git a/patch/kernel/odroidc2-next/0079-dt-bindings-clk-gxbb-expose-MPLL0-and-MPLL1-clocks.patch b/patch/kernel/odroidc2-next/0079-dt-bindings-clk-gxbb-expose-MPLL0-and-MPLL1-clocks.patch deleted file mode 100644 index 898e1d905..000000000 --- a/patch/kernel/odroidc2-next/0079-dt-bindings-clk-gxbb-expose-MPLL0-and-MPLL1-clocks.patch +++ /dev/null @@ -1,42 +0,0 @@ -From abb052acd69dfbe05ae9e03d14f6fbed4a3a96c0 Mon Sep 17 00:00:00 2001 -From: Jerome Brunet -Date: Thu, 26 Jan 2017 11:11:25 +0100 -Subject: [PATCH 79/93] dt-bindings: clk: gxbb: expose MPLL0 and MPLL1 clocks - -Signed-off-by: Jerome Brunet ---- - drivers/clk/meson/gxbb.h | 4 ++-- - include/dt-bindings/clock/gxbb-clkc.h | 2 ++ - 2 files changed, 4 insertions(+), 2 deletions(-) - -diff --git a/drivers/clk/meson/gxbb.h b/drivers/clk/meson/gxbb.h -index 298bfa5..084b016 100644 ---- a/drivers/clk/meson/gxbb.h -+++ b/drivers/clk/meson/gxbb.h -@@ -181,8 +181,8 @@ - #define CLKID_MPEG_SEL 10 - #define CLKID_MPEG_DIV 11 - /* CLKID_CLK81 */ --#define CLKID_MPLL0 13 --#define CLKID_MPLL1 14 -+/* CLKID_MPLL0 */ -+/* CLKID_MPLL1 */ - /* CLKID_MPLL2 */ - #define CLKID_DDR 16 - #define CLKID_DOS 17 -diff --git a/include/dt-bindings/clock/gxbb-clkc.h b/include/dt-bindings/clock/gxbb-clkc.h -index cfd7558..a1246d2 100644 ---- a/include/dt-bindings/clock/gxbb-clkc.h -+++ b/include/dt-bindings/clock/gxbb-clkc.h -@@ -12,6 +12,8 @@ - #define CLKID_FCLK_DIV4 6 - #define CLKID_GP0_PLL 9 - #define CLKID_CLK81 12 -+#define CLKID_MPLL0 13 -+#define CLKID_MPLL1 14 - #define CLKID_MPLL2 15 - #define CLKID_SPI 34 - #define CLKID_I2C 22 --- -1.9.1 - diff --git a/patch/kernel/odroidc2-next/0079-phy-meson-add-USB2-PHY-support-for-Meson-GXL-and-GXM.patch b/patch/kernel/odroidc2-next/0079-phy-meson-add-USB2-PHY-support-for-Meson-GXL-and-GXM.patch new file mode 100644 index 000000000..504a0d77d --- /dev/null +++ b/patch/kernel/odroidc2-next/0079-phy-meson-add-USB2-PHY-support-for-Meson-GXL-and-GXM.patch @@ -0,0 +1,325 @@ +From c7975e835ec6c8dea399b649597f6fe8461214cb Mon Sep 17 00:00:00 2001 +From: Martin Blumenstingl +Date: Sat, 1 Apr 2017 11:18:30 +0200 +Subject: [PATCH 79/79] phy: meson: add USB2 PHY support for Meson GXL and GXM + +This adds a new driver for the USB2 PHYs found on Meson GXL and GXM SoCs +(both SoCs are using the same USB PHY register layout). + +The USB2 PHY is a simple PHY which only has a few registers to configure +the mode (host/device) and a reset register (to enable/disable the PHY). + +Unfortunately there are no datasheets available for this PHY. The driver +was written by reading the code from Amlogic's GPL kernel sources and +by analyzing the registers on an actual GXL and GXM device running the +kernel that was shipped on the boards I have. + +Signed-off-by: Martin Blumenstingl +Signed-off-by: Neil Armstrong +--- + drivers/phy/Kconfig | 12 ++ + drivers/phy/Makefile | 1 + + drivers/phy/phy-meson-gxl-usb2.c | 261 +++++++++++++++++++++++++++++++++++++++ + 3 files changed, 274 insertions(+) + create mode 100644 drivers/phy/phy-meson-gxl-usb2.c + +diff --git a/drivers/phy/Kconfig b/drivers/phy/Kconfig +index afaf7b6..27189e2 100644 +--- a/drivers/phy/Kconfig ++++ b/drivers/phy/Kconfig +@@ -530,4 +530,16 @@ config PHY_MESON8B_USB2 + and GXBB SoCs. + If unsure, say N. + ++config PHY_MESON_GXL_USB ++ tristate "Meson GXL and GXM USB2 PHY drivers" ++ default ARCH_MESON ++ depends on OF && (ARCH_MESON || COMPILE_TEST) ++ depends on USB_SUPPORT ++ select GENERIC_PHY ++ select REGMAP_MMIO ++ help ++ Enable this to support the Meson USB2 PHYs found in Meson ++ GXL and GXM SoCs. ++ If unsure, say N. ++ + endmenu +diff --git a/drivers/phy/Makefile b/drivers/phy/Makefile +index f8047b4..bea10c6 100644 +--- a/drivers/phy/Makefile ++++ b/drivers/phy/Makefile +@@ -64,3 +64,4 @@ obj-$(CONFIG_PHY_CYGNUS_PCIE) += phy-bcm-cygnus-pcie.o + obj-$(CONFIG_ARCH_TEGRA) += tegra/ + obj-$(CONFIG_PHY_NS2_PCIE) += phy-bcm-ns2-pcie.o + obj-$(CONFIG_PHY_MESON8B_USB2) += phy-meson8b-usb2.o ++obj-$(CONFIG_PHY_MESON_GXL_USB) += phy-meson-gxl-usb2.o +diff --git a/drivers/phy/phy-meson-gxl-usb2.c b/drivers/phy/phy-meson-gxl-usb2.c +new file mode 100644 +index 0000000..f5fbd3c +--- /dev/null ++++ b/drivers/phy/phy-meson-gxl-usb2.c +@@ -0,0 +1,261 @@ ++/* ++ * Meson GXL and GXM USB2 PHY driver ++ * ++ * Copyright (C) 2017 Martin Blumenstingl ++ * ++ * This program is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License version 2 as ++ * published by the Free Software Foundation. ++ * ++ * You should have received a copy of the GNU General Public License ++ * along with this program. If not, see . ++ */ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++/* bits [31:27] are read-only */ ++#define U2P_R0 0x0 ++ #define U2P_R0_BYPASS_SEL BIT(0) ++ #define U2P_R0_BYPASS_DM_EN BIT(1) ++ #define U2P_R0_BYPASS_DP_EN BIT(2) ++ #define U2P_R0_TXBITSTUFF_ENH BIT(3) ++ #define U2P_R0_TXBITSTUFF_EN BIT(4) ++ #define U2P_R0_DM_PULLDOWN BIT(5) ++ #define U2P_R0_DP_PULLDOWN BIT(6) ++ #define U2P_R0_DP_VBUS_VLD_EXT_SEL BIT(7) ++ #define U2P_R0_DP_VBUS_VLD_EXT BIT(8) ++ #define U2P_R0_ADP_PRB_EN BIT(9) ++ #define U2P_R0_ADP_DISCHARGE BIT(10) ++ #define U2P_R0_ADP_CHARGE BIT(11) ++ #define U2P_R0_DRV_VBUS BIT(12) ++ #define U2P_R0_ID_PULLUP BIT(13) ++ #define U2P_R0_LOOPBACK_EN_B BIT(14) ++ #define U2P_R0_OTG_DISABLE BIT(15) ++ #define U2P_R0_COMMON_ONN BIT(16) ++ #define U2P_R0_FSEL_MASK GENMASK(19, 17) ++ #define U2P_R0_REF_CLK_SEL_MASK GENMASK(21, 20) ++ #define U2P_R0_POWER_ON_RESET BIT(22) ++ #define U2P_R0_V_ATE_TEST_EN_B_MASK GENMASK(24, 23) ++ #define U2P_R0_ID_SET_ID_DQ BIT(25) ++ #define U2P_R0_ATE_RESET BIT(26) ++ #define U2P_R0_FSV_MINUS BIT(27) ++ #define U2P_R0_FSV_PLUS BIT(28) ++ #define U2P_R0_BYPASS_DM_DATA BIT(29) ++ #define U2P_R0_BYPASS_DP_DATA BIT(30) ++ ++#define U2P_R1 0x4 ++ #define U2P_R1_BURN_IN_TEST BIT(0) ++ #define U2P_R1_ACA_ENABLE BIT(1) ++ #define U2P_R1_DCD_ENABLE BIT(2) ++ #define U2P_R1_VDAT_SRC_EN_B BIT(3) ++ #define U2P_R1_VDAT_DET_EN_B BIT(4) ++ #define U2P_R1_CHARGES_SEL BIT(5) ++ #define U2P_R1_TX_PREEMP_PULSE_TUNE BIT(6) ++ #define U2P_R1_TX_PREEMP_AMP_TUNE_MASK GENMASK(8, 7) ++ #define U2P_R1_TX_RES_TUNE_MASK GENMASK(10, 9) ++ #define U2P_R1_TX_RISE_TUNE_MASK GENMASK(12, 11) ++ #define U2P_R1_TX_VREF_TUNE_MASK GENMASK(16, 13) ++ #define U2P_R1_TX_FSLS_TUNE_MASK GENMASK(20, 17) ++ #define U2P_R1_TX_HSXV_TUNE_MASK GENMASK(22, 21) ++ #define U2P_R1_OTG_TUNE_MASK GENMASK(25, 23) ++ #define U2P_R1_SQRX_TUNE_MASK GENMASK(28, 26) ++ #define U2P_R1_COMP_DIS_TUNE_MASK GENMASK(31, 29) ++ ++/* bits [31:14] are read-only */ ++#define U2P_R2 0x8 ++ #define U2P_R2_DATA_IN_MASK GENMASK(3, 0) ++ #define U2P_R2_DATA_IN_EN_MASK GENMASK(7, 4) ++ #define U2P_R2_ADDR_MASK GENMASK(11, 8) ++ #define U2P_R2_DATA_OUT_SEL BIT(12) ++ #define U2P_R2_CLK BIT(13) ++ #define U2P_R2_DATA_OUT_MASK GENMASK(17, 14) ++ #define U2P_R2_ACA_PIN_RANGE_C BIT(18) ++ #define U2P_R2_ACA_PIN_RANGE_B BIT(19) ++ #define U2P_R2_ACA_PIN_RANGE_A BIT(20) ++ #define U2P_R2_ACA_PIN_GND BIT(21) ++ #define U2P_R2_ACA_PIN_FLOAT BIT(22) ++ #define U2P_R2_CHARGE_DETECT BIT(23) ++ #define U2P_R2_DEVICE_SESSION_VALID BIT(24) ++ #define U2P_R2_ADP_PROBE BIT(25) ++ #define U2P_R2_ADP_SENSE BIT(26) ++ #define U2P_R2_SESSION_END BIT(27) ++ #define U2P_R2_VBUS_VALID BIT(28) ++ #define U2P_R2_B_VALID BIT(29) ++ #define U2P_R2_A_VALID BIT(30) ++ #define U2P_R2_ID_DIG BIT(31) ++ ++#define U2P_R3 0xc ++ ++#define RESET_COMPLETE_TIME 500 ++ ++struct phy_meson_gxl_usb2_priv { ++ struct regmap *regmap; ++ enum phy_mode mode; ++ int is_enabled; ++}; ++ ++static const struct regmap_config phy_meson_gxl_usb2_regmap_conf = { ++ .reg_bits = 8, ++ .val_bits = 32, ++ .reg_stride = 4, ++ .max_register = U2P_R3, ++}; ++ ++static int phy_meson_gxl_usb2_reset(struct phy *phy) ++{ ++ struct phy_meson_gxl_usb2_priv *priv = phy_get_drvdata(phy); ++ ++ if (!priv->is_enabled) ++ return 0; ++ ++ /* reset the PHY and wait until settings are stabilized */ ++ regmap_update_bits(priv->regmap, U2P_R0, U2P_R0_POWER_ON_RESET, ++ U2P_R0_POWER_ON_RESET); ++ udelay(RESET_COMPLETE_TIME); ++ regmap_update_bits(priv->regmap, U2P_R0, U2P_R0_POWER_ON_RESET, 0); ++ udelay(RESET_COMPLETE_TIME); ++ ++ return 0; ++} ++ ++static int phy_meson_gxl_usb2_set_mode(struct phy *phy, enum phy_mode mode) ++{ ++ struct phy_meson_gxl_usb2_priv *priv = phy_get_drvdata(phy); ++ ++ switch (mode) { ++ case PHY_MODE_USB_HOST: ++ case PHY_MODE_USB_OTG: ++ regmap_update_bits(priv->regmap, U2P_R0, U2P_R0_DM_PULLDOWN, ++ U2P_R0_DM_PULLDOWN); ++ regmap_update_bits(priv->regmap, U2P_R0, U2P_R0_DP_PULLDOWN, ++ U2P_R0_DP_PULLDOWN); ++ regmap_update_bits(priv->regmap, U2P_R0, U2P_R0_ID_PULLUP, 0); ++ break; ++ ++ case PHY_MODE_USB_DEVICE: ++ regmap_update_bits(priv->regmap, U2P_R0, U2P_R0_DM_PULLDOWN, ++ 0); ++ regmap_update_bits(priv->regmap, U2P_R0, U2P_R0_DP_PULLDOWN, ++ 0); ++ regmap_update_bits(priv->regmap, U2P_R0, U2P_R0_ID_PULLUP, ++ U2P_R0_ID_PULLUP); ++ break; ++ ++ default: ++ return -EINVAL; ++ } ++ ++ phy_meson_gxl_usb2_reset(phy); ++ ++ priv->mode = mode; ++ ++ return 0; ++} ++ ++static int phy_meson_gxl_usb2_power_off(struct phy *phy) ++{ ++ struct phy_meson_gxl_usb2_priv *priv = phy_get_drvdata(phy); ++ ++ priv->is_enabled = 0; ++ ++ /* power off the PHY by putting it into reset mode */ ++ regmap_update_bits(priv->regmap, U2P_R0, U2P_R0_POWER_ON_RESET, ++ U2P_R0_POWER_ON_RESET); ++ ++ return 0; ++} ++ ++static int phy_meson_gxl_usb2_power_on(struct phy *phy) ++{ ++ struct phy_meson_gxl_usb2_priv *priv = phy_get_drvdata(phy); ++ int ret; ++ ++ priv->is_enabled = 1; ++ ++ /* power on the PHY by taking it out of reset mode */ ++ regmap_update_bits(priv->regmap, U2P_R0, U2P_R0_POWER_ON_RESET, 0); ++ ++ ret = phy_meson_gxl_usb2_set_mode(phy, priv->mode); ++ if (ret) { ++ phy_meson_gxl_usb2_power_off(phy); ++ ++ dev_err(&phy->dev, "Failed to initialize PHY with mode %d\n", ++ priv->mode); ++ return ret; ++ } ++ ++ return 0; ++} ++ ++static const struct phy_ops phy_meson_gxl_usb2_ops = { ++ .power_on = phy_meson_gxl_usb2_power_on, ++ .power_off = phy_meson_gxl_usb2_power_off, ++ .set_mode = phy_meson_gxl_usb2_set_mode, ++ .reset = phy_meson_gxl_usb2_reset, ++ .owner = THIS_MODULE, ++}; ++ ++static int phy_meson_gxl_usb2_probe(struct platform_device *pdev) ++{ ++ struct device *dev = &pdev->dev; ++ struct phy_provider *phy_provider; ++ struct resource *res; ++ struct phy_meson_gxl_usb2_priv *priv; ++ struct phy *phy; ++ void __iomem *base; ++ ++ priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL); ++ if (!priv) ++ return -ENOMEM; ++ ++ platform_set_drvdata(pdev, priv); ++ ++ res = platform_get_resource(pdev, IORESOURCE_MEM, 0); ++ base = devm_ioremap_resource(dev, res); ++ if (IS_ERR(base)) ++ return PTR_ERR(base); ++ ++ priv->mode = PHY_MODE_USB_HOST; ++ ++ priv->regmap = devm_regmap_init_mmio(dev, base, ++ &phy_meson_gxl_usb2_regmap_conf); ++ if (IS_ERR(priv->regmap)) ++ return PTR_ERR(priv->regmap); ++ ++ phy = devm_phy_create(dev, NULL, &phy_meson_gxl_usb2_ops); ++ if (IS_ERR(phy)) { ++ dev_err(dev, "failed to create PHY\n"); ++ return PTR_ERR(phy); ++ } ++ ++ phy_set_drvdata(phy, priv); ++ ++ phy_provider = devm_of_phy_provider_register(dev, of_phy_simple_xlate); ++ ++ return PTR_ERR_OR_ZERO(phy_provider); ++} ++ ++static const struct of_device_id phy_meson_gxl_usb2_of_match[] = { ++ { .compatible = "amlogic,meson-gxl-usb2-phy", }, ++ { }, ++}; ++MODULE_DEVICE_TABLE(of, phy_meson_gxl_usb2_of_match); ++ ++static struct platform_driver phy_meson_gxl_usb2_driver = { ++ .probe = phy_meson_gxl_usb2_probe, ++ .driver = { ++ .name = "phy-meson-gxl-usb2", ++ .of_match_table = phy_meson_gxl_usb2_of_match, ++ }, ++}; ++module_platform_driver(phy_meson_gxl_usb2_driver); ++ ++MODULE_AUTHOR("Martin Blumenstingl "); ++MODULE_DESCRIPTION("Meson GXL and GXM USB2 PHY driver"); ++MODULE_LICENSE("GPL v2"); +-- +1.9.1 + diff --git a/patch/kernel/odroidc2-next/0080-dt-bindings-clock-gxbb-expose-i2s-master-clock.patch b/patch/kernel/odroidc2-next/0080-dt-bindings-clock-gxbb-expose-i2s-master-clock.patch deleted file mode 100644 index f539fd589..000000000 --- a/patch/kernel/odroidc2-next/0080-dt-bindings-clock-gxbb-expose-i2s-master-clock.patch +++ /dev/null @@ -1,50 +0,0 @@ -From f6986222eefd41918451f33b92d0bfe21174e636 Mon Sep 17 00:00:00 2001 -From: Jerome Brunet -Date: Thu, 26 Jan 2017 11:12:52 +0100 -Subject: [PATCH 80/93] dt-bindings: clock: gxbb: expose i2s master clock - -Signed-off-by: Jerome Brunet - -Conflicts: - include/dt-bindings/clock/gxbb-clkc.h ---- - drivers/clk/meson/gxbb.h | 4 ++-- - include/dt-bindings/clock/gxbb-clkc.h | 8 +++++--- - 2 files changed, 7 insertions(+), 5 deletions(-) - -diff --git a/drivers/clk/meson/gxbb.h b/drivers/clk/meson/gxbb.h -index 084b016..740b755f 100644 ---- a/drivers/clk/meson/gxbb.h -+++ b/drivers/clk/meson/gxbb.h -@@ -266,8 +266,8 @@ - /* CLKID_SD_EMMC_B */ - /* CLKID_SD_EMMC_C */ - #define CLKID_MPLL0_PLL 97 --#define CLKID_CTS_AMCLK 98 --#define CLKID_CTS_AMCLK_SEL 99 -+/* CLKID_CTS_AMCLK */ -+/* CLKID_CTS_AMCLK_SEL */ - #define CLKID_CTS_AMCLK_DIV 100 - /* CLKID_MALI_0 */ - /* CLKID_MALI_1 */ -diff --git a/include/dt-bindings/clock/gxbb-clkc.h b/include/dt-bindings/clock/gxbb-clkc.h -index a1246d2..0e690ac 100644 ---- a/include/dt-bindings/clock/gxbb-clkc.h -+++ b/include/dt-bindings/clock/gxbb-clkc.h -@@ -29,8 +29,10 @@ - #define CLKID_SD_EMMC_A 94 - #define CLKID_SD_EMMC_B 95 - #define CLKID_SD_EMMC_C 96 --#define CLKID_MALI_0 97 --#define CLKID_MALI_1 98 --#define CLKID_MALI 99 -+#define CLKID_CTS_AMCLK 98 -+#define CLKID_CTS_AMCLK_SEL 99 -+#define CLKID_MALI_0 101 -+#define CLKID_MALI_1 102 -+#define CLKID_MALI 103 - - #endif /* __GXBB_CLKC_H */ --- -1.9.1 - diff --git a/patch/kernel/odroidc2-next/0081-dt-bindings-expose-i2s-dma-and-dai-clock-gates.patch b/patch/kernel/odroidc2-next/0081-dt-bindings-expose-i2s-dma-and-dai-clock-gates.patch deleted file mode 100644 index 53ba4f797..000000000 --- a/patch/kernel/odroidc2-next/0081-dt-bindings-expose-i2s-dma-and-dai-clock-gates.patch +++ /dev/null @@ -1,71 +0,0 @@ -From 2878ea522ede6a743148419877ef28b3387369a3 Mon Sep 17 00:00:00 2001 -From: Jerome Brunet -Date: Sun, 12 Feb 2017 00:58:59 +0100 -Subject: [PATCH 81/93] dt-bindings: expose i2s dma and dai clock gates - -Signed-off-by: Jerome Brunet ---- - drivers/clk/meson/gxbb.h | 10 +++++----- - include/dt-bindings/clock/gxbb-clkc.h | 5 +++++ - 2 files changed, 10 insertions(+), 5 deletions(-) - -diff --git a/drivers/clk/meson/gxbb.h b/drivers/clk/meson/gxbb.h -index 740b755f..2c66d88 100644 ---- a/drivers/clk/meson/gxbb.h -+++ b/drivers/clk/meson/gxbb.h -@@ -206,16 +206,16 @@ - #define CLKID_I2S_SPDIF 35 - #define CLKID_ETH 36 - #define CLKID_DEMUX 37 --#define CLKID_AIU_GLUE 38 -+/* CLKID_AIU_GLUE */ - #define CLKID_IEC958 39 --#define CLKID_I2S_OUT 40 -+/* CLKID_I2S_OUT */ - #define CLKID_AMCLK 41 - #define CLKID_AIFIFO2 42 - #define CLKID_MIXER 43 --#define CLKID_MIXER_IFACE 44 -+/* CLKID_MIXER_IFACE */ - #define CLKID_ADC 45 - #define CLKID_BLKMV 46 --#define CLKID_AIU 47 -+/* CLKID_AIU */ - #define CLKID_UART1 48 - #define CLKID_G2D 49 - /* CLKID_USB0 */ -@@ -248,7 +248,7 @@ - /* CLKID_GCLK_VENCI_INT0 */ - #define CLKID_GCLK_VENCI_INT 78 - #define CLKID_DAC_CLK 79 --#define CLKID_AOCLK_GATE 80 -+/* CLKID_AOCLK_GATE */ - #define CLKID_IEC958_GATE 81 - #define CLKID_ENC480P 82 - #define CLKID_RNG1 83 -diff --git a/include/dt-bindings/clock/gxbb-clkc.h b/include/dt-bindings/clock/gxbb-clkc.h -index 0e690ac..ce5e0da 100644 ---- a/include/dt-bindings/clock/gxbb-clkc.h -+++ b/include/dt-bindings/clock/gxbb-clkc.h -@@ -18,6 +18,10 @@ - #define CLKID_SPI 34 - #define CLKID_I2C 22 - #define CLKID_ETH 36 -+#define CLKID_AIU_GLUE 38 -+#define CLKID_I2S_OUT 40 -+#define CLKID_MIXER_IFACE 44 -+#define CLKID_AIU 47 - #define CLKID_USB0 50 - #define CLKID_USB1 51 - #define CLKID_USB 55 -@@ -25,6 +29,7 @@ - #define CLKID_USB1_DDR_BRIDGE 64 - #define CLKID_USB0_DDR_BRIDGE 65 - #define CLKID_GCLK_VENCI_INT0 77 -+#define CLKID_AOCLK_GATE 80 - #define CLKID_AO_I2C 93 - #define CLKID_SD_EMMC_A 94 - #define CLKID_SD_EMMC_B 95 --- -1.9.1 - diff --git a/patch/kernel/odroidc2-next/0082-ARM64-dts-meson-initial-aiu-support-for-gxbb.patch b/patch/kernel/odroidc2-next/0082-ARM64-dts-meson-initial-aiu-support-for-gxbb.patch deleted file mode 100644 index 271cd4c61..000000000 --- a/patch/kernel/odroidc2-next/0082-ARM64-dts-meson-initial-aiu-support-for-gxbb.patch +++ /dev/null @@ -1,55 +0,0 @@ -From 045b11333a76b8e94c37665cea6b94a2b562a666 Mon Sep 17 00:00:00 2001 -From: Jerome Brunet -Date: Sun, 12 Feb 2017 01:00:13 +0100 -Subject: [PATCH 82/93] ARM64: dts: meson: initial aiu support for gxbb - -Signed-off-by: Jerome Brunet ---- - arch/arm64/boot/dts/amlogic/meson-gxbb.dtsi | 31 +++++++++++++++++++++++++++++ - 1 file changed, 31 insertions(+) - -diff --git a/arch/arm64/boot/dts/amlogic/meson-gxbb.dtsi b/arch/arm64/boot/dts/amlogic/meson-gxbb.dtsi -index ea111a2..6346776 100644 ---- a/arch/arm64/boot/dts/amlogic/meson-gxbb.dtsi -+++ b/arch/arm64/boot/dts/amlogic/meson-gxbb.dtsi -@@ -163,6 +163,37 @@ - clocks = <&clkc CLKID_SPI>; - status = "disabled"; - }; -+ -+ aiu: aiu@5400 { -+ compatible = "amlogic,meson-aiu" , "simple-mfd", "syscon" ; -+ reg = <0x0 0x5400 0x0 0x24c>; -+ -+ aiu_i2s_dai: aiu-i2s-dai { -+ #sound-dai-cells = <0>; -+ compatible = "amlogic,meson-aiu-i2s-dai"; -+ clocks = <&clkc CLKID_CTS_AMCLK>, -+ <&clkc CLKID_AIU>, -+ <&clkc CLKID_AIU_GLUE>, -+ <&clkc CLKID_AOCLK_GATE>, -+ <&clkc CLKID_MIXER_IFACE>; -+ clock-names = "amclk","aiu_top", "aiu_glue", -+ "aoclk", "mixer_if"; -+ status = "disbaled"; -+ }; -+ -+ aiu_i2s_dma: aiu_i2s_dma { -+ #sound-dai-cells = <0>; -+ compatible = "amlogic,meson-aiu-i2s-dma"; -+ interrupts = ; -+ clocks = <&clkc CLKID_AIU>, -+ <&clkc CLKID_AIU_GLUE>, -+ <&clkc CLKID_I2S_OUT>; -+ clock-names = "aiu_top", "aiu_glue", -+ "i2s_out"; -+ status = "disabled"; -+ }; -+ }; -+ - }; - - ðmac { --- -1.9.1 - diff --git a/patch/kernel/odroidc2-next/0083-ARM64-dts-meson-gxbb-p200-initial-sound-card-support.patch b/patch/kernel/odroidc2-next/0083-ARM64-dts-meson-gxbb-p200-initial-sound-card-support.patch deleted file mode 100644 index 157b96d33..000000000 --- a/patch/kernel/odroidc2-next/0083-ARM64-dts-meson-gxbb-p200-initial-sound-card-support.patch +++ /dev/null @@ -1,74 +0,0 @@ -From 33217241684bbf4017095204ed2e3246cd5aa495 Mon Sep 17 00:00:00 2001 -From: Jerome Brunet -Date: Sun, 12 Feb 2017 01:01:25 +0100 -Subject: [PATCH 83/93] ARM64: dts: meson: gxbb-p200: initial sound card - support - -Signed-off-by: Jerome Brunet ---- - arch/arm64/boot/dts/amlogic/meson-gxbb-p200.dts | 45 +++++++++++++++++++++++++ - 1 file changed, 45 insertions(+) - -diff --git a/arch/arm64/boot/dts/amlogic/meson-gxbb-p200.dts b/arch/arm64/boot/dts/amlogic/meson-gxbb-p200.dts -index 03e3d76..df820b6 100644 ---- a/arch/arm64/boot/dts/amlogic/meson-gxbb-p200.dts -+++ b/arch/arm64/boot/dts/amlogic/meson-gxbb-p200.dts -@@ -49,6 +49,39 @@ - / { - compatible = "amlogic,p200", "amlogic,meson-gxbb"; - model = "Amlogic Meson GXBB P200 Development Board"; -+ -+ soc { -+ i2s_codec: external-codec { -+ #sound-dai-cells = <0>; -+ compatible = "everest,es7134lv"; -+ status = "okay"; -+ }; -+ -+ sound { -+ compatible = "simple-audio-card"; -+ simple-audio-card,name = "meson-gxbb"; -+ status = "okay"; -+ -+ simple-audio-card,dai-link@0 { -+ /* RCA Output */ -+ format = "i2s"; -+ mclk-fs = <256>; -+ bitclock-master = <&aiu_i2s_dai>; -+ frame-master = <&aiu_i2s_dai>; -+ plat { -+ sound-dai = <&aiu_i2s_dma>; -+ }; -+ -+ cpu { -+ sound-dai = <&aiu_i2s_dai>; -+ }; -+ -+ codec { -+ sound-dai = <&i2s_codec>; -+ }; -+ }; -+ }; -+ }; - }; - - &i2c_B { -@@ -56,3 +89,15 @@ - pinctrl-0 = <&i2c_b_pins>; - pinctrl-names = "default"; - }; -+ -+&aiu_i2s_dai { -+ pinctrl-0 = <&i2s_am_clk_pins>, <&i2s_out_bclks_pins>, -+ <&i2s_out_ch01_ao_pins>; -+ pinctrl-names = "default"; -+ status = "okay"; -+}; -+ -+&aiu_i2s_dma { -+ status = "okay"; -+}; -+ --- -1.9.1 - diff --git a/patch/kernel/odroidc2-next/0085-snd-meson-quick-and-dirty-hdmi-activation.patch b/patch/kernel/odroidc2-next/0085-snd-meson-quick-and-dirty-hdmi-activation.patch deleted file mode 100644 index 722831805..000000000 --- a/patch/kernel/odroidc2-next/0085-snd-meson-quick-and-dirty-hdmi-activation.patch +++ /dev/null @@ -1,35 +0,0 @@ -From d4fcb333d0d36c0d485ede17ac989b8296a0a88b Mon Sep 17 00:00:00 2001 -From: Jerome Brunet -Date: Tue, 14 Feb 2017 19:10:32 +0100 -Subject: [PATCH 85/93] snd: meson: quick and dirty hdmi activation - -Signed-off-by: Jerome Brunet ---- - sound/soc/meson/aiu-i2s-dai.c | 11 +++++++++++ - 1 file changed, 11 insertions(+) - -diff --git a/sound/soc/meson/aiu-i2s-dai.c b/sound/soc/meson/aiu-i2s-dai.c -index 1f9f3bf..56a5b87 100644 ---- a/sound/soc/meson/aiu-i2s-dai.c -+++ b/sound/soc/meson/aiu-i2s-dai.c -@@ -206,6 +206,17 @@ static int aiu_i2s_dai_hw_params(struct snd_pcm_substream *substream, - return ret; - } - -+ /* Quick and dirty hack for HDMI */ -+ regmap_update_bits(priv->regmap, AIU_HDMI_CLK_DATA_CTRL, -+ AIU_HDMI_CLK_DATA_CTRL_CLK_SEL_MASK | -+ AIU_HDMI_CLK_DATA_CTRL_DATA_SEL_MASK, -+ AIU_HDMI_CLK_DATA_CTRL_CLK_I2S | -+ AIU_HDMI_CLK_DATA_CTRL_DATA_I2S); -+ -+ regmap_update_bits(priv->regmap, AIU_CLK_CTRL_MORE, -+ AIU_CLK_CTRL_MORE_HDMI_TX_SEL_MASK, -+ AIU_CLK_CTRL_MORE_HDMI_TX_INT_CLK); -+ - return 0; - } - --- -1.9.1 - diff --git a/patch/kernel/odroidc2-next/0086-snd-meson-quick-and-dirty-activation-of-dw-hdmi-code.patch b/patch/kernel/odroidc2-next/0086-snd-meson-quick-and-dirty-activation-of-dw-hdmi-code.patch deleted file mode 100644 index 3ae508841..000000000 --- a/patch/kernel/odroidc2-next/0086-snd-meson-quick-and-dirty-activation-of-dw-hdmi-code.patch +++ /dev/null @@ -1,27 +0,0 @@ -From 566355ff11f673633d08d0826fd58e9201a7af70 Mon Sep 17 00:00:00 2001 -From: Jerome Brunet -Date: Tue, 14 Feb 2017 19:13:04 +0100 -Subject: [PATCH 86/93] snd: meson: quick and dirty activation of dw-hdmi codec - -Signed-off-by: Jerome Brunet ---- - arch/arm64/boot/dts/amlogic/meson-gxbb-p200.dts | 3 ++- - 1 file changed, 2 insertions(+), 1 deletion(-) - -diff --git a/arch/arm64/boot/dts/amlogic/meson-gxbb-p200.dts b/arch/arm64/boot/dts/amlogic/meson-gxbb-p200.dts -index df820b6..ceacc36 100644 ---- a/arch/arm64/boot/dts/amlogic/meson-gxbb-p200.dts -+++ b/arch/arm64/boot/dts/amlogic/meson-gxbb-p200.dts -@@ -77,7 +77,8 @@ - }; - - codec { -- sound-dai = <&i2s_codec>; -+ //sound-dai = <&i2s_codec>; -+ sound-dai = <&hdmi_tx>; - }; - }; - }; --- -1.9.1 - diff --git a/patch/kernel/odroidc2-next/0087-ARM64-dts-meson-add-sound-dai-cells.patch b/patch/kernel/odroidc2-next/0087-ARM64-dts-meson-add-sound-dai-cells.patch deleted file mode 100644 index c3d7b94d4..000000000 --- a/patch/kernel/odroidc2-next/0087-ARM64-dts-meson-add-sound-dai-cells.patch +++ /dev/null @@ -1,23 +0,0 @@ -From 4e8266aaf755068ca04998a19ebe3c00c2608f57 Mon Sep 17 00:00:00 2001 -From: Jerome Brunet -Date: Tue, 14 Feb 2017 19:12:29 +0100 -Subject: [PATCH 87/93] ARM64: dts: meson: add sound-dai-cells - -Signed-off-by: Jerome Brunet ---- - arch/arm64/boot/dts/amlogic/meson-gxbb.dtsi | 1 + - 1 file changed, 1 insertion(+) - -diff --git a/arch/arm64/boot/dts/amlogic/meson-gxbb.dtsi b/arch/arm64/boot/dts/amlogic/meson-gxbb.dtsi -index 6346776..676c353 100644 ---- a/arch/arm64/boot/dts/amlogic/meson-gxbb.dtsi -+++ b/arch/arm64/boot/dts/amlogic/meson-gxbb.dtsi -@@ -662,4 +662,5 @@ - <&clkc CLKID_CLK81>, - <&clkc CLKID_GCLK_VENCI_INT0>; - clock-names = "isfr", "iahb", "venci"; -+ #sound-dai-cells = <0>; - }; --- -1.9.1 - diff --git a/patch/kernel/odroidc2-next/0089-ARM64-config-add-meson-aiu-to-defconfig.patch b/patch/kernel/odroidc2-next/0089-ARM64-config-add-meson-aiu-to-defconfig.patch deleted file mode 100644 index 17883d843..000000000 --- a/patch/kernel/odroidc2-next/0089-ARM64-config-add-meson-aiu-to-defconfig.patch +++ /dev/null @@ -1,28 +0,0 @@ -From 8099f5de27ff1e58827afdba160121f637a035c7 Mon Sep 17 00:00:00 2001 -From: Jerome Brunet -Date: Tue, 14 Feb 2017 19:22:33 +0100 -Subject: [PATCH 89/93] ARM64: config: add meson aiu to defconfig - -NOT READY FOR ML - -Signed-off-by: Jerome Brunet ---- - arch/arm64/configs/defconfig | 2 ++ - 1 file changed, 2 insertions(+) - -diff --git a/arch/arm64/configs/defconfig b/arch/arm64/configs/defconfig -index 33b744d..7497bdf 100644 ---- a/arch/arm64/configs/defconfig -+++ b/arch/arm64/configs/defconfig -@@ -344,6 +344,8 @@ CONFIG_SOUND=y - CONFIG_SND=y - CONFIG_SND_SOC=y - CONFIG_SND_BCM2835_SOC_I2S=m -+CONFIG_SND_MESON_AIU_I2S_DAI=m -+CONFIG_SND_MESON_AIU_I2S_DMA=m - CONFIG_SND_SOC_RCAR=y - CONFIG_SND_SOC_SAMSUNG=y - CONFIG_SND_SOC_AK4613=y --- -1.9.1 - diff --git a/patch/kernel/odroidc2-next/0090-ARM64-dts-meson-move-sound-card-from-p200-to-gxbb.patch b/patch/kernel/odroidc2-next/0090-ARM64-dts-meson-move-sound-card-from-p200-to-gxbb.patch deleted file mode 100644 index f86fd0361..000000000 --- a/patch/kernel/odroidc2-next/0090-ARM64-dts-meson-move-sound-card-from-p200-to-gxbb.patch +++ /dev/null @@ -1,131 +0,0 @@ -From 94e399f63f0a7bd2b6fce0e50f032fe68636f6d1 Mon Sep 17 00:00:00 2001 -From: Jerome Brunet -Date: Tue, 14 Feb 2017 19:29:38 +0100 -Subject: [PATCH 90/93] ARM64: dts: meson: move sound card from p200 to gxbb - -NOT READY FOR ML - -Signed-off-by: Jerome Brunet ---- - arch/arm64/boot/dts/amlogic/meson-gxbb-p200.dts | 45 ------------------------- - arch/arm64/boot/dts/amlogic/meson-gxbb.dtsi | 30 +++++++++++++++-- - 2 files changed, 28 insertions(+), 47 deletions(-) - -diff --git a/arch/arm64/boot/dts/amlogic/meson-gxbb-p200.dts b/arch/arm64/boot/dts/amlogic/meson-gxbb-p200.dts -index ceacc36..5f4cd7b 100644 ---- a/arch/arm64/boot/dts/amlogic/meson-gxbb-p200.dts -+++ b/arch/arm64/boot/dts/amlogic/meson-gxbb-p200.dts -@@ -49,40 +49,6 @@ - / { - compatible = "amlogic,p200", "amlogic,meson-gxbb"; - model = "Amlogic Meson GXBB P200 Development Board"; -- -- soc { -- i2s_codec: external-codec { -- #sound-dai-cells = <0>; -- compatible = "everest,es7134lv"; -- status = "okay"; -- }; -- -- sound { -- compatible = "simple-audio-card"; -- simple-audio-card,name = "meson-gxbb"; -- status = "okay"; -- -- simple-audio-card,dai-link@0 { -- /* RCA Output */ -- format = "i2s"; -- mclk-fs = <256>; -- bitclock-master = <&aiu_i2s_dai>; -- frame-master = <&aiu_i2s_dai>; -- plat { -- sound-dai = <&aiu_i2s_dma>; -- }; -- -- cpu { -- sound-dai = <&aiu_i2s_dai>; -- }; -- -- codec { -- //sound-dai = <&i2s_codec>; -- sound-dai = <&hdmi_tx>; -- }; -- }; -- }; -- }; - }; - - &i2c_B { -@@ -91,14 +57,3 @@ - pinctrl-names = "default"; - }; - --&aiu_i2s_dai { -- pinctrl-0 = <&i2s_am_clk_pins>, <&i2s_out_bclks_pins>, -- <&i2s_out_ch01_ao_pins>; -- pinctrl-names = "default"; -- status = "okay"; --}; -- --&aiu_i2s_dma { -- status = "okay"; --}; -- -diff --git a/arch/arm64/boot/dts/amlogic/meson-gxbb.dtsi b/arch/arm64/boot/dts/amlogic/meson-gxbb.dtsi -index 676c353..79bc445 100644 ---- a/arch/arm64/boot/dts/amlogic/meson-gxbb.dtsi -+++ b/arch/arm64/boot/dts/amlogic/meson-gxbb.dtsi -@@ -135,6 +135,32 @@ - dr_mode = "host"; - status = "disabled"; - }; -+ -+ sound { -+ compatible = "simple-audio-card"; -+ simple-audio-card,name = "meson-gxbb"; -+ status = "okay"; -+ -+ simple-audio-card,dai-link@0 { -+ /* HDMI Output */ -+ format = "i2s"; -+ mclk-fs = <256>; -+ bitclock-master = <&aiu_i2s_dai>; -+ frame-master = <&aiu_i2s_dai>; -+ plat { -+ sound-dai = <&aiu_i2s_dma>; -+ }; -+ -+ cpu { -+ sound-dai = <&aiu_i2s_dai>; -+ }; -+ -+ codec { -+ sound-dai = <&hdmi_tx>; -+ }; -+ }; -+ }; -+ - }; - }; - -@@ -178,7 +204,7 @@ - <&clkc CLKID_MIXER_IFACE>; - clock-names = "amclk","aiu_top", "aiu_glue", - "aoclk", "mixer_if"; -- status = "disbaled"; -+ status = "okay"; - }; - - aiu_i2s_dma: aiu_i2s_dma { -@@ -190,7 +216,7 @@ - <&clkc CLKID_I2S_OUT>; - clock-names = "aiu_top", "aiu_glue", - "i2s_out"; -- status = "disabled"; -+ status = "okay"; - }; - }; - --- -1.9.1 - diff --git a/patch/kernel/odroidc2-next/0091-clk-meson-merge-fixup.patch b/patch/kernel/odroidc2-next/0091-clk-meson-merge-fixup.patch deleted file mode 100644 index 82b4cf3e6..000000000 --- a/patch/kernel/odroidc2-next/0091-clk-meson-merge-fixup.patch +++ /dev/null @@ -1,34 +0,0 @@ -From 56f7ef263740cf489aaf19d3a395bf0627c58bf7 Mon Sep 17 00:00:00 2001 -From: Neil Armstrong -Date: Wed, 15 Feb 2017 13:13:52 +0100 -Subject: [PATCH 91/93] clk: meson: merge fixup - ---- - drivers/clk/meson/gxbb.c | 4 ---- - 1 file changed, 4 deletions(-) - -diff --git a/drivers/clk/meson/gxbb.c b/drivers/clk/meson/gxbb.c -index 9e2e407..bac0622 100644 ---- a/drivers/clk/meson/gxbb.c -+++ b/drivers/clk/meson/gxbb.c -@@ -1054,8 +1054,6 @@ - &gxbb_mali_0_sel, - &gxbb_mali_1_sel, - &gxbb_mali, -- &gxbb_mpeg_clk_sel, -- &gxbb_sar_adc_clk_sel, - &gxbb_cts_amclk_sel, - }; - -@@ -1063,8 +1061,6 @@ - &gxbb_mpeg_clk_div, - &gxbb_mali_0_div, - &gxbb_mali_1_div, -- &gxbb_mpeg_clk_div, -- &gxbb_sar_adc_clk_div, - }; - - struct gxbb_composite_clk { --- -1.9.1 - diff --git a/patch/kernel/odroidc2-next/0093-snd-soc-meson-aiu-i2s-Keep-div_lrclk-to-64-only.patch b/patch/kernel/odroidc2-next/0093-snd-soc-meson-aiu-i2s-Keep-div_lrclk-to-64-only.patch deleted file mode 100644 index d76d9b747..000000000 --- a/patch/kernel/odroidc2-next/0093-snd-soc-meson-aiu-i2s-Keep-div_lrclk-to-64-only.patch +++ /dev/null @@ -1,81 +0,0 @@ -From 6f6cf1c907049feee431c036cbdd3ac475535bd0 Mon Sep 17 00:00:00 2001 -From: Neil Armstrong -Date: Mon, 27 Mar 2017 12:04:00 +0200 -Subject: [PATCH 93/93] snd: soc: meson-aiu-i2s: Keep div_lrclk to 64 only - ---- - sound/soc/meson/aiu-i2s-dai.c | 37 ++++--------------------------------- - 1 file changed, 4 insertions(+), 33 deletions(-) - -diff --git a/sound/soc/meson/aiu-i2s-dai.c b/sound/soc/meson/aiu-i2s-dai.c -index 56a5b87..a37758f 100644 ---- a/sound/soc/meson/aiu-i2s-dai.c -+++ b/sound/soc/meson/aiu-i2s-dai.c -@@ -126,18 +126,6 @@ static int aiu_i2s_dai_trigger(struct snd_pcm_substream *substream, int cmd, - } - } - --static int __get_lrclk_div(unsigned int os, unsigned int width) --{ -- if (((os % 48) == 0) && (width == 24)) -- return 48; -- else if (((os % 64) == 0) && (width == 24)) -- return 64; -- else if (((os % 32) == 0) && (width == 16)) -- return 32; -- -- return -EINVAL; --} -- - /* - * FIXME: Most of this stuff should be done using CCF when the support of - * regmap based clocks is added -@@ -145,41 +133,24 @@ static int __get_lrclk_div(unsigned int os, unsigned int width) - static int __bclks_set_rate(struct aiu_i2s_dai *priv, unsigned int srate, - unsigned int width) - { -- int div_lrclk, div_bclk; -+ int div_bclk; - unsigned int os; - u32 val; - - /* Get the oversampling factor */ - os = DIV_ROUND_CLOSEST(clk_get_rate(priv->amclk), srate); - -- /* Get the divider between bclk and lrclk */ -- div_lrclk = __get_lrclk_div(os, width); -- -- switch (div_lrclk) { -- case 32: -- val = AIU_I2S_DAC_CFG_AOCLK_32; -- break; -- case 48: -- val = AIU_I2S_DAC_CFG_AOCLK_48; -- break; -- case 64: -- val = AIU_I2S_DAC_CFG_AOCLK_64; -- break; -- default: -- return -EINVAL; -- } -- - /* Set the divider between lrclk and bclk */ - regmap_update_bits(priv->regmap, AIU_I2S_DAC_CFG, - AIU_I2S_DAC_CFG_PAYLOAD_SIZE_MASK, -- val); -+ AIU_I2S_DAC_CFG_AOCLK_64); - - regmap_update_bits(priv->regmap, AIU_CODEC_DAC_LRCLK_CTRL, - AIU_CODEC_DAC_LRCLK_CTRL_DIV_MASK, -- AIU_CODEC_DAC_LRCLK_CTRL_DIV(div_lrclk)); -+ AIU_CODEC_DAC_LRCLK_CTRL_DIV(64)); - - /* Set the divider between blclk and amclk */ -- div_bclk = os / div_lrclk; -+ div_bclk = os / 64; - - /* Use CLK_MORE for the i2s divider */ - regmap_update_bits(priv->regmap, AIU_CLK_CTRL, --- -1.9.1 - diff --git a/patch/kernel/odroidc2-next/packaging-4.x-NEXT-with-postinstall-scripts.patch b/patch/kernel/odroidc2-next/packaging-4.x-NEXT-with-postinstall-scripts.patch index 91c2faad2..53c827bb1 100644 --- a/patch/kernel/odroidc2-next/packaging-4.x-NEXT-with-postinstall-scripts.patch +++ b/patch/kernel/odroidc2-next/packaging-4.x-NEXT-with-postinstall-scripts.patch @@ -1,10 +1,10 @@ diff --git a/scripts/package/builddeb b/scripts/package/builddeb -index 6c3b038..cc9b3c0 100755 +index aad67000..006d8ec7 100755 --- a/scripts/package/builddeb +++ b/scripts/package/builddeb -@@ -27,6 +27,28 @@ create_package() { - chown -R root:root "$pdir" - chmod -R go-w "$pdir" +@@ -29,6 +29,28 @@ create_package() { + # in case we are in a restrictive umask environment like 0077 + chmod -R a+rX "$pdir" + # Create preinstall and post install script to remove dtb + if [[ "$1" == *dtb* ]]; then @@ -20,18 +20,18 @@ index 6c3b038..cc9b3c0 100755 + echo "exit 0" >> $pdir/DEBIAN/postinst + chmod 775 $pdir/DEBIAN/postinst + fi -+ ++ + # Create postinstall script for headers + if [[ "$1" == *headers* ]]; then + echo "cd /usr/src/linux-headers-$version; echo \"Compiling headers - please wait ...\"; make -s scripts >/dev/null 2>&1" >> $pdir/DEBIAN/postinst + echo "exit 0" >> $pdir/DEBIAN/postinst + chmod 775 $pdir/DEBIAN/postinst + fi -+ ++ # Create the package dpkg-gencontrol $forcearch -Vkernel:debarch="${debarch}" -p$pname -P"$pdir" dpkg --build "$pdir" .. -@@ -93,11 +115,13 @@ tmpdir="$objtree/debian/tmp" +@@ -95,11 +117,13 @@ tmpdir="$objtree/debian/tmp" fwdir="$objtree/debian/fwtmp" kernel_headers_dir="$objtree/debian/hdrtmp" libc_headers_dir="$objtree/debian/headertmp" @@ -49,7 +49,7 @@ index 6c3b038..cc9b3c0 100755 dbg_packagename=$packagename-dbg debarch= forcearch= -@@ -124,7 +148,9 @@ esac +@@ -126,7 +150,9 @@ esac BUILD_DEBUG="$(grep -s '^CONFIG_DEBUG_INFO=y' $KCONFIG_CONFIG || true)" # Setup the directory structure @@ -60,7 +60,7 @@ index 6c3b038..cc9b3c0 100755 mkdir -m 755 -p "$tmpdir/DEBIAN" mkdir -p "$tmpdir/lib" "$tmpdir/boot" mkdir -p "$fwdir/lib/firmware/$version/" -@@ -183,6 +209,11 @@ if grep -q '^CONFIG_MODULES=y' $KCONFIG_CONFIG ; then +@@ -180,6 +206,11 @@ if grep -q '^CONFIG_MODULES=y' $KCONFIG_CONFIG ; then fi fi @@ -72,28 +72,7 @@ index 6c3b038..cc9b3c0 100755 if [ "$ARCH" != "um" ]; then $MAKE headers_check KBUILD_SRC= $MAKE headers_install KBUILD_SRC= INSTALL_HDR_PATH="$libc_headers_dir/usr" -@@ -195,7 +226,7 @@ fi - # so do we; recent versions of dracut and initramfs-tools will obey this. - debhookdir=${KDEB_HOOKDIR:-/etc/kernel} - if grep -q '^CONFIG_BLK_DEV_INITRD=y' $KCONFIG_CONFIG; then -- want_initrd=Yes -+ want_initrd=Yes - else - want_initrd=No - fi -@@ -207,9 +238,11 @@ for script in postinst postrm preinst prerm ; do - set -e - - # Pass maintainer script parameters to hook scripts -+ - export DEB_MAINT_PARAMS="\$*" - - # Tell initramfs builder whether it's wanted -+ - export INITRD=$want_initrd - - test -d $debhookdir/$script.d && run-parts --arg="$version" --arg="/$installed_image_path" $debhookdir/$script.d -@@ -218,6 +251,55 @@ EOF +@@ -215,6 +246,55 @@ EOF chmod 755 "$tmpdir/DEBIAN/$script" done @@ -149,33 +128,23 @@ index 6c3b038..cc9b3c0 100755 # Try to determine maintainer and email values if [ -n "$DEBEMAIL" ]; then email=$DEBEMAIL -@@ -328,16 +414,24 @@ fi - (cd $objtree; find arch/$SRCARCH/include Module.symvers include scripts -type f) >> "$objtree/debian/hdrobjfiles" +@@ -329,12 +409,15 @@ if grep -q '^CONFIG_GCC_PLUGINS=y' $KCONFIG_CONFIG ; then + fi destdir=$kernel_headers_dir/usr/src/linux-headers-$version mkdir -p "$destdir" -+######################## headers patch -+ZACNI=$(pwd) -+cd $destdir -+patch -p1 < /tmp/headers-debian-byteshift.patch -+cd $ZACNI -+######################## headers patch ++(cd $destdir; patch -p1 < /tmp/headers-debian-byteshift.patch) (cd $srctree; tar -c -f - -T -) < "$objtree/debian/hdrsrcfiles" | (cd $destdir; tar -xf -) (cd $objtree; tar -c -f - -T -) < "$objtree/debian/hdrobjfiles" | (cd $destdir; tar -xf -) (cd $objtree; cp $KCONFIG_CONFIG $destdir/.config) # copy .config manually to be where it's expected to be ln -sf "/usr/src/linux-headers-$version" "$kernel_headers_dir/lib/modules/$version/build" rm -f "$objtree/debian/hdrsrcfiles" "$objtree/debian/hdrobjfiles" -+(cd "$destdir"; make M=scripts clean) ++(cd $destdir; make M=scripts clean) + cat <> debian/control Package: $kernel_headers_packagename --Provides: linux-headers, linux-headers-2.6 -+Provides: linux-headers - Architecture: any - Description: Linux kernel headers for $KERNELRELEASE on \${kernel:debarch} - This package provides kernel header files for $KERNELRELEASE on \${kernel:debarch} -@@ -363,6 +457,16 @@ fi +@@ -363,6 +446,16 @@ fi cat <> debian/control @@ -192,7 +161,7 @@ index 6c3b038..cc9b3c0 100755 Package: $libc_headers_packagename Section: devel Provides: linux-kernel-headers -@@ -374,7 +478,7 @@ EOF +@@ -374,7 +467,7 @@ EOF if [ "$ARCH" != "um" ]; then create_package "$kernel_headers_packagename" "$kernel_headers_dir"