From a6611a92d5f4d3bab43feb1abf36924caf3ecc87 Mon Sep 17 00:00:00 2001 From: Zoltan Herpai Date: Sat, 9 Jan 2016 16:20:39 +0000 Subject: [PATCH] sunxi: initial 4.4 support Signed-off-by: Zoltan HERPAI SVN-Revision: 48161 --- target/linux/sunxi/config-4.4 | 509 +++++++++++++++ ...100-clk-sunxi-add-dram-gates-support.patch | 43 ++ .../101-dt-sun4i-add-dram-gates.patch | 90 +++ .../102-dt-sun7i-add-dram-gates.patch | 79 +++ .../103-clk-sunxi-add-h3-clksupport.patch | 189 ++++++ .../104-1-dt-sunxi-add-h3-dtsi.patch | 518 ++++++++++++++++ .../104-2-dt-sun8i-add-orangepi-plus.patch | 116 ++++ .../105-phy-use_of_match_node.patch | 220 +++++++ .../patches-4.4/106-phy-add-h3-usbphys.patch | 126 ++++ .../107-clk-sunxi-add-h3-usbphy-clocks.patch | 51 ++ .../110-clk-sunxi-add-ve-for-sun457i.patch | 233 +++++++ .../111-1-dt-sun4i-add-ve-clock-module.patch | 34 ++ .../111-2-dt-sun7i-add-ve-clock-module.patch | 34 ++ .../115-musb-ignore-vbus-errors.patch | 28 + .../116-crypto-add-missing-statesize.patch | 39 ++ .../130-pinctrl-sunxi-add-h3-pio.patch | 577 ++++++++++++++++++ .../patches-4.4/131-reset-add-h3-resets.patch | 95 +++ .../132-dt-sun8i-add-h3-usbclocks.patch | 36 ++ ...-sun8i-add-usbphy-usbhost-ctrl-nodes.patch | 125 ++++ ...dt-sun8i-orangepiplus-enable-usbhost.patch | 79 +++ .../135-clk-sunxi-fix-signedness-bug.patch | 27 + ...et-add-of_reset_control_get_by_index.patch | 113 ++++ .../141-reset-fix-of_reset_control_get.patch | 41 ++ ...reset-use-ENOTSUPP-instead-of-ENOSYS.patch | 91 +++ ...eset-add-shared-resetcontrol-asserts.patch | 271 ++++++++ ...lat-support-multiple-reset-ctrllines.patch | 131 ++++ ...lat-support-multiple-reset-ctrllines.patch | 132 ++++ ...50-dt-sun7i-enable-codec-on-pcduino3.patch | 29 + .../200-dt-sun7i-add-lamobo-r1.patch | 335 ++++++++++ 29 files changed, 4391 insertions(+) create mode 100644 target/linux/sunxi/config-4.4 create mode 100644 target/linux/sunxi/patches-4.4/100-clk-sunxi-add-dram-gates-support.patch create mode 100644 target/linux/sunxi/patches-4.4/101-dt-sun4i-add-dram-gates.patch create mode 100644 target/linux/sunxi/patches-4.4/102-dt-sun7i-add-dram-gates.patch create mode 100644 target/linux/sunxi/patches-4.4/103-clk-sunxi-add-h3-clksupport.patch create mode 100644 target/linux/sunxi/patches-4.4/104-1-dt-sunxi-add-h3-dtsi.patch create mode 100644 target/linux/sunxi/patches-4.4/104-2-dt-sun8i-add-orangepi-plus.patch create mode 100644 target/linux/sunxi/patches-4.4/105-phy-use_of_match_node.patch create mode 100644 target/linux/sunxi/patches-4.4/106-phy-add-h3-usbphys.patch create mode 100644 target/linux/sunxi/patches-4.4/107-clk-sunxi-add-h3-usbphy-clocks.patch create mode 100644 target/linux/sunxi/patches-4.4/110-clk-sunxi-add-ve-for-sun457i.patch create mode 100644 target/linux/sunxi/patches-4.4/111-1-dt-sun4i-add-ve-clock-module.patch create mode 100644 target/linux/sunxi/patches-4.4/111-2-dt-sun7i-add-ve-clock-module.patch create mode 100644 target/linux/sunxi/patches-4.4/115-musb-ignore-vbus-errors.patch create mode 100644 target/linux/sunxi/patches-4.4/116-crypto-add-missing-statesize.patch create mode 100644 target/linux/sunxi/patches-4.4/130-pinctrl-sunxi-add-h3-pio.patch create mode 100644 target/linux/sunxi/patches-4.4/131-reset-add-h3-resets.patch create mode 100644 target/linux/sunxi/patches-4.4/132-dt-sun8i-add-h3-usbclocks.patch create mode 100644 target/linux/sunxi/patches-4.4/133-dt-sun8i-add-usbphy-usbhost-ctrl-nodes.patch create mode 100644 target/linux/sunxi/patches-4.4/134-dt-sun8i-orangepiplus-enable-usbhost.patch create mode 100644 target/linux/sunxi/patches-4.4/135-clk-sunxi-fix-signedness-bug.patch create mode 100644 target/linux/sunxi/patches-4.4/140-reset-add-of_reset_control_get_by_index.patch create mode 100644 target/linux/sunxi/patches-4.4/141-reset-fix-of_reset_control_get.patch create mode 100644 target/linux/sunxi/patches-4.4/142-reset-use-ENOTSUPP-instead-of-ENOSYS.patch create mode 100644 target/linux/sunxi/patches-4.4/143-reset-add-shared-resetcontrol-asserts.patch create mode 100644 target/linux/sunxi/patches-4.4/144-usb-ehci-plat-support-multiple-reset-ctrllines.patch create mode 100644 target/linux/sunxi/patches-4.4/145-usb-ohci-plat-support-multiple-reset-ctrllines.patch create mode 100644 target/linux/sunxi/patches-4.4/150-dt-sun7i-enable-codec-on-pcduino3.patch create mode 100644 target/linux/sunxi/patches-4.4/200-dt-sun7i-add-lamobo-r1.patch diff --git a/target/linux/sunxi/config-4.4 b/target/linux/sunxi/config-4.4 new file mode 100644 index 0000000000..20cfe7a033 --- /dev/null +++ b/target/linux/sunxi/config-4.4 @@ -0,0 +1,509 @@ +CONFIG_ADVISE_SYSCALLS=y +# CONFIG_AHCI_SUNXI is not set +CONFIG_ALIGNMENT_TRAP=y +# CONFIG_APM_EMULATION is not set +CONFIG_ARCH_HAS_ATOMIC64_DEC_IF_POSITIVE=y +CONFIG_ARCH_HAS_ELF_RANDOMIZE=y +CONFIG_ARCH_HAS_GCOV_PROFILE_ALL=y +CONFIG_ARCH_HAS_RESET_CONTROLLER=y +CONFIG_ARCH_HAS_SG_CHAIN=y +CONFIG_ARCH_HAS_TICK_BROADCAST=y +CONFIG_ARCH_HAVE_CUSTOM_GPIO_H=y +CONFIG_ARCH_MIGHT_HAVE_PC_PARPORT=y +CONFIG_ARCH_MULTIPLATFORM=y +# CONFIG_ARCH_MULTI_CPU_AUTO is not set +CONFIG_ARCH_MULTI_V6_V7=y +CONFIG_ARCH_MULTI_V7=y +CONFIG_ARCH_NR_GPIO=416 +CONFIG_ARCH_REQUIRE_GPIOLIB=y +# CONFIG_ARCH_SELECT_MEMORY_MODEL is not set +# CONFIG_ARCH_SPARSEMEM_DEFAULT is not set +CONFIG_ARCH_SUNXI=y +CONFIG_ARCH_SUPPORTS_ATOMIC_RMW=y +CONFIG_ARCH_SUPPORTS_UPROBES=y +CONFIG_ARCH_USE_BUILTIN_BSWAP=y +CONFIG_ARCH_USE_CMPXCHG_LOCKREF=y +CONFIG_ARCH_WANT_GENERAL_HUGETLB=y +CONFIG_ARCH_WANT_IPC_PARSE_VERSION=y +CONFIG_ARCH_WANT_OPTIONAL_GPIOLIB=y +CONFIG_ARM=y +CONFIG_ARM_APPENDED_DTB=y +CONFIG_ARM_ARCH_TIMER=y +CONFIG_ARM_ARCH_TIMER_EVTSTREAM=y +CONFIG_ARM_ATAG_DTB_COMPAT=y +# CONFIG_ARM_ATAG_DTB_COMPAT_CMDLINE_EXTEND is not set +CONFIG_ARM_ATAG_DTB_COMPAT_CMDLINE_FROM_BOOTLOADER=y +CONFIG_ARM_CPU_SUSPEND=y +CONFIG_ARM_ERRATA_643719=y +CONFIG_ARM_GIC=y +CONFIG_ARM_HAS_SG_CHAIN=y +CONFIG_ARM_HEAVY_MB=y +CONFIG_ARM_L1_CACHE_SHIFT=6 +CONFIG_ARM_L1_CACHE_SHIFT_6=y +# CONFIG_ARM_LPAE is not set +CONFIG_ARM_PATCH_PHYS_VIRT=y +CONFIG_ARM_PMU=y +CONFIG_ARM_PSCI=y +CONFIG_ARM_PSCI_FW=y +CONFIG_ARM_THUMB=y +# CONFIG_ARM_THUMBEE is not set +CONFIG_ARM_UNWIND=y +CONFIG_ARM_VIRT_EXT=y +CONFIG_ATA=y +CONFIG_ATAGS=y +# CONFIG_ATA_SFF is not set +CONFIG_AUDIT=y +# CONFIG_AUDITSYSCALL is not set +CONFIG_AUDIT_GENERIC=y +CONFIG_AUTO_ZRELADDR=y +CONFIG_AXP20X_POWER=y +CONFIG_B53=y +# CONFIG_B53_MMAP_DRIVER is not set +CONFIG_B53_PHY_DRIVER=y +CONFIG_B53_PHY_FIXUP=y +# CONFIG_B53_SRAB_DRIVER is not set +CONFIG_BACKLIGHT_CLASS_DEVICE=y +CONFIG_BACKLIGHT_LCD_SUPPORT=y +CONFIG_BACKLIGHT_PWM=y +CONFIG_BINFMT_MISC=y +CONFIG_BOUNCE=y +# CONFIG_BPF_SYSCALL is not set +CONFIG_BUILD_BIN2C=y +CONFIG_CACHE_L2X0=y +CONFIG_CAN=y +CONFIG_CLKDEV_LOOKUP=y +CONFIG_CLKSRC_MMIO=y +CONFIG_CLKSRC_OF=y +CONFIG_CLKSRC_PROBE=y +CONFIG_CLONE_BACKWARDS=y +CONFIG_COMMON_CLK=y +CONFIG_COMPACTION=y +CONFIG_CONFIGFS_FS=y +CONFIG_CONNECTOR=y +CONFIG_CONSOLE_TRANSLATIONS=y +CONFIG_COREDUMP=y +CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS=y +CONFIG_CPUFREQ_DT=y +CONFIG_CPU_32v6K=y +CONFIG_CPU_32v7=y +CONFIG_CPU_ABRT_EV7=y +# CONFIG_CPU_BPREDICT_DISABLE is not set +CONFIG_CPU_CACHE_V7=y +CONFIG_CPU_CACHE_VIPT=y +CONFIG_CPU_COPY_V6=y +CONFIG_CPU_CP15=y +CONFIG_CPU_CP15_MMU=y +CONFIG_CPU_FREQ=y +CONFIG_CPU_FREQ_DEFAULT_GOV_PERFORMANCE=y +CONFIG_CPU_FREQ_GOV_COMMON=y +CONFIG_CPU_FREQ_GOV_CONSERVATIVE=y +CONFIG_CPU_FREQ_GOV_ONDEMAND=y +CONFIG_CPU_FREQ_GOV_PERFORMANCE=y +CONFIG_CPU_FREQ_GOV_POWERSAVE=y +CONFIG_CPU_FREQ_GOV_USERSPACE=y +CONFIG_CPU_FREQ_STAT=y +CONFIG_CPU_HAS_ASID=y +# CONFIG_CPU_ICACHE_DISABLE is not set +CONFIG_CPU_PABRT_V7=y +CONFIG_CPU_PM=y +CONFIG_CPU_RMAP=y +CONFIG_CPU_THERMAL=y +CONFIG_CPU_TLB_V7=y +CONFIG_CPU_V7=y +CONFIG_CRC16=y +CONFIG_CRC_T10DIF=y +CONFIG_CRYPTO_CRC32C=y +CONFIG_CRYPTO_CRCT10DIF=y +CONFIG_CRYPTO_DEV_SUN4I_SS=y +CONFIG_CRYPTO_HASH=y +CONFIG_CRYPTO_HASH2=y +CONFIG_CRYPTO_RNG2=y +CONFIG_CRYPTO_WORKQUEUE=y +CONFIG_DCACHE_WORD_ACCESS=y +CONFIG_DEBUG_BUGVERBOSE=y +CONFIG_DEBUG_LL_INCLUDE="mach/debug-macro.S" +CONFIG_DEBUG_MEMORY_INIT=y +# CONFIG_DEBUG_UART_8250 is not set +# CONFIG_DEBUG_USER is not set +CONFIG_DEFAULT_CFQ=y +# CONFIG_DEFAULT_DEADLINE is not set +CONFIG_DEFAULT_IOSCHED="cfq" +CONFIG_DIRECT_IO=y +CONFIG_DMADEVICES=y +CONFIG_DMA_ENGINE=y +CONFIG_DMA_OF=y +CONFIG_DMA_SUN4I=y +CONFIG_DMA_SUN6I=y +CONFIG_DMA_VIRTUAL_CHANNELS=y +CONFIG_DNOTIFY=y +CONFIG_DTC=y +CONFIG_DUMMY_CONSOLE=y +CONFIG_DWMAC_GENERIC=y +CONFIG_DWMAC_SUNXI=y +CONFIG_DYNAMIC_DEBUG=y +CONFIG_EDAC_ATOMIC_SCRUB=y +CONFIG_EDAC_SUPPORT=y +CONFIG_ELF_CORE=y +# CONFIG_EMBEDDED is not set +CONFIG_ENABLE_MUST_CHECK=y +# CONFIG_ENABLE_WARN_DEPRECATED is not set +CONFIG_EXT4_FS=y +CONFIG_EXTCON=y +CONFIG_FB=y +CONFIG_FB_CFB_COPYAREA=y +CONFIG_FB_CFB_FILLRECT=y +CONFIG_FB_CFB_IMAGEBLIT=y +CONFIG_FB_CMDLINE=y +CONFIG_FB_FOREIGN_ENDIAN=y +CONFIG_FB_LITTLE_ENDIAN=y +CONFIG_FB_MODE_HELPERS=y +CONFIG_FB_SIMPLE=y +CONFIG_FB_TILEBLITTING=y +CONFIG_FIX_EARLYCON_MEM=y +# CONFIG_FONTS is not set +CONFIG_FONT_8x16=y +CONFIG_FONT_8x8=y +CONFIG_FONT_SUPPORT=y +CONFIG_FRAMEBUFFER_CONSOLE=y +CONFIG_FRAMEBUFFER_CONSOLE_DETECT_PRIMARY=y +CONFIG_FRAMEBUFFER_CONSOLE_ROTATION=y +CONFIG_FRAME_WARN=2048 +CONFIG_FREEZER=y +CONFIG_FS_MBCACHE=y +CONFIG_FS_POSIX_ACL=y +CONFIG_GENERIC_ALLOCATOR=y +CONFIG_GENERIC_BUG=y +CONFIG_GENERIC_CLOCKEVENTS=y +CONFIG_GENERIC_CLOCKEVENTS_BROADCAST=y +CONFIG_GENERIC_IDLE_POLL_SETUP=y +CONFIG_GENERIC_IO=y +CONFIG_GENERIC_IRQ_CHIP=y +CONFIG_GENERIC_IRQ_SHOW=y +CONFIG_GENERIC_IRQ_SHOW_LEVEL=y +CONFIG_GENERIC_PCI_IOMAP=y +CONFIG_GENERIC_PHY=y +CONFIG_GENERIC_PINCONF=y +CONFIG_GENERIC_SCHED_CLOCK=y +CONFIG_GENERIC_SMP_IDLE_THREAD=y +CONFIG_GENERIC_STRNCPY_FROM_USER=y +CONFIG_GENERIC_STRNLEN_USER=y +CONFIG_GENERIC_TIME_VSYSCALL=y +CONFIG_GLOB=y +CONFIG_GPIOLIB=y +CONFIG_GPIO_DEVRES=y +CONFIG_GPIO_SYSFS=y +CONFIG_HANDLE_DOMAIN_IRQ=y +CONFIG_HARDIRQS_SW_RESEND=y +CONFIG_HAS_DMA=y +CONFIG_HAS_IOMEM=y +CONFIG_HAS_IOPORT_MAP=y +# CONFIG_HAVE_64BIT_ALIGNED_ACCESS is not set +CONFIG_HAVE_ARCH_AUDITSYSCALL=y +CONFIG_HAVE_ARCH_BITREVERSE=y +CONFIG_HAVE_ARCH_JUMP_LABEL=y +CONFIG_HAVE_ARCH_KGDB=y +CONFIG_HAVE_ARCH_PFN_VALID=y +CONFIG_HAVE_ARCH_SECCOMP_FILTER=y +CONFIG_HAVE_ARCH_TRACEHOOK=y +CONFIG_HAVE_ARM_ARCH_TIMER=y +# CONFIG_HAVE_BOOTMEM_INFO_NODE is not set +CONFIG_HAVE_BPF_JIT=y +CONFIG_HAVE_CC_STACKPROTECTOR=y +CONFIG_HAVE_CLK=y +CONFIG_HAVE_CLK_PREPARE=y +CONFIG_HAVE_CONTEXT_TRACKING=y +CONFIG_HAVE_C_RECORDMCOUNT=y +CONFIG_HAVE_DEBUG_KMEMLEAK=y +CONFIG_HAVE_DMA_API_DEBUG=y +CONFIG_HAVE_DMA_ATTRS=y +CONFIG_HAVE_DMA_CONTIGUOUS=y +CONFIG_HAVE_DYNAMIC_FTRACE=y +CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS=y +CONFIG_HAVE_FTRACE_MCOUNT_RECORD=y +CONFIG_HAVE_FUNCTION_GRAPH_TRACER=y +CONFIG_HAVE_FUNCTION_TRACER=y +CONFIG_HAVE_GENERIC_DMA_COHERENT=y +CONFIG_HAVE_HW_BREAKPOINT=y +CONFIG_HAVE_IRQ_TIME_ACCOUNTING=y +CONFIG_HAVE_KERNEL_GZIP=y +CONFIG_HAVE_KERNEL_LZ4=y +CONFIG_HAVE_KERNEL_LZMA=y +CONFIG_HAVE_KERNEL_LZO=y +CONFIG_HAVE_KERNEL_XZ=y +CONFIG_HAVE_MEMBLOCK=y +CONFIG_HAVE_MOD_ARCH_SPECIFIC=y +CONFIG_HAVE_NET_DSA=y +CONFIG_HAVE_OPROFILE=y +CONFIG_HAVE_OPTPROBES=y +CONFIG_HAVE_PERF_EVENTS=y +CONFIG_HAVE_PERF_REGS=y +CONFIG_HAVE_PERF_USER_STACK_DUMP=y +CONFIG_HAVE_PROC_CPU=y +CONFIG_HAVE_REGS_AND_STACK_ACCESS_API=y +CONFIG_HAVE_SMP=y +CONFIG_HAVE_SYSCALL_TRACEPOINTS=y +CONFIG_HAVE_UID16=y +CONFIG_HAVE_VIRT_CPU_ACCOUNTING_GEN=y +CONFIG_HIGHMEM=y +CONFIG_HIGHPTE=y +CONFIG_HOTPLUG_CPU=y +CONFIG_HWMON=y +CONFIG_HW_CONSOLE=y +CONFIG_HW_RANDOM=y +CONFIG_HW_RANDOM_TIMERIOMEM=y +CONFIG_HZ_FIXED=0 +CONFIG_I2C=y +CONFIG_I2C_BOARDINFO=y +CONFIG_I2C_CHARDEV=y +CONFIG_I2C_COMPAT=y +CONFIG_I2C_HELPER_AUTO=y +CONFIG_I2C_MV64XXX=y +CONFIG_I2C_SUN6I_P2WI=y +CONFIG_INITRAMFS_SOURCE="" +CONFIG_INPUT=y +CONFIG_INPUT_AXP20X_PEK=y +CONFIG_INPUT_KEYBOARD=y +CONFIG_INPUT_MOUSEDEV=y +CONFIG_INPUT_MOUSEDEV_PSAUX=y +CONFIG_INPUT_MOUSEDEV_SCREEN_X=1024 +CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768 +CONFIG_INPUT_TOUCHSCREEN=y +CONFIG_IOMMU_HELPER=y +CONFIG_IOSCHED_CFQ=y +CONFIG_IPC_NS=y +CONFIG_IRQCHIP=y +CONFIG_IRQ_DOMAIN=y +CONFIG_IRQ_DOMAIN_HIERARCHY=y +CONFIG_IRQ_FORCED_THREADING=y +CONFIG_IRQ_WORK=y +CONFIG_JBD2=y +CONFIG_KALLSYMS=y +# CONFIG_KERNEL_MODE_NEON is not set +CONFIG_KEYBOARD_SUN4I_LRADC=y +CONFIG_KSM=y +CONFIG_LCD_CLASS_DEVICE=y +CONFIG_LCD_PLATFORM=y +CONFIG_LEDS_GPIO=y +CONFIG_LEGACY_PTYS=y +CONFIG_LEGACY_PTY_COUNT=256 +CONFIG_LIBFDT=y +CONFIG_LOCK_SPIN_ON_OWNER=y +CONFIG_LOGO=y +CONFIG_LOGO_LINUX_CLUT224=y +CONFIG_LOGO_LINUX_MONO=y +CONFIG_LOGO_LINUX_VGA16=y +CONFIG_LOG_BUF_SHIFT=19 +CONFIG_LZO_COMPRESS=y +CONFIG_LZO_DECOMPRESS=y +CONFIG_MACH_SUN4I=y +CONFIG_MACH_SUN5I=y +CONFIG_MACH_SUN6I=y +CONFIG_MACH_SUN7I=y +CONFIG_MACH_SUN8I=y +CONFIG_MACH_SUN9I=y +CONFIG_MAGIC_SYSRQ=y +CONFIG_MDIO_BOARDINFO=y +CONFIG_MDIO_SUN4I=y +CONFIG_MEDIA_SUPPORT=y +CONFIG_MFD_AXP20X=y +CONFIG_MFD_CORE=y +CONFIG_MFD_SUN6I_PRCM=y +CONFIG_MFD_SYSCON=y +CONFIG_MIGHT_HAVE_CACHE_L2X0=y +CONFIG_MIGHT_HAVE_PCI=y +CONFIG_MIGRATION=y +CONFIG_MMC=y +CONFIG_MMC_BLOCK=y +# CONFIG_MMC_BLOCK_BOUNCE is not set +CONFIG_MMC_SUNXI=y +CONFIG_MODULES_TREE_LOOKUP=y +CONFIG_MODULES_USE_ELF_REL=y +# CONFIG_MTD is not set +CONFIG_MULTI_IRQ_HANDLER=y +CONFIG_MUTEX_SPIN_ON_OWNER=y +CONFIG_NAMESPACES=y +CONFIG_NEED_DMA_MAP_STATE=y +CONFIG_NEON=y +CONFIG_NET_FLOW_LIMIT=y +CONFIG_NET_NS=y +CONFIG_NET_PTP_CLASSIFY=y +CONFIG_NET_VENDOR_ALLWINNER=y +CONFIG_NLS=y +CONFIG_NO_BOOTMEM=y +CONFIG_NO_HZ=y +CONFIG_NO_HZ_COMMON=y +CONFIG_NO_HZ_IDLE=y +CONFIG_NR_CPUS=8 +CONFIG_NVMEM=y +# CONFIG_NVMEM_SUNXI_SID is not set +CONFIG_OF=y +CONFIG_OF_ADDRESS=y +CONFIG_OF_EARLY_FLATTREE=y +CONFIG_OF_FLATTREE=y +CONFIG_OF_GPIO=y +CONFIG_OF_IRQ=y +CONFIG_OF_MDIO=y +CONFIG_OF_NET=y +CONFIG_OF_RESERVED_MEM=y +CONFIG_OLD_SIGACTION=y +CONFIG_OLD_SIGSUSPEND3=y +CONFIG_OUTER_CACHE=y +CONFIG_OUTER_CACHE_SYNC=y +CONFIG_PAGE_OFFSET=0xC0000000 +# CONFIG_PARTITION_ADVANCED is not set +# CONFIG_PCI is not set +# CONFIG_PCI_DOMAINS_GENERIC is not set +# CONFIG_PCI_SYSCALL is not set +CONFIG_PERF_EVENTS=y +CONFIG_PERF_USE_VMALLOC=y +CONFIG_PGTABLE_LEVELS=2 +CONFIG_PHYLIB=y +CONFIG_PHY_SUN4I_USB=y +CONFIG_PHY_SUN9I_USB=y +CONFIG_PINCTRL=y +# CONFIG_PINCTRL_SINGLE is not set +CONFIG_PINCTRL_SUNXI_COMMON=y +# CONFIG_PL310_ERRATA_588369 is not set +# CONFIG_PL310_ERRATA_727915 is not set +# CONFIG_PL310_ERRATA_753970 is not set +# CONFIG_PL310_ERRATA_769419 is not set +CONFIG_PM=y +CONFIG_PM_CLK=y +# CONFIG_PM_DEBUG is not set +CONFIG_PM_OPP=y +CONFIG_PM_SLEEP=y +CONFIG_PM_SLEEP_SMP=y +CONFIG_POWER_RESET=y +CONFIG_POWER_SUPPLY=y +CONFIG_PPS=y +CONFIG_PREEMPT=y +CONFIG_PREEMPT_COUNT=y +# CONFIG_PREEMPT_NONE is not set +CONFIG_PREEMPT_RCU=y +CONFIG_PRINTK_TIME=y +CONFIG_PROC_EVENTS=y +CONFIG_PROC_PAGE_MONITOR=y +CONFIG_PTP_1588_CLOCK=y +CONFIG_PWM=y +CONFIG_PWM_SUN4I=y +CONFIG_PWM_SYSFS=y +CONFIG_RATIONAL=y +# CONFIG_RCU_BOOST is not set +CONFIG_RCU_STALL_COMMON=y +CONFIG_REGMAP=y +CONFIG_REGMAP_I2C=y +CONFIG_REGMAP_IRQ=y +CONFIG_REGMAP_MMIO=y +CONFIG_REGMAP_SPI=y +CONFIG_REGULATOR=y +CONFIG_REGULATOR_AXP20X=y +CONFIG_REGULATOR_FIXED_VOLTAGE=y +CONFIG_REGULATOR_GPIO=y +CONFIG_RELAY=y +CONFIG_RESET_CONTROLLER=y +CONFIG_RTC_CLASS=y +# CONFIG_RTC_DRV_SUNXI is not set +CONFIG_RWSEM_SPIN_ON_OWNER=y +CONFIG_RWSEM_XCHGADD_ALGORITHM=y +CONFIG_SATA_PMP=y +CONFIG_SCHED_HRTICK=y +CONFIG_SCHED_INFO=y +CONFIG_SCSI=y +CONFIG_SDIO_UART=y +CONFIG_SECURITYFS=y +CONFIG_SERIAL_8250_DEPRECATED_OPTIONS=y +CONFIG_SERIAL_8250_DW=y +CONFIG_SERIAL_8250_FSL=y +CONFIG_SERIAL_8250_NR_UARTS=8 +CONFIG_SERIAL_8250_RUNTIME_UARTS=8 +CONFIG_SERIAL_OF_PLATFORM=y +CONFIG_SERIO=y +CONFIG_SERIO_SERPORT=y +# CONFIG_SLAB is not set +CONFIG_SLUB=y +CONFIG_SLUB_CPU_PARTIAL=y +CONFIG_SLUB_DEBUG=y +# CONFIG_SLUB_DEBUG_ON is not set +CONFIG_SMP=y +CONFIG_SMP_ON_UP=y +CONFIG_SND=y +CONFIG_SND_COMPRESS_OFFLOAD=y +CONFIG_SND_JACK=y +CONFIG_SND_PCM=y +CONFIG_SND_SOC=y +CONFIG_SND_SOC_I2C_AND_SPI=y +# CONFIG_SND_USB is not set +CONFIG_SOUND=y +CONFIG_SPARSE_IRQ=y +CONFIG_SPI=y +CONFIG_SPI_MASTER=y +CONFIG_SPI_SUN4I=y +CONFIG_SPI_SUN6I=y +CONFIG_SRCU=y +# CONFIG_STAGING is not set +CONFIG_STMMAC_ETH=y +CONFIG_STMMAC_PLATFORM=y +CONFIG_STRICT_DEVMEM=y +# CONFIG_SUN4I_EMAC is not set +CONFIG_SUN4I_TIMER=y +CONFIG_SUN5I_HSTIMER=y +CONFIG_SUNXI_RSB=y +CONFIG_SUNXI_SRAM=y +CONFIG_SUNXI_WATCHDOG=y +CONFIG_SUSPEND=y +CONFIG_SUSPEND_FREEZER=y +CONFIG_SWCONFIG=y +CONFIG_SWIOTLB=y +CONFIG_SWP_EMULATE=y +CONFIG_SYSFS_SYSCALL=y +CONFIG_SYS_SUPPORTS_APM_EMULATION=y +CONFIG_THERMAL=y +CONFIG_THERMAL_DEFAULT_GOV_STEP_WISE=y +CONFIG_THERMAL_GOV_STEP_WISE=y +CONFIG_THERMAL_HWMON=y +CONFIG_THERMAL_OF=y +# CONFIG_THUMB2_KERNEL is not set +CONFIG_TICK_CPU_ACCOUNTING=y +CONFIG_TMPFS_POSIX_ACL=y +CONFIG_TOUCHSCREEN_PROPERTIES=y +CONFIG_TOUCHSCREEN_SUN4I=y +CONFIG_UNCOMPRESS_INCLUDE="debug/uncompress.h" +CONFIG_USB=y +CONFIG_USB_ANNOUNCE_NEW_DEVICES=y +# CONFIG_USB_AUDIO is not set +CONFIG_USB_COMMON=y +CONFIG_USB_DWC2=y +CONFIG_USB_DWC2_HOST=y +# CONFIG_USB_DWC2_TRACK_MISSED_SOFS is not set +CONFIG_USB_EHCI_HCD=y +CONFIG_USB_EHCI_HCD_PLATFORM=y +# CONFIG_USB_ETH is not set +CONFIG_USB_GADGET=y +CONFIG_USB_NET_DRIVERS=y +CONFIG_USB_OHCI_HCD=y +CONFIG_USB_OHCI_HCD_PLATFORM=y +CONFIG_USB_STORAGE=y +CONFIG_USB_SUPPORT=y +CONFIG_USERIO=y +CONFIG_USE_OF=y +CONFIG_UTS_NS=y +CONFIG_VDSO=y +CONFIG_VECTORS_BASE=0xffff0000 +CONFIG_VFP=y +CONFIG_VFPv3=y +CONFIG_VM_EVENT_COUNTERS=y +CONFIG_VT=y +CONFIG_VT_CONSOLE=y +CONFIG_VT_CONSOLE_SLEEP=y +CONFIG_VT_HW_CONSOLE_BINDING=y +CONFIG_WATCHDOG_CORE=y +# CONFIG_WQ_POWER_EFFICIENT_DEFAULT is not set +CONFIG_XFRM_ALGO=y +CONFIG_XFRM_USER=y +CONFIG_XPS=y +CONFIG_XZ_DEC_ARM=y +CONFIG_XZ_DEC_BCJ=y +CONFIG_ZBOOT_ROM_BSS=0 +CONFIG_ZBOOT_ROM_TEXT=0 +CONFIG_ZLIB_INFLATE=y +CONFIG_ZONE_DMA_FLAG=0 diff --git a/target/linux/sunxi/patches-4.4/100-clk-sunxi-add-dram-gates-support.patch b/target/linux/sunxi/patches-4.4/100-clk-sunxi-add-dram-gates-support.patch new file mode 100644 index 0000000000..f9caaa014c --- /dev/null +++ b/target/linux/sunxi/patches-4.4/100-clk-sunxi-add-dram-gates-support.patch @@ -0,0 +1,43 @@ +From 6d3a47c29186aa8d26ff05a6209c94291ace0696 Mon Sep 17 00:00:00 2001 +From: Chen-Yu Tsai +Date: Sat, 5 Dec 2015 21:16:42 +0800 +Subject: [PATCH] clk: sunxi: Add DRAM gates support for sun4i-a10 + +The A10/A20 share the same set of DRAM clock gates, which controls +direct memory access for some peripherals. + +On the A10, bit 15 controls the system's DRAM clock output (possibly +to the DRAM chips), which we need to keep on. + +On the A20 this has been moved to the DRAM controller, becoming a no-op. +However it is still listed in the user manual, so add it anyway. + +Signed-off-by: Chen-Yu Tsai +Signed-off-by: Maxime Ripard +--- + Documentation/devicetree/bindings/clock/sunxi.txt | 1 + + drivers/clk/sunxi/clk-simple-gates.c | 12 ++++++++++++ + 2 files changed, 13 insertions(+) + +diff --git a/Documentation/devicetree/bindings/clock/sunxi.txt b/Documentation/devicetree/bindings/clock/sunxi.txt +index 153ac72..ef0b452 100644 +diff --git a/drivers/clk/sunxi/clk-simple-gates.c b/drivers/clk/sunxi/clk-simple-gates.c +index c8acc06..f4da52b 100644 +--- a/drivers/clk/sunxi/clk-simple-gates.c ++++ b/drivers/clk/sunxi/clk-simple-gates.c +@@ -160,3 +160,15 @@ CLK_OF_DECLARE(sun5i_a13_ahb, "allwinner,sun5i-a13-ahb-gates-clk", + sun4i_a10_ahb_init); + CLK_OF_DECLARE(sun7i_a20_ahb, "allwinner,sun7i-a20-ahb-gates-clk", + sun4i_a10_ahb_init); ++ ++static const int sun4i_a10_dram_critical_clocks[] __initconst = { ++ 15, /* dram_output */ ++}; ++ ++static void __init sun4i_a10_dram_init(struct device_node *node) ++{ ++ sunxi_simple_gates_setup(node, sun4i_a10_dram_critical_clocks, ++ ARRAY_SIZE(sun4i_a10_dram_critical_clocks)); ++} ++CLK_OF_DECLARE(sun4i_a10_dram, "allwinner,sun4i-a10-dram-gates-clk", ++ sun4i_a10_dram_init); diff --git a/target/linux/sunxi/patches-4.4/101-dt-sun4i-add-dram-gates.patch b/target/linux/sunxi/patches-4.4/101-dt-sun4i-add-dram-gates.patch new file mode 100644 index 0000000000..9bdf400c9c --- /dev/null +++ b/target/linux/sunxi/patches-4.4/101-dt-sun4i-add-dram-gates.patch @@ -0,0 +1,90 @@ +From 82f8582feef4c048ee7ef0155a71c23614a7856d Mon Sep 17 00:00:00 2001 +From: Chen-Yu Tsai +Date: Sat, 5 Dec 2015 21:16:44 +0800 +Subject: [PATCH] ARM: dts: sun4i: Add DRAM gates + +The DRAM gates controls direct memory access for some peripherals. +These peripherals include the display pipeline, so add the required +gates to the simplefb nodes as well. + +Signed-off-by: Chen-Yu Tsai +Signed-off-by: Maxime Ripard +--- + arch/arm/boot/dts/sun4i-a10.dtsi | 36 ++++++++++++++++++++++++++++++++---- + 1 file changed, 32 insertions(+), 4 deletions(-) + +diff --git a/arch/arm/boot/dts/sun4i-a10.dtsi b/arch/arm/boot/dts/sun4i-a10.dtsi +index aa90f31..849d024 100644 +--- a/arch/arm/boot/dts/sun4i-a10.dtsi ++++ b/arch/arm/boot/dts/sun4i-a10.dtsi +@@ -66,7 +66,7 @@ + "simple-framebuffer"; + allwinner,pipeline = "de_be0-lcd0-hdmi"; + clocks = <&pll5 1>, <&ahb_gates 36>, <&ahb_gates 43>, +- <&ahb_gates 44>; ++ <&ahb_gates 44>, <&dram_gates 26>; + status = "disabled"; + }; + +@@ -75,7 +75,8 @@ + "simple-framebuffer"; + allwinner,pipeline = "de_fe0-de_be0-lcd0-hdmi"; + clocks = <&pll5 1>, <&ahb_gates 36>, <&ahb_gates 43>, +- <&ahb_gates 44>, <&ahb_gates 46>; ++ <&ahb_gates 44>, <&ahb_gates 46>, ++ <&dram_gates 25>, <&dram_gates 26>; + status = "disabled"; + }; + +@@ -84,7 +85,8 @@ + "simple-framebuffer"; + allwinner,pipeline = "de_fe0-de_be0-lcd0"; + clocks = <&pll5 1>, <&ahb_gates 36>, <&ahb_gates 44>, +- <&ahb_gates 46>; ++ <&ahb_gates 46>, <&dram_gates 25>, ++ <&dram_gates 26>; + status = "disabled"; + }; + +@@ -93,7 +95,8 @@ + "simple-framebuffer"; + allwinner,pipeline = "de_fe0-de_be0-lcd0-tve0"; + clocks = <&pll5 1>, <&ahb_gates 34>, <&ahb_gates 36>, +- <&ahb_gates 44>, <&ahb_gates 46>; ++ <&ahb_gates 44>, <&ahb_gates 46>, ++ <&dram_gates 25>, <&dram_gates 26>; + status = "disabled"; + }; + }; +@@ -492,6 +495,31 @@ + clock-output-names = "spi3"; + }; + ++ dram_gates: clk@01c20100 { ++ #clock-cells = <1>; ++ compatible = "allwinner,sun4i-a10-dram-gates-clk"; ++ reg = <0x01c20100 0x4>; ++ clocks = <&pll5 0>; ++ clock-indices = <0>, ++ <1>, <2>, ++ <3>, ++ <4>, ++ <5>, <6>, ++ <15>, ++ <24>, <25>, ++ <26>, <27>, ++ <28>, <29>; ++ clock-output-names = "dram_ve", ++ "dram_csi0", "dram_csi1", ++ "dram_ts", ++ "dram_tvd", ++ "dram_tve0", "dram_tve1", ++ "dram_output", ++ "dram_de_fe1", "dram_de_fe0", ++ "dram_de_be0", "dram_de_be1", ++ "dram_de_mp", "dram_ace"; ++ }; ++ + codec_clk: clk@01c20140 { + #clock-cells = <0>; + compatible = "allwinner,sun4i-a10-codec-clk"; diff --git a/target/linux/sunxi/patches-4.4/102-dt-sun7i-add-dram-gates.patch b/target/linux/sunxi/patches-4.4/102-dt-sun7i-add-dram-gates.patch new file mode 100644 index 0000000000..981ef5ba78 --- /dev/null +++ b/target/linux/sunxi/patches-4.4/102-dt-sun7i-add-dram-gates.patch @@ -0,0 +1,79 @@ +From 0b4bf5a5200b9ac5ddf545665f171feb5594677d Mon Sep 17 00:00:00 2001 +From: Chen-Yu Tsai +Date: Sat, 5 Dec 2015 21:16:46 +0800 +Subject: [PATCH] ARM: dts: sun7i: Add DRAM gates + +The DRAM gates controls direct memory access for some peripherals. +These peripherals include the display pipeline, so add the required +gates to the simplefb nodes as well. + +Signed-off-by: Chen-Yu Tsai +Signed-off-by: Maxime Ripard +--- + arch/arm/boot/dts/sun7i-a20.dtsi | 32 +++++++++++++++++++++++++++++--- + 1 file changed, 29 insertions(+), 3 deletions(-) + +diff --git a/arch/arm/boot/dts/sun7i-a20.dtsi b/arch/arm/boot/dts/sun7i-a20.dtsi +index e02eb72..21169c0 100644 +--- a/arch/arm/boot/dts/sun7i-a20.dtsi ++++ b/arch/arm/boot/dts/sun7i-a20.dtsi +@@ -68,7 +68,7 @@ + "simple-framebuffer"; + allwinner,pipeline = "de_be0-lcd0-hdmi"; + clocks = <&pll5 1>, <&ahb_gates 36>, <&ahb_gates 43>, +- <&ahb_gates 44>; ++ <&ahb_gates 44>, <&dram_gates 26>; + status = "disabled"; + }; + +@@ -76,7 +76,8 @@ + compatible = "allwinner,simple-framebuffer", + "simple-framebuffer"; + allwinner,pipeline = "de_be0-lcd0"; +- clocks = <&pll5 1>, <&ahb_gates 36>, <&ahb_gates 44>; ++ clocks = <&pll5 1>, <&ahb_gates 36>, <&ahb_gates 44>, ++ <&dram_gates 26>; + status = "disabled"; + }; + +@@ -85,7 +86,7 @@ + "simple-framebuffer"; + allwinner,pipeline = "de_be0-lcd0-tve0"; + clocks = <&pll5 1>, <&ahb_gates 34>, <&ahb_gates 36>, +- <&ahb_gates 44>; ++ <&ahb_gates 44>, <&dram_gates 26>; + status = "disabled"; + }; + }; +@@ -501,6 +502,31 @@ + clock-output-names = "spi3"; + }; + ++ dram_gates: clk@01c20100 { ++ #clock-cells = <1>; ++ compatible = "allwinner,sun4i-a10-dram-gates-clk"; ++ reg = <0x01c20100 0x4>; ++ clocks = <&pll5 0>; ++ clock-indices = <0>, ++ <1>, <2>, ++ <3>, ++ <4>, ++ <5>, <6>, ++ <15>, ++ <24>, <25>, ++ <26>, <27>, ++ <28>, <29>; ++ clock-output-names = "dram_ve", ++ "dram_csi0", "dram_csi1", ++ "dram_ts", ++ "dram_tvd", ++ "dram_tve0", "dram_tve1", ++ "dram_output", ++ "dram_de_fe1", "dram_de_fe0", ++ "dram_de_be0", "dram_de_be1", ++ "dram_de_mp", "dram_ace"; ++ }; ++ + codec_clk: clk@01c20140 { + #clock-cells = <0>; + compatible = "allwinner,sun4i-a10-codec-clk"; diff --git a/target/linux/sunxi/patches-4.4/103-clk-sunxi-add-h3-clksupport.patch b/target/linux/sunxi/patches-4.4/103-clk-sunxi-add-h3-clksupport.patch new file mode 100644 index 0000000000..04a536f330 --- /dev/null +++ b/target/linux/sunxi/patches-4.4/103-clk-sunxi-add-h3-clksupport.patch @@ -0,0 +1,189 @@ +From ab6e23a4e388f5f2696b8e92c350f845142da118 Mon Sep 17 00:00:00 2001 +From: Jens Kuske +Date: Fri, 4 Dec 2015 22:24:40 +0100 +Subject: [PATCH] clk: sunxi: Add H3 clocks support + +The H3 clock control unit is similar to the those of other sun8i family +members like the A23. + +It adds a new bus gates clock similar to the simple gates, but with a +different parent clock for each single gate. +Some of the gates use the new AHB2 clock as parent, whose clock source +is muxable between AHB1 and PLL6/2. The documentation isn't totally clear +about which devices belong to AHB2 now, especially USB EHIC/OHIC, so it +is mostly based on Allwinner kernel source code. + +Signed-off-by: Jens Kuske +Acked-by: Rob Herring +Signed-off-by: Maxime Ripard +--- + Documentation/devicetree/bindings/clock/sunxi.txt | 2 + + drivers/clk/sunxi/Makefile | 1 + + drivers/clk/sunxi/clk-sun8i-bus-gates.c | 112 ++++++++++++++++++++++ + drivers/clk/sunxi/clk-sunxi.c | 6 ++ + 4 files changed, 121 insertions(+) + create mode 100644 drivers/clk/sunxi/clk-sun8i-bus-gates.c + +diff --git a/Documentation/devicetree/bindings/clock/sunxi.txt b/Documentation/devicetree/bindings/clock/sunxi.txt +index ef0b452..014eab8 100644 +diff --git a/drivers/clk/sunxi/Makefile b/drivers/clk/sunxi/Makefile +index 103efab..abf4916 100644 +--- a/drivers/clk/sunxi/Makefile ++++ b/drivers/clk/sunxi/Makefile +@@ -10,6 +10,7 @@ obj-y += clk-a10-pll2.o + obj-y += clk-a20-gmac.o + obj-y += clk-mod0.o + obj-y += clk-simple-gates.o ++obj-y += clk-sun8i-bus-gates.o + obj-y += clk-sun8i-mbus.o + obj-y += clk-sun9i-core.o + obj-y += clk-sun9i-mmc.o +diff --git a/drivers/clk/sunxi/clk-sun8i-bus-gates.c b/drivers/clk/sunxi/clk-sun8i-bus-gates.c +new file mode 100644 +index 0000000..7ab60c5 +--- /dev/null ++++ b/drivers/clk/sunxi/clk-sun8i-bus-gates.c +@@ -0,0 +1,112 @@ ++/* ++ * Copyright (C) 2015 Jens Kuske ++ * ++ * Based on clk-simple-gates.c, which is: ++ * Copyright 2015 Maxime Ripard ++ * ++ * Maxime Ripard ++ * ++ * 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. ++ */ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++ ++static DEFINE_SPINLOCK(gates_lock); ++ ++static void __init sun8i_h3_bus_gates_init(struct device_node *node) ++{ ++ static const char * const names[] = { "ahb1", "ahb2", "apb1", "apb2" }; ++ enum { AHB1, AHB2, APB1, APB2, PARENT_MAX } clk_parent; ++ const char *parents[PARENT_MAX]; ++ struct clk_onecell_data *clk_data; ++ const char *clk_name; ++ struct property *prop; ++ struct resource res; ++ void __iomem *clk_reg; ++ void __iomem *reg; ++ const __be32 *p; ++ int number, i; ++ u8 clk_bit; ++ u32 index; ++ ++ reg = of_io_request_and_map(node, 0, of_node_full_name(node)); ++ if (IS_ERR(reg)) ++ return; ++ ++ for (i = 0; i < ARRAY_SIZE(names); i++) { ++ index = of_property_match_string(node, "clock-names", ++ names[i]); ++ if (index < 0) ++ return; ++ ++ parents[i] = of_clk_get_parent_name(node, index); ++ } ++ ++ clk_data = kmalloc(sizeof(struct clk_onecell_data), GFP_KERNEL); ++ if (!clk_data) ++ goto err_unmap; ++ ++ number = of_property_count_u32_elems(node, "clock-indices"); ++ of_property_read_u32_index(node, "clock-indices", number - 1, &number); ++ ++ clk_data->clks = kcalloc(number + 1, sizeof(struct clk *), GFP_KERNEL); ++ if (!clk_data->clks) ++ goto err_free_data; ++ ++ i = 0; ++ of_property_for_each_u32(node, "clock-indices", prop, p, index) { ++ of_property_read_string_index(node, "clock-output-names", ++ i, &clk_name); ++ ++ if (index == 17 || (index >= 29 && index <= 31)) ++ clk_parent = AHB2; ++ else if (index <= 63 || index >= 128) ++ clk_parent = AHB1; ++ else if (index >= 64 && index <= 95) ++ clk_parent = APB1; ++ else if (index >= 96 && index <= 127) ++ clk_parent = APB2; ++ ++ clk_reg = reg + 4 * (index / 32); ++ clk_bit = index % 32; ++ ++ clk_data->clks[index] = clk_register_gate(NULL, clk_name, ++ parents[clk_parent], ++ 0, clk_reg, clk_bit, ++ 0, &gates_lock); ++ i++; ++ ++ if (IS_ERR(clk_data->clks[index])) { ++ WARN_ON(true); ++ continue; ++ } ++ } ++ ++ clk_data->clk_num = number + 1; ++ of_clk_add_provider(node, of_clk_src_onecell_get, clk_data); ++ ++ return; ++ ++err_free_data: ++ kfree(clk_data); ++err_unmap: ++ iounmap(reg); ++ of_address_to_resource(node, 0, &res); ++ release_mem_region(res.start, resource_size(&res)); ++} ++ ++CLK_OF_DECLARE(sun8i_h3_bus_gates, "allwinner,sun8i-h3-bus-gates-clk", ++ sun8i_h3_bus_gates_init); +diff --git a/drivers/clk/sunxi/clk-sunxi.c b/drivers/clk/sunxi/clk-sunxi.c +index 9c79af0c..5ba2188 100644 +--- a/drivers/clk/sunxi/clk-sunxi.c ++++ b/drivers/clk/sunxi/clk-sunxi.c +@@ -778,6 +778,10 @@ static const struct mux_data sun6i_a31_ahb1_mux_data __initconst = { + .shift = 12, + }; + ++static const struct mux_data sun8i_h3_ahb2_mux_data __initconst = { ++ .shift = 0, ++}; ++ + static void __init sunxi_mux_clk_setup(struct device_node *node, + struct mux_data *data) + { +@@ -1130,6 +1134,7 @@ static const struct of_device_id clk_divs_match[] __initconst = { + static const struct of_device_id clk_mux_match[] __initconst = { + {.compatible = "allwinner,sun4i-a10-cpu-clk", .data = &sun4i_cpu_mux_data,}, + {.compatible = "allwinner,sun6i-a31-ahb1-mux-clk", .data = &sun6i_a31_ahb1_mux_data,}, ++ {.compatible = "allwinner,sun8i-h3-ahb2-clk", .data = &sun8i_h3_ahb2_mux_data,}, + {} + }; + +@@ -1212,6 +1217,7 @@ CLK_OF_DECLARE(sun6i_a31_clk_init, "allwinner,sun6i-a31", sun6i_init_clocks); + CLK_OF_DECLARE(sun6i_a31s_clk_init, "allwinner,sun6i-a31s", sun6i_init_clocks); + CLK_OF_DECLARE(sun8i_a23_clk_init, "allwinner,sun8i-a23", sun6i_init_clocks); + CLK_OF_DECLARE(sun8i_a33_clk_init, "allwinner,sun8i-a33", sun6i_init_clocks); ++CLK_OF_DECLARE(sun8i_h3_clk_init, "allwinner,sun8i-h3", sun6i_init_clocks); + + static void __init sun9i_init_clocks(struct device_node *node) + { diff --git a/target/linux/sunxi/patches-4.4/104-1-dt-sunxi-add-h3-dtsi.patch b/target/linux/sunxi/patches-4.4/104-1-dt-sunxi-add-h3-dtsi.patch new file mode 100644 index 0000000000..19e957bd61 --- /dev/null +++ b/target/linux/sunxi/patches-4.4/104-1-dt-sunxi-add-h3-dtsi.patch @@ -0,0 +1,518 @@ +From 318d93bc41823e86967c8251eef0444a72e4d687 Mon Sep 17 00:00:00 2001 +From: Jens Kuske +Date: Fri, 4 Dec 2015 22:24:42 +0100 +Subject: [PATCH] ARM: dts: sunxi: Add Allwinner H3 DTSI + +The Allwinner H3 is a home entertainment system oriented SoC with +four Cortex-A7 cores and a Mali-400MP2 GPU. + +Signed-off-by: Jens Kuske +Signed-off-by: Maxime Ripard +--- + arch/arm/boot/dts/sun8i-h3.dtsi | 497 ++++++++++++++++++++++++++++++++++++++++ + 1 file changed, 497 insertions(+) + create mode 100644 arch/arm/boot/dts/sun8i-h3.dtsi + +diff --git a/arch/arm/boot/dts/sun8i-h3.dtsi b/arch/arm/boot/dts/sun8i-h3.dtsi +new file mode 100644 +index 0000000..1524130e +--- /dev/null ++++ b/arch/arm/boot/dts/sun8i-h3.dtsi +@@ -0,0 +1,497 @@ ++/* ++ * Copyright (C) 2015 Jens Kuske ++ * ++ * 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 file 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 file 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. ++ */ ++ ++#include "skeleton.dtsi" ++ ++#include ++#include ++ ++/ { ++ interrupt-parent = <&gic>; ++ ++ cpus { ++ #address-cells = <1>; ++ #size-cells = <0>; ++ ++ cpu@0 { ++ compatible = "arm,cortex-a7"; ++ device_type = "cpu"; ++ reg = <0>; ++ }; ++ ++ cpu@1 { ++ compatible = "arm,cortex-a7"; ++ device_type = "cpu"; ++ reg = <1>; ++ }; ++ ++ cpu@2 { ++ compatible = "arm,cortex-a7"; ++ device_type = "cpu"; ++ reg = <2>; ++ }; ++ ++ cpu@3 { ++ compatible = "arm,cortex-a7"; ++ device_type = "cpu"; ++ reg = <3>; ++ }; ++ }; ++ ++ timer { ++ compatible = "arm,armv7-timer"; ++ interrupts = , ++ , ++ , ++ ; ++ }; ++ ++ clocks { ++ #address-cells = <1>; ++ #size-cells = <1>; ++ ranges; ++ ++ osc24M: osc24M_clk { ++ #clock-cells = <0>; ++ compatible = "fixed-clock"; ++ clock-frequency = <24000000>; ++ clock-output-names = "osc24M"; ++ }; ++ ++ osc32k: osc32k_clk { ++ #clock-cells = <0>; ++ compatible = "fixed-clock"; ++ clock-frequency = <32768>; ++ clock-output-names = "osc32k"; ++ }; ++ ++ pll1: clk@01c20000 { ++ #clock-cells = <0>; ++ compatible = "allwinner,sun8i-a23-pll1-clk"; ++ reg = <0x01c20000 0x4>; ++ clocks = <&osc24M>; ++ clock-output-names = "pll1"; ++ }; ++ ++ /* dummy clock until actually implemented */ ++ pll5: pll5_clk { ++ #clock-cells = <0>; ++ compatible = "fixed-clock"; ++ clock-frequency = <0>; ++ clock-output-names = "pll5"; ++ }; ++ ++ pll6: clk@01c20028 { ++ #clock-cells = <1>; ++ compatible = "allwinner,sun6i-a31-pll6-clk"; ++ reg = <0x01c20028 0x4>; ++ clocks = <&osc24M>; ++ clock-output-names = "pll6", "pll6x2"; ++ }; ++ ++ pll6d2: pll6d2_clk { ++ #clock-cells = <0>; ++ compatible = "fixed-factor-clock"; ++ clock-div = <2>; ++ clock-mult = <1>; ++ clocks = <&pll6 0>; ++ clock-output-names = "pll6d2"; ++ }; ++ ++ /* dummy clock until pll6 can be reused */ ++ pll8: pll8_clk { ++ #clock-cells = <0>; ++ compatible = "fixed-clock"; ++ clock-frequency = <1>; ++ clock-output-names = "pll8"; ++ }; ++ ++ cpu: cpu_clk@01c20050 { ++ #clock-cells = <0>; ++ compatible = "allwinner,sun4i-a10-cpu-clk"; ++ reg = <0x01c20050 0x4>; ++ clocks = <&osc32k>, <&osc24M>, <&pll1>, <&pll1>; ++ clock-output-names = "cpu"; ++ }; ++ ++ axi: axi_clk@01c20050 { ++ #clock-cells = <0>; ++ compatible = "allwinner,sun4i-a10-axi-clk"; ++ reg = <0x01c20050 0x4>; ++ clocks = <&cpu>; ++ clock-output-names = "axi"; ++ }; ++ ++ ahb1: ahb1_clk@01c20054 { ++ #clock-cells = <0>; ++ compatible = "allwinner,sun6i-a31-ahb1-clk"; ++ reg = <0x01c20054 0x4>; ++ clocks = <&osc32k>, <&osc24M>, <&axi>, <&pll6 0>; ++ clock-output-names = "ahb1"; ++ }; ++ ++ ahb2: ahb2_clk@01c2005c { ++ #clock-cells = <0>; ++ compatible = "allwinner,sun8i-h3-ahb2-clk"; ++ reg = <0x01c2005c 0x4>; ++ clocks = <&ahb1>, <&pll6d2>; ++ clock-output-names = "ahb2"; ++ }; ++ ++ apb1: apb1_clk@01c20054 { ++ #clock-cells = <0>; ++ compatible = "allwinner,sun4i-a10-apb0-clk"; ++ reg = <0x01c20054 0x4>; ++ clocks = <&ahb1>; ++ clock-output-names = "apb1"; ++ }; ++ ++ apb2: apb2_clk@01c20058 { ++ #clock-cells = <0>; ++ compatible = "allwinner,sun4i-a10-apb1-clk"; ++ reg = <0x01c20058 0x4>; ++ clocks = <&osc32k>, <&osc24M>, <&pll6 0>, <&pll6 0>; ++ clock-output-names = "apb2"; ++ }; ++ ++ bus_gates: clk@01c20060 { ++ #clock-cells = <1>; ++ compatible = "allwinner,sun8i-h3-bus-gates-clk"; ++ reg = <0x01c20060 0x14>; ++ clocks = <&ahb1>, <&ahb2>, <&apb1>, <&apb2>; ++ clock-names = "ahb1", "ahb2", "apb1", "apb2"; ++ clock-indices = <5>, <6>, <8>, ++ <9>, <10>, <13>, ++ <14>, <17>, <18>, ++ <19>, <20>, ++ <21>, <23>, ++ <24>, <25>, ++ <26>, <27>, ++ <28>, <29>, ++ <30>, <31>, <32>, ++ <35>, <36>, <37>, ++ <40>, <41>, <43>, ++ <44>, <52>, <53>, ++ <54>, <64>, ++ <65>, <69>, <72>, ++ <76>, <77>, <78>, ++ <96>, <97>, <98>, ++ <112>, <113>, ++ <114>, <115>, ++ <116>, <128>, <135>; ++ clock-output-names = "bus_ce", "bus_dma", "bus_mmc0", ++ "bus_mmc1", "bus_mmc2", "bus_nand", ++ "bus_sdram", "bus_gmac", "bus_ts", ++ "bus_hstimer", "bus_spi0", ++ "bus_spi1", "bus_otg", ++ "bus_otg_ehci0", "bus_ehci1", ++ "bus_ehci2", "bus_ehci3", ++ "bus_otg_ohci0", "bus_ohci1", ++ "bus_ohci2", "bus_ohci3", "bus_ve", ++ "bus_lcd0", "bus_lcd1", "bus_deint", ++ "bus_csi", "bus_tve", "bus_hdmi", ++ "bus_de", "bus_gpu", "bus_msgbox", ++ "bus_spinlock", "bus_codec", ++ "bus_spdif", "bus_pio", "bus_ths", ++ "bus_i2s0", "bus_i2s1", "bus_i2s2", ++ "bus_i2c0", "bus_i2c1", "bus_i2c2", ++ "bus_uart0", "bus_uart1", ++ "bus_uart2", "bus_uart3", ++ "bus_scr", "bus_ephy", "bus_dbg"; ++ }; ++ ++ mmc0_clk: clk@01c20088 { ++ #clock-cells = <1>; ++ compatible = "allwinner,sun4i-a10-mmc-clk"; ++ reg = <0x01c20088 0x4>; ++ clocks = <&osc24M>, <&pll6 0>, <&pll8>; ++ clock-output-names = "mmc0", ++ "mmc0_output", ++ "mmc0_sample"; ++ }; ++ ++ mmc1_clk: clk@01c2008c { ++ #clock-cells = <1>; ++ compatible = "allwinner,sun4i-a10-mmc-clk"; ++ reg = <0x01c2008c 0x4>; ++ clocks = <&osc24M>, <&pll6 0>, <&pll8>; ++ clock-output-names = "mmc1", ++ "mmc1_output", ++ "mmc1_sample"; ++ }; ++ ++ mmc2_clk: clk@01c20090 { ++ #clock-cells = <1>; ++ compatible = "allwinner,sun4i-a10-mmc-clk"; ++ reg = <0x01c20090 0x4>; ++ clocks = <&osc24M>, <&pll6 0>, <&pll8>; ++ clock-output-names = "mmc2", ++ "mmc2_output", ++ "mmc2_sample"; ++ }; ++ ++ mbus_clk: clk@01c2015c { ++ #clock-cells = <0>; ++ compatible = "allwinner,sun8i-a23-mbus-clk"; ++ reg = <0x01c2015c 0x4>; ++ clocks = <&osc24M>, <&pll6 1>, <&pll5>; ++ clock-output-names = "mbus"; ++ }; ++ }; ++ ++ soc { ++ compatible = "simple-bus"; ++ #address-cells = <1>; ++ #size-cells = <1>; ++ ranges; ++ ++ dma: dma-controller@01c02000 { ++ compatible = "allwinner,sun8i-h3-dma"; ++ reg = <0x01c02000 0x1000>; ++ interrupts = ; ++ clocks = <&bus_gates 6>; ++ resets = <&ahb_rst 6>; ++ #dma-cells = <1>; ++ }; ++ ++ mmc0: mmc@01c0f000 { ++ compatible = "allwinner,sun5i-a13-mmc"; ++ reg = <0x01c0f000 0x1000>; ++ clocks = <&bus_gates 8>, ++ <&mmc0_clk 0>, ++ <&mmc0_clk 1>, ++ <&mmc0_clk 2>; ++ clock-names = "ahb", ++ "mmc", ++ "output", ++ "sample"; ++ resets = <&ahb_rst 8>; ++ reset-names = "ahb"; ++ interrupts = ; ++ status = "disabled"; ++ #address-cells = <1>; ++ #size-cells = <0>; ++ }; ++ ++ mmc1: mmc@01c10000 { ++ compatible = "allwinner,sun5i-a13-mmc"; ++ reg = <0x01c10000 0x1000>; ++ clocks = <&bus_gates 9>, ++ <&mmc1_clk 0>, ++ <&mmc1_clk 1>, ++ <&mmc1_clk 2>; ++ clock-names = "ahb", ++ "mmc", ++ "output", ++ "sample"; ++ resets = <&ahb_rst 9>; ++ reset-names = "ahb"; ++ interrupts = ; ++ status = "disabled"; ++ #address-cells = <1>; ++ #size-cells = <0>; ++ }; ++ ++ mmc2: mmc@01c11000 { ++ compatible = "allwinner,sun5i-a13-mmc"; ++ reg = <0x01c11000 0x1000>; ++ clocks = <&bus_gates 10>, ++ <&mmc2_clk 0>, ++ <&mmc2_clk 1>, ++ <&mmc2_clk 2>; ++ clock-names = "ahb", ++ "mmc", ++ "output", ++ "sample"; ++ resets = <&ahb_rst 10>; ++ reset-names = "ahb"; ++ interrupts = ; ++ status = "disabled"; ++ #address-cells = <1>; ++ #size-cells = <0>; ++ }; ++ ++ pio: pinctrl@01c20800 { ++ compatible = "allwinner,sun8i-h3-pinctrl"; ++ reg = <0x01c20800 0x400>; ++ interrupts = , ++ ; ++ clocks = <&bus_gates 69>; ++ gpio-controller; ++ #gpio-cells = <3>; ++ interrupt-controller; ++ #interrupt-cells = <2>; ++ ++ uart0_pins_a: uart0@0 { ++ allwinner,pins = "PA4", "PA5"; ++ allwinner,function = "uart0"; ++ allwinner,drive = ; ++ allwinner,pull = ; ++ }; ++ ++ mmc0_pins_a: mmc0@0 { ++ allwinner,pins = "PF0", "PF1", "PF2", "PF3", ++ "PF4", "PF5"; ++ allwinner,function = "mmc0"; ++ allwinner,drive = ; ++ allwinner,pull = ; ++ }; ++ ++ mmc0_cd_pin: mmc0_cd_pin@0 { ++ allwinner,pins = "PF6"; ++ allwinner,function = "gpio_in"; ++ allwinner,drive = ; ++ allwinner,pull = ; ++ }; ++ ++ mmc1_pins_a: mmc1@0 { ++ allwinner,pins = "PG0", "PG1", "PG2", "PG3", ++ "PG4", "PG5"; ++ allwinner,function = "mmc1"; ++ allwinner,drive = ; ++ allwinner,pull = ; ++ }; ++ }; ++ ++ ahb_rst: reset@01c202c0 { ++ #reset-cells = <1>; ++ compatible = "allwinner,sun6i-a31-ahb1-reset"; ++ reg = <0x01c202c0 0xc>; ++ }; ++ ++ apb1_rst: reset@01c202d0 { ++ #reset-cells = <1>; ++ compatible = "allwinner,sun6i-a31-clock-reset"; ++ reg = <0x01c202d0 0x4>; ++ }; ++ ++ apb2_rst: reset@01c202d8 { ++ #reset-cells = <1>; ++ compatible = "allwinner,sun6i-a31-clock-reset"; ++ reg = <0x01c202d8 0x4>; ++ }; ++ ++ timer@01c20c00 { ++ compatible = "allwinner,sun4i-a10-timer"; ++ reg = <0x01c20c00 0xa0>; ++ interrupts = , ++ ; ++ clocks = <&osc24M>; ++ }; ++ ++ wdt0: watchdog@01c20ca0 { ++ compatible = "allwinner,sun6i-a31-wdt"; ++ reg = <0x01c20ca0 0x20>; ++ interrupts = ; ++ }; ++ ++ uart0: serial@01c28000 { ++ compatible = "snps,dw-apb-uart"; ++ reg = <0x01c28000 0x400>; ++ interrupts = ; ++ reg-shift = <2>; ++ reg-io-width = <4>; ++ clocks = <&bus_gates 112>; ++ resets = <&apb2_rst 16>; ++ dmas = <&dma 6>, <&dma 6>; ++ dma-names = "rx", "tx"; ++ status = "disabled"; ++ }; ++ ++ uart1: serial@01c28400 { ++ compatible = "snps,dw-apb-uart"; ++ reg = <0x01c28400 0x400>; ++ interrupts = ; ++ reg-shift = <2>; ++ reg-io-width = <4>; ++ clocks = <&bus_gates 113>; ++ resets = <&apb2_rst 17>; ++ dmas = <&dma 7>, <&dma 7>; ++ dma-names = "rx", "tx"; ++ status = "disabled"; ++ }; ++ ++ uart2: serial@01c28800 { ++ compatible = "snps,dw-apb-uart"; ++ reg = <0x01c28800 0x400>; ++ interrupts = ; ++ reg-shift = <2>; ++ reg-io-width = <4>; ++ clocks = <&bus_gates 114>; ++ resets = <&apb2_rst 18>; ++ dmas = <&dma 8>, <&dma 8>; ++ dma-names = "rx", "tx"; ++ status = "disabled"; ++ }; ++ ++ uart3: serial@01c28c00 { ++ compatible = "snps,dw-apb-uart"; ++ reg = <0x01c28c00 0x400>; ++ interrupts = ; ++ reg-shift = <2>; ++ reg-io-width = <4>; ++ clocks = <&bus_gates 115>; ++ resets = <&apb2_rst 19>; ++ dmas = <&dma 9>, <&dma 9>; ++ dma-names = "rx", "tx"; ++ status = "disabled"; ++ }; ++ ++ gic: interrupt-controller@01c81000 { ++ compatible = "arm,cortex-a7-gic", "arm,cortex-a15-gic"; ++ reg = <0x01c81000 0x1000>, ++ <0x01c82000 0x1000>, ++ <0x01c84000 0x2000>, ++ <0x01c86000 0x2000>; ++ interrupt-controller; ++ #interrupt-cells = <3>; ++ interrupts = ; ++ }; ++ ++ rtc: rtc@01f00000 { ++ compatible = "allwinner,sun6i-a31-rtc"; ++ reg = <0x01f00000 0x54>; ++ interrupts = , ++ ; ++ }; ++ }; ++}; diff --git a/target/linux/sunxi/patches-4.4/104-2-dt-sun8i-add-orangepi-plus.patch b/target/linux/sunxi/patches-4.4/104-2-dt-sun8i-add-orangepi-plus.patch new file mode 100644 index 0000000000..589a85856c --- /dev/null +++ b/target/linux/sunxi/patches-4.4/104-2-dt-sun8i-add-orangepi-plus.patch @@ -0,0 +1,116 @@ +From dfcf8196de7411a5e7fd49795938b1bc8c56859c Mon Sep 17 00:00:00 2001 +From: Jens Kuske +Date: Fri, 4 Dec 2015 22:24:43 +0100 +Subject: [PATCH] ARM: dts: sun8i: Add Orange Pi Plus support + +The Orange Pi Plus is a SBC based on the Allwinner H3 SoC +with 8GB eMMC, multiple USB ports through a USB hub chip, SATA through +a USB-SATA bridge, one uSD slot, a 10/100/1000M ethernet port, +WiFi, HDMI, headphone jack, IR receiver, a microphone, a CSI connector +and a 40-pin GPIO header. + +Signed-off-by: Jens Kuske +Signed-off-by: Maxime Ripard +--- + arch/arm/boot/dts/Makefile | 3 +- + arch/arm/boot/dts/sun8i-h3-orangepi-plus.dts | 77 ++++++++++++++++++++++++++++ + 2 files changed, 79 insertions(+), 1 deletion(-) + create mode 100644 arch/arm/boot/dts/sun8i-h3-orangepi-plus.dts + +diff --git a/arch/arm/boot/dts/Makefile b/arch/arm/boot/dts/Makefile +index e8f44c7..cc7309b 100644 +--- a/arch/arm/boot/dts/Makefile ++++ b/arch/arm/boot/dts/Makefile +@@ -661,7 +661,8 @@ dtb-$(CONFIG_MACH_SUN8I) += \ + sun8i-a33-ga10h-v1.1.dtb \ + sun8i-a33-ippo-q8h-v1.2.dtb \ + sun8i-a33-q8-tablet.dtb \ +- sun8i-a33-sinlinx-sina33.dtb ++ sun8i-a33-sinlinx-sina33.dtb \ ++ sun8i-h3-orangepi-plus.dtb + dtb-$(CONFIG_MACH_SUN9I) += \ + sun9i-a80-optimus.dtb \ + sun9i-a80-cubieboard4.dtb +diff --git a/arch/arm/boot/dts/sun8i-h3-orangepi-plus.dts b/arch/arm/boot/dts/sun8i-h3-orangepi-plus.dts +new file mode 100644 +index 0000000..e67df59 +--- /dev/null ++++ b/arch/arm/boot/dts/sun8i-h3-orangepi-plus.dts +@@ -0,0 +1,77 @@ ++/* ++ * Copyright (C) 2015 Jens Kuske ++ * ++ * 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 file 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 file 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 "sun8i-h3.dtsi" ++#include "sunxi-common-regulators.dtsi" ++ ++#include ++#include ++ ++/ { ++ model = "Xunlong Orange Pi Plus"; ++ compatible = "xunlong,orangepi-plus", "allwinner,sun8i-h3"; ++ ++ aliases { ++ serial0 = &uart0; ++ }; ++ ++ chosen { ++ stdout-path = "serial0:115200n8"; ++ }; ++}; ++ ++&mmc0 { ++ pinctrl-names = "default"; ++ pinctrl-0 = <&mmc0_pins_a>, <&mmc0_cd_pin>; ++ vmmc-supply = <®_vcc3v3>; ++ bus-width = <4>; ++ cd-gpios = <&pio 5 6 GPIO_ACTIVE_HIGH>; /* PF6 */ ++ cd-inverted; ++ status = "okay"; ++}; ++ ++&uart0 { ++ pinctrl-names = "default"; ++ pinctrl-0 = <&uart0_pins_a>; ++ status = "okay"; ++}; diff --git a/target/linux/sunxi/patches-4.4/105-phy-use_of_match_node.patch b/target/linux/sunxi/patches-4.4/105-phy-use_of_match_node.patch new file mode 100644 index 0000000000..970de980f1 --- /dev/null +++ b/target/linux/sunxi/patches-4.4/105-phy-use_of_match_node.patch @@ -0,0 +1,220 @@ +From 5c627d8e7660c170c591ef281184fd11d0493440 Mon Sep 17 00:00:00 2001 +From: Hans de Goede +Date: Fri, 11 Dec 2015 16:32:17 +0100 +Subject: [PATCH] phy-sun4i-usb: Use of_match_node to get model specific config + data + +Use of_match_node instead of calling of_device_is_compatible a ton of +times to get model specific config data. + +Signed-off-by: Hans de Goede +Signed-off-by: Kishon Vijay Abraham I +--- + drivers/phy/phy-sun4i-usb.c | 121 +++++++++++++++++++++++++++++--------------- + 1 file changed, 79 insertions(+), 42 deletions(-) + +diff --git a/drivers/phy/phy-sun4i-usb.c b/drivers/phy/phy-sun4i-usb.c +index b12964b..35b1fa3 100644 +--- a/drivers/phy/phy-sun4i-usb.c ++++ b/drivers/phy/phy-sun4i-usb.c +@@ -32,6 +32,7 @@ + #include + #include + #include ++#include + #include + #include + #include +@@ -88,12 +89,23 @@ + #define DEBOUNCE_TIME msecs_to_jiffies(50) + #define POLL_TIME msecs_to_jiffies(250) + ++enum sun4i_usb_phy_type { ++ sun4i_a10_phy, ++ sun8i_a33_phy, ++}; ++ ++struct sun4i_usb_phy_cfg { ++ int num_phys; ++ enum sun4i_usb_phy_type type; ++ u32 disc_thresh; ++ u8 phyctl_offset; ++ bool dedicated_clocks; ++}; ++ + struct sun4i_usb_phy_data { + void __iomem *base; ++ const struct sun4i_usb_phy_cfg *cfg; + struct mutex mutex; +- int num_phys; +- u32 disc_thresh; +- bool has_a33_phyctl; + struct sun4i_usb_phy { + struct phy *phy; + void __iomem *pmu; +@@ -159,17 +171,14 @@ static void sun4i_usb_phy_write(struct sun4i_usb_phy *phy, u32 addr, u32 data, + { + struct sun4i_usb_phy_data *phy_data = to_sun4i_usb_phy_data(phy); + u32 temp, usbc_bit = BIT(phy->index * 2); +- void *phyctl; ++ void *phyctl = phy_data->base + phy_data->cfg->phyctl_offset; + int i; + + mutex_lock(&phy_data->mutex); + +- if (phy_data->has_a33_phyctl) { +- phyctl = phy_data->base + REG_PHYCTL_A33; ++ if (phy_data->cfg->type == sun8i_a33_phy) { + /* A33 needs us to set phyctl to 0 explicitly */ + writel(0, phyctl); +- } else { +- phyctl = phy_data->base + REG_PHYCTL_A10; + } + + for (i = 0; i < len; i++) { +@@ -249,7 +258,8 @@ static int sun4i_usb_phy_init(struct phy *_phy) + sun4i_usb_phy_write(phy, PHY_TX_AMPLITUDE_TUNE, 0x14, 5); + + /* Disconnect threshold adjustment */ +- sun4i_usb_phy_write(phy, PHY_DISCON_TH_SEL, data->disc_thresh, 2); ++ sun4i_usb_phy_write(phy, PHY_DISCON_TH_SEL, ++ data->cfg->disc_thresh, 2); + + sun4i_usb_phy_passby(phy, 1); + +@@ -476,7 +486,7 @@ static struct phy *sun4i_usb_phy_xlate(struct device *dev, + { + struct sun4i_usb_phy_data *data = dev_get_drvdata(dev); + +- if (args->args[0] >= data->num_phys) ++ if (args->args[0] >= data->cfg->num_phys) + return ERR_PTR(-ENODEV); + + return data->phys[args->args[0]].phy; +@@ -511,7 +521,6 @@ static int sun4i_usb_phy_probe(struct platform_device *pdev) + struct device *dev = &pdev->dev; + struct device_node *np = dev->of_node; + struct phy_provider *phy_provider; +- bool dedicated_clocks; + struct resource *res; + int i, ret; + +@@ -522,29 +531,9 @@ static int sun4i_usb_phy_probe(struct platform_device *pdev) + mutex_init(&data->mutex); + INIT_DELAYED_WORK(&data->detect, sun4i_usb_phy0_id_vbus_det_scan); + dev_set_drvdata(dev, data); +- +- if (of_device_is_compatible(np, "allwinner,sun5i-a13-usb-phy") || +- of_device_is_compatible(np, "allwinner,sun8i-a23-usb-phy") || +- of_device_is_compatible(np, "allwinner,sun8i-a33-usb-phy")) +- data->num_phys = 2; +- else +- data->num_phys = 3; +- +- if (of_device_is_compatible(np, "allwinner,sun5i-a13-usb-phy") || +- of_device_is_compatible(np, "allwinner,sun7i-a20-usb-phy")) +- data->disc_thresh = 2; +- else +- data->disc_thresh = 3; +- +- if (of_device_is_compatible(np, "allwinner,sun6i-a31-usb-phy") || +- of_device_is_compatible(np, "allwinner,sun8i-a23-usb-phy") || +- of_device_is_compatible(np, "allwinner,sun8i-a33-usb-phy")) +- dedicated_clocks = true; +- else +- dedicated_clocks = false; +- +- if (of_device_is_compatible(np, "allwinner,sun8i-a33-usb-phy")) +- data->has_a33_phyctl = true; ++ data->cfg = of_device_get_match_data(dev); ++ if (!data->cfg) ++ return -EINVAL; + + res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "phy_ctrl"); + data->base = devm_ioremap_resource(dev, res); +@@ -590,7 +579,7 @@ static int sun4i_usb_phy_probe(struct platform_device *pdev) + } + } + +- for (i = 0; i < data->num_phys; i++) { ++ for (i = 0; i < data->cfg->num_phys; i++) { + struct sun4i_usb_phy *phy = data->phys + i; + char name[16]; + +@@ -602,7 +591,7 @@ static int sun4i_usb_phy_probe(struct platform_device *pdev) + phy->vbus = NULL; + } + +- if (dedicated_clocks) ++ if (data->cfg->dedicated_clocks) + snprintf(name, sizeof(name), "usb%d_phy", i); + else + strlcpy(name, "usb_phy", sizeof(name)); +@@ -689,13 +678,61 @@ static int sun4i_usb_phy_probe(struct platform_device *pdev) + return 0; + } + ++static const struct sun4i_usb_phy_cfg sun4i_a10_cfg = { ++ .num_phys = 3, ++ .type = sun4i_a10_phy, ++ .disc_thresh = 3, ++ .phyctl_offset = REG_PHYCTL_A10, ++ .dedicated_clocks = false, ++}; ++ ++static const struct sun4i_usb_phy_cfg sun5i_a13_cfg = { ++ .num_phys = 2, ++ .type = sun4i_a10_phy, ++ .disc_thresh = 2, ++ .phyctl_offset = REG_PHYCTL_A10, ++ .dedicated_clocks = false, ++}; ++ ++static const struct sun4i_usb_phy_cfg sun6i_a31_cfg = { ++ .num_phys = 3, ++ .type = sun4i_a10_phy, ++ .disc_thresh = 3, ++ .phyctl_offset = REG_PHYCTL_A10, ++ .dedicated_clocks = true, ++}; ++ ++static const struct sun4i_usb_phy_cfg sun7i_a20_cfg = { ++ .num_phys = 3, ++ .type = sun4i_a10_phy, ++ .disc_thresh = 2, ++ .phyctl_offset = REG_PHYCTL_A10, ++ .dedicated_clocks = false, ++}; ++ ++static const struct sun4i_usb_phy_cfg sun8i_a23_cfg = { ++ .num_phys = 2, ++ .type = sun4i_a10_phy, ++ .disc_thresh = 3, ++ .phyctl_offset = REG_PHYCTL_A10, ++ .dedicated_clocks = true, ++}; ++ ++static const struct sun4i_usb_phy_cfg sun8i_a33_cfg = { ++ .num_phys = 2, ++ .type = sun8i_a33_phy, ++ .disc_thresh = 3, ++ .phyctl_offset = REG_PHYCTL_A33, ++ .dedicated_clocks = true, ++}; ++ + static const struct of_device_id sun4i_usb_phy_of_match[] = { +- { .compatible = "allwinner,sun4i-a10-usb-phy" }, +- { .compatible = "allwinner,sun5i-a13-usb-phy" }, +- { .compatible = "allwinner,sun6i-a31-usb-phy" }, +- { .compatible = "allwinner,sun7i-a20-usb-phy" }, +- { .compatible = "allwinner,sun8i-a23-usb-phy" }, +- { .compatible = "allwinner,sun8i-a33-usb-phy" }, ++ { .compatible = "allwinner,sun4i-a10-usb-phy", .data = &sun4i_a10_cfg }, ++ { .compatible = "allwinner,sun5i-a13-usb-phy", .data = &sun5i_a13_cfg }, ++ { .compatible = "allwinner,sun6i-a31-usb-phy", .data = &sun6i_a31_cfg }, ++ { .compatible = "allwinner,sun7i-a20-usb-phy", .data = &sun7i_a20_cfg }, ++ { .compatible = "allwinner,sun8i-a23-usb-phy", .data = &sun8i_a23_cfg }, ++ { .compatible = "allwinner,sun8i-a33-usb-phy", .data = &sun8i_a33_cfg }, + { }, + }; + MODULE_DEVICE_TABLE(of, sun4i_usb_phy_of_match); diff --git a/target/linux/sunxi/patches-4.4/106-phy-add-h3-usbphys.patch b/target/linux/sunxi/patches-4.4/106-phy-add-h3-usbphys.patch new file mode 100644 index 0000000000..47c6332a77 --- /dev/null +++ b/target/linux/sunxi/patches-4.4/106-phy-add-h3-usbphys.patch @@ -0,0 +1,126 @@ +From 317c5224795b41a08ba8c08573d74ba95096faa5 Mon Sep 17 00:00:00 2001 +From: Reinder de Haan +Date: Fri, 11 Dec 2015 16:32:18 +0100 +Subject: [PATCH] phy-sun4i-usb: Add support for the host usb-phys found on the + H3 SoC + +Note this commit only adds support for phys 1-3, phy 0, the otg phy, is +not yet (fully) supported after this commit. + +Signed-off-by: Reinder de Haan +Signed-off-by: Hans de Goede +Acked-by: Rob Herring +Signed-off-by: Kishon Vijay Abraham I +--- + .../devicetree/bindings/phy/sun4i-usb-phy.txt | 1 + + drivers/phy/phy-sun4i-usb.c | 41 +++++++++++++++++----- + 2 files changed, 33 insertions(+), 9 deletions(-) + +diff --git a/Documentation/devicetree/bindings/phy/sun4i-usb-phy.txt b/Documentation/devicetree/bindings/phy/sun4i-usb-phy.txt +index 0cebf74..95736d7 100644 +--- a/Documentation/devicetree/bindings/phy/sun4i-usb-phy.txt ++++ b/Documentation/devicetree/bindings/phy/sun4i-usb-phy.txt +@@ -9,6 +9,7 @@ Required properties: + * allwinner,sun7i-a20-usb-phy + * allwinner,sun8i-a23-usb-phy + * allwinner,sun8i-a33-usb-phy ++ * allwinner,sun8i-h3-usb-phy + - reg : a list of offset + length pairs + - reg-names : + * "phy_ctrl" +diff --git a/drivers/phy/phy-sun4i-usb.c b/drivers/phy/phy-sun4i-usb.c +index 35b1fa3..bae54f7 100644 +--- a/drivers/phy/phy-sun4i-usb.c ++++ b/drivers/phy/phy-sun4i-usb.c +@@ -47,6 +47,9 @@ + #define REG_PHYBIST 0x08 + #define REG_PHYTUNE 0x0c + #define REG_PHYCTL_A33 0x10 ++#define REG_PHY_UNK_H3 0x20 ++ ++#define REG_PMU_UNK_H3 0x10 + + #define PHYCTL_DATA BIT(7) + +@@ -80,7 +83,7 @@ + #define PHY_DISCON_TH_SEL 0x2a + #define PHY_SQUELCH_DETECT 0x3c + +-#define MAX_PHYS 3 ++#define MAX_PHYS 4 + + /* + * Note do not raise the debounce time, we must report Vusb high within 100ms +@@ -92,6 +95,7 @@ + enum sun4i_usb_phy_type { + sun4i_a10_phy, + sun8i_a33_phy, ++ sun8i_h3_phy, + }; + + struct sun4i_usb_phy_cfg { +@@ -239,6 +243,7 @@ static int sun4i_usb_phy_init(struct phy *_phy) + struct sun4i_usb_phy *phy = phy_get_drvdata(_phy); + struct sun4i_usb_phy_data *data = to_sun4i_usb_phy_data(phy); + int ret; ++ u32 val; + + ret = clk_prepare_enable(phy->clk); + if (ret) +@@ -250,16 +255,26 @@ static int sun4i_usb_phy_init(struct phy *_phy) + return ret; + } + +- /* Enable USB 45 Ohm resistor calibration */ +- if (phy->index == 0) +- sun4i_usb_phy_write(phy, PHY_RES45_CAL_EN, 0x01, 1); ++ if (data->cfg->type == sun8i_h3_phy) { ++ if (phy->index == 0) { ++ val = readl(data->base + REG_PHY_UNK_H3); ++ writel(val & ~1, data->base + REG_PHY_UNK_H3); ++ } ++ ++ val = readl(phy->pmu + REG_PMU_UNK_H3); ++ writel(val & ~2, phy->pmu + REG_PMU_UNK_H3); ++ } else { ++ /* Enable USB 45 Ohm resistor calibration */ ++ if (phy->index == 0) ++ sun4i_usb_phy_write(phy, PHY_RES45_CAL_EN, 0x01, 1); + +- /* Adjust PHY's magnitude and rate */ +- sun4i_usb_phy_write(phy, PHY_TX_AMPLITUDE_TUNE, 0x14, 5); ++ /* Adjust PHY's magnitude and rate */ ++ sun4i_usb_phy_write(phy, PHY_TX_AMPLITUDE_TUNE, 0x14, 5); + +- /* Disconnect threshold adjustment */ +- sun4i_usb_phy_write(phy, PHY_DISCON_TH_SEL, +- data->cfg->disc_thresh, 2); ++ /* Disconnect threshold adjustment */ ++ sun4i_usb_phy_write(phy, PHY_DISCON_TH_SEL, ++ data->cfg->disc_thresh, 2); ++ } + + sun4i_usb_phy_passby(phy, 1); + +@@ -726,6 +741,13 @@ static const struct sun4i_usb_phy_cfg sun8i_a33_cfg = { + .dedicated_clocks = true, + }; + ++static const struct sun4i_usb_phy_cfg sun8i_h3_cfg = { ++ .num_phys = 4, ++ .type = sun8i_h3_phy, ++ .disc_thresh = 3, ++ .dedicated_clocks = true, ++}; ++ + static const struct of_device_id sun4i_usb_phy_of_match[] = { + { .compatible = "allwinner,sun4i-a10-usb-phy", .data = &sun4i_a10_cfg }, + { .compatible = "allwinner,sun5i-a13-usb-phy", .data = &sun5i_a13_cfg }, +@@ -733,6 +755,7 @@ static const struct of_device_id sun4i_usb_phy_of_match[] = { + { .compatible = "allwinner,sun7i-a20-usb-phy", .data = &sun7i_a20_cfg }, + { .compatible = "allwinner,sun8i-a23-usb-phy", .data = &sun8i_a23_cfg }, + { .compatible = "allwinner,sun8i-a33-usb-phy", .data = &sun8i_a33_cfg }, ++ { .compatible = "allwinner,sun8i-h3-usb-phy", .data = &sun8i_h3_cfg }, + { }, + }; + MODULE_DEVICE_TABLE(of, sun4i_usb_phy_of_match); diff --git a/target/linux/sunxi/patches-4.4/107-clk-sunxi-add-h3-usbphy-clocks.patch b/target/linux/sunxi/patches-4.4/107-clk-sunxi-add-h3-usbphy-clocks.patch new file mode 100644 index 0000000000..7cd0a62557 --- /dev/null +++ b/target/linux/sunxi/patches-4.4/107-clk-sunxi-add-h3-usbphy-clocks.patch @@ -0,0 +1,51 @@ +From 7bec0200ac214b5cba44e2c2c4385815be4b9f00 Mon Sep 17 00:00:00 2001 +From: Reinder de Haan +Date: Sun, 15 Nov 2015 20:46:13 +0100 +Subject: [PATCH] clk: sunxi: Add support for the H3 usb phy clocks + +The H3 has a usb-phy clk register which is similar to that of earlier +SoCs, but with support for a larger number of phys. So we can simply add +a new set of clk-data and a new compatible and be done with it. + +Acked-by: Chen-Yu Tsai +Acked-by: Rob Herring +Signed-off-by: Reinder de Haan +Signed-off-by: Hans de Goede +Signed-off-by: Maxime Ripard +--- + Documentation/devicetree/bindings/clock/sunxi.txt | 1 + + drivers/clk/sunxi/clk-usb.c | 12 ++++++++++++ + 2 files changed, 13 insertions(+) + +diff --git a/Documentation/devicetree/bindings/clock/sunxi.txt b/Documentation/devicetree/bindings/clock/sunxi.txt +index 8a47b77..a94bb56 100644 +--- a/Documentation/devicetree/bindings/clock/sunxi.txt ++++ b/Documentation/devicetree/bindings/clock/sunxi.txt +@@ -68,6 +68,7 @@ Required properties: + "allwinner,sun5i-a13-usb-clk" - for usb gates + resets on A13 + "allwinner,sun6i-a31-usb-clk" - for usb gates + resets on A31 + "allwinner,sun8i-a23-usb-clk" - for usb gates + resets on A23 ++ "allwinner,sun8i-h3-usb-clk" - for usb gates + resets on H3 + "allwinner,sun9i-a80-usb-mod-clk" - for usb gates + resets on A80 + "allwinner,sun9i-a80-usb-phy-clk" - for usb phy gates + resets on A80 + +diff --git a/drivers/clk/sunxi/clk-usb.c b/drivers/clk/sunxi/clk-usb.c +index 1a72cd6..67b8e38 100644 +--- a/drivers/clk/sunxi/clk-usb.c ++++ b/drivers/clk/sunxi/clk-usb.c +@@ -243,3 +243,15 @@ static void __init sun9i_a80_usb_phy_setup(struct device_node *node) + sunxi_usb_clk_setup(node, &sun9i_a80_usb_phy_data, &a80_usb_phy_lock); + } + CLK_OF_DECLARE(sun9i_a80_usb_phy, "allwinner,sun9i-a80-usb-phy-clk", sun9i_a80_usb_phy_setup); ++ ++static const struct usb_clk_data sun8i_h3_usb_clk_data __initconst = { ++ .clk_mask = BIT(19) | BIT(18) | BIT(17) | BIT(16) | ++ BIT(11) | BIT(10) | BIT(9) | BIT(8), ++ .reset_mask = BIT(3) | BIT(2) | BIT(1) | BIT(0), ++}; ++ ++static void __init sun8i_h3_usb_setup(struct device_node *node) ++{ ++ sunxi_usb_clk_setup(node, &sun8i_h3_usb_clk_data, &sun4i_a10_usb_lock); ++} ++CLK_OF_DECLARE(sun8i_h3_usb, "allwinner,sun8i-h3-usb-clk", sun8i_h3_usb_setup); diff --git a/target/linux/sunxi/patches-4.4/110-clk-sunxi-add-ve-for-sun457i.patch b/target/linux/sunxi/patches-4.4/110-clk-sunxi-add-ve-for-sun457i.patch new file mode 100644 index 0000000000..12c9e5e2af --- /dev/null +++ b/target/linux/sunxi/patches-4.4/110-clk-sunxi-add-ve-for-sun457i.patch @@ -0,0 +1,233 @@ +From 3cdd9f5c4953465abb87ec757159cc0576ae6b0a Mon Sep 17 00:00:00 2001 +From: Chen-Yu Tsai +Date: Sat, 5 Dec 2015 21:16:43 +0800 +Subject: [PATCH] clk: sunxi: Add VE (Video Engine) module clock driver for + sun[457]i + +The video engine has its own special module clock, consisting of a clock +gate, configurable dividers, and a reset control. + +On later (sun[68]i) families, the reset control is moved out of this +piece of hardware and grouped with reset controls of other peripherals. + +Signed-off-by: Chen-Yu Tsai +Tested-by: Jens Kuske +Signed-off-by: Maxime Ripard +--- + Documentation/devicetree/bindings/clock/sunxi.txt | 4 + + drivers/clk/sunxi/Makefile | 1 + + drivers/clk/sunxi/clk-a10-ve.c | 171 ++++++++++++++++++++++ + 3 files changed, 176 insertions(+) + create mode 100644 drivers/clk/sunxi/clk-a10-ve.c + +diff --git a/Documentation/devicetree/bindings/clock/sunxi.txt b/Documentation/devicetree/bindings/clock/sunxi.txt +index 014eab8..e59f57b 100644 +--- a/Documentation/devicetree/bindings/clock/sunxi.txt ++++ b/Documentation/devicetree/bindings/clock/sunxi.txt +@@ -76,6 +76,7 @@ Required properties: + "allwinner,sun8i-h3-usb-clk" - for usb gates + resets on H3 + "allwinner,sun9i-a80-usb-mod-clk" - for usb gates + resets on A80 + "allwinner,sun9i-a80-usb-phy-clk" - for usb phy gates + resets on A80 ++ "allwinner,sun4i-a10-ve-clk" - for the Video Engine clock + + Required properties for all clocks: + - reg : shall be the control register address for the clock. +@@ -95,6 +96,9 @@ Required properties for all clocks: + And "allwinner,*-usb-clk" clocks also require: + - reset-cells : shall be set to 1 + ++The "allwinner,sun4i-a10-ve-clk" clock also requires: ++- reset-cells : shall be set to 0 ++ + The "allwinner,sun9i-a80-mmc-config-clk" clock also requires: + - #reset-cells : shall be set to 1 + - resets : shall be the reset control phandle for the mmc block. +diff --git a/drivers/clk/sunxi/Makefile b/drivers/clk/sunxi/Makefile +index abf4916..1a909f9 100644 +--- a/drivers/clk/sunxi/Makefile ++++ b/drivers/clk/sunxi/Makefile +@@ -7,6 +7,7 @@ obj-y += clk-a10-codec.o + obj-y += clk-a10-hosc.o + obj-y += clk-a10-mod1.o + obj-y += clk-a10-pll2.o ++obj-y += clk-a10-ve.o + obj-y += clk-a20-gmac.o + obj-y += clk-mod0.o + obj-y += clk-simple-gates.o +diff --git a/drivers/clk/sunxi/clk-a10-ve.c b/drivers/clk/sunxi/clk-a10-ve.c +new file mode 100644 +index 0000000..044c171 +--- /dev/null ++++ b/drivers/clk/sunxi/clk-a10-ve.c +@@ -0,0 +1,171 @@ ++/* ++ * Copyright 2015 Chen-Yu Tsai ++ * ++ * Chen-Yu Tsai ++ * ++ * 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. ++ */ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++ ++static DEFINE_SPINLOCK(ve_lock); ++ ++#define SUN4I_VE_ENABLE 31 ++#define SUN4I_VE_DIVIDER_SHIFT 16 ++#define SUN4I_VE_DIVIDER_WIDTH 3 ++#define SUN4I_VE_RESET 0 ++ ++/** ++ * sunxi_ve_reset... - reset bit in ve clk registers handling ++ */ ++ ++struct ve_reset_data { ++ void __iomem *reg; ++ spinlock_t *lock; ++ struct reset_controller_dev rcdev; ++}; ++ ++static int sunxi_ve_reset_assert(struct reset_controller_dev *rcdev, ++ unsigned long id) ++{ ++ struct ve_reset_data *data = container_of(rcdev, ++ struct ve_reset_data, ++ rcdev); ++ unsigned long flags; ++ u32 reg; ++ ++ spin_lock_irqsave(data->lock, flags); ++ ++ reg = readl(data->reg); ++ writel(reg & ~BIT(SUN4I_VE_RESET), data->reg); ++ ++ spin_unlock_irqrestore(data->lock, flags); ++ ++ return 0; ++} ++ ++static int sunxi_ve_reset_deassert(struct reset_controller_dev *rcdev, ++ unsigned long id) ++{ ++ struct ve_reset_data *data = container_of(rcdev, ++ struct ve_reset_data, ++ rcdev); ++ unsigned long flags; ++ u32 reg; ++ ++ spin_lock_irqsave(data->lock, flags); ++ ++ reg = readl(data->reg); ++ writel(reg | BIT(SUN4I_VE_RESET), data->reg); ++ ++ spin_unlock_irqrestore(data->lock, flags); ++ ++ return 0; ++} ++ ++static int sunxi_ve_of_xlate(struct reset_controller_dev *rcdev, ++ const struct of_phandle_args *reset_spec) ++{ ++ if (WARN_ON(reset_spec->args_count != 0)) ++ return -EINVAL; ++ ++ return 0; ++} ++ ++static struct reset_control_ops sunxi_ve_reset_ops = { ++ .assert = sunxi_ve_reset_assert, ++ .deassert = sunxi_ve_reset_deassert, ++}; ++ ++static void __init sun4i_ve_clk_setup(struct device_node *node) ++{ ++ struct clk *clk; ++ struct clk_divider *div; ++ struct clk_gate *gate; ++ struct ve_reset_data *reset_data; ++ const char *parent; ++ const char *clk_name = node->name; ++ void __iomem *reg; ++ int err; ++ ++ reg = of_io_request_and_map(node, 0, of_node_full_name(node)); ++ if (IS_ERR(reg)) ++ return; ++ ++ div = kzalloc(sizeof(*div), GFP_KERNEL); ++ if (!div) ++ goto err_unmap; ++ ++ gate = kzalloc(sizeof(*gate), GFP_KERNEL); ++ if (!gate) ++ goto err_free_div; ++ ++ of_property_read_string(node, "clock-output-names", &clk_name); ++ parent = of_clk_get_parent_name(node, 0); ++ ++ gate->reg = reg; ++ gate->bit_idx = SUN4I_VE_ENABLE; ++ gate->lock = &ve_lock; ++ ++ div->reg = reg; ++ div->shift = SUN4I_VE_DIVIDER_SHIFT; ++ div->width = SUN4I_VE_DIVIDER_WIDTH; ++ div->lock = &ve_lock; ++ ++ clk = clk_register_composite(NULL, clk_name, &parent, 1, ++ NULL, NULL, ++ &div->hw, &clk_divider_ops, ++ &gate->hw, &clk_gate_ops, ++ CLK_SET_RATE_PARENT); ++ if (IS_ERR(clk)) ++ goto err_free_gate; ++ ++ err = of_clk_add_provider(node, of_clk_src_simple_get, clk); ++ if (err) ++ goto err_unregister_clk; ++ ++ reset_data = kzalloc(sizeof(*reset_data), GFP_KERNEL); ++ if (!reset_data) ++ goto err_del_provider; ++ ++ reset_data->reg = reg; ++ reset_data->lock = &ve_lock; ++ reset_data->rcdev.nr_resets = 1; ++ reset_data->rcdev.ops = &sunxi_ve_reset_ops; ++ reset_data->rcdev.of_node = node; ++ reset_data->rcdev.of_xlate = sunxi_ve_of_xlate; ++ reset_data->rcdev.of_reset_n_cells = 0; ++ err = reset_controller_register(&reset_data->rcdev); ++ if (err) ++ goto err_free_reset; ++ ++ return; ++ ++err_free_reset: ++ kfree(reset_data); ++err_del_provider: ++ of_clk_del_provider(node); ++err_unregister_clk: ++ clk_unregister(clk); ++err_free_gate: ++ kfree(gate); ++err_free_div: ++ kfree(div); ++err_unmap: ++ iounmap(reg); ++} ++CLK_OF_DECLARE(sun4i_ve, "allwinner,sun4i-a10-ve-clk", ++ sun4i_ve_clk_setup); diff --git a/target/linux/sunxi/patches-4.4/111-1-dt-sun4i-add-ve-clock-module.patch b/target/linux/sunxi/patches-4.4/111-1-dt-sun4i-add-ve-clock-module.patch new file mode 100644 index 0000000000..f24711ea41 --- /dev/null +++ b/target/linux/sunxi/patches-4.4/111-1-dt-sun4i-add-ve-clock-module.patch @@ -0,0 +1,34 @@ +From 1ccc4939220cf815c309feddcf82dba260499194 Mon Sep 17 00:00:00 2001 +From: Chen-Yu Tsai +Date: Sat, 5 Dec 2015 21:16:45 +0800 +Subject: [PATCH] ARM: dts: sun4i: Add VE (Video Engine) module clock node + +The video engine has its own module clock, which also includes a +reset control for it. + +Signed-off-by: Chen-Yu Tsai +Signed-off-by: Maxime Ripard +--- + arch/arm/boot/dts/sun4i-a10.dtsi | 9 +++++++++ + 1 file changed, 9 insertions(+) + +diff --git a/arch/arm/boot/dts/sun4i-a10.dtsi b/arch/arm/boot/dts/sun4i-a10.dtsi +index 849d024..2c8f5e6 100644 +--- a/arch/arm/boot/dts/sun4i-a10.dtsi ++++ b/arch/arm/boot/dts/sun4i-a10.dtsi +@@ -520,6 +520,15 @@ + "dram_de_mp", "dram_ace"; + }; + ++ ve_clk: clk@01c2013c { ++ #clock-cells = <0>; ++ #reset-cells = <0>; ++ compatible = "allwinner,sun4i-a10-ve-clk"; ++ reg = <0x01c2013c 0x4>; ++ clocks = <&pll4>; ++ clock-output-names = "ve"; ++ }; ++ + codec_clk: clk@01c20140 { + #clock-cells = <0>; + compatible = "allwinner,sun4i-a10-codec-clk"; diff --git a/target/linux/sunxi/patches-4.4/111-2-dt-sun7i-add-ve-clock-module.patch b/target/linux/sunxi/patches-4.4/111-2-dt-sun7i-add-ve-clock-module.patch new file mode 100644 index 0000000000..bac58d088e --- /dev/null +++ b/target/linux/sunxi/patches-4.4/111-2-dt-sun7i-add-ve-clock-module.patch @@ -0,0 +1,34 @@ +From f0571ab140723f9a898d4a404118580534dcc468 Mon Sep 17 00:00:00 2001 +From: Chen-Yu Tsai +Date: Sat, 5 Dec 2015 21:16:47 +0800 +Subject: [PATCH] ARM: dts: sun7i: Add VE (Video Engine) module clock node + +The video engine has its own module clock, which also includes a +reset control for it. + +Signed-off-by: Chen-Yu Tsai +Signed-off-by: Maxime Ripard +--- + arch/arm/boot/dts/sun7i-a20.dtsi | 9 +++++++++ + 1 file changed, 9 insertions(+) + +diff --git a/arch/arm/boot/dts/sun7i-a20.dtsi b/arch/arm/boot/dts/sun7i-a20.dtsi +index 21169c0..0940a78 100644 +--- a/arch/arm/boot/dts/sun7i-a20.dtsi ++++ b/arch/arm/boot/dts/sun7i-a20.dtsi +@@ -527,6 +527,15 @@ + "dram_de_mp", "dram_ace"; + }; + ++ ve_clk: clk@01c2013c { ++ #clock-cells = <0>; ++ #reset-cells = <0>; ++ compatible = "allwinner,sun4i-a10-ve-clk"; ++ reg = <0x01c2013c 0x4>; ++ clocks = <&pll4>; ++ clock-output-names = "ve"; ++ }; ++ + codec_clk: clk@01c20140 { + #clock-cells = <0>; + compatible = "allwinner,sun4i-a10-codec-clk"; diff --git a/target/linux/sunxi/patches-4.4/115-musb-ignore-vbus-errors.patch b/target/linux/sunxi/patches-4.4/115-musb-ignore-vbus-errors.patch new file mode 100644 index 0000000000..3814e347fd --- /dev/null +++ b/target/linux/sunxi/patches-4.4/115-musb-ignore-vbus-errors.patch @@ -0,0 +1,28 @@ +From fce20ac5d8c98f1a8ea5298051d9fa669e455f04 Mon Sep 17 00:00:00 2001 +From: Hans de Goede +Date: Tue, 4 Aug 2015 23:22:45 +0200 +Subject: [PATCH] musb: sunxi: Ignore VBus errors in host-only mode + +For some unclear reason sometimes we get VBus errors in host-only mode, +even though we do not have any vbus-detection then. Ignore these. + +Signed-off-by: Hans de Goede +--- + drivers/usb/musb/sunxi.c | 4 ++++ + 1 file changed, 4 insertions(+) + +diff --git a/drivers/usb/musb/sunxi.c b/drivers/usb/musb/sunxi.c +index d9b0dc4..4b472b8 100644 +--- a/drivers/usb/musb/sunxi.c ++++ b/drivers/usb/musb/sunxi.c +@@ -194,6 +194,10 @@ static irqreturn_t sunxi_musb_interrupt(int irq, void *__hci) + musb_writeb(musb->mregs, MUSB_FADDR, 0); + } + ++ /* Ignore Vbus errors when in host only mode */ ++ if (musb->port_mode == MUSB_PORT_MODE_HOST) ++ musb->int_usb &= ~MUSB_INTR_VBUSERROR; ++ + musb->int_tx = readw(musb->mregs + SUNXI_MUSB_INTRTX); + if (musb->int_tx) + writew(musb->int_tx, musb->mregs + SUNXI_MUSB_INTRTX); diff --git a/target/linux/sunxi/patches-4.4/116-crypto-add-missing-statesize.patch b/target/linux/sunxi/patches-4.4/116-crypto-add-missing-statesize.patch new file mode 100644 index 0000000000..3dfa60c77e --- /dev/null +++ b/target/linux/sunxi/patches-4.4/116-crypto-add-missing-statesize.patch @@ -0,0 +1,39 @@ +From 4f9ea86604e3ba64edd2817795798168fbb3c1a6 Mon Sep 17 00:00:00 2001 +From: LABBE Corentin +Date: Mon, 16 Nov 2015 09:35:54 +0100 +Subject: [PATCH] crypto: sun4i-ss - add missing statesize + +sun4i-ss implementaton of md5/sha1 is via ahash algorithms. +Commit 8996eafdcbad ("crypto: ahash - ensure statesize is non-zero") +made impossible to load them without giving statesize. This patch +specifiy statesize for sha1 and md5. + +Fixes: 6298e948215f ("crypto: sunxi-ss - Add Allwinner Security System crypto accelerator") +Cc: # v4.3+ +Tested-by: Chen-Yu Tsai +Signed-off-by: LABBE Corentin +Signed-off-by: Herbert Xu +--- + drivers/crypto/sunxi-ss/sun4i-ss-core.c | 2 ++ + 1 file changed, 2 insertions(+) + +diff --git a/drivers/crypto/sunxi-ss/sun4i-ss-core.c b/drivers/crypto/sunxi-ss/sun4i-ss-core.c +index eab6fe2..107cd2a 100644 +--- a/drivers/crypto/sunxi-ss/sun4i-ss-core.c ++++ b/drivers/crypto/sunxi-ss/sun4i-ss-core.c +@@ -39,6 +39,7 @@ static struct sun4i_ss_alg_template ss_algs[] = { + .import = sun4i_hash_import_md5, + .halg = { + .digestsize = MD5_DIGEST_SIZE, ++ .statesize = sizeof(struct md5_state), + .base = { + .cra_name = "md5", + .cra_driver_name = "md5-sun4i-ss", +@@ -66,6 +67,7 @@ static struct sun4i_ss_alg_template ss_algs[] = { + .import = sun4i_hash_import_sha1, + .halg = { + .digestsize = SHA1_DIGEST_SIZE, ++ .statesize = sizeof(struct sha1_state), + .base = { + .cra_name = "sha1", + .cra_driver_name = "sha1-sun4i-ss", diff --git a/target/linux/sunxi/patches-4.4/130-pinctrl-sunxi-add-h3-pio.patch b/target/linux/sunxi/patches-4.4/130-pinctrl-sunxi-add-h3-pio.patch new file mode 100644 index 0000000000..37921fa984 --- /dev/null +++ b/target/linux/sunxi/patches-4.4/130-pinctrl-sunxi-add-h3-pio.patch @@ -0,0 +1,577 @@ +From 03b83828e452418c18ba506e3e02b5deadbb53fa Mon Sep 17 00:00:00 2001 +From: Jens Kuske +Date: Tue, 27 Oct 2015 17:50:23 +0100 +Subject: [PATCH] pinctrl: sunxi: Add H3 PIO controller support + +The H3 uses the same pin controller as previous SoC's from Allwinner. +Add support for the pins controlled by the main PIO controller. + +Signed-off-by: Jens Kuske +Acked-by: Maxime Ripard +--- + .../bindings/pinctrl/allwinner,sunxi-pinctrl.txt | 1 + + drivers/pinctrl/sunxi/Kconfig | 4 + + drivers/pinctrl/sunxi/Makefile | 1 + + drivers/pinctrl/sunxi/pinctrl-sun8i-h3.c | 516 +++++++++++++++++++++ + 4 files changed, 522 insertions(+) + create mode 100644 drivers/pinctrl/sunxi/pinctrl-sun8i-h3.c + +diff --git a/Documentation/devicetree/bindings/pinctrl/allwinner,sunxi-pinctrl.txt b/Documentation/devicetree/bindings/pinctrl/allwinner,sunxi-pinctrl.txt +index b321b26..e6ba602 100644 +--- a/Documentation/devicetree/bindings/pinctrl/allwinner,sunxi-pinctrl.txt ++++ b/Documentation/devicetree/bindings/pinctrl/allwinner,sunxi-pinctrl.txt +@@ -18,6 +18,7 @@ Required properties: + "allwinner,sun8i-a23-r-pinctrl" + "allwinner,sun8i-a33-pinctrl" + "allwinner,sun8i-a83t-pinctrl" ++ "allwinner,sun8i-h3-pinctrl" + + - reg: Should contain the register physical address and length for the + pin controller. +diff --git a/drivers/pinctrl/sunxi/Kconfig b/drivers/pinctrl/sunxi/Kconfig +index e68fd95..89ab7f5 100644 +--- a/drivers/pinctrl/sunxi/Kconfig ++++ b/drivers/pinctrl/sunxi/Kconfig +@@ -51,6 +51,10 @@ config PINCTRL_SUN8I_A23_R + depends on RESET_CONTROLLER + select PINCTRL_SUNXI_COMMON + ++config PINCTRL_SUN8I_H3 ++ def_bool MACH_SUN8I ++ select PINCTRL_SUNXI_COMMON ++ + config PINCTRL_SUN9I_A80 + def_bool MACH_SUN9I + select PINCTRL_SUNXI_COMMON +diff --git a/drivers/pinctrl/sunxi/Makefile b/drivers/pinctrl/sunxi/Makefile +index e080290..6bd818e 100644 +--- a/drivers/pinctrl/sunxi/Makefile ++++ b/drivers/pinctrl/sunxi/Makefile +@@ -13,4 +13,5 @@ obj-$(CONFIG_PINCTRL_SUN8I_A23) += pinctrl-sun8i-a23.o + obj-$(CONFIG_PINCTRL_SUN8I_A23_R) += pinctrl-sun8i-a23-r.o + obj-$(CONFIG_PINCTRL_SUN8I_A33) += pinctrl-sun8i-a33.o + obj-$(CONFIG_PINCTRL_SUN8I_A83T) += pinctrl-sun8i-a83t.o ++obj-$(CONFIG_PINCTRL_SUN8I_H3) += pinctrl-sun8i-h3.o + obj-$(CONFIG_PINCTRL_SUN9I_A80) += pinctrl-sun9i-a80.o +diff --git a/drivers/pinctrl/sunxi/pinctrl-sun8i-h3.c b/drivers/pinctrl/sunxi/pinctrl-sun8i-h3.c +new file mode 100644 +index 0000000..98d465d +--- /dev/null ++++ b/drivers/pinctrl/sunxi/pinctrl-sun8i-h3.c +@@ -0,0 +1,516 @@ ++/* ++ * Allwinner H3 SoCs pinctrl driver. ++ * ++ * Copyright (C) 2015 Jens Kuske ++ * ++ * Based on pinctrl-sun8i-a23.c, which is: ++ * Copyright (C) 2014 Chen-Yu Tsai ++ * Copyright (C) 2014 Maxime Ripard ++ * ++ * This file is licensed under the terms of the GNU General Public ++ * License version 2. This program is licensed "as is" without any ++ * warranty of any kind, whether express or implied. ++ */ ++ ++#include ++#include ++#include ++#include ++#include ++ ++#include "pinctrl-sunxi.h" ++ ++static const struct sunxi_desc_pin sun8i_h3_pins[] = { ++ SUNXI_PIN(SUNXI_PINCTRL_PIN(A, 0), ++ SUNXI_FUNCTION(0x0, "gpio_in"), ++ SUNXI_FUNCTION(0x1, "gpio_out"), ++ SUNXI_FUNCTION(0x2, "uart2"), /* TX */ ++ SUNXI_FUNCTION(0x3, "jtag"), /* MS */ ++ SUNXI_FUNCTION_IRQ_BANK(0x6, 0, 0)), /* PA_EINT0 */ ++ SUNXI_PIN(SUNXI_PINCTRL_PIN(A, 1), ++ SUNXI_FUNCTION(0x0, "gpio_in"), ++ SUNXI_FUNCTION(0x1, "gpio_out"), ++ SUNXI_FUNCTION(0x2, "uart2"), /* RX */ ++ SUNXI_FUNCTION(0x3, "jtag"), /* CK */ ++ SUNXI_FUNCTION_IRQ_BANK(0x6, 0, 1)), /* PA_EINT1 */ ++ SUNXI_PIN(SUNXI_PINCTRL_PIN(A, 2), ++ SUNXI_FUNCTION(0x0, "gpio_in"), ++ SUNXI_FUNCTION(0x1, "gpio_out"), ++ SUNXI_FUNCTION(0x2, "uart2"), /* RTS */ ++ SUNXI_FUNCTION(0x3, "jtag"), /* DO */ ++ SUNXI_FUNCTION_IRQ_BANK(0x6, 0, 2)), /* PA_EINT2 */ ++ SUNXI_PIN(SUNXI_PINCTRL_PIN(A, 3), ++ SUNXI_FUNCTION(0x0, "gpio_in"), ++ SUNXI_FUNCTION(0x1, "gpio_out"), ++ SUNXI_FUNCTION(0x2, "uart2"), /* CTS */ ++ SUNXI_FUNCTION(0x3, "jtag"), /* DI */ ++ SUNXI_FUNCTION_IRQ_BANK(0x6, 0, 3)), /* PA_EINT3 */ ++ SUNXI_PIN(SUNXI_PINCTRL_PIN(A, 4), ++ SUNXI_FUNCTION(0x0, "gpio_in"), ++ SUNXI_FUNCTION(0x1, "gpio_out"), ++ SUNXI_FUNCTION(0x2, "uart0"), /* TX */ ++ SUNXI_FUNCTION_IRQ_BANK(0x6, 0, 4)), /* PA_EINT4 */ ++ SUNXI_PIN(SUNXI_PINCTRL_PIN(A, 5), ++ SUNXI_FUNCTION(0x0, "gpio_in"), ++ SUNXI_FUNCTION(0x1, "gpio_out"), ++ SUNXI_FUNCTION(0x2, "uart0"), /* RX */ ++ SUNXI_FUNCTION(0x3, "pwm0"), ++ SUNXI_FUNCTION_IRQ_BANK(0x6, 0, 5)), /* PA_EINT5 */ ++ SUNXI_PIN(SUNXI_PINCTRL_PIN(A, 6), ++ SUNXI_FUNCTION(0x0, "gpio_in"), ++ SUNXI_FUNCTION(0x1, "gpio_out"), ++ SUNXI_FUNCTION(0x2, "sim"), /* PWREN */ ++ SUNXI_FUNCTION(0x3, "pwm1"), ++ SUNXI_FUNCTION_IRQ_BANK(0x6, 0, 6)), /* PA_EINT6 */ ++ SUNXI_PIN(SUNXI_PINCTRL_PIN(A, 7), ++ SUNXI_FUNCTION(0x0, "gpio_in"), ++ SUNXI_FUNCTION(0x1, "gpio_out"), ++ SUNXI_FUNCTION(0x2, "sim"), /* CLK */ ++ SUNXI_FUNCTION_IRQ_BANK(0x6, 0, 7)), /* PA_EINT7 */ ++ SUNXI_PIN(SUNXI_PINCTRL_PIN(A, 8), ++ SUNXI_FUNCTION(0x0, "gpio_in"), ++ SUNXI_FUNCTION(0x1, "gpio_out"), ++ SUNXI_FUNCTION(0x2, "sim"), /* DATA */ ++ SUNXI_FUNCTION_IRQ_BANK(0x6, 0, 8)), /* PA_EINT8 */ ++ SUNXI_PIN(SUNXI_PINCTRL_PIN(A, 9), ++ SUNXI_FUNCTION(0x0, "gpio_in"), ++ SUNXI_FUNCTION(0x1, "gpio_out"), ++ SUNXI_FUNCTION(0x2, "sim"), /* RST */ ++ SUNXI_FUNCTION_IRQ_BANK(0x6, 0, 9)), /* PA_EINT9 */ ++ SUNXI_PIN(SUNXI_PINCTRL_PIN(A, 10), ++ SUNXI_FUNCTION(0x0, "gpio_in"), ++ SUNXI_FUNCTION(0x1, "gpio_out"), ++ SUNXI_FUNCTION(0x2, "sim"), /* DET */ ++ SUNXI_FUNCTION_IRQ_BANK(0x6, 0, 10)), /* PA_EINT10 */ ++ SUNXI_PIN(SUNXI_PINCTRL_PIN(A, 11), ++ SUNXI_FUNCTION(0x0, "gpio_in"), ++ SUNXI_FUNCTION(0x1, "gpio_out"), ++ SUNXI_FUNCTION(0x2, "i2c0"), /* SCK */ ++ SUNXI_FUNCTION(0x3, "di"), /* TX */ ++ SUNXI_FUNCTION_IRQ_BANK(0x6, 0, 11)), /* PA_EINT11 */ ++ SUNXI_PIN(SUNXI_PINCTRL_PIN(A, 12), ++ SUNXI_FUNCTION(0x0, "gpio_in"), ++ SUNXI_FUNCTION(0x1, "gpio_out"), ++ SUNXI_FUNCTION(0x2, "i2c0"), /* SDA */ ++ SUNXI_FUNCTION(0x3, "di"), /* RX */ ++ SUNXI_FUNCTION_IRQ_BANK(0x6, 0, 12)), /* PA_EINT12 */ ++ SUNXI_PIN(SUNXI_PINCTRL_PIN(A, 13), ++ SUNXI_FUNCTION(0x0, "gpio_in"), ++ SUNXI_FUNCTION(0x1, "gpio_out"), ++ SUNXI_FUNCTION(0x2, "spi1"), /* CS */ ++ SUNXI_FUNCTION(0x3, "uart3"), /* TX */ ++ SUNXI_FUNCTION_IRQ_BANK(0x6, 0, 13)), /* PA_EINT13 */ ++ SUNXI_PIN(SUNXI_PINCTRL_PIN(A, 14), ++ SUNXI_FUNCTION(0x0, "gpio_in"), ++ SUNXI_FUNCTION(0x1, "gpio_out"), ++ SUNXI_FUNCTION(0x2, "spi1"), /* CLK */ ++ SUNXI_FUNCTION(0x3, "uart3"), /* RX */ ++ SUNXI_FUNCTION_IRQ_BANK(0x6, 0, 14)), /* PA_EINT14 */ ++ SUNXI_PIN(SUNXI_PINCTRL_PIN(A, 15), ++ SUNXI_FUNCTION(0x0, "gpio_in"), ++ SUNXI_FUNCTION(0x1, "gpio_out"), ++ SUNXI_FUNCTION(0x2, "spi1"), /* MOSI */ ++ SUNXI_FUNCTION(0x3, "uart3"), /* RTS */ ++ SUNXI_FUNCTION_IRQ_BANK(0x6, 0, 15)), /* PA_EINT15 */ ++ SUNXI_PIN(SUNXI_PINCTRL_PIN(A, 16), ++ SUNXI_FUNCTION(0x0, "gpio_in"), ++ SUNXI_FUNCTION(0x1, "gpio_out"), ++ SUNXI_FUNCTION(0x2, "spi1"), /* MISO */ ++ SUNXI_FUNCTION(0x3, "uart3"), /* CTS */ ++ SUNXI_FUNCTION_IRQ_BANK(0x6, 0, 16)), /* PA_EINT16 */ ++ SUNXI_PIN(SUNXI_PINCTRL_PIN(A, 17), ++ SUNXI_FUNCTION(0x0, "gpio_in"), ++ SUNXI_FUNCTION(0x1, "gpio_out"), ++ SUNXI_FUNCTION(0x2, "spdif"), /* OUT */ ++ SUNXI_FUNCTION_IRQ_BANK(0x6, 0, 17)), /* PA_EINT17 */ ++ SUNXI_PIN(SUNXI_PINCTRL_PIN(A, 18), ++ SUNXI_FUNCTION(0x0, "gpio_in"), ++ SUNXI_FUNCTION(0x1, "gpio_out"), ++ SUNXI_FUNCTION(0x2, "i2s0"), /* SYNC */ ++ SUNXI_FUNCTION(0x3, "i2c1"), /* SCK */ ++ SUNXI_FUNCTION_IRQ_BANK(0x6, 0, 18)), /* PA_EINT18 */ ++ SUNXI_PIN(SUNXI_PINCTRL_PIN(A, 19), ++ SUNXI_FUNCTION(0x0, "gpio_in"), ++ SUNXI_FUNCTION(0x1, "gpio_out"), ++ SUNXI_FUNCTION(0x2, "i2s0"), /* CLK */ ++ SUNXI_FUNCTION(0x3, "i2c1"), /* SDA */ ++ SUNXI_FUNCTION_IRQ_BANK(0x6, 0, 19)), /* PA_EINT19 */ ++ SUNXI_PIN(SUNXI_PINCTRL_PIN(A, 20), ++ SUNXI_FUNCTION(0x0, "gpio_in"), ++ SUNXI_FUNCTION(0x1, "gpio_out"), ++ SUNXI_FUNCTION(0x2, "i2s0"), /* DOUT */ ++ SUNXI_FUNCTION(0x3, "sim"), /* VPPEN */ ++ SUNXI_FUNCTION_IRQ_BANK(0x6, 0, 20)), /* PA_EINT20 */ ++ SUNXI_PIN(SUNXI_PINCTRL_PIN(A, 21), ++ SUNXI_FUNCTION(0x0, "gpio_in"), ++ SUNXI_FUNCTION(0x1, "gpio_out"), ++ SUNXI_FUNCTION(0x2, "i2s0"), /* DIN */ ++ SUNXI_FUNCTION(0x3, "sim"), /* VPPPP */ ++ SUNXI_FUNCTION_IRQ_BANK(0x6, 0, 21)), /* PA_EINT21 */ ++ /* Hole */ ++ SUNXI_PIN(SUNXI_PINCTRL_PIN(C, 0), ++ SUNXI_FUNCTION(0x0, "gpio_in"), ++ SUNXI_FUNCTION(0x1, "gpio_out"), ++ SUNXI_FUNCTION(0x2, "nand0"), /* WE */ ++ SUNXI_FUNCTION(0x3, "spi0")), /* MOSI */ ++ SUNXI_PIN(SUNXI_PINCTRL_PIN(C, 1), ++ SUNXI_FUNCTION(0x0, "gpio_in"), ++ SUNXI_FUNCTION(0x1, "gpio_out"), ++ SUNXI_FUNCTION(0x2, "nand0"), /* ALE */ ++ SUNXI_FUNCTION(0x3, "spi0")), /* MISO */ ++ SUNXI_PIN(SUNXI_PINCTRL_PIN(C, 2), ++ SUNXI_FUNCTION(0x0, "gpio_in"), ++ SUNXI_FUNCTION(0x1, "gpio_out"), ++ SUNXI_FUNCTION(0x2, "nand0"), /* CLE */ ++ SUNXI_FUNCTION(0x3, "spi0")), /* CLK */ ++ SUNXI_PIN(SUNXI_PINCTRL_PIN(C, 3), ++ SUNXI_FUNCTION(0x0, "gpio_in"), ++ SUNXI_FUNCTION(0x1, "gpio_out"), ++ SUNXI_FUNCTION(0x2, "nand0"), /* CE1 */ ++ SUNXI_FUNCTION(0x3, "spi0")), /* CS */ ++ SUNXI_PIN(SUNXI_PINCTRL_PIN(C, 4), ++ SUNXI_FUNCTION(0x0, "gpio_in"), ++ SUNXI_FUNCTION(0x1, "gpio_out"), ++ SUNXI_FUNCTION(0x2, "nand0")), /* CE0 */ ++ SUNXI_PIN(SUNXI_PINCTRL_PIN(C, 5), ++ SUNXI_FUNCTION(0x0, "gpio_in"), ++ SUNXI_FUNCTION(0x1, "gpio_out"), ++ SUNXI_FUNCTION(0x2, "nand0"), /* RE */ ++ SUNXI_FUNCTION(0x3, "mmc2")), /* CLK */ ++ SUNXI_PIN(SUNXI_PINCTRL_PIN(C, 6), ++ SUNXI_FUNCTION(0x0, "gpio_in"), ++ SUNXI_FUNCTION(0x1, "gpio_out"), ++ SUNXI_FUNCTION(0x2, "nand0"), /* RB0 */ ++ SUNXI_FUNCTION(0x3, "mmc2")), /* CMD */ ++ SUNXI_PIN(SUNXI_PINCTRL_PIN(C, 7), ++ SUNXI_FUNCTION(0x0, "gpio_in"), ++ SUNXI_FUNCTION(0x1, "gpio_out"), ++ SUNXI_FUNCTION(0x2, "nand0")), /* RB1 */ ++ SUNXI_PIN(SUNXI_PINCTRL_PIN(C, 8), ++ SUNXI_FUNCTION(0x0, "gpio_in"), ++ SUNXI_FUNCTION(0x1, "gpio_out"), ++ SUNXI_FUNCTION(0x2, "nand0"), /* DQ0 */ ++ SUNXI_FUNCTION(0x3, "mmc2")), /* D0 */ ++ SUNXI_PIN(SUNXI_PINCTRL_PIN(C, 9), ++ SUNXI_FUNCTION(0x0, "gpio_in"), ++ SUNXI_FUNCTION(0x1, "gpio_out"), ++ SUNXI_FUNCTION(0x2, "nand0"), /* DQ1 */ ++ SUNXI_FUNCTION(0x3, "mmc2")), /* D1 */ ++ SUNXI_PIN(SUNXI_PINCTRL_PIN(C, 10), ++ SUNXI_FUNCTION(0x0, "gpio_in"), ++ SUNXI_FUNCTION(0x1, "gpio_out"), ++ SUNXI_FUNCTION(0x2, "nand0"), /* DQ2 */ ++ SUNXI_FUNCTION(0x3, "mmc2")), /* D2 */ ++ SUNXI_PIN(SUNXI_PINCTRL_PIN(C, 11), ++ SUNXI_FUNCTION(0x0, "gpio_in"), ++ SUNXI_FUNCTION(0x1, "gpio_out"), ++ SUNXI_FUNCTION(0x2, "nand0"), /* DQ3 */ ++ SUNXI_FUNCTION(0x3, "mmc2")), /* D3 */ ++ SUNXI_PIN(SUNXI_PINCTRL_PIN(C, 12), ++ SUNXI_FUNCTION(0x0, "gpio_in"), ++ SUNXI_FUNCTION(0x1, "gpio_out"), ++ SUNXI_FUNCTION(0x2, "nand0"), /* DQ4 */ ++ SUNXI_FUNCTION(0x3, "mmc2")), /* D4 */ ++ SUNXI_PIN(SUNXI_PINCTRL_PIN(C, 13), ++ SUNXI_FUNCTION(0x0, "gpio_in"), ++ SUNXI_FUNCTION(0x1, "gpio_out"), ++ SUNXI_FUNCTION(0x2, "nand0"), /* DQ5 */ ++ SUNXI_FUNCTION(0x3, "mmc2")), /* D5 */ ++ SUNXI_PIN(SUNXI_PINCTRL_PIN(C, 14), ++ SUNXI_FUNCTION(0x0, "gpio_in"), ++ SUNXI_FUNCTION(0x1, "gpio_out"), ++ SUNXI_FUNCTION(0x2, "nand"), /* DQ6 */ ++ SUNXI_FUNCTION(0x3, "mmc2")), /* D6 */ ++ SUNXI_PIN(SUNXI_PINCTRL_PIN(C, 15), ++ SUNXI_FUNCTION(0x0, "gpio_in"), ++ SUNXI_FUNCTION(0x1, "gpio_out"), ++ SUNXI_FUNCTION(0x2, "nand"), /* DQ7 */ ++ SUNXI_FUNCTION(0x3, "mmc2")), /* D7 */ ++ SUNXI_PIN(SUNXI_PINCTRL_PIN(C, 16), ++ SUNXI_FUNCTION(0x0, "gpio_in"), ++ SUNXI_FUNCTION(0x1, "gpio_out"), ++ SUNXI_FUNCTION(0x2, "nand"), /* DQS */ ++ SUNXI_FUNCTION(0x3, "mmc2")), /* RST */ ++ /* Hole */ ++ SUNXI_PIN(SUNXI_PINCTRL_PIN(D, 0), ++ SUNXI_FUNCTION(0x0, "gpio_in"), ++ SUNXI_FUNCTION(0x1, "gpio_out"), ++ SUNXI_FUNCTION(0x2, "emac")), /* RXD3 */ ++ SUNXI_PIN(SUNXI_PINCTRL_PIN(D, 1), ++ SUNXI_FUNCTION(0x0, "gpio_in"), ++ SUNXI_FUNCTION(0x1, "gpio_out"), ++ SUNXI_FUNCTION(0x2, "emac")), /* RXD2 */ ++ SUNXI_PIN(SUNXI_PINCTRL_PIN(D, 2), ++ SUNXI_FUNCTION(0x0, "gpio_in"), ++ SUNXI_FUNCTION(0x1, "gpio_out"), ++ SUNXI_FUNCTION(0x2, "emac")), /* RXD1 */ ++ SUNXI_PIN(SUNXI_PINCTRL_PIN(D, 3), ++ SUNXI_FUNCTION(0x0, "gpio_in"), ++ SUNXI_FUNCTION(0x1, "gpio_out"), ++ SUNXI_FUNCTION(0x2, "emac")), /* RXD0 */ ++ SUNXI_PIN(SUNXI_PINCTRL_PIN(D, 4), ++ SUNXI_FUNCTION(0x0, "gpio_in"), ++ SUNXI_FUNCTION(0x1, "gpio_out"), ++ SUNXI_FUNCTION(0x2, "emac")), /* RXCK */ ++ SUNXI_PIN(SUNXI_PINCTRL_PIN(D, 5), ++ SUNXI_FUNCTION(0x0, "gpio_in"), ++ SUNXI_FUNCTION(0x1, "gpio_out"), ++ SUNXI_FUNCTION(0x2, "emac")), /* RXCTL/RCDV */ ++ SUNXI_PIN(SUNXI_PINCTRL_PIN(D, 6), ++ SUNXI_FUNCTION(0x0, "gpio_in"), ++ SUNXI_FUNCTION(0x1, "gpio_out"), ++ SUNXI_FUNCTION(0x2, "emac")), /* RXERR */ ++ SUNXI_PIN(SUNXI_PINCTRL_PIN(D, 7), ++ SUNXI_FUNCTION(0x0, "gpio_in"), ++ SUNXI_FUNCTION(0x1, "gpio_out"), ++ SUNXI_FUNCTION(0x2, "emac")), /* TXD3 */ ++ SUNXI_PIN(SUNXI_PINCTRL_PIN(D, 8), ++ SUNXI_FUNCTION(0x0, "gpio_in"), ++ SUNXI_FUNCTION(0x1, "gpio_out"), ++ SUNXI_FUNCTION(0x2, "emac")), /* TXD2L */ ++ SUNXI_PIN(SUNXI_PINCTRL_PIN(D, 9), ++ SUNXI_FUNCTION(0x0, "gpio_in"), ++ SUNXI_FUNCTION(0x1, "gpio_out"), ++ SUNXI_FUNCTION(0x2, "emac")), /* TXD1 */ ++ SUNXI_PIN(SUNXI_PINCTRL_PIN(D, 10), ++ SUNXI_FUNCTION(0x0, "gpio_in"), ++ SUNXI_FUNCTION(0x1, "gpio_out"), ++ SUNXI_FUNCTION(0x2, "emac")), /* TXD0 */ ++ SUNXI_PIN(SUNXI_PINCTRL_PIN(D, 11), ++ SUNXI_FUNCTION(0x0, "gpio_in"), ++ SUNXI_FUNCTION(0x1, "gpio_out"), ++ SUNXI_FUNCTION(0x2, "emac")), /* CRS */ ++ SUNXI_PIN(SUNXI_PINCTRL_PIN(D, 12), ++ SUNXI_FUNCTION(0x0, "gpio_in"), ++ SUNXI_FUNCTION(0x1, "gpio_out"), ++ SUNXI_FUNCTION(0x2, "emac")), /* TXCK */ ++ SUNXI_PIN(SUNXI_PINCTRL_PIN(D, 13), ++ SUNXI_FUNCTION(0x0, "gpio_in"), ++ SUNXI_FUNCTION(0x1, "gpio_out"), ++ SUNXI_FUNCTION(0x2, "emac")), /* TXCTL/TXEN */ ++ SUNXI_PIN(SUNXI_PINCTRL_PIN(D, 14), ++ SUNXI_FUNCTION(0x0, "gpio_in"), ++ SUNXI_FUNCTION(0x1, "gpio_out"), ++ SUNXI_FUNCTION(0x2, "emac")), /* TXERR */ ++ SUNXI_PIN(SUNXI_PINCTRL_PIN(D, 15), ++ SUNXI_FUNCTION(0x0, "gpio_in"), ++ SUNXI_FUNCTION(0x1, "gpio_out"), ++ SUNXI_FUNCTION(0x2, "emac")), /* CLKIN/COL */ ++ SUNXI_PIN(SUNXI_PINCTRL_PIN(D, 16), ++ SUNXI_FUNCTION(0x0, "gpio_in"), ++ SUNXI_FUNCTION(0x1, "gpio_out"), ++ SUNXI_FUNCTION(0x2, "emac")), /* MDC */ ++ SUNXI_PIN(SUNXI_PINCTRL_PIN(D, 17), ++ SUNXI_FUNCTION(0x0, "gpio_in"), ++ SUNXI_FUNCTION(0x1, "gpio_out"), ++ SUNXI_FUNCTION(0x2, "emac")), /* MDIO */ ++ /* Hole */ ++ SUNXI_PIN(SUNXI_PINCTRL_PIN(E, 0), ++ SUNXI_FUNCTION(0x0, "gpio_in"), ++ SUNXI_FUNCTION(0x1, "gpio_out"), ++ SUNXI_FUNCTION(0x2, "csi"), /* PCLK */ ++ SUNXI_FUNCTION(0x3, "ts")), /* CLK */ ++ SUNXI_PIN(SUNXI_PINCTRL_PIN(E, 1), ++ SUNXI_FUNCTION(0x0, "gpio_in"), ++ SUNXI_FUNCTION(0x1, "gpio_out"), ++ SUNXI_FUNCTION(0x2, "csi"), /* MCLK */ ++ SUNXI_FUNCTION(0x3, "ts")), /* ERR */ ++ SUNXI_PIN(SUNXI_PINCTRL_PIN(E, 2), ++ SUNXI_FUNCTION(0x0, "gpio_in"), ++ SUNXI_FUNCTION(0x1, "gpio_out"), ++ SUNXI_FUNCTION(0x2, "csi"), /* HSYNC */ ++ SUNXI_FUNCTION(0x3, "ts")), /* SYNC */ ++ SUNXI_PIN(SUNXI_PINCTRL_PIN(E, 3), ++ SUNXI_FUNCTION(0x0, "gpio_in"), ++ SUNXI_FUNCTION(0x1, "gpio_out"), ++ SUNXI_FUNCTION(0x2, "csi"), /* VSYNC */ ++ SUNXI_FUNCTION(0x3, "ts")), /* DVLD */ ++ SUNXI_PIN(SUNXI_PINCTRL_PIN(E, 4), ++ SUNXI_FUNCTION(0x0, "gpio_in"), ++ SUNXI_FUNCTION(0x1, "gpio_out"), ++ SUNXI_FUNCTION(0x2, "csi"), /* D0 */ ++ SUNXI_FUNCTION(0x3, "ts")), /* D0 */ ++ SUNXI_PIN(SUNXI_PINCTRL_PIN(E, 5), ++ SUNXI_FUNCTION(0x0, "gpio_in"), ++ SUNXI_FUNCTION(0x1, "gpio_out"), ++ SUNXI_FUNCTION(0x2, "csi"), /* D1 */ ++ SUNXI_FUNCTION(0x3, "ts")), /* D1 */ ++ SUNXI_PIN(SUNXI_PINCTRL_PIN(E, 6), ++ SUNXI_FUNCTION(0x0, "gpio_in"), ++ SUNXI_FUNCTION(0x1, "gpio_out"), ++ SUNXI_FUNCTION(0x2, "csi"), /* D2 */ ++ SUNXI_FUNCTION(0x3, "ts")), /* D2 */ ++ SUNXI_PIN(SUNXI_PINCTRL_PIN(E, 7), ++ SUNXI_FUNCTION(0x0, "gpio_in"), ++ SUNXI_FUNCTION(0x1, "gpio_out"), ++ SUNXI_FUNCTION(0x2, "csi"), /* D3 */ ++ SUNXI_FUNCTION(0x3, "ts")), /* D3 */ ++ SUNXI_PIN(SUNXI_PINCTRL_PIN(E, 8), ++ SUNXI_FUNCTION(0x0, "gpio_in"), ++ SUNXI_FUNCTION(0x1, "gpio_out"), ++ SUNXI_FUNCTION(0x2, "csi"), /* D4 */ ++ SUNXI_FUNCTION(0x3, "ts")), /* D4 */ ++ SUNXI_PIN(SUNXI_PINCTRL_PIN(E, 9), ++ SUNXI_FUNCTION(0x0, "gpio_in"), ++ SUNXI_FUNCTION(0x1, "gpio_out"), ++ SUNXI_FUNCTION(0x2, "csi"), /* D5 */ ++ SUNXI_FUNCTION(0x3, "ts")), /* D5 */ ++ SUNXI_PIN(SUNXI_PINCTRL_PIN(E, 10), ++ SUNXI_FUNCTION(0x0, "gpio_in"), ++ SUNXI_FUNCTION(0x1, "gpio_out"), ++ SUNXI_FUNCTION(0x2, "csi"), /* D6 */ ++ SUNXI_FUNCTION(0x3, "ts")), /* D6 */ ++ SUNXI_PIN(SUNXI_PINCTRL_PIN(E, 11), ++ SUNXI_FUNCTION(0x0, "gpio_in"), ++ SUNXI_FUNCTION(0x1, "gpio_out"), ++ SUNXI_FUNCTION(0x2, "csi"), /* D7 */ ++ SUNXI_FUNCTION(0x3, "ts")), /* D7 */ ++ SUNXI_PIN(SUNXI_PINCTRL_PIN(E, 12), ++ SUNXI_FUNCTION(0x0, "gpio_in"), ++ SUNXI_FUNCTION(0x1, "gpio_out"), ++ SUNXI_FUNCTION(0x2, "csi"), /* SCK */ ++ SUNXI_FUNCTION(0x3, "i2c2")), /* SCK */ ++ SUNXI_PIN(SUNXI_PINCTRL_PIN(E, 13), ++ SUNXI_FUNCTION(0x0, "gpio_in"), ++ SUNXI_FUNCTION(0x1, "gpio_out"), ++ SUNXI_FUNCTION(0x2, "csi"), /* SDA */ ++ SUNXI_FUNCTION(0x3, "i2c2")), /* SDA */ ++ SUNXI_PIN(SUNXI_PINCTRL_PIN(E, 14), ++ SUNXI_FUNCTION(0x0, "gpio_in"), ++ SUNXI_FUNCTION(0x1, "gpio_out")), ++ SUNXI_PIN(SUNXI_PINCTRL_PIN(E, 15), ++ SUNXI_FUNCTION(0x0, "gpio_in"), ++ SUNXI_FUNCTION(0x1, "gpio_out")), ++ /* Hole */ ++ SUNXI_PIN(SUNXI_PINCTRL_PIN(F, 0), ++ SUNXI_FUNCTION(0x0, "gpio_in"), ++ SUNXI_FUNCTION(0x1, "gpio_out"), ++ SUNXI_FUNCTION(0x2, "mmc0"), /* D1 */ ++ SUNXI_FUNCTION(0x3, "jtag")), /* MS */ ++ SUNXI_PIN(SUNXI_PINCTRL_PIN(F, 1), ++ SUNXI_FUNCTION(0x0, "gpio_in"), ++ SUNXI_FUNCTION(0x1, "gpio_out"), ++ SUNXI_FUNCTION(0x2, "mmc0"), /* D0 */ ++ SUNXI_FUNCTION(0x3, "jtag")), /* DI */ ++ SUNXI_PIN(SUNXI_PINCTRL_PIN(F, 2), ++ SUNXI_FUNCTION(0x0, "gpio_in"), ++ SUNXI_FUNCTION(0x1, "gpio_out"), ++ SUNXI_FUNCTION(0x2, "mmc0"), /* CLK */ ++ SUNXI_FUNCTION(0x3, "uart0")), /* TX */ ++ SUNXI_PIN(SUNXI_PINCTRL_PIN(F, 3), ++ SUNXI_FUNCTION(0x0, "gpio_in"), ++ SUNXI_FUNCTION(0x1, "gpio_out"), ++ SUNXI_FUNCTION(0x2, "mmc0"), /* CMD */ ++ SUNXI_FUNCTION(0x3, "jtag")), /* DO */ ++ SUNXI_PIN(SUNXI_PINCTRL_PIN(F, 4), ++ SUNXI_FUNCTION(0x0, "gpio_in"), ++ SUNXI_FUNCTION(0x1, "gpio_out"), ++ SUNXI_FUNCTION(0x2, "mmc0"), /* D3 */ ++ SUNXI_FUNCTION(0x3, "uart0")), /* RX */ ++ SUNXI_PIN(SUNXI_PINCTRL_PIN(F, 5), ++ SUNXI_FUNCTION(0x0, "gpio_in"), ++ SUNXI_FUNCTION(0x1, "gpio_out"), ++ SUNXI_FUNCTION(0x2, "mmc0"), /* D2 */ ++ SUNXI_FUNCTION(0x3, "jtag")), /* CK */ ++ SUNXI_PIN(SUNXI_PINCTRL_PIN(F, 6), ++ SUNXI_FUNCTION(0x0, "gpio_in"), ++ SUNXI_FUNCTION(0x1, "gpio_out"), ++ SUNXI_FUNCTION(0x2, "mmc0")), /* DET */ ++ /* Hole */ ++ SUNXI_PIN(SUNXI_PINCTRL_PIN(G, 0), ++ SUNXI_FUNCTION(0x0, "gpio_in"), ++ SUNXI_FUNCTION(0x1, "gpio_out"), ++ SUNXI_FUNCTION(0x2, "mmc1"), /* CLK */ ++ SUNXI_FUNCTION_IRQ_BANK(0x4, 1, 0)), /* PG_EINT0 */ ++ SUNXI_PIN(SUNXI_PINCTRL_PIN(G, 1), ++ SUNXI_FUNCTION(0x0, "gpio_in"), ++ SUNXI_FUNCTION(0x1, "gpio_out"), ++ SUNXI_FUNCTION(0x2, "mmc1"), /* CMD */ ++ SUNXI_FUNCTION_IRQ_BANK(0x4, 1, 1)), /* PG_EINT1 */ ++ SUNXI_PIN(SUNXI_PINCTRL_PIN(G, 2), ++ SUNXI_FUNCTION(0x0, "gpio_in"), ++ SUNXI_FUNCTION(0x1, "gpio_out"), ++ SUNXI_FUNCTION(0x2, "mmc1"), /* D0 */ ++ SUNXI_FUNCTION_IRQ_BANK(0x4, 1, 2)), /* PG_EINT2 */ ++ SUNXI_PIN(SUNXI_PINCTRL_PIN(G, 3), ++ SUNXI_FUNCTION(0x0, "gpio_in"), ++ SUNXI_FUNCTION(0x1, "gpio_out"), ++ SUNXI_FUNCTION(0x2, "mmc1"), /* D1 */ ++ SUNXI_FUNCTION_IRQ_BANK(0x4, 1, 3)), /* PG_EINT3 */ ++ SUNXI_PIN(SUNXI_PINCTRL_PIN(G, 4), ++ SUNXI_FUNCTION(0x0, "gpio_in"), ++ SUNXI_FUNCTION(0x1, "gpio_out"), ++ SUNXI_FUNCTION(0x2, "mmc1"), /* D2 */ ++ SUNXI_FUNCTION_IRQ_BANK(0x4, 1, 4)), /* PG_EINT4 */ ++ SUNXI_PIN(SUNXI_PINCTRL_PIN(G, 5), ++ SUNXI_FUNCTION(0x0, "gpio_in"), ++ SUNXI_FUNCTION(0x1, "gpio_out"), ++ SUNXI_FUNCTION(0x2, "mmc1"), /* D3 */ ++ SUNXI_FUNCTION_IRQ_BANK(0x4, 1, 5)), /* PG_EINT5 */ ++ SUNXI_PIN(SUNXI_PINCTRL_PIN(G, 6), ++ SUNXI_FUNCTION(0x0, "gpio_in"), ++ SUNXI_FUNCTION(0x1, "gpio_out"), ++ SUNXI_FUNCTION(0x2, "uart1"), /* TX */ ++ SUNXI_FUNCTION_IRQ_BANK(0x4, 1, 6)), /* PG_EINT6 */ ++ SUNXI_PIN(SUNXI_PINCTRL_PIN(G, 7), ++ SUNXI_FUNCTION(0x0, "gpio_in"), ++ SUNXI_FUNCTION(0x1, "gpio_out"), ++ SUNXI_FUNCTION(0x2, "uart1"), /* RX */ ++ SUNXI_FUNCTION_IRQ_BANK(0x4, 1, 7)), /* PG_EINT7 */ ++ SUNXI_PIN(SUNXI_PINCTRL_PIN(G, 8), ++ SUNXI_FUNCTION(0x0, "gpio_in"), ++ SUNXI_FUNCTION(0x1, "gpio_out"), ++ SUNXI_FUNCTION(0x2, "uart1"), /* RTS */ ++ SUNXI_FUNCTION_IRQ_BANK(0x4, 1, 8)), /* PG_EINT8 */ ++ SUNXI_PIN(SUNXI_PINCTRL_PIN(G, 9), ++ SUNXI_FUNCTION(0x0, "gpio_in"), ++ SUNXI_FUNCTION(0x1, "gpio_out"), ++ SUNXI_FUNCTION(0x2, "uart1"), /* CTS */ ++ SUNXI_FUNCTION_IRQ_BANK(0x4, 1, 9)), /* PG_EINT9 */ ++ SUNXI_PIN(SUNXI_PINCTRL_PIN(G, 10), ++ SUNXI_FUNCTION(0x0, "gpio_in"), ++ SUNXI_FUNCTION(0x1, "gpio_out"), ++ SUNXI_FUNCTION(0x2, "i2s1"), /* SYNC */ ++ SUNXI_FUNCTION_IRQ_BANK(0x4, 1, 10)), /* PG_EINT10 */ ++ SUNXI_PIN(SUNXI_PINCTRL_PIN(G, 11), ++ SUNXI_FUNCTION(0x0, "gpio_in"), ++ SUNXI_FUNCTION(0x1, "gpio_out"), ++ SUNXI_FUNCTION(0x2, "i2s1"), /* CLK */ ++ SUNXI_FUNCTION_IRQ_BANK(0x4, 1, 11)), /* PG_EINT11 */ ++ SUNXI_PIN(SUNXI_PINCTRL_PIN(G, 12), ++ SUNXI_FUNCTION(0x0, "gpio_in"), ++ SUNXI_FUNCTION(0x1, "gpio_out"), ++ SUNXI_FUNCTION(0x2, "i2s1"), /* DOUT */ ++ SUNXI_FUNCTION_IRQ_BANK(0x4, 1, 12)), /* PG_EINT12 */ ++ SUNXI_PIN(SUNXI_PINCTRL_PIN(G, 13), ++ SUNXI_FUNCTION(0x0, "gpio_in"), ++ SUNXI_FUNCTION(0x1, "gpio_out"), ++ SUNXI_FUNCTION(0x2, "i2s1"), /* DIN */ ++ SUNXI_FUNCTION_IRQ_BANK(0x4, 1, 13)), /* PG_EINT13 */ ++}; ++ ++static const struct sunxi_pinctrl_desc sun8i_h3_pinctrl_data = { ++ .pins = sun8i_h3_pins, ++ .npins = ARRAY_SIZE(sun8i_h3_pins), ++ .irq_banks = 2, ++}; ++ ++static int sun8i_h3_pinctrl_probe(struct platform_device *pdev) ++{ ++ return sunxi_pinctrl_init(pdev, ++ &sun8i_h3_pinctrl_data); ++} ++ ++static const struct of_device_id sun8i_h3_pinctrl_match[] = { ++ { .compatible = "allwinner,sun8i-h3-pinctrl", }, ++ {} ++}; ++ ++static struct platform_driver sun8i_h3_pinctrl_driver = { ++ .probe = sun8i_h3_pinctrl_probe, ++ .driver = { ++ .name = "sun8i-h3-pinctrl", ++ .of_match_table = sun8i_h3_pinctrl_match, ++ }, ++}; ++builtin_platform_driver(sun8i_h3_pinctrl_driver); diff --git a/target/linux/sunxi/patches-4.4/131-reset-add-h3-resets.patch b/target/linux/sunxi/patches-4.4/131-reset-add-h3-resets.patch new file mode 100644 index 0000000000..a07cbe5797 --- /dev/null +++ b/target/linux/sunxi/patches-4.4/131-reset-add-h3-resets.patch @@ -0,0 +1,95 @@ +From 5f0bb9d0bc545ef53a83f7bd176fdc0736eed8e5 Mon Sep 17 00:00:00 2001 +From: Jens Kuske +Date: Tue, 27 Oct 2015 17:50:24 +0100 +Subject: [PATCH] reset: sunxi: Add Allwinner H3 bus resets + +The H3 bus resets have some holes between the registers, so we add +an of_xlate() function to skip them according to the datasheet. + +Signed-off-by: Jens Kuske +--- + .../bindings/reset/allwinner,sunxi-clock-reset.txt | 1 + + drivers/reset/reset-sunxi.c | 30 +++++++++++++++++++--- + 2 files changed, 28 insertions(+), 3 deletions(-) + +diff --git a/Documentation/devicetree/bindings/reset/allwinner,sunxi-clock-reset.txt b/Documentation/devicetree/bindings/reset/allwinner,sunxi-clock-reset.txt +index c8f77571..e11f023 100644 +--- a/Documentation/devicetree/bindings/reset/allwinner,sunxi-clock-reset.txt ++++ b/Documentation/devicetree/bindings/reset/allwinner,sunxi-clock-reset.txt +@@ -8,6 +8,7 @@ Required properties: + - compatible: Should be one of the following: + "allwinner,sun6i-a31-ahb1-reset" + "allwinner,sun6i-a31-clock-reset" ++ "allwinner,sun8i-h3-bus-reset" + - reg: should be register base and length as documented in the + datasheet + - #reset-cells: 1, see below +diff --git a/drivers/reset/reset-sunxi.c b/drivers/reset/reset-sunxi.c +index 3d95c87..c91e146 100644 +--- a/drivers/reset/reset-sunxi.c ++++ b/drivers/reset/reset-sunxi.c +@@ -75,7 +75,9 @@ static struct reset_control_ops sunxi_reset_ops = { + .deassert = sunxi_reset_deassert, + }; + +-static int sunxi_reset_init(struct device_node *np) ++static int sunxi_reset_init(struct device_node *np, ++ int (*of_xlate)(struct reset_controller_dev *rcdev, ++ const struct of_phandle_args *reset_spec)) + { + struct sunxi_reset_data *data; + struct resource res; +@@ -108,6 +110,7 @@ static int sunxi_reset_init(struct device_node *np) + data->rcdev.nr_resets = size * 32; + data->rcdev.ops = &sunxi_reset_ops; + data->rcdev.of_node = np; ++ data->rcdev.of_xlate = of_xlate; + reset_controller_register(&data->rcdev); + + return 0; +@@ -117,6 +120,21 @@ static int sunxi_reset_init(struct device_node *np) + return ret; + }; + ++static int sun8i_h3_bus_reset_xlate(struct reset_controller_dev *rcdev, ++ const struct of_phandle_args *reset_spec) ++{ ++ unsigned int index = reset_spec->args[0]; ++ ++ if (index < 96) ++ return index; ++ else if (index < 128) ++ return index + 32; ++ else if (index < 160) ++ return index + 64; ++ else ++ return -EINVAL; ++} ++ + /* + * These are the reset controller we need to initialize early on in + * our system, before we can even think of using a regular device +@@ -124,15 +142,21 @@ static int sunxi_reset_init(struct device_node *np) + */ + static const struct of_device_id sunxi_early_reset_dt_ids[] __initdata = { + { .compatible = "allwinner,sun6i-a31-ahb1-reset", }, ++ { .compatible = "allwinner,sun8i-h3-bus-reset", .data = sun8i_h3_bus_reset_xlate, }, + { /* sentinel */ }, + }; + + void __init sun6i_reset_init(void) + { + struct device_node *np; ++ const struct of_device_id *match; ++ int (*of_xlate)(struct reset_controller_dev *rcdev, ++ const struct of_phandle_args *reset_spec); + +- for_each_matching_node(np, sunxi_early_reset_dt_ids) +- sunxi_reset_init(np); ++ for_each_matching_node_and_match(np, sunxi_early_reset_dt_ids, &match) { ++ of_xlate = match->data; ++ sunxi_reset_init(np, of_xlate); ++ } + } + + /* diff --git a/target/linux/sunxi/patches-4.4/132-dt-sun8i-add-h3-usbclocks.patch b/target/linux/sunxi/patches-4.4/132-dt-sun8i-add-h3-usbclocks.patch new file mode 100644 index 0000000000..a38d34174c --- /dev/null +++ b/target/linux/sunxi/patches-4.4/132-dt-sun8i-add-h3-usbclocks.patch @@ -0,0 +1,36 @@ +From d6a71e3caae07fb2d98e93ee62477273abaceb27 Mon Sep 17 00:00:00 2001 +From: Reinder de Haan +Date: Tue, 3 Nov 2015 15:13:00 +0100 +Subject: [PATCH] ARM: dts: sun8i: Add support for H3 usb clocks + +Add a node describing the usb-clks found on the H3. + +Signed-off-by: Reinder de Haan +Signed-off-by: Hans de Goede +--- + arch/arm/boot/dts/sun8i-h3.dtsi | 12 ++++++++++++ + 1 file changed, 12 insertions(+) + +diff --git a/arch/arm/boot/dts/sun8i-h3.dtsi b/arch/arm/boot/dts/sun8i-h3.dtsi +index 1524130e..cbab947 100644 +--- a/arch/arm/boot/dts/sun8i-h3.dtsi ++++ b/arch/arm/boot/dts/sun8i-h3.dtsi +@@ -269,6 +269,18 @@ + "mmc2_sample"; + }; + ++ usb_clk: clk@01c200cc { ++ #clock-cells = <1>; ++ #reset-cells = <1>; ++ compatible = "allwinner,sun8i-h3-usb-clk"; ++ reg = <0x01c200cc 0x4>; ++ clocks = <&osc24M>; ++ clock-output-names = "usb_phy0", "usb_phy1", ++ "usb_phy2", "usb_phy3", ++ "usb_ohci0", "usb_ohci1", ++ "usb_ohci2", "usb_ohci3"; ++ }; ++ + mbus_clk: clk@01c2015c { + #clock-cells = <0>; + compatible = "allwinner,sun8i-a23-mbus-clk"; diff --git a/target/linux/sunxi/patches-4.4/133-dt-sun8i-add-usbphy-usbhost-ctrl-nodes.patch b/target/linux/sunxi/patches-4.4/133-dt-sun8i-add-usbphy-usbhost-ctrl-nodes.patch new file mode 100644 index 0000000000..6910834297 --- /dev/null +++ b/target/linux/sunxi/patches-4.4/133-dt-sun8i-add-usbphy-usbhost-ctrl-nodes.patch @@ -0,0 +1,125 @@ +From 5971a2f283d21eab36d7de24d35301f081f83418 Mon Sep 17 00:00:00 2001 +From: Reinder de Haan +Date: Tue, 3 Nov 2015 15:14:20 +0100 +Subject: [PATCH] ARM: dts: sun8i: Add usbphy and usb host controller nodes + +Add nodes describing the H3's usbphy and usb host controller nodes. + +Signed-off-by: Reinder de Haan +Signed-off-by: Hans de Goede +--- + arch/arm/boot/dts/sun8i-h3.dtsi | 101 ++++++++++++++++++++++++++++++++++++++++ + 1 file changed, 101 insertions(+) + +diff --git a/arch/arm/boot/dts/sun8i-h3.dtsi b/arch/arm/boot/dts/sun8i-h3.dtsi +index cbab947..1169f515 100644 +--- a/arch/arm/boot/dts/sun8i-h3.dtsi ++++ b/arch/arm/boot/dts/sun8i-h3.dtsi +@@ -362,6 +362,107 @@ + #size-cells = <0>; + }; + ++ usbphy: phy@01c19400 { ++ compatible = "allwinner,sun8i-h3-usb-phy"; ++ reg = <0x01c19400 0x2c>, ++ <0x01c1a800 0x4>, ++ <0x01c1b800 0x4>, ++ <0x01c1c800 0x4>, ++ <0x01c1d800 0x4>; ++ reg-names = "phy_ctrl", ++ "pmu0", ++ "pmu1", ++ "pmu2", ++ "pmu3"; ++ clocks = <&usb_clk 8>, ++ <&usb_clk 9>, ++ <&usb_clk 10>, ++ <&usb_clk 11>; ++ clock-names = "usb0_phy", ++ "usb1_phy", ++ "usb2_phy", ++ "usb3_phy"; ++ resets = <&usb_clk 0>, ++ <&usb_clk 1>, ++ <&usb_clk 2>, ++ <&usb_clk 3>; ++ reset-names = "usb0_reset", ++ "usb1_reset", ++ "usb2_reset", ++ "usb3_reset"; ++ status = "disabled"; ++ #phy-cells = <1>; ++ }; ++ ++ ehci1: usb@01c1b000 { ++ compatible = "allwinner,sun8i-h3-ehci", "generic-ehci"; ++ reg = <0x01c1b000 0x100>; ++ interrupts = ; ++ clocks = <&bus_gates 25>, <&bus_gates 29>; ++ resets = <&ahb_rst 25>, <&ahb_rst 29>; ++ phys = <&usbphy 1>; ++ phy-names = "usb"; ++ status = "disabled"; ++ }; ++ ++ ohci1: usb@01c1b400 { ++ compatible = "allwinner,sun8i-h3-ohci", "generic-ohci"; ++ reg = <0x01c1b400 0x100>; ++ interrupts = ; ++ clocks = <&bus_gates 29>, <&bus_gates 25>, ++ <&usb_clk 17>; ++ resets = <&ahb_rst 29>, <&ahb_rst 25>; ++ phys = <&usbphy 1>; ++ phy-names = "usb"; ++ status = "disabled"; ++ }; ++ ++ ehci2: usb@01c1c000 { ++ compatible = "allwinner,sun8i-h3-ehci", "generic-ehci"; ++ reg = <0x01c1c000 0x100>; ++ interrupts = ; ++ clocks = <&bus_gates 26>, <&bus_gates 30>; ++ resets = <&ahb_rst 26>, <&ahb_rst 30>; ++ phys = <&usbphy 2>; ++ phy-names = "usb"; ++ status = "disabled"; ++ }; ++ ++ ohci2: usb@01c1c400 { ++ compatible = "allwinner,sun8i-h3-ohci", "generic-ohci"; ++ reg = <0x01c1c400 0x100>; ++ interrupts = ; ++ clocks = <&bus_gates 30>, <&bus_gates 26>, ++ <&usb_clk 18>; ++ resets = <&ahb_rst 30>, <&ahb_rst 26>; ++ phys = <&usbphy 2>; ++ phy-names = "usb"; ++ status = "disabled"; ++ }; ++ ++ ehci3: usb@01c1d000 { ++ compatible = "allwinner,sun8i-h3-ehci", "generic-ehci"; ++ reg = <0x01c1d000 0x100>; ++ interrupts = ; ++ clocks = <&bus_gates 27>, <&bus_gates 31>; ++ resets = <&ahb_rst 27>, <&ahb_rst 31>; ++ phys = <&usbphy 3>; ++ phy-names = "usb"; ++ status = "disabled"; ++ }; ++ ++ ohci3: usb@01c1d400 { ++ compatible = "allwinner,sun8i-h3-ohci", "generic-ohci"; ++ reg = <0x01c1d400 0x100>; ++ interrupts = ; ++ clocks = <&bus_gates 31>, <&bus_gates 27>, ++ <&usb_clk 19>; ++ resets = <&ahb_rst 31>, <&ahb_rst 27>; ++ phys = <&usbphy 3>; ++ phy-names = "usb"; ++ status = "disabled"; ++ }; ++ + pio: pinctrl@01c20800 { + compatible = "allwinner,sun8i-h3-pinctrl"; + reg = <0x01c20800 0x400>; diff --git a/target/linux/sunxi/patches-4.4/134-dt-sun8i-orangepiplus-enable-usbhost.patch b/target/linux/sunxi/patches-4.4/134-dt-sun8i-orangepiplus-enable-usbhost.patch new file mode 100644 index 0000000000..403e185459 --- /dev/null +++ b/target/linux/sunxi/patches-4.4/134-dt-sun8i-orangepiplus-enable-usbhost.patch @@ -0,0 +1,79 @@ +From 37e04fd781d3fc6d08116d38d34ec8124d916441 Mon Sep 17 00:00:00 2001 +From: Jens Kuske +Date: Tue, 17 Nov 2015 17:12:07 +0100 +Subject: [PATCH] ARM: dts: sun8i-h3-orangepi-plus: Enable USB host controllers + +Enable the 2 USB host controllers used on the Orange Pi Plus +and add the necessary regulators. + +Signed-off-by: Reinder de Haan +Signed-off-by: Hans de Goede +Signed-off-by: Jens Kuske +--- + arch/arm/boot/dts/sun8i-h3-orangepi-plus.dts | 44 ++++++++++++++++++++++++++++ + 1 file changed, 44 insertions(+) + +diff --git a/arch/arm/boot/dts/sun8i-h3-orangepi-plus.dts b/arch/arm/boot/dts/sun8i-h3-orangepi-plus.dts +index e67df59..1cb6c66 100644 +--- a/arch/arm/boot/dts/sun8i-h3-orangepi-plus.dts ++++ b/arch/arm/boot/dts/sun8i-h3-orangepi-plus.dts +@@ -58,6 +58,35 @@ + chosen { + stdout-path = "serial0:115200n8"; + }; ++ ++ reg_usb3_vbus: usb3-vbus { ++ compatible = "regulator-fixed"; ++ pinctrl-names = "default"; ++ pinctrl-0 = <&usb3_vbus_pin_a>; ++ regulator-name = "usb3-vbus"; ++ regulator-min-microvolt = <5000000>; ++ regulator-max-microvolt = <5000000>; ++ regulator-boot-on; ++ enable-active-high; ++ gpio = <&pio 6 11 GPIO_ACTIVE_HIGH>; ++ }; ++}; ++ ++&ehci1 { ++ status = "okay"; ++}; ++ ++&ehci3 { ++ status = "okay"; ++}; ++ ++&pio { ++ usb3_vbus_pin_a: usb3_vbus_pin@0 { ++ allwinner,pins = "PG11"; ++ allwinner,function = "gpio_out"; ++ allwinner,drive = ; ++ allwinner,pull = ; ++ }; + }; + + &mmc0 { +@@ -70,8 +99,23 @@ + status = "okay"; + }; + ++®_usb1_vbus { ++ gpio = <&pio 6 13 GPIO_ACTIVE_HIGH>; ++ status = "okay"; ++}; ++ + &uart0 { + pinctrl-names = "default"; + pinctrl-0 = <&uart0_pins_a>; + status = "okay"; + }; ++ ++&usb1_vbus_pin_a { ++ allwinner,pins = "PG13"; ++}; ++ ++&usbphy { ++ usb1_vbus-supply = <®_usb1_vbus>; ++ usb3_vbus-supply = <®_usb3_vbus>; ++ status = "okay"; ++}; diff --git a/target/linux/sunxi/patches-4.4/135-clk-sunxi-fix-signedness-bug.patch b/target/linux/sunxi/patches-4.4/135-clk-sunxi-fix-signedness-bug.patch new file mode 100644 index 0000000000..c90bbb5213 --- /dev/null +++ b/target/linux/sunxi/patches-4.4/135-clk-sunxi-fix-signedness-bug.patch @@ -0,0 +1,27 @@ +From b1558f168f4ef5956913d73fe330c4da85c74349 Mon Sep 17 00:00:00 2001 +From: Dan Carpenter +Date: Sat, 12 Dec 2015 15:43:46 +0300 +Subject: [PATCH] clk: sunxi: signedness bug in sun8i_h3_bus_gates_init() + +"index" needs to be signed for the error handling to work. + +Fixes: ab6e23a4e388 ('clk: sunxi: Add H3 clocks support') +Signed-off-by: Dan Carpenter +Signed-off-by: Maxime Ripard +--- + drivers/clk/sunxi/clk-sun8i-bus-gates.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/drivers/clk/sunxi/clk-sun8i-bus-gates.c b/drivers/clk/sunxi/clk-sun8i-bus-gates.c +index 7ab60c5..b8c7753 100644 +--- a/drivers/clk/sunxi/clk-sun8i-bus-gates.c ++++ b/drivers/clk/sunxi/clk-sun8i-bus-gates.c +@@ -40,7 +40,7 @@ static void __init sun8i_h3_bus_gates_init(struct device_node *node) + const __be32 *p; + int number, i; + u8 clk_bit; +- u32 index; ++ int index; + + reg = of_io_request_and_map(node, 0, of_node_full_name(node)); + if (IS_ERR(reg)) diff --git a/target/linux/sunxi/patches-4.4/140-reset-add-of_reset_control_get_by_index.patch b/target/linux/sunxi/patches-4.4/140-reset-add-of_reset_control_get_by_index.patch new file mode 100644 index 0000000000..1a48d7c23f --- /dev/null +++ b/target/linux/sunxi/patches-4.4/140-reset-add-of_reset_control_get_by_index.patch @@ -0,0 +1,113 @@ +From b4faa163a7ebae9faab5d0aefe70143e3379178b Mon Sep 17 00:00:00 2001 +From: Vince Hsu +Date: Mon, 13 Jul 2015 13:39:39 +0100 +Subject: [PATCH] reset: add of_reset_control_get_by_index() + +Add of_reset_control_get_by_index() to allow the drivers to get reset +device without knowing its name. + +Signed-off-by: Vince Hsu +[jonathanh@nvidia.com: Updated stub function to return -ENOTSUPP instead + of -ENOSYS which should only be used for system calls.] +Signed-off-by: Jon Hunter +Signed-off-by: Philipp Zabel +--- + drivers/reset/core.c | 40 +++++++++++++++++++++++++++++----------- + include/linux/reset.h | 9 +++++++++ + 2 files changed, 38 insertions(+), 11 deletions(-) + +diff --git a/drivers/reset/core.c b/drivers/reset/core.c +index 7955e00..81ae17d 100644 +--- a/drivers/reset/core.c ++++ b/drivers/reset/core.c +@@ -141,27 +141,24 @@ int reset_control_status(struct reset_control *rstc) + EXPORT_SYMBOL_GPL(reset_control_status); + + /** +- * of_reset_control_get - Lookup and obtain a reference to a reset controller. ++ * of_reset_control_get_by_index - Lookup and obtain a reference to a reset ++ * controller by index. + * @node: device to be reset by the controller +- * @id: reset line name +- * +- * Returns a struct reset_control or IS_ERR() condition containing errno. ++ * @index: index of the reset controller + * +- * Use of id names is optional. ++ * This is to be used to perform a list of resets for a device or power domain ++ * in whatever order. Returns a struct reset_control or IS_ERR() condition ++ * containing errno. + */ +-struct reset_control *of_reset_control_get(struct device_node *node, +- const char *id) ++struct reset_control *of_reset_control_get_by_index(struct device_node *node, ++ int index) + { + struct reset_control *rstc = ERR_PTR(-EPROBE_DEFER); + struct reset_controller_dev *r, *rcdev; + struct of_phandle_args args; +- int index = 0; + int rstc_id; + int ret; + +- if (id) +- index = of_property_match_string(node, +- "reset-names", id); + ret = of_parse_phandle_with_args(node, "resets", "#reset-cells", + index, &args); + if (ret) +@@ -202,6 +199,27 @@ struct reset_control *of_reset_control_get(struct device_node *node, + + return rstc; + } ++EXPORT_SYMBOL_GPL(of_reset_control_get_by_index); ++ ++/** ++ * of_reset_control_get - Lookup and obtain a reference to a reset controller. ++ * @node: device to be reset by the controller ++ * @id: reset line name ++ * ++ * Returns a struct reset_control or IS_ERR() condition containing errno. ++ * ++ * Use of id names is optional. ++ */ ++struct reset_control *of_reset_control_get(struct device_node *node, ++ const char *id) ++{ ++ int index = 0; ++ ++ if (id) ++ index = of_property_match_string(node, ++ "reset-names", id); ++ return of_reset_control_get_by_index(node, index); ++} + EXPORT_SYMBOL_GPL(of_reset_control_get); + + /** +diff --git a/include/linux/reset.h b/include/linux/reset.h +index 7f65f9c..6db74ad 100644 +--- a/include/linux/reset.h ++++ b/include/linux/reset.h +@@ -38,6 +38,9 @@ static inline struct reset_control *devm_reset_control_get_optional( + struct reset_control *of_reset_control_get(struct device_node *node, + const char *id); + ++struct reset_control *of_reset_control_get_by_index( ++ struct device_node *node, int index); ++ + #else + + static inline int reset_control_reset(struct reset_control *rstc) +@@ -106,6 +109,12 @@ static inline struct reset_control *of_reset_control_get( + return ERR_PTR(-ENOSYS); + } + ++static inline struct reset_control *of_reset_control_get_by_index( ++ struct device_node *node, int index) ++{ ++ return ERR_PTR(-ENOTSUPP); ++} ++ + #endif /* CONFIG_RESET_CONTROLLER */ + + #endif diff --git a/target/linux/sunxi/patches-4.4/141-reset-fix-of_reset_control_get.patch b/target/linux/sunxi/patches-4.4/141-reset-fix-of_reset_control_get.patch new file mode 100644 index 0000000000..62891b4e8c --- /dev/null +++ b/target/linux/sunxi/patches-4.4/141-reset-fix-of_reset_control_get.patch @@ -0,0 +1,41 @@ +From 7fd7a26b60090a7df15f30ba10b0d39cbbd6a94e Mon Sep 17 00:00:00 2001 +From: Alban Bedel +Date: Tue, 1 Sep 2015 17:28:31 +0200 +Subject: [PATCH] reset: Fix of_reset_control_get() for consistent return + values + +When of_reset_control_get() is called without connection ID it returns +-ENOENT when the 'resets' property doesn't exists or is an empty entry. +However when a connection ID is given it returns -EINVAL when the 'resets' +property doesn't exists or the requested name can't be found. This is +because the error code returned by of_property_match_string() is just +passed down as an index to of_parse_phandle_with_args(), which then +returns -EINVAL. + +To get a consistent return value with both code paths we must return +-ENOENT when of_property_match_string() fails. + +Signed-off-by: Alban Bedel +Signed-off-by: Philipp Zabel +--- + drivers/reset/core.c | 5 ++++- + 1 file changed, 4 insertions(+), 1 deletion(-) + +diff --git a/drivers/reset/core.c b/drivers/reset/core.c +index 81ae17d..77cfc49 100644 +--- a/drivers/reset/core.c ++++ b/drivers/reset/core.c +@@ -215,9 +215,12 @@ struct reset_control *of_reset_control_get(struct device_node *node, + { + int index = 0; + +- if (id) ++ if (id) { + index = of_property_match_string(node, + "reset-names", id); ++ if (index < 0) ++ return ERR_PTR(-ENOENT); ++ } + return of_reset_control_get_by_index(node, index); + } + EXPORT_SYMBOL_GPL(of_reset_control_get); diff --git a/target/linux/sunxi/patches-4.4/142-reset-use-ENOTSUPP-instead-of-ENOSYS.patch b/target/linux/sunxi/patches-4.4/142-reset-use-ENOTSUPP-instead-of-ENOSYS.patch new file mode 100644 index 0000000000..a80eed4481 --- /dev/null +++ b/target/linux/sunxi/patches-4.4/142-reset-use-ENOTSUPP-instead-of-ENOSYS.patch @@ -0,0 +1,91 @@ +From 5a819175b911ce33f3337e1e069d4bcea1ec4788 Mon Sep 17 00:00:00 2001 +From: Philipp Zabel +Date: Thu, 29 Oct 2015 09:55:00 +0100 +Subject: [PATCH] reset: use ENOTSUPP instead of ENOSYS + +ENOSYS is reserved to report invalid syscalls to userspace. +Consistently return ENOTSUPP to indicate that the driver doesn't support +the functionality or the reset framework is not enabled at all. + +Signed-off-by: Philipp Zabel +--- + drivers/reset/core.c | 8 ++++---- + include/linux/reset.h | 8 ++++---- + 2 files changed, 8 insertions(+), 8 deletions(-) + +diff --git a/drivers/reset/core.c b/drivers/reset/core.c +index 77cfc49..9ab9290 100644 +--- a/drivers/reset/core.c ++++ b/drivers/reset/core.c +@@ -95,7 +95,7 @@ int reset_control_reset(struct reset_control *rstc) + if (rstc->rcdev->ops->reset) + return rstc->rcdev->ops->reset(rstc->rcdev, rstc->id); + +- return -ENOSYS; ++ return -ENOTSUPP; + } + EXPORT_SYMBOL_GPL(reset_control_reset); + +@@ -108,7 +108,7 @@ int reset_control_assert(struct reset_control *rstc) + if (rstc->rcdev->ops->assert) + return rstc->rcdev->ops->assert(rstc->rcdev, rstc->id); + +- return -ENOSYS; ++ return -ENOTSUPP; + } + EXPORT_SYMBOL_GPL(reset_control_assert); + +@@ -121,7 +121,7 @@ int reset_control_deassert(struct reset_control *rstc) + if (rstc->rcdev->ops->deassert) + return rstc->rcdev->ops->deassert(rstc->rcdev, rstc->id); + +- return -ENOSYS; ++ return -ENOTSUPP; + } + EXPORT_SYMBOL_GPL(reset_control_deassert); + +@@ -136,7 +136,7 @@ int reset_control_status(struct reset_control *rstc) + if (rstc->rcdev->ops->status) + return rstc->rcdev->ops->status(rstc->rcdev, rstc->id); + +- return -ENOSYS; ++ return -ENOTSUPP; + } + EXPORT_SYMBOL_GPL(reset_control_status); + +diff --git a/include/linux/reset.h b/include/linux/reset.h +index 6db74ad..c4c097d 100644 +--- a/include/linux/reset.h ++++ b/include/linux/reset.h +@@ -74,7 +74,7 @@ static inline void reset_control_put(struct reset_control *rstc) + + static inline int device_reset_optional(struct device *dev) + { +- return -ENOSYS; ++ return -ENOTSUPP; + } + + static inline struct reset_control *__must_check reset_control_get( +@@ -94,19 +94,19 @@ static inline struct reset_control *__must_check devm_reset_control_get( + static inline struct reset_control *reset_control_get_optional( + struct device *dev, const char *id) + { +- return ERR_PTR(-ENOSYS); ++ return ERR_PTR(-ENOTSUPP); + } + + static inline struct reset_control *devm_reset_control_get_optional( + struct device *dev, const char *id) + { +- return ERR_PTR(-ENOSYS); ++ return ERR_PTR(-ENOTSUPP); + } + + static inline struct reset_control *of_reset_control_get( + struct device_node *node, const char *id) + { +- return ERR_PTR(-ENOSYS); ++ return ERR_PTR(-ENOTSUPP); + } + + static inline struct reset_control *of_reset_control_get_by_index( diff --git a/target/linux/sunxi/patches-4.4/143-reset-add-shared-resetcontrol-asserts.patch b/target/linux/sunxi/patches-4.4/143-reset-add-shared-resetcontrol-asserts.patch new file mode 100644 index 0000000000..3e962d9dab --- /dev/null +++ b/target/linux/sunxi/patches-4.4/143-reset-add-shared-resetcontrol-asserts.patch @@ -0,0 +1,271 @@ +From d25cfe9b4f9663216ce4e011e3f1e7fa669ab58a Mon Sep 17 00:00:00 2001 +From: Hans de Goede +Date: Fri, 27 Nov 2015 21:09:05 +0100 +Subject: [PATCH] reset: Add shared reset_control_[de]assert variants + +Add reset_control_deassert_shared / reset_control_assert_shared +functions which are intended for use by drivers for hw blocks which +(may) share a reset line with another driver / hw block. + +Unlike the regular reset_control_[de]assert functions these functions +keep track of how often deassert_shared / assert_shared have been called +and keep the line deasserted as long as deassert has been called more +times than assert. + +Signed-off-by: Hans de Goede +--- +Changes in v2: +-This is a new patch in v2 of this patch-set +--- + drivers/reset/core.c | 121 ++++++++++++++++++++++++++++++++++++--- + include/linux/reset-controller.h | 2 + + include/linux/reset.h | 2 + + 3 files changed, 116 insertions(+), 9 deletions(-) + +diff --git a/drivers/reset/core.c b/drivers/reset/core.c +index 9ab9290..8c3436c 100644 +--- a/drivers/reset/core.c ++++ b/drivers/reset/core.c +@@ -22,16 +22,29 @@ static DEFINE_MUTEX(reset_controller_list_mutex); + static LIST_HEAD(reset_controller_list); + + /** ++ * struct reset_line - a reset line ++ * @list: list entry for the reset controllers reset line list ++ * @id: ID of the reset line in the reset controller device ++ * @refcnt: Number of reset_control structs referencing this device ++ * @deassert_cnt: Number of times this reset line has been deasserted ++ */ ++struct reset_line { ++ struct list_head list; ++ unsigned int id; ++ unsigned int refcnt; ++ unsigned int deassert_cnt; ++}; ++ ++/** + * struct reset_control - a reset control + * @rcdev: a pointer to the reset controller device + * this reset control belongs to +- * @id: ID of the reset controller in the reset +- * controller device ++ * @line: reset line for this reset control + */ + struct reset_control { + struct reset_controller_dev *rcdev; ++ struct reset_line *line; + struct device *dev; +- unsigned int id; + }; + + /** +@@ -66,6 +79,8 @@ int reset_controller_register(struct reset_controller_dev *rcdev) + rcdev->of_xlate = of_reset_simple_xlate; + } + ++ INIT_LIST_HEAD(&rcdev->reset_line_head); ++ + mutex_lock(&reset_controller_list_mutex); + list_add(&rcdev->list, &reset_controller_list); + mutex_unlock(&reset_controller_list_mutex); +@@ -93,7 +108,7 @@ EXPORT_SYMBOL_GPL(reset_controller_unregister); + int reset_control_reset(struct reset_control *rstc) + { + if (rstc->rcdev->ops->reset) +- return rstc->rcdev->ops->reset(rstc->rcdev, rstc->id); ++ return rstc->rcdev->ops->reset(rstc->rcdev, rstc->line->id); + + return -ENOTSUPP; + } +@@ -106,7 +121,7 @@ EXPORT_SYMBOL_GPL(reset_control_reset); + int reset_control_assert(struct reset_control *rstc) + { + if (rstc->rcdev->ops->assert) +- return rstc->rcdev->ops->assert(rstc->rcdev, rstc->id); ++ return rstc->rcdev->ops->assert(rstc->rcdev, rstc->line->id); + + return -ENOTSUPP; + } +@@ -119,13 +134,55 @@ EXPORT_SYMBOL_GPL(reset_control_assert); + int reset_control_deassert(struct reset_control *rstc) + { + if (rstc->rcdev->ops->deassert) +- return rstc->rcdev->ops->deassert(rstc->rcdev, rstc->id); ++ return rstc->rcdev->ops->deassert(rstc->rcdev, rstc->line->id); + + return -ENOTSUPP; + } + EXPORT_SYMBOL_GPL(reset_control_deassert); + + /** ++ * reset_control_assert_shared - asserts a shared reset line ++ * @rstc: reset controller ++ * ++ * Assert a shared reset line, this functions decreases the deassert count ++ * of the line by one and asserts it if, and only if, the deassert count ++ * reaches 0. ++ */ ++int reset_control_assert_shared(struct reset_control *rstc) ++{ ++ if (!rstc->rcdev->ops->assert) ++ return -ENOTSUPP; ++ ++ rstc->line->deassert_cnt--; ++ if (rstc->line->deassert_cnt) ++ return 0; ++ ++ return rstc->rcdev->ops->assert(rstc->rcdev, rstc->line->id); ++} ++EXPORT_SYMBOL_GPL(reset_control_assert_shared); ++ ++/** ++ * reset_control_deassert_shared - deasserts a shared reset line ++ * @rstc: reset controller ++ * ++ * Assert a shared reset line, this functions increases the deassert count ++ * of the line by one and deasserts the reset line (if it was not already ++ * deasserted). ++ */ ++int reset_control_deassert_shared(struct reset_control *rstc) ++{ ++ if (!rstc->rcdev->ops->deassert) ++ return -ENOTSUPP; ++ ++ rstc->line->deassert_cnt++; ++ if (rstc->line->deassert_cnt != 1) ++ return 0; ++ ++ return rstc->rcdev->ops->deassert(rstc->rcdev, rstc->line->id); ++} ++EXPORT_SYMBOL_GPL(reset_control_deassert_shared); ++ ++/** + * reset_control_status - returns a negative errno if not supported, a + * positive value if the reset line is asserted, or zero if the reset + * line is not asserted. +@@ -134,12 +191,47 @@ EXPORT_SYMBOL_GPL(reset_control_deassert); + int reset_control_status(struct reset_control *rstc) + { + if (rstc->rcdev->ops->status) +- return rstc->rcdev->ops->status(rstc->rcdev, rstc->id); ++ return rstc->rcdev->ops->status(rstc->rcdev, rstc->line->id); + + return -ENOTSUPP; + } + EXPORT_SYMBOL_GPL(reset_control_status); + ++static struct reset_line *reset_line_get(struct reset_controller_dev *rcdev, ++ unsigned int index) ++{ ++ struct reset_line *line; ++ ++ list_for_each_entry(line, &rcdev->reset_line_head, list) { ++ if (line->id == index) { ++ line->refcnt++; ++ return line; ++ } ++ } ++ ++ line = kzalloc(sizeof(*line), GFP_KERNEL); ++ if (!line) ++ return NULL; ++ ++ list_add(&line->list, &rcdev->reset_line_head); ++ line->id = index; ++ line->refcnt = 1; ++ ++ return line; ++} ++ ++static void reset_line_put(struct reset_line *line) ++{ ++ if (!line) ++ return; ++ ++ if (--line->refcnt) ++ return; ++ ++ list_del(&line->list); ++ kfree(line); ++} ++ + /** + * of_reset_control_get_by_index - Lookup and obtain a reference to a reset + * controller by index. +@@ -155,6 +247,7 @@ struct reset_control *of_reset_control_get_by_index(struct device_node *node, + { + struct reset_control *rstc = ERR_PTR(-EPROBE_DEFER); + struct reset_controller_dev *r, *rcdev; ++ struct reset_line *line; + struct of_phandle_args args; + int rstc_id; + int ret; +@@ -186,16 +279,22 @@ struct reset_control *of_reset_control_get_by_index(struct device_node *node, + } + + try_module_get(rcdev->owner); ++ ++ /* reset_controller_list_mutex also protects the reset_line list */ ++ line = reset_line_get(rcdev, rstc_id); ++ + mutex_unlock(&reset_controller_list_mutex); + + rstc = kzalloc(sizeof(*rstc), GFP_KERNEL); +- if (!rstc) { ++ if (!line || !rstc) { ++ kfree(rstc); ++ reset_line_put(line); + module_put(rcdev->owner); + return ERR_PTR(-ENOMEM); + } + + rstc->rcdev = rcdev; +- rstc->id = rstc_id; ++ rstc->line = line; + + return rstc; + } +@@ -259,6 +358,10 @@ void reset_control_put(struct reset_control *rstc) + if (IS_ERR(rstc)) + return; + ++ mutex_lock(&reset_controller_list_mutex); ++ reset_line_put(rstc->line); ++ mutex_unlock(&reset_controller_list_mutex); ++ + module_put(rstc->rcdev->owner); + kfree(rstc); + } +diff --git a/include/linux/reset-controller.h b/include/linux/reset-controller.h +index ce6b962..7f2cbd1 100644 +--- a/include/linux/reset-controller.h ++++ b/include/linux/reset-controller.h +@@ -31,6 +31,7 @@ struct of_phandle_args; + * @ops: a pointer to device specific struct reset_control_ops + * @owner: kernel module of the reset controller driver + * @list: internal list of reset controller devices ++ * @reset_line_head: head of internal list of reset lines + * @of_node: corresponding device tree node as phandle target + * @of_reset_n_cells: number of cells in reset line specifiers + * @of_xlate: translation function to translate from specifier as found in the +@@ -41,6 +42,7 @@ struct reset_controller_dev { + struct reset_control_ops *ops; + struct module *owner; + struct list_head list; ++ struct list_head reset_line_head; + struct device_node *of_node; + int of_reset_n_cells; + int (*of_xlate)(struct reset_controller_dev *rcdev, +diff --git a/include/linux/reset.h b/include/linux/reset.h +index c4c097d..1cca8ce 100644 +--- a/include/linux/reset.h ++++ b/include/linux/reset.h +@@ -11,6 +11,8 @@ int reset_control_reset(struct reset_control *rstc); + int reset_control_assert(struct reset_control *rstc); + int reset_control_deassert(struct reset_control *rstc); + int reset_control_status(struct reset_control *rstc); ++int reset_control_assert_shared(struct reset_control *rstc); ++int reset_control_deassert_shared(struct reset_control *rstc); + + struct reset_control *reset_control_get(struct device *dev, const char *id); + void reset_control_put(struct reset_control *rstc); diff --git a/target/linux/sunxi/patches-4.4/144-usb-ehci-plat-support-multiple-reset-ctrllines.patch b/target/linux/sunxi/patches-4.4/144-usb-ehci-plat-support-multiple-reset-ctrllines.patch new file mode 100644 index 0000000000..faafa1f0a3 --- /dev/null +++ b/target/linux/sunxi/patches-4.4/144-usb-ehci-plat-support-multiple-reset-ctrllines.patch @@ -0,0 +1,131 @@ +From 957e8f96c67052ca843ea9ffc5223662b973e5de Mon Sep 17 00:00:00 2001 +From: Reinder de Haan +Date: Sun, 15 Nov 2015 14:24:46 +0100 +Subject: [PATCH] ehci-platform: Add support for controllers with multiple + reset lines + +At least the EHCI/OHCI found on the Allwinnner H3 SoC needs multiple +reset lines, the controller will not initialize while the reset for +its companion is still asserted, which means we need to de-assert +2 resets for the controller to work. + +Signed-off-by: Reinder de Haan +Signed-off-by: Hans de Goede +--- +Changes in v2: +-Use the new reset_control_[de]assert_shared reset-controller functions +--- + Documentation/devicetree/bindings/usb/usb-ehci.txt | 2 +- + drivers/usb/host/ehci-platform.c | 47 +++++++++++++--------- + 2 files changed, 30 insertions(+), 19 deletions(-) + +diff --git a/Documentation/devicetree/bindings/usb/usb-ehci.txt b/Documentation/devicetree/bindings/usb/usb-ehci.txt +index a12d601..0701812 100644 +--- a/Documentation/devicetree/bindings/usb/usb-ehci.txt ++++ b/Documentation/devicetree/bindings/usb/usb-ehci.txt +@@ -18,7 +18,7 @@ Optional properties: + - clocks : a list of phandle + clock specifier pairs + - phys : phandle + phy specifier pair + - phy-names : "usb" +- - resets : phandle + reset specifier pair ++ - resets : a list of phandle + reset specifier pairs + + Example (Sequoia 440EPx): + ehci@e0000300 { +diff --git a/drivers/usb/host/ehci-platform.c b/drivers/usb/host/ehci-platform.c +index bd7082f2..6fbf32a 100644 +--- a/drivers/usb/host/ehci-platform.c ++++ b/drivers/usb/host/ehci-platform.c +@@ -39,11 +39,12 @@ + + #define DRIVER_DESC "EHCI generic platform driver" + #define EHCI_MAX_CLKS 3 ++#define EHCI_MAX_RESETS 2 + #define hcd_to_ehci_priv(h) ((struct ehci_platform_priv *)hcd_to_ehci(h)->priv) + + struct ehci_platform_priv { + struct clk *clks[EHCI_MAX_CLKS]; +- struct reset_control *rst; ++ struct reset_control *resets[EHCI_MAX_RESETS]; + struct phy **phys; + int num_phys; + bool reset_on_resume; +@@ -149,7 +150,7 @@ static int ehci_platform_probe(struct platform_device *dev) + struct usb_ehci_pdata *pdata = dev_get_platdata(&dev->dev); + struct ehci_platform_priv *priv; + struct ehci_hcd *ehci; +- int err, irq, phy_num, clk = 0; ++ int err, irq, phy_num, clk = 0, rst = 0; + + if (usb_disabled()) + return -ENODEV; +@@ -232,18 +233,24 @@ static int ehci_platform_probe(struct platform_device *dev) + break; + } + } +- } + +- priv->rst = devm_reset_control_get_optional(&dev->dev, NULL); +- if (IS_ERR(priv->rst)) { +- err = PTR_ERR(priv->rst); +- if (err == -EPROBE_DEFER) +- goto err_put_clks; +- priv->rst = NULL; +- } else { +- err = reset_control_deassert(priv->rst); +- if (err) +- goto err_put_clks; ++ for (rst = 0; rst < EHCI_MAX_RESETS; rst++) { ++ priv->resets[rst] = ++ of_reset_control_get_by_index(dev->dev.of_node, ++ rst); ++ if (IS_ERR(priv->resets[rst])) { ++ err = PTR_ERR(priv->resets[rst]); ++ if (err == -EPROBE_DEFER) ++ goto err_reset; ++ priv->resets[rst] = NULL; ++ break; ++ } ++ err = reset_control_deassert_shared(priv->resets[rst]); ++ if (err) { ++ reset_control_put(priv->resets[rst]); ++ goto err_reset; ++ } ++ } + } + + if (pdata->big_endian_desc) +@@ -300,8 +307,10 @@ static int ehci_platform_probe(struct platform_device *dev) + if (pdata->power_off) + pdata->power_off(dev); + err_reset: +- if (priv->rst) +- reset_control_assert(priv->rst); ++ while (--rst >= 0) { ++ reset_control_assert_shared(priv->resets[rst]); ++ reset_control_put(priv->resets[rst]); ++ } + err_put_clks: + while (--clk >= 0) + clk_put(priv->clks[clk]); +@@ -319,15 +328,17 @@ static int ehci_platform_remove(struct platform_device *dev) + struct usb_hcd *hcd = platform_get_drvdata(dev); + struct usb_ehci_pdata *pdata = dev_get_platdata(&dev->dev); + struct ehci_platform_priv *priv = hcd_to_ehci_priv(hcd); +- int clk; ++ int clk, rst; + + usb_remove_hcd(hcd); + + if (pdata->power_off) + pdata->power_off(dev); + +- if (priv->rst) +- reset_control_assert(priv->rst); ++ for (rst = 0; rst < EHCI_MAX_RESETS && priv->resets[rst]; rst++) { ++ reset_control_assert_shared(priv->resets[rst]); ++ reset_control_put(priv->resets[rst]); ++ } + + for (clk = 0; clk < EHCI_MAX_CLKS && priv->clks[clk]; clk++) + clk_put(priv->clks[clk]); diff --git a/target/linux/sunxi/patches-4.4/145-usb-ohci-plat-support-multiple-reset-ctrllines.patch b/target/linux/sunxi/patches-4.4/145-usb-ohci-plat-support-multiple-reset-ctrllines.patch new file mode 100644 index 0000000000..6f536b918d --- /dev/null +++ b/target/linux/sunxi/patches-4.4/145-usb-ohci-plat-support-multiple-reset-ctrllines.patch @@ -0,0 +1,132 @@ +From 5f0c864c1f207dba1db587747a58ec6b362dadf8 Mon Sep 17 00:00:00 2001 +From: Hans de Goede +Date: Sun, 29 Nov 2015 18:44:14 +0100 +Subject: [PATCH] ohci-platform: Add support for controllers with multiple + reset lines + +At least the EHCI/OHCI found on the Allwinnner H3 SoC needs multiple +reset lines, the controller will not initialize while the reset for +its companion is still asserted, which means we need to de-assert +2 resets for the controller to work. + +Signed-off-by: Hans de Goede +--- +Changes in v2: +-New patch in v2 of this patch-set, to complement the identical patch for + the ehci-platform code +--- + Documentation/devicetree/bindings/usb/usb-ohci.txt | 2 +- + drivers/usb/host/ohci-platform.c | 49 +++++++++++++--------- + 2 files changed, 30 insertions(+), 21 deletions(-) + +diff --git a/Documentation/devicetree/bindings/usb/usb-ohci.txt b/Documentation/devicetree/bindings/usb/usb-ohci.txt +index 19233b7..9df4569 100644 +--- a/Documentation/devicetree/bindings/usb/usb-ohci.txt ++++ b/Documentation/devicetree/bindings/usb/usb-ohci.txt +@@ -14,7 +14,7 @@ Optional properties: + - clocks : a list of phandle + clock specifier pairs + - phys : phandle + phy specifier pair + - phy-names : "usb" +-- resets : phandle + reset specifier pair ++- resets : a list of phandle + reset specifier pairs + + Example: + +diff --git a/drivers/usb/host/ohci-platform.c b/drivers/usb/host/ohci-platform.c +index c2669f18..7d8bbc4 100644 +--- a/drivers/usb/host/ohci-platform.c ++++ b/drivers/usb/host/ohci-platform.c +@@ -33,11 +33,12 @@ + + #define DRIVER_DESC "OHCI generic platform driver" + #define OHCI_MAX_CLKS 3 ++#define OHCI_MAX_RESETS 2 + #define hcd_to_ohci_priv(h) ((struct ohci_platform_priv *)hcd_to_ohci(h)->priv) + + struct ohci_platform_priv { + struct clk *clks[OHCI_MAX_CLKS]; +- struct reset_control *rst; ++ struct reset_control *resets[OHCI_MAX_RESETS]; + struct phy **phys; + int num_phys; + }; +@@ -117,7 +118,7 @@ static int ohci_platform_probe(struct platform_device *dev) + struct usb_ohci_pdata *pdata = dev_get_platdata(&dev->dev); + struct ohci_platform_priv *priv; + struct ohci_hcd *ohci; +- int err, irq, phy_num, clk = 0; ++ int err, irq, phy_num, clk = 0, rst = 0; + + if (usb_disabled()) + return -ENODEV; +@@ -195,19 +196,23 @@ static int ohci_platform_probe(struct platform_device *dev) + break; + } + } +- +- } +- +- priv->rst = devm_reset_control_get_optional(&dev->dev, NULL); +- if (IS_ERR(priv->rst)) { +- err = PTR_ERR(priv->rst); +- if (err == -EPROBE_DEFER) +- goto err_put_clks; +- priv->rst = NULL; +- } else { +- err = reset_control_deassert(priv->rst); +- if (err) +- goto err_put_clks; ++ for (rst = 0; rst < OHCI_MAX_RESETS; rst++) { ++ priv->resets[rst] = ++ of_reset_control_get_by_index(dev->dev.of_node, ++ rst); ++ if (IS_ERR(priv->resets[rst])) { ++ err = PTR_ERR(priv->resets[rst]); ++ if (err == -EPROBE_DEFER) ++ goto err_reset; ++ priv->resets[rst] = NULL; ++ break; ++ } ++ err = reset_control_deassert_shared(priv->resets[rst]); ++ if (err) { ++ reset_control_put(priv->resets[rst]); ++ goto err_reset; ++ } ++ } + } + + if (pdata->big_endian_desc) +@@ -265,8 +270,10 @@ static int ohci_platform_probe(struct platform_device *dev) + if (pdata->power_off) + pdata->power_off(dev); + err_reset: +- if (priv->rst) +- reset_control_assert(priv->rst); ++ while (--rst >= 0) { ++ reset_control_assert_shared(priv->resets[rst]); ++ reset_control_put(priv->resets[rst]); ++ } + err_put_clks: + while (--clk >= 0) + clk_put(priv->clks[clk]); +@@ -284,15 +291,17 @@ static int ohci_platform_remove(struct platform_device *dev) + struct usb_hcd *hcd = platform_get_drvdata(dev); + struct usb_ohci_pdata *pdata = dev_get_platdata(&dev->dev); + struct ohci_platform_priv *priv = hcd_to_ohci_priv(hcd); +- int clk; ++ int clk, rst; + + usb_remove_hcd(hcd); + + if (pdata->power_off) + pdata->power_off(dev); + +- if (priv->rst) +- reset_control_assert(priv->rst); ++ for (rst = 0; rst < OHCI_MAX_RESETS && priv->resets[rst]; rst++) { ++ reset_control_assert_shared(priv->resets[rst]); ++ reset_control_put(priv->resets[rst]); ++ } + + for (clk = 0; clk < OHCI_MAX_CLKS && priv->clks[clk]; clk++) + clk_put(priv->clks[clk]); diff --git a/target/linux/sunxi/patches-4.4/150-dt-sun7i-enable-codec-on-pcduino3.patch b/target/linux/sunxi/patches-4.4/150-dt-sun7i-enable-codec-on-pcduino3.patch new file mode 100644 index 0000000000..c0d9660100 --- /dev/null +++ b/target/linux/sunxi/patches-4.4/150-dt-sun7i-enable-codec-on-pcduino3.patch @@ -0,0 +1,29 @@ +From 5296d8ff65298091758aa8d50d00539cd3781042 Mon Sep 17 00:00:00 2001 +From: Jelle van der Waa +Date: Sun, 9 Aug 2015 18:51:22 +0200 +Subject: [PATCH] ARM: dts: sun7i: Enable audio codec on pcDuino + +Enable the on-chip audio codec + +Signed-off-by: Jelle van der Waa +Signed-off-by: Hans de Goede +--- + arch/arm/boot/dts/sun7i-a20-pcduino3.dts | 5 +++++ + 1 file changed, 5 insertions(+) + +diff --git a/arch/arm/boot/dts/sun7i-a20-pcduino3.dts b/arch/arm/boot/dts/sun7i-a20-pcduino3.dts +index 861a4a6..067f365 100644 +--- a/arch/arm/boot/dts/sun7i-a20-pcduino3.dts ++++ b/arch/arm/boot/dts/sun7i-a20-pcduino3.dts +@@ -111,6 +111,11 @@ + allwinner,pins = "PH2"; + }; + ++ ++&codec { ++ status = "okay"; ++}; ++ + &cpu0 { + cpu-supply = <®_dcdc2>; + }; diff --git a/target/linux/sunxi/patches-4.4/200-dt-sun7i-add-lamobo-r1.patch b/target/linux/sunxi/patches-4.4/200-dt-sun7i-add-lamobo-r1.patch new file mode 100644 index 0000000000..dceaea884b --- /dev/null +++ b/target/linux/sunxi/patches-4.4/200-dt-sun7i-add-lamobo-r1.patch @@ -0,0 +1,335 @@ +From 46662c86b453d7098ff22d6112d0481f07d523a1 Mon Sep 17 00:00:00 2001 +From: Jelle de Jong +Date: Sun, 18 Oct 2015 16:34:39 +0200 +Subject: [PATCH] ARM: dts: sun7i: Add dts file for the lamobo-r1 board + +The lamobo-r1 board, sometimes called the BPI-R1 but not labelled as such +on the PCB, is meant as a A20 based router board. As such the board comes +with a built-in switch chip giving it 5 gigabit ethernet boards, and it +has a large empty area on the pcb with mounting holes which will fit a +2.5 inch harddisk. To complete its networking features it has a +Realtek RTL8192CU for WiFi 802.11 b/g/n. + +Signed-off-by: Jelle de Jong +Signed-off-by: Hans de Goede +--- + arch/arm/boot/dts/Makefile | 1 + + arch/arm/boot/dts/sun7i-a20-lamobo-r1.dts | 297 ++++++++++++++++++++++++++++++ + 2 files changed, 298 insertions(+) + create mode 100644 arch/arm/boot/dts/sun7i-a20-lamobo-r1.dts + +diff --git a/arch/arm/boot/dts/Makefile b/arch/arm/boot/dts/Makefile +index cc7309b..6f8deac 100644 +--- a/arch/arm/boot/dts/Makefile ++++ b/arch/arm/boot/dts/Makefile +@@ -639,6 +639,7 @@ dtb-$(CONFIG_MACH_SUN7I) += \ + sun7i-a20-cubietruck.dtb \ + sun7i-a20-hummingbird.dtb \ + sun7i-a20-i12-tvbox.dtb \ ++ sun7i-a20-lamobo-r1.dtb \ + sun7i-a20-m3.dtb \ + sun7i-a20-mk808c.dtb \ + sun7i-a20-olimex-som-evb.dtb \ +diff --git a/arch/arm/boot/dts/sun7i-a20-lamobo-r1.dts b/arch/arm/boot/dts/sun7i-a20-lamobo-r1.dts +new file mode 100644 +index 0000000..975b0b2 +--- /dev/null ++++ b/arch/arm/boot/dts/sun7i-a20-lamobo-r1.dts +@@ -0,0 +1,297 @@ ++/* ++ * Copyright 2015 Jelle de Jong ++ * ++ * 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 file 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 file 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 "sun7i-a20.dtsi" ++#include "sunxi-common-regulators.dtsi" ++ ++#include ++#include ++#include ++ ++/ { ++ model = "Lamobo R1"; ++ compatible = "lamobo,lamobo-r1", "allwinner,sun7i-a20"; ++ ++ aliases { ++ serial0 = &uart0; ++ serial1 = &uart3; ++ serial2 = &uart7; ++ }; ++ ++ chosen { ++ stdout-path = "serial0:115200n8"; ++ }; ++ ++ leds { ++ compatible = "gpio-leds"; ++ pinctrl-names = "default"; ++ pinctrl-0 = <&led_pins_lamobo_r1>; ++ ++ green { ++ label = "lamobo_r1:green:usr"; ++ gpios = <&pio 7 24 GPIO_ACTIVE_HIGH>; ++ }; ++ }; ++ ++ reg_gmac_3v3: gmac-3v3 { ++ compatible = "regulator-fixed"; ++ pinctrl-names = "default"; ++ pinctrl-0 = <&gmac_power_pin_lamobo_r1>; ++ regulator-name = "gmac-3v3"; ++ regulator-min-microvolt = <3300000>; ++ regulator-max-microvolt = <3300000>; ++ startup-delay-us = <100000>; ++ enable-active-high; ++ gpio = <&pio 7 23 GPIO_ACTIVE_HIGH>; /* PH23 */ ++ }; ++}; ++ ++&ahci_pwr_pin_a { ++ allwinner,pins = "PB3"; ++}; ++ ++&ahci { ++ target-supply = <®_ahci_5v>; ++ status = "okay"; ++}; ++ ++&cpu0 { ++ cpu-supply = <®_dcdc2>; ++ operating-points = < ++ /* kHz uV */ ++ 960000 1400000 ++ 912000 1400000 ++ 864000 1350000 ++ 720000 1250000 ++ 528000 1150000 ++ 312000 1100000 ++ 144000 1050000 ++ >; ++}; ++ ++&ehci0 { ++ status = "okay"; ++}; ++ ++&ehci1 { ++ status = "okay"; ++}; ++ ++&gmac { ++ pinctrl-names = "default"; ++ pinctrl-0 = <&gmac_pins_rgmii_a>; ++ phy = <&phy1>; ++ phy-mode = "rgmii"; ++ phy-supply = <®_gmac_3v3>; ++ status = "okay"; ++ ++ phy1: ethernet-phy@1 { ++ reg = <1>; ++ }; ++}; ++ ++&i2c0 { ++ pinctrl-names = "default"; ++ pinctrl-0 = <&i2c0_pins_a>; ++ status = "okay"; ++ ++ axp209: pmic@34 { ++ reg = <0x34>; ++ interrupt-parent = <&nmi_intc>; ++ interrupts = <0 IRQ_TYPE_LEVEL_LOW>; ++ }; ++}; ++ ++&i2c2 { ++ pinctrl-names = "default"; ++ pinctrl-0 = <&i2c2_pins_a>; ++ status = "okay"; ++}; ++ ++&ir0 { ++ pinctrl-names = "default"; ++ pinctrl-0 = <&ir0_rx_pins_a>; ++ status = "okay"; ++}; ++ ++&mmc0 { ++ pinctrl-names = "default"; ++ pinctrl-0 = <&mmc0_pins_a>, <&mmc0_cd_pin_lamobo_r1>; ++ vmmc-supply = <®_vcc3v3>; ++ bus-width = <4>; ++ cd-gpios = <&pio 7 10 GPIO_ACTIVE_HIGH>; /* PH10 */ ++ cd-inverted; ++ status = "okay"; ++}; ++ ++&ohci0 { ++ status = "okay"; ++}; ++ ++&ohci1 { ++ status = "okay"; ++}; ++ ++&otg_sram { ++ status = "okay"; ++}; ++ ++&pio { ++ usb0_id_detect_pin: usb0_id_detect_pin@0 { ++ allwinner,pins = "PH4"; ++ allwinner,function = "gpio_in"; ++ allwinner,drive = ; ++ allwinner,pull = ; ++ }; ++ ++ mmc0_cd_pin_lamobo_r1: mmc0_cd_pin@0 { ++ allwinner,pins = "PH10"; ++ allwinner,function = "gpio_in"; ++ allwinner,drive = ; ++ allwinner,pull = ; ++ }; ++ ++ gmac_power_pin_lamobo_r1: gmac_power_pin@0 { ++ allwinner,pins = "PH23"; ++ allwinner,function = "gpio_out"; ++ allwinner,drive = ; ++ allwinner,pull = ; ++ }; ++ ++ led_pins_lamobo_r1: led_pins@0 { ++ allwinner,pins = "PH24"; ++ allwinner,function = "gpio_out"; ++ allwinner,drive = ; ++ allwinner,pull = ; ++ }; ++}; ++ ++#include "axp209.dtsi" ++ ++®_ahci_5v { ++ gpio = <&pio 1 3 0>; /* PB3 */ ++ status = "okay"; ++}; ++ ++®_dcdc2 { ++ regulator-always-on; ++ regulator-min-microvolt = <1000000>; ++ regulator-max-microvolt = <1400000>; ++ regulator-name = "vdd-cpu"; ++}; ++ ++®_dcdc3 { ++ regulator-always-on; ++ regulator-min-microvolt = <1000000>; ++ regulator-max-microvolt = <1400000>; ++ regulator-name = "vdd-int-dll"; ++}; ++ ++®_ldo1 { ++ regulator-name = "vdd-rtc"; ++}; ++ ++®_ldo2 { ++ regulator-always-on; ++ regulator-min-microvolt = <3000000>; ++ regulator-max-microvolt = <3000000>; ++ regulator-name = "avcc"; ++}; ++ ++®_usb0_vbus { ++ status = "okay"; ++}; ++ ++®_usb1_vbus { ++ status = "okay"; ++}; ++ ++®_usb2_vbus { ++ status = "okay"; ++}; ++ ++&spi0 { ++ pinctrl-names = "default"; ++ pinctrl-0 = <&spi0_pins_a>, ++ <&spi0_cs0_pins_a>, ++ <&spi0_cs1_pins_a>; ++ status = "okay"; ++}; ++ ++&uart0 { ++ pinctrl-names = "default"; ++ pinctrl-0 = <&uart0_pins_a>; ++ status = "okay"; ++}; ++ ++&uart3 { ++ pinctrl-names = "default"; ++ pinctrl-0 = <&uart3_pins_b>; ++ status = "okay"; ++}; ++ ++&uart7 { ++ pinctrl-names = "default"; ++ pinctrl-0 = <&uart7_pins_a>; ++ status = "okay"; ++}; ++ ++&usb_otg { ++ dr_mode = "otg"; ++ status = "okay"; ++}; ++ ++&usb_power_supply { ++ status = "okay"; ++}; ++ ++&usbphy { ++ pinctrl-names = "default"; ++ pinctrl-0 = <&usb0_id_detect_pin>; ++ usb0_id_det-gpio = <&pio 7 4 GPIO_ACTIVE_HIGH>; /* PH4 */ ++ usb0_vbus_power-supply = <&usb_power_supply>; ++ usb0_vbus-supply = <®_usb0_vbus>; ++ usb1_vbus-supply = <®_usb1_vbus>; ++ usb2_vbus-supply = <®_usb2_vbus>; ++ status = "okay"; ++}; -- 2.25.1