sunxi: initial 3.13 support
authorZoltan Herpai <wigyori@uid0.hu>
Wed, 5 Feb 2014 08:42:28 +0000 (08:42 +0000)
committerZoltan Herpai <wigyori@uid0.hu>
Wed, 5 Feb 2014 08:42:28 +0000 (08:42 +0000)
Signed-off-by: Zoltan HERPAI <wigyori@uid0.hu>
SVN-Revision: 39471

92 files changed:
target/linux/sunxi/config-3.13 [new file with mode: 0644]
target/linux/sunxi/patches-3.13/100-clk-composite-determine-rate.patch [new file with mode: 0644]
target/linux/sunxi/patches-3.13/101-fix-off-by-one-masks.patch [new file with mode: 0644]
target/linux/sunxi/patches-3.13/102-clk-factors-clear-vars.patch [new file with mode: 0644]
target/linux/sunxi/patches-3.13/103-sunxi-clk-core-clock-protect.patch [new file with mode: 0644]
target/linux/sunxi/patches-3.13/104-clk-sunxi-fix-memory-leak.patch [new file with mode: 0644]
target/linux/sunxi/patches-3.13/105-reset-add-reset-ctrler.patch [new file with mode: 0644]
target/linux/sunxi/patches-3.13/106-add-Kconfig-for-reset.patch [new file with mode: 0644]
target/linux/sunxi/patches-3.13/107-sunxi-register-a31-reset.patch [new file with mode: 0644]
target/linux/sunxi/patches-3.13/108-sun6i-add-smp-support.patch [new file with mode: 0644]
target/linux/sunxi/patches-3.13/109-dt-sun6i-add-reset-ctrler.patch [new file with mode: 0644]
target/linux/sunxi/patches-3.13/110-sun4i-clkevent-fill-irqfield.patch [new file with mode: 0644]
target/linux/sunxi/patches-3.13/111-sun4i-clksrc-change-cpu-mask.patch [new file with mode: 0644]
target/linux/sunxi/patches-3.13/112-sun4i-clksrc-increase-a-bit-in-clockevent.patch [new file with mode: 0644]
target/linux/sunxi/patches-3.13/113-clk-sunxi-register-factors-clocks.patch [new file with mode: 0644]
target/linux/sunxi/patches-3.13/114-clk-sunxi-clean-magic-number.patch [new file with mode: 0644]
target/linux/sunxi/patches-3.13/115-clk-sunxi_add-gating-pll1.patch [new file with mode: 0644]
target/linux/sunxi/patches-3.13/116-clk-sunxi-add-pll4.patch [new file with mode: 0644]
target/linux/sunxi/patches-3.13/117-clk-sunxi-factors_clk_setup_update.patch [new file with mode: 0644]
target/linux/sunxi/patches-3.13/118-clk-sunxi-add-pll5-pll6.patch [new file with mode: 0644]
target/linux/sunxi/patches-3.13/119-dt-sunxi-add-pll5-pll6.patch [new file with mode: 0644]
target/linux/sunxi/patches-3.13/120-clk-sunxi-mod0.patch [new file with mode: 0644]
target/linux/sunxi/patches-3.13/121-clk-sunxi-better-factor-dt-nodes.patch [new file with mode: 0644]
target/linux/sunxi/patches-3.13/122-1-dt-sun4i-add-mod0.patch [new file with mode: 0644]
target/linux/sunxi/patches-3.13/122-2-dt-sun5i-add-mod0.patch [new file with mode: 0644]
target/linux/sunxi/patches-3.13/122-3-dt-sun7i-add-mod0.patch [new file with mode: 0644]
target/linux/sunxi/patches-3.13/123-clk-sunxi-automatic-reparenting.patch [new file with mode: 0644]
target/linux/sunxi/patches-3.13/124-clk-sunxi-muxable-ahb-clock.patch [new file with mode: 0644]
target/linux/sunxi/patches-3.13/125-dt-sunxi-update-ahb-clock-sun57i.patch [new file with mode: 0644]
target/linux/sunxi/patches-3.13/126-regulator-dont-print-error-when-no-regulator-found.patch [new file with mode: 0644]
target/linux/sunxi/patches-3.13/130-dt-sunxi-add-mbusclk.patch [new file with mode: 0644]
target/linux/sunxi/patches-3.13/131-dt-sunxi-add-emac-aliases.patch [new file with mode: 0644]
target/linux/sunxi/patches-3.13/132-dt-sun7i-update-eth-aliases.patch [new file with mode: 0644]
target/linux/sunxi/patches-3.13/133-dt-sun7i-add-arch-timers.patch [new file with mode: 0644]
target/linux/sunxi/patches-3.13/135-dt-sun5i-a13-add-olinuxino-micro.patch [new file with mode: 0644]
target/linux/sunxi/patches-3.13/140-sun47i-rtc-driver.patch [new file with mode: 0644]
target/linux/sunxi/patches-3.13/141-dt-sun47i-add-rtc.patch [new file with mode: 0644]
target/linux/sunxi/patches-3.13/145-clksrc-add-hstimer.patch [new file with mode: 0644]
target/linux/sunxi/patches-3.13/146-1-dt-sun5i-a10s-add-hstimer.patch [new file with mode: 0644]
target/linux/sunxi/patches-3.13/146-2-dt-sun5i-a13-add-hstimer.patch [new file with mode: 0644]
target/linux/sunxi/patches-3.13/146-3-dt-sun7i-a20-add-hstimer.patch [new file with mode: 0644]
target/linux/sunxi/patches-3.13/150-1-clk-sunxi-implement-mmc-phasectrl.patch [new file with mode: 0644]
target/linux/sunxi/patches-3.13/150-2-clk-sunxi-export-func.patch [new file with mode: 0644]
target/linux/sunxi/patches-3.13/151-pinctrl-sun5i-a13-port-F.patch [new file with mode: 0644]
target/linux/sunxi/patches-3.13/152-sunxi-mmc-add-Kconfig.patch [new file with mode: 0644]
target/linux/sunxi/patches-3.13/153-1-dt-sun4i-add-mmc.patch [new file with mode: 0644]
target/linux/sunxi/patches-3.13/153-2-dt-sun5i-add-mmc.patch [new file with mode: 0644]
target/linux/sunxi/patches-3.13/153-3-dt-sun7i-add-mmc.patch [new file with mode: 0644]
target/linux/sunxi/patches-3.13/154-mmc-update-compat-nodes.patch [new file with mode: 0644]
target/linux/sunxi/patches-3.13/160-ahci-add-pre-start-hook.patch [new file with mode: 0644]
target/linux/sunxi/patches-3.13/161-sunxi-ahci-add-driver.patch [new file with mode: 0644]
target/linux/sunxi/patches-3.13/162-1-dt-sun4i-add-ahci-nodes.patch [new file with mode: 0644]
target/linux/sunxi/patches-3.13/162-2-dt-sun7i-add-ahci-nodes.patch [new file with mode: 0644]
target/linux/sunxi/patches-3.13/170-clk-sunxi-add-support-for-usbclocks.patch [new file with mode: 0644]
target/linux/sunxi/patches-3.13/171-clk-sunxi-add-support-for-sun5i-usbclocks.patch [new file with mode: 0644]
target/linux/sunxi/patches-3.13/172-usb-add-ehci-driver.patch [new file with mode: 0644]
target/linux/sunxi/patches-3.13/173-1-dt-sun4i-add-usbclock-nodes.patch [new file with mode: 0644]
target/linux/sunxi/patches-3.13/173-2-dt-sun4i-add-ehci-bindings.patch [new file with mode: 0644]
target/linux/sunxi/patches-3.13/173-3-dt-sun4i-add-ehci-cubieboard.patch [new file with mode: 0644]
target/linux/sunxi/patches-3.13/173-4-dt-sun4i-add-ehci-a1000.patch [new file with mode: 0644]
target/linux/sunxi/patches-3.13/174-1-dt-sun7i-add-usbclock-nodes.patch [new file with mode: 0644]
target/linux/sunxi/patches-3.13/174-2-dt-sun7i-add-ehci-bindings.patch [new file with mode: 0644]
target/linux/sunxi/patches-3.13/174-3-dt-sun7i-add-ehci-cubieboard2.patch [new file with mode: 0644]
target/linux/sunxi/patches-3.13/174-4-dt-sun7i-add-ehci-olinuxino-a20-micro.patch [new file with mode: 0644]
target/linux/sunxi/patches-3.13/174-5-dt-sun7i-add-ehci-cubietruck.patch [new file with mode: 0644]
target/linux/sunxi/patches-3.13/175-1-dt-sun5i-add-usbclock-nodes.patch [new file with mode: 0644]
target/linux/sunxi/patches-3.13/175-2-dt-sun5i-add-ehci-bindings.patch [new file with mode: 0644]
target/linux/sunxi/patches-3.13/175-3-dt-sun5i-add-ehci-a13.patch [new file with mode: 0644]
target/linux/sunxi/patches-3.13/176-dt-sunxi-update-usb-regulator.patch [new file with mode: 0644]
target/linux/sunxi/patches-3.13/177-dt-sun7i-fix-ehci-irqtypes.patch [new file with mode: 0644]
target/linux/sunxi/patches-3.13/178-sunxi-ehci-fix-resource-check.patch [new file with mode: 0644]
target/linux/sunxi/patches-3.13/180-sunxi-select-PSCI.patch [new file with mode: 0644]
target/linux/sunxi/patches-3.13/190-stmmac-enable-main-clock-when-probing.patch [new file with mode: 0644]
target/linux/sunxi/patches-3.13/191-stmmac-honor-DT-params.patch [new file with mode: 0644]
target/linux/sunxi/patches-3.13/192-stmmac-use-platform-data-with-compat.patch [new file with mode: 0644]
target/linux/sunxi/patches-3.13/193-stmmac-platform-ext-for-a20.patch [new file with mode: 0644]
target/linux/sunxi/patches-3.13/194-dt-sun7i-add-gmac-ctrler.patch [new file with mode: 0644]
target/linux/sunxi/patches-3.13/195-dt-sun7i-add-gmac-pinmuxing.patch [new file with mode: 0644]
target/linux/sunxi/patches-3.13/196-1-dt-sun7i-enable-gmac-cubietruck.patch [new file with mode: 0644]
target/linux/sunxi/patches-3.13/196-2-dt-sun7i-enable-gmac-cubieboard2.patch [new file with mode: 0644]
target/linux/sunxi/patches-3.13/196-3-dt-sun7i-enable-gmac-a20-micro.patch [new file with mode: 0644]
target/linux/sunxi/patches-3.13/200-sun5i-timer-add-support-for-reset-ctrler.patch [new file with mode: 0644]
target/linux/sunxi/patches-3.13/201-reset-add-of_reset_control_get.patch [new file with mode: 0644]
target/linux/sunxi/patches-3.13/210-clk-sunxi-add-a20-output-clk.patch [new file with mode: 0644]
target/linux/sunxi/patches-3.13/211-dt-sun7i-add-external-clk-output.patch [new file with mode: 0644]
target/linux/sunxi/patches-3.13/212-pinctrl-sunxi-add-a20-output-clkpin-funcs.patch [new file with mode: 0644]
target/linux/sunxi/patches-3.13/213-dt-sun7i-add-external-clk-outputs.patch [new file with mode: 0644]
target/linux/sunxi/patches-3.13/230-dt-add-pcduino.patch [new file with mode: 0644]
target/linux/sunxi/patches-3.13/231-dt-add-a10-olinuxino-lime.patch [new file with mode: 0644]
target/linux/sunxi/patches-3.13/232-dt-pcduino-update-mmc-entry.patch [new file with mode: 0644]
target/linux/sunxi/patches-3.13/233-dt-lime-update-mmc-entry.patch [new file with mode: 0644]
target/linux/sunxi/patches-3.13/234-dt-cubietruck-update-mmc-entry.patch [new file with mode: 0644]

diff --git a/target/linux/sunxi/config-3.13 b/target/linux/sunxi/config-3.13
new file mode 100644 (file)
index 0000000..0460b56
--- /dev/null
@@ -0,0 +1,421 @@
+# CONFIG_AHCI_SUNXI is not set
+CONFIG_ALIGNMENT_TRAP=y
+# CONFIG_APM_EMULATION is not set
+CONFIG_ARCH_BINFMT_ELF_RANDOMIZE_PIE=y
+CONFIG_ARCH_HAS_ATOMIC64_DEC_IF_POSITIVE=y
+CONFIG_ARCH_HAS_RESET_CONTROLLER=y
+CONFIG_ARCH_HAS_TICK_BROADCAST=y
+CONFIG_ARCH_HAVE_CUSTOM_GPIO_H=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_NEEDS_CPU_IDLE_COUPLED is not set
+CONFIG_ARCH_NR_GPIO=288
+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_SUSPEND_POSSIBLE=y
+CONFIG_ARCH_USE_CMPXCHG_LOCKREF=y
+CONFIG_ARCH_WANT_GENERAL_HUGETLB=y
+CONFIG_ARCH_WANT_IPC_PARSE_VERSION=y
+CONFIG_ARM=y
+CONFIG_ARM_APPENDED_DTB=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 is not set
+CONFIG_ARM_ERRATA_430973=y
+CONFIG_ARM_ERRATA_720789=y
+CONFIG_ARM_ERRATA_754322=y
+CONFIG_ARM_ERRATA_775420=y
+CONFIG_ARM_GIC=y
+CONFIG_ARM_L1_CACHE_SHIFT=6
+CONFIG_ARM_L1_CACHE_SHIFT_6=y
+# CONFIG_ARM_LPAE is not set
+CONFIG_ARM_NR_BANKS=8
+CONFIG_ARM_PATCH_PHYS_VIRT=y
+CONFIG_ARM_PSCI=y
+CONFIG_ARM_THUMB=y
+# CONFIG_ARM_THUMBEE is not set
+CONFIG_ARM_VIRT_EXT=y
+CONFIG_ATA=y
+CONFIG_ATAGS=y
+CONFIG_AUDIT=y
+# CONFIG_AUDITSYSCALL is not set
+CONFIG_AUDIT_GENERIC=y
+CONFIG_AUTO_ZRELADDR=y
+CONFIG_AVERAGE=y
+CONFIG_BINFMT_MISC=y
+CONFIG_BLK_CGROUP=y
+CONFIG_BLK_DEV_SD=y
+CONFIG_BLK_DEV_SR=y
+CONFIG_BLK_DEV_SR_VENDOR=y
+CONFIG_BOUNCE=y
+CONFIG_BRIDGE_IGMP_SNOOPING=y
+# CONFIG_CACHE_L2X0 is not set
+CONFIG_CFQ_GROUP_IOSCHED=y
+CONFIG_CGROUPS=y
+CONFIG_CGROUP_CPUACCT=y
+CONFIG_CGROUP_DEVICE=y
+CONFIG_CGROUP_FREEZER=y
+# CONFIG_CGROUP_PERF is not set
+# CONFIG_CGROUP_SCHED is not set
+# CONFIG_CHARGER_BQ24190 is not set
+CONFIG_CLKDEV_LOOKUP=y
+CONFIG_CLKSRC_MMIO=y
+CONFIG_CLKSRC_OF=y
+CONFIG_CLONE_BACKWARDS=y
+CONFIG_CMDLINE="console=ttyS0,115200 earlyprintk rootwait root=/dev/mmcblk0p2"
+CONFIG_CMDLINE_FORCE=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_CPUSETS=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_HAS_ASID=y
+# CONFIG_CPU_ICACHE_DISABLE is not set
+CONFIG_CPU_PABRT_V7=y
+CONFIG_CPU_RMAP=y
+CONFIG_CPU_TLB_V7=y
+CONFIG_CPU_V7=y
+CONFIG_CRC16=y
+CONFIG_CRC_T10DIF=y
+CONFIG_CRYPTO_ARC4=y
+CONFIG_CRYPTO_BLKCIPHER=y
+CONFIG_CRYPTO_BLKCIPHER2=y
+CONFIG_CRYPTO_CRC32C=y
+CONFIG_CRYPTO_CRCT10DIF=y
+CONFIG_CRYPTO_HASH=y
+CONFIG_CRYPTO_HASH2=y
+CONFIG_CRYPTO_RNG2=y
+CONFIG_CRYPTO_WORKQUEUE=y
+CONFIG_DCACHE_WORD_ACCESS=y
+# CONFIG_DEBUG_BLK_CGROUP is not set
+CONFIG_DEBUG_BUGVERBOSE=y
+# CONFIG_DEBUG_KERNEL is not set
+CONFIG_DEBUG_LL_INCLUDE="mach/debug-macro.S"
+CONFIG_DEBUG_MEMORY_INIT=y
+# CONFIG_DEBUG_UART_8250 is not set
+# CONFIG_DEBUG_UART_PL01X is not set
+# CONFIG_DEBUG_USER is not set
+CONFIG_DECOMPRESS_BZIP2=y
+CONFIG_DECOMPRESS_GZIP=y
+CONFIG_DECOMPRESS_LZ4=y
+CONFIG_DECOMPRESS_LZMA=y
+CONFIG_DECOMPRESS_LZO=y
+CONFIG_DECOMPRESS_XZ=y
+CONFIG_DEFAULT_CFQ=y
+# CONFIG_DEFAULT_DEADLINE is not set
+CONFIG_DEFAULT_IOSCHED="cfq"
+CONFIG_DIRECT_IO=y
+CONFIG_DMADEVICES=y
+CONFIG_DMA_OF=y
+CONFIG_DNOTIFY=y
+CONFIG_DTC=y
+CONFIG_DUMMY_CONSOLE=y
+CONFIG_DWMAC_SUNXI=y
+# CONFIG_DW_DMAC_CORE is not set
+CONFIG_DYNAMIC_DEBUG=y
+# CONFIG_EEPROM_SUNXI_SID is not set
+CONFIG_ELF_CORE=y
+# CONFIG_EMBEDDED is not set
+CONFIG_ENABLE_MUST_CHECK=y
+# CONFIG_ENABLE_WARN_DEPRECATED is not set
+# CONFIG_EXPERT is not set
+CONFIG_EXT4_FS=y
+CONFIG_FRAME_POINTER=y
+CONFIG_FRAME_WARN=2048
+CONFIG_FREEZER=y
+CONFIG_FS_POSIX_ACL=y
+CONFIG_GARP=y
+CONFIG_GENERIC_ACL=y
+CONFIG_GENERIC_BUG=y
+CONFIG_GENERIC_CLOCKEVENTS=y
+CONFIG_GENERIC_CLOCKEVENTS_BROADCAST=y
+CONFIG_GENERIC_CLOCKEVENTS_BUILD=y
+CONFIG_GENERIC_IDLE_POLL_SETUP=y
+CONFIG_GENERIC_IO=y
+CONFIG_GENERIC_IRQ_CHIP=y
+CONFIG_GENERIC_IRQ_SHOW=y
+CONFIG_GENERIC_NET_UTILS=y
+CONFIG_GENERIC_PCI_IOMAP=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_GPIOLIB=y
+CONFIG_GPIO_DEVRES=y
+# CONFIG_HAMRADIO is not set
+CONFIG_HARDIRQS_SW_RESEND=y
+CONFIG_HAS_DMA=y
+CONFIG_HAS_IOMEM=y
+CONFIG_HAS_IOPORT=y
+# CONFIG_HAVE_64BIT_ALIGNED_ACCESS is not set
+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_BOOTMEM_INFO_NODE is not set
+CONFIG_HAVE_BPF_JIT=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_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_NET_DSA=y
+CONFIG_HAVE_OPROFILE=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 is not set
+CONFIG_HW_CONSOLE=y
+CONFIG_HZ_FIXED=0
+CONFIG_I2C=y
+CONFIG_I2C_BOARDINFO=y
+CONFIG_I2C_MUX=y
+# CONFIG_I2C_MUX_GPIO is not set
+# CONFIG_I2C_MUX_PCA9541 is not set
+# CONFIG_I2C_MUX_PCA954x is not set
+CONFIG_I2C_MUX_PINCTRL=y
+CONFIG_I2C_MV64XXX=y
+CONFIG_IKCONFIG=y
+CONFIG_IKCONFIG_PROC=y
+CONFIG_INITRAMFS_SOURCE=""
+CONFIG_INPUT=y
+# CONFIG_INPUT_MISC is not set
+CONFIG_INPUT_MOUSEDEV=y
+CONFIG_INPUT_MOUSEDEV_PSAUX=y
+CONFIG_INPUT_MOUSEDEV_SCREEN_X=1024
+CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768
+CONFIG_IOSCHED_CFQ=y
+CONFIG_IPC_NS=y
+# CONFIG_IP_ADVANCED_ROUTER is not set
+CONFIG_IP_PNP=y
+# CONFIG_IP_PNP_BOOTP is not set
+CONFIG_IP_PNP_DHCP=y
+# CONFIG_IP_PNP_RARP is not set
+CONFIG_IRQCHIP=y
+CONFIG_IRQ_DOMAIN=y
+CONFIG_IRQ_FORCED_THREADING=y
+CONFIG_IRQ_WORK=y
+# CONFIG_JFFS2_CMODE_PRIORITY is not set
+CONFIG_KALLSYMS=y
+CONFIG_KERNEL_GZIP=y
+# CONFIG_KERNEL_XZ is not set
+CONFIG_KSM=y
+CONFIG_KTIME_SCALAR=y
+CONFIG_LEDS_GPIO=y
+# CONFIG_LEDS_REGULATOR is not set
+CONFIG_LEGACY_PTYS=y
+CONFIG_LEGACY_PTY_COUNT=256
+CONFIG_LOG_BUF_SHIFT=19
+CONFIG_LZ4_DECOMPRESS=y
+CONFIG_LZO_DECOMPRESS=y
+CONFIG_MAGIC_SYSRQ=y
+CONFIG_MDIO_BOARDINFO=y
+CONFIG_MDIO_SUN4I=y
+# CONFIG_MEMCG is not set
+CONFIG_MIGRATION=y
+CONFIG_MMC=y
+CONFIG_MMC_BLOCK=y
+# CONFIG_MMC_BLOCK_BOUNCE is not set
+CONFIG_MMC_SUNXI=y
+CONFIG_MMC_UNSAFE_RESUME=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 is not set
+# CONFIG_NETPRIO_CGROUP is not set
+# CONFIG_NET_CLS_CGROUP is not set
+CONFIG_NET_FLOW_LIMIT=y
+CONFIG_NET_NS=y
+CONFIG_NET_RX_BUSY_POLL=y
+CONFIG_NET_VENDOR_ALLWINNER=y
+CONFIG_NLS=y
+CONFIG_NO_HZ=y
+CONFIG_NO_HZ_COMMON=y
+CONFIG_NO_HZ_IDLE=y
+CONFIG_NR_CPUS=4
+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_OLD_SIGACTION=y
+CONFIG_OLD_SIGSUSPEND3=y
+CONFIG_PAGEFLAGS_EXTENDED=y
+CONFIG_PAGE_OFFSET=0xC0000000
+# CONFIG_PARTITION_ADVANCED is not set
+# CONFIG_PCI_SYSCALL is not set
+CONFIG_PERF_EVENTS=y
+CONFIG_PERF_USE_VMALLOC=y
+CONFIG_PHYLIB=y
+CONFIG_PID_NS=y
+CONFIG_PINCTRL=y
+# CONFIG_PINCTRL_SINGLE is not set
+CONFIG_PINCTRL_SUNXI=y
+CONFIG_PM=y
+CONFIG_PM_CLK=y
+# CONFIG_PM_DEBUG is not set
+CONFIG_PM_RUNTIME=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_PRINT_QUOTA_WARNING is not set
+CONFIG_PROC_EVENTS=y
+CONFIG_PROC_PAGE_MONITOR=y
+CONFIG_PROC_PID_CPUSET=y
+CONFIG_PTP_1588_CLOCK=y
+# CONFIG_QFMT_V1 is not set
+# CONFIG_QFMT_V2 is not set
+CONFIG_QUOTA=y
+CONFIG_QUOTACTL=y
+CONFIG_QUOTA_NETLINK_INTERFACE=y
+# CONFIG_RCU_BOOST is not set
+CONFIG_RCU_CPU_STALL_VERBOSE=y
+CONFIG_RCU_STALL_COMMON=y
+CONFIG_RD_BZIP2=y
+CONFIG_RD_GZIP=y
+CONFIG_RD_LZ4=y
+CONFIG_RD_LZMA=y
+CONFIG_RD_LZO=y
+CONFIG_RD_XZ=y
+CONFIG_REGULATOR=y
+# CONFIG_REGULATOR_DEBUG is not set
+CONFIG_REGULATOR_FIXED_VOLTAGE=y
+# CONFIG_REGULATOR_USERSPACE_CONSUMER is not set
+CONFIG_RELAY=y
+CONFIG_RESET_CONTROLLER=y
+CONFIG_RESOURCE_COUNTERS=y
+# CONFIG_RFKILL_REGULATOR is not set
+CONFIG_RFS_ACCEL=y
+CONFIG_RPS=y
+CONFIG_SATA_AHCI_PLATFORM=y
+# CONFIG_SATA_RCAR is not set
+CONFIG_SCHED_HRTICK=y
+CONFIG_SCSI=y
+CONFIG_SECURITYFS=y
+CONFIG_SERIAL_8250_DW=y
+CONFIG_SERIAL_8250_NR_UARTS=8
+CONFIG_SERIAL_8250_RUNTIME_UARTS=8
+CONFIG_SERIAL_8250_SYSRQ=y
+CONFIG_SERIO=y
+# CONFIG_SERIO_APBPS2 is not set
+# CONFIG_SERIO_OLPC_APSP is not set
+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_SPARSE_IRQ=y
+# CONFIG_STAGING is not set
+# CONFIG_STMMAC_DA is not set
+# CONFIG_STMMAC_DEBUG_FS is not set
+CONFIG_STMMAC_ETH=y
+CONFIG_STMMAC_PLATFORM=y
+CONFIG_STOP_MACHINE=y
+CONFIG_STRICT_DEVMEM=y
+# CONFIG_SUN4I_EMAC is not set
+CONFIG_SUN4I_TIMER=y
+CONFIG_SUN5I_HSTIMER=y
+CONFIG_SUNXI_WATCHDOG=y
+CONFIG_SWP_EMULATE=y
+CONFIG_SYS_SUPPORTS_APM_EMULATION=y
+CONFIG_TASKSTATS=y
+CONFIG_TASK_DELAY_ACCT=y
+CONFIG_TASK_IO_ACCOUNTING=y
+CONFIG_TASK_XACCT=y
+# CONFIG_TCP_CONG_ADVANCED is not set
+# CONFIG_THUMB2_KERNEL is not set
+CONFIG_TICK_CPU_ACCOUNTING=y
+CONFIG_TMPFS_POSIX_ACL=y
+CONFIG_TREE_PREEMPT_RCU=y
+CONFIG_UEVENT_HELPER_PATH=""
+CONFIG_UID16=y
+CONFIG_UNCOMPRESS_INCLUDE="debug/uncompress.h"
+CONFIG_UNINLINE_SPIN_UNLOCK=y
+CONFIG_USB=y
+CONFIG_USB_ANNOUNCE_NEW_DEVICES=y
+CONFIG_USB_COMMON=y
+CONFIG_USB_DEBUG=y
+CONFIG_USB_EHCI_HCD=y
+# CONFIG_USB_EHCI_HCD_PLATFORM is not set
+CONFIG_USB_STORAGE=y
+CONFIG_USB_SUNXI_EHCI=y
+CONFIG_USB_SUPPORT=y
+# CONFIG_USER_NS is not set
+CONFIG_USE_OF=y
+CONFIG_UTS_NS=y
+CONFIG_VECTORS_BASE=0xffff0000
+CONFIG_VFP=y
+CONFIG_VFPv3=y
+CONFIG_VLAN_8021Q_GVRP=y
+CONFIG_VM_EVENT_COUNTERS=y
+CONFIG_VT=y
+CONFIG_VT_CONSOLE=y
+CONFIG_VT_HW_CONSOLE_BINDING=y
+CONFIG_WATCHDOG_CORE=y
+# CONFIG_XEN is not set
+CONFIG_XFRM_ALGO=y
+CONFIG_XFRM_USER=y
+CONFIG_XPS=y
+CONFIG_XZ_DEC_ARM=y
+CONFIG_XZ_DEC_ARMTHUMB=y
+CONFIG_XZ_DEC_BCJ=y
+CONFIG_ZBOOT_ROM_BSS=0
+CONFIG_ZBOOT_ROM_TEXT=0
+# CONFIG_ZBUD is not set
+CONFIG_ZLIB_INFLATE=y
+CONFIG_ZONE_DMA_FLAG=0
diff --git a/target/linux/sunxi/patches-3.13/100-clk-composite-determine-rate.patch b/target/linux/sunxi/patches-3.13/100-clk-composite-determine-rate.patch
new file mode 100644 (file)
index 0000000..6abbcbe
--- /dev/null
@@ -0,0 +1,75 @@
+From a968e9dc5983d258a4aa7e496d58c92e9e4cf670 Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?Emilio=20L=C3=B3pez?= <emilio@elopez.com.ar>
+Date: Sat, 14 Sep 2013 21:37:59 -0300
+Subject: [PATCH] clk: composite: .determine_rate support
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+This commit adds .determine_rate support to the composite clock. It will
+use the .determine_rate callback from the rate component if available,
+and fall back on the mux component otherwise. This allows composite
+clocks to enjoy the benefits of automatic clock reparenting.
+
+Signed-off-by: Emilio López <emilio@elopez.com.ar>
+Signed-off-by: Maxime Ripard <maxime.ripard@free-electrons.com>
+---
+ drivers/clk/clk-composite.c | 28 ++++++++++++++++++++++++++++
+ 1 file changed, 28 insertions(+)
+
+diff --git a/drivers/clk/clk-composite.c b/drivers/clk/clk-composite.c
+index a33f46f..753d0b7 100644
+--- a/drivers/clk/clk-composite.c
++++ b/drivers/clk/clk-composite.c
+@@ -55,6 +55,30 @@ static unsigned long clk_composite_recalc_rate(struct clk_hw *hw,
+       return rate_ops->recalc_rate(rate_hw, parent_rate);
+ }
++static long clk_composite_determine_rate(struct clk_hw *hw, unsigned long rate,
++                                      unsigned long *best_parent_rate,
++                                      struct clk **best_parent_p)
++{
++      struct clk_composite *composite = to_clk_composite(hw);
++      const struct clk_ops *rate_ops = composite->rate_ops;
++      const struct clk_ops *mux_ops = composite->mux_ops;
++      struct clk_hw *rate_hw = composite->rate_hw;
++      struct clk_hw *mux_hw = composite->mux_hw;
++
++      if (rate_hw && rate_ops && rate_ops->determine_rate) {
++              rate_hw->clk = hw->clk;
++              return rate_ops->determine_rate(rate_hw, rate, best_parent_rate,
++                                              best_parent_p);
++      } else if (mux_hw && mux_ops && mux_ops->determine_rate) {
++              mux_hw->clk = hw->clk;
++              return mux_ops->determine_rate(rate_hw, rate, best_parent_rate,
++                                             best_parent_p);
++      } else {
++              pr_err("clk: clk_composite_determine_rate function called, but no mux or rate callback set!\n");
++              return 0;
++      }
++}
++
+ static long clk_composite_round_rate(struct clk_hw *hw, unsigned long rate,
+                                 unsigned long *prate)
+ {
+@@ -147,6 +171,8 @@ struct clk *clk_register_composite(struct device *dev, const char *name,
+               composite->mux_ops = mux_ops;
+               clk_composite_ops->get_parent = clk_composite_get_parent;
+               clk_composite_ops->set_parent = clk_composite_set_parent;
++              if (mux_ops->determine_rate)
++                      clk_composite_ops->determine_rate = clk_composite_determine_rate;
+       }
+       if (rate_hw && rate_ops) {
+@@ -170,6 +196,8 @@ struct clk *clk_register_composite(struct device *dev, const char *name,
+               composite->rate_hw = rate_hw;
+               composite->rate_ops = rate_ops;
+               clk_composite_ops->recalc_rate = clk_composite_recalc_rate;
++              if (rate_ops->determine_rate)
++                      clk_composite_ops->determine_rate = clk_composite_determine_rate;
+       }
+       if (gate_hw && gate_ops) {
+-- 
+1.8.5.1
+
diff --git a/target/linux/sunxi/patches-3.13/101-fix-off-by-one-masks.patch b/target/linux/sunxi/patches-3.13/101-fix-off-by-one-masks.patch
new file mode 100644 (file)
index 0000000..4f04d54
--- /dev/null
@@ -0,0 +1,34 @@
+From b3cb099f8b0cbe56fcfbb4fb9c7cce48afff41f0 Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?Emilio=20L=C3=B3pez?= <emilio@elopez.com.ar>
+Date: Fri, 20 Sep 2013 22:03:10 -0300
+Subject: [PATCH] clk: sunxi: factors: fix off-by-one masks
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+The previous code would generate one bit too long masks, and was
+needlessly complicated. This patch replaces it by simpler code that can
+generate the masks correctly.
+
+Signed-off-by: Emilio López <emilio@elopez.com.ar>
+Signed-off-by: Maxime Ripard <maxime.ripard@free-electrons.com>
+---
+ drivers/clk/sunxi/clk-factors.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/clk/sunxi/clk-factors.c b/drivers/clk/sunxi/clk-factors.c
+index 88523f9..5687ac9 100644
+--- a/drivers/clk/sunxi/clk-factors.c
++++ b/drivers/clk/sunxi/clk-factors.c
+@@ -40,7 +40,7 @@ struct clk_factors {
+ #define to_clk_factors(_hw) container_of(_hw, struct clk_factors, hw)
+-#define SETMASK(len, pos)             (((-1U) >> (31-len))  << (pos))
++#define SETMASK(len, pos)             (((1U << (len)) - 1) << (pos))
+ #define CLRMASK(len, pos)             (~(SETMASK(len, pos)))
+ #define FACTOR_GET(bit, len, reg)     (((reg) & SETMASK(len, bit)) >> (bit))
+-- 
+1.8.5.1
+
diff --git a/target/linux/sunxi/patches-3.13/102-clk-factors-clear-vars.patch b/target/linux/sunxi/patches-3.13/102-clk-factors-clear-vars.patch
new file mode 100644 (file)
index 0000000..6254e1b
--- /dev/null
@@ -0,0 +1,32 @@
+From 789bea92aba0256a7f5309992327df8729333750 Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?Emilio=20L=C3=B3pez?= <emilio@elopez.com.ar>
+Date: Fri, 20 Sep 2013 22:03:11 -0300
+Subject: [PATCH] clk: sunxi: factors: clear variables before using them
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+Random bits may get into our factors if we don't clear n, k, m and p.
+
+Signed-off-by: Emilio López <emilio@elopez.com.ar>
+Signed-off-by: Maxime Ripard <maxime.ripard@free-electrons.com>
+---
+ drivers/clk/sunxi/clk-factors.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/clk/sunxi/clk-factors.c b/drivers/clk/sunxi/clk-factors.c
+index 5687ac9..f05207a 100644
+--- a/drivers/clk/sunxi/clk-factors.c
++++ b/drivers/clk/sunxi/clk-factors.c
+@@ -88,7 +88,7 @@ static long clk_factors_round_rate(struct clk_hw *hw, unsigned long rate,
+ static int clk_factors_set_rate(struct clk_hw *hw, unsigned long rate,
+                               unsigned long parent_rate)
+ {
+-      u8 n, k, m, p;
++      u8 n = 0, k = 0, m = 0, p = 0;
+       u32 reg;
+       struct clk_factors *factors = to_clk_factors(hw);
+       struct clk_factors_config *config = factors->config;
+-- 
+1.8.5.1
+
diff --git a/target/linux/sunxi/patches-3.13/103-sunxi-clk-core-clock-protect.patch b/target/linux/sunxi/patches-3.13/103-sunxi-clk-core-clock-protect.patch
new file mode 100644 (file)
index 0000000..a2a430d
--- /dev/null
@@ -0,0 +1,71 @@
+From 7df19a0adca7806e081479eecb07365652c26ef5 Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?Emilio=20L=C3=B3pez?= <emilio@elopez.com.ar>
+Date: Fri, 20 Sep 2013 22:03:12 -0300
+Subject: [PATCH] clk: sunxi: protect core clocks from accidental shutdown
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+Some important clocks may get disabled as a side effect of another clock
+being disabled, because they have no consumers. This patch implements a
+mechanism so those clocks can be claimed by the driver and therefore
+remain enabled at all times.
+
+Signed-off-by: Emilio López <emilio@elopez.com.ar>
+Signed-off-by: Maxime Ripard <maxime.ripard@free-electrons.com>
+
+Conflicts:
+       drivers/clk/sunxi/clk-sunxi.c
+---
+ drivers/clk/sunxi/clk-sunxi.c | 28 ++++++++++++++++++++++++++++
+ 1 file changed, 28 insertions(+)
+
+diff --git a/drivers/clk/sunxi/clk-sunxi.c b/drivers/clk/sunxi/clk-sunxi.c
+index 9bbd035..8fc1375 100644
+--- a/drivers/clk/sunxi/clk-sunxi.c
++++ b/drivers/clk/sunxi/clk-sunxi.c
+@@ -616,6 +616,31 @@ static void __init of_sunxi_table_clock_setup(const struct of_device_id *clk_mat
+       }
+ }
++/**
++ * System clock protection
++ *
++ * By enabling these critical clocks, we prevent their accidental gating
++ * by the framework
++ */
++static void __init sunxi_clock_protect(void)
++{
++      struct clk *clk;
++
++      /* memory bus clock - sun5i+ */
++      clk = clk_get(NULL, "mbus");
++      if (!IS_ERR(clk)) {
++              clk_prepare_enable(clk);
++              clk_put(clk);
++      }
++
++      /* DDR clock - sun4i+ */
++      clk = clk_get(NULL, "pll5_ddr");
++      if (!IS_ERR(clk)) {
++              clk_prepare_enable(clk);
++              clk_put(clk);
++      }
++}
++
+ static void __init sunxi_init_clocks(struct device_node *np)
+ {
+       /* Register factor clocks */
+@@ -629,6 +654,9 @@ static void __init sunxi_init_clocks(struct device_node *np)
+       /* Register gate clocks */
+       of_sunxi_table_clock_setup(clk_gates_match, sunxi_gates_clk_setup);
++
++      /* Enable core system clocks */
++      sunxi_clock_protect();
+ }
+ CLK_OF_DECLARE(sun4i_a10_clk_init, "allwinner,sun4i-a10", sunxi_init_clocks);
+ CLK_OF_DECLARE(sun5i_a10s_clk_init, "allwinner,sun5i-a10s", sunxi_init_clocks);
+-- 
+1.8.5.1
+
diff --git a/target/linux/sunxi/patches-3.13/104-clk-sunxi-fix-memory-leak.patch b/target/linux/sunxi/patches-3.13/104-clk-sunxi-fix-memory-leak.patch
new file mode 100644 (file)
index 0000000..99b0db8
--- /dev/null
@@ -0,0 +1,68 @@
+From 9dc8189536f4c59bb7ad8c736021cefc1488bf74 Mon Sep 17 00:00:00 2001
+From: "Victor N. Ramos Mello" <victornrm@gmail.com>
+Date: Fri, 18 Oct 2013 20:27:51 -0300
+Subject: [PATCH] drivers: clk: sunxi: Fix memory leakage in clk-sunxi.c
+
+Fix a possible memory leak in sun4i_osc_clk_setup().
+Moved clock-frequency check to save superfluous allocation.
+
+Signed-off-by: Victor N. Ramos Mello <victornrm@gmail.com>
+Signed-off-by: Maxime Ripard <maxime.ripard@free-electrons.com>
+---
+ drivers/clk/sunxi/clk-sunxi.c | 28 +++++++++++++++++-----------
+ 1 file changed, 17 insertions(+), 11 deletions(-)
+
+diff --git a/drivers/clk/sunxi/clk-sunxi.c b/drivers/clk/sunxi/clk-sunxi.c
+index 8fc1375..492ef0e 100644
+--- a/drivers/clk/sunxi/clk-sunxi.c
++++ b/drivers/clk/sunxi/clk-sunxi.c
+@@ -37,18 +37,16 @@ static void __init sun4i_osc_clk_setup(struct device_node *node)
+       const char *clk_name = node->name;
+       u32 rate;
++      if (of_property_read_u32(node, "clock-frequency", &rate))
++              return;
++
+       /* allocate fixed-rate and gate clock structs */
+       fixed = kzalloc(sizeof(struct clk_fixed_rate), GFP_KERNEL);
+       if (!fixed)
+               return;
+       gate = kzalloc(sizeof(struct clk_gate), GFP_KERNEL);
+-      if (!gate) {
+-              kfree(fixed);
+-              return;
+-      }
+-
+-      if (of_property_read_u32(node, "clock-frequency", &rate))
+-              return;
++      if (!gate)
++              goto err_free_fixed;
+       /* set up gate and fixed rate properties */
+       gate->reg = of_iomap(node, 0);
+@@ -63,10 +61,18 @@ static void __init sun4i_osc_clk_setup(struct device_node *node)
+                       &gate->hw, &clk_gate_ops,
+                       CLK_IS_ROOT);
+-      if (!IS_ERR(clk)) {
+-              of_clk_add_provider(node, of_clk_src_simple_get, clk);
+-              clk_register_clkdev(clk, clk_name, NULL);
+-      }
++      if (IS_ERR(clk))
++              goto err_free_gate;
++
++      of_clk_add_provider(node, of_clk_src_simple_get, clk);
++      clk_register_clkdev(clk, clk_name, NULL);
++
++      return;
++
++err_free_gate:
++      kfree(gate);
++err_free_fixed:
++      kfree(fixed);
+ }
+ CLK_OF_DECLARE(sun4i_osc, "allwinner,sun4i-osc-clk", sun4i_osc_clk_setup);
+-- 
+1.8.5.1
+
diff --git a/target/linux/sunxi/patches-3.13/105-reset-add-reset-ctrler.patch b/target/linux/sunxi/patches-3.13/105-reset-add-reset-ctrler.patch
new file mode 100644 (file)
index 0000000..38c8f75
--- /dev/null
@@ -0,0 +1,214 @@
+From 8015cea648c452bbfe0fc820dcb1185beaeb8736 Mon Sep 17 00:00:00 2001
+From: Maxime Ripard <maxime.ripard@free-electrons.com>
+Date: Tue, 24 Sep 2013 11:07:43 +0300
+Subject: [PATCH] reset: Add Allwinner SoCs Reset Controller Driver
+
+The Allwinner A31 and most of the other Allwinner SoCs have an IP
+maintaining a few other IPs in the SoC in reset by default. Among these
+IPs are the A31's High Speed Timers, hence why we can't use the regular
+driver construct in every cases, and need to call the registering
+function directly during machine initialisation.
+
+Apart from this, the implementation is fairly straightforward, and could
+easily be moved to a generic MMIO-based reset controller driver if the
+need ever arise.
+
+Signed-off-by: Maxime Ripard <maxime.ripard@free-electrons.com>
+Acked-by: Philipp Zabel <p.zabel@pengutronix.de>
+---
+ drivers/reset/Makefile      |   1 +
+ drivers/reset/reset-sunxi.c | 175 ++++++++++++++++++++++++++++++++++++++++++++
+ 2 files changed, 176 insertions(+)
+ create mode 100644 drivers/reset/reset-sunxi.c
+
+diff --git a/drivers/reset/Makefile b/drivers/reset/Makefile
+index 1e2d83f..cc29832 100644
+--- a/drivers/reset/Makefile
++++ b/drivers/reset/Makefile
+@@ -1 +1,2 @@
+ obj-$(CONFIG_RESET_CONTROLLER) += core.o
++obj-$(CONFIG_ARCH_SUNXI) += reset-sunxi.o
+diff --git a/drivers/reset/reset-sunxi.c b/drivers/reset/reset-sunxi.c
+new file mode 100644
+index 0000000..695bd34
+--- /dev/null
++++ b/drivers/reset/reset-sunxi.c
+@@ -0,0 +1,175 @@
++/*
++ * Allwinner SoCs Reset Controller driver
++ *
++ * Copyright 2013 Maxime Ripard
++ *
++ * Maxime Ripard <maxime.ripard@free-electrons.com>
++ *
++ * This program is free software; you can redistribute it and/or modify
++ * it under the terms of the GNU General Public License as published by
++ * the Free Software Foundation; either version 2 of the License, or
++ * (at your option) any later version.
++ */
++
++#include <linux/err.h>
++#include <linux/io.h>
++#include <linux/module.h>
++#include <linux/of.h>
++#include <linux/of_address.h>
++#include <linux/platform_device.h>
++#include <linux/reset-controller.h>
++#include <linux/slab.h>
++#include <linux/spinlock.h>
++#include <linux/types.h>
++
++struct sunxi_reset_data {
++      spinlock_t                      lock;
++      void __iomem                    *membase;
++      struct reset_controller_dev     rcdev;
++};
++
++static int sunxi_reset_assert(struct reset_controller_dev *rcdev,
++                            unsigned long id)
++{
++      struct sunxi_reset_data *data = container_of(rcdev,
++                                                   struct sunxi_reset_data,
++                                                   rcdev);
++      int bank = id / BITS_PER_LONG;
++      int offset = id % BITS_PER_LONG;
++      unsigned long flags;
++      u32 reg;
++
++      spin_lock_irqsave(&data->lock, flags);
++
++      reg = readl(data->membase + (bank * 4));
++      writel(reg & ~BIT(offset), data->membase + (bank * 4));
++
++      spin_unlock_irqrestore(&data->lock, flags);
++
++      return 0;
++}
++
++static int sunxi_reset_deassert(struct reset_controller_dev *rcdev,
++                              unsigned long id)
++{
++      struct sunxi_reset_data *data = container_of(rcdev,
++                                                   struct sunxi_reset_data,
++                                                   rcdev);
++      int bank = id / BITS_PER_LONG;
++      int offset = id % BITS_PER_LONG;
++      unsigned long flags;
++      u32 reg;
++
++      spin_lock_irqsave(&data->lock, flags);
++
++      reg = readl(data->membase + (bank * 4));
++      writel(reg | BIT(offset), data->membase + (bank * 4));
++
++      spin_unlock_irqrestore(&data->lock, flags);
++
++      return 0;
++}
++
++static struct reset_control_ops sunxi_reset_ops = {
++      .assert         = sunxi_reset_assert,
++      .deassert       = sunxi_reset_deassert,
++};
++
++static int sunxi_reset_init(struct device_node *np)
++{
++      struct sunxi_reset_data *data;
++      struct resource res;
++      resource_size_t size;
++      int ret;
++
++      data = kzalloc(sizeof(*data), GFP_KERNEL);
++      if (!data)
++              return -ENOMEM;
++
++      ret = of_address_to_resource(np, 0, &res);
++      if (ret)
++              goto err_alloc;
++
++      size = resource_size(&res);
++      if (!request_mem_region(res.start, size, np->name)) {
++              ret = -EBUSY;
++              goto err_alloc;
++      }
++
++      data->membase = ioremap(res.start, size);
++      if (!data->membase) {
++              ret = -ENOMEM;
++              goto err_alloc;
++      }
++
++      data->rcdev.owner = THIS_MODULE;
++      data->rcdev.nr_resets = size * 32;
++      data->rcdev.ops = &sunxi_reset_ops;
++      data->rcdev.of_node = np;
++      reset_controller_register(&data->rcdev);
++
++      return 0;
++
++err_alloc:
++      kfree(data);
++      return ret;
++};
++
++/*
++ * These are the reset controller we need to initialize early on in
++ * our system, before we can even think of using a regular device
++ * driver for it.
++ */
++static const struct of_device_id sunxi_early_reset_dt_ids[] __initdata = {
++      { .compatible = "allwinner,sun6i-a31-ahb1-reset", },
++      { /* sentinel */ },
++};
++
++void __init sun6i_reset_init(void)
++{
++      struct device_node *np;
++
++      for_each_matching_node(np, sunxi_early_reset_dt_ids)
++              sunxi_reset_init(np);
++}
++
++/*
++ * And these are the controllers we can register through the regular
++ * device model.
++ */
++static const struct of_device_id sunxi_reset_dt_ids[] = {
++       { .compatible = "allwinner,sun6i-a31-clock-reset", },
++       { /* sentinel */ },
++};
++MODULE_DEVICE_TABLE(of, sunxi_reset_dt_ids);
++
++static int sunxi_reset_probe(struct platform_device *pdev)
++{
++      return sunxi_reset_init(pdev->dev.of_node);
++}
++
++static int sunxi_reset_remove(struct platform_device *pdev)
++{
++      struct sunxi_reset_data *data = platform_get_drvdata(pdev);
++
++      reset_controller_unregister(&data->rcdev);
++      iounmap(data->membase);
++      kfree(data);
++
++      return 0;
++}
++
++static struct platform_driver sunxi_reset_driver = {
++      .probe  = sunxi_reset_probe,
++      .remove = sunxi_reset_remove,
++      .driver = {
++              .name           = "sunxi-reset",
++              .owner          = THIS_MODULE,
++              .of_match_table = sunxi_reset_dt_ids,
++      },
++};
++module_platform_driver(sunxi_reset_driver);
++
++MODULE_AUTHOR("Maxime Ripard <maxime.ripard@free-electrons.com");
++MODULE_DESCRIPTION("Allwinner SoCs Reset Controller Driver");
++MODULE_LICENSE("GPL");
+-- 
+1.8.5.1
+
diff --git a/target/linux/sunxi/patches-3.13/106-add-Kconfig-for-reset.patch b/target/linux/sunxi/patches-3.13/106-add-Kconfig-for-reset.patch
new file mode 100644 (file)
index 0000000..ae2a504
--- /dev/null
@@ -0,0 +1,28 @@
+From 73f948fb57f489ed8252fa8480575c91f027200d Mon Sep 17 00:00:00 2001
+From: Maxime Ripard <maxime.ripard@free-electrons.com>
+Date: Tue, 24 Sep 2013 11:09:55 +0300
+Subject: [PATCH] ARM: sunxi: Select ARCH_HAS_RESET_CONTROLLER
+
+The A31 has a reset controller, and we have to select this option to
+have access to the reset controller framework.
+
+Signed-off-by: Maxime Ripard <maxime.ripard@free-electrons.com>
+Acked-by: Philipp Zabel <p.zabel@pengutronix.de>
+---
+ arch/arm/mach-sunxi/Kconfig | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/arch/arm/mach-sunxi/Kconfig b/arch/arm/mach-sunxi/Kconfig
+index c9e72c8..e3457b9 100644
+--- a/arch/arm/mach-sunxi/Kconfig
++++ b/arch/arm/mach-sunxi/Kconfig
+@@ -1,5 +1,6 @@
+ config ARCH_SUNXI
+       bool "Allwinner A1X SOCs" if ARCH_MULTI_V7
++      select ARCH_HAS_RESET_CONTROLLER
+       select ARCH_REQUIRE_GPIOLIB
+       select ARM_GIC
+       select CLKSRC_MMIO
+-- 
+1.8.5.1
+
diff --git a/target/linux/sunxi/patches-3.13/107-sunxi-register-a31-reset.patch b/target/linux/sunxi/patches-3.13/107-sunxi-register-a31-reset.patch
new file mode 100644 (file)
index 0000000..b0e98d7
--- /dev/null
@@ -0,0 +1,50 @@
+From dae0e37c2df466f5eb6459d05f392e86b4236666 Mon Sep 17 00:00:00 2001
+From: Maxime Ripard <maxime.ripard@free-electrons.com>
+Date: Sat, 5 Oct 2013 14:53:48 +0200
+Subject: [PATCH] ARM: sunxi: Register the A31 reset IP in init_time
+
+The A31 has a reset IP that maintains a few other IPs in reset by
+default. Among these IPs are the UARTs, and most notably the timers. We
+thus need to register the reset driver before initializing the timers so
+that the reset timer can use the reset framework.
+
+Signed-off-by: Maxime Ripard <maxime.ripard@free-electrons.com>
+Acked-by: Philipp Zabel <p.zabel@pengutronix.de>
+---
+ arch/arm/mach-sunxi/sunxi.c | 11 +++++++++++
+ 1 file changed, 11 insertions(+)
+
+diff --git a/arch/arm/mach-sunxi/sunxi.c b/arch/arm/mach-sunxi/sunxi.c
+index 61d3a38..594ac48 100644
+--- a/arch/arm/mach-sunxi/sunxi.c
++++ b/arch/arm/mach-sunxi/sunxi.c
+@@ -10,6 +10,8 @@
+  * warranty of any kind, whether express or implied.
+  */
++#include <linux/clk-provider.h>
++#include <linux/clocksource.h>
+ #include <linux/delay.h>
+ #include <linux/kernel.h>
+ #include <linux/init.h>
+@@ -132,8 +134,17 @@ static void __init sunxi_dt_init(void)
+       NULL,
+ };
++extern void __init sun6i_reset_init(void);
++static void __init sun6i_timer_init(void)
++{
++      of_clk_init(NULL);
++      sun6i_reset_init();
++      clocksource_of_init();
++}
++
+ DT_MACHINE_START(SUN6I_DT, "Allwinner sun6i (A31) Family")
+       .init_machine   = sunxi_dt_init,
++      .init_time      = sun6i_timer_init,
+       .dt_compat      = sun6i_board_dt_compat,
+       .restart        = sun6i_restart,
+ MACHINE_END
+-- 
+1.8.5.1
+
diff --git a/target/linux/sunxi/patches-3.13/108-sun6i-add-smp-support.patch b/target/linux/sunxi/patches-3.13/108-sun6i-add-smp-support.patch
new file mode 100644 (file)
index 0000000..e591404
--- /dev/null
@@ -0,0 +1,222 @@
+From 6f5002c91f35f6b171bc608b87b3f2b55451f32b Mon Sep 17 00:00:00 2001
+From: Maxime Ripard <maxime.ripard@free-electrons.com>
+Date: Sun, 3 Nov 2013 10:30:13 +0100
+Subject: [PATCH] ARM: sun6i: Add SMP support for the Allwinner A31
+
+The A31 is a quad Cortex-A7. Add the logic to use the IPs used to
+control the CPU configuration and the CPU power so that we can bring up
+secondary CPUs at boot.
+
+Signed-off-by: Maxime Ripard <maxime.ripard@free-electrons.com>
+---
+ arch/arm/mach-sunxi/Makefile  |   1 +
+ arch/arm/mach-sunxi/common.h  |  19 +++++++
+ arch/arm/mach-sunxi/headsmp.S |   9 +++
+ arch/arm/mach-sunxi/platsmp.c | 124 ++++++++++++++++++++++++++++++++++++++++++
+ arch/arm/mach-sunxi/sunxi.c   |   3 +
+ 5 files changed, 156 insertions(+)
+ create mode 100644 arch/arm/mach-sunxi/common.h
+ create mode 100644 arch/arm/mach-sunxi/headsmp.S
+ create mode 100644 arch/arm/mach-sunxi/platsmp.c
+
+diff --git a/arch/arm/mach-sunxi/Makefile b/arch/arm/mach-sunxi/Makefile
+index 93bebfc..d939720 100644
+--- a/arch/arm/mach-sunxi/Makefile
++++ b/arch/arm/mach-sunxi/Makefile
+@@ -1 +1,2 @@
+ obj-$(CONFIG_ARCH_SUNXI) += sunxi.o
++obj-$(CONFIG_SMP) += platsmp.o headsmp.o
+diff --git a/arch/arm/mach-sunxi/common.h b/arch/arm/mach-sunxi/common.h
+new file mode 100644
+index 0000000..9e5ac47
+--- /dev/null
++++ b/arch/arm/mach-sunxi/common.h
+@@ -0,0 +1,19 @@
++/*
++ * Core functions for Allwinner SoCs
++ *
++ * Copyright (C) 2013 Maxime Ripard
++ *
++ * Maxime Ripard <maxime.ripard@free-electrons.com>
++ *
++ * 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.
++ */
++
++#ifndef __ARCH_SUNXI_COMMON_H_
++#define __ARCH_SUNXI_COMMON_H_
++
++void sun6i_secondary_startup(void);
++extern struct smp_operations sun6i_smp_ops;
++
++#endif /* __ARCH_SUNXI_COMMON_H_ */
+diff --git a/arch/arm/mach-sunxi/headsmp.S b/arch/arm/mach-sunxi/headsmp.S
+new file mode 100644
+index 0000000..a10d494
+--- /dev/null
++++ b/arch/arm/mach-sunxi/headsmp.S
+@@ -0,0 +1,9 @@
++#include <linux/linkage.h>
++#include <linux/init.h>
++
++        .section ".text.head", "ax"
++
++ENTRY(sun6i_secondary_startup)
++      msr     cpsr_fsxc, #0xd3
++      b       secondary_startup
++ENDPROC(sun6i_secondary_startup)
+diff --git a/arch/arm/mach-sunxi/platsmp.c b/arch/arm/mach-sunxi/platsmp.c
+new file mode 100644
+index 0000000..7b141d8
+--- /dev/null
++++ b/arch/arm/mach-sunxi/platsmp.c
+@@ -0,0 +1,124 @@
++/*
++ * SMP support for Allwinner SoCs
++ *
++ * Copyright (C) 2013 Maxime Ripard
++ *
++ * Maxime Ripard <maxime.ripard@free-electrons.com>
++ *
++ * Based on code
++ *  Copyright (C) 2012-2013 Allwinner Ltd.
++ *
++ * 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 <linux/delay.h>
++#include <linux/init.h>
++#include <linux/io.h>
++#include <linux/memory.h>
++#include <linux/of.h>
++#include <linux/of_address.h>
++#include <linux/smp.h>
++
++#include "common.h"
++
++#define CPUCFG_CPU_PWR_CLAMP_STATUS_REG(cpu)  ((cpu) * 0x40 + 0x64)
++#define CPUCFG_CPU_RST_CTRL_REG(cpu)          (((cpu) + 1) * 0x40)
++#define CPUCFG_CPU_CTRL_REG(cpu)              (((cpu) + 1) * 0x40 + 0x04)
++#define CPUCFG_CPU_STATUS_REG(cpu)            (((cpu) + 1) * 0x40 + 0x08)
++#define CPUCFG_GEN_CTRL_REG                   0x184
++#define CPUCFG_PRIVATE0_REG                   0x1a4
++#define CPUCFG_PRIVATE1_REG                   0x1a8
++#define CPUCFG_DBG_CTL0_REG                   0x1e0
++#define CPUCFG_DBG_CTL1_REG                   0x1e4
++
++#define PRCM_CPU_PWROFF_REG                   0x100
++#define PRCM_CPU_PWR_CLAMP_REG(cpu)           (((cpu) * 4) + 0x140)
++
++static void __iomem *cpucfg_membase;
++static void __iomem *prcm_membase;
++
++static DEFINE_SPINLOCK(cpu_lock);
++
++static void __init sun6i_smp_prepare_cpus(unsigned int max_cpus)
++{
++      struct device_node *node;
++
++      node = of_find_compatible_node(NULL, NULL, "allwinner,sun6i-a31-prcm");
++      if (!node) {
++              pr_err("Missing A31 PRCM node in the device tree\n");
++              return;
++      }
++
++      prcm_membase = of_iomap(node, 0);
++      if (!prcm_membase) {
++              pr_err("Couldn't map A31 PRCM registers\n");
++              return;
++      }
++
++      node = of_find_compatible_node(NULL, NULL,
++                                     "allwinner,sun6i-a31-cpuconfig");
++      if (!node) {
++              pr_err("Missing A31 CPU config node in the device tree\n");
++              return;
++      }
++
++      cpucfg_membase = of_iomap(node, 0);
++      if (!cpucfg_membase)
++              pr_err("Couldn't map A31 CPU config registers\n");
++
++}
++
++static int sun6i_smp_boot_secondary(unsigned int cpu,
++                                  struct task_struct *idle)
++{
++      u32 reg;
++      int i;
++
++      if (!(prcm_membase && cpucfg_membase))
++              return -EFAULT;
++
++      spin_lock(&cpu_lock);
++
++      /* Set CPU boot address */
++      writel(virt_to_phys(sun6i_secondary_startup),
++             cpucfg_membase + CPUCFG_PRIVATE0_REG);
++
++      /* Assert the CPU core in reset */
++      writel(0, cpucfg_membase + CPUCFG_CPU_RST_CTRL_REG(cpu));
++
++      /* Assert the L1 cache in reset */
++      reg = readl(cpucfg_membase + CPUCFG_GEN_CTRL_REG);
++      writel(reg & ~BIT(cpu), cpucfg_membase + CPUCFG_GEN_CTRL_REG);
++
++      /* Disable external debug access */
++      reg = readl(cpucfg_membase + CPUCFG_DBG_CTL1_REG);
++      writel(reg & ~BIT(cpu), cpucfg_membase + CPUCFG_DBG_CTL1_REG);
++
++      /* Power up the CPU */
++      for (i = 0; i <= 8; i++)
++              writel(0xff >> i, prcm_membase + PRCM_CPU_PWR_CLAMP_REG(cpu));
++      mdelay(10);
++
++      /* Clear CPU power-off gating */
++      reg = readl(prcm_membase + PRCM_CPU_PWROFF_REG);
++      writel(reg & ~BIT(cpu), prcm_membase + PRCM_CPU_PWROFF_REG);
++      mdelay(1);
++
++      /* Deassert the CPU core reset */
++      writel(3, cpucfg_membase + CPUCFG_CPU_RST_CTRL_REG(cpu));
++
++      /* Enable back the external debug accesses */
++      reg = readl(cpucfg_membase + CPUCFG_DBG_CTL1_REG);
++      writel(reg | BIT(cpu), cpucfg_membase + CPUCFG_DBG_CTL1_REG);
++
++      spin_unlock(&cpu_lock);
++
++      return 0;
++}
++
++struct smp_operations sun6i_smp_ops __initdata = {
++      .smp_prepare_cpus       = sun6i_smp_prepare_cpus,
++      .smp_boot_secondary     = sun6i_smp_boot_secondary,
++};
+diff --git a/arch/arm/mach-sunxi/sunxi.c b/arch/arm/mach-sunxi/sunxi.c
+index 594ac48..aeea6ce 100644
+--- a/arch/arm/mach-sunxi/sunxi.c
++++ b/arch/arm/mach-sunxi/sunxi.c
+@@ -25,6 +25,8 @@
+ #include <asm/mach/map.h>
+ #include <asm/system_misc.h>
++#include "common.h"
++
+ #define SUN4I_WATCHDOG_CTRL_REG               0x00
+ #define SUN4I_WATCHDOG_CTRL_RESTART           BIT(0)
+ #define SUN4I_WATCHDOG_MODE_REG               0x04
+@@ -147,6 +149,7 @@ static void __init sun6i_timer_init(void)
+       .init_time      = sun6i_timer_init,
+       .dt_compat      = sun6i_board_dt_compat,
+       .restart        = sun6i_restart,
++      .smp            = smp_ops(sun6i_smp_ops),
+ MACHINE_END
+ static const char * const sun7i_board_dt_compat[] = {
+-- 
+1.8.5.1
+
diff --git a/target/linux/sunxi/patches-3.13/109-dt-sun6i-add-reset-ctrler.patch b/target/linux/sunxi/patches-3.13/109-dt-sun6i-add-reset-ctrler.patch
new file mode 100644 (file)
index 0000000..92f2efa
--- /dev/null
@@ -0,0 +1,95 @@
+From f88dc0623908b574d9dcdae8815ccd0829fc6828 Mon Sep 17 00:00:00 2001
+From: Maxime Ripard <maxime.ripard@free-electrons.com>
+Date: Tue, 24 Sep 2013 11:10:41 +0300
+Subject: [PATCH] ARM: sun6i: Add the reset controller to the DTSI
+
+The A31 has a reset controller IP that maintains a few other IPs in
+reset, among which we can find the UARTs, high speed timers or the I2C.
+Now that we have support for them, add the reset controllers to the DTSI.
+
+Signed-off-by: Maxime Ripard <maxime.ripard@free-electrons.com>
+Acked-by: Philipp Zabel <p.zabel@pengutronix.de>
+---
+ arch/arm/boot/dts/sun6i-a31.dtsi | 24 ++++++++++++++++++++++++
+ 1 file changed, 24 insertions(+)
+
+diff --git a/arch/arm/boot/dts/sun6i-a31.dtsi b/arch/arm/boot/dts/sun6i-a31.dtsi
+index 7f5878c..97966b0 100644
+--- a/arch/arm/boot/dts/sun6i-a31.dtsi
++++ b/arch/arm/boot/dts/sun6i-a31.dtsi
+@@ -212,6 +212,24 @@
+                       };
+               };
++              ahb1_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-timer";
+                       reg = <0x01c20c00 0xa0>;
+@@ -235,6 +253,7 @@
+                       reg-shift = <2>;
+                       reg-io-width = <4>;
+                       clocks = <&apb2_gates 16>;
++                      resets = <&apb2_rst 16>;
+                       status = "disabled";
+               };
+@@ -245,6 +264,7 @@
+                       reg-shift = <2>;
+                       reg-io-width = <4>;
+                       clocks = <&apb2_gates 17>;
++                      resets = <&apb2_rst 17>;
+                       status = "disabled";
+               };
+@@ -255,6 +275,7 @@
+                       reg-shift = <2>;
+                       reg-io-width = <4>;
+                       clocks = <&apb2_gates 18>;
++                      resets = <&apb2_rst 18>;
+                       status = "disabled";
+               };
+@@ -265,6 +286,7 @@
+                       reg-shift = <2>;
+                       reg-io-width = <4>;
+                       clocks = <&apb2_gates 19>;
++                      resets = <&apb2_rst 19>;
+                       status = "disabled";
+               };
+@@ -275,6 +297,7 @@
+                       reg-shift = <2>;
+                       reg-io-width = <4>;
+                       clocks = <&apb2_gates 20>;
++                      resets = <&apb2_rst 20>;
+                       status = "disabled";
+               };
+@@ -285,6 +308,7 @@
+                       reg-shift = <2>;
+                       reg-io-width = <4>;
+                       clocks = <&apb2_gates 21>;
++                      resets = <&apb2_rst 21>;
+                       status = "disabled";
+               };
+-- 
+1.8.5.1
+
diff --git a/target/linux/sunxi/patches-3.13/110-sun4i-clkevent-fill-irqfield.patch b/target/linux/sunxi/patches-3.13/110-sun4i-clkevent-fill-irqfield.patch
new file mode 100644 (file)
index 0000000..12bd64a
--- /dev/null
@@ -0,0 +1,33 @@
+From abc12cd5c39556824cc9022db6eddc64e8e8dbe9 Mon Sep 17 00:00:00 2001
+From: Maxime Ripard <maxime.ripard@free-electrons.com>
+Date: Wed, 23 Oct 2013 17:54:39 +0100
+Subject: [PATCH] clockevent: sun4i: Fill the irq field in the clockevent
+ structure
+
+The clock event structure irq field was not filled previously to the
+interrupt we're using.
+
+This was resulting in the timer not being used at all when using a
+configuration with SMP enabled on a system with several CPUs, and with
+the cpumask set to the cpu_possible_mask.
+
+Signed-off-by: Maxime Ripard <maxime.ripard@free-electrons.com>
+---
+ drivers/clocksource/sun4i_timer.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/drivers/clocksource/sun4i_timer.c b/drivers/clocksource/sun4i_timer.c
+index a4f6119..db937e9 100644
+--- a/drivers/clocksource/sun4i_timer.c
++++ b/drivers/clocksource/sun4i_timer.c
+@@ -191,6 +191,7 @@ static void __init sun4i_timer_init(struct device_node *node)
+       writel(val | TIMER_IRQ_EN(0), timer_base + TIMER_IRQ_EN_REG);
+       sun4i_clockevent.cpumask = cpumask_of(0);
++      sun4i_clockevent.irq = irq;
+       clockevents_config_and_register(&sun4i_clockevent, rate,
+                                       TIMER_SYNC_TICKS, 0xffffffff);
+-- 
+1.8.5.1
+
diff --git a/target/linux/sunxi/patches-3.13/111-sun4i-clksrc-change-cpu-mask.patch b/target/linux/sunxi/patches-3.13/111-sun4i-clksrc-change-cpu-mask.patch
new file mode 100644 (file)
index 0000000..8f32c7e
--- /dev/null
@@ -0,0 +1,30 @@
+From 64a9fa131380f9cef9328d0cf9f2d49a538e6dd2 Mon Sep 17 00:00:00 2001
+From: Maxime Ripard <maxime.ripard@free-electrons.com>
+Date: Wed, 9 Oct 2013 22:44:56 +0200
+Subject: [PATCH] clocksource: sun4i: change CPU mask to cpu_possible_mask
+
+The interrupt for the timer is a shared processor interrupt, so any CPU
+found in the system can handle it. Switch to our cpumask to
+cpu_possible_mask instead of cpumask_of(0).
+
+Signed-off-by: Maxime Ripard <maxime.ripard@free-electrons.com>
+---
+ drivers/clocksource/sun4i_timer.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/clocksource/sun4i_timer.c b/drivers/clocksource/sun4i_timer.c
+index db937e9..e1878eb 100644
+--- a/drivers/clocksource/sun4i_timer.c
++++ b/drivers/clocksource/sun4i_timer.c
+@@ -190,7 +190,7 @@ static void __init sun4i_timer_init(struct device_node *node)
+       val = readl(timer_base + TIMER_IRQ_EN_REG);
+       writel(val | TIMER_IRQ_EN(0), timer_base + TIMER_IRQ_EN_REG);
+-      sun4i_clockevent.cpumask = cpumask_of(0);
++      sun4i_clockevent.cpumask = cpu_possible_mask;
+       sun4i_clockevent.irq = irq;
+       clockevents_config_and_register(&sun4i_clockevent, rate,
+-- 
+1.8.5.1
+
diff --git a/target/linux/sunxi/patches-3.13/112-sun4i-clksrc-increase-a-bit-in-clockevent.patch b/target/linux/sunxi/patches-3.13/112-sun4i-clksrc-increase-a-bit-in-clockevent.patch
new file mode 100644 (file)
index 0000000..4067e27
--- /dev/null
@@ -0,0 +1,46 @@
+From a4eb936767bd6a63d54734b9ce48932609ce58eb Mon Sep 17 00:00:00 2001
+From: Maxime Ripard <maxime.ripard@free-electrons.com>
+Date: Thu, 7 Nov 2013 12:01:48 +0100
+Subject: [PATCH] clocksource: sun4i: Increase a bit the clock event and
+ sources rating
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+We want to keep this driver as the default provider of the clock events
+and source, yet some other driver might fit in the "desired" category of
+ratings. Hence, we need to increase a bit the rating so that we can have
+more flexibility in the ratings we choose.
+
+Signed-off-by: Maxime Ripard <maxime.ripard@free-electrons.com>
+Tested-by: Emilio López <emilio@elopez.com.ar>
+Signed-off-by: Daniel Lezcano <daniel.lezcano@linaro.org>
+---
+ drivers/clocksource/sun4i_timer.c | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/clocksource/sun4i_timer.c b/drivers/clocksource/sun4i_timer.c
+index e1878eb..a9b0b5b 100644
+--- a/drivers/clocksource/sun4i_timer.c
++++ b/drivers/clocksource/sun4i_timer.c
+@@ -114,7 +114,7 @@ static int sun4i_clkevt_next_event(unsigned long evt,
+ static struct clock_event_device sun4i_clockevent = {
+       .name = "sun4i_tick",
+-      .rating = 300,
++      .rating = 350,
+       .features = CLOCK_EVT_FEAT_PERIODIC | CLOCK_EVT_FEAT_ONESHOT,
+       .set_mode = sun4i_clkevt_mode,
+       .set_next_event = sun4i_clkevt_next_event,
+@@ -172,7 +172,7 @@ static void __init sun4i_timer_init(struct device_node *node)
+       setup_sched_clock(sun4i_timer_sched_read, 32, rate);
+       clocksource_mmio_init(timer_base + TIMER_CNTVAL_REG(1), node->name,
+-                            rate, 300, 32, clocksource_mmio_readl_down);
++                            rate, 350, 32, clocksource_mmio_readl_down);
+       ticks_per_jiffy = DIV_ROUND_UP(rate, HZ);
+-- 
+1.8.5.1
+
diff --git a/target/linux/sunxi/patches-3.13/113-clk-sunxi-register-factors-clocks.patch b/target/linux/sunxi/patches-3.13/113-clk-sunxi-register-factors-clocks.patch
new file mode 100644 (file)
index 0000000..6a6974e
--- /dev/null
@@ -0,0 +1,232 @@
+From 9212bc4a3752e9a4db2f73afd99278eb28e5dcff Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?Emilio=20L=C3=B3pez?= <emilio@elopez.com.ar>
+Date: Mon, 23 Dec 2013 00:32:32 -0300
+Subject: [PATCH] clk: sunxi: register factors clocks behind composite
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+This commit reworks factors clock registration to be done behind a
+composite clock. This allows us to additionally add a gate, mux or
+divisors, as it will be needed by some future PLLs.
+
+Signed-off-by: Emilio López <emilio@elopez.com.ar>
+Acked-by: Maxime Ripard <maxime.ripard@free-electrons.com>
+---
+ drivers/clk/sunxi/clk-factors.c | 63 +------------------------------------
+ drivers/clk/sunxi/clk-factors.h | 16 +++++-----
+ drivers/clk/sunxi/clk-sunxi.c   | 70 ++++++++++++++++++++++++++++++++++++++---
+ 3 files changed, 76 insertions(+), 73 deletions(-)
+
+diff --git a/drivers/clk/sunxi/clk-factors.c b/drivers/clk/sunxi/clk-factors.c
+index f05207a..9e23264 100644
+--- a/drivers/clk/sunxi/clk-factors.c
++++ b/drivers/clk/sunxi/clk-factors.c
+@@ -30,14 +30,6 @@
+  * parent - fixed parent.  No clk_set_parent support
+  */
+-struct clk_factors {
+-      struct clk_hw hw;
+-      void __iomem *reg;
+-      struct clk_factors_config *config;
+-      void (*get_factors) (u32 *rate, u32 parent, u8 *n, u8 *k, u8 *m, u8 *p);
+-      spinlock_t *lock;
+-};
+-
+ #define to_clk_factors(_hw) container_of(_hw, struct clk_factors, hw)
+ #define SETMASK(len, pos)             (((1U << (len)) - 1) << (pos))
+@@ -120,61 +112,8 @@ static int clk_factors_set_rate(struct clk_hw *hw, unsigned long rate,
+       return 0;
+ }
+-static const struct clk_ops clk_factors_ops = {
++const struct clk_ops clk_factors_ops = {
+       .recalc_rate = clk_factors_recalc_rate,
+       .round_rate = clk_factors_round_rate,
+       .set_rate = clk_factors_set_rate,
+ };
+-
+-/**
+- * clk_register_factors - register a factors clock with
+- * the clock framework
+- * @dev: device registering this clock
+- * @name: name of this clock
+- * @parent_name: name of clock's parent
+- * @flags: framework-specific flags
+- * @reg: register address to adjust factors
+- * @config: shift and width of factors n, k, m and p
+- * @get_factors: function to calculate the factors for a given frequency
+- * @lock: shared register lock for this clock
+- */
+-struct clk *clk_register_factors(struct device *dev, const char *name,
+-                               const char *parent_name,
+-                               unsigned long flags, void __iomem *reg,
+-                               struct clk_factors_config *config,
+-                               void (*get_factors)(u32 *rate, u32 parent,
+-                                                   u8 *n, u8 *k, u8 *m, u8 *p),
+-                               spinlock_t *lock)
+-{
+-      struct clk_factors *factors;
+-      struct clk *clk;
+-      struct clk_init_data init;
+-
+-      /* allocate the factors */
+-      factors = kzalloc(sizeof(struct clk_factors), GFP_KERNEL);
+-      if (!factors) {
+-              pr_err("%s: could not allocate factors clk\n", __func__);
+-              return ERR_PTR(-ENOMEM);
+-      }
+-
+-      init.name = name;
+-      init.ops = &clk_factors_ops;
+-      init.flags = flags;
+-      init.parent_names = (parent_name ? &parent_name : NULL);
+-      init.num_parents = (parent_name ? 1 : 0);
+-
+-      /* struct clk_factors assignments */
+-      factors->reg = reg;
+-      factors->config = config;
+-      factors->lock = lock;
+-      factors->hw.init = &init;
+-      factors->get_factors = get_factors;
+-
+-      /* register the clock */
+-      clk = clk_register(dev, &factors->hw);
+-
+-      if (IS_ERR(clk))
+-              kfree(factors);
+-
+-      return clk;
+-}
+diff --git a/drivers/clk/sunxi/clk-factors.h b/drivers/clk/sunxi/clk-factors.h
+index f49851c..02e1a43 100644
+--- a/drivers/clk/sunxi/clk-factors.h
++++ b/drivers/clk/sunxi/clk-factors.h
+@@ -17,11 +17,13 @@ struct clk_factors_config {
+       u8 pwidth;
+ };
+-struct clk *clk_register_factors(struct device *dev, const char *name,
+-                               const char *parent_name,
+-                               unsigned long flags, void __iomem *reg,
+-                               struct clk_factors_config *config,
+-                               void (*get_factors) (u32 *rate, u32 parent_rate,
+-                                                    u8 *n, u8 *k, u8 *m, u8 *p),
+-                               spinlock_t *lock);
++struct clk_factors {
++      struct clk_hw hw;
++      void __iomem *reg;
++      struct clk_factors_config *config;
++      void (*get_factors) (u32 *rate, u32 parent, u8 *n, u8 *k, u8 *m, u8 *p);
++      spinlock_t *lock;
++};
++
++extern const struct clk_ops clk_factors_ops;
+ #endif
+diff --git a/drivers/clk/sunxi/clk-sunxi.c b/drivers/clk/sunxi/clk-sunxi.c
+index 492ef0e..7dc39a6 100644
+--- a/drivers/clk/sunxi/clk-sunxi.c
++++ b/drivers/clk/sunxi/clk-sunxi.c
+@@ -23,6 +23,9 @@
+ static DEFINE_SPINLOCK(clk_lock);
++/* Maximum number of parents our clocks have */
++#define SUNXI_MAX_PARENTS     5
++
+ /**
+  * sun4i_osc_clk_setup() - Setup function for gatable oscillator
+  */
+@@ -261,7 +264,11 @@ static void sun4i_get_apb1_factors(u32 *freq, u32 parent_rate,
+  * sunxi_factors_clk_setup() - Setup function for factor clocks
+  */
++#define SUNXI_FACTORS_MUX_MASK 0x3
++
+ struct factors_data {
++      int enable;
++      int mux;
+       struct clk_factors_config *table;
+       void (*getter) (u32 *rate, u32 parent_rate, u8 *n, u8 *k, u8 *m, u8 *p);
+ };
+@@ -312,16 +319,71 @@ static void __init sunxi_factors_clk_setup(struct device_node *node,
+                                          struct factors_data *data)
+ {
+       struct clk *clk;
++      struct clk_factors *factors;
++      struct clk_gate *gate = NULL;
++      struct clk_mux *mux = NULL;
++      struct clk_hw *gate_hw = NULL;
++      struct clk_hw *mux_hw = NULL;
+       const char *clk_name = node->name;
+-      const char *parent;
++      const char *parents[SUNXI_MAX_PARENTS];
+       void *reg;
++      int i = 0;
+       reg = of_iomap(node, 0);
+-      parent = of_clk_get_parent_name(node, 0);
++      /* if we have a mux, we will have >1 parents */
++      while (i < SUNXI_MAX_PARENTS &&
++             (parents[i] = of_clk_get_parent_name(node, i)) != NULL)
++              i++;
++
++      factors = kzalloc(sizeof(struct clk_factors), GFP_KERNEL);
++      if (!factors)
++              return;
++
++      /* Add a gate if this factor clock can be gated */
++      if (data->enable) {
++              gate = kzalloc(sizeof(struct clk_gate), GFP_KERNEL);
++              if (!gate) {
++                      kfree(factors);
++                      return;
++              }
++
++              /* set up gate properties */
++              gate->reg = reg;
++              gate->bit_idx = data->enable;
++              gate->lock = &clk_lock;
++              gate_hw = &gate->hw;
++      }
++
++      /* Add a mux if this factor clock can be muxed */
++      if (data->mux) {
++              mux = kzalloc(sizeof(struct clk_mux), GFP_KERNEL);
++              if (!mux) {
++                      kfree(factors);
++                      kfree(gate);
++                      return;
++              }
++
++              /* set up gate properties */
++              mux->reg = reg;
++              mux->shift = data->mux;
++              mux->mask = SUNXI_FACTORS_MUX_MASK;
++              mux->lock = &clk_lock;
++              mux_hw = &mux->hw;
++      }
++
++      /* set up factors properties */
++      factors->reg = reg;
++      factors->config = data->table;
++      factors->get_factors = data->getter;
++      factors->lock = &clk_lock;
+-      clk = clk_register_factors(NULL, clk_name, parent, 0, reg,
+-                                 data->table, data->getter, &clk_lock);
++      clk = clk_register_composite(NULL, clk_name,
++                      parents, i,
++                      mux_hw, &clk_mux_ops,
++                      &factors->hw, &clk_factors_ops,
++                      gate_hw, &clk_gate_ops,
++                      i ? 0 : CLK_IS_ROOT);
+       if (!IS_ERR(clk)) {
+               of_clk_add_provider(node, of_clk_src_simple_get, clk);
+-- 
+1.8.5.1
+
diff --git a/target/linux/sunxi/patches-3.13/114-clk-sunxi-clean-magic-number.patch b/target/linux/sunxi/patches-3.13/114-clk-sunxi-clean-magic-number.patch
new file mode 100644 (file)
index 0000000..be77e30
--- /dev/null
@@ -0,0 +1,40 @@
+From 33574f94b0d4d8bc8af732fbcb4f911c3dd8c96b Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?Emilio=20L=C3=B3pez?= <emilio@elopez.com.ar>
+Date: Mon, 23 Dec 2013 00:32:33 -0300
+Subject: [PATCH] clk: sunxi: clean the magic number of mux parents
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+This was pointed out during the review of the factor patches. Let's
+indicate what does that magic 5 mean.
+
+Signed-off-by: Emilio López <emilio@elopez.com.ar>
+---
+ drivers/clk/sunxi/clk-sunxi.c | 5 +++--
+ 1 file changed, 3 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/clk/sunxi/clk-sunxi.c b/drivers/clk/sunxi/clk-sunxi.c
+index 7dc39a6..25ebba8 100644
+--- a/drivers/clk/sunxi/clk-sunxi.c
++++ b/drivers/clk/sunxi/clk-sunxi.c
+@@ -420,13 +420,14 @@ static void __init sunxi_mux_clk_setup(struct device_node *node,
+ {
+       struct clk *clk;
+       const char *clk_name = node->name;
+-      const char *parents[5];
++      const char *parents[SUNXI_MAX_PARENTS];
+       void *reg;
+       int i = 0;
+       reg = of_iomap(node, 0);
+-      while (i < 5 && (parents[i] = of_clk_get_parent_name(node, i)) != NULL)
++      while (i < SUNXI_MAX_PARENTS &&
++             (parents[i] = of_clk_get_parent_name(node, i)) != NULL)
+               i++;
+       clk = clk_register_mux(NULL, clk_name, parents, i,
+-- 
+1.8.5.1
+
diff --git a/target/linux/sunxi/patches-3.13/115-clk-sunxi_add-gating-pll1.patch b/target/linux/sunxi/patches-3.13/115-clk-sunxi_add-gating-pll1.patch
new file mode 100644 (file)
index 0000000..a982d4c
--- /dev/null
@@ -0,0 +1,53 @@
+From 3d56b9643ff9fff3c7ceb095e03f4ab7e149b9ce Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?Emilio=20L=C3=B3pez?= <emilio@elopez.com.ar>
+Date: Mon, 23 Dec 2013 00:32:34 -0300
+Subject: [PATCH] clk: sunxi: add gating support to PLL1
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+This commit adds gating support to PLL1 on the clock driver. This makes
+the PLL1 implementation fully compatible with PLL4 as well.
+
+Signed-off-by: Emilio López <emilio@elopez.com.ar>
+Acked-by: Maxime Ripard <maxime.ripard@free-electrons.com>
+Acked-by: Mike Turquette <mturquette@linaro.org>
+---
+ Documentation/devicetree/bindings/clock/sunxi.txt | 2 +-
+ drivers/clk/sunxi/clk-sunxi.c                     | 2 ++
+ 2 files changed, 3 insertions(+), 1 deletion(-)
+
+diff --git a/Documentation/devicetree/bindings/clock/sunxi.txt b/Documentation/devicetree/bindings/clock/sunxi.txt
+index 91a748f..b8c6cc4 100644
+--- a/Documentation/devicetree/bindings/clock/sunxi.txt
++++ b/Documentation/devicetree/bindings/clock/sunxi.txt
+@@ -7,7 +7,7 @@ This binding uses the common clock binding[1].
+ Required properties:
+ - compatible : shall be one of the following:
+       "allwinner,sun4i-osc-clk" - for a gatable oscillator
+-      "allwinner,sun4i-pll1-clk" - for the main PLL clock
++      "allwinner,sun4i-pll1-clk" - for the main PLL clock and PLL4
+       "allwinner,sun6i-a31-pll1-clk" - for the main PLL clock on A31
+       "allwinner,sun4i-cpu-clk" - for the CPU multiplexer clock
+       "allwinner,sun4i-axi-clk" - for the AXI clock
+diff --git a/drivers/clk/sunxi/clk-sunxi.c b/drivers/clk/sunxi/clk-sunxi.c
+index 25ebba8..52f34ec 100644
+--- a/drivers/clk/sunxi/clk-sunxi.c
++++ b/drivers/clk/sunxi/clk-sunxi.c
+@@ -301,11 +301,13 @@ struct factors_data {
+ };
+ static const struct factors_data sun4i_pll1_data __initconst = {
++      .enable = 31,
+       .table = &sun4i_pll1_config,
+       .getter = sun4i_get_pll1_factors,
+ };
+ static const struct factors_data sun6i_a31_pll1_data __initconst = {
++      .enable = 31,
+       .table = &sun6i_a31_pll1_config,
+       .getter = sun6i_a31_get_pll1_factors,
+ };
+-- 
+1.8.5.1
+
diff --git a/target/linux/sunxi/patches-3.13/116-clk-sunxi-add-pll4.patch b/target/linux/sunxi/patches-3.13/116-clk-sunxi-add-pll4.patch
new file mode 100644 (file)
index 0000000..84541de
--- /dev/null
@@ -0,0 +1,95 @@
+From ff0b5fdb65bc7f10af7e83bb0919cb6bec2dc624 Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?Emilio=20L=C3=B3pez?= <emilio@elopez.com.ar>
+Date: Mon, 23 Dec 2013 00:32:35 -0300
+Subject: [PATCH] ARM: sunxi: add PLL4 support
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+This commit adds the PLL4 definition to the sun4i, sun5i and sun7i
+device trees. PLL4 is compatible with PLL1.
+
+Signed-off-by: Emilio López <emilio@elopez.com.ar>
+Acked-by: Maxime Ripard <maxime.ripard@free-electrons.com>
+---
+ arch/arm/boot/dts/sun4i-a10.dtsi  | 7 +++++++
+ arch/arm/boot/dts/sun5i-a10s.dtsi | 7 +++++++
+ arch/arm/boot/dts/sun5i-a13.dtsi  | 7 +++++++
+ arch/arm/boot/dts/sun7i-a20.dtsi  | 7 +++++++
+ 4 files changed, 28 insertions(+)
+
+diff --git a/arch/arm/boot/dts/sun4i-a10.dtsi b/arch/arm/boot/dts/sun4i-a10.dtsi
+index 0bf70ee..1d6346c 100644
+--- a/arch/arm/boot/dts/sun4i-a10.dtsi
++++ b/arch/arm/boot/dts/sun4i-a10.dtsi
+@@ -70,6 +70,13 @@
+                       clocks = <&osc24M>;
+               };
++              pll4: pll4@01c20018 {
++                      #clock-cells = <0>;
++                      compatible = "allwinner,sun4i-pll1-clk";
++                      reg = <0x01c20018 0x4>;
++                      clocks = <&osc24M>;
++              };
++
+               /* dummy is 200M */
+               cpu: cpu@01c20054 {
+                       #clock-cells = <0>;
+diff --git a/arch/arm/boot/dts/sun5i-a10s.dtsi b/arch/arm/boot/dts/sun5i-a10s.dtsi
+index 924a2c1..64d6d75 100644
+--- a/arch/arm/boot/dts/sun5i-a10s.dtsi
++++ b/arch/arm/boot/dts/sun5i-a10s.dtsi
+@@ -67,6 +67,13 @@
+                       clocks = <&osc24M>;
+               };
++              pll4: pll4@01c20018 {
++                      #clock-cells = <0>;
++                      compatible = "allwinner,sun4i-pll1-clk";
++                      reg = <0x01c20018 0x4>;
++                      clocks = <&osc24M>;
++              };
++
+               /* dummy is 200M */
+               cpu: cpu@01c20054 {
+                       #clock-cells = <0>;
+diff --git a/arch/arm/boot/dts/sun5i-a13.dtsi b/arch/arm/boot/dts/sun5i-a13.dtsi
+index 1ccd75d..2c355c8 100644
+--- a/arch/arm/boot/dts/sun5i-a13.dtsi
++++ b/arch/arm/boot/dts/sun5i-a13.dtsi
+@@ -67,6 +67,13 @@
+                       clocks = <&osc24M>;
+               };
++              pll4: pll4@01c20018 {
++                      #clock-cells = <0>;
++                      compatible = "allwinner,sun4i-pll1-clk";
++                      reg = <0x01c20018 0x4>;
++                      clocks = <&osc24M>;
++              };
++
+               /* dummy is 200M */
+               cpu: cpu@01c20054 {
+                       #clock-cells = <0>;
+diff --git a/arch/arm/boot/dts/sun7i-a20.dtsi b/arch/arm/boot/dts/sun7i-a20.dtsi
+index c74147a..18144f0 100644
+--- a/arch/arm/boot/dts/sun7i-a20.dtsi
++++ b/arch/arm/boot/dts/sun7i-a20.dtsi
+@@ -66,6 +66,13 @@
+                       clocks = <&osc24M>;
+               };
++              pll4: pll4@01c20018 {
++                      #clock-cells = <0>;
++                      compatible = "allwinner,sun4i-pll1-clk";
++                      reg = <0x01c20018 0x4>;
++                      clocks = <&osc24M>;
++              };
++
+               /*
+                * This is a dummy clock, to be used as placeholder on
+                * other mux clocks when a specific parent clock is not
+-- 
+1.8.5.1
+
diff --git a/target/linux/sunxi/patches-3.13/117-clk-sunxi-factors_clk_setup_update.patch b/target/linux/sunxi/patches-3.13/117-clk-sunxi-factors_clk_setup_update.patch
new file mode 100644 (file)
index 0000000..be38689
--- /dev/null
@@ -0,0 +1,79 @@
+From 8a3282a0a185108e37e7a48437b58d956ff56f4a Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?Emilio=20L=C3=B3pez?= <emilio@elopez.com.ar>
+Date: Mon, 23 Dec 2013 00:32:36 -0300
+Subject: [PATCH] clk: sunxi: make factors_clk_setup return the clock it
+ registers
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+We will be needing this to register a factor clock as parent with leaf
+divisors on a single call.
+
+Signed-off-by: Emilio López <emilio@elopez.com.ar>
+Acked-by: Mike Turquette <mturquette@linaro.org>
+---
+ drivers/clk/sunxi/clk-sunxi.c | 15 ++++++++-------
+ 1 file changed, 8 insertions(+), 7 deletions(-)
+
+diff --git a/drivers/clk/sunxi/clk-sunxi.c b/drivers/clk/sunxi/clk-sunxi.c
+index 52f34ec..96ccb3c 100644
+--- a/drivers/clk/sunxi/clk-sunxi.c
++++ b/drivers/clk/sunxi/clk-sunxi.c
+@@ -317,8 +317,8 @@ struct factors_data {
+       .getter = sun4i_get_apb1_factors,
+ };
+-static void __init sunxi_factors_clk_setup(struct device_node *node,
+-                                         struct factors_data *data)
++static struct clk * __init sunxi_factors_clk_setup(struct device_node *node,
++                                              const struct factors_data *data)
+ {
+       struct clk *clk;
+       struct clk_factors *factors;
+@@ -340,14 +340,14 @@ static void __init sunxi_factors_clk_setup(struct device_node *node,
+       factors = kzalloc(sizeof(struct clk_factors), GFP_KERNEL);
+       if (!factors)
+-              return;
++              return NULL;
+       /* Add a gate if this factor clock can be gated */
+       if (data->enable) {
+               gate = kzalloc(sizeof(struct clk_gate), GFP_KERNEL);
+               if (!gate) {
+                       kfree(factors);
+-                      return;
++                      return NULL;
+               }
+               /* set up gate properties */
+@@ -363,7 +363,7 @@ static void __init sunxi_factors_clk_setup(struct device_node *node,
+               if (!mux) {
+                       kfree(factors);
+                       kfree(gate);
+-                      return;
++                      return NULL;
+               }
+               /* set up gate properties */
+@@ -384,13 +384,14 @@ static void __init sunxi_factors_clk_setup(struct device_node *node,
+                       parents, i,
+                       mux_hw, &clk_mux_ops,
+                       &factors->hw, &clk_factors_ops,
+-                      gate_hw, &clk_gate_ops,
+-                      i ? 0 : CLK_IS_ROOT);
++                      gate_hw, &clk_gate_ops, 0);
+       if (!IS_ERR(clk)) {
+               of_clk_add_provider(node, of_clk_src_simple_get, clk);
+               clk_register_clkdev(clk, clk_name, NULL);
+       }
++
++      return clk;
+ }
+-- 
+1.8.5.1
+
diff --git a/target/linux/sunxi/patches-3.13/118-clk-sunxi-add-pll5-pll6.patch b/target/linux/sunxi/patches-3.13/118-clk-sunxi-add-pll5-pll6.patch
new file mode 100644 (file)
index 0000000..425c929
--- /dev/null
@@ -0,0 +1,310 @@
+From 655893a197a5134a371a5c6b579f1bbce03ab413 Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?Emilio=20L=C3=B3pez?= <emilio@elopez.com.ar>
+Date: Mon, 23 Dec 2013 00:32:37 -0300
+Subject: [PATCH] clk: sunxi: add PLL5 and PLL6 support
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+This commit implements PLL5 and PLL6 support on the sunxi clock driver.
+These PLLs use a similar factor clock, but differ on their outputs.
+
+Signed-off-by: Emilio López <emilio@elopez.com.ar>
+Acked-by: Mike Turquette <mturquette@linaro.org>
+---
+ Documentation/devicetree/bindings/clock/sunxi.txt |   2 +
+ drivers/clk/sunxi/clk-sunxi.c                     | 230 ++++++++++++++++++++++
+ 2 files changed, 232 insertions(+)
+
+diff --git a/Documentation/devicetree/bindings/clock/sunxi.txt b/Documentation/devicetree/bindings/clock/sunxi.txt
+index b8c6cc4..80b2a39 100644
+--- a/Documentation/devicetree/bindings/clock/sunxi.txt
++++ b/Documentation/devicetree/bindings/clock/sunxi.txt
+@@ -9,6 +9,8 @@ Required properties:
+       "allwinner,sun4i-osc-clk" - for a gatable oscillator
+       "allwinner,sun4i-pll1-clk" - for the main PLL clock and PLL4
+       "allwinner,sun6i-a31-pll1-clk" - for the main PLL clock on A31
++      "allwinner,sun4i-pll5-clk" - for the PLL5 clock
++      "allwinner,sun4i-pll6-clk" - for the PLL6 clock
+       "allwinner,sun4i-cpu-clk" - for the CPU multiplexer clock
+       "allwinner,sun4i-axi-clk" - for the AXI clock
+       "allwinner,sun4i-axi-gates-clk" - for the AXI gates
+diff --git a/drivers/clk/sunxi/clk-sunxi.c b/drivers/clk/sunxi/clk-sunxi.c
+index 96ccb3c..649d7c3 100644
+--- a/drivers/clk/sunxi/clk-sunxi.c
++++ b/drivers/clk/sunxi/clk-sunxi.c
+@@ -218,6 +218,40 @@ static void sun6i_a31_get_pll1_factors(u32 *freq, u32 parent_rate,
+ }
+ /**
++ * sun4i_get_pll5_factors() - calculates n, k factors for PLL5
++ * PLL5 rate is calculated as follows
++ * rate = parent_rate * n * (k + 1)
++ * parent_rate is always 24Mhz
++ */
++
++static void sun4i_get_pll5_factors(u32 *freq, u32 parent_rate,
++                                 u8 *n, u8 *k, u8 *m, u8 *p)
++{
++      u8 div;
++
++      /* Normalize value to a parent_rate multiple (24M) */
++      div = *freq / parent_rate;
++      *freq = parent_rate * div;
++
++      /* we were called to round the frequency, we can now return */
++      if (n == NULL)
++              return;
++
++      if (div < 31)
++              *k = 0;
++      else if (div / 2 < 31)
++              *k = 1;
++      else if (div / 3 < 31)
++              *k = 2;
++      else
++              *k = 3;
++
++      *n = DIV_ROUND_UP(div, (*k+1));
++}
++
++
++
++/**
+  * sun4i_get_apb1_factors() - calculates m, p factors for APB1
+  * APB1 rate is calculated as follows
+  * rate = (parent_rate >> p) / (m + 1);
+@@ -293,6 +327,13 @@ struct factors_data {
+       .mwidth = 2,
+ };
++static struct clk_factors_config sun4i_pll5_config = {
++      .nshift = 8,
++      .nwidth = 5,
++      .kshift = 4,
++      .kwidth = 2,
++};
++
+ static struct clk_factors_config sun4i_apb1_config = {
+       .mshift = 0,
+       .mwidth = 5,
+@@ -312,6 +353,12 @@ struct factors_data {
+       .getter = sun6i_a31_get_pll1_factors,
+ };
++static const struct factors_data sun4i_pll5_data __initconst = {
++      .enable = 31,
++      .table = &sun4i_pll5_config,
++      .getter = sun4i_get_pll5_factors,
++};
++
+ static const struct factors_data sun4i_apb1_data __initconst = {
+       .table = &sun4i_apb1_config,
+       .getter = sun4i_get_apb1_factors,
+@@ -627,6 +674,179 @@ static void __init sunxi_gates_clk_setup(struct device_node *node,
+       of_clk_add_provider(node, of_clk_src_onecell_get, clk_data);
+ }
++
++
++/**
++ * sunxi_divs_clk_setup() helper data
++ */
++
++#define SUNXI_DIVS_MAX_QTY    2
++#define SUNXI_DIVISOR_WIDTH   2
++
++struct divs_data {
++      const struct factors_data *factors; /* data for the factor clock */
++      struct {
++              u8 fixed; /* is it a fixed divisor? if not... */
++              struct clk_div_table *table; /* is it a table based divisor? */
++              u8 shift; /* otherwise it's a normal divisor with this shift */
++              u8 pow;   /* is it power-of-two based? */
++              u8 gate;  /* is it independently gateable? */
++      } div[SUNXI_DIVS_MAX_QTY];
++};
++
++static struct clk_div_table pll6_sata_tbl[] = {
++      { .val = 0, .div = 6, },
++      { .val = 1, .div = 12, },
++      { .val = 2, .div = 18, },
++      { .val = 3, .div = 24, },
++      { } /* sentinel */
++};
++
++static const struct divs_data pll5_divs_data __initconst = {
++      .factors = &sun4i_pll5_data,
++      .div = {
++              { .shift = 0, .pow = 0, }, /* M, DDR */
++              { .shift = 16, .pow = 1, }, /* P, other */
++      }
++};
++
++static const struct divs_data pll6_divs_data __initconst = {
++      .factors = &sun4i_pll5_data,
++      .div = {
++              { .shift = 0, .table = pll6_sata_tbl, .gate = 14 }, /* M, SATA */
++              { .fixed = 2 }, /* P, other */
++      }
++};
++
++/**
++ * sunxi_divs_clk_setup() - Setup function for leaf divisors on clocks
++ *
++ * These clocks look something like this
++ *            ________________________
++ *           |         ___divisor 1---|----> to consumer
++ * parent >--|  pll___/___divisor 2---|----> to consumer
++ *           |        \_______________|____> to consumer
++ *           |________________________|
++ */
++
++static void __init sunxi_divs_clk_setup(struct device_node *node,
++                                      struct divs_data *data)
++{
++      struct clk_onecell_data *clk_data;
++      const char *parent  = node->name;
++      const char *clk_name;
++      struct clk **clks, *pclk;
++      struct clk_hw *gate_hw, *rate_hw;
++      const struct clk_ops *rate_ops;
++      struct clk_gate *gate = NULL;
++      struct clk_fixed_factor *fix_factor;
++      struct clk_divider *divider;
++      void *reg;
++      int i = 0;
++      int flags, clkflags;
++
++      /* Set up factor clock that we will be dividing */
++      pclk = sunxi_factors_clk_setup(node, data->factors);
++
++      reg = of_iomap(node, 0);
++
++      clk_data = kmalloc(sizeof(struct clk_onecell_data), GFP_KERNEL);
++      if (!clk_data)
++              return;
++
++      clks = kzalloc(SUNXI_DIVS_MAX_QTY * sizeof(struct clk *), GFP_KERNEL);
++      if (!clks)
++              goto free_clkdata;
++
++      clk_data->clks = clks;
++
++      /* It's not a good idea to have automatic reparenting changing
++       * our RAM clock! */
++      clkflags = !strcmp("pll5", parent) ? 0 : CLK_SET_RATE_PARENT;
++
++      for (i = 0; i < SUNXI_DIVS_MAX_QTY; i++) {
++              if (of_property_read_string_index(node, "clock-output-names",
++                                                i, &clk_name) != 0)
++                      break;
++
++              gate_hw = NULL;
++              rate_hw = NULL;
++              rate_ops = NULL;
++
++              /* If this leaf clock can be gated, create a gate */
++              if (data->div[i].gate) {
++                      gate = kzalloc(sizeof(*gate), GFP_KERNEL);
++                      if (!gate)
++                              goto free_clks;
++
++                      gate->reg = reg;
++                      gate->bit_idx = data->div[i].gate;
++                      gate->lock = &clk_lock;
++
++                      gate_hw = &gate->hw;
++              }
++
++              /* Leaves can be fixed or configurable divisors */
++              if (data->div[i].fixed) {
++                      fix_factor = kzalloc(sizeof(*fix_factor), GFP_KERNEL);
++                      if (!fix_factor)
++                              goto free_gate;
++
++                      fix_factor->mult = 1;
++                      fix_factor->div = data->div[i].fixed;
++
++                      rate_hw = &fix_factor->hw;
++                      rate_ops = &clk_fixed_factor_ops;
++              } else {
++                      divider = kzalloc(sizeof(*divider), GFP_KERNEL);
++                      if (!divider)
++                              goto free_gate;
++
++                      flags = data->div[i].pow ? CLK_DIVIDER_POWER_OF_TWO : 0;
++
++                      divider->reg = reg;
++                      divider->shift = data->div[i].shift;
++                      divider->width = SUNXI_DIVISOR_WIDTH;
++                      divider->flags = flags;
++                      divider->lock = &clk_lock;
++                      divider->table = data->div[i].table;
++
++                      rate_hw = &divider->hw;
++                      rate_ops = &clk_divider_ops;
++              }
++
++              /* Wrap the (potential) gate and the divisor on a composite
++               * clock to unify them */
++              clks[i] = clk_register_composite(NULL, clk_name, &parent, 1,
++                                               NULL, NULL,
++                                               rate_hw, rate_ops,
++                                               gate_hw, &clk_gate_ops,
++                                               clkflags);
++
++              WARN_ON(IS_ERR(clk_data->clks[i]));
++              clk_register_clkdev(clks[i], clk_name, NULL);
++      }
++
++      /* The last clock available on the getter is the parent */
++      clks[i++] = pclk;
++
++      /* Adjust to the real max */
++      clk_data->clk_num = i;
++
++      of_clk_add_provider(node, of_clk_src_onecell_get, clk_data);
++
++      return;
++
++free_gate:
++      kfree(gate);
++free_clks:
++      kfree(clks);
++free_clkdata:
++      kfree(clk_data);
++}
++
++
++
+ /* Matches for factors clocks */
+ static const struct of_device_id clk_factors_match[] __initconst = {
+       {.compatible = "allwinner,sun4i-pll1-clk", .data = &sun4i_pll1_data,},
+@@ -644,6 +864,13 @@ static void __init sunxi_gates_clk_setup(struct device_node *node,
+       {}
+ };
++/* Matches for divided outputs */
++static const struct of_device_id clk_divs_match[] __initconst = {
++      {.compatible = "allwinner,sun4i-pll5-clk", .data = &pll5_divs_data,},
++      {.compatible = "allwinner,sun4i-pll6-clk", .data = &pll6_divs_data,},
++      {}
++};
++
+ /* Matches for mux clocks */
+ static const struct of_device_id clk_mux_match[] __initconst = {
+       {.compatible = "allwinner,sun4i-cpu-clk", .data = &sun4i_cpu_mux_data,},
+@@ -721,6 +948,9 @@ static void __init sunxi_init_clocks(struct device_node *np)
+       /* Register divider clocks */
+       of_sunxi_table_clock_setup(clk_div_match, sunxi_divider_clk_setup);
++      /* Register divided output clocks */
++      of_sunxi_table_clock_setup(clk_divs_match, sunxi_divs_clk_setup);
++
+       /* Register mux clocks */
+       of_sunxi_table_clock_setup(clk_mux_match, sunxi_mux_clk_setup);
+-- 
+1.8.5.1
+
diff --git a/target/linux/sunxi/patches-3.13/119-dt-sunxi-add-pll5-pll6.patch b/target/linux/sunxi/patches-3.13/119-dt-sunxi-add-pll5-pll6.patch
new file mode 100644 (file)
index 0000000..bfc278c
--- /dev/null
@@ -0,0 +1,198 @@
+From 6d3ca59232090bff1b5e1abfd3417a3859e47425 Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?Emilio=20L=C3=B3pez?= <emilio@elopez.com.ar>
+Date: Mon, 23 Dec 2013 00:32:38 -0300
+Subject: [PATCH] ARM: sunxi: add PLL5 and PLL6 support
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+This commit adds PLL5 and PLL6 nodes to the sun4i, sun5i and sun7i
+device trees.
+
+Signed-off-by: Emilio López <emilio@elopez.com.ar>
+Acked-by: Maxime Ripard <maxime.ripard@free-electrons.com>
+---
+ arch/arm/boot/dts/sun4i-a10.dtsi  | 19 +++++++++++++++++--
+ arch/arm/boot/dts/sun5i-a10s.dtsi | 19 +++++++++++++++++--
+ arch/arm/boot/dts/sun5i-a13.dtsi  | 19 +++++++++++++++++--
+ arch/arm/boot/dts/sun7i-a20.dtsi  | 28 ++++++++++++++++------------
+ 4 files changed, 67 insertions(+), 18 deletions(-)
+
+diff --git a/arch/arm/boot/dts/sun4i-a10.dtsi b/arch/arm/boot/dts/sun4i-a10.dtsi
+index 1d6346c..07564e9e 100644
+--- a/arch/arm/boot/dts/sun4i-a10.dtsi
++++ b/arch/arm/boot/dts/sun4i-a10.dtsi
+@@ -77,6 +77,22 @@
+                       clocks = <&osc24M>;
+               };
++              pll5: pll5@01c20020 {
++                      #clock-cells = <1>;
++                      compatible = "allwinner,sun4i-pll5-clk";
++                      reg = <0x01c20020 0x4>;
++                      clocks = <&osc24M>;
++                      clock-output-names = "pll5_ddr", "pll5_other";
++              };
++
++              pll6: pll6@01c20028 {
++                      #clock-cells = <1>;
++                      compatible = "allwinner,sun4i-pll6-clk";
++                      reg = <0x01c20028 0x4>;
++                      clocks = <&osc24M>;
++                      clock-output-names = "pll6_sata", "pll6_other", "pll6";
++              };
++
+               /* dummy is 200M */
+               cpu: cpu@01c20054 {
+                       #clock-cells = <0>;
+@@ -142,12 +158,11 @@
+                               "apb0_ir1", "apb0_keypad";
+               };
+-              /* dummy is pll62 */
+               apb1_mux: apb1_mux@01c20058 {
+                       #clock-cells = <0>;
+                       compatible = "allwinner,sun4i-apb1-mux-clk";
+                       reg = <0x01c20058 0x4>;
+-                      clocks = <&osc24M>, <&dummy>, <&osc32k>;
++                      clocks = <&osc24M>, <&pll6 1>, <&osc32k>;
+               };
+               apb1: apb1@01c20058 {
+diff --git a/arch/arm/boot/dts/sun5i-a10s.dtsi b/arch/arm/boot/dts/sun5i-a10s.dtsi
+index 64d6d75..ca19362 100644
+--- a/arch/arm/boot/dts/sun5i-a10s.dtsi
++++ b/arch/arm/boot/dts/sun5i-a10s.dtsi
+@@ -74,6 +74,22 @@
+                       clocks = <&osc24M>;
+               };
++              pll5: pll5@01c20020 {
++                      #clock-cells = <1>;
++                      compatible = "allwinner,sun4i-pll5-clk";
++                      reg = <0x01c20020 0x4>;
++                      clocks = <&osc24M>;
++                      clock-output-names = "pll5_ddr", "pll5_other";
++              };
++
++              pll6: pll6@01c20028 {
++                      #clock-cells = <1>;
++                      compatible = "allwinner,sun4i-pll6-clk";
++                      reg = <0x01c20028 0x4>;
++                      clocks = <&osc24M>;
++                      clock-output-names = "pll6_sata", "pll6_other", "pll6";
++              };
++
+               /* dummy is 200M */
+               cpu: cpu@01c20054 {
+                       #clock-cells = <0>;
+@@ -134,12 +150,11 @@
+                               "apb0_ir", "apb0_keypad";
+               };
+-              /* dummy is pll62 */
+               apb1_mux: apb1_mux@01c20058 {
+                       #clock-cells = <0>;
+                       compatible = "allwinner,sun4i-apb1-mux-clk";
+                       reg = <0x01c20058 0x4>;
+-                      clocks = <&osc24M>, <&dummy>, <&osc32k>;
++                      clocks = <&osc24M>, <&pll6 1>, <&osc32k>;
+               };
+               apb1: apb1@01c20058 {
+diff --git a/arch/arm/boot/dts/sun5i-a13.dtsi b/arch/arm/boot/dts/sun5i-a13.dtsi
+index 2c355c8..9ac706a 100644
+--- a/arch/arm/boot/dts/sun5i-a13.dtsi
++++ b/arch/arm/boot/dts/sun5i-a13.dtsi
+@@ -74,6 +74,22 @@
+                       clocks = <&osc24M>;
+               };
++              pll5: pll5@01c20020 {
++                      #clock-cells = <1>;
++                      compatible = "allwinner,sun4i-pll5-clk";
++                      reg = <0x01c20020 0x4>;
++                      clocks = <&osc24M>;
++                      clock-output-names = "pll5_ddr", "pll5_other";
++              };
++
++              pll6: pll6@01c20028 {
++                      #clock-cells = <1>;
++                      compatible = "allwinner,sun4i-pll6-clk";
++                      reg = <0x01c20028 0x4>;
++                      clocks = <&osc24M>;
++                      clock-output-names = "pll6_sata", "pll6_other", "pll6";
++              };
++
+               /* dummy is 200M */
+               cpu: cpu@01c20054 {
+                       #clock-cells = <0>;
+@@ -132,12 +148,11 @@
+                       clock-output-names = "apb0_codec", "apb0_pio", "apb0_ir";
+               };
+-              /* dummy is pll6 */
+               apb1_mux: apb1_mux@01c20058 {
+                       #clock-cells = <0>;
+                       compatible = "allwinner,sun4i-apb1-mux-clk";
+                       reg = <0x01c20058 0x4>;
+-                      clocks = <&osc24M>, <&dummy>, <&osc32k>;
++                      clocks = <&osc24M>, <&pll6 1>, <&osc32k>;
+               };
+               apb1: apb1@01c20058 {
+diff --git a/arch/arm/boot/dts/sun7i-a20.dtsi b/arch/arm/boot/dts/sun7i-a20.dtsi
+index 18144f0..9176ed0 100644
+--- a/arch/arm/boot/dts/sun7i-a20.dtsi
++++ b/arch/arm/boot/dts/sun7i-a20.dtsi
+@@ -73,23 +73,27 @@
+                       clocks = <&osc24M>;
+               };
+-              /*
+-               * This is a dummy clock, to be used as placeholder on
+-               * other mux clocks when a specific parent clock is not
+-               * yet implemented. It should be dropped when the driver
+-               * is complete.
+-               */
+-              pll6: pll6 {
+-                      #clock-cells = <0>;
+-                      compatible = "fixed-clock";
+-                      clock-frequency = <0>;
++              pll5: pll5@01c20020 {
++                      #clock-cells = <1>;
++                      compatible = "allwinner,sun4i-pll5-clk";
++                      reg = <0x01c20020 0x4>;
++                      clocks = <&osc24M>;
++                      clock-output-names = "pll5_ddr", "pll5_other";
++              };
++
++              pll6: pll6@01c20028 {
++                      #clock-cells = <1>;
++                      compatible = "allwinner,sun4i-pll6-clk";
++                      reg = <0x01c20028 0x4>;
++                      clocks = <&osc24M>;
++                      clock-output-names = "pll6_sata", "pll6_other", "pll6";
+               };
+               cpu: cpu@01c20054 {
+                       #clock-cells = <0>;
+                       compatible = "allwinner,sun4i-cpu-clk";
+                       reg = <0x01c20054 0x4>;
+-                      clocks = <&osc32k>, <&osc24M>, <&pll1>, <&pll6>;
++                      clocks = <&osc32k>, <&osc24M>, <&pll1>, <&pll6 1>;
+               };
+               axi: axi@01c20054 {
+@@ -148,7 +152,7 @@
+                       #clock-cells = <0>;
+                       compatible = "allwinner,sun4i-apb1-mux-clk";
+                       reg = <0x01c20058 0x4>;
+-                      clocks = <&osc24M>, <&pll6>, <&osc32k>;
++                      clocks = <&osc24M>, <&pll6 1>, <&osc32k>;
+               };
+               apb1: apb1@01c20058 {
+-- 
+1.8.5.1
+
diff --git a/target/linux/sunxi/patches-3.13/120-clk-sunxi-mod0.patch b/target/linux/sunxi/patches-3.13/120-clk-sunxi-mod0.patch
new file mode 100644 (file)
index 0000000..34a2a2a
--- /dev/null
@@ -0,0 +1,129 @@
+From bdc913d1ef5143a8728ae414fcb90f9ed87a58da Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?Emilio=20L=C3=B3pez?= <emilio@elopez.com.ar>
+Date: Mon, 23 Dec 2013 00:32:39 -0300
+Subject: [PATCH] clk: sunxi: mod0 support
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+This commit implements support for the "module 0" type of clocks, as
+used by MMC, IR, NAND, SATA and other components.
+
+Signed-off-by: Emilio López <emilio@elopez.com.ar>
+Acked-by: Mike Turquette <mturquette@linaro.org>
+---
+ Documentation/devicetree/bindings/clock/sunxi.txt |  5 +-
+ drivers/clk/sunxi/clk-sunxi.c                     | 57 +++++++++++++++++++++++
+ 2 files changed, 61 insertions(+), 1 deletion(-)
+
+diff --git a/Documentation/devicetree/bindings/clock/sunxi.txt b/Documentation/devicetree/bindings/clock/sunxi.txt
+index 80b2a39..46d8433 100644
+--- a/Documentation/devicetree/bindings/clock/sunxi.txt
++++ b/Documentation/devicetree/bindings/clock/sunxi.txt
+@@ -35,10 +35,13 @@ Required properties:
+       "allwinner,sun7i-a20-apb1-gates-clk" - for the APB1 gates on A20
+       "allwinner,sun6i-a31-apb2-div-clk" - for the APB2 gates on A31
+       "allwinner,sun6i-a31-apb2-gates-clk" - for the APB2 gates on A31
++      "allwinner,sun4i-mod0-clk" - for the module 0 family of clocks
+ Required properties for all clocks:
+ - reg : shall be the control register address for the clock.
+-- clocks : shall be the input parent clock(s) phandle for the clock
++- clocks : shall be the input parent clock(s) phandle for the clock. For
++      multiplexed clocks, the list order must match the hardware
++      programming order.
+ - #clock-cells : from common clock binding; shall be set to 0 except for
+       "allwinner,*-gates-clk" where it shall be set to 1
+diff --git a/drivers/clk/sunxi/clk-sunxi.c b/drivers/clk/sunxi/clk-sunxi.c
+index 649d7c3..af99b57 100644
+--- a/drivers/clk/sunxi/clk-sunxi.c
++++ b/drivers/clk/sunxi/clk-sunxi.c
+@@ -295,6 +295,47 @@ static void sun4i_get_apb1_factors(u32 *freq, u32 parent_rate,
+ /**
++ * sun4i_get_mod0_factors() - calculates m, n factors for MOD0-style clocks
++ * MMC rate is calculated as follows
++ * rate = (parent_rate >> p) / (m + 1);
++ */
++
++static void sun4i_get_mod0_factors(u32 *freq, u32 parent_rate,
++                                 u8 *n, u8 *k, u8 *m, u8 *p)
++{
++      u8 div, calcm, calcp;
++
++      /* These clocks can only divide, so we will never be able to achieve
++       * frequencies higher than the parent frequency */
++      if (*freq > parent_rate)
++              *freq = parent_rate;
++
++      div = parent_rate / *freq;
++
++      if (div < 16)
++              calcp = 0;
++      else if (div / 2 < 16)
++              calcp = 1;
++      else if (div / 4 < 16)
++              calcp = 2;
++      else
++              calcp = 3;
++
++      calcm = DIV_ROUND_UP(div, 1 << calcp);
++
++      *freq = (parent_rate >> calcp) / calcm;
++
++      /* we were called to round the frequency, we can now return */
++      if (n == NULL)
++              return;
++
++      *m = calcm - 1;
++      *p = calcp;
++}
++
++
++
++/**
+  * sunxi_factors_clk_setup() - Setup function for factor clocks
+  */
+@@ -341,6 +382,14 @@ struct factors_data {
+       .pwidth = 2,
+ };
++/* user manual says "n" but it's really "p" */
++static struct clk_factors_config sun4i_mod0_config = {
++      .mshift = 0,
++      .mwidth = 4,
++      .pshift = 16,
++      .pwidth = 2,
++};
++
+ static const struct factors_data sun4i_pll1_data __initconst = {
+       .enable = 31,
+       .table = &sun4i_pll1_config,
+@@ -364,6 +413,13 @@ struct factors_data {
+       .getter = sun4i_get_apb1_factors,
+ };
++static const struct factors_data sun4i_mod0_data __initconst = {
++      .enable = 31,
++      .mux = 24,
++      .table = &sun4i_mod0_config,
++      .getter = sun4i_get_mod0_factors,
++};
++
+ static struct clk * __init sunxi_factors_clk_setup(struct device_node *node,
+                                               const struct factors_data *data)
+ {
+@@ -852,6 +908,7 @@ static void __init sunxi_divs_clk_setup(struct device_node *node,
+       {.compatible = "allwinner,sun4i-pll1-clk", .data = &sun4i_pll1_data,},
+       {.compatible = "allwinner,sun6i-a31-pll1-clk", .data = &sun6i_a31_pll1_data,},
+       {.compatible = "allwinner,sun4i-apb1-clk", .data = &sun4i_apb1_data,},
++      {.compatible = "allwinner,sun4i-mod0-clk", .data = &sun4i_mod0_data,},
+       {}
+ };
+-- 
+1.8.5.1
+
diff --git a/target/linux/sunxi/patches-3.13/121-clk-sunxi-better-factor-dt-nodes.patch b/target/linux/sunxi/patches-3.13/121-clk-sunxi-better-factor-dt-nodes.patch
new file mode 100644 (file)
index 0000000..175f115
--- /dev/null
@@ -0,0 +1,52 @@
+From 7d47b009bf287bf5e0817f47c40e32b7ec0e8151 Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?Emilio=20L=C3=B3pez?= <emilio@elopez.com.ar>
+Date: Mon, 23 Dec 2013 00:32:40 -0300
+Subject: [PATCH] clk: sunxi: support better factor DT nodes
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+The DT nodes should look like
+
+    abc_clk: clk@deadbeef {
+        ...
+        clock-output-names = "abc";
+    }
+
+But our old DT nodes look like
+
+    abc: abc@deadbeef {
+        ...
+    }
+
+So, let's support both formats, until we can transition everything
+to the new, correct one.
+
+Signed-off-by: Emilio López <emilio@elopez.com.ar>
+---
+ drivers/clk/sunxi/clk-sunxi.c | 9 +++++++++
+ 1 file changed, 9 insertions(+)
+
+diff --git a/drivers/clk/sunxi/clk-sunxi.c b/drivers/clk/sunxi/clk-sunxi.c
+index af99b57..81d4c72 100644
+--- a/drivers/clk/sunxi/clk-sunxi.c
++++ b/drivers/clk/sunxi/clk-sunxi.c
+@@ -441,6 +441,15 @@ static struct clk * __init sunxi_factors_clk_setup(struct device_node *node,
+              (parents[i] = of_clk_get_parent_name(node, i)) != NULL)
+               i++;
++      /* Nodes should be providing the name via clock-output-names
++       * but originally our dts didn't, and so we used node->name.
++       * The new, better nodes look like clk@deadbeef, so we pull the
++       * name just in this case */
++      if (!strcmp("clk", clk_name)) {
++              of_property_read_string_index(node, "clock-output-names",
++                                            0, &clk_name);
++      }
++
+       factors = kzalloc(sizeof(struct clk_factors), GFP_KERNEL);
+       if (!factors)
+               return NULL;
+-- 
+1.8.5.1
+
diff --git a/target/linux/sunxi/patches-3.13/122-1-dt-sun4i-add-mod0.patch b/target/linux/sunxi/patches-3.13/122-1-dt-sun4i-add-mod0.patch
new file mode 100644 (file)
index 0000000..e635f2e
--- /dev/null
@@ -0,0 +1,150 @@
+From dda274b6f95902b619af1fb14f26e231bb420371 Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?Emilio=20L=C3=B3pez?= <emilio@elopez.com.ar>
+Date: Mon, 23 Dec 2013 00:32:41 -0300
+Subject: [PATCH] ARM: sun4i: dt: mod0 clocks
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+This commit adds all the mod0 clocks present on sun4i to its device tree
+
+Signed-off-by: Emilio López <emilio@elopez.com.ar>
+Acked-by: Maxime Ripard <maxime.ripard@free-electrons.com>
+---
+ arch/arm/boot/dts/sun4i-a10.dtsi | 120 +++++++++++++++++++++++++++++++++++++++
+ 1 file changed, 120 insertions(+)
+
+diff --git a/arch/arm/boot/dts/sun4i-a10.dtsi b/arch/arm/boot/dts/sun4i-a10.dtsi
+index 07564e9e..3ba2b46 100644
+--- a/arch/arm/boot/dts/sun4i-a10.dtsi
++++ b/arch/arm/boot/dts/sun4i-a10.dtsi
+@@ -184,6 +184,126 @@
+                               "apb1_uart4", "apb1_uart5", "apb1_uart6",
+                               "apb1_uart7";
+               };
++
++              nand_clk: clk@01c20080 {
++                      #clock-cells = <0>;
++                      compatible = "allwinner,sun4i-mod0-clk";
++                      reg = <0x01c20080 0x4>;
++                      clocks = <&osc24M>, <&pll6 1>, <&pll5 1>;
++                      clock-output-names = "nand";
++              };
++
++              ms_clk: clk@01c20084 {
++                      #clock-cells = <0>;
++                      compatible = "allwinner,sun4i-mod0-clk";
++                      reg = <0x01c20084 0x4>;
++                      clocks = <&osc24M>, <&pll6 1>, <&pll5 1>;
++                      clock-output-names = "ms";
++              };
++
++              mmc0_clk: clk@01c20088 {
++                      #clock-cells = <0>;
++                      compatible = "allwinner,sun4i-mod0-clk";
++                      reg = <0x01c20088 0x4>;
++                      clocks = <&osc24M>, <&pll6 1>, <&pll5 1>;
++                      clock-output-names = "mmc0";
++              };
++
++              mmc1_clk: clk@01c2008c {
++                      #clock-cells = <0>;
++                      compatible = "allwinner,sun4i-mod0-clk";
++                      reg = <0x01c2008c 0x4>;
++                      clocks = <&osc24M>, <&pll6 1>, <&pll5 1>;
++                      clock-output-names = "mmc1";
++              };
++
++              mmc2_clk: clk@01c20090 {
++                      #clock-cells = <0>;
++                      compatible = "allwinner,sun4i-mod0-clk";
++                      reg = <0x01c20090 0x4>;
++                      clocks = <&osc24M>, <&pll6 1>, <&pll5 1>;
++                      clock-output-names = "mmc2";
++              };
++
++              mmc3_clk: clk@01c20094 {
++                      #clock-cells = <0>;
++                      compatible = "allwinner,sun4i-mod0-clk";
++                      reg = <0x01c20094 0x4>;
++                      clocks = <&osc24M>, <&pll6 1>, <&pll5 1>;
++                      clock-output-names = "mmc3";
++              };
++
++              ts_clk: clk@01c20098 {
++                      #clock-cells = <0>;
++                      compatible = "allwinner,sun4i-mod0-clk";
++                      reg = <0x01c20098 0x4>;
++                      clocks = <&osc24M>, <&pll6 1>, <&pll5 1>;
++                      clock-output-names = "ts";
++              };
++
++              ss_clk: clk@01c2009c {
++                      #clock-cells = <0>;
++                      compatible = "allwinner,sun4i-mod0-clk";
++                      reg = <0x01c2009c 0x4>;
++                      clocks = <&osc24M>, <&pll6 1>, <&pll5 1>;
++                      clock-output-names = "ss";
++              };
++
++              spi0_clk: clk@01c200a0 {
++                      #clock-cells = <0>;
++                      compatible = "allwinner,sun4i-mod0-clk";
++                      reg = <0x01c200a0 0x4>;
++                      clocks = <&osc24M>, <&pll6 1>, <&pll5 1>;
++                      clock-output-names = "spi0";
++              };
++
++              spi1_clk: clk@01c200a4 {
++                      #clock-cells = <0>;
++                      compatible = "allwinner,sun4i-mod0-clk";
++                      reg = <0x01c200a4 0x4>;
++                      clocks = <&osc24M>, <&pll6 1>, <&pll5 1>;
++                      clock-output-names = "spi1";
++              };
++
++              spi2_clk: clk@01c200a8 {
++                      #clock-cells = <0>;
++                      compatible = "allwinner,sun4i-mod0-clk";
++                      reg = <0x01c200a8 0x4>;
++                      clocks = <&osc24M>, <&pll6 1>, <&pll5 1>;
++                      clock-output-names = "spi2";
++              };
++
++              pata_clk: clk@01c200ac {
++                      #clock-cells = <0>;
++                      compatible = "allwinner,sun4i-mod0-clk";
++                      reg = <0x01c200ac 0x4>;
++                      clocks = <&osc24M>, <&pll6 1>, <&pll5 1>;
++                      clock-output-names = "pata";
++              };
++
++              ir0_clk: clk@01c200b0 {
++                      #clock-cells = <0>;
++                      compatible = "allwinner,sun4i-mod0-clk";
++                      reg = <0x01c200b0 0x4>;
++                      clocks = <&osc24M>, <&pll6 1>, <&pll5 1>;
++                      clock-output-names = "ir0";
++              };
++
++              ir1_clk: clk@01c200b4 {
++                      #clock-cells = <0>;
++                      compatible = "allwinner,sun4i-mod0-clk";
++                      reg = <0x01c200b4 0x4>;
++                      clocks = <&osc24M>, <&pll6 1>, <&pll5 1>;
++                      clock-output-names = "ir1";
++              };
++
++              spi3_clk: clk@01c200d4 {
++                      #clock-cells = <0>;
++                      compatible = "allwinner,sun4i-mod0-clk";
++                      reg = <0x01c200d4 0x4>;
++                      clocks = <&osc24M>, <&pll6 1>, <&pll5 1>;
++                      clock-output-names = "spi3";
++              };
+       };
+       soc@01c00000 {
+-- 
+1.8.5.1
+
diff --git a/target/linux/sunxi/patches-3.13/122-2-dt-sun5i-add-mod0.patch b/target/linux/sunxi/patches-3.13/122-2-dt-sun5i-add-mod0.patch
new file mode 100644 (file)
index 0000000..bea53fe
--- /dev/null
@@ -0,0 +1,220 @@
+From 9a8d3f21c94099a2bcd79ac1684cc8020fd98df2 Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?Emilio=20L=C3=B3pez?= <emilio@elopez.com.ar>
+Date: Mon, 23 Dec 2013 00:32:42 -0300
+Subject: [PATCH] ARM: sun5i: dt: mod0 clocks
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+This commit adds all the mod0 clocks available on A10 and A13. The list
+has been constructed by looking at the Allwinner code release for A10S
+and A13.
+
+Signed-off-by: Emilio López <emilio@elopez.com.ar>
+Acked-by: Maxime Ripard <maxime.ripard@free-electrons.com>
+---
+ arch/arm/boot/dts/sun5i-a10s.dtsi | 88 +++++++++++++++++++++++++++++++++++++++
+ arch/arm/boot/dts/sun5i-a13.dtsi  | 88 +++++++++++++++++++++++++++++++++++++++
+ 2 files changed, 176 insertions(+)
+
+diff --git a/arch/arm/boot/dts/sun5i-a10s.dtsi b/arch/arm/boot/dts/sun5i-a10s.dtsi
+index ca19362..96c7185 100644
+--- a/arch/arm/boot/dts/sun5i-a10s.dtsi
++++ b/arch/arm/boot/dts/sun5i-a10s.dtsi
+@@ -173,6 +173,94 @@
+                               "apb1_i2c2", "apb1_uart0", "apb1_uart1",
+                               "apb1_uart2", "apb1_uart3";
+               };
++
++              nand_clk: clk@01c20080 {
++                      #clock-cells = <0>;
++                      compatible = "allwinner,sun4i-mod0-clk";
++                      reg = <0x01c20080 0x4>;
++                      clocks = <&osc24M>, <&pll6 1>, <&pll5 1>;
++                      clock-output-names = "nand";
++              };
++
++              ms_clk: clk@01c20084 {
++                      #clock-cells = <0>;
++                      compatible = "allwinner,sun4i-mod0-clk";
++                      reg = <0x01c20084 0x4>;
++                      clocks = <&osc24M>, <&pll6 1>, <&pll5 1>;
++                      clock-output-names = "ms";
++              };
++
++              mmc0_clk: clk@01c20088 {
++                      #clock-cells = <0>;
++                      compatible = "allwinner,sun4i-mod0-clk";
++                      reg = <0x01c20088 0x4>;
++                      clocks = <&osc24M>, <&pll6 1>, <&pll5 1>;
++                      clock-output-names = "mmc0";
++              };
++
++              mmc1_clk: clk@01c2008c {
++                      #clock-cells = <0>;
++                      compatible = "allwinner,sun4i-mod0-clk";
++                      reg = <0x01c2008c 0x4>;
++                      clocks = <&osc24M>, <&pll6 1>, <&pll5 1>;
++                      clock-output-names = "mmc1";
++              };
++
++              mmc2_clk: clk@01c20090 {
++                      #clock-cells = <0>;
++                      compatible = "allwinner,sun4i-mod0-clk";
++                      reg = <0x01c20090 0x4>;
++                      clocks = <&osc24M>, <&pll6 1>, <&pll5 1>;
++                      clock-output-names = "mmc2";
++              };
++
++              ts_clk: clk@01c20098 {
++                      #clock-cells = <0>;
++                      compatible = "allwinner,sun4i-mod0-clk";
++                      reg = <0x01c20098 0x4>;
++                      clocks = <&osc24M>, <&pll6 1>, <&pll5 1>;
++                      clock-output-names = "ts";
++              };
++
++              ss_clk: clk@01c2009c {
++                      #clock-cells = <0>;
++                      compatible = "allwinner,sun4i-mod0-clk";
++                      reg = <0x01c2009c 0x4>;
++                      clocks = <&osc24M>, <&pll6 1>, <&pll5 1>;
++                      clock-output-names = "ss";
++              };
++
++              spi0_clk: clk@01c200a0 {
++                      #clock-cells = <0>;
++                      compatible = "allwinner,sun4i-mod0-clk";
++                      reg = <0x01c200a0 0x4>;
++                      clocks = <&osc24M>, <&pll6 1>, <&pll5 1>;
++                      clock-output-names = "spi0";
++              };
++
++              spi1_clk: clk@01c200a4 {
++                      #clock-cells = <0>;
++                      compatible = "allwinner,sun4i-mod0-clk";
++                      reg = <0x01c200a4 0x4>;
++                      clocks = <&osc24M>, <&pll6 1>, <&pll5 1>;
++                      clock-output-names = "spi1";
++              };
++
++              spi2_clk: clk@01c200a8 {
++                      #clock-cells = <0>;
++                      compatible = "allwinner,sun4i-mod0-clk";
++                      reg = <0x01c200a8 0x4>;
++                      clocks = <&osc24M>, <&pll6 1>, <&pll5 1>;
++                      clock-output-names = "spi2";
++              };
++
++              ir0_clk: clk@01c200b0 {
++                      #clock-cells = <0>;
++                      compatible = "allwinner,sun4i-mod0-clk";
++                      reg = <0x01c200b0 0x4>;
++                      clocks = <&osc24M>, <&pll6 1>, <&pll5 1>;
++                      clock-output-names = "ir0";
++              };
+       };
+       soc@01c00000 {
+diff --git a/arch/arm/boot/dts/sun5i-a13.dtsi b/arch/arm/boot/dts/sun5i-a13.dtsi
+index 9ac706a..e2505d6 100644
+--- a/arch/arm/boot/dts/sun5i-a13.dtsi
++++ b/arch/arm/boot/dts/sun5i-a13.dtsi
+@@ -170,6 +170,94 @@
+                       clock-output-names = "apb1_i2c0", "apb1_i2c1",
+                               "apb1_i2c2", "apb1_uart1", "apb1_uart3";
+               };
++
++              nand_clk: clk@01c20080 {
++                      #clock-cells = <0>;
++                      compatible = "allwinner,sun4i-mod0-clk";
++                      reg = <0x01c20080 0x4>;
++                      clocks = <&osc24M>, <&pll6 1>, <&pll5 1>;
++                      clock-output-names = "nand";
++              };
++
++              ms_clk: clk@01c20084 {
++                      #clock-cells = <0>;
++                      compatible = "allwinner,sun4i-mod0-clk";
++                      reg = <0x01c20084 0x4>;
++                      clocks = <&osc24M>, <&pll6 1>, <&pll5 1>;
++                      clock-output-names = "ms";
++              };
++
++              mmc0_clk: clk@01c20088 {
++                      #clock-cells = <0>;
++                      compatible = "allwinner,sun4i-mod0-clk";
++                      reg = <0x01c20088 0x4>;
++                      clocks = <&osc24M>, <&pll6 1>, <&pll5 1>;
++                      clock-output-names = "mmc0";
++              };
++
++              mmc1_clk: clk@01c2008c {
++                      #clock-cells = <0>;
++                      compatible = "allwinner,sun4i-mod0-clk";
++                      reg = <0x01c2008c 0x4>;
++                      clocks = <&osc24M>, <&pll6 1>, <&pll5 1>;
++                      clock-output-names = "mmc1";
++              };
++
++              mmc2_clk: clk@01c20090 {
++                      #clock-cells = <0>;
++                      compatible = "allwinner,sun4i-mod0-clk";
++                      reg = <0x01c20090 0x4>;
++                      clocks = <&osc24M>, <&pll6 1>, <&pll5 1>;
++                      clock-output-names = "mmc2";
++              };
++
++              ts_clk: clk@01c20098 {
++                      #clock-cells = <0>;
++                      compatible = "allwinner,sun4i-mod0-clk";
++                      reg = <0x01c20098 0x4>;
++                      clocks = <&osc24M>, <&pll6 1>, <&pll5 1>;
++                      clock-output-names = "ts";
++              };
++
++              ss_clk: clk@01c2009c {
++                      #clock-cells = <0>;
++                      compatible = "allwinner,sun4i-mod0-clk";
++                      reg = <0x01c2009c 0x4>;
++                      clocks = <&osc24M>, <&pll6 1>, <&pll5 1>;
++                      clock-output-names = "ss";
++              };
++
++              spi0_clk: clk@01c200a0 {
++                      #clock-cells = <0>;
++                      compatible = "allwinner,sun4i-mod0-clk";
++                      reg = <0x01c200a0 0x4>;
++                      clocks = <&osc24M>, <&pll6 1>, <&pll5 1>;
++                      clock-output-names = "spi0";
++              };
++
++              spi1_clk: clk@01c200a4 {
++                      #clock-cells = <0>;
++                      compatible = "allwinner,sun4i-mod0-clk";
++                      reg = <0x01c200a4 0x4>;
++                      clocks = <&osc24M>, <&pll6 1>, <&pll5 1>;
++                      clock-output-names = "spi1";
++              };
++
++              spi2_clk: clk@01c200a8 {
++                      #clock-cells = <0>;
++                      compatible = "allwinner,sun4i-mod0-clk";
++                      reg = <0x01c200a8 0x4>;
++                      clocks = <&osc24M>, <&pll6 1>, <&pll5 1>;
++                      clock-output-names = "spi2";
++              };
++
++              ir0_clk: clk@01c200b0 {
++                      #clock-cells = <0>;
++                      compatible = "allwinner,sun4i-mod0-clk";
++                      reg = <0x01c200b0 0x4>;
++                      clocks = <&osc24M>, <&pll6 1>, <&pll5 1>;
++                      clock-output-names = "ir0";
++              };
+       };
+       soc@01c00000 {
+-- 
+1.8.5.1
+
diff --git a/target/linux/sunxi/patches-3.13/122-3-dt-sun7i-add-mod0.patch b/target/linux/sunxi/patches-3.13/122-3-dt-sun7i-add-mod0.patch
new file mode 100644 (file)
index 0000000..bf61059
--- /dev/null
@@ -0,0 +1,151 @@
+From d7904e075e3378bec09333b6a3247b3146b3dd91 Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?Emilio=20L=C3=B3pez?= <emilio@elopez.com.ar>
+Date: Mon, 23 Dec 2013 00:32:43 -0300
+Subject: [PATCH] ARM: sun7i: dt: mod0 clocks
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+This commit adds all the mod0 clocks available on A20 to its device
+tree. This list was created by looking at AW's code release.
+
+Signed-off-by: Emilio López <emilio@elopez.com.ar>
+Acked-by: Maxime Ripard <maxime.ripard@free-electrons.com>
+---
+ arch/arm/boot/dts/sun7i-a20.dtsi | 120 +++++++++++++++++++++++++++++++++++++++
+ 1 file changed, 120 insertions(+)
+
+diff --git a/arch/arm/boot/dts/sun7i-a20.dtsi b/arch/arm/boot/dts/sun7i-a20.dtsi
+index 9176ed0..f6ee631 100644
+--- a/arch/arm/boot/dts/sun7i-a20.dtsi
++++ b/arch/arm/boot/dts/sun7i-a20.dtsi
+@@ -174,6 +174,126 @@
+                               "apb1_uart2", "apb1_uart3", "apb1_uart4",
+                               "apb1_uart5", "apb1_uart6", "apb1_uart7";
+               };
++
++              nand_clk: clk@01c20080 {
++                      #clock-cells = <0>;
++                      compatible = "allwinner,sun4i-mod0-clk";
++                      reg = <0x01c20080 0x4>;
++                      clocks = <&osc24M>, <&pll6 1>, <&pll5 1>;
++                      clock-output-names = "nand";
++              };
++
++              ms_clk: clk@01c20084 {
++                      #clock-cells = <0>;
++                      compatible = "allwinner,sun4i-mod0-clk";
++                      reg = <0x01c20084 0x4>;
++                      clocks = <&osc24M>, <&pll6 1>, <&pll5 1>;
++                      clock-output-names = "ms";
++              };
++
++              mmc0_clk: clk@01c20088 {
++                      #clock-cells = <0>;
++                      compatible = "allwinner,sun4i-mod0-clk";
++                      reg = <0x01c20088 0x4>;
++                      clocks = <&osc24M>, <&pll6 1>, <&pll5 1>;
++                      clock-output-names = "mmc0";
++              };
++
++              mmc1_clk: clk@01c2008c {
++                      #clock-cells = <0>;
++                      compatible = "allwinner,sun4i-mod0-clk";
++                      reg = <0x01c2008c 0x4>;
++                      clocks = <&osc24M>, <&pll6 1>, <&pll5 1>;
++                      clock-output-names = "mmc1";
++              };
++
++              mmc2_clk: clk@01c20090 {
++                      #clock-cells = <0>;
++                      compatible = "allwinner,sun4i-mod0-clk";
++                      reg = <0x01c20090 0x4>;
++                      clocks = <&osc24M>, <&pll6 1>, <&pll5 1>;
++                      clock-output-names = "mmc2";
++              };
++
++              mmc3_clk: clk@01c20094 {
++                      #clock-cells = <0>;
++                      compatible = "allwinner,sun4i-mod0-clk";
++                      reg = <0x01c20094 0x4>;
++                      clocks = <&osc24M>, <&pll6 1>, <&pll5 1>;
++                      clock-output-names = "mmc3";
++              };
++
++              ts_clk: clk@01c20098 {
++                      #clock-cells = <0>;
++                      compatible = "allwinner,sun4i-mod0-clk";
++                      reg = <0x01c20098 0x4>;
++                      clocks = <&osc24M>, <&pll6 1>, <&pll5 1>;
++                      clock-output-names = "ts";
++              };
++
++              ss_clk: clk@01c2009c {
++                      #clock-cells = <0>;
++                      compatible = "allwinner,sun4i-mod0-clk";
++                      reg = <0x01c2009c 0x4>;
++                      clocks = <&osc24M>, <&pll6 1>, <&pll5 1>;
++                      clock-output-names = "ss";
++              };
++
++              spi0_clk: clk@01c200a0 {
++                      #clock-cells = <0>;
++                      compatible = "allwinner,sun4i-mod0-clk";
++                      reg = <0x01c200a0 0x4>;
++                      clocks = <&osc24M>, <&pll6 1>, <&pll5 1>;
++                      clock-output-names = "spi0";
++              };
++
++              spi1_clk: clk@01c200a4 {
++                      #clock-cells = <0>;
++                      compatible = "allwinner,sun4i-mod0-clk";
++                      reg = <0x01c200a4 0x4>;
++                      clocks = <&osc24M>, <&pll6 1>, <&pll5 1>;
++                      clock-output-names = "spi1";
++              };
++
++              spi2_clk: clk@01c200a8 {
++                      #clock-cells = <0>;
++                      compatible = "allwinner,sun4i-mod0-clk";
++                      reg = <0x01c200a8 0x4>;
++                      clocks = <&osc24M>, <&pll6 1>, <&pll5 1>;
++                      clock-output-names = "spi2";
++              };
++
++              pata_clk: clk@01c200ac {
++                      #clock-cells = <0>;
++                      compatible = "allwinner,sun4i-mod0-clk";
++                      reg = <0x01c200ac 0x4>;
++                      clocks = <&osc24M>, <&pll6 1>, <&pll5 1>;
++                      clock-output-names = "pata";
++              };
++
++              ir0_clk: clk@01c200b0 {
++                      #clock-cells = <0>;
++                      compatible = "allwinner,sun4i-mod0-clk";
++                      reg = <0x01c200b0 0x4>;
++                      clocks = <&osc24M>, <&pll6 1>, <&pll5 1>;
++                      clock-output-names = "ir0";
++              };
++
++              ir1_clk: clk@01c200b4 {
++                      #clock-cells = <0>;
++                      compatible = "allwinner,sun4i-mod0-clk";
++                      reg = <0x01c200b4 0x4>;
++                      clocks = <&osc24M>, <&pll6 1>, <&pll5 1>;
++                      clock-output-names = "ir1";
++              };
++
++              spi3_clk: clk@01c200d4 {
++                      #clock-cells = <0>;
++                      compatible = "allwinner,sun4i-mod0-clk";
++                      reg = <0x01c200d4 0x4>;
++                      clocks = <&osc24M>, <&pll6 1>, <&pll5 1>;
++                      clock-output-names = "spi3";
++              };
+       };
+       soc@01c00000 {
+-- 
+1.8.5.1
+
diff --git a/target/linux/sunxi/patches-3.13/123-clk-sunxi-automatic-reparenting.patch b/target/linux/sunxi/patches-3.13/123-clk-sunxi-automatic-reparenting.patch
new file mode 100644 (file)
index 0000000..c772b9f
--- /dev/null
@@ -0,0 +1,73 @@
+From 04b5b3f9c83c0c0b472c4704d83ec7f56a485a21 Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?Emilio=20L=C3=B3pez?= <emilio@elopez.com.ar>
+Date: Thu, 5 Sep 2013 19:52:41 -0300
+Subject: [PATCH] clk: sunxi: factors: automatic reparenting support
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+This commit implements .determine_rate, so that our factor clocks can be
+reparented when needed.
+
+Signed-off-by: Emilio López <emilio@elopez.com.ar>
+---
+ drivers/clk/sunxi/clk-factors.c | 36 ++++++++++++++++++++++++++++++++++++
+ 1 file changed, 36 insertions(+)
+
+diff --git a/drivers/clk/sunxi/clk-factors.c b/drivers/clk/sunxi/clk-factors.c
+index 9e23264..3806d97 100644
+--- a/drivers/clk/sunxi/clk-factors.c
++++ b/drivers/clk/sunxi/clk-factors.c
+@@ -77,6 +77,41 @@ static long clk_factors_round_rate(struct clk_hw *hw, unsigned long rate,
+       return rate;
+ }
++static long clk_factors_determine_rate(struct clk_hw *hw, unsigned long rate,
++                                     unsigned long *best_parent_rate,
++                                     struct clk **best_parent_p)
++{
++      struct clk *clk = hw->clk, *parent, *best_parent = NULL;
++      int i, num_parents;
++      unsigned long parent_rate, best = 0, child_rate, best_child_rate = 0;
++
++      /* find the parent that can help provide the fastest rate <= rate */
++      num_parents = __clk_get_num_parents(clk);
++      for (i = 0; i < num_parents; i++) {
++              parent = clk_get_parent_by_index(clk, i);
++              if (!parent)
++                      continue;
++              if (__clk_get_flags(clk) & CLK_SET_RATE_PARENT)
++                      parent_rate = __clk_round_rate(parent, rate);
++              else
++                      parent_rate = __clk_get_rate(parent);
++
++              child_rate = clk_factors_round_rate(hw, rate, &parent_rate);
++
++              if (child_rate <= rate && child_rate > best_child_rate) {
++                      best_parent = parent;
++                      best = parent_rate;
++                      best_child_rate = child_rate;
++              }
++      }
++
++      if (best_parent)
++              *best_parent_p = best_parent;
++      *best_parent_rate = best;
++
++      return best_child_rate;
++}
++
+ static int clk_factors_set_rate(struct clk_hw *hw, unsigned long rate,
+                               unsigned long parent_rate)
+ {
+@@ -113,6 +148,7 @@ static int clk_factors_set_rate(struct clk_hw *hw, unsigned long rate,
+ }
+ const struct clk_ops clk_factors_ops = {
++      .determine_rate = clk_factors_determine_rate,
+       .recalc_rate = clk_factors_recalc_rate,
+       .round_rate = clk_factors_round_rate,
+       .set_rate = clk_factors_set_rate,
+-- 
+1.8.5.1
+
diff --git a/target/linux/sunxi/patches-3.13/124-clk-sunxi-muxable-ahb-clock.patch b/target/linux/sunxi/patches-3.13/124-clk-sunxi-muxable-ahb-clock.patch
new file mode 100644 (file)
index 0000000..83b69b5
--- /dev/null
@@ -0,0 +1,102 @@
+From 9490107c16c8eaa35b07794e19d5d2eddea8e44b Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?Emilio=20L=C3=B3pez?= <emilio@elopez.com.ar>
+Date: Sat, 14 Sep 2013 20:48:40 -0300
+Subject: [PATCH] clk: sunxi: Implement muxable AHB clock
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+sun5i and sun7i have a mux to change the AHB clock parent, this commit
+adds support for it on the driver.
+
+Signed-off-by: Emilio López <emilio@elopez.com.ar>
+---
+ Documentation/devicetree/bindings/clock/sunxi.txt |  1 +
+ drivers/clk/sunxi/clk-sunxi.c                     | 37 +++++++++++++++++++++++
+ 2 files changed, 38 insertions(+)
+
+diff --git a/Documentation/devicetree/bindings/clock/sunxi.txt b/Documentation/devicetree/bindings/clock/sunxi.txt
+index e840cb2..941bd93 100644
+--- a/Documentation/devicetree/bindings/clock/sunxi.txt
++++ b/Documentation/devicetree/bindings/clock/sunxi.txt
+@@ -15,6 +15,7 @@ Required properties:
+       "allwinner,sun4i-axi-clk" - for the AXI clock
+       "allwinner,sun4i-axi-gates-clk" - for the AXI gates
+       "allwinner,sun4i-ahb-clk" - for the AHB clock
++      "allwinner,sun5i-a13-ahb-clk" - for the AHB clock on A13
+       "allwinner,sun4i-ahb-gates-clk" - for the AHB gates on A10
+       "allwinner,sun5i-a13-ahb-gates-clk" - for the AHB gates on A13
+       "allwinner,sun5i-a10s-ahb-gates-clk" - for the AHB gates on A10s
+diff --git a/drivers/clk/sunxi/clk-sunxi.c b/drivers/clk/sunxi/clk-sunxi.c
+index ea3edeb..625089b 100644
+--- a/drivers/clk/sunxi/clk-sunxi.c
++++ b/drivers/clk/sunxi/clk-sunxi.c
+@@ -249,7 +249,32 @@ static void sun4i_get_pll5_factors(u32 *freq, u32 parent_rate,
+       *n = DIV_ROUND_UP(div, (*k+1));
+ }
++/**
++ * sun5i_get_ahb_factors() - calculates p factor for AHB
++ * AHB rate is calculated as follows
++ * rate = parent_rate >> p
++ */
++static void sun5i_a13_get_ahb_factors(u32 *freq, u32 parent_rate,
++                                    u8 *n, u8 *k, u8 *m, u8 *p)
++{
++      u8 div;
++
++      /* This clock can only divide, so we will never achieve a higher
++       * rate than the parent's */
++      if (*freq > parent_rate)
++              *freq = parent_rate;
++
++      /* Normalize value to a parent multiple */
++      div = *freq / parent_rate;
++      *freq = parent_rate * div;
++
++      /* we were called to round the frequency, we can now return */
++      if (n == NULL)
++              return;
++
++      *p = div;
++}
+ /**
+  * sun4i_get_apb1_factors() - calculates m, p factors for APB1
+@@ -375,6 +400,11 @@ struct factors_data {
+       .kwidth = 2,
+ };
++static struct clk_factors_config sun5i_a13_ahb_config = {
++      .pshift = 4,
++      .pwidth = 2,
++};
++
+ static struct clk_factors_config sun4i_apb1_config = {
+       .mshift = 0,
+       .mwidth = 5,
+@@ -408,6 +438,12 @@ struct factors_data {
+       .getter = sun4i_get_pll5_factors,
+ };
++static const struct factors_data sun5i_a13_ahb_data __initconst = {
++      .mux = 6,
++      .table = &sun5i_a13_ahb_config,
++      .getter = sun5i_a13_get_ahb_factors,
++};
++
+ static const struct factors_data sun4i_apb1_data __initconst = {
+       .mux = 24,
+       .table = &sun4i_apb1_config,
+@@ -913,6 +949,7 @@ static void __init sunxi_divs_clk_setup(struct device_node *node,
+ static const struct of_device_id clk_factors_match[] __initconst = {
+       {.compatible = "allwinner,sun4i-pll1-clk", .data = &sun4i_pll1_data,},
+       {.compatible = "allwinner,sun6i-a31-pll1-clk", .data = &sun6i_a31_pll1_data,},
++      {.compatible = "allwinner,sun5i-a13-ahb-clk", .data = &sun5i_a13_ahb_data,},
+       {.compatible = "allwinner,sun4i-apb1-clk", .data = &sun4i_apb1_data,},
+       {.compatible = "allwinner,sun4i-mod0-clk", .data = &sun4i_mod0_data,},
+       {}
+-- 
+1.8.5.1
+
diff --git a/target/linux/sunxi/patches-3.13/125-dt-sunxi-update-ahb-clock-sun57i.patch b/target/linux/sunxi/patches-3.13/125-dt-sunxi-update-ahb-clock-sun57i.patch
new file mode 100644 (file)
index 0000000..6e1dc68
--- /dev/null
@@ -0,0 +1,69 @@
+From c8fe5648aff581545ce5744f73ee1312080b8ef4 Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?Emilio=20L=C3=B3pez?= <emilio@elopez.com.ar>
+Date: Sat, 14 Sep 2013 20:44:03 -0300
+Subject: [PATCH] ARM: sunxi: dt: Update AHB clock to be muxable on sun[57]i
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+sun5i and sun7i have a mux to select the parent clock for AHB. This
+commit implements the required changes on the device trees.
+
+Signed-off-by: Emilio López <emilio@elopez.com.ar>
+---
+ arch/arm/boot/dts/sun5i-a10s.dtsi | 4 ++--
+ arch/arm/boot/dts/sun5i-a13.dtsi  | 4 ++--
+ arch/arm/boot/dts/sun7i-a20.dtsi  | 4 ++--
+ 3 files changed, 6 insertions(+), 6 deletions(-)
+
+diff --git a/arch/arm/boot/dts/sun5i-a10s.dtsi b/arch/arm/boot/dts/sun5i-a10s.dtsi
+index fd3acbd..c42ed2a 100644
+--- a/arch/arm/boot/dts/sun5i-a10s.dtsi
++++ b/arch/arm/boot/dts/sun5i-a10s.dtsi
+@@ -115,9 +115,9 @@
+               ahb: ahb@01c20054 {
+                       #clock-cells = <0>;
+-                      compatible = "allwinner,sun4i-ahb-clk";
++                      compatible = "allwinner,sun5i-a13-ahb-clk";
+                       reg = <0x01c20054 0x4>;
+-                      clocks = <&axi>;
++                      clocks = <&axi>, <&cpu>, <&pll6 1>;
+               };
+               ahb_gates: ahb_gates@01c20060 {
+diff --git a/arch/arm/boot/dts/sun5i-a13.dtsi b/arch/arm/boot/dts/sun5i-a13.dtsi
+index 9d40bb4..8274a41 100644
+--- a/arch/arm/boot/dts/sun5i-a13.dtsi
++++ b/arch/arm/boot/dts/sun5i-a13.dtsi
+@@ -115,9 +115,9 @@
+               ahb: ahb@01c20054 {
+                       #clock-cells = <0>;
+-                      compatible = "allwinner,sun4i-ahb-clk";
++                      compatible = "allwinner,sun5i-a13-ahb-clk";
+                       reg = <0x01c20054 0x4>;
+-                      clocks = <&axi>;
++                      clocks = <&axi>, <&cpu>, <&pll6 1>;
+               };
+               ahb_gates: ahb_gates@01c20060 {
+diff --git a/arch/arm/boot/dts/sun7i-a20.dtsi b/arch/arm/boot/dts/sun7i-a20.dtsi
+index ec13310..8819c68 100644
+--- a/arch/arm/boot/dts/sun7i-a20.dtsi
++++ b/arch/arm/boot/dts/sun7i-a20.dtsi
+@@ -105,9 +105,9 @@
+               ahb: ahb@01c20054 {
+                       #clock-cells = <0>;
+-                      compatible = "allwinner,sun4i-ahb-clk";
++                      compatible = "allwinner,sun5i-a13-ahb-clk";
+                       reg = <0x01c20054 0x4>;
+-                      clocks = <&axi>;
++                      clocks = <&axi>, <&pll6 1>, <&pll6 2>;
+               };
+               ahb_gates: ahb_gates@01c20060 {
+-- 
+1.8.5.1
+
diff --git a/target/linux/sunxi/patches-3.13/126-regulator-dont-print-error-when-no-regulator-found.patch b/target/linux/sunxi/patches-3.13/126-regulator-dont-print-error-when-no-regulator-found.patch
new file mode 100644 (file)
index 0000000..b7952b8
--- /dev/null
@@ -0,0 +1,34 @@
+From 820a121fdef79cc1293e6fee2fbe8156d9e8a75a Mon Sep 17 00:00:00 2001
+From: Hans de Goede <hdegoede@redhat.com>
+Date: Wed, 11 Dec 2013 15:07:52 +0100
+Subject: [PATCH] regulator_get_optional: don't print an error when no
+ regulator is found
+
+Only print an error when _regulator_get() is expected to return a valid
+regulator, that is when _regulator_get() is called from regulator_get() and
+we're not using the dummy because we don't have full-constraints, or when
+_regulator_get() is called from regulator_get_exclusive() in which case
+returning a dummy is not allowed.
+
+Signed-off-by: Hans de Goede <hdegoede@redhat.com>
+---
+ drivers/regulator/core.c | 3 ++-
+ 1 file changed, 2 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/regulator/core.c b/drivers/regulator/core.c
+index d85f313..9888f26 100644
+--- a/drivers/regulator/core.c
++++ b/drivers/regulator/core.c
+@@ -1351,7 +1351,8 @@ static struct regulator *_regulator_get(struct device *dev, const char *id,
+               rdev = dummy_regulator_rdev;
+               goto found;
+-      } else {
++      /* Don't log an error when called from regulator_get_optional() */
++      } else if (!have_full_constraints() || exclusive) {
+               dev_err(dev, "dummy supplies not allowed\n");
+       }
+-- 
+1.8.5.1
+
diff --git a/target/linux/sunxi/patches-3.13/130-dt-sunxi-add-mbusclk.patch b/target/linux/sunxi/patches-3.13/130-dt-sunxi-add-mbusclk.patch
new file mode 100644 (file)
index 0000000..a76a97e
--- /dev/null
@@ -0,0 +1,79 @@
+From 538d4a6ca5f41039d906f28be82e0f4d26ec8ac9 Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?Emilio=20L=C3=B3pez?= <emilio@elopez.com.ar>
+Date: Mon, 23 Dec 2013 00:32:44 -0300
+Subject: [PATCH] ARM: sunxi: dt: add nodes for the mbus clock
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+mbus is the memory bus clock, and it is present on both sun5i and sun7i
+machines. Its register layout is compatible with the mod0 one.
+
+Signed-off-by: Emilio López <emilio@elopez.com.ar>
+Acked-by: Maxime Ripard <maxime.ripard@free-electrons.com>
+---
+ arch/arm/boot/dts/sun5i-a10s.dtsi | 8 ++++++++
+ arch/arm/boot/dts/sun5i-a13.dtsi  | 8 ++++++++
+ arch/arm/boot/dts/sun7i-a20.dtsi  | 8 ++++++++
+ 3 files changed, 24 insertions(+)
+
+diff --git a/arch/arm/boot/dts/sun5i-a10s.dtsi b/arch/arm/boot/dts/sun5i-a10s.dtsi
+index 96c7185..78360b3 100644
+--- a/arch/arm/boot/dts/sun5i-a10s.dtsi
++++ b/arch/arm/boot/dts/sun5i-a10s.dtsi
+@@ -261,6 +261,14 @@
+                       clocks = <&osc24M>, <&pll6 1>, <&pll5 1>;
+                       clock-output-names = "ir0";
+               };
++
++              mbus_clk: clk@01c2015c {
++                      #clock-cells = <0>;
++                      compatible = "allwinner,sun4i-mod0-clk";
++                      reg = <0x01c2015c 0x4>;
++                      clocks = <&osc24M>, <&pll6 1>, <&pll5 1>;
++                      clock-output-names = "mbus";
++              };
+       };
+       soc@01c00000 {
+diff --git a/arch/arm/boot/dts/sun5i-a13.dtsi b/arch/arm/boot/dts/sun5i-a13.dtsi
+index e2505d6..2f37ca5 100644
+--- a/arch/arm/boot/dts/sun5i-a13.dtsi
++++ b/arch/arm/boot/dts/sun5i-a13.dtsi
+@@ -258,6 +258,14 @@
+                       clocks = <&osc24M>, <&pll6 1>, <&pll5 1>;
+                       clock-output-names = "ir0";
+               };
++
++              mbus_clk: clk@01c2015c {
++                      #clock-cells = <0>;
++                      compatible = "allwinner,sun4i-mod0-clk";
++                      reg = <0x01c2015c 0x4>;
++                      clocks = <&osc24M>, <&pll6 1>, <&pll5 1>;
++                      clock-output-names = "mbus";
++              };
+       };
+       soc@01c00000 {
+diff --git a/arch/arm/boot/dts/sun7i-a20.dtsi b/arch/arm/boot/dts/sun7i-a20.dtsi
+index f6ee631..4c25f81 100644
+--- a/arch/arm/boot/dts/sun7i-a20.dtsi
++++ b/arch/arm/boot/dts/sun7i-a20.dtsi
+@@ -294,6 +294,14 @@
+                       clocks = <&osc24M>, <&pll6 1>, <&pll5 1>;
+                       clock-output-names = "spi3";
+               };
++
++              mbus_clk: clk@01c2015c {
++                      #clock-cells = <0>;
++                      compatible = "allwinner,sun4i-mod0-clk";
++                      reg = <0x01c2015c 0x4>;
++                      clocks = <&osc24M>, <&pll6 2>, <&pll5 1>;
++                      clock-output-names = "mbus";
++              };
+       };
+       soc@01c00000 {
+-- 
+1.8.5.1
+
diff --git a/target/linux/sunxi/patches-3.13/131-dt-sunxi-add-emac-aliases.patch b/target/linux/sunxi/patches-3.13/131-dt-sunxi-add-emac-aliases.patch
new file mode 100644 (file)
index 0000000..e9e929e
--- /dev/null
@@ -0,0 +1,69 @@
+From 2af807481169af627dc63f98b773c33d85020658 Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?Emilio=20L=C3=B3pez?= <emilio@elopez.com.ar>
+Date: Fri, 15 Nov 2013 15:26:44 -0300
+Subject: [PATCH] ARM: sunxi: dt: add EMAC aliases
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+U-Boot uses the ethernet0 alias to locate the right node to fill in
+the MAC address of the first ethernet interface. This patch adds the
+alias on all the sunxi SoCs with EMAC. In this way, people using
+ethernet in U-Boot (eg, for tftp) can keep a consistent address on both
+U-Boot and Linux with no additional effort.
+
+Signed-off-by: Emilio López <emilio@elopez.com.ar>
+---
+ arch/arm/boot/dts/sun4i-a10.dtsi  | 4 ++++
+ arch/arm/boot/dts/sun5i-a10s.dtsi | 4 ++++
+ arch/arm/boot/dts/sun7i-a20.dtsi  | 4 ++++
+ 3 files changed, 12 insertions(+)
+
+diff --git a/arch/arm/boot/dts/sun4i-a10.dtsi b/arch/arm/boot/dts/sun4i-a10.dtsi
+index f11f292..0bf70ee 100644
+--- a/arch/arm/boot/dts/sun4i-a10.dtsi
++++ b/arch/arm/boot/dts/sun4i-a10.dtsi
+@@ -15,6 +15,10 @@
+ / {
+       interrupt-parent = <&intc>;
++      aliases {
++              ethernet0 = &emac;
++      };
++
+       cpus {
+               #address-cells = <1>;
+               #size-cells = <0>;
+diff --git a/arch/arm/boot/dts/sun5i-a10s.dtsi b/arch/arm/boot/dts/sun5i-a10s.dtsi
+index 5247674..b4764be 100644
+--- a/arch/arm/boot/dts/sun5i-a10s.dtsi
++++ b/arch/arm/boot/dts/sun5i-a10s.dtsi
+@@ -16,6 +16,10 @@
+ / {
+       interrupt-parent = <&intc>;
++      aliases {
++              ethernet0 = &emac;
++      };
++
+       cpus {
+               cpu@0 {
+                       compatible = "arm,cortex-a8";
+diff --git a/arch/arm/boot/dts/sun7i-a20.dtsi b/arch/arm/boot/dts/sun7i-a20.dtsi
+index cc3683c..93f7f96 100644
+--- a/arch/arm/boot/dts/sun7i-a20.dtsi
++++ b/arch/arm/boot/dts/sun7i-a20.dtsi
+@@ -16,6 +16,10 @@
+ / {
+       interrupt-parent = <&gic>;
++      aliases {
++              ethernet0 = &emac;
++      };
++
+       cpus {
+               #address-cells = <1>;
+               #size-cells = <0>;
+-- 
+1.8.5.1
+
diff --git a/target/linux/sunxi/patches-3.13/132-dt-sun7i-update-eth-aliases.patch b/target/linux/sunxi/patches-3.13/132-dt-sun7i-update-eth-aliases.patch
new file mode 100644 (file)
index 0000000..b4f5009
--- /dev/null
@@ -0,0 +1,30 @@
+From dfd4430579f5e53324c00e9e21fb0929bb46542c Mon Sep 17 00:00:00 2001
+From: Chen-Yu Tsai <wens@csie.org>
+Date: Sat, 7 Dec 2013 01:29:43 +0800
+Subject: [PATCH] ARM: dts: sun7i: Add ethernet alias for GMAC
+
+U-Boot will insert MAC address into the device tree image.
+It looks up ethernet[0-5] aliases to find the ethernet nodes.
+Alias GMAC as ethernet0, as it is the only ethernet controller used.
+
+Signed-off-by: Chen-Yu Tsai <wens@csie.org>
+---
+ arch/arm/boot/dts/sun7i-a20.dtsi | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/arch/arm/boot/dts/sun7i-a20.dtsi b/arch/arm/boot/dts/sun7i-a20.dtsi
+index a0d6ef7..d718f65 100644
+--- a/arch/arm/boot/dts/sun7i-a20.dtsi
++++ b/arch/arm/boot/dts/sun7i-a20.dtsi
+@@ -17,7 +17,7 @@
+       interrupt-parent = <&gic>;
+       aliases {
+-              ethernet0 = &emac;
++              ethernet0 = &gmac;
+       };
+       cpus {
+-- 
+1.8.5.1
+
diff --git a/target/linux/sunxi/patches-3.13/133-dt-sun7i-add-arch-timers.patch b/target/linux/sunxi/patches-3.13/133-dt-sun7i-add-arch-timers.patch
new file mode 100644 (file)
index 0000000..c3b51e7
--- /dev/null
@@ -0,0 +1,38 @@
+From 26523a27f47828e50212201ba25862fe1e2b845c Mon Sep 17 00:00:00 2001
+From: Hans de Goede <hdegoede@redhat.com>
+Date: Sun, 1 Dec 2013 22:40:34 +0100
+Subject: [PATCH] ARM: dts: sun7i: Add arch timers
+
+Note this requires a new enough uboot, otherwise things won't work, ie:
+
+https://github.com/jwrdegoede/u-boot-sunxi/commits/sunxi-next
+or:
+http://xenbits.xen.org/gitweb/?p=people/ianc/u-boot.git;a=shortlog;h=refs/heads/devel/sunxi-psci
+
+Signed-off-by: Hans de Goede <hdegoede@redhat.com>
+---
+ arch/arm/boot/dts/sun7i-a20.dtsi | 8 ++++++++
+ 1 file changed, 8 insertions(+)
+
+diff --git a/arch/arm/boot/dts/sun7i-a20.dtsi b/arch/arm/boot/dts/sun7i-a20.dtsi
+index d718f65..c9c123a 100644
+--- a/arch/arm/boot/dts/sun7i-a20.dtsi
++++ b/arch/arm/boot/dts/sun7i-a20.dtsi
+@@ -297,6 +297,14 @@
+               };
+       };
++      timer {
++              compatible = "arm,armv7-timer";
++              interrupts = <1 13 0xf08>,
++                           <1 14 0xf08>,
++                           <1 11 0xf08>,
++                           <1 10 0xf08>;
++      };
++
+       soc@01c00000 {
+               compatible = "simple-bus";
+               #address-cells = <1>;
+-- 
+1.8.5.1
+
diff --git a/target/linux/sunxi/patches-3.13/135-dt-sun5i-a13-add-olinuxino-micro.patch b/target/linux/sunxi/patches-3.13/135-dt-sun5i-a13-add-olinuxino-micro.patch
new file mode 100644 (file)
index 0000000..5872d84
--- /dev/null
@@ -0,0 +1,116 @@
+From aad62992a2921436ec7c054f8b80bc916b8cc9d7 Mon Sep 17 00:00:00 2001
+From: Hans de Goede <hdegoede@redhat.com>
+Date: Sat, 14 Dec 2013 16:26:17 +0100
+Subject: [PATCH] ARM: dts: sun5i: Add new sun5i-a13-olinuxino-micro board
+
+The A13-OLinuXino-MICRO is a small dev-board with the Allwinner A13 SoC:
+https://www.olimex.com/Products/OLinuXino/A13/A13-OLinuXino-MICRO/
+
+Features:
+A13 Cortex A8 processor at 1GHz, 3D Mali400 GPU
+256 MB RAM (128Mbit x 16)
+5VDC input power supply with own ICs, noise immune design
+1 USB host
+1 USB OTG which can power the board
+SD-card connector for booting the Linux image
+VGA video output
+LCD signals available on connector so you still can use LCD if you disable VGA/HDMI
+Audio output
+Microphone input pads (no connector)
+
+Signed-off-by: Hans de Goede <hdegoede@redhat.com>
+---
+ arch/arm/boot/dts/Makefile                      |  1 +
+ arch/arm/boot/dts/sun5i-a13-olinuxino-micro.dts | 68 +++++++++++++++++++++++++
+ 2 files changed, 69 insertions(+)
+ create mode 100644 arch/arm/boot/dts/sun5i-a13-olinuxino-micro.dts
+
+diff --git a/arch/arm/boot/dts/Makefile b/arch/arm/boot/dts/Makefile
+index d57c1a6..b663ed7 100644
+--- a/arch/arm/boot/dts/Makefile
++++ b/arch/arm/boot/dts/Makefile
+@@ -255,6 +255,7 @@ dtb-$(CONFIG_ARCH_SUNXI) += \
+       sun4i-a10-hackberry.dtb \
+       sun5i-a10s-olinuxino-micro.dtb \
+       sun5i-a13-olinuxino.dtb \
++      sun5i-a13-olinuxino-micro.dtb \
+       sun6i-a31-colombus.dtb \
+       sun7i-a20-cubieboard2.dtb \
+       sun7i-a20-cubietruck.dtb \
+diff --git a/arch/arm/boot/dts/sun5i-a13-olinuxino-micro.dts b/arch/arm/boot/dts/sun5i-a13-olinuxino-micro.dts
+new file mode 100644
+index 0000000..fe2ce0a
+--- /dev/null
++++ b/arch/arm/boot/dts/sun5i-a13-olinuxino-micro.dts
+@@ -0,0 +1,68 @@
++/*
++ * Copyright 2012 Maxime Ripard
++ * Copyright 2013 Hans de Goede <hdegoede@redhat.com>
++ *
++ * Maxime Ripard <maxime.ripard@free-electrons.com>
++ *
++ * The code contained herein is licensed under the GNU General Public
++ * License. You may obtain a copy of the GNU General Public License
++ * Version 2 or later at the following locations:
++ *
++ * http://www.opensource.org/licenses/gpl-license.html
++ * http://www.gnu.org/copyleft/gpl.html
++ */
++
++/dts-v1/;
++/include/ "sun5i-a13.dtsi"
++
++/ {
++      model = "Olimex A13-Olinuxino Micro";
++      compatible = "olimex,a13-olinuxino-micro", "allwinner,sun5i-a13";
++
++      soc@01c00000 {
++              pinctrl@01c20800 {
++                      led_pins_olinuxinom: led_pins@0 {
++                              allwinner,pins = "PG9";
++                              allwinner,function = "gpio_out";
++                              allwinner,drive = <1>;
++                              allwinner,pull = <0>;
++                      };
++              };
++
++              uart1: serial@01c28400 {
++                      pinctrl-names = "default";
++                      pinctrl-0 = <&uart1_pins_b>;
++                      status = "okay";
++              };
++
++              i2c0: i2c@01c2ac00 {
++                      pinctrl-names = "default";
++                      pinctrl-0 = <&i2c0_pins_a>;
++                      status = "okay";
++              };
++
++              i2c1: i2c@01c2b000 {
++                      pinctrl-names = "default";
++                      pinctrl-0 = <&i2c1_pins_a>;
++                      status = "okay";
++              };
++
++              i2c2: i2c@01c2b400 {
++                      pinctrl-names = "default";
++                      pinctrl-0 = <&i2c2_pins_a>;
++                      status = "okay";
++              };
++      };
++
++      leds {
++              compatible = "gpio-leds";
++              pinctrl-names = "default";
++              pinctrl-0 = <&led_pins_olinuxinom>;
++
++              power {
++                      label = "a13-olinuxino-micro:green:power";
++                      gpios = <&pio 6 9 0>;
++                      default-state = "on";
++              };
++      };
++};
+-- 
+1.8.5.1
+
diff --git a/target/linux/sunxi/patches-3.13/140-sun47i-rtc-driver.patch b/target/linux/sunxi/patches-3.13/140-sun47i-rtc-driver.patch
new file mode 100644 (file)
index 0000000..7945522
--- /dev/null
@@ -0,0 +1,580 @@
+From c6890cadc2129a07d69f3dcbfca66522c27b8069 Mon Sep 17 00:00:00 2001
+From: Carlo Caione <carlo.caione@gmail.com>
+Date: Sat, 16 Nov 2013 18:33:54 +0100
+Subject: [PATCH] ARM: sun4i/sun7i: RTC driver
+
+This patch introduces the driver for the RTC in the Allwinner A10 and
+A20 SoCs.
+
+Signed-off-by: Carlo Caione <carlo.caione@gmail.com>
+Acked-by: Alessandro Zummo <a.zummo@towertech.it>
+Signed-off-by: Maxime Ripard <maxime.ripard@free-electrons.com>
+---
+ drivers/rtc/Kconfig     |   7 +
+ drivers/rtc/Makefile    |   1 +
+ drivers/rtc/rtc-sunxi.c | 523 ++++++++++++++++++++++++++++++++++++++++++++++++
+ 3 files changed, 531 insertions(+)
+ create mode 100644 drivers/rtc/rtc-sunxi.c
+
+diff --git a/drivers/rtc/Kconfig b/drivers/rtc/Kconfig
+index 0077302..c2fa86c 100644
+--- a/drivers/rtc/Kconfig
++++ b/drivers/rtc/Kconfig
+@@ -1104,6 +1104,13 @@ config RTC_DRV_SUN4V
+         If you say Y here you will get support for the Hypervisor
+         based RTC on SUN4V systems.
++config RTC_DRV_SUNXI
++      tristate "Allwinner sun4i/sun7i RTC"
++      depends on ARCH_SUNXI
++      help
++        If you say Y here you will get support for the RTC found on
++        Allwinner A10/A20.
++
+ config RTC_DRV_STARFIRE
+       bool "Starfire RTC"
+       depends on SPARC64
+diff --git a/drivers/rtc/Makefile b/drivers/rtc/Makefile
+index 27b4bd8..63f3e99 100644
+--- a/drivers/rtc/Makefile
++++ b/drivers/rtc/Makefile
+@@ -117,6 +117,7 @@ obj-$(CONFIG_RTC_DRV_STARFIRE)     += rtc-starfire.o
+ obj-$(CONFIG_RTC_DRV_STK17TA8)        += rtc-stk17ta8.o
+ obj-$(CONFIG_RTC_DRV_STMP)    += rtc-stmp3xxx.o
+ obj-$(CONFIG_RTC_DRV_SUN4V)   += rtc-sun4v.o
++obj-$(CONFIG_RTC_DRV_SUNXI)   += rtc-sunxi.o
+ obj-$(CONFIG_RTC_DRV_TEGRA)   += rtc-tegra.o
+ obj-$(CONFIG_RTC_DRV_TEST)    += rtc-test.o
+ obj-$(CONFIG_RTC_DRV_TILE)    += rtc-tile.o
+diff --git a/drivers/rtc/rtc-sunxi.c b/drivers/rtc/rtc-sunxi.c
+new file mode 100644
+index 0000000..68a3528
+--- /dev/null
++++ b/drivers/rtc/rtc-sunxi.c
+@@ -0,0 +1,523 @@
++/*
++ * An RTC driver for Allwinner A10/A20
++ *
++ * Copyright (c) 2013, Carlo Caione <carlo.caione@gmail.com>
++ *
++ * This program is free software; you can redistribute it and/or modify
++ * it under the terms of the GNU General Public License as published by
++ * the Free Software Foundation; either version 2 of the License, or
++ * (at your option) any later version.
++ *
++ * This program is distributed in the hope that it will be useful, but WITHOUT
++ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
++ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
++ * more details.
++ *
++ * You should have received a copy of the GNU General Public License along
++ * with this program; if not, write to the Free Software Foundation, Inc.,
++ * 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
++ */
++
++#include <linux/delay.h>
++#include <linux/err.h>
++#include <linux/fs.h>
++#include <linux/init.h>
++#include <linux/interrupt.h>
++#include <linux/io.h>
++#include <linux/kernel.h>
++#include <linux/module.h>
++#include <linux/of.h>
++#include <linux/of_address.h>
++#include <linux/of_device.h>
++#include <linux/platform_device.h>
++#include <linux/rtc.h>
++#include <linux/types.h>
++
++#define SUNXI_LOSC_CTRL                               0x0000
++#define SUNXI_LOSC_CTRL_RTC_HMS_ACC           BIT(8)
++#define SUNXI_LOSC_CTRL_RTC_YMD_ACC           BIT(7)
++
++#define SUNXI_RTC_YMD                         0x0004
++
++#define SUNXI_RTC_HMS                         0x0008
++
++#define SUNXI_ALRM_DHMS                               0x000c
++
++#define SUNXI_ALRM_EN                         0x0014
++#define SUNXI_ALRM_EN_CNT_EN                  BIT(8)
++
++#define SUNXI_ALRM_IRQ_EN                     0x0018
++#define SUNXI_ALRM_IRQ_EN_CNT_IRQ_EN          BIT(0)
++
++#define SUNXI_ALRM_IRQ_STA                    0x001c
++#define SUNXI_ALRM_IRQ_STA_CNT_IRQ_PEND               BIT(0)
++
++#define SUNXI_MASK_DH                         0x0000001f
++#define SUNXI_MASK_SM                         0x0000003f
++#define SUNXI_MASK_M                          0x0000000f
++#define SUNXI_MASK_LY                         0x00000001
++#define SUNXI_MASK_D                          0x00000ffe
++#define SUNXI_MASK_M                          0x0000000f
++
++#define SUNXI_GET(x, mask, shift)             (((x) & ((mask) << (shift))) \
++                                                      >> (shift))
++
++#define SUNXI_SET(x, mask, shift)             (((x) & (mask)) << (shift))
++
++/*
++ * Get date values
++ */
++#define SUNXI_DATE_GET_DAY_VALUE(x)           SUNXI_GET(x, SUNXI_MASK_DH, 0)
++#define SUNXI_DATE_GET_MON_VALUE(x)           SUNXI_GET(x, SUNXI_MASK_M, 8)
++#define SUNXI_DATE_GET_YEAR_VALUE(x, mask)    SUNXI_GET(x, mask, 16)
++
++/*
++ * Get time values
++ */
++#define SUNXI_TIME_GET_SEC_VALUE(x)           SUNXI_GET(x, SUNXI_MASK_SM, 0)
++#define SUNXI_TIME_GET_MIN_VALUE(x)           SUNXI_GET(x, SUNXI_MASK_SM, 8)
++#define SUNXI_TIME_GET_HOUR_VALUE(x)          SUNXI_GET(x, SUNXI_MASK_DH, 16)
++
++/*
++ * Get alarm values
++ */
++#define SUNXI_ALRM_GET_SEC_VALUE(x)           SUNXI_GET(x, SUNXI_MASK_SM, 0)
++#define SUNXI_ALRM_GET_MIN_VALUE(x)           SUNXI_GET(x, SUNXI_MASK_SM, 8)
++#define SUNXI_ALRM_GET_HOUR_VALUE(x)          SUNXI_GET(x, SUNXI_MASK_DH, 16)
++
++/*
++ * Set date values
++ */
++#define SUNXI_DATE_SET_DAY_VALUE(x)           SUNXI_DATE_GET_DAY_VALUE(x)
++#define SUNXI_DATE_SET_MON_VALUE(x)           SUNXI_SET(x, SUNXI_MASK_M, 8)
++#define SUNXI_DATE_SET_YEAR_VALUE(x, mask)    SUNXI_SET(x, mask, 16)
++#define SUNXI_LEAP_SET_VALUE(x, shift)                SUNXI_SET(x, SUNXI_MASK_LY, shift)
++
++/*
++ * Set time values
++ */
++#define SUNXI_TIME_SET_SEC_VALUE(x)           SUNXI_TIME_GET_SEC_VALUE(x)
++#define SUNXI_TIME_SET_MIN_VALUE(x)           SUNXI_SET(x, SUNXI_MASK_SM, 8)
++#define SUNXI_TIME_SET_HOUR_VALUE(x)          SUNXI_SET(x, SUNXI_MASK_DH, 16)
++
++/*
++ * Set alarm values
++ */
++#define SUNXI_ALRM_SET_SEC_VALUE(x)           SUNXI_ALRM_GET_SEC_VALUE(x)
++#define SUNXI_ALRM_SET_MIN_VALUE(x)           SUNXI_SET(x, SUNXI_MASK_SM, 8)
++#define SUNXI_ALRM_SET_HOUR_VALUE(x)          SUNXI_SET(x, SUNXI_MASK_DH, 16)
++#define SUNXI_ALRM_SET_DAY_VALUE(x)           SUNXI_SET(x, SUNXI_MASK_D, 21)
++
++/*
++ * Time unit conversions
++ */
++#define SEC_IN_MIN                            60
++#define SEC_IN_HOUR                           (60 * SEC_IN_MIN)
++#define SEC_IN_DAY                            (24 * SEC_IN_HOUR)
++
++/*
++ * The year parameter passed to the driver is usually an offset relative to
++ * the year 1900. This macro is used to convert this offset to another one
++ * relative to the minimum year allowed by the hardware.
++ */
++#define SUNXI_YEAR_OFF(x)                     ((x)->min - 1900)
++
++/*
++ * min and max year are arbitrary set considering the limited range of the
++ * hardware register field
++ */
++struct sunxi_rtc_data_year {
++      unsigned int min;               /* min year allowed */
++      unsigned int max;               /* max year allowed */
++      unsigned int mask;              /* mask for the year field */
++      unsigned char leap_shift;       /* bit shift to get the leap year */
++};
++
++static struct sunxi_rtc_data_year data_year_param[] = {
++      [0] = {
++              .min            = 2010,
++              .max            = 2073,
++              .mask           = 0x3f,
++              .leap_shift     = 22,
++      },
++      [1] = {
++              .min            = 1970,
++              .max            = 2225,
++              .mask           = 0xff,
++              .leap_shift     = 24,
++      },
++};
++
++struct sunxi_rtc_dev {
++      struct rtc_device *rtc;
++      struct device *dev;
++      struct sunxi_rtc_data_year *data_year;
++      void __iomem *base;
++      int irq;
++};
++
++static irqreturn_t sunxi_rtc_alarmirq(int irq, void *id)
++{
++      struct sunxi_rtc_dev *chip = (struct sunxi_rtc_dev *) id;
++      u32 val;
++
++      val = readl(chip->base + SUNXI_ALRM_IRQ_STA);
++
++      if (val & SUNXI_ALRM_IRQ_STA_CNT_IRQ_PEND) {
++              val |= SUNXI_ALRM_IRQ_STA_CNT_IRQ_PEND;
++              writel(val, chip->base + SUNXI_ALRM_IRQ_STA);
++
++              rtc_update_irq(chip->rtc, 1, RTC_AF | RTC_IRQF);
++
++              return IRQ_HANDLED;
++      }
++
++      return IRQ_NONE;
++}
++
++static void sunxi_rtc_setaie(int to, struct sunxi_rtc_dev *chip)
++{
++      u32 alrm_val = 0;
++      u32 alrm_irq_val = 0;
++
++      if (to) {
++              alrm_val = readl(chip->base + SUNXI_ALRM_EN);
++              alrm_val |= SUNXI_ALRM_EN_CNT_EN;
++
++              alrm_irq_val = readl(chip->base + SUNXI_ALRM_IRQ_EN);
++              alrm_irq_val |= SUNXI_ALRM_IRQ_EN_CNT_IRQ_EN;
++      } else {
++              writel(SUNXI_ALRM_IRQ_STA_CNT_IRQ_PEND,
++                              chip->base + SUNXI_ALRM_IRQ_STA);
++      }
++
++      writel(alrm_val, chip->base + SUNXI_ALRM_EN);
++      writel(alrm_irq_val, chip->base + SUNXI_ALRM_IRQ_EN);
++}
++
++static int sunxi_rtc_getalarm(struct device *dev, struct rtc_wkalrm *wkalrm)
++{
++      struct sunxi_rtc_dev *chip = dev_get_drvdata(dev);
++      struct rtc_time *alrm_tm = &wkalrm->time;
++      u32 alrm;
++      u32 alrm_en;
++      u32 date;
++
++      alrm = readl(chip->base + SUNXI_ALRM_DHMS);
++      date = readl(chip->base + SUNXI_RTC_YMD);
++
++      alrm_tm->tm_sec = SUNXI_ALRM_GET_SEC_VALUE(alrm);
++      alrm_tm->tm_min = SUNXI_ALRM_GET_MIN_VALUE(alrm);
++      alrm_tm->tm_hour = SUNXI_ALRM_GET_HOUR_VALUE(alrm);
++
++      alrm_tm->tm_mday = SUNXI_DATE_GET_DAY_VALUE(date);
++      alrm_tm->tm_mon = SUNXI_DATE_GET_MON_VALUE(date);
++      alrm_tm->tm_year = SUNXI_DATE_GET_YEAR_VALUE(date,
++                      chip->data_year->mask);
++
++      alrm_tm->tm_mon -= 1;
++
++      /*
++       * switch from (data_year->min)-relative offset to
++       * a (1900)-relative one
++       */
++      alrm_tm->tm_year += SUNXI_YEAR_OFF(chip->data_year);
++
++      alrm_en = readl(chip->base + SUNXI_ALRM_IRQ_EN);
++      if (alrm_en & SUNXI_ALRM_EN_CNT_EN)
++              wkalrm->enabled = 1;
++
++      return 0;
++}
++
++static int sunxi_rtc_gettime(struct device *dev, struct rtc_time *rtc_tm)
++{
++      struct sunxi_rtc_dev *chip = dev_get_drvdata(dev);
++      u32 date, time;
++
++      /*
++       * read again in case it changes
++       */
++      do {
++              date = readl(chip->base + SUNXI_RTC_YMD);
++              time = readl(chip->base + SUNXI_RTC_HMS);
++      } while ((date != readl(chip->base + SUNXI_RTC_YMD)) ||
++               (time != readl(chip->base + SUNXI_RTC_HMS)));
++
++      rtc_tm->tm_sec  = SUNXI_TIME_GET_SEC_VALUE(time);
++      rtc_tm->tm_min  = SUNXI_TIME_GET_MIN_VALUE(time);
++      rtc_tm->tm_hour = SUNXI_TIME_GET_HOUR_VALUE(time);
++
++      rtc_tm->tm_mday = SUNXI_DATE_GET_DAY_VALUE(date);
++      rtc_tm->tm_mon  = SUNXI_DATE_GET_MON_VALUE(date);
++      rtc_tm->tm_year = SUNXI_DATE_GET_YEAR_VALUE(date,
++                                      chip->data_year->mask);
++
++      rtc_tm->tm_mon  -= 1;
++
++      /*
++       * switch from (data_year->min)-relative offset to
++       * a (1900)-relative one
++       */
++      rtc_tm->tm_year += SUNXI_YEAR_OFF(chip->data_year);
++
++      return rtc_valid_tm(rtc_tm);
++}
++
++static int sunxi_rtc_setalarm(struct device *dev, struct rtc_wkalrm *wkalrm)
++{
++      struct sunxi_rtc_dev *chip = dev_get_drvdata(dev);
++      struct rtc_time *alrm_tm = &wkalrm->time;
++      struct rtc_time tm_now;
++      u32 alrm = 0;
++      unsigned long time_now = 0;
++      unsigned long time_set = 0;
++      unsigned long time_gap = 0;
++      unsigned long time_gap_day = 0;
++      unsigned long time_gap_hour = 0;
++      unsigned long time_gap_min = 0;
++      int ret = 0;
++
++      ret = sunxi_rtc_gettime(dev, &tm_now);
++      if (ret < 0) {
++              dev_err(dev, "Error in getting time\n");
++              return -EINVAL;
++      }
++
++      rtc_tm_to_time(alrm_tm, &time_set);
++      rtc_tm_to_time(&tm_now, &time_now);
++      if (time_set <= time_now) {
++              dev_err(dev, "Date to set in the past\n");
++              return -EINVAL;
++      }
++
++      time_gap = time_set - time_now;
++      time_gap_day = time_gap / SEC_IN_DAY;
++      time_gap -= time_gap_day * SEC_IN_DAY;
++      time_gap_hour = time_gap / SEC_IN_HOUR;
++      time_gap -= time_gap_hour * SEC_IN_HOUR;
++      time_gap_min = time_gap / SEC_IN_MIN;
++      time_gap -= time_gap_min * SEC_IN_MIN;
++
++      if (time_gap_day > 255) {
++              dev_err(dev, "Day must be in the range 0 - 255\n");
++              return -EINVAL;
++      }
++
++      sunxi_rtc_setaie(0, chip);
++      writel(0, chip->base + SUNXI_ALRM_DHMS);
++      usleep_range(100, 300);
++
++      alrm = SUNXI_ALRM_SET_SEC_VALUE(time_gap) |
++              SUNXI_ALRM_SET_MIN_VALUE(time_gap_min) |
++              SUNXI_ALRM_SET_HOUR_VALUE(time_gap_hour) |
++              SUNXI_ALRM_SET_DAY_VALUE(time_gap_day);
++      writel(alrm, chip->base + SUNXI_ALRM_DHMS);
++
++      writel(0, chip->base + SUNXI_ALRM_IRQ_EN);
++      writel(SUNXI_ALRM_IRQ_EN_CNT_IRQ_EN, chip->base + SUNXI_ALRM_IRQ_EN);
++
++      sunxi_rtc_setaie(wkalrm->enabled, chip);
++
++      return 0;
++}
++
++static int sunxi_rtc_wait(struct sunxi_rtc_dev *chip, int offset,
++                        unsigned int mask, unsigned int ms_timeout)
++{
++      const unsigned long timeout = jiffies + msecs_to_jiffies(ms_timeout);
++      u32 reg;
++
++      do {
++              reg = readl(chip->base + offset);
++              reg &= mask;
++
++              if (reg == mask)
++                      return 0;
++
++      } while (time_before(jiffies, timeout));
++
++      return -ETIMEDOUT;
++}
++
++static int sunxi_rtc_settime(struct device *dev, struct rtc_time *rtc_tm)
++{
++      struct sunxi_rtc_dev *chip = dev_get_drvdata(dev);
++      u32 date = 0;
++      u32 time = 0;
++      int year;
++
++      /*
++       * the input rtc_tm->tm_year is the offset relative to 1900. We use
++       * the SUNXI_YEAR_OFF macro to rebase it with respect to the min year
++       * allowed by the hardware
++       */
++
++      year = rtc_tm->tm_year + 1900;
++      if (year < chip->data_year->min || year > chip->data_year->max) {
++              dev_err(dev, "rtc only supports year in range %d - %d\n",
++                              chip->data_year->min, chip->data_year->max);
++              return -EINVAL;
++      }
++
++      rtc_tm->tm_year -= SUNXI_YEAR_OFF(chip->data_year);
++      rtc_tm->tm_mon += 1;
++
++      date = SUNXI_DATE_SET_DAY_VALUE(rtc_tm->tm_mday) |
++              SUNXI_DATE_SET_MON_VALUE(rtc_tm->tm_mon)  |
++              SUNXI_DATE_SET_YEAR_VALUE(rtc_tm->tm_year,
++                              chip->data_year->mask);
++
++      if (is_leap_year(year))
++              date |= SUNXI_LEAP_SET_VALUE(1, chip->data_year->leap_shift);
++
++      time = SUNXI_TIME_SET_SEC_VALUE(rtc_tm->tm_sec)  |
++              SUNXI_TIME_SET_MIN_VALUE(rtc_tm->tm_min)  |
++              SUNXI_TIME_SET_HOUR_VALUE(rtc_tm->tm_hour);
++
++      writel(0, chip->base + SUNXI_RTC_HMS);
++      writel(0, chip->base + SUNXI_RTC_YMD);
++
++      writel(time, chip->base + SUNXI_RTC_HMS);
++
++      /*
++       * After writing the RTC HH-MM-SS register, the
++       * SUNXI_LOSC_CTRL_RTC_HMS_ACC bit is set and it will not
++       * be cleared until the real writing operation is finished
++       */
++
++      if (sunxi_rtc_wait(chip, SUNXI_LOSC_CTRL,
++                              SUNXI_LOSC_CTRL_RTC_HMS_ACC, 50)) {
++              dev_err(dev, "Failed to set rtc time.\n");
++              return -1;
++      }
++
++      writel(date, chip->base + SUNXI_RTC_YMD);
++
++      /*
++       * After writing the RTC YY-MM-DD register, the
++       * SUNXI_LOSC_CTRL_RTC_YMD_ACC bit is set and it will not
++       * be cleared until the real writing operation is finished
++       */
++
++      if (sunxi_rtc_wait(chip, SUNXI_LOSC_CTRL,
++                              SUNXI_LOSC_CTRL_RTC_YMD_ACC, 50)) {
++              dev_err(dev, "Failed to set rtc time.\n");
++              return -1;
++      }
++
++      return 0;
++}
++
++static int sunxi_rtc_alarm_irq_enable(struct device *dev, unsigned int enabled)
++{
++      struct sunxi_rtc_dev *chip = dev_get_drvdata(dev);
++
++      if (!enabled)
++              sunxi_rtc_setaie(enabled, chip);
++
++      return 0;
++}
++
++static const struct rtc_class_ops sunxi_rtc_ops = {
++      .read_time              = sunxi_rtc_gettime,
++      .set_time               = sunxi_rtc_settime,
++      .read_alarm             = sunxi_rtc_getalarm,
++      .set_alarm              = sunxi_rtc_setalarm,
++      .alarm_irq_enable       = sunxi_rtc_alarm_irq_enable
++};
++
++static const struct of_device_id sunxi_rtc_dt_ids[] = {
++      { .compatible = "allwinner,sun4i-rtc", .data = &data_year_param[0] },
++      { .compatible = "allwinner,sun7i-a20-rtc", .data = &data_year_param[1] },
++      { /* sentinel */ },
++};
++MODULE_DEVICE_TABLE(of, sunxi_rtc_dt_ids);
++
++static int sunxi_rtc_probe(struct platform_device *pdev)
++{
++      struct sunxi_rtc_dev *chip;
++      struct resource *res;
++      const struct of_device_id *of_id;
++      int ret;
++
++      chip = devm_kzalloc(&pdev->dev, sizeof(*chip), GFP_KERNEL);
++      if (!chip)
++              return -ENOMEM;
++
++      platform_set_drvdata(pdev, chip);
++      chip->dev = &pdev->dev;
++
++      res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
++      chip->base = devm_ioremap_resource(&pdev->dev, res);
++      if (IS_ERR(chip->base))
++              return PTR_ERR(chip->base);
++
++      chip->irq = platform_get_irq(pdev, 0);
++      if (chip->irq < 0) {
++              dev_err(&pdev->dev, "No IRQ resource\n");
++              return chip->irq;
++      }
++      ret = devm_request_irq(&pdev->dev, chip->irq, sunxi_rtc_alarmirq,
++                      0, dev_name(&pdev->dev), chip);
++      if (ret) {
++              dev_err(&pdev->dev, "Could not request IRQ\n");
++              return ret;
++      }
++
++      of_id = of_match_device(sunxi_rtc_dt_ids, &pdev->dev);
++      if (!of_id) {
++              dev_err(&pdev->dev, "Unable to setup RTC data\n");
++              return -ENODEV;
++      }
++      chip->data_year = (struct sunxi_rtc_data_year *) of_id->data;
++
++      /* clear the alarm count value */
++      writel(0, chip->base + SUNXI_ALRM_DHMS);
++
++      /* disable alarm, not generate irq pending */
++      writel(0, chip->base + SUNXI_ALRM_EN);
++
++      /* disable alarm week/cnt irq, unset to cpu */
++      writel(0, chip->base + SUNXI_ALRM_IRQ_EN);
++
++      /* clear alarm week/cnt irq pending */
++      writel(SUNXI_ALRM_IRQ_STA_CNT_IRQ_PEND, chip->base +
++                      SUNXI_ALRM_IRQ_STA);
++
++      chip->rtc = rtc_device_register("rtc-sunxi", &pdev->dev,
++                      &sunxi_rtc_ops, THIS_MODULE);
++      if (IS_ERR(chip->rtc)) {
++              dev_err(&pdev->dev, "unable to register device\n");
++              return PTR_ERR(chip->rtc);
++      }
++
++      dev_info(&pdev->dev, "RTC enabled\n");
++
++      return 0;
++}
++
++static int sunxi_rtc_remove(struct platform_device *pdev)
++{
++      struct sunxi_rtc_dev *chip = platform_get_drvdata(pdev);
++
++      rtc_device_unregister(chip->rtc);
++
++      return 0;
++}
++
++static struct platform_driver sunxi_rtc_driver = {
++      .probe          = sunxi_rtc_probe,
++      .remove         = sunxi_rtc_remove,
++      .driver         = {
++              .name           = "sunxi-rtc",
++              .owner          = THIS_MODULE,
++              .of_match_table = sunxi_rtc_dt_ids,
++      },
++};
++
++module_platform_driver(sunxi_rtc_driver);
++
++MODULE_DESCRIPTION("sunxi RTC driver");
++MODULE_AUTHOR("Carlo Caione <carlo.caione@gmail.com>");
++MODULE_LICENSE("GPL");
+-- 
+1.8.5.1
+
diff --git a/target/linux/sunxi/patches-3.13/141-dt-sun47i-add-rtc.patch b/target/linux/sunxi/patches-3.13/141-dt-sun47i-add-rtc.patch
new file mode 100644 (file)
index 0000000..63de19b
--- /dev/null
@@ -0,0 +1,51 @@
+From b15b9f68606134222f7aff5120c8ef70ffab92b8 Mon Sep 17 00:00:00 2001
+From: Carlo Caione <carlo.caione@gmail.com>
+Date: Wed, 16 Oct 2013 20:30:26 +0200
+Subject: [PATCH] ARM: dts: sun4i/sun7i: add RTC node
+
+Add the RTC node to DTS for Allwinner A10 and Allwinner A20.
+
+Signed-off-by: Carlo Caione <carlo.caione@gmail.com>
+Signed-off-by: Maxime Ripard <maxime.ripard@free-electrons.com>
+---
+ arch/arm/boot/dts/sun4i-a10.dtsi | 6 ++++++
+ arch/arm/boot/dts/sun7i-a20.dtsi | 6 ++++++
+ 2 files changed, 12 insertions(+)
+
+diff --git a/arch/arm/boot/dts/sun4i-a10.dtsi b/arch/arm/boot/dts/sun4i-a10.dtsi
+index 319cc6b..f11f292 100644
+--- a/arch/arm/boot/dts/sun4i-a10.dtsi
++++ b/arch/arm/boot/dts/sun4i-a10.dtsi
+@@ -266,6 +266,12 @@
+                       reg = <0x01c20c90 0x10>;
+               };
++              rtc: rtc@01c20d00 {
++                      compatible = "allwinner,sun4i-rtc";
++                      reg = <0x01c20d00 0x20>;
++                      interrupts = <24>;
++              };
++
+               sid: eeprom@01c23800 {
+                       compatible = "allwinner,sun4i-sid";
+                       reg = <0x01c23800 0x10>;
+diff --git a/arch/arm/boot/dts/sun7i-a20.dtsi b/arch/arm/boot/dts/sun7i-a20.dtsi
+index 367611a..cc3683c 100644
+--- a/arch/arm/boot/dts/sun7i-a20.dtsi
++++ b/arch/arm/boot/dts/sun7i-a20.dtsi
+@@ -265,6 +265,12 @@
+                       reg = <0x01c20c90 0x10>;
+               };
++              rtc: rtc@01c20d00 {
++                      compatible = "allwinner,sun7i-a20-rtc";
++                      reg = <0x01c20d00 0x20>;
++                      interrupts = <0 24 1>;
++              };
++
+               sid: eeprom@01c23800 {
+                       compatible = "allwinner,sun7i-a20-sid";
+                       reg = <0x01c23800 0x200>;
+-- 
+1.8.5.1
+
diff --git a/target/linux/sunxi/patches-3.13/145-clksrc-add-hstimer.patch b/target/linux/sunxi/patches-3.13/145-clksrc-add-hstimer.patch
new file mode 100644 (file)
index 0000000..db54eb8
--- /dev/null
@@ -0,0 +1,297 @@
+From 3bf30f6381f9287eb99ce096bf2fa327a69c8a71 Mon Sep 17 00:00:00 2001
+From: Maxime Ripard <maxime.ripard@free-electrons.com>
+Date: Thu, 7 Nov 2013 12:01:48 +0100
+Subject: [PATCH] clocksource: Add Allwinner SoCs HS timers driver
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+Most of the Allwinner SoCs (at this time, all but the A10) also have a
+High Speed timers that are not using the 24MHz oscillator as a source
+but rather the AHB clock running much faster.
+
+The IP is slightly different between the A10s/A13 and the one used in
+the A20/A31, since the latter have 4 timers available, while the former
+have only 2 of them.
+
+[dlezcano] : Fixed conflict with b788beda "Order Kconfig options
+               alphabetically"
+
+Signed-off-by: Maxime Ripard <maxime.ripard@free-electrons.com>
+Tested-by: Emilio López <emilio@elopez.com.ar>
+Signed-off-by: Daniel Lezcano <daniel.lezcano@linaro.org>
+---
+ .../bindings/timer/allwinner,sun5i-a13-hstimer.txt |  22 +++
+ arch/arm/mach-sunxi/Kconfig                        |   1 +
+ drivers/clocksource/Kconfig                        |   4 +
+ drivers/clocksource/Makefile                       |   1 +
+ drivers/clocksource/timer-sun5i.c                  | 192 +++++++++++++++++++++
+ 5 files changed, 220 insertions(+)
+ create mode 100644 Documentation/devicetree/bindings/timer/allwinner,sun5i-a13-hstimer.txt
+ create mode 100644 drivers/clocksource/timer-sun5i.c
+
+diff --git a/Documentation/devicetree/bindings/timer/allwinner,sun5i-a13-hstimer.txt b/Documentation/devicetree/bindings/timer/allwinner,sun5i-a13-hstimer.txt
+new file mode 100644
+index 0000000..7c26154
+--- /dev/null
++++ b/Documentation/devicetree/bindings/timer/allwinner,sun5i-a13-hstimer.txt
+@@ -0,0 +1,22 @@
++Allwinner SoCs High Speed Timer Controller
++
++Required properties:
++
++- compatible :        should be "allwinner,sun5i-a13-hstimer" or
++              "allwinner,sun7i-a20-hstimer"
++- reg : Specifies base physical address and size of the registers.
++- interrupts :        The interrupts of these timers (2 for the sun5i IP, 4 for the sun7i
++              one)
++- clocks: phandle to the source clock (usually the AHB clock)
++
++Example:
++
++timer@01c60000 {
++      compatible = "allwinner,sun7i-a20-hstimer";
++      reg = <0x01c60000 0x1000>;
++      interrupts = <0 51 1>,
++                   <0 52 1>,
++                   <0 53 1>,
++                   <0 54 1>;
++      clocks = <&ahb1_gates 19>;
++};
+diff --git a/arch/arm/mach-sunxi/Kconfig b/arch/arm/mach-sunxi/Kconfig
+index e3457b9..547004c 100644
+--- a/arch/arm/mach-sunxi/Kconfig
++++ b/arch/arm/mach-sunxi/Kconfig
+@@ -13,3 +13,4 @@ config ARCH_SUNXI
+       select PINCTRL_SUNXI
+       select SPARSE_IRQ
+       select SUN4I_TIMER
++      select SUN5I_HSTIMER
+diff --git a/drivers/clocksource/Kconfig b/drivers/clocksource/Kconfig
+index 634c4d6..cd6950f 100644
+--- a/drivers/clocksource/Kconfig
++++ b/drivers/clocksource/Kconfig
+@@ -37,6 +37,10 @@ config SUN4I_TIMER
+       select CLKSRC_MMIO
+       bool
++config SUN5I_HSTIMER
++      select CLKSRC_MMIO
++      bool
++
+ config VT8500_TIMER
+       bool
+diff --git a/drivers/clocksource/Makefile b/drivers/clocksource/Makefile
+index 33621ef..358358d 100644
+--- a/drivers/clocksource/Makefile
++++ b/drivers/clocksource/Makefile
+@@ -22,6 +22,7 @@ obj-$(CONFIG_ARCH_MOXART)    += moxart_timer.o
+ obj-$(CONFIG_ARCH_MXS)                += mxs_timer.o
+ obj-$(CONFIG_ARCH_PRIMA2)     += timer-prima2.o
+ obj-$(CONFIG_SUN4I_TIMER)     += sun4i_timer.o
++obj-$(CONFIG_SUN5I_HSTIMER)   += timer-sun5i.o
+ obj-$(CONFIG_ARCH_TEGRA)      += tegra20_timer.o
+ obj-$(CONFIG_VT8500_TIMER)    += vt8500_timer.o
+ obj-$(CONFIG_ARCH_NSPIRE)     += zevio-timer.o
+diff --git a/drivers/clocksource/timer-sun5i.c b/drivers/clocksource/timer-sun5i.c
+new file mode 100644
+index 0000000..bddc522
+--- /dev/null
++++ b/drivers/clocksource/timer-sun5i.c
+@@ -0,0 +1,192 @@
++/*
++ * Allwinner SoCs hstimer driver.
++ *
++ * Copyright (C) 2013 Maxime Ripard
++ *
++ * Maxime Ripard <maxime.ripard@free-electrons.com>
++ *
++ * 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 <linux/clk.h>
++#include <linux/clockchips.h>
++#include <linux/delay.h>
++#include <linux/interrupt.h>
++#include <linux/irq.h>
++#include <linux/irqreturn.h>
++#include <linux/sched_clock.h>
++#include <linux/of.h>
++#include <linux/of_address.h>
++#include <linux/of_irq.h>
++
++#define TIMER_IRQ_EN_REG              0x00
++#define TIMER_IRQ_EN(val)                     BIT(val)
++#define TIMER_IRQ_ST_REG              0x04
++#define TIMER_CTL_REG(val)            (0x20 * (val) + 0x10)
++#define TIMER_CTL_ENABLE                      BIT(0)
++#define TIMER_CTL_RELOAD                      BIT(1)
++#define TIMER_CTL_CLK_PRES(val)                       (((val) & 0x7) << 4)
++#define TIMER_CTL_ONESHOT                     BIT(7)
++#define TIMER_INTVAL_LO_REG(val)      (0x20 * (val) + 0x14)
++#define TIMER_INTVAL_HI_REG(val)      (0x20 * (val) + 0x18)
++#define TIMER_CNTVAL_LO_REG(val)      (0x20 * (val) + 0x1c)
++#define TIMER_CNTVAL_HI_REG(val)      (0x20 * (val) + 0x20)
++
++#define TIMER_SYNC_TICKS      3
++
++static void __iomem *timer_base;
++static u32 ticks_per_jiffy;
++
++/*
++ * When we disable a timer, we need to wait at least for 2 cycles of
++ * the timer source clock. We will use for that the clocksource timer
++ * that is already setup and runs at the same frequency than the other
++ * timers, and we never will be disabled.
++ */
++static void sun5i_clkevt_sync(void)
++{
++      u32 old = readl(timer_base + TIMER_CNTVAL_LO_REG(1));
++
++      while ((old - readl(timer_base + TIMER_CNTVAL_LO_REG(1))) < TIMER_SYNC_TICKS)
++              cpu_relax();
++}
++
++static void sun5i_clkevt_time_stop(u8 timer)
++{
++      u32 val = readl(timer_base + TIMER_CTL_REG(timer));
++      writel(val & ~TIMER_CTL_ENABLE, timer_base + TIMER_CTL_REG(timer));
++
++      sun5i_clkevt_sync();
++}
++
++static void sun5i_clkevt_time_setup(u8 timer, u32 delay)
++{
++      writel(delay, timer_base + TIMER_INTVAL_LO_REG(timer));
++}
++
++static void sun5i_clkevt_time_start(u8 timer, bool periodic)
++{
++      u32 val = readl(timer_base + TIMER_CTL_REG(timer));
++
++      if (periodic)
++              val &= ~TIMER_CTL_ONESHOT;
++      else
++              val |= TIMER_CTL_ONESHOT;
++
++      writel(val | TIMER_CTL_ENABLE | TIMER_CTL_RELOAD,
++             timer_base + TIMER_CTL_REG(timer));
++}
++
++static void sun5i_clkevt_mode(enum clock_event_mode mode,
++                            struct clock_event_device *clk)
++{
++      switch (mode) {
++      case CLOCK_EVT_MODE_PERIODIC:
++              sun5i_clkevt_time_stop(0);
++              sun5i_clkevt_time_setup(0, ticks_per_jiffy);
++              sun5i_clkevt_time_start(0, true);
++              break;
++      case CLOCK_EVT_MODE_ONESHOT:
++              sun5i_clkevt_time_stop(0);
++              sun5i_clkevt_time_start(0, false);
++              break;
++      case CLOCK_EVT_MODE_UNUSED:
++      case CLOCK_EVT_MODE_SHUTDOWN:
++      default:
++              sun5i_clkevt_time_stop(0);
++              break;
++      }
++}
++
++static int sun5i_clkevt_next_event(unsigned long evt,
++                                 struct clock_event_device *unused)
++{
++      sun5i_clkevt_time_stop(0);
++      sun5i_clkevt_time_setup(0, evt - TIMER_SYNC_TICKS);
++      sun5i_clkevt_time_start(0, false);
++
++      return 0;
++}
++
++static struct clock_event_device sun5i_clockevent = {
++      .name = "sun5i_tick",
++      .rating = 340,
++      .features = CLOCK_EVT_FEAT_PERIODIC | CLOCK_EVT_FEAT_ONESHOT,
++      .set_mode = sun5i_clkevt_mode,
++      .set_next_event = sun5i_clkevt_next_event,
++};
++
++
++static irqreturn_t sun5i_timer_interrupt(int irq, void *dev_id)
++{
++      struct clock_event_device *evt = (struct clock_event_device *)dev_id;
++
++      writel(0x1, timer_base + TIMER_IRQ_ST_REG);
++      evt->event_handler(evt);
++
++      return IRQ_HANDLED;
++}
++
++static struct irqaction sun5i_timer_irq = {
++      .name = "sun5i_timer0",
++      .flags = IRQF_TIMER | IRQF_IRQPOLL,
++      .handler = sun5i_timer_interrupt,
++      .dev_id = &sun5i_clockevent,
++};
++
++static u32 sun5i_timer_sched_read(void)
++{
++      return ~readl(timer_base + TIMER_CNTVAL_LO_REG(1));
++}
++
++static void __init sun5i_timer_init(struct device_node *node)
++{
++      unsigned long rate;
++      struct clk *clk;
++      int ret, irq;
++      u32 val;
++
++      timer_base = of_iomap(node, 0);
++      if (!timer_base)
++              panic("Can't map registers");
++
++      irq = irq_of_parse_and_map(node, 0);
++      if (irq <= 0)
++              panic("Can't parse IRQ");
++
++      clk = of_clk_get(node, 0);
++      if (IS_ERR(clk))
++              panic("Can't get timer clock");
++      clk_prepare_enable(clk);
++      rate = clk_get_rate(clk);
++
++      writel(~0, timer_base + TIMER_INTVAL_LO_REG(1));
++      writel(TIMER_CTL_ENABLE | TIMER_CTL_RELOAD,
++             timer_base + TIMER_CTL_REG(1));
++
++      setup_sched_clock(sun5i_timer_sched_read, 32, rate);
++      clocksource_mmio_init(timer_base + TIMER_CNTVAL_LO_REG(1), node->name,
++                            rate, 340, 32, clocksource_mmio_readl_down);
++
++      ticks_per_jiffy = DIV_ROUND_UP(rate, HZ);
++
++      ret = setup_irq(irq, &sun5i_timer_irq);
++      if (ret)
++              pr_warn("failed to setup irq %d\n", irq);
++
++      /* Enable timer0 interrupt */
++      val = readl(timer_base + TIMER_IRQ_EN_REG);
++      writel(val | TIMER_IRQ_EN(0), timer_base + TIMER_IRQ_EN_REG);
++
++      sun5i_clockevent.cpumask = cpu_possible_mask;
++      sun5i_clockevent.irq = irq;
++
++      clockevents_config_and_register(&sun5i_clockevent, rate,
++                                      TIMER_SYNC_TICKS, 0xffffffff);
++}
++CLOCKSOURCE_OF_DECLARE(sun5i_a13, "allwinner,sun5i-a13-hstimer",
++                     sun5i_timer_init);
++CLOCKSOURCE_OF_DECLARE(sun7i_a20, "allwinner,sun7i-a20-hstimer",
++                     sun5i_timer_init);
+-- 
+1.8.5.1
+
diff --git a/target/linux/sunxi/patches-3.13/146-1-dt-sun5i-a10s-add-hstimer.patch b/target/linux/sunxi/patches-3.13/146-1-dt-sun5i-a10s-add-hstimer.patch
new file mode 100644 (file)
index 0000000..afdaa5a
--- /dev/null
@@ -0,0 +1,38 @@
+From 5ace5467690055b1772dcac69dd1377735b8a34b Mon Sep 17 00:00:00 2001
+From: Maxime Ripard <maxime.ripard@free-electrons.com>
+Date: Thu, 7 Nov 2013 12:01:48 +0100
+Subject: [PATCH] ARM: sun5i: a10s: Add support for the High Speed Timers
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+The Allwinner A10s has support for two high speed timers. Now that we
+have a driver to support it, we can enable them in the device tree.
+
+Signed-off-by: Maxime Ripard <maxime.ripard@free-electrons.com>
+Tested-by: Emilio López <emilio@elopez.com.ar>
+Signed-off-by: Daniel Lezcano <daniel.lezcano@linaro.org>
+---
+ arch/arm/boot/dts/sun5i-a10s.dtsi | 7 +++++++
+ 1 file changed, 7 insertions(+)
+
+diff --git a/arch/arm/boot/dts/sun5i-a10s.dtsi b/arch/arm/boot/dts/sun5i-a10s.dtsi
+index b4764be..924a2c1 100644
+--- a/arch/arm/boot/dts/sun5i-a10s.dtsi
++++ b/arch/arm/boot/dts/sun5i-a10s.dtsi
+@@ -336,5 +336,12 @@
+                       clock-frequency = <100000>;
+                       status = "disabled";
+               };
++
++              timer@01c60000 {
++                      compatible = "allwinner,sun5i-a13-hstimer";
++                      reg = <0x01c60000 0x1000>;
++                      interrupts = <82>, <83>;
++                      clocks = <&ahb_gates 28>;
++              };
+       };
+ };
+-- 
+1.8.5.1
+
diff --git a/target/linux/sunxi/patches-3.13/146-2-dt-sun5i-a13-add-hstimer.patch b/target/linux/sunxi/patches-3.13/146-2-dt-sun5i-a13-add-hstimer.patch
new file mode 100644 (file)
index 0000000..b209b12
--- /dev/null
@@ -0,0 +1,38 @@
+From 22a3eff19679e0e592e061201690670a2f5fdba7 Mon Sep 17 00:00:00 2001
+From: Maxime Ripard <maxime.ripard@free-electrons.com>
+Date: Thu, 7 Nov 2013 12:01:48 +0100
+Subject: [PATCH] ARM: sun5i: a13: Add support for the High Speed Timers
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+The Allwinner A13 has support for two high speed timers. Now that we
+have a driver to support it, we can enable them in the device tree.
+
+Signed-off-by: Maxime Ripard <maxime.ripard@free-electrons.com>
+Tested-by: Emilio López <emilio@elopez.com.ar>
+Signed-off-by: Daniel Lezcano <daniel.lezcano@linaro.org>
+---
+ arch/arm/boot/dts/sun5i-a13.dtsi | 7 +++++++
+ 1 file changed, 7 insertions(+)
+
+diff --git a/arch/arm/boot/dts/sun5i-a13.dtsi b/arch/arm/boot/dts/sun5i-a13.dtsi
+index ce8ef2a..1ccd75d 100644
+--- a/arch/arm/boot/dts/sun5i-a13.dtsi
++++ b/arch/arm/boot/dts/sun5i-a13.dtsi
+@@ -273,5 +273,12 @@
+                       clock-frequency = <100000>;
+                       status = "disabled";
+               };
++
++              timer@01c60000 {
++                      compatible = "allwinner,sun5i-a13-hstimer";
++                      reg = <0x01c60000 0x1000>;
++                      interrupts = <82>, <83>;
++                      clocks = <&ahb_gates 28>;
++              };
+       };
+ };
+-- 
+1.8.5.1
+
diff --git a/target/linux/sunxi/patches-3.13/146-3-dt-sun7i-a20-add-hstimer.patch b/target/linux/sunxi/patches-3.13/146-3-dt-sun7i-a20-add-hstimer.patch
new file mode 100644 (file)
index 0000000..7112ff0
--- /dev/null
@@ -0,0 +1,48 @@
+From 6c23e1fa6bd220b8f5665c150c83d4c016d95482 Mon Sep 17 00:00:00 2001
+From: Maxime Ripard <maxime.ripard@free-electrons.com>
+Date: Thu, 7 Nov 2013 12:01:48 +0100
+Subject: [PATCH] ARM: sun7i: a20: Add support for the High Speed Timers
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+The Allwinner A20 has support for four high speed timers. Apart for the
+number of timers (4 vs 2), it's basically the same logic than the high
+speed timers found in the sun5i chips.
+
+Now that we have a driver to support it, we can enable them in the
+device tree.
+
+[dlezcano] : Fixed conflict with 428abbb8 "Enable the I2C controllers"
+
+Signed-off-by: Maxime Ripard <maxime.ripard@free-electrons.com>
+Tested-by: Emilio López <emilio@elopez.com.ar>
+Signed-off-by: Daniel Lezcano <daniel.lezcano@linaro.org>
+---
+ arch/arm/boot/dts/sun7i-a20.dtsi | 10 ++++++++++
+ 1 file changed, 10 insertions(+)
+
+diff --git a/arch/arm/boot/dts/sun7i-a20.dtsi b/arch/arm/boot/dts/sun7i-a20.dtsi
+index 93f7f96..c74147a 100644
+--- a/arch/arm/boot/dts/sun7i-a20.dtsi
++++ b/arch/arm/boot/dts/sun7i-a20.dtsi
+@@ -405,6 +405,16 @@
+                       status = "disabled";
+               };
++              hstimer@01c60000 {
++                      compatible = "allwinner,sun7i-a20-hstimer";
++                      reg = <0x01c60000 0x1000>;
++                      interrupts = <0 81 1>,
++                                   <0 82 1>,
++                                   <0 83 1>,
++                                   <0 84 1>;
++                      clocks = <&ahb_gates 28>;
++              };
++
+               gic: interrupt-controller@01c81000 {
+                       compatible = "arm,cortex-a7-gic", "arm,cortex-a15-gic";
+                       reg = <0x01c81000 0x1000>,
+-- 
+1.8.5.1
+
diff --git a/target/linux/sunxi/patches-3.13/150-1-clk-sunxi-implement-mmc-phasectrl.patch b/target/linux/sunxi/patches-3.13/150-1-clk-sunxi-implement-mmc-phasectrl.patch
new file mode 100644 (file)
index 0000000..69586c4
--- /dev/null
@@ -0,0 +1,62 @@
+From 4f43ab43125a12dbc23e352ac0eb4fd80a876fb5 Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?Emilio=20L=C3=B3pez?= <emilio@elopez.com.ar>
+Date: Fri, 20 Sep 2013 20:29:17 -0300
+Subject: [PATCH] clk: sunxi: Implement MMC phase control
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+Signed-off-by: Emilio López <emilio@elopez.com.ar>
+---
+ drivers/clk/sunxi/clk-sunxi.c | 35 +++++++++++++++++++++++++++++++++++
+ 1 file changed, 35 insertions(+)
+
+diff --git a/drivers/clk/sunxi/clk-sunxi.c b/drivers/clk/sunxi/clk-sunxi.c
+index 625089b..6d3286a 100644
+--- a/drivers/clk/sunxi/clk-sunxi.c
++++ b/drivers/clk/sunxi/clk-sunxi.c
+@@ -361,6 +361,41 @@ static void sun4i_get_mod0_factors(u32 *freq, u32 parent_rate,
+ /**
++ * clk_sunxi_mmc_phase_control() - configures MMC clock phase control
++ */
++
++void clk_sunxi_mmc_phase_control(struct clk_hw *hw, u8 sample, u8 output)
++{
++      #define to_clk_composite(_hw) container_of(_hw, struct clk_composite, hw)
++      #define to_clk_factors(_hw) container_of(_hw, struct clk_factors, hw)
++
++      struct clk_composite *composite = to_clk_composite(hw);
++      struct clk_hw *rate_hw = composite->rate_hw;
++      struct clk_factors *factors = to_clk_factors(rate_hw);
++      unsigned long flags = 0;
++      u32 reg;
++
++      if (factors->lock)
++              spin_lock_irqsave(factors->lock, flags);
++
++      reg = readl(factors->reg);
++
++      /* set sample clock phase control */
++      reg &= ~(0x7 << 20);
++      reg |= ((sample & 0x7) << 20);
++
++      /* set output clock phase control */
++      reg &= ~(0x7 << 8);
++      reg |= ((output & 0x7) << 8);
++
++      writel(reg, factors->reg);
++
++      if (factors->lock)
++              spin_unlock_irqrestore(factors->lock, flags);
++}
++
++
++/**
+  * sunxi_factors_clk_setup() - Setup function for factor clocks
+  */
+-- 
+1.8.5.1
+
diff --git a/target/linux/sunxi/patches-3.13/150-2-clk-sunxi-export-func.patch b/target/linux/sunxi/patches-3.13/150-2-clk-sunxi-export-func.patch
new file mode 100644 (file)
index 0000000..59c8849
--- /dev/null
@@ -0,0 +1,42 @@
+From a8cfe8ebdb18e6724b6520e08602b8e72e762ab9 Mon Sep 17 00:00:00 2001
+From: Hans de Goede <hdegoede@redhat.com>
+Date: Sun, 15 Dec 2013 19:44:01 +0100
+Subject: [PATCH] ARM: sunxi: clk: export clk_sunxi_mmc_phase_control
+
+Signed-off-by: Hans de Goede <hdegoede@redhat.com>
+---
+ include/linux/clk/sunxi.h | 22 ++++++++++++++++++++++
+ 1 file changed, 22 insertions(+)
+ create mode 100644 include/linux/clk/sunxi.h
+
+diff --git a/include/linux/clk/sunxi.h b/include/linux/clk/sunxi.h
+new file mode 100644
+index 0000000..1ef5c89
+--- /dev/null
++++ b/include/linux/clk/sunxi.h
+@@ -0,0 +1,22 @@
++/*
++ * Copyright 2013 - Hans de Goede <hdegoede@redhat.com>
++ *
++ * 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.
++ */
++
++#ifndef __LINUX_CLK_SUNXI_H_
++#define __LINUX_CLK_SUNXI_H_
++
++#include <linux/clk.h>
++
++void clk_sunxi_mmc_phase_control(struct clk_hw *hw, u8 sample, u8 output);
++
++#endif
+-- 
+1.8.5.1
+
diff --git a/target/linux/sunxi/patches-3.13/151-pinctrl-sun5i-a13-port-F.patch b/target/linux/sunxi/patches-3.13/151-pinctrl-sun5i-a13-port-F.patch
new file mode 100644 (file)
index 0000000..cbd3194
--- /dev/null
@@ -0,0 +1,56 @@
+From 33b0123664b627005728cfe7b1967b790392ceec Mon Sep 17 00:00:00 2001
+From: Hans de Goede <hdegoede@redhat.com>
+Date: Sat, 14 Dec 2013 17:20:13 +0100
+Subject: [PATCH] ARM: sunxi: fix sun5i-a13 port F multiplexing
+
+The correct value for selecting the mmc0 function on port F pins is 2 not 4,
+as per the data-sheet:
+http://dl.linux-sunxi.org/A13/A13%20Datasheet%20-%20v1.12%20%282012-03-29%29.pdf
+
+Signed-off-by: Hans de Goede <hdegoede@redhat.com>
+Acked-by: Maxime Ripard <maxime.ripard@free-electrons.com>
+---
+ drivers/pinctrl/pinctrl-sunxi-pins.h | 12 ++++++------
+ 1 file changed, 6 insertions(+), 6 deletions(-)
+
+diff --git a/drivers/pinctrl/pinctrl-sunxi-pins.h b/drivers/pinctrl/pinctrl-sunxi-pins.h
+index 2c7446a..7c1b05e 100644
+--- a/drivers/pinctrl/pinctrl-sunxi-pins.h
++++ b/drivers/pinctrl/pinctrl-sunxi-pins.h
+@@ -1932,27 +1932,27 @@
+       SUNXI_PIN(SUNXI_PINCTRL_PIN_PF0,
+                 SUNXI_FUNCTION(0x0, "gpio_in"),
+                 SUNXI_FUNCTION(0x1, "gpio_out"),
+-                SUNXI_FUNCTION(0x4, "mmc0")),         /* D1 */
++                SUNXI_FUNCTION(0x2, "mmc0")),         /* D1 */
+       SUNXI_PIN(SUNXI_PINCTRL_PIN_PF1,
+                 SUNXI_FUNCTION(0x0, "gpio_in"),
+                 SUNXI_FUNCTION(0x1, "gpio_out"),
+-                SUNXI_FUNCTION(0x4, "mmc0")),         /* D0 */
++                SUNXI_FUNCTION(0x2, "mmc0")),         /* D0 */
+       SUNXI_PIN(SUNXI_PINCTRL_PIN_PF2,
+                 SUNXI_FUNCTION(0x0, "gpio_in"),
+                 SUNXI_FUNCTION(0x1, "gpio_out"),
+-                SUNXI_FUNCTION(0x4, "mmc0")),         /* CLK */
++                SUNXI_FUNCTION(0x2, "mmc0")),         /* CLK */
+       SUNXI_PIN(SUNXI_PINCTRL_PIN_PF3,
+                 SUNXI_FUNCTION(0x0, "gpio_in"),
+                 SUNXI_FUNCTION(0x1, "gpio_out"),
+-                SUNXI_FUNCTION(0x4, "mmc0")),         /* CMD */
++                SUNXI_FUNCTION(0x2, "mmc0")),         /* CMD */
+       SUNXI_PIN(SUNXI_PINCTRL_PIN_PF4,
+                 SUNXI_FUNCTION(0x0, "gpio_in"),
+                 SUNXI_FUNCTION(0x1, "gpio_out"),
+-                SUNXI_FUNCTION(0x4, "mmc0")),         /* D3 */
++                SUNXI_FUNCTION(0x2, "mmc0")),         /* D3 */
+       SUNXI_PIN(SUNXI_PINCTRL_PIN_PF5,
+                 SUNXI_FUNCTION(0x0, "gpio_in"),
+                 SUNXI_FUNCTION(0x1, "gpio_out"),
+-                SUNXI_FUNCTION(0x4, "mmc0")),         /* D2 */
++                SUNXI_FUNCTION(0x2, "mmc0")),         /* D2 */
+       /* Hole */
+       SUNXI_PIN(SUNXI_PINCTRL_PIN_PG0,
+                 SUNXI_FUNCTION(0x0, "gpio_in"),
+-- 
+1.8.5.1
+
diff --git a/target/linux/sunxi/patches-3.13/152-sunxi-mmc-add-Kconfig.patch b/target/linux/sunxi/patches-3.13/152-sunxi-mmc-add-Kconfig.patch
new file mode 100644 (file)
index 0000000..c3cb13d
--- /dev/null
@@ -0,0 +1,55 @@
+From 447675f817b95881e9922f002de3fc7f6d6e9207 Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?David=20Lanzend=C3=B6rfer?= <david.lanzendoerfer@o2s.ch>
+Date: Fri, 6 Sep 2013 22:34:33 +0200
+Subject: [PATCH] ARM: sunxi-mci: Add driver for SD/MMC hosts found within
+ Allwinner A1X SoCs
+
+Signed-off-by: Hans de Goede <hdegoede@redhat.com>
+---
+ drivers/mmc/host/Kconfig     |    8 +
+ drivers/mmc/host/Makefile    |    2 +
+ drivers/mmc/host/sunxi-mci.c | 1056 ++++++++++++++++++++++++++++++++++++++++++
+ drivers/mmc/host/sunxi-mci.h |  334 +++++++++++++
+ 4 files changed, 1400 insertions(+)
+ create mode 100644 drivers/mmc/host/sunxi-mci.c
+ create mode 100644 drivers/mmc/host/sunxi-mci.h
+
+diff --git a/drivers/mmc/host/Kconfig b/drivers/mmc/host/Kconfig
+index 7fc5099..0df0322 100644
+--- a/drivers/mmc/host/Kconfig
++++ b/drivers/mmc/host/Kconfig
+@@ -665,3 +665,11 @@ config MMC_REALTEK_PCI
+       help
+         Say Y here to include driver code to support SD/MMC card interface
+         of Realtek PCI-E card reader
++
++config MMC_SUNXI
++      tristate "Allwinner A1X SD/MMC Host Controller support"
++      depends on ARCH_SUNXI
++      default y
++      help
++        This selects support for the SD/MMC Host Controller on
++        Allwinner A1X based SoCs.
+diff --git a/drivers/mmc/host/Makefile b/drivers/mmc/host/Makefile
+index c41d0c3..f76f783 100644
+--- a/drivers/mmc/host/Makefile
++++ b/drivers/mmc/host/Makefile
+@@ -52,6 +52,8 @@ obj-$(CONFIG_MMC_WMT)                += wmt-sdmmc.o
+ obj-$(CONFIG_MMC_REALTEK_PCI) += rtsx_pci_sdmmc.o
++obj-$(CONFIG_MMC_SUNXI)               += sunxi-mci.o
++
+ obj-$(CONFIG_MMC_SDHCI_PLTFM)         += sdhci-pltfm.o
+ obj-$(CONFIG_MMC_SDHCI_CNS3XXX)               += sdhci-cns3xxx.o
+ obj-$(CONFIG_MMC_SDHCI_ESDHC_IMX)     += sdhci-esdhc-imx.o
+diff --git a/drivers/mmc/host/sunxi-mci.c b/drivers/mmc/host/sunxi-mci.c
+new file mode 100644
+index 0000000..cbde1d3
+diff --git a/drivers/mmc/host/sunxi-mci.h b/drivers/mmc/host/sunxi-mci.h
+new file mode 100644
+index 0000000..0f5f95c
+\ No newline at end of file
+-- 
+1.8.5.1
+
diff --git a/target/linux/sunxi/patches-3.13/153-1-dt-sun4i-add-mmc.patch b/target/linux/sunxi/patches-3.13/153-1-dt-sun4i-add-mmc.patch
new file mode 100644 (file)
index 0000000..bcc323f
--- /dev/null
@@ -0,0 +1,106 @@
+From 677631fa522e4ac24f636535e3abb5cd1a5ef40e Mon Sep 17 00:00:00 2001
+From: Hans de Goede <hdegoede@redhat.com>
+Date: Sat, 14 Dec 2013 22:58:12 +0100
+Subject: [PATCH] ARM: dts: sun4i: Add support for mmc
+
+Signed-off-by: Hans de Goede <hdegoede@redhat.com>
+---
+ arch/arm/boot/dts/sun4i-a10-a1000.dts      | 16 ++++++++++++++++
+ arch/arm/boot/dts/sun4i-a10-cubieboard.dts | 16 ++++++++++++++++
+ arch/arm/boot/dts/sun4i-a10.dtsi           | 17 +++++++++++++++++
+ 3 files changed, 49 insertions(+)
+
+diff --git a/arch/arm/boot/dts/sun4i-a10-a1000.dts b/arch/arm/boot/dts/sun4i-a10-a1000.dts
+index eb4d73b..aef8207 100644
+--- a/arch/arm/boot/dts/sun4i-a10-a1000.dts
++++ b/arch/arm/boot/dts/sun4i-a10-a1000.dts
+@@ -39,7 +39,23 @@
+                       };
+               };
++              mmc0: mmc@01c0f000 {
++                      pinctrl-names = "default";
++                      pinctrl-0 = <&mmc0_pins_a>;
++                      pinctrl-1 = <&mmc0_cd_pin_a1000>;
++                      cd-gpios = <&pio 7 1 0>; /* PH1 */
++                      cd-mode = <1>;
++                      status = "okay";
++              };
++
+               pinctrl@01c20800 {
++                      mmc0_cd_pin_a1000: mmc0_cd_pin@0 {
++                              allwinner,pins = "PH1";
++                              allwinner,function = "gpio_in";
++                              allwinner,drive = <0>;
++                              allwinner,pull = <0>;
++                      };
++
+                       emac_power_pin_a1000: emac_power_pin@0 {
+                               allwinner,pins = "PH15";
+                               allwinner,function = "gpio_out";
+diff --git a/arch/arm/boot/dts/sun4i-a10-cubieboard.dts b/arch/arm/boot/dts/sun4i-a10-cubieboard.dts
+index 425a7db..f50fb2b 100644
+--- a/arch/arm/boot/dts/sun4i-a10-cubieboard.dts
++++ b/arch/arm/boot/dts/sun4i-a10-cubieboard.dts
+@@ -42,7 +42,23 @@
+                       };
+               };
++              mmc0: mmc@01c0f000 {
++                      pinctrl-names = "default";
++                      pinctrl-0 = <&mmc0_pins_a>;
++                      pinctrl-1 = <&mmc0_cd_pin_cubieboard>;
++                      cd-gpios = <&pio 7 1 0>; /* PH1 */
++                      cd-mode = <1>;
++                      status = "okay";
++              };
++
+               pinctrl@01c20800 {
++                      mmc0_cd_pin_cubieboard: mmc0_cd_pin@0 {
++                              allwinner,pins = "PH1";
++                              allwinner,function = "gpio_in";
++                              allwinner,drive = <0>;
++                              allwinner,pull = <0>;
++                      };
++
+                       led_pins_cubieboard: led_pins@0 {
+                               allwinner,pins = "PH20", "PH21";
+                               allwinner,function = "gpio_out";
+diff --git a/arch/arm/boot/dts/sun4i-a10.dtsi b/arch/arm/boot/dts/sun4i-a10.dtsi
+index 9779c6b..4736dd2 100644
+--- a/arch/arm/boot/dts/sun4i-a10.dtsi
++++ b/arch/arm/boot/dts/sun4i-a10.dtsi
+@@ -321,6 +321,16 @@
+                       #size-cells = <0>;
+               };
++              mmc0: mmc@01c0f000 {
++                      compatible = "allwinner,sun4i-a10-mmc";
++                      reg = <0x01c0f000 0x1000>;
++                      clocks = <&ahb_gates 8>, <&mmc0_clk>;
++                      clock-names = "ahb", "mod";
++                      interrupts = <32>;
++                      bus-width = <4>;
++                      status = "disabled";
++              };
++
+               intc: interrupt-controller@01c20400 {
+                       compatible = "allwinner,sun4i-ic";
+                       reg = <0x01c20400 0x400>;
+@@ -391,6 +401,13 @@
+                               allwinner,drive = <0>;
+                               allwinner,pull = <0>;
+                       };
++
++                      mmc0_pins_a: mmc0@0 {
++                              allwinner,pins = "PF0","PF1","PF2","PF3","PF4","PF5";
++                              allwinner,function = "mmc0";
++                              allwinner,drive = <3>;
++                              allwinner,pull = <0>;
++                      };
+               };
+               timer@01c20c00 {
+-- 
+1.8.5.1
+
diff --git a/target/linux/sunxi/patches-3.13/153-2-dt-sun5i-add-mmc.patch b/target/linux/sunxi/patches-3.13/153-2-dt-sun5i-add-mmc.patch
new file mode 100644 (file)
index 0000000..48d8f85
--- /dev/null
@@ -0,0 +1,204 @@
+From 48332fd7217cf5b06b438503513e54e6138e0637 Mon Sep 17 00:00:00 2001
+From: Hans de Goede <hdegoede@redhat.com>
+Date: Sat, 14 Dec 2013 22:58:14 +0100
+Subject: [PATCH] ARM: dts: sun5i: Add support for mmc
+
+Signed-off-by: Hans de Goede <hdegoede@redhat.com>
+---
+ arch/arm/boot/dts/sun5i-a10s-olinuxino-micro.dts | 32 ++++++++++++++++++++++
+ arch/arm/boot/dts/sun5i-a10s.dtsi                | 34 ++++++++++++++++++++++++
+ arch/arm/boot/dts/sun5i-a13-olinuxino-micro.dts  | 16 +++++++++++
+ arch/arm/boot/dts/sun5i-a13-olinuxino.dts        | 16 +++++++++++
+ arch/arm/boot/dts/sun5i-a13.dtsi                 | 17 ++++++++++++
+ 5 files changed, 115 insertions(+)
+
+diff --git a/arch/arm/boot/dts/sun5i-a10s-olinuxino-micro.dts b/arch/arm/boot/dts/sun5i-a10s-olinuxino-micro.dts
+index 3c9f8b3..e47a731 100644
+--- a/arch/arm/boot/dts/sun5i-a10s-olinuxino-micro.dts
++++ b/arch/arm/boot/dts/sun5i-a10s-olinuxino-micro.dts
+@@ -34,7 +34,39 @@
+                       };
+               };
++              mmc0: mmc@01c0f000 {
++                      pinctrl-names = "default";
++                      pinctrl-0 = <&mmc0_pins_a>;
++                      pinctrl-1 = <&mmc0_cd_pin_olinuxino_micro>;
++                      cd-gpios = <&pio 6 1 0>; /* PG1 */
++                      cd-mode = <1>;
++                      status = "okay";
++              };
++
++              mmc1: mmc@01c10000 {
++                      pinctrl-names = "default";
++                      pinctrl-0 = <&mmc1_pins_a>;
++                      pinctrl-1 = <&mmc1_cd_pin_olinuxino_micro>;
++                      cd-gpios = <&pio 6 13 0>; /* PG13 */
++                      cd-mode = <1>;
++                      status = "okay";
++              };
++
+               pinctrl@01c20800 {
++                      mmc0_cd_pin_olinuxino_micro: mmc0_cd_pin@0 {
++                              allwinner,pins = "PG1";
++                              allwinner,function = "gpio_in";
++                              allwinner,drive = <0>;
++                              allwinner,pull = <0>;
++                      };
++
++                      mmc1_cd_pin_olinuxino_micro: mmc1_cd_pin@0 {
++                              allwinner,pins = "PG13";
++                              allwinner,function = "gpio_in";
++                              allwinner,drive = <0>;
++                              allwinner,pull = <0>;
++                      };
++
+                       led_pins_olinuxino: led_pins@0 {
+                               allwinner,pins = "PE3";
+                               allwinner,function = "gpio_out";
+diff --git a/arch/arm/boot/dts/sun5i-a10s.dtsi b/arch/arm/boot/dts/sun5i-a10s.dtsi
+index c42ed2a..c3bb9bd 100644
+--- a/arch/arm/boot/dts/sun5i-a10s.dtsi
++++ b/arch/arm/boot/dts/sun5i-a10s.dtsi
+@@ -286,6 +286,26 @@
+                       #size-cells = <0>;
+               };
++              mmc0: mmc@01c0f000 {
++                      compatible = "allwinner,sun5i-a13-mmc";
++                      reg = <0x01c0f000 0x1000>;
++                      clocks = <&ahb_gates 8>, <&mmc0_clk>;
++                      clock-names = "ahb", "mod";
++                      interrupts = <32>;
++                      bus-width = <4>;
++                      status = "disabled";
++              };
++
++              mmc1: mmc@01c10000 {
++                      compatible = "allwinner,sun5i-a13-mmc";
++                      reg = <0x01c10000 0x1000>;
++                      clocks = <&ahb_gates 9>, <&mmc1_clk>;
++                      clock-names = "ahb", "mod";
++                      interrupts = <33>;
++                      bus-width = <4>;
++                      status = "disabled";
++              };
++
+               intc: interrupt-controller@01c20400 {
+                       compatible = "allwinner,sun4i-ic";
+                       reg = <0x01c20400 0x400>;
+@@ -356,6 +376,20 @@
+                               allwinner,drive = <0>;
+                               allwinner,pull = <0>;
+                       };
++
++                      mmc0_pins_a: mmc0@0 {
++                              allwinner,pins = "PF0","PF1","PF2","PF3","PF4","PF5";
++                              allwinner,function = "mmc0";
++                              allwinner,drive = <3>;
++                              allwinner,pull = <0>;
++                      };
++
++                      mmc1_pins_a: mmc1@0 {
++                              allwinner,pins = "PG3","PG4","PG5","PG6","PG7","PG8";
++                              allwinner,function = "mmc1";
++                              allwinner,drive = <3>;
++                              allwinner,pull = <0>;
++                      };
+               };
+               timer@01c20c00 {
+diff --git a/arch/arm/boot/dts/sun5i-a13-olinuxino-micro.dts b/arch/arm/boot/dts/sun5i-a13-olinuxino-micro.dts
+index fe2ce0a..37ec3d9 100644
+--- a/arch/arm/boot/dts/sun5i-a13-olinuxino-micro.dts
++++ b/arch/arm/boot/dts/sun5i-a13-olinuxino-micro.dts
+@@ -20,7 +20,23 @@
+       compatible = "olimex,a13-olinuxino-micro", "allwinner,sun5i-a13";
+       soc@01c00000 {
++              mmc0: mmc@01c0f000 {
++                      pinctrl-names = "default";
++                      pinctrl-0 = <&mmc0_pins_a>;
++                      pinctrl-1 = <&mmc0_cd_pin_olinuxinom>;
++                      cd-gpios = <&pio 6 0 0>; /* PG0 */
++                      cd-mode = <1>;
++                      status = "okay";
++              };
++
+               pinctrl@01c20800 {
++                      mmc0_cd_pin_olinuxinom: mmc0_cd_pin@0 {
++                              allwinner,pins = "PG0";
++                              allwinner,function = "gpio_in";
++                              allwinner,drive = <0>;
++                              allwinner,pull = <0>;
++                      };
++
+                       led_pins_olinuxinom: led_pins@0 {
+                               allwinner,pins = "PG9";
+                               allwinner,function = "gpio_out";
+diff --git a/arch/arm/boot/dts/sun5i-a13-olinuxino.dts b/arch/arm/boot/dts/sun5i-a13-olinuxino.dts
+index 9e508dc..cf77d9a 100644
+--- a/arch/arm/boot/dts/sun5i-a13-olinuxino.dts
++++ b/arch/arm/boot/dts/sun5i-a13-olinuxino.dts
+@@ -23,7 +23,23 @@
+       };
+       soc@01c00000 {
++              mmc0: mmc@01c0f000 {
++                      pinctrl-names = "default";
++                      pinctrl-0 = <&mmc0_pins_a>;
++                      pinctrl-1 = <&mmc0_cd_pin_olinuxino>;
++                      cd-gpios = <&pio 6 0 0>; /* PG0 */
++                      cd-mode = <1>;
++                      status = "okay";
++              };
++
+               pinctrl@01c20800 {
++                      mmc0_cd_pin_olinuxino: mmc0_cd_pin@0 {
++                              allwinner,pins = "PG0";
++                              allwinner,function = "gpio_in";
++                              allwinner,drive = <0>;
++                              allwinner,pull = <0>;
++                      };
++
+                       led_pins_olinuxino: led_pins@0 {
+                               allwinner,pins = "PG9";
+                               allwinner,function = "gpio_out";
+diff --git a/arch/arm/boot/dts/sun5i-a13.dtsi b/arch/arm/boot/dts/sun5i-a13.dtsi
+index 8274a41..2dde48a 100644
+--- a/arch/arm/boot/dts/sun5i-a13.dtsi
++++ b/arch/arm/boot/dts/sun5i-a13.dtsi
+@@ -267,6 +267,16 @@
+               #size-cells = <1>;
+               ranges;
++              mmc0: mmc@01c0f000 {
++                      compatible = "allwinner,sun5i-a13-mmc";
++                      reg = <0x01c0f000 0x1000>;
++                      clocks = <&ahb_gates 8>, <&mmc0_clk>;
++                      clock-names = "ahb", "mod";
++                      interrupts = <32>;
++                      bus-width = <4>;
++                      status = "disabled";
++              };
++
+               intc: interrupt-controller@01c20400 {
+                       compatible = "allwinner,sun4i-ic";
+                       reg = <0x01c20400 0x400>;
+@@ -319,6 +329,13 @@
+                               allwinner,drive = <0>;
+                               allwinner,pull = <0>;
+                       };
++
++                      mmc0_pins_a: mmc0@0 {
++                              allwinner,pins = "PF0","PF1","PF2","PF3","PF4","PF5";
++                              allwinner,function = "mmc0";
++                              allwinner,drive = <3>;
++                              allwinner,pull = <0>;
++                      };
+               };
+               timer@01c20c00 {
+-- 
+1.8.5.1
+
diff --git a/target/linux/sunxi/patches-3.13/153-3-dt-sun7i-add-mmc.patch b/target/linux/sunxi/patches-3.13/153-3-dt-sun7i-add-mmc.patch
new file mode 100644 (file)
index 0000000..79286b2
--- /dev/null
@@ -0,0 +1,142 @@
+From 3cce544eb5964c14653dddde731cac4cbff97d90 Mon Sep 17 00:00:00 2001
+From: Hans de Goede <hdegoede@redhat.com>
+Date: Sat, 14 Dec 2013 22:58:15 +0100
+Subject: [PATCH] ARM: dts: sun7i: Add support for mmc
+
+Signed-off-by: Hans de Goede <hdegoede@redhat.com>
+---
+ arch/arm/boot/dts/sun7i-a20-cubieboard2.dts     | 16 ++++++++++++
+ arch/arm/boot/dts/sun7i-a20-cubietruck.dts      | 16 ++++++++++++
+ arch/arm/boot/dts/sun7i-a20-olinuxino-micro.dts | 32 +++++++++++++++++++++++
+ arch/arm/boot/dts/sun7i-a20.dtsi                | 34 +++++++++++++++++++++++++
+ 4 files changed, 98 insertions(+)
+
+diff --git a/arch/arm/boot/dts/sun7i-a20-cubieboard2.dts b/arch/arm/boot/dts/sun7i-a20-cubieboard2.dts
+index 5c51cb8..d28e600 100644
+--- a/arch/arm/boot/dts/sun7i-a20-cubieboard2.dts
++++ b/arch/arm/boot/dts/sun7i-a20-cubieboard2.dts
+@@ -34,7 +34,23 @@
+                       };
+               };
++              mmc0: mmc@01c0f000 {
++                      pinctrl-names = "default";
++                      pinctrl-0 = <&mmc0_pins_a>;
++                      pinctrl-1 = <&mmc0_cd_pin_cubieboard2>;
++                      cd-gpios = <&pio 7 1 0>; /* PH1 */
++                      cd-mode = <1>;
++                      status = "okay";
++              };
++
+               pinctrl@01c20800 {
++                      mmc0_cd_pin_cubieboard2: mmc0_cd_pin@0 {
++                              allwinner,pins = "PH1";
++                              allwinner,function = "gpio_in";
++                              allwinner,drive = <0>;
++                              allwinner,pull = <0>;
++                      };
++
+                       led_pins_cubieboard2: led_pins@0 {
+                               allwinner,pins = "PH20", "PH21";
+                               allwinner,function = "gpio_out";
+diff --git a/arch/arm/boot/dts/sun7i-a20-cubietruck.dts b/arch/arm/boot/dts/sun7i-a20-cubietruck.dts
+index 8a1009d..7ee628a 100644
+diff --git a/arch/arm/boot/dts/sun7i-a20-olinuxino-micro.dts b/arch/arm/boot/dts/sun7i-a20-olinuxino-micro.dts
+index ead3013..d377696 100644
+--- a/arch/arm/boot/dts/sun7i-a20-olinuxino-micro.dts
++++ b/arch/arm/boot/dts/sun7i-a20-olinuxino-micro.dts
+@@ -34,7 +34,39 @@
+                       };
+               };
++              mmc0: mmc@01c0f000 {
++                      pinctrl-names = "default";
++                      pinctrl-0 = <&mmc0_pins_a>;
++                      pinctrl-1 = <&mmc0_cd_pin_olinuxinom>;
++                      cd-gpios = <&pio 7 1 0>; /* PH1 */
++                      cd-mode = <1>;
++                      status = "okay";
++              };
++
++              mmc3: mmc@01c12000 {
++                      pinctrl-names = "default";
++                      pinctrl-0 = <&mmc3_pins_a>;
++                      pinctrl-1 = <&mmc3_cd_pin_olinuxinom>;
++                      cd-gpios = <&pio 7 11 0>; /* PH11 */
++                      cd-mode = <1>;
++                      status = "okay";
++              };
++
+               pinctrl@01c20800 {
++                      mmc0_cd_pin_olinuxinom: mmc0_cd_pin@0 {
++                              allwinner,pins = "PH1";
++                              allwinner,function = "gpio_in";
++                              allwinner,drive = <0>;
++                              allwinner,pull = <0>;
++                      };
++
++                      mmc3_cd_pin_olinuxinom: mmc3_cd_pin@0 {
++                              allwinner,pins = "PH11";
++                              allwinner,function = "gpio_in";
++                              allwinner,drive = <0>;
++                              allwinner,pull = <0>;
++                      };
++
+                       led_pins_olinuxino: led_pins@0 {
+                               allwinner,pins = "PH2";
+                               allwinner,function = "gpio_out";
+diff --git a/arch/arm/boot/dts/sun7i-a20.dtsi b/arch/arm/boot/dts/sun7i-a20.dtsi
+index 8819c68..0c1d363 100644
+--- a/arch/arm/boot/dts/sun7i-a20.dtsi
++++ b/arch/arm/boot/dts/sun7i-a20.dtsi
+@@ -319,6 +319,26 @@
+                       #size-cells = <0>;
+               };
++              mmc0: mmc@01c0f000 {
++                      compatible = "allwinner,sun5i-a13-mmc";
++                      reg = <0x01c0f000 0x1000>;
++                      clocks = <&ahb_gates 8>, <&mmc0_clk>;
++                      clock-names = "ahb", "mod";
++                      interrupts = <0 32 4>;
++                      bus-width = <4>;
++                      status = "disabled";
++              };
++
++              mmc3: mmc@01c12000 {
++                      compatible = "allwinner,sun5i-a13-mmc";
++                      reg = <0x01c12000 0x1000>;
++                      clocks = <&ahb_gates 11>, <&mmc3_clk>;
++                      clock-names = "ahb", "mod";
++                      interrupts = <0 35 4>;
++                      bus-width = <4>;
++                      status = "disabled";
++              };
++
+               pio: pinctrl@01c20800 {
+                       compatible = "allwinner,sun7i-a20-pinctrl";
+                       reg = <0x01c20800 0x400>;
+@@ -382,6 +402,20 @@
+                               allwinner,drive = <0>;
+                               allwinner,pull = <0>;
+                       };
++
++                      mmc0_pins_a: mmc0@0 {
++                              allwinner,pins = "PF0","PF1","PF2","PF3","PF4","PF5";
++                              allwinner,function = "mmc0";
++                              allwinner,drive = <3>;
++                              allwinner,pull = <0>;
++                      };
++
++                      mmc3_pins_a: mmc3@0 {
++                              allwinner,pins = "PI4","PI5","PI6","PI7","PI8","PI9";
++                              allwinner,function = "mmc3";
++                              allwinner,drive = <3>;
++                              allwinner,pull = <0>;
++                      };
+               };
+               timer@01c20c00 {
+-- 
+1.8.5.1
+
diff --git a/target/linux/sunxi/patches-3.13/154-mmc-update-compat-nodes.patch b/target/linux/sunxi/patches-3.13/154-mmc-update-compat-nodes.patch
new file mode 100644 (file)
index 0000000..5de6093
--- /dev/null
@@ -0,0 +1,23 @@
+diff -ruN old/drivers/mmc/host/sunxi-mci.c new/drivers/mmc/host/sunxi-mci.c
+--- old/drivers/mmc/host/sunxi-mci.c   2014-01-22 23:41:25.000000000 +0100
++++ new/drivers/mmc/host/sunxi-mci.c   2014-01-28 16:55:24.000000000 +0100
+@@ -715,8 +715,8 @@
+ }
+ static const struct of_device_id sunxi_mmc_of_match[] = {
+-      { .compatible = "allwinner,sun4i-mmc", },
+-      { .compatible = "allwinner,sun5i-mmc", },
++      { .compatible = "allwinner,sun4i-a10-mmc", },
++      { .compatible = "allwinner,sun5i-a13-mmc", },
+       { /* sentinel */ }
+ };
+ MODULE_DEVICE_TABLE(of, sunxi_mmc_of_match);
+@@ -736,7 +736,7 @@
+       struct device_node *np = pdev->dev.of_node;
+       int ret;
+-      if (of_device_is_compatible(np, "allwinner,sun4i-mmc"))
++      if (of_device_is_compatible(np, "allwinner,sun4i-a10-mmc"))
+               host->idma_des_size_bits = 13;
+       else
+               host->idma_des_size_bits = 16;
diff --git a/target/linux/sunxi/patches-3.13/160-ahci-add-pre-start-hook.patch b/target/linux/sunxi/patches-3.13/160-ahci-add-pre-start-hook.patch
new file mode 100644 (file)
index 0000000..342c114
--- /dev/null
@@ -0,0 +1,53 @@
+From 3eec76bc21d78e56ac8404b59f29dd9dbbd1528a Mon Sep 17 00:00:00 2001
+From: Oliver Schinagl <oliver@schinagl.nl>
+Date: Mon, 2 Dec 2013 16:13:32 +0100
+Subject: [PATCH] libahci: Add a pre ahci_start_engine hook
+
+Allwinner A10 and A20 ARM SoCs have an AHCI sata controller which need a
+special register to be poked before starting the DMA engine.
+
+This register gets reset on an ahci_stop_engine call, so there is no other
+place then ahci_start_engine where this poking can be done.
+
+This commit adds a pre ahci_start_engine hook for use by the Allwinner AHCI
+driver (and potentially other drivers in the future).
+
+Signed-off-by: Hans de Goede <hdegoede@redhat.com>
+---
+ drivers/ata/ahci.h    | 2 ++
+ drivers/ata/libahci.c | 4 ++++
+ 2 files changed, 6 insertions(+)
+
+diff --git a/drivers/ata/ahci.h b/drivers/ata/ahci.h
+index 2289efd..1bba479 100644
+--- a/drivers/ata/ahci.h
++++ b/drivers/ata/ahci.h
+@@ -323,6 +323,8 @@ struct ahci_host_priv {
+       u32                     em_msg_type;    /* EM message type */
+       struct clk              *clk;           /* Only for platforms supporting clk */
+       void                    *plat_data;     /* Other platform data */
++      /* Optional pre ahci_start_engine hook */
++      void                    (*pre_start_engine)(struct ata_port *ap);
+ };
+ extern int ahci_ignore_sss;
+diff --git a/drivers/ata/libahci.c b/drivers/ata/libahci.c
+index c482f8c..780e9df 100644
+--- a/drivers/ata/libahci.c
++++ b/drivers/ata/libahci.c
+@@ -568,8 +568,12 @@ static int ahci_scr_write(struct ata_link *link, unsigned int sc_reg, u32 val)
+ void ahci_start_engine(struct ata_port *ap)
+ {
+       void __iomem *port_mmio = ahci_port_base(ap);
++      struct ahci_host_priv *hpriv = ap->host->private_data;
+       u32 tmp;
++      if (hpriv->pre_start_engine)
++              hpriv->pre_start_engine(ap);
++
+       /* start DMA */
+       tmp = readl(port_mmio + PORT_CMD);
+       tmp |= PORT_CMD_START;
+-- 
+1.8.5.1
+
diff --git a/target/linux/sunxi/patches-3.13/161-sunxi-ahci-add-driver.patch b/target/linux/sunxi/patches-3.13/161-sunxi-ahci-add-driver.patch
new file mode 100644 (file)
index 0000000..c4b8d38
--- /dev/null
@@ -0,0 +1,449 @@
+From 22345cc059de4a6ea1dc7657dd6ad86ca16a8814 Mon Sep 17 00:00:00 2001
+From: Oliver Schinagl <oliver@schinagl.nl>
+Date: Tue, 3 Dec 2013 12:07:01 +0100
+Subject: [PATCH] ARM: sunxi: Add ahci-sunxi driver for the Allwinner SUNXi
+ SoCs sata
+
+This patch adds support for the ahci sata controler found on Allwinner A10
+and A20 SoCs.
+
+Orignally written by Olliver Schinagl using the approach of having a platform
+device which probe method creates a new child platform device which gets
+driven by ahci_platform.c, as done by ahci_imx.c .
+
+Given that almost all functionality already is shared through libahci /
+ata-core, and that ahci_platform.c cannot cleanly handle somewhat more complex
+platform specific ahci cases, such as the sunxi case, it was refactored into
+a stand-alone platform driver by Hans de Goede.
+
+Signed-off-by: Olliver Schinagl <oliver@schinagl.nl>
+Signed-off-by: Hans de Goede <hdegoede@redhat.com>
+---
+ .../devicetree/bindings/ata/ahci-sunxi.txt         |  24 ++
+ drivers/ata/Kconfig                                |   9 +
+ drivers/ata/Makefile                               |   1 +
+ drivers/ata/ahci_sunxi.c                           | 349 +++++++++++++++++++++
+ 4 files changed, 383 insertions(+)
+ create mode 100644 Documentation/devicetree/bindings/ata/ahci-sunxi.txt
+ create mode 100644 drivers/ata/ahci_sunxi.c
+
+diff --git a/Documentation/devicetree/bindings/ata/ahci-sunxi.txt b/Documentation/devicetree/bindings/ata/ahci-sunxi.txt
+new file mode 100644
+index 0000000..0792fa5
+--- /dev/null
++++ b/Documentation/devicetree/bindings/ata/ahci-sunxi.txt
+@@ -0,0 +1,24 @@
++Allwinner SUNXI AHCI SATA Controller
++
++SATA nodes are defined to describe on-chip Serial ATA controllers.
++Each SATA controller should have its own node.
++
++Required properties:
++- compatible  : compatible list, contains "allwinner,sun4i-a10-ahci"
++- reg         : <registers mapping>
++- interrupts  : <interrupt mapping for AHCI IRQ>
++- clocks      : clocks for ACHI
++- clock-names : clock names for AHCI
++
++Optional properties:
++- pwr-supply  : regulator to control the power supply GPIO
++
++Example:
++      ahci@01c18000 {
++              compatible = "allwinner,sun4i-a10-ahci";
++              reg = <0x01c18000 0x1000>;
++              interrupts = <0 56 1>;
++              clocks = <&ahb_gates 25>, <&pll6 0>;
++              clock-names = "ahb_sata", "pll6_sata";
++              pwr-supply = <&reg_ahci_5v>;
++      };
+diff --git a/drivers/ata/Kconfig b/drivers/ata/Kconfig
+index 4e73772..3c80bbe 100644
+--- a/drivers/ata/Kconfig
++++ b/drivers/ata/Kconfig
+@@ -106,6 +106,15 @@ config AHCI_IMX
+         If unsure, say N.
++config AHCI_SUNXI
++      tristate "Allwinner sunxi AHCI SATA support"
++      depends on ARCH_SUNXI
++      help
++        This option enables support for the Allwinner sunxi SoC's
++        onboard AHCI SATA.
++
++        If unsure, say N.
++
+ config SATA_FSL
+       tristate "Freescale 3.0Gbps SATA support"
+       depends on FSL_SOC
+diff --git a/drivers/ata/Makefile b/drivers/ata/Makefile
+index 46518c6..956abc3 100644
+--- a/drivers/ata/Makefile
++++ b/drivers/ata/Makefile
+@@ -11,6 +11,7 @@ obj-$(CONFIG_SATA_SIL24)     += sata_sil24.o
+ obj-$(CONFIG_SATA_DWC)                += sata_dwc_460ex.o
+ obj-$(CONFIG_SATA_HIGHBANK)   += sata_highbank.o libahci.o
+ obj-$(CONFIG_AHCI_IMX)                += ahci_imx.o
++obj-$(CONFIG_AHCI_SUNXI)      += ahci_sunxi.o libahci.o
+ # SFF w/ custom DMA
+ obj-$(CONFIG_PDC_ADMA)                += pdc_adma.o
+diff --git a/drivers/ata/ahci_sunxi.c b/drivers/ata/ahci_sunxi.c
+new file mode 100644
+index 0000000..22d3972
+--- /dev/null
++++ b/drivers/ata/ahci_sunxi.c
+@@ -0,0 +1,349 @@
++/*
++ * Allwinner sunxi AHCI SATA platform driver
++ * Copyright 2013 Olliver Schinagl <oliver@schinagl.nl>
++ * Copyright 2014 Hans de Goede <hdegoede@redhat.com>
++ *
++ * based on the AHCI SATA platform driver by Jeff Garzik and Anton Vorontsov
++ * Based on code from Allwinner Technology Co., Ltd. <www.allwinnertech.com>,
++ * Daniel Wang <danielwang@allwinnertech.com>
++ *
++ * This program is free software; you can redistribute it and/or modify it
++ * under the terms and conditions of the GNU General Public License,
++ * version 2, as published by the Free Software Foundation.
++ *
++ * This program is distributed in the hope 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 <linux/clk.h>
++#include <linux/errno.h>
++#include <linux/kernel.h>
++#include <linux/module.h>
++#include <linux/of_device.h>
++#include <linux/platform_device.h>
++#include <linux/regulator/consumer.h>
++#include "ahci.h"
++
++#define AHCI_BISTAFR 0x00a0
++#define AHCI_BISTCR 0x00a4
++#define AHCI_BISTFCTR 0x00a8
++#define AHCI_BISTSR 0x00ac
++#define AHCI_BISTDECR 0x00b0
++#define AHCI_DIAGNR0 0x00b4
++#define AHCI_DIAGNR1 0x00b8
++#define AHCI_OOBR 0x00bc
++#define AHCI_PHYCS0R 0x00c0
++#define AHCI_PHYCS1R 0x00c4
++#define AHCI_PHYCS2R 0x00c8
++#define AHCI_TIMER1MS 0x00e0
++#define AHCI_GPARAM1R 0x00e8
++#define AHCI_GPARAM2R 0x00ec
++#define AHCI_PPARAMR 0x00f0
++#define AHCI_TESTR 0x00f4
++#define AHCI_VERSIONR 0x00f8
++#define AHCI_IDR 0x00fc
++#define AHCI_RWCR 0x00fc
++#define AHCI_P0DMACR 0x0170
++#define AHCI_P0PHYCR 0x0178
++#define AHCI_P0PHYSR 0x017c
++
++struct sunxi_ahci {
++      struct ahci_host_priv hpriv;
++      struct regulator *pwr;
++      struct clk *sata_clk;
++      struct clk *ahb_clk;
++};
++
++static void sunxi_clrbits(void __iomem *reg, u32 clr_val)
++{
++      u32 reg_val;
++
++      reg_val = readl(reg);
++      reg_val &= ~(clr_val);
++      writel(reg_val, reg);
++}
++
++static void sunxi_setbits(void __iomem *reg, u32 set_val)
++{
++      u32 reg_val;
++
++      reg_val = readl(reg);
++      reg_val |= set_val;
++      writel(reg_val, reg);
++}
++
++static void sunxi_clrsetbits(void __iomem *reg, u32 clr_val, u32 set_val)
++{
++      u32 reg_val;
++
++      reg_val = readl(reg);
++      reg_val &= ~(clr_val);
++      reg_val |= set_val;
++      writel(reg_val, reg);
++}
++
++static u32 sunxi_getbits(void __iomem *reg, u8 mask, u8 shift)
++{
++      return (readl(reg) >> shift) & mask;
++}
++
++static int sunxi_ahci_phy_init(struct device *dev, void __iomem *reg_base)
++{
++      u32 reg_val;
++      int timeout;
++
++      /* This magic is from the original code */
++      writel(0, reg_base + AHCI_RWCR);
++      mdelay(5);
++
++      sunxi_setbits(reg_base + AHCI_PHYCS1R, BIT(19));
++      sunxi_clrsetbits(reg_base + AHCI_PHYCS0R,
++                       (0x7 << 24),
++                       (0x5 << 24) | BIT(23) | BIT(18));
++      sunxi_clrsetbits(reg_base + AHCI_PHYCS1R,
++                       (0x3 << 16) | (0x1f << 8) | (0x3 << 6),
++                       (0x2 << 16) | (0x6 << 8) | (0x2 << 6));
++      sunxi_setbits(reg_base + AHCI_PHYCS1R, BIT(28) | BIT(15));
++      sunxi_clrbits(reg_base + AHCI_PHYCS1R, BIT(19));
++      sunxi_clrsetbits(reg_base + AHCI_PHYCS0R,
++                       (0x7 << 20), (0x3 << 20));
++      sunxi_clrsetbits(reg_base + AHCI_PHYCS2R,
++                       (0x1f << 5), (0x19 << 5));
++      mdelay(5);
++
++      sunxi_setbits(reg_base + AHCI_PHYCS0R, (0x1 << 19));
++
++      timeout = 0x100000;
++      do {
++              reg_val = sunxi_getbits(reg_base + AHCI_PHYCS0R, 0x7, 28);
++      } while (--timeout && (reg_val != 0x2));
++      if (!timeout) {
++              dev_err(dev, "PHY power up failed.\n");
++              return -EIO;
++      }
++
++      sunxi_setbits(reg_base + AHCI_PHYCS2R, (0x1 << 24));
++
++      timeout = 0x100000;
++      do {
++              reg_val = sunxi_getbits(reg_base + AHCI_PHYCS2R, 0x1, 24);
++      } while (--timeout && reg_val);
++      if (!timeout) {
++              dev_err(dev, "PHY calibration failed.\n");
++              return -EIO;
++      }
++      mdelay(15);
++
++      writel(0x7, reg_base + AHCI_RWCR);
++
++      return 0;
++}
++
++void sunxi_ahci_pre_start_engine(struct ata_port *ap)
++{
++      struct ahci_host_priv *hpriv = ap->host->private_data;
++
++      /* Setup DMA before DMA start */
++      sunxi_clrsetbits(hpriv->mmio + AHCI_P0DMACR, 0x0000ff00, 0x00004400);
++}
++
++static int sunxi_ahci_enable_clks(struct sunxi_ahci *ahci)
++{
++      int ret;
++
++      ret = clk_prepare_enable(ahci->sata_clk);
++      if (ret)
++              return ret;
++
++      ret = clk_prepare_enable(ahci->ahb_clk);
++      if (ret)
++              clk_disable_unprepare(ahci->sata_clk);
++
++      return ret;
++}
++
++static void sunxi_ahci_disable_clks(struct sunxi_ahci *ahci)
++{
++      clk_disable_unprepare(ahci->ahb_clk);
++      clk_disable_unprepare(ahci->sata_clk);
++}
++
++static void sunxi_ahci_host_stop(struct ata_host *host)
++{
++      struct ahci_host_priv *hpriv = host->private_data;
++      struct sunxi_ahci *ahci = hpriv->plat_data;
++
++      if (!IS_ERR(ahci->pwr))
++              regulator_disable(ahci->pwr);
++
++      sunxi_ahci_disable_clks(ahci);
++}
++
++static struct ata_port_operations sunxi_ahci_platform_ops = {
++      .inherits       = &ahci_ops,
++      .host_stop      = sunxi_ahci_host_stop,
++};
++
++static const struct ata_port_info sunxiahci_port_info = {
++      AHCI_HFLAGS(AHCI_HFLAG_32BIT_ONLY | AHCI_HFLAG_NO_MSI |
++                        AHCI_HFLAG_NO_PMP | AHCI_HFLAG_YES_NCQ),
++      .flags          = AHCI_FLAG_COMMON | ATA_FLAG_NCQ,
++      .pio_mask       = ATA_PIO4,
++      .udma_mask      = ATA_UDMA6,
++      .port_ops       = &sunxi_ahci_platform_ops,
++};
++
++static struct scsi_host_template sunxi_ahci_platform_sht = {
++      AHCI_SHT("sunxi_ahci"),
++};
++
++static int sunxi_ahci_probe(struct platform_device *pdev)
++{
++      struct device *dev = &pdev->dev;
++      const struct ata_port_info *ppi[] = { &sunxiahci_port_info, NULL };
++      struct sunxi_ahci *ahci;
++      struct ata_host *host;
++      int ret;
++
++      ahci = devm_kzalloc(&pdev->dev, sizeof(*ahci), GFP_KERNEL);
++      if (!ahci)
++              return -ENOMEM;
++
++      ahci->pwr = devm_regulator_get_optional(dev, "pwr");
++      if (IS_ERR(ahci->pwr) && PTR_ERR(ahci->pwr) == -EPROBE_DEFER)
++              return -EPROBE_DEFER;
++
++      host = ata_host_alloc_pinfo(dev, ppi, 1);
++      if (!host)
++              return -ENOMEM;
++
++      host->private_data = &ahci->hpriv;
++      host->flags |= ATA_HOST_PARALLEL_SCAN;
++
++      ahci->hpriv.flags = (unsigned long)ppi[0]->private_data;
++      ahci->hpriv.plat_data = ahci;
++      ahci->hpriv.pre_start_engine = sunxi_ahci_pre_start_engine;
++      ahci->hpriv.mmio = devm_ioremap_resource(dev,
++                            platform_get_resource(pdev, IORESOURCE_MEM, 0));
++      if (IS_ERR(ahci->hpriv.mmio))
++              return PTR_ERR(ahci->hpriv.mmio);
++
++      ahci->ahb_clk = devm_clk_get(&pdev->dev, "ahb_sata");
++      if (IS_ERR(ahci->ahb_clk))
++              return PTR_ERR(ahci->ahb_clk);
++
++      ahci->sata_clk = devm_clk_get(&pdev->dev, "pll6_sata");
++      if (IS_ERR(ahci->sata_clk))
++              return PTR_ERR(ahci->sata_clk);
++
++      ret = sunxi_ahci_enable_clks(ahci);
++      if (ret)
++              return ret;
++
++      if (!IS_ERR(ahci->pwr)) {
++              ret = regulator_enable(ahci->pwr);
++              if (ret) {
++                      sunxi_ahci_disable_clks(ahci);
++                      return ret;
++              }
++      }
++
++      ret = sunxi_ahci_phy_init(dev, ahci->hpriv.mmio);
++      if (ret) {
++              sunxi_ahci_host_stop(host);
++              return ret;
++      }
++
++      ahci_save_initial_config(dev, &ahci->hpriv, 0, 0);
++
++      ret = ahci_reset_controller(host);
++      if (ret) {
++              sunxi_ahci_host_stop(host);
++              return ret;
++      }
++
++      ahci_init_controller(host);
++      ahci_print_info(host, "sunxi");
++
++      ret = ata_host_activate(host, platform_get_irq(pdev, 0),
++                              ahci_interrupt, 0, &sunxi_ahci_platform_sht);
++      if (ret)
++              sunxi_ahci_host_stop(host);
++
++      return ret;
++}
++
++#ifdef CONFIG_PM_SLEEP
++static int sunxi_ahci_susp(struct device *dev)
++{
++      struct ata_host *host = dev_get_drvdata(dev);
++      struct ahci_host_priv *hpriv = host->private_data;
++      struct sunxi_ahci *ahci = hpriv->plat_data;
++      int ret;
++
++      /*
++       * AHCI spec rev1.1 section 8.3.3:
++       * Software must disable interrupts prior to requesting a
++       * transition of the HBA to D3 state.
++       */
++      sunxi_clrbits(hpriv->mmio + HOST_CTL, HOST_IRQ_EN);
++
++      ret = ata_host_suspend(host, PMSG_SUSPEND);
++      if (ret)
++              return ret;
++
++      sunxi_ahci_disable_clks(ahci);
++
++      return 0;
++}
++
++static int sunxi_ahci_resume(struct device *dev)
++{
++      struct ata_host *host = dev_get_drvdata(dev);
++      struct ahci_host_priv *hpriv = host->private_data;
++      struct sunxi_ahci *ahci = hpriv->plat_data;
++      int ret;
++
++      ret = sunxi_ahci_enable_clks(ahci);
++      if (ret)
++              return ret;
++
++      if (dev->power.power_state.event == PM_EVENT_SUSPEND) {
++              ret = ahci_reset_controller(host);
++              if (ret)
++                      return ret;
++
++              ahci_init_controller(host);
++      }
++
++      ata_host_resume(host);
++
++      return 0;
++}
++#endif
++
++static SIMPLE_DEV_PM_OPS(sunxi_ahci_pmo, sunxi_ahci_susp, sunxi_ahci_resume);
++
++static const struct of_device_id sunxi_ahci_of_match[] = {
++      { .compatible = "allwinner,sun4i-a10-ahci" },
++      { /* sentinel */ },
++};
++MODULE_DEVICE_TABLE(of, sunxi_ahci_of_match);
++
++static struct platform_driver sunxi_ahci_driver = {
++      .probe = sunxi_ahci_probe,
++      .remove = ata_platform_remove_one,
++      .driver = {
++              .name = "sunxi-ahci",
++              .owner = THIS_MODULE,
++              .of_match_table = sunxi_ahci_of_match,
++              .pm = &sunxi_ahci_pmo,
++      },
++};
++module_platform_driver(sunxi_ahci_driver);
++
++MODULE_DESCRIPTION("Allwinner sunxi AHCI SATA platform driver");
++MODULE_AUTHOR("Olliver Schinagl <oliver@schinagl.nl>");
++MODULE_LICENSE("GPL");
+-- 
+1.8.5.1
+
diff --git a/target/linux/sunxi/patches-3.13/162-1-dt-sun4i-add-ahci-nodes.patch b/target/linux/sunxi/patches-3.13/162-1-dt-sun4i-add-ahci-nodes.patch
new file mode 100644 (file)
index 0000000..b69c480
--- /dev/null
@@ -0,0 +1,99 @@
+From 23af610e09f78822ade4067a400ff9ceb5b020ea Mon Sep 17 00:00:00 2001
+From: Oliver Schinagl <oliver@schinagl.nl>
+Date: Tue, 3 Dec 2013 12:10:11 +0100
+Subject: [PATCH] ARM: sun4i: dts: Add ahci / sata support
+
+This patch adds sunxi sata support to A10 boards that have such a connector.
+Some boards also feature a regulator via a GPIO and support for this is also
+added.
+
+Signed-off-by: Olliver Schinagl <oliver@schinagl.nl>
+Signed-off-by: Hans de Goede <hdegoede@redhat.com>
+---
+ arch/arm/boot/dts/sun4i-a10-a1000.dts      |  4 ++++
+ arch/arm/boot/dts/sun4i-a10-cubieboard.dts | 27 +++++++++++++++++++++++++++
+ arch/arm/boot/dts/sun4i-a10.dtsi           |  9 +++++++++
+ 3 files changed, 40 insertions(+)
+
+diff --git a/arch/arm/boot/dts/sun4i-a10-a1000.dts b/arch/arm/boot/dts/sun4i-a10-a1000.dts
+index aef8207..fd6d512 100644
+--- a/arch/arm/boot/dts/sun4i-a10-a1000.dts
++++ b/arch/arm/boot/dts/sun4i-a10-a1000.dts
+@@ -48,6 +48,10 @@
+                       status = "okay";
+               };
++              sata: ahci@01c18000 {
++                      status = "okay";
++              };
++
+               pinctrl@01c20800 {
+                       mmc0_cd_pin_a1000: mmc0_cd_pin@0 {
+                               allwinner,pins = "PH1";
+diff --git a/arch/arm/boot/dts/sun4i-a10-cubieboard.dts b/arch/arm/boot/dts/sun4i-a10-cubieboard.dts
+index f50fb2b..53ac453 100644
+--- a/arch/arm/boot/dts/sun4i-a10-cubieboard.dts
++++ b/arch/arm/boot/dts/sun4i-a10-cubieboard.dts
+@@ -51,7 +51,19 @@
+                       status = "okay";
+               };
++              sata: ahci@01c18000 {
++                      pwr-supply = <&reg_ahci_5v>;
++                      status = "okay";
++              };
++
+               pinctrl@01c20800 {
++                      ahci_pwr_pin_cubieboard: ahci_pwr_pin@0 {
++                              allwinner,pins = "PB8";
++                              allwinner,function = "gpio_out";
++                              allwinner,drive = <0>;
++                              allwinner,pull = <0>;
++                      };
++
+                       mmc0_cd_pin_cubieboard: mmc0_cd_pin@0 {
+                               allwinner,pins = "PH1";
+                               allwinner,function = "gpio_in";
+@@ -102,4 +114,19 @@
+                       linux,default-trigger = "heartbeat";
+               };
+       };
++
++      regulators {
++              compatible = "simple-bus";
++              pinctrl-names = "default";
++
++              reg_ahci_5v: ahci-5v {
++                      compatible = "regulator-fixed";
++                      regulator-name = "ahci-5v";
++                      regulator-min-microvolt = <5000000>;
++                      regulator-max-microvolt = <5000000>;
++                      pinctrl-0 = <&ahci_pwr_pin_cubieboard>;
++                      gpio = <&pio 1 8 0>;
++                      enable-active-high;
++              };
++      };
+ };
+diff --git a/arch/arm/boot/dts/sun4i-a10.dtsi b/arch/arm/boot/dts/sun4i-a10.dtsi
+index 4736dd2..731b491 100644
+--- a/arch/arm/boot/dts/sun4i-a10.dtsi
++++ b/arch/arm/boot/dts/sun4i-a10.dtsi
+@@ -331,6 +331,15 @@
+                       status = "disabled";
+               };
++              sata: ahci@01c18000 {
++                      compatible = "allwinner,sun4i-a10-ahci";
++                      reg = <0x01c18000 0x1000>;
++                      interrupts = <56>;
++                      clocks = <&ahb_gates 25>, <&pll6 0>;
++                      clock-names = "ahb_sata", "pll6_sata";
++                      status = "disabled";
++              };
++
+               intc: interrupt-controller@01c20400 {
+                       compatible = "allwinner,sun4i-ic";
+                       reg = <0x01c20400 0x400>;
+-- 
+1.8.5.1
+
diff --git a/target/linux/sunxi/patches-3.13/162-2-dt-sun7i-add-ahci-nodes.patch b/target/linux/sunxi/patches-3.13/162-2-dt-sun7i-add-ahci-nodes.patch
new file mode 100644 (file)
index 0000000..5801f66
--- /dev/null
@@ -0,0 +1,178 @@
+From 4ce1f4c3ab04a697e9861b77582077b905b3f8a0 Mon Sep 17 00:00:00 2001
+From: Hans de Goede <hdegoede@redhat.com>
+Date: Fri, 3 Jan 2014 10:27:51 +0100
+Subject: [PATCH] ARM: sun7i: dts: Add ahci / sata support
+
+This patch adds sunxi sata support to A20 boards that have such a connector.
+Some boards also feature a regulator via a GPIO and support for this is also
+added.
+
+Signed-off-by: Olliver Schinagl <oliver@schinagl.nl>
+Signed-off-by: Hans de Goede <hdegoede@redhat.com>
+---
+ arch/arm/boot/dts/sun7i-a20-cubieboard2.dts     | 27 +++++++++++++++++++++++++
+ arch/arm/boot/dts/sun7i-a20-cubietruck.dts      | 27 +++++++++++++++++++++++++
+ arch/arm/boot/dts/sun7i-a20-olinuxino-micro.dts | 26 ++++++++++++++++++++++++
+ arch/arm/boot/dts/sun7i-a20.dtsi                |  9 +++++++++
+ 4 files changed, 89 insertions(+)
+
+diff --git a/arch/arm/boot/dts/sun7i-a20-cubieboard2.dts b/arch/arm/boot/dts/sun7i-a20-cubieboard2.dts
+index 48777cd..a26711c 100644
+--- a/arch/arm/boot/dts/sun7i-a20-cubieboard2.dts
++++ b/arch/arm/boot/dts/sun7i-a20-cubieboard2.dts
+@@ -28,7 +28,19 @@
+                       status = "okay";
+               };
++              sata: ahci@01c18000 {
++                      pwr-supply = <&reg_ahci_5v>;
++                      status = "okay";
++              };
++
+               pinctrl@01c20800 {
++                      ahci_pwr_pin_cubieboard2: ahci_pwr_pin@0 {
++                              allwinner,pins = "PB8";
++                              allwinner,function = "gpio_out";
++                              allwinner,drive = <0>;
++                              allwinner,pull = <0>;
++                      };
++
+                       mmc0_cd_pin_cubieboard2: mmc0_cd_pin@0 {
+                               allwinner,pins = "PH1";
+                               allwinner,function = "gpio_in";
+@@ -86,4 +98,19 @@
+                       gpios = <&pio 7 20 0>;
+               };
+       };
++
++      regulators {
++              compatible = "simple-bus";
++              pinctrl-names = "default";
++
++              reg_ahci_5v: ahci-5v {
++                      compatible = "regulator-fixed";
++                      regulator-name = "ahci-5v";
++                      regulator-min-microvolt = <5000000>;
++                      regulator-max-microvolt = <5000000>;
++                      pinctrl-0 = <&ahci_pwr_pin_cubieboard2>;
++                      gpio = <&pio 1 8 0>;
++                      enable-active-high;
++              };
++      };
+ };
+diff --git a/arch/arm/boot/dts/sun7i-a20-cubietruck.dts b/arch/arm/boot/dts/sun7i-a20-cubietruck.dts
+index 2684f27..a5f3418 100644
+--- a/arch/arm/boot/dts/sun7i-a20-cubietruck.dts
++++ b/arch/arm/boot/dts/sun7i-a20-cubietruck.dts
+@@ -28,6 +28,11 @@
+                       status = "okay";
+               };
++              sata: ahci@01c18000 {
++                      pwr-supply = <&reg_ahci_5v>;
++                      status = "okay";
++              };
++
+               pinctrl@01c20800 {
+                       mmc0_cd_pin_cubietruck: mmc0_cd_pin@0 {
+                               allwinner,pins = "PH1";
+@@ -36,6 +41,13 @@
+                               allwinner,pull = <0>;
+                       };
++                      ahci_pwr_pin_cubietruck: ahci_pwr_pin@0 {
++                              allwinner,pins = "PH12";
++                              allwinner,function = "gpio_out";
++                              allwinner,drive = <0>;
++                              allwinner,pull = <0>;
++                      };
++
+                       led_pins_cubietruck: led_pins@0 {
+                               allwinner,pins = "PH7", "PH11", "PH20", "PH21";
+                               allwinner,function = "gpio_out";
+@@ -84,4 +96,19 @@
+                       gpios = <&pio 7 7 0>;
+               };
+       };
++
++      regulators {
++              compatible = "simple-bus";
++              pinctrl-names = "default";
++
++              reg_ahci_5v: ahci-5v {
++                      compatible = "regulator-fixed";
++                      regulator-name = "ahci-5v";
++                      regulator-min-microvolt = <5000000>;
++                      regulator-max-microvolt = <5000000>;
++                      pinctrl-0 = <&ahci_pwr_pin_cubietruck>;
++                      gpio = <&pio 7 12 0>;
++                      enable-active-high;
++              };
++      };
+ };
+diff --git a/arch/arm/boot/dts/sun7i-a20-olinuxino-micro.dts b/arch/arm/boot/dts/sun7i-a20-olinuxino-micro.dts
+index bf6f6c8..20b1000 100644
+--- a/arch/arm/boot/dts/sun7i-a20-olinuxino-micro.dts
++++ b/arch/arm/boot/dts/sun7i-a20-olinuxino-micro.dts
+@@ -37,7 +37,19 @@
+                       status = "okay";
+               };
++              sata: ahci@01c18000 {
++                      pwr-supply = <&reg_ahci_5v>;
++                      status = "okay";
++              };
++
+               pinctrl@01c20800 {
++                      ahci_pwr_pin_olinuxinom: ahci_pwr_pin@0 {
++                              allwinner,pins = "PB8";
++                              allwinner,function = "gpio_out";
++                              allwinner,drive = <0>;
++                              allwinner,pull = <0>;
++                      };
++
+                       mmc0_cd_pin_olinuxinom: mmc0_cd_pin@0 {
+                               allwinner,pins = "PH1";
+                               allwinner,function = "gpio_in";
+@@ -116,4 +128,18 @@
+                       default-state = "on";
+               };
+       };
++
++      regulators {
++              compatible = "simple-bus";
++
++              reg_ahci_5v: ahci-5v {
++                      compatible = "regulator-fixed";
++                      regulator-name = "ahci-5v";
++                      regulator-min-microvolt = <5000000>;
++                      regulator-max-microvolt = <5000000>;
++                      pinctrl-0 = <&ahci_pwr_pin_olinuxinom>;
++                      gpio = <&pio 1 8 0>;
++                      enable-active-high;
++              };
++      };
+ };
+diff --git a/arch/arm/boot/dts/sun7i-a20.dtsi b/arch/arm/boot/dts/sun7i-a20.dtsi
+index c9c123a..3242a29 100644
+--- a/arch/arm/boot/dts/sun7i-a20.dtsi
++++ b/arch/arm/boot/dts/sun7i-a20.dtsi
+@@ -448,6 +448,15 @@
+                       };
+               };
++              sata: ahci@01c18000 {
++                      compatible = "allwinner,sun4i-a10-ahci";
++                      reg = <0x01c18000 0x1000>;
++                      interrupts = <0 56 1>;
++                      clocks = <&ahb_gates 25>, <&pll6 0>;
++                      clock-names = "ahb_sata", "pll6_sata";
++                      status = "disabled";
++              };
++
+               timer@01c20c00 {
+                       compatible = "allwinner,sun4i-timer";
+                       reg = <0x01c20c00 0x90>;
+-- 
+1.8.5.1
+
diff --git a/target/linux/sunxi/patches-3.13/170-clk-sunxi-add-support-for-usbclocks.patch b/target/linux/sunxi/patches-3.13/170-clk-sunxi-add-support-for-usbclocks.patch
new file mode 100644 (file)
index 0000000..54aa9f2
--- /dev/null
@@ -0,0 +1,36 @@
+From 109e7dc17a77f84d56e76dea873363a8262bc806 Mon Sep 17 00:00:00 2001
+From: arokux <arokux@gmail.com>
+Date: Thu, 19 Sep 2013 21:59:32 +0200
+Subject: [PATCH] clk: sunxi: Add support for USB clocks
+
+Signed-off-by: Hans de Goede <hdegoede@redhat.com>
+---
+ drivers/clk/sunxi/clk-sunxi.c | 5 +++++
+ 1 file changed, 5 insertions(+)
+
+diff --git a/drivers/clk/sunxi/clk-sunxi.c b/drivers/clk/sunxi/clk-sunxi.c
+index 6d3286a..573ef28 100644
+--- a/drivers/clk/sunxi/clk-sunxi.c
++++ b/drivers/clk/sunxi/clk-sunxi.c
+@@ -702,6 +702,10 @@ struct gates_data {
+       .mask = {0x7F77FFF, 0x14FB3F},
+ };
++static const struct gates_data sun47i_usb_gates_data __initconst = {
++      .mask = {0x1C0},
++};
++
+ static const struct gates_data sun5i_a10s_ahb_gates_data __initconst = {
+       .mask = {0x147667e7, 0x185915},
+ };
+@@ -1017,6 +1021,7 @@ static void __init sunxi_divs_clk_setup(struct device_node *node,
+ static const struct of_device_id clk_gates_match[] __initconst = {
+       {.compatible = "allwinner,sun4i-axi-gates-clk", .data = &sun4i_axi_gates_data,},
+       {.compatible = "allwinner,sun4i-ahb-gates-clk", .data = &sun4i_ahb_gates_data,},
++      {.compatible = "allwinner,sun47i-usb-gates-clk", .data = &sun47i_usb_gates_data,},
+       {.compatible = "allwinner,sun5i-a10s-ahb-gates-clk", .data = &sun5i_a10s_ahb_gates_data,},
+       {.compatible = "allwinner,sun5i-a13-ahb-gates-clk", .data = &sun5i_a13_ahb_gates_data,},
+       {.compatible = "allwinner,sun6i-a31-ahb1-gates-clk", .data = &sun6i_a31_ahb1_gates_data,},
+-- 
+1.8.5.1
+
diff --git a/target/linux/sunxi/patches-3.13/171-clk-sunxi-add-support-for-sun5i-usbclocks.patch b/target/linux/sunxi/patches-3.13/171-clk-sunxi-add-support-for-sun5i-usbclocks.patch
new file mode 100644 (file)
index 0000000..d8456e4
--- /dev/null
@@ -0,0 +1,36 @@
+From 6b5cb5cada555c90562aed82e8891439a35009ab Mon Sep 17 00:00:00 2001
+From: arokux <arokux@gmail.com>
+Date: Sun, 6 Oct 2013 14:04:50 +0200
+Subject: [PATCH] clk: sun5i: Add support for USB clocks
+
+Signed-off-by: Hans de Goede <hdegoede@redhat.com>
+---
+ drivers/clk/sunxi/clk-sunxi.c | 5 +++++
+ 1 file changed, 5 insertions(+)
+
+diff --git a/drivers/clk/sunxi/clk-sunxi.c b/drivers/clk/sunxi/clk-sunxi.c
+index 573ef28..8a07a68 100644
+--- a/drivers/clk/sunxi/clk-sunxi.c
++++ b/drivers/clk/sunxi/clk-sunxi.c
+@@ -706,6 +706,10 @@ struct gates_data {
+       .mask = {0x1C0},
+ };
++static const struct gates_data sun5i_usb_gates_data __initconst = {
++       .mask = {0x140},
++};
++
+ static const struct gates_data sun5i_a10s_ahb_gates_data __initconst = {
+       .mask = {0x147667e7, 0x185915},
+ };
+@@ -1024,6 +1028,7 @@ static void __init sunxi_divs_clk_setup(struct device_node *node,
+       {.compatible = "allwinner,sun47i-usb-gates-clk", .data = &sun47i_usb_gates_data,},
+       {.compatible = "allwinner,sun5i-a10s-ahb-gates-clk", .data = &sun5i_a10s_ahb_gates_data,},
+       {.compatible = "allwinner,sun5i-a13-ahb-gates-clk", .data = &sun5i_a13_ahb_gates_data,},
++      {.compatible = "allwinner,sun5i-usb-gates-clk", .data = &sun5i_usb_gates_data,},
+       {.compatible = "allwinner,sun6i-a31-ahb1-gates-clk", .data = &sun6i_a31_ahb1_gates_data,},
+       {.compatible = "allwinner,sun7i-a20-ahb-gates-clk", .data = &sun7i_a20_ahb_gates_data,},
+       {.compatible = "allwinner,sun4i-apb0-gates-clk", .data = &sun4i_apb0_gates_data,},
+-- 
+1.8.5.1
+
diff --git a/target/linux/sunxi/patches-3.13/172-usb-add-ehci-driver.patch b/target/linux/sunxi/patches-3.13/172-usb-add-ehci-driver.patch
new file mode 100644 (file)
index 0000000..724c73a
--- /dev/null
@@ -0,0 +1,503 @@
+From 825ce97e1faa39bfd30c3dca95fba5eb021cb534 Mon Sep 17 00:00:00 2001
+From: arokux <arokux@gmail.com>
+Date: Wed, 18 Sep 2013 21:45:03 +0200
+Subject: [PATCH] ARM: sunxi: usb: Add Allwinner sunXi EHCI driver
+
+Signed-off-by: Hans de Goede <hdegoede@redhat.com>
+
+Conflicts:
+       drivers/usb/host/Makefile
+---
+ drivers/usb/host/Kconfig      |   9 +
+ drivers/usb/host/Makefile     |   1 +
+ drivers/usb/host/ehci-sunxi.c | 446 ++++++++++++++++++++++++++++++++++++++++++
+ 3 files changed, 456 insertions(+)
+ create mode 100644 drivers/usb/host/ehci-sunxi.c
+
+diff --git a/drivers/usb/host/Kconfig b/drivers/usb/host/Kconfig
+index a9707da..db94dba 100644
+--- a/drivers/usb/host/Kconfig
++++ b/drivers/usb/host/Kconfig
+@@ -273,6 +273,15 @@ config USB_OCTEON_EHCI
+         USB 2.0 device support.  All CN6XXX based chips with USB are
+         supported.
++config USB_SUNXI_EHCI
++      tristate "Allwinner sunXi EHCI support"
++      depends on ARCH_SUNXI
++      default n
++      help
++        Enable support for the Allwinner sunXi on-chip EHCI
++        controller. It is needed for high-speed (480Mbit/sec)
++        USB 2.0 device support.
++
+ endif # USB_EHCI_HCD
+ config USB_OXU210HP_HCD
+diff --git a/drivers/usb/host/Makefile b/drivers/usb/host/Makefile
+index 01e879e..d96053d 100644
+--- a/drivers/usb/host/Makefile
++++ b/drivers/usb/host/Makefile
+@@ -39,6 +39,7 @@ obj-$(CONFIG_USB_EHCI_HCD_AT91) += ehci-atmel.o
+ obj-$(CONFIG_USB_EHCI_MSM)    += ehci-msm.o
+ obj-$(CONFIG_USB_EHCI_TEGRA)  += ehci-tegra.o
+ obj-$(CONFIG_USB_W90X900_EHCI)        += ehci-w90x900.o
++obj-$(CONFIG_USB_SUNXI_EHCI)  += ehci-sunxi.o
+ obj-$(CONFIG_USB_OXU210HP_HCD)        += oxu210hp-hcd.o
+ obj-$(CONFIG_USB_ISP116X_HCD) += isp116x-hcd.o
+diff --git a/drivers/usb/host/ehci-sunxi.c b/drivers/usb/host/ehci-sunxi.c
+new file mode 100644
+index 0000000..e7e15cc
+--- /dev/null
++++ b/drivers/usb/host/ehci-sunxi.c
+@@ -0,0 +1,446 @@
++/*
++ * Copyright (C) 2013 Roman Byshko
++ *
++ * Roman Byshko <rbyshko@gmail.com>
++ *
++ * Based on code from
++ * Allwinner Technology Co., Ltd. <www.allwinnertech.com>
++ *
++ * 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 <linux/bitops.h>
++#include <linux/clk.h>
++#include <linux/dma-mapping.h>
++#include <linux/io.h>
++#include <linux/irq.h>
++#include <linux/module.h>
++#include <linux/of.h>
++#include <linux/platform_device.h>
++#include <linux/regulator/consumer.h>
++#include <linux/reset.h>
++#include <linux/usb.h>
++#include <linux/usb/hcd.h>
++
++#include "ehci.h"
++
++#define DRV_DESC      "Allwinner sunXi EHCI driver"
++#define DRV_NAME      "sunxi-ehci"
++
++#define SUNXI_USB_PASSBY_EN   1
++
++#define SUNXI_EHCI_AHB_ICHR8_EN               BIT(10)
++#define SUNXI_EHCI_AHB_INCR4_BURST_EN BIT(9)
++#define SUNXI_EHCI_AHB_INCRX_ALIGN_EN BIT(8)
++#define SUNXI_EHCI_ULPI_BYPASS_EN     BIT(0)
++
++struct sunxi_ehci_hcd {
++      struct clk *phy_clk;
++      struct clk *ahb_ehci_clk;
++      struct reset_control *reset;
++      struct regulator *vbus_reg;
++      void __iomem *csr;
++      void __iomem *pmuirq;
++      int irq;
++      int id;
++};
++
++
++static void usb_phy_write(struct sunxi_ehci_hcd *sunxi_ehci,u32 addr, u32 data, u32 len)
++{
++      u32 j = 0;
++      u32 temp = 0;
++      u32 usbc_bit = 0;
++      void __iomem *dest = sunxi_ehci->csr;
++
++      usbc_bit = BIT(sunxi_ehci->id << 1);
++
++      for (j = 0; j < len; j++) {
++              temp = readl(dest);
++
++              /* clear the address portion */
++              temp &= ~(0xff << 8);
++
++              /* set the address */
++              temp |= ((addr + j) << 8);
++              writel(temp, dest);
++
++              /* set the data bit and clear usbc bit*/
++              temp = readb(dest);
++              if (data & 0x1)
++                      temp |= BIT(7);
++              else
++                      temp &= ~BIT(7);
++              temp &= ~usbc_bit;
++              writeb(temp, dest);
++
++              /* flip usbc_bit */
++              __set_bit(usbc_bit, dest);
++              __clear_bit(usbc_bit, dest);
++
++              data >>= 1;
++      }
++}
++
++/* FIXME: should this function be protected by a lock?
++ * ehci1 and ehci0 could call it concurrently with same csr.
++ */
++static void sunxi_usb_phy_init(struct sunxi_ehci_hcd *sunxi_ehci)
++{
++      /* The following comments are machine
++       * translated from Chinese, you have been warned!
++       */
++
++      /* adjust PHY's magnitude and rate */
++      usb_phy_write(sunxi_ehci, 0x20, 0x14, 5);
++
++      /* threshold adjustment disconnect */
++      usb_phy_write(sunxi_ehci, 0x2a, 3, 2);
++
++      return;
++}
++
++static void sunxi_usb_passby(struct sunxi_ehci_hcd *sunxi_ehci, int enable)
++{
++      unsigned long reg_value = 0;
++      unsigned long bits = 0;
++      static DEFINE_SPINLOCK(lock);
++      unsigned long flags = 0;
++      void __iomem *addr = sunxi_ehci->pmuirq;
++
++      bits = SUNXI_EHCI_AHB_ICHR8_EN |
++              SUNXI_EHCI_AHB_INCR4_BURST_EN |
++              SUNXI_EHCI_AHB_INCRX_ALIGN_EN |
++              SUNXI_EHCI_ULPI_BYPASS_EN;
++
++      spin_lock_irqsave(&lock, flags);
++
++      reg_value = readl(addr);
++
++      if (enable)
++              reg_value |= bits;
++      else
++              reg_value &= ~bits;
++
++      writel(reg_value, addr);
++
++      spin_unlock_irqrestore(&lock, flags);
++
++      return;
++}
++
++static void sunxi_ehci_disable(struct sunxi_ehci_hcd *sunxi_ehci)
++{
++      regulator_disable(sunxi_ehci->vbus_reg);
++
++      sunxi_usb_passby(sunxi_ehci, !SUNXI_USB_PASSBY_EN);
++
++      clk_disable_unprepare(sunxi_ehci->ahb_ehci_clk);
++      clk_disable_unprepare(sunxi_ehci->phy_clk);
++
++      reset_control_assert(sunxi_ehci->reset);
++}
++
++static int sunxi_ehci_enable(struct sunxi_ehci_hcd *sunxi_ehci)
++{
++      int ret;
++
++      ret = clk_prepare_enable(sunxi_ehci->phy_clk);
++      if (ret)
++              return ret;
++
++      ret = reset_control_deassert(sunxi_ehci->reset);
++      if (ret)
++              goto fail1;
++
++      ret = clk_prepare_enable(sunxi_ehci->ahb_ehci_clk);
++      if (ret)
++              goto fail2;
++
++      sunxi_usb_phy_init(sunxi_ehci);
++
++      sunxi_usb_passby(sunxi_ehci, SUNXI_USB_PASSBY_EN);
++
++      ret = regulator_enable(sunxi_ehci->vbus_reg);
++      if (ret)
++              goto fail3;
++
++      return 0;
++
++fail3:
++      clk_disable_unprepare(sunxi_ehci->ahb_ehci_clk);
++fail2:
++      reset_control_assert(sunxi_ehci->reset);
++fail1:
++      clk_disable_unprepare(sunxi_ehci->phy_clk);
++
++      return ret;
++}
++
++#ifdef CONFIG_PM
++static int sunxi_ehci_suspend(struct device *dev)
++{
++      struct sunxi_ehci_hcd *sunxi_ehci = NULL;
++      struct usb_hcd *hcd = dev_get_drvdata(dev);
++      int ret;
++
++      bool do_wakeup = device_may_wakeup(dev);
++
++      ret = ehci_suspend(hcd, do_wakeup);
++
++      sunxi_ehci = (struct sunxi_ehci_hcd *)hcd_to_ehci(hcd)->priv;
++
++      sunxi_ehci_disable(sunxi_ehci);
++
++      return ret;
++}
++
++static int sunxi_ehci_resume(struct device *dev)
++{
++      struct sunxi_ehci_hcd *sunxi_ehci = NULL;
++      struct usb_hcd *hcd = dev_get_drvdata(dev);
++      int ret;
++
++      sunxi_ehci = (struct sunxi_ehci_hcd *)hcd_to_ehci(hcd)->priv;
++
++      ret = sunxi_ehci_enable(sunxi_ehci);
++      if (ret)
++              return ret;
++
++      return ehci_resume(hcd, false);
++}
++
++
++static const struct dev_pm_ops sunxi_ehci_pmops = {
++      .suspend        = sunxi_ehci_suspend,
++      .resume         = sunxi_ehci_resume,
++};
++
++#define SUNXI_EHCI_PMOPS (&sunxi_ehci_pmops)
++#else /* !CONFIG_PM */
++#define SUNXI_EHCI_PMOPS NULL
++#endif /* CONFIG_PM */
++
++static const struct ehci_driver_overrides sunxi_overrides __initconst = {
++      .reset =        NULL,
++      .extra_priv_size        = sizeof(struct sunxi_ehci_hcd),
++};
++
++/* FIXME: Should there be two instances of hc_driver,
++ * or one is enough to handle two EHCI controllers? */
++static struct hc_driver __read_mostly sunxi_ehci_hc_driver;
++
++static int sunxi_ehci_init(struct platform_device *pdev, struct usb_hcd *hcd,
++                         struct sunxi_ehci_hcd *sunxi_ehci)
++{
++      void __iomem *ehci_regs = NULL;
++      struct resource *res = NULL;
++
++      sunxi_ehci->vbus_reg = devm_regulator_get(&pdev->dev, "vbus");
++      if (IS_ERR(sunxi_ehci->vbus_reg)) {
++              if (PTR_ERR(sunxi_ehci->vbus_reg) == -EPROBE_DEFER)
++                      return -EPROBE_DEFER;
++
++              dev_info(&pdev->dev, "no USB VBUS power supply found\n");
++      }
++
++      sunxi_ehci->id = of_alias_get_id(pdev->dev.of_node, "ehci");
++      if (sunxi_ehci->id < 0)
++              return sunxi_ehci->id;
++
++      /* FIXME: should res be freed on some failure? */
++      res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
++      if (!res) {
++              dev_err(&pdev->dev, "failed to get I/O memory\n");
++              return -ENXIO;
++      }
++      ehci_regs = devm_ioremap_resource(&pdev->dev, res);
++      if (IS_ERR(ehci_regs))
++              return PTR_ERR(ehci_regs);
++
++      hcd->rsrc_start = res->start;
++      hcd->rsrc_len = resource_size(res);
++      hcd->regs = ehci_regs;
++      hcd_to_ehci(hcd)->caps = ehci_regs;
++
++      res = platform_get_resource(pdev, IORESOURCE_MEM, 1);
++      if (!res) {
++              dev_err(&pdev->dev, "failed to get I/O memory\n");
++              return -ENXIO;
++      }
++      sunxi_ehci->pmuirq = devm_ioremap_resource(&pdev->dev, res);
++      if (IS_ERR(sunxi_ehci->pmuirq))
++              return PTR_ERR(sunxi_ehci->pmuirq);
++
++      res = platform_get_resource(pdev, IORESOURCE_MEM, 2);
++      if (!res) {
++              dev_err(&pdev->dev, "failed to get I/O memory\n");
++              return -ENXIO;
++      }
++
++      /* FIXME: this one byte needs to be shared between both EHCIs,
++       * that is why ioremap instead of devm_ioremap_resource,
++       * memory is not unmaped back for now.
++       */
++      sunxi_ehci->csr = ioremap(res->start, resource_size(res));
++      if (IS_ERR(sunxi_ehci->csr)) {
++              dev_err(&pdev->dev, "failed to remap memory\n");
++              return PTR_ERR(sunxi_ehci->csr);
++      }
++
++      sunxi_ehci->irq = platform_get_irq(pdev, 0);
++      if (!sunxi_ehci->irq) {
++              dev_err(&pdev->dev, "failed to get IRQ\n");
++              return -ENODEV;
++      }
++
++      sunxi_ehci->phy_clk = devm_clk_get(&pdev->dev, "usb_phy");
++      if (IS_ERR(sunxi_ehci->phy_clk)) {
++              dev_err(&pdev->dev, "failed to get usb_phy clock\n");
++              return PTR_ERR(sunxi_ehci->phy_clk);
++      }
++      sunxi_ehci->ahb_ehci_clk = devm_clk_get(&pdev->dev, "ahb_ehci");
++      if (IS_ERR(sunxi_ehci->ahb_ehci_clk)) {
++              dev_err(&pdev->dev, "failed to get ahb_ehci clock\n");
++              return PTR_ERR(sunxi_ehci->ahb_ehci_clk);
++      }
++
++      sunxi_ehci->reset = reset_control_get(&pdev->dev, "ehci_reset");
++      if (IS_ERR(sunxi_ehci->reset))
++      {
++              dev_err(&pdev->dev, "failed to get ehci_reset reset line\n");
++              return PTR_ERR(sunxi_ehci->reset);
++      }
++
++      return 0;
++}
++
++static int sunxi_ehci_probe(struct platform_device *pdev)
++{
++      struct sunxi_ehci_hcd *sunxi_ehci = NULL;
++      struct usb_hcd *hcd = NULL;
++      int ret;
++
++      if (pdev->num_resources != 4) {
++              dev_err(&pdev->dev, "invalid number of resources: %i\n",
++                     pdev->num_resources);
++              return -ENODEV;
++      }
++
++      if (pdev->resource[0].flags != IORESOURCE_MEM
++                      || pdev->resource[1].flags != IORESOURCE_MEM
++                      || pdev->resource[2].flags != IORESOURCE_MEM
++                      || pdev->resource[3].flags != IORESOURCE_IRQ) {
++              dev_err(&pdev->dev, "invalid resource type\n");
++              return -ENODEV;
++      }
++
++      if (!pdev->dev.dma_mask)
++              pdev->dev.dma_mask = &pdev->dev.coherent_dma_mask;
++      if (!pdev->dev.coherent_dma_mask)
++              pdev->dev.coherent_dma_mask = DMA_BIT_MASK(32);
++
++      hcd = usb_create_hcd(&sunxi_ehci_hc_driver, &pdev->dev,
++                           dev_name(&pdev->dev));
++      if (!hcd) {
++              dev_err(&pdev->dev, "unable to create HCD\n");
++              return -ENOMEM;
++      }
++
++      platform_set_drvdata(pdev, hcd);
++
++      sunxi_ehci = (struct sunxi_ehci_hcd *)hcd_to_ehci(hcd)->priv;
++      ret = sunxi_ehci_init(pdev, hcd, sunxi_ehci);
++      if (ret)
++              goto fail1;
++
++      ret = sunxi_ehci_enable(sunxi_ehci);
++      if (ret)
++              goto fail1;
++
++      ret = usb_add_hcd(hcd, sunxi_ehci->irq, IRQF_SHARED | IRQF_DISABLED);
++      if (ret) {
++              dev_err(&pdev->dev, "failed to add USB HCD\n");
++              goto fail2;
++      }
++
++      return 0;
++
++fail2:
++      sunxi_ehci_disable(sunxi_ehci);
++
++fail1:
++      usb_put_hcd(hcd);
++      return ret;
++}
++
++static int sunxi_ehci_remove(struct platform_device *pdev)
++{
++      struct usb_hcd *hcd = platform_get_drvdata(pdev);
++      struct sunxi_ehci_hcd *sunxi_ehci = NULL;
++
++      sunxi_ehci = (struct sunxi_ehci_hcd *)hcd_to_ehci(hcd)->priv;
++
++      usb_remove_hcd(hcd);
++
++      sunxi_ehci_disable(sunxi_ehci);
++
++      usb_put_hcd(hcd);
++
++      return 0;
++}
++
++static void sunxi_ehci_shutdown(struct platform_device *pdev)
++{
++      struct usb_hcd *hcd = platform_get_drvdata(pdev);
++      struct sunxi_ehci_hcd *sunxi_ehci = NULL;
++
++      sunxi_ehci = (struct sunxi_ehci_hcd *)hcd_to_ehci(hcd)->priv;
++
++      usb_hcd_platform_shutdown(pdev);
++
++      sunxi_ehci_disable(sunxi_ehci);
++}
++
++static const struct of_device_id ehci_of_match[] = {
++      {.compatible = "allwinner,sunxi-ehci"},
++      {},
++};
++
++static struct platform_driver ehci_sunxi_driver = {
++      .driver = {
++              .of_match_table = ehci_of_match,
++              .name = DRV_NAME,
++              .pm = SUNXI_EHCI_PMOPS,
++      },
++      .probe = sunxi_ehci_probe,
++      .remove = sunxi_ehci_remove,
++      .shutdown = sunxi_ehci_shutdown,
++};
++
++static int __init sunxi_ehci_init_module(void)
++{
++      if (usb_disabled())
++              return -ENODEV;
++
++      pr_info(DRV_NAME ": " DRV_DESC "\n");
++
++      ehci_init_driver(&sunxi_ehci_hc_driver, &sunxi_overrides);
++
++      return platform_driver_register(&ehci_sunxi_driver);
++}
++module_init(sunxi_ehci_init_module);
++
++static void __exit sunxi_ehci_exit_module(void)
++{
++      platform_driver_unregister(&ehci_sunxi_driver);
++}
++module_exit(sunxi_ehci_exit_module);
++
++MODULE_DESCRIPTION(DRIVER_DESC);
++MODULE_LICENSE("GPL");
++MODULE_ALIAS("platform:" DRV_NAME);
++MODULE_DEVICE_TABLE(of, ehci_of_match);
++MODULE_AUTHOR("Roman Byshko <rbyshko@gmail.com>");
+-- 
+1.8.5.1
+
diff --git a/target/linux/sunxi/patches-3.13/173-1-dt-sun4i-add-usbclock-nodes.patch b/target/linux/sunxi/patches-3.13/173-1-dt-sun4i-add-usbclock-nodes.patch
new file mode 100644 (file)
index 0000000..1d702d8
--- /dev/null
@@ -0,0 +1,32 @@
+From 04f41bafdff26bd895f2a1f894fd427779d7ed51 Mon Sep 17 00:00:00 2001
+From: arokux <arokux@gmail.com>
+Date: Thu, 19 Sep 2013 21:58:47 +0200
+Subject: [PATCH] ARM: sun4i: dt: Add bindings for USB clocks
+
+Signed-off-by: Hans de Goede <hdegoede@redhat.com>
+---
+ arch/arm/boot/dts/sun4i-a10.dtsi | 8 ++++++++
+ 1 file changed, 8 insertions(+)
+
+diff --git a/arch/arm/boot/dts/sun4i-a10.dtsi b/arch/arm/boot/dts/sun4i-a10.dtsi
+index 731b491..c9913c0 100644
+--- a/arch/arm/boot/dts/sun4i-a10.dtsi
++++ b/arch/arm/boot/dts/sun4i-a10.dtsi
+@@ -93,6 +93,14 @@
+                       clock-output-names = "pll6_sata", "pll6_other", "pll6";
+               };
++              usb:usb@0x01c200cc {
++                      #clock-cells = <1>;
++                      compatible = "allwinner,sun47i-usb-gates-clk";
++                      reg = <0x01c200cc 0x4>;
++                      clocks = <&pll6 1>;
++                      clock-output-names = "usb_ohci0", "usb_ohci1", "usb_phy";
++              };
++
+               /* dummy is 200M */
+               cpu: cpu@01c20054 {
+                       #clock-cells = <0>;
+-- 
+1.8.5.1
+
diff --git a/target/linux/sunxi/patches-3.13/173-2-dt-sun4i-add-ehci-bindings.patch b/target/linux/sunxi/patches-3.13/173-2-dt-sun4i-add-ehci-bindings.patch
new file mode 100644 (file)
index 0000000..b00e6d9
--- /dev/null
@@ -0,0 +1,63 @@
+From ec53e86224acaa3891148fa298bb1504f3579d6b Mon Sep 17 00:00:00 2001
+From: arokux <arokux@gmail.com>
+Date: Wed, 18 Sep 2013 00:30:04 +0200
+Subject: [PATCH] ARM: sun4i: dt: Add USB EHCI bindings
+
+Signed-off-by: Hans de Goede <hdegoede@redhat.com>
+
+Conflicts:
+       arch/arm/boot/dts/sun4i-a10.dtsi
+---
+ arch/arm/boot/dts/sun4i-a10.dtsi | 30 ++++++++++++++++++++++++++++++
+ 1 file changed, 30 insertions(+)
+
+diff --git a/arch/arm/boot/dts/sun4i-a10.dtsi b/arch/arm/boot/dts/sun4i-a10.dtsi
+index c9913c0..64eda82 100644
+--- a/arch/arm/boot/dts/sun4i-a10.dtsi
++++ b/arch/arm/boot/dts/sun4i-a10.dtsi
+@@ -17,6 +17,8 @@
+       aliases {
+               ethernet0 = &emac;
++              ehci1 = &ehci0;
++              ehci2 = &ehci1;
+       };
+       cpus {
+@@ -556,5 +558,33 @@
+                       clock-frequency = <100000>;
+                       status = "disabled";
+               };
++
++              usb_rst: reset@0x01c200cc {
++                      #reset-cells = <1>;
++                      compatible = "allwinner,sun4i-clock-reset";
++                      reg = <0x01c200cc 0x4>;
++              };
++
++              ehci0: ehci0@0x01c14000 {
++                      compatible = "allwinner,sunxi-ehci";
++                      reg = <0x01c14000 0x400 0x01c14800 0x4 0x01c13404 0x4>;
++                      interrupts = <39>;
++                      resets = <&usb_rst 1>;
++                      reset-names = "ehci_reset";
++                      clocks = <&usb 8>, <&ahb_gates 1>;
++                      clock-names = "usb_phy", "ahb_ehci";
++                      status = "disabled";
++              };
++
++              ehci1: ehci1@0x01c1c000 {
++                      compatible = "allwinner,sunxi-ehci";
++                      reg = <0x01c1c000 0x400 0x01c1c800 0x4 0x01c13404 0x4>;
++                      interrupts = <40>;
++                      resets = <&usb_rst 2>;
++                      reset-names = "ehci_reset";
++                      clocks = <&usb 8>, <&ahb_gates 3>;
++                      clock-names = "usb_phy", "ahb_ehci";
++                      status = "disabled";
++              };
+       };
+ };
+-- 
+1.8.5.1
+
diff --git a/target/linux/sunxi/patches-3.13/173-3-dt-sun4i-add-ehci-cubieboard.patch b/target/linux/sunxi/patches-3.13/173-3-dt-sun4i-add-ehci-cubieboard.patch
new file mode 100644 (file)
index 0000000..a71e6b4
--- /dev/null
@@ -0,0 +1,86 @@
+From 875bbd46c296e4b9ed130848bc64be5cf39669c8 Mon Sep 17 00:00:00 2001
+From: arokux <arokux@gmail.com>
+Date: Wed, 18 Sep 2013 22:45:06 +0200
+Subject: [PATCH] ARM: sun4i: dt: Add EHCI bindings to Cubieboard-A10
+
+Signed-off-by: Hans de Goede <hdegoede@redhat.com>
+
+Conflicts:
+       arch/arm/boot/dts/sun4i-a10-cubieboard.dts
+---
+ arch/arm/boot/dts/sun4i-a10-cubieboard.dts | 46 ++++++++++++++++++++++++++++++
+ 1 file changed, 46 insertions(+)
+
+diff --git a/arch/arm/boot/dts/sun4i-a10-cubieboard.dts b/arch/arm/boot/dts/sun4i-a10-cubieboard.dts
+index 53ac453..48864a4 100644
+--- a/arch/arm/boot/dts/sun4i-a10-cubieboard.dts
++++ b/arch/arm/boot/dts/sun4i-a10-cubieboard.dts
+@@ -77,6 +77,20 @@
+                               allwinner,drive = <1>;
+                               allwinner,pull = <0>;
+                       };
++
++                      usb1_vbus_pin: usb1_vbus_pin@0 {
++                                      allwinner,pins = "PH6";
++                                      allwinner,function = "gpio_out";
++                                      allwinner,drive = <0>;
++                                      allwinner,pull = <2>;
++                      };
++
++                      usb2_vbus_pin: usb2_vbus_pin@0 {
++                                      allwinner,pins = "PH3";
++                                      allwinner,function = "gpio_out";
++                                      allwinner,drive = <0>;
++                                      allwinner,pull = <2>;
++                      };
+               };
+               uart0: serial@01c28000 {
+@@ -96,6 +110,16 @@
+                       pinctrl-0 = <&i2c1_pins_a>;
+                       status = "okay";
+               };
++
++              ehci0: ehci0@0x01c14000 {
++                              vbus-supply = <&reg_usb1_vbus>;
++                              status = "okay";
++              };
++
++              ehci1: ehci1@0x01c1c000 {
++                              vbus-supply = <&reg_usb2_vbus>;
++                              status = "okay";
++              };
+       };
+       leds {
+@@ -128,5 +152,27 @@
+                       gpio = <&pio 1 8 0>;
+                       enable-active-high;
+               };
++
++              reg_usb1_vbus: usb1-vbus {
++                      compatible = "regulator-fixed";
++                      pinctrl-names = "default";
++                      pinctrl-0 = <&usb1_vbus_pin>;
++                      regulator-name = "usb1-vbus";
++                      regulator-min-microvolt = <3300000>;
++                      regulator-max-microvolt = <3300000>;
++                      enable-active-high;
++                      gpio = <&pio 7 6 0>;
++              };
++
++              reg_usb2_vbus: usb2-vbus {
++                      compatible = "regulator-fixed";
++                      pinctrl-names = "default";
++                      pinctrl-0 = <&usb2_vbus_pin>;
++                      regulator-name = "usb2-vbus";
++                      regulator-min-microvolt = <3300000>;
++                      regulator-max-microvolt = <3300000>;
++                      enable-active-high;
++                      gpio = <&pio 7 3 0>;
++              };
+       };
+ };
+-- 
+1.8.5.1
+
diff --git a/target/linux/sunxi/patches-3.13/173-4-dt-sun4i-add-ehci-a1000.patch b/target/linux/sunxi/patches-3.13/173-4-dt-sun4i-add-ehci-a1000.patch
new file mode 100644 (file)
index 0000000..f9a7125
--- /dev/null
@@ -0,0 +1,83 @@
+From 9a86b6c16abc11b1090fbf4e102b4eed1d474d96 Mon Sep 17 00:00:00 2001
+From: arokux <arokux@gmail.com>
+Date: Wed, 18 Sep 2013 00:30:40 +0200
+Subject: [PATCH] ARM: sun4i: dt: Add EHCI bindings to the Mele A1000
+
+Signed-off-by: Hans de Goede <hdegoede@redhat.com>
+---
+ arch/arm/boot/dts/sun4i-a10-a1000.dts | 46 +++++++++++++++++++++++++++++++++++
+ 1 file changed, 46 insertions(+)
+
+diff --git a/arch/arm/boot/dts/sun4i-a10-a1000.dts b/arch/arm/boot/dts/sun4i-a10-a1000.dts
+index fd6d512..e3bfc59 100644
+--- a/arch/arm/boot/dts/sun4i-a10-a1000.dts
++++ b/arch/arm/boot/dts/sun4i-a10-a1000.dts
+@@ -73,6 +73,20 @@
+                               allwinner,drive = <0>;
+                               allwinner,pull = <0>;
+                       };
++
++                      usb1_vbus_pin: usb1_vbus_pin@0 {
++                                      allwinner,pins = "PH6";
++                                      allwinner,function = "gpio_out";
++                                      allwinner,drive = <0>;
++                                      allwinner,pull = <2>;
++                      };
++
++                      usb2_vbus_pin: usb2_vbus_pin@0 {
++                                      allwinner,pins = "PH3";
++                                      allwinner,function = "gpio_out";
++                                      allwinner,drive = <0>;
++                                      allwinner,pull = <2>;
++                      };
+               };
+               uart0: serial@01c28000 {
+@@ -86,6 +100,16 @@
+                       pinctrl-0 = <&i2c0_pins_a>;
+                       status = "okay";
+               };
++
++              ehci0: ehci0@0x01c14000 {
++                      vbus-supply = <&reg_usb1_vbus>;
++                      status = "okay";
++              };
++
++              ehci1: ehci1@0x01c1c000 {
++                      vbus-supply = <&reg_usb2_vbus>;
++                      status = "okay";
++              };
+       };
+       leds {
+@@ -117,5 +141,27 @@
+                       enable-active-high;
+                       gpio = <&pio 7 15 0>;
+               };
++
++              reg_usb1_vbus: usb1-vbus {
++                      compatible = "regulator-fixed";
++                      pinctrl-names = "default";
++                      pinctrl-0 = <&usb1_vbus_pin>;
++                      regulator-name = "usb1-vbus";
++                      regulator-min-microvolt = <3300000>;
++                      regulator-max-microvolt = <3300000>;
++                      enable-active-high;
++                      gpio = <&pio 7 6 0>;
++              };
++
++              reg_usb2_vbus: usb2-vbus {
++                      compatible = "regulator-fixed";
++                      pinctrl-names = "default";
++                      pinctrl-0 = <&usb2_vbus_pin>;
++                      regulator-name = "usb2-vbus";
++                      regulator-min-microvolt = <3300000>;
++                      regulator-max-microvolt = <3300000>;
++                      enable-active-high;
++                      gpio = <&pio 7 3 0>;
++              };
+       };
+ };
+-- 
+1.8.5.1
+
diff --git a/target/linux/sunxi/patches-3.13/174-1-dt-sun7i-add-usbclock-nodes.patch b/target/linux/sunxi/patches-3.13/174-1-dt-sun7i-add-usbclock-nodes.patch
new file mode 100644 (file)
index 0000000..7f2f080
--- /dev/null
@@ -0,0 +1,32 @@
+From b7739d837e1176b2206ee541075c9eba0a263695 Mon Sep 17 00:00:00 2001
+From: arokux <arokux@gmail.com>
+Date: Thu, 19 Sep 2013 21:24:20 +0200
+Subject: [PATCH] ARM: sun7i: dt: Add bindings for USB clocks
+
+Signed-off-by: Hans de Goede <hdegoede@redhat.com>
+---
+ arch/arm/boot/dts/sun7i-a20.dtsi | 8 ++++++++
+ 1 file changed, 8 insertions(+)
+
+diff --git a/arch/arm/boot/dts/sun7i-a20.dtsi b/arch/arm/boot/dts/sun7i-a20.dtsi
+index 3242a29..4eddc79 100644
+--- a/arch/arm/boot/dts/sun7i-a20.dtsi
++++ b/arch/arm/boot/dts/sun7i-a20.dtsi
+@@ -89,6 +89,14 @@
+                       clock-output-names = "pll6_sata", "pll6_other", "pll6";
+               };
++              usb:usb@0x01c200cc {
++                      #clock-cells = <1>;
++                      compatible = "allwinner,sun47i-usb-gates-clk";
++                      reg = <0x01c200cc 0x4>;
++                      clocks = <&pll6 1>;
++                      clock-output-names = "usb_ohci0", "usb_ohci1", "usb_phy";
++              };
++
+               cpu: cpu@01c20054 {
+                       #clock-cells = <0>;
+                       compatible = "allwinner,sun4i-cpu-clk";
+-- 
+1.8.5.1
+
diff --git a/target/linux/sunxi/patches-3.13/174-2-dt-sun7i-add-ehci-bindings.patch b/target/linux/sunxi/patches-3.13/174-2-dt-sun7i-add-ehci-bindings.patch
new file mode 100644 (file)
index 0000000..779ad3c
--- /dev/null
@@ -0,0 +1,63 @@
+From a82eb088ea3fa4c25b256400690a30f4b0392e91 Mon Sep 17 00:00:00 2001
+From: arokux <arokux@gmail.com>
+Date: Thu, 19 Sep 2013 21:36:10 +0200
+Subject: [PATCH] ARM: sun7i: dt: Add USB EHCI bindings
+
+Signed-off-by: Hans de Goede <hdegoede@redhat.com>
+
+Conflicts:
+       arch/arm/boot/dts/sun7i-a20.dtsi
+---
+ arch/arm/boot/dts/sun7i-a20.dtsi | 30 ++++++++++++++++++++++++++++++
+ 1 file changed, 30 insertions(+)
+
+diff --git a/arch/arm/boot/dts/sun7i-a20.dtsi b/arch/arm/boot/dts/sun7i-a20.dtsi
+index 4eddc79..956b5cd 100644
+--- a/arch/arm/boot/dts/sun7i-a20.dtsi
++++ b/arch/arm/boot/dts/sun7i-a20.dtsi
+@@ -18,6 +18,8 @@
+       aliases {
+               ethernet0 = &gmac;
++              ehci1 = &ehci0;
++              ehci2 = &ehci1;
+       };
+       cpus {
+@@ -652,5 +654,33 @@
+                       #interrupt-cells = <3>;
+                       interrupts = <1 9 0xf04>;
+               };
++
++              usb_rst: reset@0x01c200cc {
++                      #reset-cells = <1>;
++                      compatible = "allwinner,sun4i-clock-reset";
++                      reg = <0x01c200cc 0x4>;
++              };
++
++              ehci0: ehci0@0x01c14000 {
++                      compatible = "allwinner,sunxi-ehci";
++                      reg = <0x01c14000 0x400 0x01c14800 0x4 0x01c13404 0x4>;
++                      interrupts = <0 39 1>;
++                      resets = <&usb_rst 1>;
++                      reset-names = "ehci_reset";
++                      clocks = <&usb 8>, <&ahb_gates 1>;
++                      clock-names = "usb_phy", "ahb_ehci";
++                      status = "disabled";
++              };
++
++              ehci1: ehci1@0x01c1c000 {
++                      compatible = "allwinner,sunxi-ehci";
++                      reg = <0x01c1c000 0x400 0x01c1c800 0x4 0x01c13404 0x4>;
++                      interrupts = <0 40 1>;
++                      resets = <&usb_rst 2>;
++                      reset-names = "ehci_reset";
++                      clocks = <&usb 8>, <&ahb_gates 3>;
++                      clock-names = "usb_phy", "ahb_ehci";
++                      status = "disabled";
++              };
+       };
+ };
+-- 
+1.8.5.1
+
diff --git a/target/linux/sunxi/patches-3.13/174-3-dt-sun7i-add-ehci-cubieboard2.patch b/target/linux/sunxi/patches-3.13/174-3-dt-sun7i-add-ehci-cubieboard2.patch
new file mode 100644 (file)
index 0000000..0f00c25
--- /dev/null
@@ -0,0 +1,85 @@
+From 8ba068f40cce9612d2ac0879b6978274ab497d31 Mon Sep 17 00:00:00 2001
+From: arokux <arokux@gmail.com>
+Date: Thu, 19 Sep 2013 21:29:45 +0200
+Subject: [PATCH] ARM: sun7i: dt: Add USB EHCI bindings for Cubieboard2
+
+Signed-off-by: Hans de Goede <hdegoede@redhat.com>
+
+Conflicts:
+       arch/arm/boot/dts/sun7i-a20-cubieboard2.dts
+---
+ arch/arm/boot/dts/sun7i-a20-cubieboard2.dts | 45 +++++++++++++++++++++++++++++
+ 1 file changed, 45 insertions(+)
+
+diff --git a/arch/arm/boot/dts/sun7i-a20-cubieboard2.dts b/arch/arm/boot/dts/sun7i-a20-cubieboard2.dts
+index a26711c..10ea99d 100644
+--- a/arch/arm/boot/dts/sun7i-a20-cubieboard2.dts
++++ b/arch/arm/boot/dts/sun7i-a20-cubieboard2.dts
+@@ -54,6 +54,20 @@
+                               allwinner,drive = <0>;
+                               allwinner,pull = <0>;
+                       };
++
++                      usb1_vbus_pin: usb1_vbus_pin@0 {
++                                      allwinner,pins = "PH6";
++                                      allwinner,function = "gpio_out";
++                                      allwinner,drive = <0>;
++                                      allwinner,pull = <2>;
++                      };
++
++                      usb2_vbus_pin: usb2_vbus_pin@0 {
++                                      allwinner,pins = "PH3";
++                                      allwinner,function = "gpio_out";
++                                      allwinner,drive = <0>;
++                                      allwinner,pull = <2>;
++                      };
+               };
+               uart0: serial@01c28000 {
+@@ -71,6 +85,15 @@
+               i2c1: i2c@01c2b000 {
+                       pinctrl-names = "default";
+                       pinctrl-0 = <&i2c1_pins_a>;
++              };
++
++              ehci0: ehci0@0x01c14000 {
++                      vbus-supply = <&reg_usb1_vbus>;
++                      status = "okay";
++              };
++
++              ehci1: ehci1@0x01c1c000 {
++                      vbus-supply = <&reg_usb2_vbus>;
+                       status = "okay";
+               };
+@@ -112,5 +135,27 @@
+                       gpio = <&pio 1 8 0>;
+                       enable-active-high;
+               };
++
++              reg_usb1_vbus: usb1-vbus {
++                      compatible = "regulator-fixed";
++                      pinctrl-names = "default";
++                      pinctrl-0 = <&usb1_vbus_pin>;
++                      regulator-name = "usb1-vbus";
++                      regulator-min-microvolt = <3300000>;
++                      regulator-max-microvolt = <3300000>;
++                      enable-active-high;
++                      gpio = <&pio 7 6 0>;
++              };
++
++              reg_usb2_vbus: usb2-vbus {
++                      compatible = "regulator-fixed";
++                      pinctrl-names = "default";
++                      pinctrl-0 = <&usb2_vbus_pin>;
++                      regulator-name = "usb2-vbus";
++                      regulator-min-microvolt = <3300000>;
++                      regulator-max-microvolt = <3300000>;
++                      enable-active-high;
++                      gpio = <&pio 7 3 0>;
++              };
+       };
+ };
+-- 
+1.8.5.1
+
diff --git a/target/linux/sunxi/patches-3.13/174-4-dt-sun7i-add-ehci-olinuxino-a20-micro.patch b/target/linux/sunxi/patches-3.13/174-4-dt-sun7i-add-ehci-olinuxino-a20-micro.patch
new file mode 100644 (file)
index 0000000..41f55da
--- /dev/null
@@ -0,0 +1,91 @@
+From 5031cb9d88fe9ea4a37fe342ec5f8e2f0f930e00 Mon Sep 17 00:00:00 2001
+From: Zalan Blenessy <zalan.blenessy@gmail.com>
+Date: Sun, 22 Dec 2013 17:08:10 +0100
+Subject: [PATCH] ARM: dts: sun7i: Add ehci nodes to Olinuxino A20 Micro dts
+
+Signed-off-by: Hans de Goede <hdegoede@redhat.com>
+---
+ arch/arm/boot/dts/sun7i-a20-olinuxino-micro.dts | 47 +++++++++++++++++++++++++
+ 1 file changed, 47 insertions(+)
+
+diff --git a/arch/arm/boot/dts/sun7i-a20-olinuxino-micro.dts b/arch/arm/boot/dts/sun7i-a20-olinuxino-micro.dts
+index 20b1000..5f13ed64 100644
+--- a/arch/arm/boot/dts/sun7i-a20-olinuxino-micro.dts
++++ b/arch/arm/boot/dts/sun7i-a20-olinuxino-micro.dts
+@@ -70,6 +70,20 @@
+                               allwinner,drive = <1>;
+                               allwinner,pull = <0>;
+                       };
++
++                      usb1_vbus_pin: usb1_vbus_pin@0 {
++                                      allwinner,pins = "PH6";
++                                      allwinner,function = "gpio_out";
++                                      allwinner,drive = <0>;
++                                      allwinner,pull = <2>;
++                      };
++
++                      usb2_vbus_pin: usb2_vbus_pin@0 {
++                                      allwinner,pins = "PH3";
++                                      allwinner,function = "gpio_out";
++                                      allwinner,drive = <0>;
++                                      allwinner,pull = <2>;
++                      };
+               };
+               uart0: serial@01c28000 {
+@@ -115,6 +129,16 @@
+                       phy-mode = "mii";
+                       status = "okay";
+               };
++
++              ehci0: ehci0@0x01c14000 {
++                      vbus-supply = <&reg_usb1_vbus>;
++                      status = "okay";
++              };
++
++              ehci1: ehci1@0x01c1c000 {
++                      vbus-supply = <&reg_usb2_vbus>;
++                      status = "okay";
++              };
+       };
+       leds {
+@@ -131,6 +155,7 @@
+       regulators {
+               compatible = "simple-bus";
++              pinctrl-names = "default";
+               reg_ahci_5v: ahci-5v {
+                       compatible = "regulator-fixed";
+@@ -141,5 +166,27 @@
+                       gpio = <&pio 1 8 0>;
+                       enable-active-high;
+               };
++
++              reg_usb1_vbus: usb1-vbus {
++                      compatible = "regulator-fixed";
++                      pinctrl-names = "default";
++                      pinctrl-0 = <&usb1_vbus_pin>;
++                      regulator-name = "usb1-vbus";
++                      regulator-min-microvolt = <5000000>;
++                      regulator-max-microvolt = <5000000>;
++                      enable-active-high;
++                      gpio = <&pio 7 6 0>;
++              };
++
++              reg_usb2_vbus: usb2-vbus {
++                      compatible = "regulator-fixed";
++                      pinctrl-names = "default";
++                      pinctrl-0 = <&usb2_vbus_pin>;
++                      regulator-name = "usb2-vbus";
++                      regulator-min-microvolt = <5000000>;
++                      regulator-max-microvolt = <5000000>;
++                      enable-active-high;
++                      gpio = <&pio 7 3 0>;
++              };
+       };
+ };
+-- 
+1.8.5.1
+
diff --git a/target/linux/sunxi/patches-3.13/174-5-dt-sun7i-add-ehci-cubietruck.patch b/target/linux/sunxi/patches-3.13/174-5-dt-sun7i-add-ehci-cubietruck.patch
new file mode 100644 (file)
index 0000000..0f77758
--- /dev/null
@@ -0,0 +1,88 @@
+From 90cab9a5e7c43bfbda25dd114a838f4e4b50b6ff Mon Sep 17 00:00:00 2001
+From: Hans de Goede <hdegoede@redhat.com>
+Date: Tue, 17 Dec 2013 23:04:57 +0100
+Subject: [PATCH] ARM: dts: sun7i: Add ehci nodes to cubietruck dts
+
+Signed-off-by: Hans de Goede <hdegoede@redhat.com>
+---
+ arch/arm/boot/dts/sun7i-a20-cubietruck.dts | 46 ++++++++++++++++++++++++++++++
+ 1 file changed, 46 insertions(+)
+
+diff --git a/arch/arm/boot/dts/sun7i-a20-cubietruck.dts b/arch/arm/boot/dts/sun7i-a20-cubietruck.dts
+index a5f3418..c8b3ea9 100644
+--- a/arch/arm/boot/dts/sun7i-a20-cubietruck.dts
++++ b/arch/arm/boot/dts/sun7i-a20-cubietruck.dts
+@@ -28,11 +28,21 @@
+                       status = "okay";
+               };
++              ehci0: ehci0@0x01c14000 {
++                      vbus-supply = <&reg_usb1_vbus>;
++                      status = "okay";
++              };
++
+               sata: ahci@01c18000 {
+                       pwr-supply = <&reg_ahci_5v>;
+                       status = "okay";
+               };
++              ehci1: ehci1@0x01c1c000 {
++                      vbus-supply = <&reg_usb2_vbus>;
++                      status = "okay";
++              };
++
+               pinctrl@01c20800 {
+                       mmc0_cd_pin_cubietruck: mmc0_cd_pin@0 {
+                               allwinner,pins = "PH1";
+@@ -54,6 +64,20 @@
+                               allwinner,drive = <0>;
+                               allwinner,pull = <0>;
+                       };
++
++                      usb1_vbus_pin: usb1_vbus_pin@0 {
++                                      allwinner,pins = "PH6";
++                                      allwinner,function = "gpio_out";
++                                      allwinner,drive = <0>;
++                                      allwinner,pull = <2>;
++                      };
++
++                      usb2_vbus_pin: usb2_vbus_pin@0 {
++                                      allwinner,pins = "PH3";
++                                      allwinner,function = "gpio_out";
++                                      allwinner,drive = <0>;
++                                      allwinner,pull = <2>;
++                      };
+               };
+               uart0: serial@01c28000 {
+@@ -110,5 +134,27 @@
+                       gpio = <&pio 7 12 0>;
+                       enable-active-high;
+               };
++
++              reg_usb1_vbus: usb1-vbus {
++                      compatible = "regulator-fixed";
++                      pinctrl-names = "default";
++                      pinctrl-0 = <&usb1_vbus_pin>;
++                      regulator-name = "usb1-vbus";
++                      regulator-min-microvolt = <5000000>;
++                      regulator-max-microvolt = <5000000>;
++                      enable-active-high;
++                      gpio = <&pio 7 6 0>;
++              };
++
++              reg_usb2_vbus: usb2-vbus {
++                      compatible = "regulator-fixed";
++                      pinctrl-names = "default";
++                      pinctrl-0 = <&usb2_vbus_pin>;
++                      regulator-name = "usb2-vbus";
++                      regulator-min-microvolt = <5000000>;
++                      regulator-max-microvolt = <5000000>;
++                      enable-active-high;
++                      gpio = <&pio 7 3 0>;
++              };
+       };
+ };
+-- 
+1.8.5.1
+
diff --git a/target/linux/sunxi/patches-3.13/175-1-dt-sun5i-add-usbclock-nodes.patch b/target/linux/sunxi/patches-3.13/175-1-dt-sun5i-add-usbclock-nodes.patch
new file mode 100644 (file)
index 0000000..8adcde5
--- /dev/null
@@ -0,0 +1,32 @@
+From f017ea35bd87e7935fbf5a03bc016d8b1efa03c0 Mon Sep 17 00:00:00 2001
+From: arokux <arokux@gmail.com>
+Date: Tue, 24 Sep 2013 20:02:39 +0200
+Subject: [PATCH] ARM: sun5i: dt: Add bindings for USB Host clocks
+
+Signed-off-by: Hans de Goede <hdegoede@redhat.com>
+---
+ arch/arm/boot/dts/sun5i-a13.dtsi | 8 ++++++++
+ 1 file changed, 8 insertions(+)
+
+diff --git a/arch/arm/boot/dts/sun5i-a13.dtsi b/arch/arm/boot/dts/sun5i-a13.dtsi
+index 2dde48a..1a416d0 100644
+--- a/arch/arm/boot/dts/sun5i-a13.dtsi
++++ b/arch/arm/boot/dts/sun5i-a13.dtsi
+@@ -90,6 +90,14 @@
+                       clock-output-names = "pll6_sata", "pll6_other", "pll6";
+               };
++              usb:usb@0x01c200cc {
++                      #clock-cells = <1>;
++                      compatible = "allwinner,sun5i-usb-gates-clk";
++                      reg = <0x01c200cc 0x4>;
++                      clocks = <&pll6 1>;
++                      clock-output-names = "usb_ohci0", "usb_phy";
++              };
++
+               /* dummy is 200M */
+               cpu: cpu@01c20054 {
+                       #clock-cells = <0>;
+-- 
+1.8.5.1
+
diff --git a/target/linux/sunxi/patches-3.13/175-2-dt-sun5i-add-ehci-bindings.patch b/target/linux/sunxi/patches-3.13/175-2-dt-sun5i-add-ehci-bindings.patch
new file mode 100644 (file)
index 0000000..1434cfe
--- /dev/null
@@ -0,0 +1,51 @@
+From 3d3aa5f5c67d3f860b68def6a0ffce5e7175f85e Mon Sep 17 00:00:00 2001
+From: arokux <arokux@gmail.com>
+Date: Tue, 24 Sep 2013 20:03:40 +0200
+Subject: [PATCH] ARM: sun5i: dt: Add USB EHCI bindings
+
+Signed-off-by: Hans de Goede <hdegoede@redhat.com>
+---
+ arch/arm/boot/dts/sun5i-a13.dtsi | 21 +++++++++++++++++++++
+ 1 file changed, 21 insertions(+)
+
+diff --git a/arch/arm/boot/dts/sun5i-a13.dtsi b/arch/arm/boot/dts/sun5i-a13.dtsi
+index 1a416d0..5bf7e9a 100644
+--- a/arch/arm/boot/dts/sun5i-a13.dtsi
++++ b/arch/arm/boot/dts/sun5i-a13.dtsi
+@@ -16,6 +16,10 @@
+ / {
+       interrupt-parent = <&intc>;
++      aliases {
++              ehci1 = &ehci0;
++      };
++
+       cpus {
+               #address-cells = <1>;
+               #size-cells = <0>;
+@@ -416,5 +420,22 @@
+                       interrupts = <82>, <83>;
+                       clocks = <&ahb_gates 28>;
+               };
++
++              usb_rst: reset@0x01c200cc {
++                      #reset-cells = <1>;
++                      compatible = "allwinner,sun4i-clock-reset";
++                      reg = <0x01c200cc 0x4>;
++              };
++
++              ehci0: ehci0@0x01c14000 {
++                      compatible = "allwinner,sunxi-ehci";
++                      reg = <0x01c14000 0x400 0x01c14800 0x4 0x01c13404 0x4>;
++                      interrupts = <39>;
++                      resets = <&usb_rst 1>;
++                      reset-names = "ehci_reset";
++                      clocks = <&usb 8>, <&ahb_gates 1>;
++                      clock-names = "usb_phy", "ahb_ehci";
++                      status = "disabled";
++              };
+       };
+ };
+-- 
+1.8.5.1
+
diff --git a/target/linux/sunxi/patches-3.13/175-3-dt-sun5i-add-ehci-a13.patch b/target/linux/sunxi/patches-3.13/175-3-dt-sun5i-add-ehci-a13.patch
new file mode 100644 (file)
index 0000000..8dbc37c
--- /dev/null
@@ -0,0 +1,63 @@
+From 586c4aa0aeb07dacccb25a419a7b6625521ddea8 Mon Sep 17 00:00:00 2001
+From: arokux <arokux@gmail.com>
+Date: Tue, 24 Sep 2013 20:07:53 +0200
+Subject: [PATCH] ARM: sun5i: dt: Add EHCI bindings to A13-Olinuxino
+
+Signed-off-by: Hans de Goede <hdegoede@redhat.com>
+---
+ arch/arm/boot/dts/sun5i-a13-olinuxino.dts | 27 +++++++++++++++++++++++++++
+ 1 file changed, 27 insertions(+)
+
+diff --git a/arch/arm/boot/dts/sun5i-a13-olinuxino.dts b/arch/arm/boot/dts/sun5i-a13-olinuxino.dts
+index cf77d9a..4b73e3e 100644
+--- a/arch/arm/boot/dts/sun5i-a13-olinuxino.dts
++++ b/arch/arm/boot/dts/sun5i-a13-olinuxino.dts
+@@ -46,6 +46,13 @@
+                               allwinner,drive = <1>;
+                               allwinner,pull = <0>;
+                       };
++
++                      usb1_vbus_pin: usb1_vbus_pin@0 {
++                              allwinner,pins = "PG11";
++                              allwinner,function = "gpio_out";
++                              allwinner,drive = <0>;
++                              allwinner,pull = <2>;
++                      };
+               };
+               uart1: serial@01c28400 {
+@@ -71,6 +78,11 @@
+                       pinctrl-0 = <&i2c2_pins_a>;
+                       status = "okay";
+               };
++
++              ehci0: ehci0@0x01c14000 {
++                      vbus-supply = <&reg_usb1_vbus>;
++                      status = "okay";
++              };
+       };
+       leds {
+@@ -83,4 +95,19 @@
+                       default-state = "on";
+               };
+       };
++
++      regulators {
++              compatible = "simple-bus";
++
++              reg_usb1_vbus: usb1-vbus {
++                      compatible = "regulator-fixed";
++                      pinctrl-names = "default";
++                      pinctrl-0 = <&usb1_vbus_pin>;
++                      regulator-name = "usb1-vbus";
++                      regulator-min-microvolt = <3300000>;
++                      regulator-max-microvolt = <3300000>;
++                      enable-active-high;
++                      gpio = <&pio 6 11 0>;
++              };
++      };
+ };
+-- 
+1.8.5.1
+
diff --git a/target/linux/sunxi/patches-3.13/176-dt-sunxi-update-usb-regulator.patch b/target/linux/sunxi/patches-3.13/176-dt-sunxi-update-usb-regulator.patch
new file mode 100644 (file)
index 0000000..0db0f2b
--- /dev/null
@@ -0,0 +1,109 @@
+From b0a614458fb67fdb53e1b5518dabb85d688b196e Mon Sep 17 00:00:00 2001
+From: Hans de Goede <hdegoede@redhat.com>
+Date: Tue, 17 Dec 2013 22:59:17 +0100
+Subject: [PATCH] ARM: dts: sunxi: usb Vbus is 5v not 3.3v
+
+Signed-off-by: Hans de Goede <hdegoede@redhat.com>
+---
+ arch/arm/boot/dts/sun4i-a10-a1000.dts       | 8 ++++----
+ arch/arm/boot/dts/sun4i-a10-cubieboard.dts  | 8 ++++----
+ arch/arm/boot/dts/sun5i-a13-olinuxino.dts   | 4 ++--
+ arch/arm/boot/dts/sun7i-a20-cubieboard2.dts | 8 ++++----
+ 4 files changed, 14 insertions(+), 14 deletions(-)
+
+diff --git a/arch/arm/boot/dts/sun4i-a10-a1000.dts b/arch/arm/boot/dts/sun4i-a10-a1000.dts
+index e3bfc59..315e607 100644
+--- a/arch/arm/boot/dts/sun4i-a10-a1000.dts
++++ b/arch/arm/boot/dts/sun4i-a10-a1000.dts
+@@ -147,8 +147,8 @@
+                       pinctrl-names = "default";
+                       pinctrl-0 = <&usb1_vbus_pin>;
+                       regulator-name = "usb1-vbus";
+-                      regulator-min-microvolt = <3300000>;
+-                      regulator-max-microvolt = <3300000>;
++                      regulator-min-microvolt = <5000000>;
++                      regulator-max-microvolt = <5000000>;
+                       enable-active-high;
+                       gpio = <&pio 7 6 0>;
+               };
+@@ -158,8 +158,8 @@
+                       pinctrl-names = "default";
+                       pinctrl-0 = <&usb2_vbus_pin>;
+                       regulator-name = "usb2-vbus";
+-                      regulator-min-microvolt = <3300000>;
+-                      regulator-max-microvolt = <3300000>;
++                      regulator-min-microvolt = <5000000>;
++                      regulator-max-microvolt = <5000000>;
+                       enable-active-high;
+                       gpio = <&pio 7 3 0>;
+               };
+diff --git a/arch/arm/boot/dts/sun4i-a10-cubieboard.dts b/arch/arm/boot/dts/sun4i-a10-cubieboard.dts
+index 48864a4..0bd2aae 100644
+--- a/arch/arm/boot/dts/sun4i-a10-cubieboard.dts
++++ b/arch/arm/boot/dts/sun4i-a10-cubieboard.dts
+@@ -158,8 +158,8 @@
+                       pinctrl-names = "default";
+                       pinctrl-0 = <&usb1_vbus_pin>;
+                       regulator-name = "usb1-vbus";
+-                      regulator-min-microvolt = <3300000>;
+-                      regulator-max-microvolt = <3300000>;
++                      regulator-min-microvolt = <5000000>;
++                      regulator-max-microvolt = <5000000>;
+                       enable-active-high;
+                       gpio = <&pio 7 6 0>;
+               };
+@@ -169,8 +169,8 @@
+                       pinctrl-names = "default";
+                       pinctrl-0 = <&usb2_vbus_pin>;
+                       regulator-name = "usb2-vbus";
+-                      regulator-min-microvolt = <3300000>;
+-                      regulator-max-microvolt = <3300000>;
++                      regulator-min-microvolt = <5000000>;
++                      regulator-max-microvolt = <5000000>;
+                       enable-active-high;
+                       gpio = <&pio 7 3 0>;
+               };
+diff --git a/arch/arm/boot/dts/sun5i-a13-olinuxino.dts b/arch/arm/boot/dts/sun5i-a13-olinuxino.dts
+index 4b73e3e..b255d1b 100644
+--- a/arch/arm/boot/dts/sun5i-a13-olinuxino.dts
++++ b/arch/arm/boot/dts/sun5i-a13-olinuxino.dts
+@@ -104,8 +104,8 @@
+                       pinctrl-names = "default";
+                       pinctrl-0 = <&usb1_vbus_pin>;
+                       regulator-name = "usb1-vbus";
+-                      regulator-min-microvolt = <3300000>;
+-                      regulator-max-microvolt = <3300000>;
++                      regulator-min-microvolt = <5000000>;
++                      regulator-max-microvolt = <5000000>;
+                       enable-active-high;
+                       gpio = <&pio 6 11 0>;
+               };
+diff --git a/arch/arm/boot/dts/sun7i-a20-cubieboard2.dts b/arch/arm/boot/dts/sun7i-a20-cubieboard2.dts
+index 10ea99d..144b11a 100644
+--- a/arch/arm/boot/dts/sun7i-a20-cubieboard2.dts
++++ b/arch/arm/boot/dts/sun7i-a20-cubieboard2.dts
+@@ -141,8 +141,8 @@
+                       pinctrl-names = "default";
+                       pinctrl-0 = <&usb1_vbus_pin>;
+                       regulator-name = "usb1-vbus";
+-                      regulator-min-microvolt = <3300000>;
+-                      regulator-max-microvolt = <3300000>;
++                      regulator-min-microvolt = <5000000>;
++                      regulator-max-microvolt = <5000000>;
+                       enable-active-high;
+                       gpio = <&pio 7 6 0>;
+               };
+@@ -152,8 +152,8 @@
+                       pinctrl-names = "default";
+                       pinctrl-0 = <&usb2_vbus_pin>;
+                       regulator-name = "usb2-vbus";
+-                      regulator-min-microvolt = <3300000>;
+-                      regulator-max-microvolt = <3300000>;
++                      regulator-min-microvolt = <5000000>;
++                      regulator-max-microvolt = <5000000>;
+                       enable-active-high;
+                       gpio = <&pio 7 3 0>;
+               };
+-- 
+1.8.5.1
+
diff --git a/target/linux/sunxi/patches-3.13/177-dt-sun7i-fix-ehci-irqtypes.patch b/target/linux/sunxi/patches-3.13/177-dt-sun7i-fix-ehci-irqtypes.patch
new file mode 100644 (file)
index 0000000..9b4575e
--- /dev/null
@@ -0,0 +1,35 @@
+From 06285d1c64552291f136eb197b6f05bc9d9c1d0e Mon Sep 17 00:00:00 2001
+From: Hans de Goede <hdegoede@redhat.com>
+Date: Tue, 17 Dec 2013 23:26:45 +0100
+Subject: [PATCH] ARM: dts: sun7i: Fix ehci interrupt types
+
+Signed-off-by: Hans de Goede <hdegoede@redhat.com>
+---
+ arch/arm/boot/dts/sun7i-a20.dtsi | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/arch/arm/boot/dts/sun7i-a20.dtsi b/arch/arm/boot/dts/sun7i-a20.dtsi
+index 956b5cd..2e19c47 100644
+--- a/arch/arm/boot/dts/sun7i-a20.dtsi
++++ b/arch/arm/boot/dts/sun7i-a20.dtsi
+@@ -664,7 +664,7 @@
+               ehci0: ehci0@0x01c14000 {
+                       compatible = "allwinner,sunxi-ehci";
+                       reg = <0x01c14000 0x400 0x01c14800 0x4 0x01c13404 0x4>;
+-                      interrupts = <0 39 1>;
++                      interrupts = <0 39 4>;
+                       resets = <&usb_rst 1>;
+                       reset-names = "ehci_reset";
+                       clocks = <&usb 8>, <&ahb_gates 1>;
+@@ -675,7 +675,7 @@
+               ehci1: ehci1@0x01c1c000 {
+                       compatible = "allwinner,sunxi-ehci";
+                       reg = <0x01c1c000 0x400 0x01c1c800 0x4 0x01c13404 0x4>;
+-                      interrupts = <0 40 1>;
++                      interrupts = <0 40 4>;
+                       resets = <&usb_rst 2>;
+                       reset-names = "ehci_reset";
+                       clocks = <&usb 8>, <&ahb_gates 3>;
+-- 
+1.8.5.1
+
diff --git a/target/linux/sunxi/patches-3.13/178-sunxi-ehci-fix-resource-check.patch b/target/linux/sunxi/patches-3.13/178-sunxi-ehci-fix-resource-check.patch
new file mode 100644 (file)
index 0000000..0f472b3
--- /dev/null
@@ -0,0 +1,27 @@
+From e772c9c2f552740ae735328cbd06b1d7f8e9d885 Mon Sep 17 00:00:00 2001
+From: Hans de Goede <hdegoede@redhat.com>
+Date: Tue, 17 Dec 2013 23:27:03 +0100
+Subject: [PATCH] ARM: sunxi-ehci: Fix resource check
+
+Signed-off-by: Hans de Goede <hdegoede@redhat.com>
+---
+ drivers/usb/host/ehci-sunxi.c | 3 ++-
+ 1 file changed, 2 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/usb/host/ehci-sunxi.c b/drivers/usb/host/ehci-sunxi.c
+index e7e15cc..e050d78 100644
+--- a/drivers/usb/host/ehci-sunxi.c
++++ b/drivers/usb/host/ehci-sunxi.c
+@@ -332,7 +332,8 @@ static int sunxi_ehci_probe(struct platform_device *pdev)
+       if (pdev->resource[0].flags != IORESOURCE_MEM
+                       || pdev->resource[1].flags != IORESOURCE_MEM
+                       || pdev->resource[2].flags != IORESOURCE_MEM
+-                      || pdev->resource[3].flags != IORESOURCE_IRQ) {
++                      || (pdev->resource[3].flags & IORESOURCE_TYPE_BITS)
++                              != IORESOURCE_IRQ) {
+               dev_err(&pdev->dev, "invalid resource type\n");
+               return -ENODEV;
+       }
+-- 
+1.8.5.1
+
diff --git a/target/linux/sunxi/patches-3.13/180-sunxi-select-PSCI.patch b/target/linux/sunxi/patches-3.13/180-sunxi-select-PSCI.patch
new file mode 100644 (file)
index 0000000..3c7f178
--- /dev/null
@@ -0,0 +1,27 @@
+From d46cebc1431948638fe4e6cfd27fb9da48e6c593 Mon Sep 17 00:00:00 2001
+From: Zalan Blenessy <zalan.blenessy@gmail.com>
+Date: Sun, 22 Dec 2013 17:10:06 +0100
+Subject: [PATCH] ARM: sunxi: select ARM_PSCI
+
+This is necessary for SMP on sun7i.
+
+Signed-off-by: Hans de Goede <hdegoede@redhat.com>
+---
+ arch/arm/mach-sunxi/Kconfig | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/arch/arm/mach-sunxi/Kconfig b/arch/arm/mach-sunxi/Kconfig
+index 547004c..09df4b81 100644
+--- a/arch/arm/mach-sunxi/Kconfig
++++ b/arch/arm/mach-sunxi/Kconfig
+@@ -3,6 +3,7 @@ config ARCH_SUNXI
+       select ARCH_HAS_RESET_CONTROLLER
+       select ARCH_REQUIRE_GPIOLIB
+       select ARM_GIC
++      select ARM_PSCI
+       select CLKSRC_MMIO
+       select CLKSRC_OF
+       select COMMON_CLK
+-- 
+1.8.5.1
+
diff --git a/target/linux/sunxi/patches-3.13/190-stmmac-enable-main-clock-when-probing.patch b/target/linux/sunxi/patches-3.13/190-stmmac-enable-main-clock-when-probing.patch
new file mode 100644 (file)
index 0000000..f708584
--- /dev/null
@@ -0,0 +1,71 @@
+From 133a9b75e2b0c48cd1d8f93b0ee61089821c32d9 Mon Sep 17 00:00:00 2001
+From: Chen-Yu Tsai <wens@csie.org>
+Date: Sat, 7 Dec 2013 01:29:34 +0800
+Subject: [PATCH] net: stmmac: Enable stmmac main clock when probing hardware
+
+Signed-off-by: Chen-Yu Tsai <wens@csie.org>
+---
+ drivers/net/ethernet/stmicro/stmmac/stmmac_main.c | 24 +++++++++++++----------
+ 1 file changed, 14 insertions(+), 10 deletions(-)
+
+diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
+index 8a7a23a..4d75cba 100644
+--- a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
++++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
+@@ -2682,10 +2682,17 @@ struct stmmac_priv *stmmac_dvr_probe(struct device *device,
+       if ((phyaddr >= 0) && (phyaddr <= 31))
+               priv->plat->phy_addr = phyaddr;
++      priv->stmmac_clk = clk_get(priv->device, STMMAC_RESOURCE_NAME);
++      if (IS_ERR(priv->stmmac_clk)) {
++              pr_warn("%s: warning: cannot get CSR clock\n", __func__);
++              goto error_clk_get;
++      }
++      clk_prepare_enable(priv->stmmac_clk);
++
+       /* Init MAC and get the capabilities */
+       ret = stmmac_hw_init(priv);
+       if (ret)
+-              goto error_free_netdev;
++              goto error_hw_init;
+       ndev->netdev_ops = &stmmac_netdev_ops;
+@@ -2723,12 +2730,6 @@ struct stmmac_priv *stmmac_dvr_probe(struct device *device,
+               goto error_netdev_register;
+       }
+-      priv->stmmac_clk = clk_get(priv->device, STMMAC_RESOURCE_NAME);
+-      if (IS_ERR(priv->stmmac_clk)) {
+-              pr_warn("%s: warning: cannot get CSR clock\n", __func__);
+-              goto error_clk_get;
+-      }
+-
+       /* If a specific clk_csr value is passed from the platform
+        * this means that the CSR Clock Range selection cannot be
+        * changed at run-time and it is fixed. Viceversa the driver'll try to
+@@ -2753,15 +2754,18 @@ struct stmmac_priv *stmmac_dvr_probe(struct device *device,
+               }
+       }
++      clk_disable_unprepare(priv->stmmac_clk);
++
+       return priv;
+ error_mdio_register:
+-      clk_put(priv->stmmac_clk);
+-error_clk_get:
+       unregister_netdev(ndev);
+ error_netdev_register:
+       netif_napi_del(&priv->napi);
+-error_free_netdev:
++error_hw_init:
++      clk_disable_unprepare(priv->stmmac_clk);
++      clk_put(priv->stmmac_clk);
++error_clk_get:
+       free_netdev(ndev);
+       return NULL;
+-- 
+1.8.5.1
+
diff --git a/target/linux/sunxi/patches-3.13/191-stmmac-honor-DT-params.patch b/target/linux/sunxi/patches-3.13/191-stmmac-honor-DT-params.patch
new file mode 100644 (file)
index 0000000..6f0b02e
--- /dev/null
@@ -0,0 +1,29 @@
+From a2acf761e37031737300c47284181a21b6bc0cc2 Mon Sep 17 00:00:00 2001
+From: Chen-Yu Tsai <wens@csie.org>
+Date: Sat, 7 Dec 2013 01:29:35 +0800
+Subject: [PATCH] net: stmmac: Honor DT parameter to force DMA store and
+ forward mode
+
+"snps,force_sf_dma_mode" is documented in stmmac device tree bindings,
+but is never handled by the driver.
+
+Signed-off-by: Chen-Yu Tsai <wens@csie.org>
+---
+ drivers/net/ethernet/stmicro/stmmac/stmmac_platform.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_platform.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_platform.c
+index 51c9069..74c7aef 100644
+--- a/drivers/net/ethernet/stmicro/stmmac/stmmac_platform.c
++++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_platform.c
+@@ -47,6 +47,7 @@ static int stmmac_probe_config_dt(struct platform_device *pdev,
+               plat->bus_id = 0;
+       of_property_read_u32(np, "snps,phy-addr", &plat->phy_addr);
++      plat->force_sf_dma_mode = of_property_read_bool(np, "snps,force_sf_dma_mode");
+       plat->mdio_bus_data = devm_kzalloc(&pdev->dev,
+                                          sizeof(struct stmmac_mdio_bus_data),
+-- 
+1.8.5.1
+
diff --git a/target/linux/sunxi/patches-3.13/192-stmmac-use-platform-data-with-compat.patch b/target/linux/sunxi/patches-3.13/192-stmmac-use-platform-data-with-compat.patch
new file mode 100644 (file)
index 0000000..70b5075
--- /dev/null
@@ -0,0 +1,73 @@
+From 34722924d416c3521de2bc8d10dfcd07a55135ea Mon Sep 17 00:00:00 2001
+From: Chen-Yu Tsai <wens@csie.org>
+Date: Sat, 7 Dec 2013 01:29:36 +0800
+Subject: [PATCH] net: stmmac: Use platform data tied with compatible strings
+
+Signed-off-by: Chen-Yu Tsai <wens@csie.org>
+---
+ .../net/ethernet/stmicro/stmmac/stmmac_platform.c  | 29 ++++++++++++++--------
+ 1 file changed, 19 insertions(+), 10 deletions(-)
+
+diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_platform.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_platform.c
+index 74c7aef..df3fd1c 100644
+--- a/drivers/net/ethernet/stmicro/stmmac/stmmac_platform.c
++++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_platform.c
+@@ -26,8 +26,19 @@
+ #include <linux/io.h>
+ #include <linux/of.h>
+ #include <linux/of_net.h>
++#include <linux/of_device.h>
+ #include "stmmac.h"
++static const struct of_device_id stmmac_dt_ids[] = {
++      { .compatible = "st,spear600-gmac"},
++      { .compatible = "snps,dwmac-3.610"},
++      { .compatible = "snps,dwmac-3.70a"},
++      { .compatible = "snps,dwmac-3.710"},
++      { .compatible = "snps,dwmac"},
++      { /* sentinel */ }
++};
++MODULE_DEVICE_TABLE(of, stmmac_dt_ids);
++
+ #ifdef CONFIG_OF
+ static int stmmac_probe_config_dt(struct platform_device *pdev,
+                                 struct plat_stmmacenet_data *plat,
+@@ -35,10 +46,18 @@ static int stmmac_probe_config_dt(struct platform_device *pdev,
+ {
+       struct device_node *np = pdev->dev.of_node;
+       struct stmmac_dma_cfg *dma_cfg;
++      const struct of_device_id *device;
+       if (!np)
+               return -ENODEV;
++      device = of_match_device(stmmac_dt_ids, &pdev->dev);
++      if (!device)
++              return -ENODEV;
++
++      if (device->data)
++          memcpy(plat, device->data, sizeof(*plat));
++
+       *mac = of_get_mac_address(np);
+       plat->interface = of_get_phy_mode(np);
+@@ -257,16 +276,6 @@ int stmmac_pltfr_restore(struct device *dev)
+ static const struct dev_pm_ops stmmac_pltfr_pm_ops;
+ #endif /* CONFIG_PM */
+-static const struct of_device_id stmmac_dt_ids[] = {
+-      { .compatible = "st,spear600-gmac"},
+-      { .compatible = "snps,dwmac-3.610"},
+-      { .compatible = "snps,dwmac-3.70a"},
+-      { .compatible = "snps,dwmac-3.710"},
+-      { .compatible = "snps,dwmac"},
+-      { /* sentinel */ }
+-};
+-MODULE_DEVICE_TABLE(of, stmmac_dt_ids);
+-
+ struct platform_driver stmmac_pltfr_driver = {
+       .probe = stmmac_pltfr_probe,
+       .remove = stmmac_pltfr_remove,
+-- 
+1.8.5.1
+
diff --git a/target/linux/sunxi/patches-3.13/193-stmmac-platform-ext-for-a20.patch b/target/linux/sunxi/patches-3.13/193-stmmac-platform-ext-for-a20.patch
new file mode 100644 (file)
index 0000000..9bc1bcb
--- /dev/null
@@ -0,0 +1,204 @@
+From 3c6560eccfeee3a93d57c3b2206abfbe06459015 Mon Sep 17 00:00:00 2001
+From: Chen-Yu Tsai <wens@csie.org>
+Date: Sat, 7 Dec 2013 01:29:37 +0800
+Subject: [PATCH] net: stmmac: sunxi platfrom extensions for GMAC in Allwinner
+ A20 SoC's
+
+The Allwinner A20 has an ethernet controller that seems to be
+an early version of Synopsys DesignWare MAC 10/100/1000 Universal,
+which is supported by the stmmac driver.
+
+Allwinner's GMAC requires setting additional registers in the SoC's
+clock control unit.
+
+The exact version of the DWMAC IP that Allwinner uses is unknown,
+thus the exact feature set is unknown.
+
+Signed-off-by: Chen-Yu Tsai <wens@csie.org>
+---
+ .../bindings/net/allwinner,sun7i-gmac.txt          | 22 +++++++
+ drivers/net/ethernet/stmicro/stmmac/Kconfig        | 12 ++++
+ drivers/net/ethernet/stmicro/stmmac/Makefile       |  1 +
+ drivers/net/ethernet/stmicro/stmmac/dwmac-sunxi.c  | 76 ++++++++++++++++++++++
+ drivers/net/ethernet/stmicro/stmmac/stmmac.h       |  3 +
+ .../net/ethernet/stmicro/stmmac/stmmac_platform.c  |  3 +
+ 6 files changed, 117 insertions(+)
+ create mode 100644 Documentation/devicetree/bindings/net/allwinner,sun7i-gmac.txt
+ create mode 100644 drivers/net/ethernet/stmicro/stmmac/dwmac-sunxi.c
+
+diff --git a/Documentation/devicetree/bindings/net/allwinner,sun7i-gmac.txt b/Documentation/devicetree/bindings/net/allwinner,sun7i-gmac.txt
+new file mode 100644
+index 0000000..271554a
+--- /dev/null
++++ b/Documentation/devicetree/bindings/net/allwinner,sun7i-gmac.txt
+@@ -0,0 +1,22 @@
++* Allwinner GMAC ethernet controller
++
++This device is a platform glue layer for stmmac.
++Please see stmmac.txt for the other unchanged properties.
++
++Required properties:
++ - compatible:  Should be "allwinner,sun7i-gmac"
++ - reg: Address and length of register set for the device and corresponding
++   clock control
++
++Examples:
++
++      gmac: ethernet@01c50000 {
++              compatible = "allwinner,sun7i-gmac";
++              reg = <0x01c50000 0x10000>,
++                    <0x01c20164 0x4>;
++              interrupts = <0 85 1>;
++              interrupt-names = "macirq";
++              clocks = <&ahb_gates 49>;
++              clock-names = "stmmaceth";
++              phy-mode = "mii";
++      };
+diff --git a/drivers/net/ethernet/stmicro/stmmac/Kconfig b/drivers/net/ethernet/stmicro/stmmac/Kconfig
+index 6e52c0f..6d71210 100644
+--- a/drivers/net/ethernet/stmicro/stmmac/Kconfig
++++ b/drivers/net/ethernet/stmicro/stmmac/Kconfig
+@@ -25,6 +25,18 @@ config STMMAC_PLATFORM
+         If unsure, say N.
++config DWMAC_SUNXI
++      bool "Allwinner GMAC support"
++      depends on STMMAC_PLATFORM
++      depends on ARCH_SUNXI
++      default y
++      ---help---
++        Support for Allwinner A20 GMAC ethernet driver.
++
++        This selects Allwinner SoC glue layer support for the
++        stmmac device driver. This driver is used for A20 GMAC
++        ethernet controller.
++
+ config STMMAC_PCI
+       bool "STMMAC PCI bus support"
+       depends on STMMAC_ETH && PCI
+diff --git a/drivers/net/ethernet/stmicro/stmmac/Makefile b/drivers/net/ethernet/stmicro/stmmac/Makefile
+index 356a9dd..ecadece 100644
+--- a/drivers/net/ethernet/stmicro/stmmac/Makefile
++++ b/drivers/net/ethernet/stmicro/stmmac/Makefile
+@@ -1,6 +1,7 @@
+ obj-$(CONFIG_STMMAC_ETH) += stmmac.o
+ stmmac-$(CONFIG_STMMAC_PLATFORM) += stmmac_platform.o
+ stmmac-$(CONFIG_STMMAC_PCI) += stmmac_pci.o
++stmmac-$(CONFIG_DWMAC_SUNXI) += dwmac-sunxi.o
+ stmmac-objs:= stmmac_main.o stmmac_ethtool.o stmmac_mdio.o ring_mode.o        \
+             chain_mode.o dwmac_lib.o dwmac1000_core.o  dwmac1000_dma.o \
+             dwmac100_core.o dwmac100_dma.o enh_desc.o  norm_desc.o \
+diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac-sunxi.c b/drivers/net/ethernet/stmicro/stmmac/dwmac-sunxi.c
+new file mode 100644
+index 0000000..6c9fdb0
+--- /dev/null
++++ b/drivers/net/ethernet/stmicro/stmmac/dwmac-sunxi.c
+@@ -0,0 +1,76 @@
++/**
++ * dwmac-sunxi.c - Allwinner sunxi DWMAC specific glue layer
++ *
++ * Copyright (C) 2013 Chen-Yu Tsai
++ *
++ * Chen-Yu Tsai  <wens@csie.org>
++ *
++ * 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 <linux/clk.h>
++#include <linux/phy.h>
++#include <linux/stmmac.h>
++
++#define GMAC_IF_TYPE_RGMII    0x4
++
++#define GMAC_TX_CLK_MASK      0x3
++#define GMAC_TX_CLK_MII               0x0
++#define GMAC_TX_CLK_RGMII_INT 0x2
++
++static int sun7i_gmac_init(struct platform_device *pdev)
++{
++      struct resource *res;
++      struct device *dev = &pdev->dev;
++      void __iomem *addr = NULL;
++      struct plat_stmmacenet_data *plat_dat = NULL;
++      u32 priv_clk_reg;
++
++      plat_dat = dev_get_platdata(&pdev->dev);
++      if (!plat_dat)
++              return -EINVAL;
++
++      /* Get GMAC clock register in CCU */
++      res = platform_get_resource(pdev, IORESOURCE_MEM, 1);
++      addr = devm_ioremap_resource(dev, res);
++      if (IS_ERR(addr))
++              return PTR_ERR(addr);
++
++      priv_clk_reg = readl(addr);
++
++      /* Set GMAC interface port mode */
++      if (plat_dat->interface == PHY_INTERFACE_MODE_RGMII)
++              priv_clk_reg |= GMAC_IF_TYPE_RGMII;
++      else
++              priv_clk_reg &= ~GMAC_IF_TYPE_RGMII;
++
++      /* Set GMAC transmit clock source. */
++      priv_clk_reg &= ~GMAC_TX_CLK_MASK;
++      if (plat_dat->interface == PHY_INTERFACE_MODE_RGMII
++                      || plat_dat->interface == PHY_INTERFACE_MODE_GMII)
++              priv_clk_reg |= GMAC_TX_CLK_RGMII_INT;
++      else
++              priv_clk_reg |= GMAC_TX_CLK_MII;
++
++      writel(priv_clk_reg, addr);
++
++      /* mask out phy addr 0x0 */
++      plat_dat->mdio_bus_data->phy_mask = 0x1;
++
++      return 0;
++}
++
++const struct plat_stmmacenet_data sun7i_gmac_data = {
++      .has_gmac = 1,
++      .tx_coe = 1,
++      .init = sun7i_gmac_init,
++};
++
+diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac.h b/drivers/net/ethernet/stmicro/stmmac/stmmac.h
+index 22f89ff..c8f659a 100644
+--- a/drivers/net/ethernet/stmicro/stmmac/stmmac.h
++++ b/drivers/net/ethernet/stmicro/stmmac/stmmac.h
+@@ -130,6 +130,9 @@ struct stmmac_priv *stmmac_dvr_probe(struct device *device,
+ bool stmmac_eee_init(struct stmmac_priv *priv);
+ #ifdef CONFIG_STMMAC_PLATFORM
++#ifdef CONFIG_DWMAC_SUNXI
++extern const struct plat_stmmacenet_data sun7i_gmac_data;
++#endif
+ extern struct platform_driver stmmac_pltfr_driver;
+ static inline int stmmac_register_platform(void)
+ {
+diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_platform.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_platform.c
+index df3fd1c..6cf8292 100644
+--- a/drivers/net/ethernet/stmicro/stmmac/stmmac_platform.c
++++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_platform.c
+@@ -35,6 +35,9 @@
+       { .compatible = "snps,dwmac-3.70a"},
+       { .compatible = "snps,dwmac-3.710"},
+       { .compatible = "snps,dwmac"},
++#ifdef CONFIG_DWMAC_SUNXI
++      { .compatible = "allwinner,sun7i-gmac", .data = &sun7i_gmac_data},
++#endif
+       { /* sentinel */ }
+ };
+ MODULE_DEVICE_TABLE(of, stmmac_dt_ids);
+-- 
+1.8.5.1
+
diff --git a/target/linux/sunxi/patches-3.13/194-dt-sun7i-add-gmac-ctrler.patch b/target/linux/sunxi/patches-3.13/194-dt-sun7i-add-gmac-ctrler.patch
new file mode 100644 (file)
index 0000000..894378b
--- /dev/null
@@ -0,0 +1,38 @@
+From a07eeb627d300da0dee8cb39b59173332be8e4bb Mon Sep 17 00:00:00 2001
+From: Chen-Yu Tsai <wens@csie.org>
+Date: Sat, 7 Dec 2013 01:29:38 +0800
+Subject: [PATCH] ARM: dts: sun7i: Add GMAC controller node to sun7i DTSI
+
+Signed-off-by: Chen-Yu Tsai <wens@csie.org>
+---
+ arch/arm/boot/dts/sun7i-a20.dtsi | 14 ++++++++++++++
+ 1 file changed, 14 insertions(+)
+
+diff --git a/arch/arm/boot/dts/sun7i-a20.dtsi b/arch/arm/boot/dts/sun7i-a20.dtsi
+index 0c1d363..82be552 100644
+--- a/arch/arm/boot/dts/sun7i-a20.dtsi
++++ b/arch/arm/boot/dts/sun7i-a20.dtsi
+@@ -571,6 +571,20 @@
+                       status = "disabled";
+               };
++              gmac: ethernet@01c50000 {
++                      compatible = "allwinner,sun7i-gmac", "snps,dwmac";
++                      reg = <0x01c50000 0x10000>,
++                            <0x01c20164 0x4>;
++                      interrupts = <0 85 1>;
++                      interrupt-names = "macirq";
++                      clocks = <&ahb_gates 49>;
++                      clock-names = "stmmaceth";
++                      snps,pbl = <2>;
++                      snps,fixed-burst;
++                      snps,force_sf_dma_mode;
++                      status = "disabled";
++              };
++
+               hstimer@01c60000 {
+                       compatible = "allwinner,sun7i-a20-hstimer";
+                       reg = <0x01c60000 0x1000>;
+-- 
+1.8.5.1
+
diff --git a/target/linux/sunxi/patches-3.13/195-dt-sun7i-add-gmac-pinmuxing.patch b/target/linux/sunxi/patches-3.13/195-dt-sun7i-add-gmac-pinmuxing.patch
new file mode 100644 (file)
index 0000000..5d66055
--- /dev/null
@@ -0,0 +1,49 @@
+From 777ba9f88e1a566a6ed26fe1e8dfff4b8c1448fc Mon Sep 17 00:00:00 2001
+From: Chen-Yu Tsai <wens@csie.org>
+Date: Sat, 7 Dec 2013 01:29:39 +0800
+Subject: [PATCH] ARM: dts: sun7i: Add pin muxing options for the GMAC
+
+The A20 has EMAC and GMAC muxed on the same pins.
+Add pin sets with gmac function for MII and RGMII mode to the DTSI.
+
+Signed-off-by: Chen-Yu Tsai <wens@csie.org>
+---
+ arch/arm/boot/dts/sun7i-a20.dtsi | 22 ++++++++++++++++++++++
+ 1 file changed, 22 insertions(+)
+
+diff --git a/arch/arm/boot/dts/sun7i-a20.dtsi b/arch/arm/boot/dts/sun7i-a20.dtsi
+index 82be552..a0d6ef7 100644
+--- a/arch/arm/boot/dts/sun7i-a20.dtsi
++++ b/arch/arm/boot/dts/sun7i-a20.dtsi
+@@ -403,6 +403,28 @@
+                               allwinner,pull = <0>;
+                       };
++                      gmac_pins_mii: gmac_mii {
++                              allwinner,pins = "PA0", "PA1", "PA2",
++                                              "PA3", "PA4", "PA5", "PA6",
++                                              "PA7", "PA8", "PA9", "PA10",
++                                              "PA11", "PA12", "PA13", "PA14",
++                                              "PA15", "PA16";
++                              allwinner,function = "gmac";
++                              allwinner,drive = <3>;
++                              allwinner,pull = <0>;
++                      };
++
++                      gmac_pins_rgmii: gmac_rgmii {
++                              allwinner,pins = "PA0", "PA1", "PA2",
++                                              "PA3", "PA4", "PA5", "PA6",
++                                              "PA7", "PA8", "PA10",
++                                              "PA11", "PA12", "PA13",
++                                              "PA15", "PA16";
++                              allwinner,function = "gmac";
++                              allwinner,drive = <3>;
++                              allwinner,pull = <0>;
++                      };
++
+                       mmc0_pins_a: mmc0@0 {
+                               allwinner,pins = "PF0","PF1","PF2","PF3","PF4","PF5";
+                               allwinner,function = "mmc0";
+-- 
+1.8.5.1
+
diff --git a/target/linux/sunxi/patches-3.13/196-1-dt-sun7i-enable-gmac-cubietruck.patch b/target/linux/sunxi/patches-3.13/196-1-dt-sun7i-enable-gmac-cubietruck.patch
new file mode 100644 (file)
index 0000000..f547e66
--- /dev/null
@@ -0,0 +1,34 @@
+From a94741174cdc6bd29c56c5aa1a225ac6e7f4ebde Mon Sep 17 00:00:00 2001
+From: Chen-Yu Tsai <wens@csie.org>
+Date: Sat, 7 Dec 2013 01:29:40 +0800
+Subject: [PATCH] ARM: dts: sun7i: cubietruck: Enable the GMAC
+
+The CubieTruck uses the GMAC with an RGMII phy.
+
+Signed-off-by: Chen-Yu Tsai <wens@csie.org>
+---
+ arch/arm/boot/dts/sun7i-a20-cubietruck.dts | 8 ++++++++
+ 1 file changed, 8 insertions(+)
+
+diff --git a/arch/arm/boot/dts/sun7i-a20-cubietruck.dts b/arch/arm/boot/dts/sun7i-a20-cubietruck.dts
+index 7ee628a..2684f27 100644
+--- a/arch/arm/boot/dts/sun7i-a20-cubietruck.dts
++++ b/arch/arm/boot/dts/sun7i-a20-cubietruck.dts
+@@ -49,6 +49,14 @@
+                       pinctrl-0 = <&uart0_pins_a>;
+                       status = "okay";
+               };
++
++              gmac: ethernet@01c50000 {
++                      pinctrl-names = "default";
++                      pinctrl-0 = <&gmac_pins_rgmii>;
++                      snps,phy-addr = <1>;
++                      phy-mode = "rgmii";
++                      status = "okay";
++              };
+       };
+       leds {
+-- 
+1.8.5.1
+
diff --git a/target/linux/sunxi/patches-3.13/196-2-dt-sun7i-enable-gmac-cubieboard2.patch b/target/linux/sunxi/patches-3.13/196-2-dt-sun7i-enable-gmac-cubieboard2.patch
new file mode 100644 (file)
index 0000000..c4256a4
--- /dev/null
@@ -0,0 +1,57 @@
+From e28b63650ff934751b9fe56415dc2491a6c6b704 Mon Sep 17 00:00:00 2001
+From: Chen-Yu Tsai <wens@csie.org>
+Date: Sat, 7 Dec 2013 01:29:41 +0800
+Subject: [PATCH] ARM: dts: sun7i: cubieboard2: Enable GMAC instead of EMAC
+
+GMAC has better performance and fewer hardware issues.
+Use the GMAC in MII mode for ethernet instead of the EMAC.
+
+Signed-off-by: Chen-Yu Tsai <wens@csie.org>
+---
+ arch/arm/boot/dts/sun7i-a20-cubieboard2.dts | 23 ++++++++---------------
+ 1 file changed, 8 insertions(+), 15 deletions(-)
+
+diff --git a/arch/arm/boot/dts/sun7i-a20-cubieboard2.dts b/arch/arm/boot/dts/sun7i-a20-cubieboard2.dts
+index d28e600..48777cd 100644
+--- a/arch/arm/boot/dts/sun7i-a20-cubieboard2.dts
++++ b/arch/arm/boot/dts/sun7i-a20-cubieboard2.dts
+@@ -19,21 +19,6 @@
+       compatible = "cubietech,cubieboard2", "allwinner,sun7i-a20";
+       soc@01c00000 {
+-              emac: ethernet@01c0b000 {
+-                      pinctrl-names = "default";
+-                      pinctrl-0 = <&emac_pins_a>;
+-                      phy = <&phy1>;
+-                      status = "okay";
+-              };
+-
+-              mdio@01c0b080 {
+-                      status = "okay";
+-
+-                      phy1: ethernet-phy@1 {
+-                              reg = <1>;
+-                      };
+-              };
+-
+               mmc0: mmc@01c0f000 {
+                       pinctrl-names = "default";
+                       pinctrl-0 = <&mmc0_pins_a>;
+@@ -76,6 +61,14 @@
+                       pinctrl-0 = <&i2c1_pins_a>;
+                       status = "okay";
+               };
++
++              gmac: ethernet@01c50000 {
++                      pinctrl-names = "default";
++                      pinctrl-0 = <&gmac_pins_mii>;
++                      snps,phy-addr = <1>;
++                      phy-mode = "mii";
++                      status = "okay";
++              };
+       };
+       leds {
+-- 
+1.8.5.1
+
diff --git a/target/linux/sunxi/patches-3.13/196-3-dt-sun7i-enable-gmac-a20-micro.patch b/target/linux/sunxi/patches-3.13/196-3-dt-sun7i-enable-gmac-a20-micro.patch
new file mode 100644 (file)
index 0000000..b2aa326
--- /dev/null
@@ -0,0 +1,57 @@
+From e39d51b2236ab17628fe5d110296cd33a9c4427e Mon Sep 17 00:00:00 2001
+From: Chen-Yu Tsai <wens@csie.org>
+Date: Sat, 7 Dec 2013 01:29:42 +0800
+Subject: [PATCH] ARM: dts: sun7i: olinuxino-micro: Enable GMAC instead of EMAC
+
+GMAC has better performance and fewer hardware issues.
+Use the GMAC in MII mode for ethernet instead of the EMAC.
+
+Signed-off-by: Chen-Yu Tsai <wens@csie.org>
+---
+ arch/arm/boot/dts/sun7i-a20-olinuxino-micro.dts | 23 ++++++++---------------
+ 1 file changed, 8 insertions(+), 15 deletions(-)
+
+diff --git a/arch/arm/boot/dts/sun7i-a20-olinuxino-micro.dts b/arch/arm/boot/dts/sun7i-a20-olinuxino-micro.dts
+index d377696..bf6f6c8 100644
+--- a/arch/arm/boot/dts/sun7i-a20-olinuxino-micro.dts
++++ b/arch/arm/boot/dts/sun7i-a20-olinuxino-micro.dts
+@@ -19,21 +19,6 @@
+       compatible = "olimex,a20-olinuxino-micro", "allwinner,sun7i-a20";
+       soc@01c00000 {
+-              emac: ethernet@01c0b000 {
+-                      pinctrl-names = "default";
+-                      pinctrl-0 = <&emac_pins_a>;
+-                      phy = <&phy1>;
+-                      status = "okay";
+-              };
+-
+-              mdio@01c0b080 {
+-                      status = "okay";
+-
+-                      phy1: ethernet-phy@1 {
+-                              reg = <1>;
+-                      };
+-              };
+-
+               mmc0: mmc@01c0f000 {
+                       pinctrl-names = "default";
+                       pinctrl-0 = <&mmc0_pins_a>;
+@@ -110,6 +95,14 @@
+                       pinctrl-0 = <&i2c2_pins_a>;
+                       status = "okay";
+               };
++
++              gmac: ethernet@01c50000 {
++                      pinctrl-names = "default";
++                      pinctrl-0 = <&gmac_pins_mii>;
++                      snps,phy-addr = <1>;
++                      phy-mode = "mii";
++                      status = "okay";
++              };
+       };
+       leds {
+-- 
+1.8.5.1
+
diff --git a/target/linux/sunxi/patches-3.13/200-sun5i-timer-add-support-for-reset-ctrler.patch b/target/linux/sunxi/patches-3.13/200-sun5i-timer-add-support-for-reset-ctrler.patch
new file mode 100644 (file)
index 0000000..c13d991
--- /dev/null
@@ -0,0 +1,69 @@
+From 99489f45debd07f6e1cfa36f5c9890409714518d Mon Sep 17 00:00:00 2001
+From: Maxime Ripard <maxime.ripard@free-electrons.com>
+Date: Fri, 20 Dec 2013 22:41:08 +0100
+Subject: [PATCH] clocksource: sun5i: Add support for reset controller
+
+The Allwinner A31 that uses this timer has the timer IP asserted in reset.
+Add an optional reset property to the DT, and deassert the timer from reset if
+it's there.
+
+Signed-off-by: Maxime Ripard <maxime.ripard@free-electrons.com>
+---
+ .../devicetree/bindings/timer/allwinner,sun5i-a13-hstimer.txt       | 4 ++++
+ drivers/clocksource/timer-sun5i.c                                   | 6 ++++++
+ 2 files changed, 10 insertions(+)
+
+diff --git a/Documentation/devicetree/bindings/timer/allwinner,sun5i-a13-hstimer.txt b/Documentation/devicetree/bindings/timer/allwinner,sun5i-a13-hstimer.txt
+index 7c26154..27cfc7d 100644
+--- a/Documentation/devicetree/bindings/timer/allwinner,sun5i-a13-hstimer.txt
++++ b/Documentation/devicetree/bindings/timer/allwinner,sun5i-a13-hstimer.txt
+@@ -9,6 +9,9 @@ Required properties:
+               one)
+ - clocks: phandle to the source clock (usually the AHB clock)
++Optionnal properties:
++- resets: phandle to a reset controller asserting the timer
++
+ Example:
+ timer@01c60000 {
+@@ -19,4 +22,5 @@ timer@01c60000 {
+                    <0 53 1>,
+                    <0 54 1>;
+       clocks = <&ahb1_gates 19>;
++      resets = <&ahb1rst 19>;
+ };
+diff --git a/drivers/clocksource/timer-sun5i.c b/drivers/clocksource/timer-sun5i.c
+index bddc522..f74d75e 100644
+--- a/drivers/clocksource/timer-sun5i.c
++++ b/drivers/clocksource/timer-sun5i.c
+@@ -16,6 +16,7 @@
+ #include <linux/interrupt.h>
+ #include <linux/irq.h>
+ #include <linux/irqreturn.h>
++#include <linux/reset.h>
+ #include <linux/sched_clock.h>
+ #include <linux/of.h>
+ #include <linux/of_address.h>
+@@ -143,6 +144,7 @@ static u32 sun5i_timer_sched_read(void)
+ static void __init sun5i_timer_init(struct device_node *node)
+ {
++      struct reset_control *rstc;
+       unsigned long rate;
+       struct clk *clk;
+       int ret, irq;
+@@ -162,6 +164,10 @@ static void __init sun5i_timer_init(struct device_node *node)
+       clk_prepare_enable(clk);
+       rate = clk_get_rate(clk);
++      rstc = of_reset_control_get(node, NULL);
++      if (!IS_ERR(rstc))
++              reset_control_deassert(rstc);
++
+       writel(~0, timer_base + TIMER_INTVAL_LO_REG(1));
+       writel(TIMER_CTL_ENABLE | TIMER_CTL_RELOAD,
+              timer_base + TIMER_CTL_REG(1));
+-- 
+1.8.5.1
+
diff --git a/target/linux/sunxi/patches-3.13/201-reset-add-of_reset_control_get.patch b/target/linux/sunxi/patches-3.13/201-reset-add-of_reset_control_get.patch
new file mode 100644 (file)
index 0000000..73ecca1
--- /dev/null
@@ -0,0 +1,119 @@
+From 0325b48d6149e131c90ed6ec77458f4d2df73898 Mon Sep 17 00:00:00 2001
+From: Maxime Ripard <maxime.ripard@free-electrons.com>
+Date: Fri, 20 Dec 2013 22:41:07 +0100
+Subject: [PATCH] reset: Add of_reset_control_get
+
+In some cases, you might need to deassert from reset an hardware block that
+doesn't associated to a struct device (CPUs, timers, etc.).
+
+Add a small helper to retrieve the reset controller from the device tree
+without the need to pass a struct device.
+
+Signed-off-by: Maxime Ripard <maxime.ripard@free-electrons.com>
+---
+ drivers/reset/core.c  | 39 ++++++++++++++++++++++++++++++---------
+ include/linux/reset.h |  4 ++++
+ 2 files changed, 34 insertions(+), 9 deletions(-)
+
+diff --git a/drivers/reset/core.c b/drivers/reset/core.c
+index d1b6089..4f3dda7 100644
+--- a/drivers/reset/core.c
++++ b/drivers/reset/core.c
+@@ -127,15 +127,16 @@ int reset_control_deassert(struct reset_control *rstc)
+ EXPORT_SYMBOL_GPL(reset_control_deassert);
+ /**
+- * reset_control_get - Lookup and obtain a reference to a reset controller.
+- * @dev: device to be reset by the controller
++ * 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 *reset_control_get(struct device *dev, const char *id)
++struct reset_control *of_reset_control_get(struct device_node *node,
++                                         const char *id)
+ {
+       struct reset_control *rstc = ERR_PTR(-EPROBE_DEFER);
+       struct reset_controller_dev *r, *rcdev;
+@@ -144,13 +145,10 @@ struct reset_control *reset_control_get(struct device *dev, const char *id)
+       int rstc_id;
+       int ret;
+-      if (!dev)
+-              return ERR_PTR(-EINVAL);
+-
+       if (id)
+-              index = of_property_match_string(dev->of_node,
++              index = of_property_match_string(node,
+                                                "reset-names", id);
+-      ret = of_parse_phandle_with_args(dev->of_node, "resets", "#reset-cells",
++      ret = of_parse_phandle_with_args(node, "resets", "#reset-cells",
+                                        index, &args);
+       if (ret)
+               return ERR_PTR(ret);
+@@ -185,12 +183,35 @@ struct reset_control *reset_control_get(struct device *dev, const char *id)
+               return ERR_PTR(-ENOMEM);
+       }
+-      rstc->dev = dev;
+       rstc->rcdev = rcdev;
+       rstc->id = rstc_id;
+       return rstc;
+ }
++EXPORT_SYMBOL_GPL(of_reset_control_get);
++
++/**
++ * reset_control_get - Lookup and obtain a reference to a reset controller.
++ * @dev: 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 *reset_control_get(struct device *dev, const char *id)
++{
++      struct reset_control *rstc;
++
++      if (!dev)
++              return ERR_PTR(-EINVAL);
++
++      rstc = of_reset_control_get(dev->of_node, id);
++      if (!IS_ERR(rstc))
++              rstc->dev = dev;
++
++      return rstc;
++}
+ EXPORT_SYMBOL_GPL(reset_control_get);
+ /**
+diff --git a/include/linux/reset.h b/include/linux/reset.h
+index 6082247..a398025 100644
+--- a/include/linux/reset.h
++++ b/include/linux/reset.h
+@@ -1,6 +1,8 @@
+ #ifndef _LINUX_RESET_H_
+ #define _LINUX_RESET_H_
++#include <linux/of.h>
++
+ struct device;
+ struct reset_control;
+@@ -8,6 +10,8 @@
+ int reset_control_assert(struct reset_control *rstc);
+ int reset_control_deassert(struct reset_control *rstc);
++struct reset_control *of_reset_control_get(struct device_node *node,
++                                         const char *id);
+ struct reset_control *reset_control_get(struct device *dev, const char *id);
+ void reset_control_put(struct reset_control *rstc);
+ struct reset_control *devm_reset_control_get(struct device *dev, const char *id);
+-- 
+1.8.5.1
+
diff --git a/target/linux/sunxi/patches-3.13/210-clk-sunxi-add-a20-output-clk.patch b/target/linux/sunxi/patches-3.13/210-clk-sunxi-add-a20-output-clk.patch
new file mode 100644 (file)
index 0000000..5b46d8b
--- /dev/null
@@ -0,0 +1,119 @@
+From 5ca9eadcb5f5cd9af6f1650029ad64052a1a0b10 Mon Sep 17 00:00:00 2001
+From: Chen-Yu Tsai <wens@csie.org>
+Date: Tue, 24 Dec 2013 21:26:17 +0800
+Subject: [PATCH] clk: sunxi: Allwinner A20 output clock support
+
+This patch adds support for the external clock outputs on the
+Allwinner A20 SoC. The clock outputs are similar to "module 0"
+type clocks, with different offsets and widths for clock factors.
+
+Signed-off-by: Chen-Yu Tsai <wens@csie.org>
+---
+ Documentation/devicetree/bindings/clock/sunxi.txt |  1 +
+ drivers/clk/sunxi/clk-sunxi.c                     | 57 +++++++++++++++++++++++
+ 2 files changed, 58 insertions(+)
+
+diff --git a/Documentation/devicetree/bindings/clock/sunxi.txt b/Documentation/devicetree/bindings/clock/sunxi.txt
+index 941bd93..79c7197 100644
+--- a/Documentation/devicetree/bindings/clock/sunxi.txt
++++ b/Documentation/devicetree/bindings/clock/sunxi.txt
+@@ -36,6 +36,7 @@ Required properties:
+       "allwinner,sun6i-a31-apb2-div-clk" - for the APB2 gates on A31
+       "allwinner,sun6i-a31-apb2-gates-clk" - for the APB2 gates on A31
+       "allwinner,sun4i-mod0-clk" - for the module 0 family of clocks
++      "allwinner,sun7i-a20-out-clk" - for the external output clocks
+ Required properties for all clocks:
+ - reg : shall be the control register address for the clock.
+diff --git a/drivers/clk/sunxi/clk-sunxi.c b/drivers/clk/sunxi/clk-sunxi.c
+index 8a07a68..df1f385 100644
+--- a/drivers/clk/sunxi/clk-sunxi.c
++++ b/drivers/clk/sunxi/clk-sunxi.c
+@@ -396,6 +396,47 @@ void clk_sunxi_mmc_phase_control(struct clk_hw *hw, u8 sample, u8 output)
+ /**
++ * sun7i_a20_get_out_factors() - calculates m, p factors for CLK_OUT_A/B
++ * CLK_OUT rate is calculated as follows
++ * rate = (parent_rate >> p) / (m + 1);
++ */
++
++static void sun7i_a20_get_out_factors(u32 *freq, u32 parent_rate,
++                                    u8 *n, u8 *k, u8 *m, u8 *p)
++{
++      u8 div, calcm, calcp;
++
++      /* These clocks can only divide, so we will never be able to achieve
++       * frequencies higher than the parent frequency */
++      if (*freq > parent_rate)
++              *freq = parent_rate;
++
++      div = parent_rate / *freq;
++
++      if (div < 32)
++              calcp = 0;
++      else if (div / 2 < 32)
++              calcp = 1;
++      else if (div / 4 < 32)
++              calcp = 2;
++      else
++              calcp = 3;
++
++      calcm = DIV_ROUND_UP(div, 1 << calcp);
++
++      *freq = (parent_rate >> calcp) / calcm;
++
++      /* we were called to round the frequency, we can now return */
++      if (n == NULL)
++              return;
++
++      *m = calcm - 1;
++      *p = calcp;
++}
++
++
++
++/**
+  * sunxi_factors_clk_setup() - Setup function for factor clocks
+  */
+@@ -455,6 +496,14 @@ struct factors_data {
+       .pwidth = 2,
+ };
++/* user manual says "n" but it's really "p" */
++static struct clk_factors_config sun7i_a20_out_config = {
++      .mshift = 8,
++      .mwidth = 5,
++      .pshift = 20,
++      .pwidth = 2,
++};
++
+ static const struct factors_data sun4i_pll1_data __initconst = {
+       .enable = 31,
+       .table = &sun4i_pll1_config,
+@@ -492,6 +541,13 @@ struct factors_data {
+       .getter = sun4i_get_mod0_factors,
+ };
++static const struct factors_data sun7i_a20_out_data __initconst = {
++      .enable = 31,
++      .mux = 24,
++      .table = &sun7i_a20_out_config,
++      .getter = sun7i_a20_get_out_factors,
++};
++
+ static struct clk * __init sunxi_factors_clk_setup(struct device_node *node,
+                                               const struct factors_data *data)
+ {
+@@ -995,6 +1051,7 @@ static void __init sunxi_divs_clk_setup(struct device_node *node,
+       {.compatible = "allwinner,sun5i-a13-ahb-clk", .data = &sun5i_a13_ahb_data,},
+       {.compatible = "allwinner,sun4i-apb1-clk", .data = &sun4i_apb1_data,},
+       {.compatible = "allwinner,sun4i-mod0-clk", .data = &sun4i_mod0_data,},
++      {.compatible = "allwinner,sun7i-a20-out-clk", .data = &sun7i_a20_out_data,},
+       {}
+ };
+-- 
+1.8.5.1
+
diff --git a/target/linux/sunxi/patches-3.13/211-dt-sun7i-add-external-clk-output.patch b/target/linux/sunxi/patches-3.13/211-dt-sun7i-add-external-clk-output.patch
new file mode 100644 (file)
index 0000000..ac7cd6a
--- /dev/null
@@ -0,0 +1,56 @@
+From 6dd612e3d7e0c76f863efaddae4738fadc461f72 Mon Sep 17 00:00:00 2001
+From: Chen-Yu Tsai <wens@csie.org>
+Date: Tue, 24 Dec 2013 21:26:18 +0800
+Subject: [PATCH] ARM: dts: sun7i: external clock outputs
+
+This commit adds the two external clock outputs available on A20 to
+its device tree. A dummy fixed factor clock is also added to serve as
+the first input of the clock outputs, which according to AW's A20 user
+manual, is the 24MHz oscillator divided by 750.
+
+Signed-off-by: Chen-Yu Tsai <wens@csie.org>
+---
+ arch/arm/boot/dts/sun7i-a20.dtsi | 27 +++++++++++++++++++++++++++
+ 1 file changed, 27 insertions(+)
+
+diff --git a/arch/arm/boot/dts/sun7i-a20.dtsi b/arch/arm/boot/dts/sun7i-a20.dtsi
+index 2e19c47..858e0710 100644
+--- a/arch/arm/boot/dts/sun7i-a20.dtsi
++++ b/arch/arm/boot/dts/sun7i-a20.dtsi
+@@ -305,6 +305,33 @@
+                       clocks = <&osc24M>, <&pll6 2>, <&pll5 1>;
+                       clock-output-names = "mbus";
+               };
++
++              /*
++               * Dummy clock used by output clocks
++               */
++              osc24M_32k: osc24M_32k {
++                      #clock-cells = <0>;
++                      compatible = "fixed-factor-clock";
++                      clock-div = <750>;
++                      clock-mult = <1>;
++                      clocks = <&osc24M>;
++              };
++
++              clk_out_a: clk@01c201f0 {
++                      #clock-cells = <0>;
++                      compatible = "allwinner,sun7i-a20-out-clk";
++                      reg = <0x01c201f0 0x4>;
++                      clocks = <&osc24M_32k>, <&osc32k>, <&osc24M>;
++                      clock-output-names = "clk_out_a";
++              };
++
++              clk_out_b: clk@01c201f4 {
++                      #clock-cells = <0>;
++                      compatible = "allwinner,sun7i-a20-out-clk";
++                      reg = <0x01c201f4 0x4>;
++                      clocks = <&osc24M_32k>, <&osc32k>, <&osc24M>;
++                      clock-output-names = "clk_out_b";
++              };
+       };
+       timer {
+-- 
+1.8.5.1
+
diff --git a/target/linux/sunxi/patches-3.13/212-pinctrl-sunxi-add-a20-output-clkpin-funcs.patch b/target/linux/sunxi/patches-3.13/212-pinctrl-sunxi-add-a20-output-clkpin-funcs.patch
new file mode 100644 (file)
index 0000000..299d89f
--- /dev/null
@@ -0,0 +1,37 @@
+From 271a35ef6237c3b775aad357969dc75ae5b56988 Mon Sep 17 00:00:00 2001
+From: Chen-Yu Tsai <wens@csie.org>
+Date: Tue, 24 Dec 2013 21:26:19 +0800
+Subject: [PATCH] pinctrl: sunxi: Add Allwinner A20 clock output pin functions
+
+This patch adds the clock output pin functions on the A20.
+The 2 pins can output a configurable clock to be used by
+external modules. This is used on the CubieTruck, to supply
+a 32768 Hz low power clock to the onboard Wifi+BT module.
+
+Signed-off-by: Chen-Yu Tsai <wens@csie.org>
+---
+ drivers/pinctrl/pinctrl-sunxi-pins.h | 2 ++
+ 1 file changed, 2 insertions(+)
+
+diff --git a/drivers/pinctrl/pinctrl-sunxi-pins.h b/drivers/pinctrl/pinctrl-sunxi-pins.h
+index 7c1b05e..3d60669 100644
+--- a/drivers/pinctrl/pinctrl-sunxi-pins.h
++++ b/drivers/pinctrl/pinctrl-sunxi-pins.h
+@@ -3774,12 +3774,14 @@
+                 SUNXI_FUNCTION(0x1, "gpio_out"),
+                 SUNXI_FUNCTION(0x2, "spi0"),          /* MOSI */
+                 SUNXI_FUNCTION(0x3, "uart6"),         /* TX */
++                SUNXI_FUNCTION(0x4, "clk_out_a"),     /* CLK_OUT_A */
+                 SUNXI_FUNCTION_IRQ(0x5, 24)),         /* EINT24 */
+       SUNXI_PIN(SUNXI_PINCTRL_PIN_PI13,
+                 SUNXI_FUNCTION(0x0, "gpio_in"),
+                 SUNXI_FUNCTION(0x1, "gpio_out"),
+                 SUNXI_FUNCTION(0x2, "spi0"),          /* MISO */
+                 SUNXI_FUNCTION(0x3, "uart6"),         /* RX */
++                SUNXI_FUNCTION(0x4, "clk_out_b"),     /* CLK_OUT_B */
+                 SUNXI_FUNCTION_IRQ(0x5, 25)),         /* EINT25 */
+       SUNXI_PIN(SUNXI_PINCTRL_PIN_PI14,
+                 SUNXI_FUNCTION(0x0, "gpio_in"),
+-- 
+1.8.5.1
+
diff --git a/target/linux/sunxi/patches-3.13/213-dt-sun7i-add-external-clk-outputs.patch b/target/linux/sunxi/patches-3.13/213-dt-sun7i-add-external-clk-outputs.patch
new file mode 100644 (file)
index 0000000..bc9694b
--- /dev/null
@@ -0,0 +1,43 @@
+From f3a50c26f33a4627e5d3e35f80db3f22a5375237 Mon Sep 17 00:00:00 2001
+From: Chen-Yu Tsai <wens@csie.org>
+Date: Tue, 24 Dec 2013 21:26:20 +0800
+Subject: [PATCH] ARM: dts: sun7i: Add pin muxing options for clock outputs
+
+This patch adds the clock output pin options on the A20.
+The 2 pins can output a configurable clock to be used by
+external modules. This is used on the CubieTruck, to supply
+a 32768 Hz low power clock to the onboard Wifi+BT module.
+
+Signed-off-by: Chen-Yu Tsai <wens@csie.org>
+---
+ arch/arm/boot/dts/sun7i-a20.dtsi | 14 ++++++++++++++
+ 1 file changed, 14 insertions(+)
+
+diff --git a/arch/arm/boot/dts/sun7i-a20.dtsi b/arch/arm/boot/dts/sun7i-a20.dtsi
+index 858e0710..bd52041 100644
+--- a/arch/arm/boot/dts/sun7i-a20.dtsi
++++ b/arch/arm/boot/dts/sun7i-a20.dtsi
+@@ -483,6 +483,20 @@
+                               allwinner,drive = <3>;
+                               allwinner,pull = <0>;
+                       };
++
++                      clk_out_a_pins: clk_out_a@0 {
++                              allwinner,pins = "PI12";
++                              allwinner,function = "clk_out_a";
++                              allwinner,drive = <0>;
++                              allwinner,pull = <0>;
++                      };
++
++                      clk_out_b_pins: clk_out_b@0 {
++                              allwinner,pins = "PI13";
++                              allwinner,function = "clk_out_b";
++                              allwinner,drive = <0>;
++                              allwinner,pull = <0>;
++                      };
+               };
+               sata: ahci@01c18000 {
+-- 
+1.8.5.1
+
diff --git a/target/linux/sunxi/patches-3.13/230-dt-add-pcduino.patch b/target/linux/sunxi/patches-3.13/230-dt-add-pcduino.patch
new file mode 100644 (file)
index 0000000..91c633c
--- /dev/null
@@ -0,0 +1,11 @@
+diff -ruN old/arch/arm/boot/dts/Makefile new/arch/arm/boot/dts/Makefile
+--- old/arch/arm/boot/dts/Makefile     2014-01-02 22:08:07.288255421 +0100
++++ new/arch/arm/boot/dts/Makefile     2014-01-02 21:25:02.000000000 +0100
+@@ -231,6 +231,7 @@
+       sun4i-a10-cubieboard.dtb \
+       sun4i-a10-mini-xplus.dtb \
+       sun4i-a10-hackberry.dtb \
++      sun4i-a10-pcduino.dtb \
+       sun5i-a10s-olinuxino-micro.dtb \
+       sun5i-a13-olinuxino.dtb \
+       sun6i-a31-colombus.dtb \
diff --git a/target/linux/sunxi/patches-3.13/231-dt-add-a10-olinuxino-lime.patch b/target/linux/sunxi/patches-3.13/231-dt-add-a10-olinuxino-lime.patch
new file mode 100644 (file)
index 0000000..1c7a15c
--- /dev/null
@@ -0,0 +1,12 @@
+Index: linux-3.12.5/arch/arm/boot/dts/Makefile
+===================================================================
+--- linux-3.12.5.orig/arch/arm/boot/dts/Makefile       2014-01-07 20:20:35.112013217 +0100
++++ linux-3.12.5/arch/arm/boot/dts/Makefile    2014-01-07 20:20:35.124013454 +0100
+@@ -232,6 +232,7 @@
+       sun4i-a10-mini-xplus.dtb \
+       sun4i-a10-hackberry.dtb \
+       sun4i-a10-pcduino.dtb \
++      sun4i-a10-olinuxino-lime.dtb \
+       sun5i-a10s-olinuxino-micro.dtb \
+       sun5i-a13-olinuxino.dtb \
+       sun5i-a13-olinuxino-micro.dtb \
diff --git a/target/linux/sunxi/patches-3.13/232-dt-pcduino-update-mmc-entry.patch b/target/linux/sunxi/patches-3.13/232-dt-pcduino-update-mmc-entry.patch
new file mode 100644 (file)
index 0000000..53c3ebd
--- /dev/null
@@ -0,0 +1,15 @@
+diff -ruN old/arch/arm/boot/dts/sun4i-a10-pcduino.dts new/arch/arm/boot/dts/sun4i-a10-pcduino.dts
+--- old/arch/arm/boot/dts/sun4i-a10-pcduino.dts        2014-01-22 23:41:25.000000000 +0100
++++ new/arch/arm/boot/dts/sun4i-a10-pcduino.dts        2014-01-28 01:08:52.787630026 +0100
+@@ -42,9 +42,9 @@
+                       };
+               };
+-              sdc0: sdc@01c0f000 {
++              mmc0: mmc@01c0f000 {
+                         pinctrl-names = "default";
+-                        pinctrl-0 = <&sdc0_pins_a>;
++                        pinctrl-0 = <&mmc0_pins_a>;
+                         pinctrl-1 = <&mmc0_cd_pin_pcduino>;
+                         cd-gpios = <&pio 7 1 0>; /* PH1 */
+                         cd-mode = <1>;
diff --git a/target/linux/sunxi/patches-3.13/233-dt-lime-update-mmc-entry.patch b/target/linux/sunxi/patches-3.13/233-dt-lime-update-mmc-entry.patch
new file mode 100644 (file)
index 0000000..d6c2d40
--- /dev/null
@@ -0,0 +1,15 @@
+diff -ruN old/arch/arm/boot/dts/sun4i-a10-olinuxino-lime.dts new/arch/arm/boot/dts/sun4i-a10-olinuxino-lime.dts
+--- old/arch/arm/boot/dts/sun4i-a10-olinuxino-lime.dts 2014-01-22 23:41:25.000000000 +0100
++++ new/arch/arm/boot/dts/sun4i-a10-olinuxino-lime.dts 2014-01-28 01:23:50.083617987 +0100
+@@ -33,9 +33,9 @@
+                       };
+               };
+-              sdc0: sdc@01c0f000 {
++              mmc0: mmc@01c0f000 {
+                       pinctrl-names = "default";
+-                      pinctrl-0 = <&sdc0_pins_a>;
++                      pinctrl-0 = <&mmc0_pins_a>;
+                       pinctrl-1 = <&mmc0_cd_pin_olinuxino>;
+                       cd-gpios = <&pio 7 1 0>; /* PH1 */
+                       cd-mode = <1>;
diff --git a/target/linux/sunxi/patches-3.13/234-dt-cubietruck-update-mmc-entry.patch b/target/linux/sunxi/patches-3.13/234-dt-cubietruck-update-mmc-entry.patch
new file mode 100644 (file)
index 0000000..1fe1a5a
--- /dev/null
@@ -0,0 +1,15 @@
+diff -ruN old/arch/arm/boot/dts/sun7i-a20-cubietruck.dts new/arch/arm/boot/dts/sun7i-a20-cubietruck.dts
+--- old/arch/arm/boot/dts/sun7i-a20-cubietruck.dts     2014-01-31 18:02:42.000000000 +0100
++++ new/arch/arm/boot/dts/sun7i-a20-cubietruck.dts     2014-01-31 18:07:13.719332547 +0100
+@@ -19,9 +19,9 @@
+       compatible = "cubietech,cubietruck", "allwinner,sun7i-a20";
+       soc@01c00000 {
+-              sdc0: sdc@01c0f000 {
++              mmc0: mmc@01c0f000 {
+                       pinctrl-names = "default";
+-                      pinctrl-0 = <&sdc0_pins_a>;
++                      pinctrl-0 = <&mmc0_pins_a>;
+                       pinctrl-1 = <&mmc0_cd_pin_cubietruck>;
+                       cd-gpios = <&pio 7 1 0>; /* PH1 */
+                       cd-mode = <1>;