ralink: add 3.14 support
authorJohn Crispin <john@openwrt.org>
Thu, 7 Aug 2014 14:41:19 +0000 (14:41 +0000)
committerJohn Crispin <john@openwrt.org>
Thu, 7 Aug 2014 14:41:19 +0000 (14:41 +0000)
Signed-off-by: John Crispin <blogic@openwrt.org>
SVN-Revision: 42040

66 files changed:
target/linux/ramips/mt7620a/config-3.14 [new file with mode: 0644]
target/linux/ramips/mt7620n/config-3.14 [new file with mode: 0644]
target/linux/ramips/mt7621/config-3.14 [new file with mode: 0644]
target/linux/ramips/patches-3.14/0001-MIPS-ralink-add-verbose-pmu-info.patch [new file with mode: 0644]
target/linux/ramips/patches-3.14/0002-MIPS-ralink-add-a-helper-for-reading-the-ECO-version.patch [new file with mode: 0644]
target/linux/ramips/patches-3.14/0003-MIPS-ralink-add-rt_sysc_m32-helper.patch [new file with mode: 0644]
target/linux/ramips/patches-3.14/0004-MIPS-ralink-adds-a-bootrom-dumper-module.patch [new file with mode: 0644]
target/linux/ramips/patches-3.14/0005-MIPS-ralink-add-illegal-access-driver.patch [new file with mode: 0644]
target/linux/ramips/patches-3.14/0006-MIPS-ralink-add-missing-clk_set_rate-to-clk.c.patch [new file with mode: 0644]
target/linux/ramips/patches-3.14/0007-MIPS-ralink-add-support-for-MT7620n.patch [new file with mode: 0644]
target/linux/ramips/patches-3.14/0008-MIPS-ralink-allow-manual-memory-override.patch [new file with mode: 0644]
target/linux/ramips/patches-3.14/0009-MIPS-ralink-define-the-wmac-clock-on-mt7620.patch [new file with mode: 0644]
target/linux/ramips/patches-3.14/0010-MIPS-ralink-define-the-wmac-clock-on-rt3883.patch [new file with mode: 0644]
target/linux/ramips/patches-3.14/0011-MIPS-ralink-add-rt2880-wmac-clock.patch [new file with mode: 0644]
target/linux/ramips/patches-3.14/0012-MIPS-ralink-add-MT7621-support.patch [new file with mode: 0644]
target/linux/ramips/patches-3.14/0013-MIPS-ralink-add-MT7621-defconfig.patch [new file with mode: 0644]
target/linux/ramips/patches-3.14/0014-MIPS-ralink-add-MT7621-dts-file.patch [new file with mode: 0644]
target/linux/ramips/patches-3.14/0015-MIPS-ralink-cleanup-early_printk.patch [new file with mode: 0644]
target/linux/ramips/patches-3.14/0016-MIPS-ralink-add-MT7621-pcie-driver.patch [new file with mode: 0644]
target/linux/ramips/patches-3.14/0017-MIPS-use-set_mode-to-enable-disable-the-cevt-r4k-irq.patch [new file with mode: 0644]
target/linux/ramips/patches-3.14/0018-MIPS-ralink-workaround-DTB-memory-issue.patch [new file with mode: 0644]
target/linux/ramips/patches-3.14/0019-MIPS-ralink-add-pseudo-pwm-led-trigger-based-on-time.patch [new file with mode: 0644]
target/linux/ramips/patches-3.14/0020-MIPS-ralink-update-dts-files.patch [new file with mode: 0644]
target/linux/ramips/patches-3.14/0021-MIPS-ralink-add-cpu-frequency-scaling.patch [new file with mode: 0644]
target/linux/ramips/patches-3.14/0022-MIPS-ralink-copy-the-commandline-from-the-devicetree.patch [new file with mode: 0644]
target/linux/ramips/patches-3.14/0023-MIPS-ralink-mt7620-fix-usb-issue-during-frequency-sc.patch [new file with mode: 0644]
target/linux/ramips/patches-3.14/0024-MIPS-ralink-add-mt7628an-devicetree-files.patch [new file with mode: 0644]
target/linux/ramips/patches-3.14/0025-MIPS-ralink-allow-loading-irq-registers-from-the-dev.patch [new file with mode: 0644]
target/linux/ramips/patches-3.14/0026-MIPS-ralink-add-mt7628an-support.patch [new file with mode: 0644]
target/linux/ramips/patches-3.14/0027-serial-ralink-adds-mt7620-serial.patch [new file with mode: 0644]
target/linux/ramips/patches-3.14/0028-serial-ralink-the-core-has-a-size-of-0x100-and-not-0.patch [new file with mode: 0644]
target/linux/ramips/patches-3.14/0029-serial-of-allow-au1x00-and-rt288x-to-load-from-OF.patch [new file with mode: 0644]
target/linux/ramips/patches-3.14/0030-pinctrl-ralink-add-pinctrl-driver.patch [new file with mode: 0644]
target/linux/ramips/patches-3.14/0031-PCI-MIPS-adds-rt2880-pci-support.patch [new file with mode: 0644]
target/linux/ramips/patches-3.14/0032-PCI-MIPS-adds-mt7620a-pcie-driver.patch [new file with mode: 0644]
target/linux/ramips/patches-3.14/0033-NET-multi-phy-support.patch [new file with mode: 0644]
target/linux/ramips/patches-3.14/0034-NET-add-of_get_mac_address_mtd.patch [new file with mode: 0644]
target/linux/ramips/patches-3.14/0035-NET-MIPS-add-ralink-SoC-ethernet-driver.patch [new file with mode: 0644]
target/linux/ramips/patches-3.14/0036-NET-add-mt7621-ethernet-driver.patch [new file with mode: 0644]
target/linux/ramips/patches-3.14/0037-USB-phy-add-ralink-SoC-driver.patch [new file with mode: 0644]
target/linux/ramips/patches-3.14/0038-USB-add-OHCI-EHCI-OF-binding.patch [new file with mode: 0644]
target/linux/ramips/patches-3.14/0039-USB-adds-dwc_otg.patch [new file with mode: 0644]
target/linux/ramips/patches-3.14/0040-USB-add-mt7621-xhci-support.patch [new file with mode: 0644]
target/linux/ramips/patches-3.14/0041-mtd-fix-cfi-cmdset-0002-erase-status-check.patch [new file with mode: 0644]
target/linux/ramips/patches-3.14/0042-mtd-cfi-cmdset-0002-force-word-write.patch [new file with mode: 0644]
target/linux/ramips/patches-3.14/0043-mtd-ralink-add-mt7620-nand-driver.patch [new file with mode: 0644]
target/linux/ramips/patches-3.14/0044-mtd-add-chunked-read-io-to-m25p80.patch [new file with mode: 0644]
target/linux/ramips/patches-3.14/0045-mtd-add-mt7621-nand-support.patch [new file with mode: 0644]
target/linux/ramips/patches-3.14/0046-DT-Add-documentation-for-gpio-ralink.patch [new file with mode: 0644]
target/linux/ramips/patches-3.14/0047-GPIO-MIPS-ralink-add-gpio-driver-for-ralink-SoC.patch [new file with mode: 0644]
target/linux/ramips/patches-3.14/0048-GPIO-ralink-add-mt7621-gpio-controller.patch [new file with mode: 0644]
target/linux/ramips/patches-3.14/0049-DT-Add-documentation-for-spi-rt2880.patch [new file with mode: 0644]
target/linux/ramips/patches-3.14/0050-SPI-ralink-add-Ralink-SoC-spi-driver.patch [new file with mode: 0644]
target/linux/ramips/patches-3.14/0051-SPI-MIPS-ralink-add-mt7621-support.patch [new file with mode: 0644]
target/linux/ramips/patches-3.14/0052-i2c-MIPS-adds-ralink-I2C-driver.patch [new file with mode: 0644]
target/linux/ramips/patches-3.14/0053-mmc-MIPS-ralink-add-sdhci-for-mt7620a-SoC.patch [new file with mode: 0644]
target/linux/ramips/patches-3.14/0054-DMA-ralink-add-rt2880-dma-engine.patch [new file with mode: 0644]
target/linux/ramips/patches-3.14/0055-asoc-add-mt7620-support.patch [new file with mode: 0644]
target/linux/ramips/patches-3.14/0056-watchdog-add-MT7621-support.patch [new file with mode: 0644]
target/linux/ramips/patches-3.14/0057-uvc-add-iPassion-iP2970-support.patch [new file with mode: 0644]
target/linux/ramips/patches-3.14/0100-mtd-split-remove-padding.patch [new file with mode: 0644]
target/linux/ramips/patches-3.14/0101-mtd-add-rtn56u-support.patch [new file with mode: 0644]
target/linux/ramips/patches-3.14/0103-MIPS-OWRTDTB.patch [new file with mode: 0644]
target/linux/ramips/rt288x/config-3.14 [new file with mode: 0644]
target/linux/ramips/rt305x/config-3.14 [new file with mode: 0644]
target/linux/ramips/rt3883/config-3.14 [new file with mode: 0644]

diff --git a/target/linux/ramips/mt7620a/config-3.14 b/target/linux/ramips/mt7620a/config-3.14
new file mode 100644 (file)
index 0000000..1ec82ae
--- /dev/null
@@ -0,0 +1,184 @@
+CONFIG_ARCH_BINFMT_ELF_RANDOMIZE_PIE=y
+CONFIG_ARCH_DISCARD_MEMBLOCK=y
+CONFIG_ARCH_HAS_ATOMIC64_DEC_IF_POSITIVE=y
+CONFIG_ARCH_HAS_RESET_CONTROLLER=y
+CONFIG_ARCH_HAVE_CUSTOM_GPIO_H=y
+CONFIG_ARCH_HIBERNATION_POSSIBLE=y
+CONFIG_ARCH_MIGHT_HAVE_PC_PARPORT=y
+CONFIG_ARCH_MIGHT_HAVE_PC_SERIO=y
+CONFIG_ARCH_REQUIRE_GPIOLIB=y
+CONFIG_ARCH_SUSPEND_POSSIBLE=y
+CONFIG_ARCH_WANT_IPC_PARSE_VERSION=y
+CONFIG_AT803X_PHY=y
+CONFIG_CC_OPTIMIZE_FOR_SIZE=y
+CONFIG_CEVT_R4K=y
+CONFIG_CLKDEV_LOOKUP=y
+CONFIG_CLKEVT_RT3352=y
+CONFIG_CLKSRC_MMIO=y
+CONFIG_CLKSRC_OF=y
+CONFIG_CLONE_BACKWARDS=y
+CONFIG_CMDLINE="rootfstype=squashfs,jffs2"
+CONFIG_CMDLINE_BOOL=y
+# CONFIG_CMDLINE_OVERRIDE is not set
+CONFIG_CPU_GENERIC_DUMP_TLB=y
+CONFIG_CPU_HAS_PREFETCH=y
+CONFIG_CPU_HAS_SYNC=y
+CONFIG_CPU_LITTLE_ENDIAN=y
+CONFIG_CPU_MIPS32=y
+# CONFIG_CPU_MIPS32_R1 is not set
+CONFIG_CPU_MIPS32_R2=y
+CONFIG_CPU_MIPSR2=y
+CONFIG_CPU_R4K_CACHE_TLB=y
+CONFIG_CPU_R4K_FPU=y
+CONFIG_CPU_SUPPORTS_32BIT_KERNEL=y
+CONFIG_CPU_SUPPORTS_HIGHMEM=y
+CONFIG_CSRC_R4K=y
+CONFIG_DEBUG_PINCTRL=y
+CONFIG_DMA_NONCOHERENT=y
+# CONFIG_DTB_MT7620A_EVAL is not set
+CONFIG_DTB_RT_NONE=y
+CONFIG_DTC=y
+CONFIG_EARLY_PRINTK=y
+# CONFIG_EARLY_PRINTK_8250 is not set
+CONFIG_GENERIC_ATOMIC64=y
+CONFIG_GENERIC_CLOCKEVENTS=y
+CONFIG_GENERIC_CLOCKEVENTS_BUILD=y
+CONFIG_GENERIC_CMOS_UPDATE=y
+CONFIG_GENERIC_IO=y
+CONFIG_GENERIC_IRQ_SHOW=y
+CONFIG_GENERIC_NET_UTILS=y
+CONFIG_GENERIC_PCI_IOMAP=y
+CONFIG_GENERIC_SMP_IDLE_THREAD=y
+CONFIG_GPIOLIB=y
+CONFIG_GPIO_DEVRES=y
+CONFIG_GPIO_RALINK=y
+CONFIG_GPIO_SYSFS=y
+CONFIG_HARDWARE_WATCHPOINTS=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_TRACEHOOK=y
+# CONFIG_HAVE_BOOTMEM_INFO_NODE is not set
+CONFIG_HAVE_CC_STACKPROTECTOR=y
+CONFIG_HAVE_CLK=y
+CONFIG_HAVE_CONTEXT_TRACKING=y
+CONFIG_HAVE_C_RECORDMCOUNT=y
+CONFIG_HAVE_DEBUG_KMEMLEAK=y
+CONFIG_HAVE_DEBUG_STACKOVERFLOW=y
+CONFIG_HAVE_DMA_API_DEBUG=y
+CONFIG_HAVE_DMA_ATTRS=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_FUNCTION_TRACE_MCOUNT_TEST=y
+CONFIG_HAVE_GENERIC_DMA_COHERENT=y
+CONFIG_HAVE_IDE=y
+CONFIG_HAVE_KVM=y
+CONFIG_HAVE_MACH_CLKDEV=y
+CONFIG_HAVE_MEMBLOCK=y
+CONFIG_HAVE_MEMBLOCK_NODE_MAP=y
+CONFIG_HAVE_MOD_ARCH_SPECIFIC=y
+CONFIG_HAVE_NET_DSA=y
+CONFIG_HAVE_OPROFILE=y
+CONFIG_HAVE_PERF_EVENTS=y
+CONFIG_HAVE_SYSCALL_TRACEPOINTS=y
+CONFIG_HW_HAS_PCI=y
+CONFIG_HW_RANDOM=m
+CONFIG_HZ_PERIODIC=y
+CONFIG_ICPLUS_PHY=y
+CONFIG_IMAGE_CMDLINE_HACK=y
+CONFIG_INET_LRO=y
+CONFIG_INITRAMFS_SOURCE=""
+CONFIG_IRQCHIP=y
+CONFIG_IRQ_CPU=y
+CONFIG_IRQ_DOMAIN=y
+CONFIG_IRQ_FORCED_THREADING=y
+CONFIG_IRQ_INTC=y
+CONFIG_IRQ_WORK=y
+CONFIG_MDIO_BOARDINFO=y
+CONFIG_MIPS=y
+# CONFIG_MIPS_HUGE_TLB_SUPPORT is not set
+CONFIG_MIPS_L1_CACHE_SHIFT=5
+# CONFIG_MIPS_MACHINE is not set
+CONFIG_MIPS_MT_DISABLED=y
+# CONFIG_MIPS_O32_FP64_SUPPORT is not set
+# CONFIG_MLX5_CORE is not set
+CONFIG_MODULES_USE_ELF_REL=y
+# CONFIG_MTD_CFI_INTELEXT is not set
+CONFIG_MTD_CMDLINE_PARTS=y
+CONFIG_MTD_M25P80=y
+CONFIG_MTD_NAND_MT7620=y
+CONFIG_MTD_PHYSMAP=y
+CONFIG_MTD_SPLIT_FIRMWARE=y
+CONFIG_MTD_UIMAGE_SPLIT=y
+CONFIG_NEED_DMA_MAP_STATE=y
+CONFIG_NEED_PER_CPU_KM=y
+CONFIG_NET_RALINK=y
+CONFIG_NET_RALINK_GSW_MT7620=y
+CONFIG_NET_RALINK_MDIO=y
+CONFIG_NET_RX_BUSY_POLL=y
+CONFIG_NLS=m
+CONFIG_NO_GENERIC_PCI_IOPORT_MAP=y
+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_MTD=y
+CONFIG_OF_NET=y
+CONFIG_OF_PCI=y
+CONFIG_OF_PCI_IRQ=y
+CONFIG_PAGEFLAGS_EXTENDED=y
+CONFIG_PCI=y
+CONFIG_PCI_DOMAINS=y
+CONFIG_PERF_USE_VMALLOC=y
+CONFIG_PHYLIB=y
+# CONFIG_PINCONF is not set
+CONFIG_PINCTRL=y
+CONFIG_PINCTRL_RT2880=y
+# CONFIG_PINCTRL_SINGLE is not set
+# CONFIG_PREEMPT_RCU is not set
+CONFIG_RALINK=y
+CONFIG_RALINK_USBPHY=y
+CONFIG_RALINK_WDT=y
+CONFIG_RA_NAT_NONE=y
+# CONFIG_RCU_STALL_COMMON is not set
+CONFIG_RESET_CONTROLLER=y
+# CONFIG_SCSI_DMA is not set
+CONFIG_SERIAL_8250_NR_UARTS=4
+CONFIG_SERIAL_8250_RT288X=y
+CONFIG_SERIAL_OF_PLATFORM=y
+# CONFIG_SLAB is not set
+CONFIG_SLUB=y
+CONFIG_SOC_MT7620=y
+# CONFIG_SOC_MT7621 is not set
+# CONFIG_SOC_RT288X is not set
+# CONFIG_SOC_RT305X is not set
+# CONFIG_SOC_RT3883 is not set
+CONFIG_SPI=y
+CONFIG_SPI_MASTER=y
+CONFIG_SPI_RT2880=y
+CONFIG_SWCONFIG=y
+CONFIG_SYS_HAS_CPU_MIPS32_R1=y
+CONFIG_SYS_HAS_CPU_MIPS32_R2=y
+CONFIG_SYS_HAS_EARLY_PRINTK=y
+CONFIG_SYS_SUPPORTS_32BIT_KERNEL=y
+CONFIG_SYS_SUPPORTS_ARBIT_HZ=y
+CONFIG_SYS_SUPPORTS_LITTLE_ENDIAN=y
+CONFIG_TICK_CPU_ACCOUNTING=y
+CONFIG_USB=m
+CONFIG_USB_COMMON=m
+# CONFIG_USB_EHCI_HCD is not set
+CONFIG_USB_PHY=y
+CONFIG_USB_SUPPORT=y
+# CONFIG_USB_UHCI_HCD is not set
+CONFIG_USE_OF=y
+CONFIG_WATCHDOG_CORE=y
+# CONFIG_ZBUD is not set
+CONFIG_ZONE_DMA_FLAG=0
diff --git a/target/linux/ramips/mt7620n/config-3.14 b/target/linux/ramips/mt7620n/config-3.14
new file mode 100644 (file)
index 0000000..db95ddf
--- /dev/null
@@ -0,0 +1,176 @@
+CONFIG_ARCH_BINFMT_ELF_RANDOMIZE_PIE=y
+CONFIG_ARCH_DISCARD_MEMBLOCK=y
+CONFIG_ARCH_HAS_ATOMIC64_DEC_IF_POSITIVE=y
+CONFIG_ARCH_HAS_RESET_CONTROLLER=y
+CONFIG_ARCH_HAVE_CUSTOM_GPIO_H=y
+CONFIG_ARCH_HIBERNATION_POSSIBLE=y
+CONFIG_ARCH_MIGHT_HAVE_PC_PARPORT=y
+CONFIG_ARCH_MIGHT_HAVE_PC_SERIO=y
+CONFIG_ARCH_REQUIRE_GPIOLIB=y
+CONFIG_ARCH_SUSPEND_POSSIBLE=y
+CONFIG_ARCH_WANT_IPC_PARSE_VERSION=y
+CONFIG_CC_OPTIMIZE_FOR_SIZE=y
+CONFIG_CEVT_R4K=y
+CONFIG_CLKDEV_LOOKUP=y
+CONFIG_CLKEVT_RT3352=y
+CONFIG_CLKSRC_MMIO=y
+CONFIG_CLKSRC_OF=y
+CONFIG_CLONE_BACKWARDS=y
+CONFIG_CMDLINE="rootfstype=squashfs,jffs2"
+CONFIG_CMDLINE_BOOL=y
+# CONFIG_CMDLINE_OVERRIDE is not set
+CONFIG_CPU_GENERIC_DUMP_TLB=y
+CONFIG_CPU_HAS_PREFETCH=y
+CONFIG_CPU_HAS_SYNC=y
+CONFIG_CPU_LITTLE_ENDIAN=y
+CONFIG_CPU_MIPS32=y
+# CONFIG_CPU_MIPS32_R1 is not set
+CONFIG_CPU_MIPS32_R2=y
+CONFIG_CPU_MIPSR2=y
+CONFIG_CPU_R4K_CACHE_TLB=y
+CONFIG_CPU_R4K_FPU=y
+CONFIG_CPU_SUPPORTS_32BIT_KERNEL=y
+CONFIG_CPU_SUPPORTS_HIGHMEM=y
+CONFIG_CSRC_R4K=y
+CONFIG_DEBUG_PINCTRL=y
+CONFIG_DMA_NONCOHERENT=y
+# CONFIG_DTB_MT7620A_EVAL is not set
+CONFIG_DTB_RT_NONE=y
+CONFIG_DTC=y
+CONFIG_EARLY_PRINTK=y
+# CONFIG_EARLY_PRINTK_8250 is not set
+CONFIG_GENERIC_ATOMIC64=y
+CONFIG_GENERIC_CLOCKEVENTS=y
+CONFIG_GENERIC_CLOCKEVENTS_BUILD=y
+CONFIG_GENERIC_CMOS_UPDATE=y
+CONFIG_GENERIC_IO=y
+CONFIG_GENERIC_IRQ_SHOW=y
+CONFIG_GENERIC_NET_UTILS=y
+CONFIG_GENERIC_PCI_IOMAP=y
+CONFIG_GENERIC_SMP_IDLE_THREAD=y
+CONFIG_GPIOLIB=y
+CONFIG_GPIO_DEVRES=y
+CONFIG_GPIO_RALINK=y
+CONFIG_GPIO_SYSFS=y
+CONFIG_HARDWARE_WATCHPOINTS=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_TRACEHOOK=y
+# CONFIG_HAVE_BOOTMEM_INFO_NODE is not set
+CONFIG_HAVE_CC_STACKPROTECTOR=y
+CONFIG_HAVE_CLK=y
+CONFIG_HAVE_CONTEXT_TRACKING=y
+CONFIG_HAVE_C_RECORDMCOUNT=y
+CONFIG_HAVE_DEBUG_KMEMLEAK=y
+CONFIG_HAVE_DEBUG_STACKOVERFLOW=y
+CONFIG_HAVE_DMA_API_DEBUG=y
+CONFIG_HAVE_DMA_ATTRS=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_FUNCTION_TRACE_MCOUNT_TEST=y
+CONFIG_HAVE_GENERIC_DMA_COHERENT=y
+CONFIG_HAVE_IDE=y
+CONFIG_HAVE_KVM=y
+CONFIG_HAVE_MACH_CLKDEV=y
+CONFIG_HAVE_MEMBLOCK=y
+CONFIG_HAVE_MEMBLOCK_NODE_MAP=y
+CONFIG_HAVE_MOD_ARCH_SPECIFIC=y
+CONFIG_HAVE_NET_DSA=y
+CONFIG_HAVE_OPROFILE=y
+CONFIG_HAVE_PERF_EVENTS=y
+CONFIG_HAVE_SYSCALL_TRACEPOINTS=y
+CONFIG_HW_HAS_PCI=y
+CONFIG_HW_RANDOM=m
+CONFIG_HZ_PERIODIC=y
+CONFIG_IMAGE_CMDLINE_HACK=y
+CONFIG_INET_LRO=y
+CONFIG_INITRAMFS_SOURCE=""
+CONFIG_IRQCHIP=y
+CONFIG_IRQ_CPU=y
+CONFIG_IRQ_DOMAIN=y
+CONFIG_IRQ_FORCED_THREADING=y
+CONFIG_IRQ_INTC=y
+CONFIG_IRQ_WORK=y
+CONFIG_MDIO_BOARDINFO=y
+CONFIG_MIPS=y
+# CONFIG_MIPS_HUGE_TLB_SUPPORT is not set
+CONFIG_MIPS_L1_CACHE_SHIFT=5
+# CONFIG_MIPS_MACHINE is not set
+CONFIG_MIPS_MT_DISABLED=y
+# CONFIG_MIPS_O32_FP64_SUPPORT is not set
+CONFIG_MODULES_USE_ELF_REL=y
+# CONFIG_MTD_CFI_INTELEXT is not set
+CONFIG_MTD_CMDLINE_PARTS=y
+CONFIG_MTD_M25P80=y
+# CONFIG_MTD_NAND_MT7620 is not set
+CONFIG_MTD_PHYSMAP=y
+CONFIG_MTD_SPLIT_FIRMWARE=y
+CONFIG_MTD_UIMAGE_SPLIT=y
+CONFIG_NEED_DMA_MAP_STATE=y
+CONFIG_NEED_PER_CPU_KM=y
+CONFIG_NET_RALINK=y
+CONFIG_NET_RALINK_GSW_MT7620=y
+CONFIG_NET_RALINK_MDIO=y
+CONFIG_NET_RX_BUSY_POLL=y
+CONFIG_NLS=m
+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_MTD=y
+CONFIG_OF_NET=y
+CONFIG_PAGEFLAGS_EXTENDED=y
+# CONFIG_PCI is not set
+CONFIG_PERF_USE_VMALLOC=y
+CONFIG_PHYLIB=y
+# CONFIG_PINCONF is not set
+CONFIG_PINCTRL=y
+CONFIG_PINCTRL_RT2880=y
+# CONFIG_PINCTRL_SINGLE is not set
+# CONFIG_PREEMPT_RCU is not set
+CONFIG_RALINK=y
+CONFIG_RALINK_USBPHY=y
+CONFIG_RALINK_WDT=y
+CONFIG_RA_NAT_NONE=y
+# CONFIG_RCU_STALL_COMMON is not set
+CONFIG_RESET_CONTROLLER=y
+# CONFIG_SCSI_DMA is not set
+CONFIG_SERIAL_8250_NR_UARTS=4
+CONFIG_SERIAL_8250_RT288X=y
+CONFIG_SERIAL_OF_PLATFORM=y
+# CONFIG_SLAB is not set
+CONFIG_SLUB=y
+CONFIG_SOC_MT7620=y
+# CONFIG_SOC_MT7621 is not set
+# CONFIG_SOC_RT288X is not set
+# CONFIG_SOC_RT305X is not set
+# CONFIG_SOC_RT3883 is not set
+CONFIG_SPI=y
+CONFIG_SPI_MASTER=y
+CONFIG_SPI_RT2880=y
+CONFIG_SWCONFIG=y
+CONFIG_SYS_HAS_CPU_MIPS32_R1=y
+CONFIG_SYS_HAS_CPU_MIPS32_R2=y
+CONFIG_SYS_HAS_EARLY_PRINTK=y
+CONFIG_SYS_SUPPORTS_32BIT_KERNEL=y
+CONFIG_SYS_SUPPORTS_ARBIT_HZ=y
+CONFIG_SYS_SUPPORTS_LITTLE_ENDIAN=y
+CONFIG_TICK_CPU_ACCOUNTING=y
+CONFIG_USB=m
+CONFIG_USB_COMMON=m
+# CONFIG_USB_EHCI_HCD is not set
+CONFIG_USB_PHY=y
+CONFIG_USB_SUPPORT=y
+CONFIG_USE_OF=y
+CONFIG_WATCHDOG_CORE=y
+# CONFIG_ZBUD is not set
+CONFIG_ZONE_DMA_FLAG=0
diff --git a/target/linux/ramips/mt7621/config-3.14 b/target/linux/ramips/mt7621/config-3.14
new file mode 100644 (file)
index 0000000..cb00c51
--- /dev/null
@@ -0,0 +1,237 @@
+# CONFIG_32B_DESC is not set
+CONFIG_ARCH_BINFMT_ELF_RANDOMIZE_PIE=y
+CONFIG_ARCH_DISCARD_MEMBLOCK=y
+CONFIG_ARCH_HAS_ATOMIC64_DEC_IF_POSITIVE=y
+CONFIG_ARCH_HAS_RESET_CONTROLLER=y
+CONFIG_ARCH_HAVE_CUSTOM_GPIO_H=y
+CONFIG_ARCH_MIGHT_HAVE_PC_PARPORT=y
+CONFIG_ARCH_MIGHT_HAVE_PC_SERIO=y
+CONFIG_ARCH_REQUIRE_GPIOLIB=y
+CONFIG_ARCH_WANT_IPC_PARSE_VERSION=y
+CONFIG_BOARD_SCACHE=y
+CONFIG_CC_OPTIMIZE_FOR_SIZE=y
+# CONFIG_CEVT_GIC is not set
+CONFIG_CEVT_R4K=y
+CONFIG_CLKDEV_LOOKUP=y
+CONFIG_CLONE_BACKWARDS=y
+CONFIG_CMDLINE="rootfstype=squashfs,jffs2"
+CONFIG_CMDLINE_BOOL=y
+# CONFIG_CMDLINE_OVERRIDE is not set
+CONFIG_CPU_GENERIC_DUMP_TLB=y
+CONFIG_CPU_HAS_PREFETCH=y
+CONFIG_CPU_HAS_SYNC=y
+CONFIG_CPU_LITTLE_ENDIAN=y
+CONFIG_CPU_MIPS32=y
+# CONFIG_CPU_MIPS32_R1 is not set
+CONFIG_CPU_MIPS32_R2=y
+CONFIG_CPU_MIPSR2=y
+CONFIG_CPU_MIPSR2_IRQ_EI=y
+CONFIG_CPU_MIPSR2_IRQ_VI=y
+CONFIG_CPU_R4K_CACHE_TLB=y
+CONFIG_CPU_R4K_FPU=y
+CONFIG_CPU_RMAP=y
+CONFIG_CPU_SUPPORTS_32BIT_KERNEL=y
+CONFIG_CPU_SUPPORTS_HIGHMEM=y
+CONFIG_CSRC_R4K=y
+CONFIG_DEBUG_PINCTRL=y
+CONFIG_DMA_NONCOHERENT=y
+# CONFIG_DTB_MT7621_EVAL is not set
+CONFIG_DTB_RT_NONE=y
+CONFIG_DTC=y
+CONFIG_EARLY_PRINTK=y
+# CONFIG_EARLY_PRINTK_8250 is not set
+CONFIG_ESW_DOUBLE_VLAN_TAG=y
+# CONFIG_GE1_MII_AN is not set
+# CONFIG_GE1_MII_FORCE_100 is not set
+# CONFIG_GE1_RGMII_AN is not set
+CONFIG_GE1_RGMII_FORCE_1000=y
+# CONFIG_GE1_RGMII_NONE is not set
+# CONFIG_GE1_RVMII_FORCE_100 is not set
+# CONFIG_GE1_TRGMII_FORCE_1200 is not set
+CONFIG_GENERIC_ATOMIC64=y
+CONFIG_GENERIC_CLOCKEVENTS=y
+CONFIG_GENERIC_CLOCKEVENTS_BUILD=y
+CONFIG_GENERIC_CMOS_UPDATE=y
+CONFIG_GENERIC_IO=y
+CONFIG_GENERIC_IRQ_SHOW=y
+CONFIG_GENERIC_NET_UTILS=y
+CONFIG_GENERIC_PCI_IOMAP=y
+CONFIG_GENERIC_SMP_IDLE_THREAD=y
+CONFIG_GPIOLIB=y
+CONFIG_GPIO_DEVRES=y
+# CONFIG_GPIO_MT7621 is not set
+CONFIG_GPIO_SYSFS=y
+CONFIG_HARDWARE_WATCHPOINTS=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_TRACEHOOK=y
+# CONFIG_HAVE_BOOTMEM_INFO_NODE is not set
+CONFIG_HAVE_CC_STACKPROTECTOR=y
+CONFIG_HAVE_CLK=y
+CONFIG_HAVE_CONTEXT_TRACKING=y
+CONFIG_HAVE_C_RECORDMCOUNT=y
+CONFIG_HAVE_DEBUG_KMEMLEAK=y
+CONFIG_HAVE_DEBUG_STACKOVERFLOW=y
+CONFIG_HAVE_DMA_API_DEBUG=y
+CONFIG_HAVE_DMA_ATTRS=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_FUNCTION_TRACE_MCOUNT_TEST=y
+CONFIG_HAVE_GENERIC_DMA_COHERENT=y
+CONFIG_HAVE_IDE=y
+CONFIG_HAVE_KVM=y
+CONFIG_HAVE_MACH_CLKDEV=y
+CONFIG_HAVE_MEMBLOCK=y
+CONFIG_HAVE_MEMBLOCK_NODE_MAP=y
+CONFIG_HAVE_MOD_ARCH_SPECIFIC=y
+CONFIG_HAVE_NET_DSA=y
+CONFIG_HAVE_OPROFILE=y
+CONFIG_HAVE_PERF_EVENTS=y
+CONFIG_HAVE_SYSCALL_TRACEPOINTS=y
+CONFIG_HW_HAS_PCI=y
+CONFIG_HW_RANDOM=m
+CONFIG_HZ_PERIODIC=y
+CONFIG_IMAGE_CMDLINE_HACK=y
+CONFIG_INITRAMFS_SOURCE=""
+CONFIG_IRQCHIP=y
+CONFIG_IRQ_CPU=y
+CONFIG_IRQ_DOMAIN=y
+CONFIG_IRQ_FORCED_THREADING=y
+CONFIG_IRQ_GIC=y
+CONFIG_IRQ_WORK=y
+# CONFIG_LAN_WAN_SUPPORT is not set
+CONFIG_MDIO_BOARDINFO=y
+CONFIG_MIPS=y
+CONFIG_MIPS_CMP=y
+CONFIG_MIPS_CPU_SCACHE=y
+# CONFIG_MIPS_HUGE_TLB_SUPPORT is not set
+CONFIG_MIPS_L1_CACHE_SHIFT=6
+CONFIG_MIPS_L1_CACHE_SHIFT_6=y
+# CONFIG_MIPS_MACHINE is not set
+CONFIG_MIPS_MT=y
+# CONFIG_MIPS_MT_DISABLED is not set
+CONFIG_MIPS_MT_FPAFF=y
+CONFIG_MIPS_MT_SMP=y
+# CONFIG_MIPS_MT_SMTC is not set
+# CONFIG_MIPS_O32_FP64_SUPPORT is not set
+CONFIG_MIPS_PERF_SHARED_TC_COUNTERS=y
+# CONFIG_MIPS_VPE_LOADER is not set
+# CONFIG_MLX5_CORE is not set
+CONFIG_MODULES_USE_ELF_REL=y
+CONFIG_MT7621_ASIC=y
+# CONFIG_MT7621_WDT is not set
+# CONFIG_MTD_CFI_INTELEXT is not set
+CONFIG_MTD_CMDLINE_PARTS=y
+CONFIG_MTD_M25P80=y
+CONFIG_MTD_PHYSMAP=y
+CONFIG_MTD_SPLIT_FIRMWARE=y
+CONFIG_MTD_UIMAGE_SPLIT=y
+CONFIG_NEED_DMA_MAP_STATE=y
+CONFIG_NET_FLOW_LIMIT=y
+# CONFIG_NET_RALINK is not set
+CONFIG_NET_RX_BUSY_POLL=y
+CONFIG_NLS=m
+CONFIG_NO_GENERIC_PCI_IOPORT_MAP=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_MTD=y
+CONFIG_OF_NET=y
+CONFIG_OF_PCI=y
+CONFIG_OF_PCI_IRQ=y
+CONFIG_PAGEFLAGS_EXTENDED=y
+CONFIG_PCI=y
+CONFIG_PCI_DISABLE_COMMON_QUIRKS=y
+CONFIG_PCI_DOMAINS=y
+CONFIG_PDMA_NEW=y
+CONFIG_PERF_USE_VMALLOC=y
+CONFIG_PHYLIB=y
+# CONFIG_PINCONF is not set
+CONFIG_PINCTRL=y
+CONFIG_PINCTRL_RT2880=y
+# CONFIG_PINCTRL_SINGLE is not set
+# CONFIG_PREEMPT_RCU is not set
+CONFIG_RAETH=y
+CONFIG_RAETH_CHECKSUM_OFFLOAD=y
+# CONFIG_RAETH_GMAC2 is not set
+# CONFIG_RAETH_HW_VLAN_RX is not set
+# CONFIG_RAETH_HW_VLAN_TX is not set
+# CONFIG_RAETH_LRO is not set
+# CONFIG_RAETH_NAPI is not set
+# CONFIG_RAETH_QDMA is not set
+CONFIG_RAETH_SCATTER_GATHER_RX_DMA=y
+# CONFIG_RAETH_SKB_RECYCLE_2K is not set
+# CONFIG_RAETH_SPECIAL_TAG is not set
+# CONFIG_RAETH_TSO is not set
+CONFIG_RALINK=y
+CONFIG_RALINK_MT7621=y
+CONFIG_RALINK_USBPHY=y
+# CONFIG_RALINK_WDT is not set
+CONFIG_RA_NAT_NONE=y
+# CONFIG_RA_NETWORK_TASKLET_BH is not set
+CONFIG_RA_NETWORK_WORKQUEUE_BH=y
+CONFIG_RCU_STALL_COMMON=y
+CONFIG_RESET_CONTROLLER=y
+CONFIG_RFS_ACCEL=y
+CONFIG_RPS=y
+CONFIG_RT_3052_ESW=y
+CONFIG_SCHED_SMT=y
+# CONFIG_SCSI_DMA is not set
+CONFIG_SERIAL_8250_NR_UARTS=4
+CONFIG_SERIAL_OF_PLATFORM=y
+# CONFIG_SLAB is not set
+CONFIG_SLUB=y
+CONFIG_SLUB_CPU_PARTIAL=y
+CONFIG_SMP=y
+CONFIG_SMP_UP=y
+# CONFIG_SOC_MT7620 is not set
+CONFIG_SOC_MT7621=y
+# CONFIG_SOC_RT288X is not set
+# CONFIG_SOC_RT305X is not set
+# CONFIG_SOC_RT3883 is not set
+CONFIG_SPI=y
+CONFIG_SPI_MASTER=y
+CONFIG_SPI_RT2880=y
+CONFIG_STOP_MACHINE=y
+CONFIG_SWCONFIG=y
+CONFIG_SYNC_R4K=y
+CONFIG_SYS_HAS_CPU_MIPS32_R1=y
+CONFIG_SYS_HAS_CPU_MIPS32_R2=y
+CONFIG_SYS_HAS_EARLY_PRINTK=y
+CONFIG_SYS_SUPPORTS_32BIT_KERNEL=y
+CONFIG_SYS_SUPPORTS_ARBIT_HZ=y
+CONFIG_SYS_SUPPORTS_LITTLE_ENDIAN=y
+CONFIG_SYS_SUPPORTS_MIPS_CMP=y
+CONFIG_SYS_SUPPORTS_MULTITHREADING=y
+CONFIG_SYS_SUPPORTS_SCHED_SMT=y
+CONFIG_SYS_SUPPORTS_SMP=y
+CONFIG_TICK_CPU_ACCOUNTING=y
+CONFIG_TREE_RCU=y
+CONFIG_USB=m
+CONFIG_USB_COMMON=m
+# CONFIG_USB_EHCI_HCD is not set
+CONFIG_USB_MT7621_XHCI_PLATFORM=y
+CONFIG_USB_PHY=y
+CONFIG_USB_SUPPORT=y
+# CONFIG_USB_UHCI_HCD is not set
+CONFIG_USB_XHCI_HCD=m
+CONFIG_USB_XHCI_PLATFORM=y
+CONFIG_USE_OF=y
+CONFIG_WAN_AT_P0=y
+# CONFIG_WAN_AT_P4 is not set
+CONFIG_WATCHDOG_CORE=y
+CONFIG_WEAK_ORDERING=y
+CONFIG_XPS=y
+# CONFIG_ZBUD is not set
+CONFIG_ZONE_DMA_FLAG=0
diff --git a/target/linux/ramips/patches-3.14/0001-MIPS-ralink-add-verbose-pmu-info.patch b/target/linux/ramips/patches-3.14/0001-MIPS-ralink-add-verbose-pmu-info.patch
new file mode 100644 (file)
index 0000000..51094d5
--- /dev/null
@@ -0,0 +1,64 @@
+From 453850d315070678245f61202ae343153589e5a6 Mon Sep 17 00:00:00 2001
+From: John Crispin <blogic@openwrt.org>
+Date: Sun, 27 Jul 2014 09:16:50 +0100
+Subject: [PATCH 01/57] MIPS: ralink: add verbose pmu info
+
+Print the PMU and LDO settings on boot.
+
+Signed-off-by: John Crispin <blogic@openwrt.org>
+---
+ arch/mips/ralink/mt7620.c |   26 ++++++++++++++++++++++++++
+ 1 file changed, 26 insertions(+)
+
+diff --git a/arch/mips/ralink/mt7620.c b/arch/mips/ralink/mt7620.c
+index a3ad56c..5846817 100644
+--- a/arch/mips/ralink/mt7620.c
++++ b/arch/mips/ralink/mt7620.c
+@@ -20,6 +20,22 @@
+ #include "common.h"
++/* analog */
++#define PMU0_CFG              0x88
++#define PMU_SW_SET            BIT(28)
++#define A_DCDC_EN             BIT(24)
++#define A_SSC_PERI            BIT(19)
++#define A_SSC_GEN             BIT(18)
++#define A_SSC_M                       0x3
++#define A_SSC_S                       16
++#define A_DLY_M                       0x7
++#define A_DLY_S                       8
++#define A_VTUNE_M             0xff
++
++/* digital */
++#define PMU1_CFG              0x8C
++#define DIG_SW_SEL            BIT(25)
++
+ /* does the board have sdram or ddram */
+ static int dram_type;
+@@ -339,6 +355,8 @@ void prom_soc_init(struct ralink_soc_info *soc_info)
+       u32 n1;
+       u32 rev;
+       u32 cfg0;
++      u32 pmu0;
++      u32 pmu1;
+       n0 = __raw_readl(sysc + SYSC_REG_CHIP_NAME0);
+       n1 = __raw_readl(sysc + SYSC_REG_CHIP_NAME1);
+@@ -386,4 +404,12 @@ void prom_soc_init(struct ralink_soc_info *soc_info)
+               BUG();
+       }
+       soc_info->mem_base = MT7620_DRAM_BASE;
++
++      pmu0 = __raw_readl(sysc + PMU0_CFG);
++      pmu1 = __raw_readl(sysc + PMU1_CFG);
++
++      pr_info("Analog PMU set to %s control\n",
++              (pmu0 & PMU_SW_SET) ? ("sw") : ("hw"));
++      pr_info("Digital PMU set to %s control\n",
++              (pmu1 & DIG_SW_SEL) ? ("sw") : ("hw"));
+ }
+-- 
+1.7.10.4
+
diff --git a/target/linux/ramips/patches-3.14/0002-MIPS-ralink-add-a-helper-for-reading-the-ECO-version.patch b/target/linux/ramips/patches-3.14/0002-MIPS-ralink-add-a-helper-for-reading-the-ECO-version.patch
new file mode 100644 (file)
index 0000000..92155d4
--- /dev/null
@@ -0,0 +1,27 @@
+From 1751f28d4779df83cc793c9d7ff75485c0ceaa23 Mon Sep 17 00:00:00 2001
+From: John Crispin <blogic@openwrt.org>
+Date: Sun, 16 Mar 2014 04:53:02 +0000
+Subject: [PATCH 02/57] MIPS: ralink: add a helper for reading the ECO version
+
+Signed-off-by: John Crispin <blogic@openwrt.org>
+---
+ arch/mips/include/asm/mach-ralink/mt7620.h |    5 +++++
+ 1 file changed, 5 insertions(+)
+
+diff --git a/arch/mips/include/asm/mach-ralink/mt7620.h b/arch/mips/include/asm/mach-ralink/mt7620.h
+index 6f9b24f..7ff9290 100644
+--- a/arch/mips/include/asm/mach-ralink/mt7620.h
++++ b/arch/mips/include/asm/mach-ralink/mt7620.h
+@@ -105,4 +105,9 @@
+ #define MT7620_GPIO_MODE_EPHY         BIT(15)
+ #define MT7620_GPIO_MODE_WDT          BIT(22)
++static inline int mt7620_get_eco(void)
++{
++      return rt_sysc_r32(SYSC_REG_CHIP_REV) & CHIP_REV_ECO_MASK;
++}
++
+ #endif
+-- 
+1.7.10.4
+
diff --git a/target/linux/ramips/patches-3.14/0003-MIPS-ralink-add-rt_sysc_m32-helper.patch b/target/linux/ramips/patches-3.14/0003-MIPS-ralink-add-rt_sysc_m32-helper.patch
new file mode 100644 (file)
index 0000000..e254ac0
--- /dev/null
@@ -0,0 +1,31 @@
+From 0f0f041cd6a05eb865e391155d3299bb55ff00e3 Mon Sep 17 00:00:00 2001
+From: John Crispin <blogic@openwrt.org>
+Date: Sun, 19 May 2013 00:42:23 +0200
+Subject: [PATCH 03/57] MIPS: ralink: add rt_sysc_m32 helper
+
+Signed-off-by: John Crispin <blogic@openwrt.org>
+---
+ arch/mips/include/asm/mach-ralink/ralink_regs.h |    7 +++++++
+ 1 file changed, 7 insertions(+)
+
+diff --git a/arch/mips/include/asm/mach-ralink/ralink_regs.h b/arch/mips/include/asm/mach-ralink/ralink_regs.h
+index 5a508f9..bd93014 100644
+--- a/arch/mips/include/asm/mach-ralink/ralink_regs.h
++++ b/arch/mips/include/asm/mach-ralink/ralink_regs.h
+@@ -26,6 +26,13 @@ static inline u32 rt_sysc_r32(unsigned reg)
+       return __raw_readl(rt_sysc_membase + reg);
+ }
++static inline void rt_sysc_m32(u32 clr, u32 set, unsigned reg)
++{
++      u32 val = rt_sysc_r32(reg) & ~clr;
++
++      __raw_writel(val | set, rt_sysc_membase + reg);
++}
++
+ static inline void rt_memc_w32(u32 val, unsigned reg)
+ {
+       __raw_writel(val, rt_memc_membase + reg);
+-- 
+1.7.10.4
+
diff --git a/target/linux/ramips/patches-3.14/0004-MIPS-ralink-adds-a-bootrom-dumper-module.patch b/target/linux/ramips/patches-3.14/0004-MIPS-ralink-adds-a-bootrom-dumper-module.patch
new file mode 100644 (file)
index 0000000..88e0f52
--- /dev/null
@@ -0,0 +1,83 @@
+From af03898c74172ab16d610f3eeaa65f66401eb7db Mon Sep 17 00:00:00 2001
+From: John Crispin <blogic@openwrt.org>
+Date: Tue, 21 May 2013 15:50:31 +0200
+Subject: [PATCH 04/57] MIPS: ralink: adds a bootrom dumper module
+
+This patch adds a trivial driver that allows userland to extract the bootrom of
+a SoC via debugfs.
+
+Signed-off-by: John Crispin <blogic@openwrt.org>
+---
+ arch/mips/ralink/Makefile  |    2 ++
+ arch/mips/ralink/bootrom.c |   48 ++++++++++++++++++++++++++++++++++++++++++++
+ 2 files changed, 50 insertions(+)
+ create mode 100644 arch/mips/ralink/bootrom.c
+
+diff --git a/arch/mips/ralink/Makefile b/arch/mips/ralink/Makefile
+index 98ae349..584a8d9 100644
+--- a/arch/mips/ralink/Makefile
++++ b/arch/mips/ralink/Makefile
+@@ -17,4 +17,6 @@ obj-$(CONFIG_SOC_MT7620) += mt7620.o
+ obj-$(CONFIG_EARLY_PRINTK) += early_printk.o
++obj-$(CONFIG_DEBUG_FS) += bootrom.o
++
+ obj-y += dts/
+diff --git a/arch/mips/ralink/bootrom.c b/arch/mips/ralink/bootrom.c
+new file mode 100644
+index 0000000..f926f6f
+--- /dev/null
++++ b/arch/mips/ralink/bootrom.c
+@@ -0,0 +1,48 @@
++/*
++ * This program is free software; you can redistribute it and/or modify it
++ * under the terms of the GNU General Public License version 2 as published
++ * by the Free Software Foundation.
++ *
++ * Copyright (C) 2013 John Crispin <blogic@openwrt.org>
++ */
++
++#include <linux/debugfs.h>
++#include <linux/seq_file.h>
++
++#define BOOTROM_OFFSET        0x10118000
++#define BOOTROM_SIZE  0x8000
++
++static void __iomem *membase = (void __iomem*) KSEG1ADDR(BOOTROM_OFFSET);
++
++static int bootrom_show(struct seq_file *s, void *unused)
++{
++      seq_write(s, membase, BOOTROM_SIZE);
++
++      return 0;
++}
++
++static int bootrom_open(struct inode *inode, struct file *file)
++{
++      return single_open(file, bootrom_show, NULL);
++}
++
++static const struct file_operations bootrom_file_ops = {
++      .open           = bootrom_open,
++      .read           = seq_read,
++      .llseek         = seq_lseek,
++      .release        = single_release,
++};
++
++static int bootrom_setup(void)
++{
++      if (!debugfs_create_file("bootrom", 0444,
++                      NULL, NULL, &bootrom_file_ops)) {
++              pr_err("Failed to create bootrom debugfs file\n");
++
++              return -EINVAL;
++      }
++
++      return 0;
++}
++
++postcore_initcall(bootrom_setup);
+-- 
+1.7.10.4
+
diff --git a/target/linux/ramips/patches-3.14/0005-MIPS-ralink-add-illegal-access-driver.patch b/target/linux/ramips/patches-3.14/0005-MIPS-ralink-add-illegal-access-driver.patch
new file mode 100644 (file)
index 0000000..5c8414a
--- /dev/null
@@ -0,0 +1,123 @@
+From 60999174904c731e55992a4087999bbd4e5f2051 Mon Sep 17 00:00:00 2001
+From: John Crispin <blogic@openwrt.org>
+Date: Thu, 16 May 2013 23:28:23 +0200
+Subject: [PATCH 05/57] MIPS: ralink: add illegal access driver
+
+these SoCs have a special irq that fires upon an illegal memmory access.
+
+Signed-off-by: John Crispin <blogic@openwrt.org>
+---
+ arch/mips/ralink/Makefile  |    2 +
+ arch/mips/ralink/ill_acc.c |   87 ++++++++++++++++++++++++++++++++++++++++++++
+ 2 files changed, 89 insertions(+)
+ create mode 100644 arch/mips/ralink/ill_acc.c
+
+diff --git a/arch/mips/ralink/Makefile b/arch/mips/ralink/Makefile
+index 584a8d9..fc57c16 100644
+--- a/arch/mips/ralink/Makefile
++++ b/arch/mips/ralink/Makefile
+@@ -10,6 +10,8 @@ obj-y := prom.o of.o reset.o clk.o irq.o timer.o
+ obj-$(CONFIG_CLKEVT_RT3352) += cevt-rt3352.o
++obj-$(CONFIG_RALINK_ILL_ACC) += ill_acc.o
++
+ obj-$(CONFIG_SOC_RT288X) += rt288x.o
+ obj-$(CONFIG_SOC_RT305X) += rt305x.o
+ obj-$(CONFIG_SOC_RT3883) += rt3883.o
+diff --git a/arch/mips/ralink/ill_acc.c b/arch/mips/ralink/ill_acc.c
+new file mode 100644
+index 0000000..4a3f696
+--- /dev/null
++++ b/arch/mips/ralink/ill_acc.c
+@@ -0,0 +1,87 @@
++/*
++ * This program is free software; you can redistribute it and/or modify it
++ * under the terms of the GNU General Public License version 2 as published
++ * by the Free Software Foundation.
++ *
++ * Copyright (C) 2013 John Crispin <blogic@openwrt.org>
++ */
++
++#include <linux/interrupt.h>
++#include <linux/of_platform.h>
++#include <linux/of_irq.h>
++
++#include <asm/mach-ralink/ralink_regs.h>
++
++#define REG_ILL_ACC_ADDR      0x10
++#define REG_ILL_ACC_TYPE      0x14
++
++#define ILL_INT_STATUS                BIT(31)
++#define ILL_ACC_WRITE         BIT(30)
++#define ILL_ACC_LEN_M         0xff
++#define ILL_ACC_OFF_M         0xf
++#define ILL_ACC_OFF_S         16
++#define ILL_ACC_ID_M          0x7
++#define ILL_ACC_ID_S          8
++
++#define       DRV_NAME                "ill_acc"
++
++static const char *ill_acc_ids[] = {
++      "cpu", "dma", "ppe", "pdma rx","pdma tx", "pci/e", "wmac", "usb",
++};
++
++static irqreturn_t ill_acc_irq_handler(int irq, void *_priv)
++{
++      struct device *dev = (struct device *) _priv;
++      u32 addr = rt_memc_r32(REG_ILL_ACC_ADDR);
++      u32 type = rt_memc_r32(REG_ILL_ACC_TYPE);
++
++      dev_err(dev, "illegal %s access from %s - addr:0x%08x offset:%d len:%d\n",
++              (type & ILL_ACC_WRITE) ? ("write") : ("read"),
++              ill_acc_ids[(type >> ILL_ACC_ID_S) & ILL_ACC_ID_M],
++              addr, (type >> ILL_ACC_OFF_S) & ILL_ACC_OFF_M,
++              type & ILL_ACC_LEN_M);
++
++      rt_memc_w32(REG_ILL_ACC_TYPE, REG_ILL_ACC_TYPE);
++
++      return IRQ_HANDLED;
++}
++
++static int __init ill_acc_of_setup(void)
++{
++      struct platform_device *pdev;
++      struct device_node *np;
++      int irq;
++
++      /* somehow this driver breaks on RT5350 */
++      if (of_machine_is_compatible("ralink,rt5350-soc"))
++              return -EINVAL;
++
++      np = of_find_compatible_node(NULL, NULL, "ralink,rt3050-memc");
++      if (!np)
++              return -EINVAL;
++
++      pdev = of_find_device_by_node(np);
++      if (!pdev) {
++              pr_err("%s: failed to lookup pdev\n", np->name);
++              return -EINVAL;
++      }
++
++      irq = irq_of_parse_and_map(np, 0);
++        if (!irq) {
++              dev_err(&pdev->dev, "failed to get irq\n");
++              return -EINVAL;
++      }
++
++      if (request_irq(irq, ill_acc_irq_handler, 0, "ill_acc", &pdev->dev)) {
++              dev_err(&pdev->dev, "failed to request irq\n");
++              return -EINVAL;
++      }
++
++      rt_memc_w32(ILL_INT_STATUS, REG_ILL_ACC_TYPE);
++
++      dev_info(&pdev->dev, "irq registered\n");
++
++      return 0;
++}
++
++arch_initcall(ill_acc_of_setup);
+-- 
+1.7.10.4
+
diff --git a/target/linux/ramips/patches-3.14/0006-MIPS-ralink-add-missing-clk_set_rate-to-clk.c.patch b/target/linux/ramips/patches-3.14/0006-MIPS-ralink-add-missing-clk_set_rate-to-clk.c.patch
new file mode 100644 (file)
index 0000000..280f107
--- /dev/null
@@ -0,0 +1,32 @@
+From 979ad9f0324ad8fa5eb4a00b57d9feb061aa3200 Mon Sep 17 00:00:00 2001
+From: John Crispin <blogic@openwrt.org>
+Date: Sun, 16 Mar 2014 04:38:07 +0000
+Subject: [PATCH 06/57] MIPS: ralink: add missing clk_set_rate() to clk.c
+
+This function was missing causing allmod to fail.
+
+Signed-off-by: John Crispin <blogic@openwrt.org>
+---
+ arch/mips/ralink/clk.c |    6 ++++++
+ 1 file changed, 6 insertions(+)
+
+diff --git a/arch/mips/ralink/clk.c b/arch/mips/ralink/clk.c
+index 5d0983d..feb5a9b 100644
+--- a/arch/mips/ralink/clk.c
++++ b/arch/mips/ralink/clk.c
+@@ -56,6 +56,12 @@ unsigned long clk_get_rate(struct clk *clk)
+ }
+ EXPORT_SYMBOL_GPL(clk_get_rate);
++int clk_set_rate(struct clk *clk, unsigned long rate)
++{
++      return -1;
++}
++EXPORT_SYMBOL_GPL(clk_set_rate);
++
+ void __init plat_time_init(void)
+ {
+       struct clk *clk;
+-- 
+1.7.10.4
+
diff --git a/target/linux/ramips/patches-3.14/0007-MIPS-ralink-add-support-for-MT7620n.patch b/target/linux/ramips/patches-3.14/0007-MIPS-ralink-add-support-for-MT7620n.patch
new file mode 100644 (file)
index 0000000..3606acb
--- /dev/null
@@ -0,0 +1,73 @@
+From efc0f99cebcab21dbabcc634b9dbb963bbbbcab8 Mon Sep 17 00:00:00 2001
+From: John Crispin <blogic@openwrt.org>
+Date: Sun, 27 Jul 2014 09:23:36 +0100
+Subject: [PATCH 07/57] MIPS: ralink: add support for MT7620n
+
+This is the small version of MT7620a.
+
+Signed-off-by: John Crispin <blogic@openwrt.org>
+---
+ arch/mips/include/asm/mach-ralink/mt7620.h |    7 ++-----
+ arch/mips/ralink/mt7620.c                  |   19 ++++++++++++-------
+ 2 files changed, 14 insertions(+), 12 deletions(-)
+
+diff --git a/arch/mips/include/asm/mach-ralink/mt7620.h b/arch/mips/include/asm/mach-ralink/mt7620.h
+index 7ff9290..27b2fa9 100644
+--- a/arch/mips/include/asm/mach-ralink/mt7620.h
++++ b/arch/mips/include/asm/mach-ralink/mt7620.h
+@@ -25,11 +25,8 @@
+ #define SYSC_REG_CPLL_CONFIG0         0x54
+ #define SYSC_REG_CPLL_CONFIG1         0x58
+-#define MT7620N_CHIP_NAME0            0x33365452
+-#define MT7620N_CHIP_NAME1            0x20203235
+-
+-#define MT7620A_CHIP_NAME0            0x3637544d
+-#define MT7620A_CHIP_NAME1            0x20203032
++#define MT7620_CHIP_NAME0             0x3637544d
++#define MT7620_CHIP_NAME1             0x20203032
+ #define SYSCFG0_XTAL_FREQ_SEL         BIT(6)
+diff --git a/arch/mips/ralink/mt7620.c b/arch/mips/ralink/mt7620.c
+index 5846817..4fdee17 100644
+--- a/arch/mips/ralink/mt7620.c
++++ b/arch/mips/ralink/mt7620.c
+@@ -357,22 +357,27 @@ void prom_soc_init(struct ralink_soc_info *soc_info)
+       u32 cfg0;
+       u32 pmu0;
+       u32 pmu1;
++      u32 bga;
+       n0 = __raw_readl(sysc + SYSC_REG_CHIP_NAME0);
+       n1 = __raw_readl(sysc + SYSC_REG_CHIP_NAME1);
++      rev = __raw_readl(sysc + SYSC_REG_CHIP_REV);
++      bga = (rev >> CHIP_REV_PKG_SHIFT) & CHIP_REV_PKG_MASK;
+-      if (n0 == MT7620N_CHIP_NAME0 && n1 == MT7620N_CHIP_NAME1) {
+-              name = "MT7620N";
+-              soc_info->compatible = "ralink,mt7620n-soc";
+-      } else if (n0 == MT7620A_CHIP_NAME0 && n1 == MT7620A_CHIP_NAME1) {
++      if (n0 != MT7620_CHIP_NAME0 || n1 != MT7620_CHIP_NAME1)
++              panic("mt7620: unknown SoC, n0:%08x n1:%08x\n", n0, n1);
++
++      if (bga) {
+               name = "MT7620A";
+               soc_info->compatible = "ralink,mt7620a-soc";
+       } else {
+-              panic("mt7620: unknown SoC, n0:%08x n1:%08x", n0, n1);
++              name = "MT7620N";
++              soc_info->compatible = "ralink,mt7620n-soc";
++#ifdef CONFIG_PCI
++              panic("mt7620n is only supported for non pci kernels");
++#endif
+       }
+-      rev = __raw_readl(sysc + SYSC_REG_CHIP_REV);
+-
+       snprintf(soc_info->sys_type, RAMIPS_SYS_TYPE_LEN,
+               "Ralink %s ver:%u eco:%u",
+               name,
+-- 
+1.7.10.4
+
diff --git a/target/linux/ramips/patches-3.14/0008-MIPS-ralink-allow-manual-memory-override.patch b/target/linux/ramips/patches-3.14/0008-MIPS-ralink-allow-manual-memory-override.patch
new file mode 100644 (file)
index 0000000..bbbe7aa
--- /dev/null
@@ -0,0 +1,50 @@
+From 071e97587a291d3a5bbd614a425f46b7f90310aa Mon Sep 17 00:00:00 2001
+From: John Crispin <blogic@openwrt.org>
+Date: Sun, 16 Mar 2014 04:40:48 +0000
+Subject: [PATCH 08/57] MIPS: ralink: allow manual memory override
+
+RT5350 relies on the bootloader setting up the memc correctly.
+On sme boards the setup is incorrect leading to 32 MB being available but only 16 being recognized. Allow these boards to manually override the memory range
+.
+Signed-off-by: John Crispin <blogic@openwrt.org>
+---
+ arch/mips/ralink/of.c |   16 +++++++++++++++-
+ 1 file changed, 15 insertions(+), 1 deletion(-)
+
+diff --git a/arch/mips/ralink/of.c b/arch/mips/ralink/of.c
+index eccc552..1b81e8f 100644
+--- a/arch/mips/ralink/of.c
++++ b/arch/mips/ralink/of.c
+@@ -78,6 +78,17 @@ void __init device_tree_init(void)
+       free_bootmem(base, size);
+ }
++static int memory_dtb;
++
++static int __init early_init_dt_find_memory(unsigned long node, const char *uname,
++                                   int depth, void *data)
++{
++      if (depth == 1 && !strcmp(uname, "memory@0"))
++              memory_dtb = 1;
++
++      return 0;
++}
++
+ void __init plat_mem_setup(void)
+ {
+       set_io_port_base(KSEG1);
+@@ -88,7 +99,10 @@ void __init plat_mem_setup(void)
+        */
+       __dt_setup_arch(&__dtb_start);
+-      if (soc_info.mem_size)
++      of_scan_flat_dt(early_init_dt_find_memory, NULL);
++      if (memory_dtb)
++              of_scan_flat_dt(early_init_dt_scan_memory, NULL);
++      else if (soc_info.mem_size)
+               add_memory_region(soc_info.mem_base, soc_info.mem_size * SZ_1M,
+                                 BOOT_MEM_RAM);
+       else
+-- 
+1.7.10.4
+
diff --git a/target/linux/ramips/patches-3.14/0009-MIPS-ralink-define-the-wmac-clock-on-mt7620.patch b/target/linux/ramips/patches-3.14/0009-MIPS-ralink-define-the-wmac-clock-on-mt7620.patch
new file mode 100644 (file)
index 0000000..17ba702
--- /dev/null
@@ -0,0 +1,25 @@
+From 1cb19fe02c830e278b91498edea09fbda37c4a21 Mon Sep 17 00:00:00 2001
+From: John Crispin <blogic@openwrt.org>
+Date: Sun, 27 Jul 2014 10:13:43 +0100
+Subject: [PATCH 09/57] MIPS: ralink: define the wmac clock on mt7620
+
+Signed-off-by: John Crispin <blogic@openwrt.org>
+---
+ arch/mips/ralink/mt7620.c |    1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/arch/mips/ralink/mt7620.c b/arch/mips/ralink/mt7620.c
+index 4fdee17..c883973 100644
+--- a/arch/mips/ralink/mt7620.c
++++ b/arch/mips/ralink/mt7620.c
+@@ -336,6 +336,7 @@ void __init ralink_clk_init(void)
+       ralink_clk_add("10000500.uart", periph_rate);
+       ralink_clk_add("10000b00.spi", sys_rate);
+       ralink_clk_add("10000c00.uartlite", periph_rate);
++      ralink_clk_add("10180000.wmac", xtal_rate);
+ }
+ void __init ralink_of_remap(void)
+-- 
+1.7.10.4
+
diff --git a/target/linux/ramips/patches-3.14/0010-MIPS-ralink-define-the-wmac-clock-on-rt3883.patch b/target/linux/ramips/patches-3.14/0010-MIPS-ralink-define-the-wmac-clock-on-rt3883.patch
new file mode 100644 (file)
index 0000000..551bd2a
--- /dev/null
@@ -0,0 +1,25 @@
+From 1f17cf131fc2ae7fa2651dbe6a622dd125939718 Mon Sep 17 00:00:00 2001
+From: John Crispin <blogic@openwrt.org>
+Date: Sun, 27 Jul 2014 10:14:30 +0100
+Subject: [PATCH 10/57] MIPS: ralink: define the wmac clock on rt3883
+
+Signed-off-by: John Crispin <blogic@openwrt.org>
+---
+ arch/mips/ralink/rt3883.c |    1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/arch/mips/ralink/rt3883.c b/arch/mips/ralink/rt3883.c
+index b474ac2..58b5b9f 100644
+--- a/arch/mips/ralink/rt3883.c
++++ b/arch/mips/ralink/rt3883.c
+@@ -204,6 +204,7 @@ void __init ralink_clk_init(void)
+       ralink_clk_add("10000b00.spi", sys_rate);
+       ralink_clk_add("10000c00.uartlite", 40000000);
+       ralink_clk_add("10100000.ethernet", sys_rate);
++      ralink_clk_add("10180000.wmac", 40000000);
+ }
+ void __init ralink_of_remap(void)
+-- 
+1.7.10.4
+
diff --git a/target/linux/ramips/patches-3.14/0011-MIPS-ralink-add-rt2880-wmac-clock.patch b/target/linux/ramips/patches-3.14/0011-MIPS-ralink-add-rt2880-wmac-clock.patch
new file mode 100644 (file)
index 0000000..fd8c28a
--- /dev/null
@@ -0,0 +1,34 @@
+From bf4f5250117cd65a78903b8ce302499806416ed1 Mon Sep 17 00:00:00 2001
+From: John Crispin <blogic@openwrt.org>
+Date: Mon, 4 Aug 2014 09:52:22 +0200
+Subject: [PATCH 11/57] MIPS: ralink: add rt2880 wmac clock
+
+Signed-off-by: John Crispin <blogic@openwrt.org>
+---
+ arch/mips/ralink/rt288x.c |    3 ++-
+ 1 file changed, 2 insertions(+), 1 deletion(-)
+
+diff --git a/arch/mips/ralink/rt288x.c b/arch/mips/ralink/rt288x.c
+index f87de1a..90e8934 100644
+--- a/arch/mips/ralink/rt288x.c
++++ b/arch/mips/ralink/rt288x.c
+@@ -76,7 +76,7 @@ struct ralink_pinmux rt_gpio_pinmux = {
+ void __init ralink_clk_init(void)
+ {
+-      unsigned long cpu_rate;
++      unsigned long cpu_rate, wmac_rate = 40000000;
+       u32 t = rt_sysc_r32(SYSC_REG_SYSTEM_CONFIG);
+       t = ((t >> SYSTEM_CONFIG_CPUCLK_SHIFT) & SYSTEM_CONFIG_CPUCLK_MASK);
+@@ -101,6 +101,7 @@ void __init ralink_clk_init(void)
+       ralink_clk_add("300500.uart", cpu_rate / 2);
+       ralink_clk_add("300c00.uartlite", cpu_rate / 2);
+       ralink_clk_add("400000.ethernet", cpu_rate / 2);
++      ralink_clk_add("480000.wmac", wmac_rate);
+ }
+ void __init ralink_of_remap(void)
+-- 
+1.7.10.4
+
diff --git a/target/linux/ramips/patches-3.14/0012-MIPS-ralink-add-MT7621-support.patch b/target/linux/ramips/patches-3.14/0012-MIPS-ralink-add-MT7621-support.patch
new file mode 100644 (file)
index 0000000..ef077e1
--- /dev/null
@@ -0,0 +1,751 @@
+From c8c69923236f2f3f184ddcc7eb41c113b5cc3223 Mon Sep 17 00:00:00 2001
+From: John Crispin <blogic@openwrt.org>
+Date: Sun, 27 Jul 2014 10:57:40 +0100
+Subject: [PATCH 12/57] MIPS: ralink: add MT7621 support
+
+Signed-off-by: John Crispin <blogic@openwrt.org>
+---
+ arch/mips/include/asm/gic.h                |    4 +
+ arch/mips/include/asm/mach-ralink/irq.h    |    9 +
+ arch/mips/include/asm/mach-ralink/mt7621.h |   39 ++++
+ arch/mips/kernel/vmlinux.lds.S             |    1 +
+ arch/mips/ralink/Kconfig                   |   18 ++
+ arch/mips/ralink/Makefile                  |    7 +-
+ arch/mips/ralink/Platform                  |    5 +
+ arch/mips/ralink/irq-gic.c                 |  271 ++++++++++++++++++++++++++++
+ arch/mips/ralink/malta-amon.c              |   81 +++++++++
+ arch/mips/ralink/mt7621.c                  |  183 +++++++++++++++++++
+ 10 files changed, 617 insertions(+), 1 deletion(-)
+ create mode 100644 arch/mips/include/asm/mach-ralink/irq.h
+ create mode 100644 arch/mips/include/asm/mach-ralink/mt7621.h
+ create mode 100644 arch/mips/ralink/irq-gic.c
+ create mode 100644 arch/mips/ralink/malta-amon.c
+ create mode 100644 arch/mips/ralink/mt7621.c
+
+diff --git a/arch/mips/include/asm/gic.h b/arch/mips/include/asm/gic.h
+index b2e3e93..29fba50 100644
+--- a/arch/mips/include/asm/gic.h
++++ b/arch/mips/include/asm/gic.h
+@@ -19,7 +19,11 @@
+ #define GIC_TRIG_EDGE                 1
+ #define GIC_TRIG_LEVEL                        0
++#define GIC_NUM_INTRS                 64
++
++#ifndef GIC_NUM_INTRS
+ #define GIC_NUM_INTRS                 (24 + NR_CPUS * 2)
++#endif
+ #define MSK(n) ((1 << (n)) - 1)
+ #define REG32(addr)           (*(volatile unsigned int *) (addr))
+diff --git a/arch/mips/include/asm/mach-ralink/irq.h b/arch/mips/include/asm/mach-ralink/irq.h
+new file mode 100644
+index 0000000..4321865
+--- /dev/null
++++ b/arch/mips/include/asm/mach-ralink/irq.h
+@@ -0,0 +1,9 @@
++#ifndef __ASM_MACH_RALINK_IRQ_H
++#define __ASM_MACH_RALINK_IRQ_H
++
++#define GIC_NUM_INTRS 64
++#define NR_IRQS 256
++
++#include_next <irq.h>
++
++#endif
+diff --git a/arch/mips/include/asm/mach-ralink/mt7621.h b/arch/mips/include/asm/mach-ralink/mt7621.h
+new file mode 100644
+index 0000000..21c8dc2
+--- /dev/null
++++ b/arch/mips/include/asm/mach-ralink/mt7621.h
+@@ -0,0 +1,39 @@
++/*
++ * This program is free software; you can redistribute it and/or modify it
++ * under the terms of the GNU General Public License version 2 as published
++ * by the Free Software Foundation.
++ *
++ * Parts of this file are based on Ralink's 2.6.21 BSP
++ *
++ * Copyright (C) 2008-2011 Gabor Juhos <juhosg@openwrt.org>
++ * Copyright (C) 2008 Imre Kaloz <kaloz@openwrt.org>
++ * Copyright (C) 2013 John Crispin <blogic@openwrt.org>
++ */
++
++#ifndef _MT7621_REGS_H_
++#define _MT7621_REGS_H_
++
++#define MT7621_SYSC_BASE              0x1E000000
++
++#define SYSC_REG_CHIP_NAME0           0x00
++#define SYSC_REG_CHIP_NAME1           0x04
++#define SYSC_REG_CHIP_REV             0x0c
++#define SYSC_REG_SYSTEM_CONFIG0               0x10
++#define SYSC_REG_SYSTEM_CONFIG1               0x14
++
++#define CHIP_REV_PKG_MASK             0x1
++#define CHIP_REV_PKG_SHIFT            16
++#define CHIP_REV_VER_MASK             0xf
++#define CHIP_REV_VER_SHIFT            8
++#define CHIP_REV_ECO_MASK             0xf
++
++#define MT7621_DRAM_BASE                0x0
++#define MT7621_DDR2_SIZE_MIN          32
++#define MT7621_DDR2_SIZE_MAX          256
++
++#define MT7621_CHIP_NAME0             0x3637544D
++#define MT7621_CHIP_NAME1             0x20203132
++
++#define MIPS_GIC_IRQ_BASE           (MIPS_CPU_IRQ_BASE + 8)
++
++#endif
+diff --git a/arch/mips/kernel/vmlinux.lds.S b/arch/mips/kernel/vmlinux.lds.S
+index 3b46f7c..fa925b7 100644
+--- a/arch/mips/kernel/vmlinux.lds.S
++++ b/arch/mips/kernel/vmlinux.lds.S
+@@ -51,6 +51,7 @@ SECTIONS
+       /* read-only */
+       _text = .;      /* Text and read-only data */
+       .text : {
++              /*. = . + 0x8000; */
+               TEXT_TEXT
+               SCHED_TEXT
+               LOCK_TEXT
+diff --git a/arch/mips/ralink/Kconfig b/arch/mips/ralink/Kconfig
+index 1bfd1c1..6a04360 100644
+--- a/arch/mips/ralink/Kconfig
++++ b/arch/mips/ralink/Kconfig
+@@ -7,6 +7,11 @@ config CLKEVT_RT3352
+       select CLKSRC_OF
+       select CLKSRC_MMIO
++config IRQ_INTC
++      bool
++      default y
++      depends on !SOC_MT7621
++
+ choice
+       prompt "Ralink SoC selection"
+       default SOC_RT305X
+@@ -34,6 +39,15 @@ choice
+               select USB_ARCH_HAS_OHCI
+               select USB_ARCH_HAS_EHCI
++      config SOC_MT7621
++              bool "MT7621"
++              select MIPS_CPU_SCACHE
++              select SYS_SUPPORTS_MULTITHREADING
++              select SYS_SUPPORTS_SMP
++              select SYS_SUPPORTS_MIPS_CMP
++              select IRQ_GIC
++              select HW_HAS_PCI
++
+ endchoice
+ choice
+@@ -61,6 +75,10 @@ choice
+               bool "MT7620A eval kit"
+               depends on SOC_MT7620
++      config DTB_MT7621_EVAL
++              bool "MT7621 eval kit"
++              depends on SOC_MT7621
++
+ endchoice
+ endif
+diff --git a/arch/mips/ralink/Makefile b/arch/mips/ralink/Makefile
+index fc57c16..ad18cdf 100644
+--- a/arch/mips/ralink/Makefile
++++ b/arch/mips/ralink/Makefile
+@@ -6,16 +6,21 @@
+ # Copyright (C) 2009-2011 Gabor Juhos <juhosg@openwrt.org>
+ # Copyright (C) 2013 John Crispin <blogic@openwrt.org>
+-obj-y := prom.o of.o reset.o clk.o irq.o timer.o
++obj-y := prom.o of.o reset.o clk.o timer.o
+ obj-$(CONFIG_CLKEVT_RT3352) += cevt-rt3352.o
+ obj-$(CONFIG_RALINK_ILL_ACC) += ill_acc.o
++obj-$(CONFIG_IRQ_INTC) += irq.o
++obj-$(CONFIG_IRQ_GIC) += irq-gic.o
++obj-$(CONFIG_MIPS_MT_SMP) += malta-amon.o
++
+ obj-$(CONFIG_SOC_RT288X) += rt288x.o
+ obj-$(CONFIG_SOC_RT305X) += rt305x.o
+ obj-$(CONFIG_SOC_RT3883) += rt3883.o
+ obj-$(CONFIG_SOC_MT7620) += mt7620.o
++obj-$(CONFIG_SOC_MT7621) += mt7621.o
+ obj-$(CONFIG_EARLY_PRINTK) += early_printk.o
+diff --git a/arch/mips/ralink/Platform b/arch/mips/ralink/Platform
+index 6d9c8c4..6095fcc 100644
+--- a/arch/mips/ralink/Platform
++++ b/arch/mips/ralink/Platform
+@@ -27,3 +27,8 @@ cflags-$(CONFIG_SOC_RT3883)  += -I$(srctree)/arch/mips/include/asm/mach-ralink/rt
+ #
+ load-$(CONFIG_SOC_MT7620)     += 0xffffffff80000000
+ cflags-$(CONFIG_SOC_MT7620)   += -I$(srctree)/arch/mips/include/asm/mach-ralink/mt7620
++
++# Ralink MT7621
++#
++load-$(CONFIG_SOC_MT7621)     += 0xffffffff80001000
++cflags-$(CONFIG_SOC_MT7621)   += -I$(srctree)/arch/mips/include/asm/mach-ralink/mt7621
+diff --git a/arch/mips/ralink/irq-gic.c b/arch/mips/ralink/irq-gic.c
+new file mode 100644
+index 0000000..0122d42
+--- /dev/null
++++ b/arch/mips/ralink/irq-gic.c
+@@ -0,0 +1,271 @@
++#include <linux/init.h>
++#include <linux/sched.h>
++#include <linux/slab.h>
++#include <linux/interrupt.h>
++#include <linux/kernel_stat.h>
++#include <linux/hardirq.h>
++#include <linux/preempt.h>
++#include <linux/irqdomain.h>
++#include <linux/of_platform.h>
++#include <linux/of_address.h>
++#include <linux/of_irq.h>
++
++#include <asm/irq_cpu.h>
++#include <asm/mipsregs.h>
++
++#include <asm/irq.h>
++#include <asm/setup.h>
++
++#include <asm/gic.h>
++#include <asm/gcmpregs.h>
++
++#include <asm/mach-ralink/mt7621.h>
++
++unsigned long _gcmp_base;
++static int gic_resched_int_base = 56;
++static int gic_call_int_base = 60;
++static struct irq_chip *irq_gic;
++static struct gic_intr_map gic_intr_map[GIC_NUM_INTRS];
++
++#if defined(CONFIG_MIPS_MT_SMP)
++static int gic_resched_int_base;
++static int gic_call_int_base;
++
++#define GIC_RESCHED_INT(cpu) (gic_resched_int_base+(cpu))
++#define GIC_CALL_INT(cpu) (gic_call_int_base+(cpu))
++
++static irqreturn_t ipi_resched_interrupt(int irq, void *dev_id)
++{
++      scheduler_ipi();
++
++      return IRQ_HANDLED;
++}
++
++static irqreturn_t
++ipi_call_interrupt(int irq, void *dev_id)
++{
++      smp_call_function_interrupt();
++
++      return IRQ_HANDLED;
++}
++
++static struct irqaction irq_resched = {
++        .handler        = ipi_resched_interrupt,
++        .flags          = IRQF_DISABLED|IRQF_PERCPU,
++        .name           = "ipi resched"
++};
++
++static struct irqaction irq_call = {
++        .handler        = ipi_call_interrupt,
++        .flags          = IRQF_DISABLED|IRQF_PERCPU,
++        .name           = "ipi call"
++};
++
++#endif
++
++static void __init
++gic_fill_map(void)
++{
++      int i;
++
++      for (i = 0; i < ARRAY_SIZE(gic_intr_map); i++) {
++              gic_intr_map[i].cpunum = 0;
++              gic_intr_map[i].pin = GIC_CPU_INT0;
++              gic_intr_map[i].polarity = GIC_POL_POS;
++              gic_intr_map[i].trigtype = GIC_TRIG_LEVEL;
++              gic_intr_map[i].flags = GIC_FLAG_IPI;
++      }
++
++#if defined(CONFIG_MIPS_MT_SMP)
++      {
++              int cpu;
++
++              gic_call_int_base = ARRAY_SIZE(gic_intr_map) - nr_cpu_ids;
++              gic_resched_int_base = gic_call_int_base - nr_cpu_ids;
++
++              i = gic_resched_int_base;
++
++              for (cpu = 0; cpu < nr_cpu_ids; cpu++) {
++                      gic_intr_map[i + cpu].cpunum = cpu;
++                      gic_intr_map[i + cpu].pin = GIC_CPU_INT1;
++                      gic_intr_map[i + cpu].trigtype = GIC_TRIG_EDGE;
++
++                      gic_intr_map[i + cpu + nr_cpu_ids].cpunum = cpu;
++                      gic_intr_map[i + cpu + nr_cpu_ids].pin = GIC_CPU_INT2;
++                      gic_intr_map[i + cpu + nr_cpu_ids].trigtype = GIC_TRIG_EDGE;
++              }
++      }
++#endif
++}
++
++void
++gic_irq_ack(struct irq_data *d)
++{
++      int irq = (d->irq - gic_irq_base);
++
++      GIC_CLR_INTR_MASK(irq);
++
++      if (gic_irq_flags[irq] & GIC_TRIG_EDGE)
++              GICWRITE(GIC_REG(SHARED, GIC_SH_WEDGE), irq);
++}
++
++void
++gic_finish_irq(struct irq_data *d)
++{
++      GIC_SET_INTR_MASK(d->irq - gic_irq_base);
++}
++
++void __init
++gic_platform_init(int irqs, struct irq_chip *irq_controller)
++{
++      irq_gic = irq_controller;
++}
++
++static void
++gic_irqdispatch(void)
++{
++      unsigned int irq = gic_get_int();
++
++      if (likely(irq < GIC_NUM_INTRS))
++              do_IRQ(MIPS_GIC_IRQ_BASE + irq);
++      else {
++              pr_err("Spurious GIC Interrupt!\n");
++              spurious_interrupt();
++      }
++
++}
++
++static void
++vi_timer_irqdispatch(void)
++{
++      do_IRQ(cp0_compare_irq);
++}
++
++#if defined(CONFIG_MIPS_MT_SMP)
++unsigned int
++plat_ipi_call_int_xlate(unsigned int cpu)
++{
++      return GIC_CALL_INT(cpu);
++}
++
++unsigned int
++plat_ipi_resched_int_xlate(unsigned int cpu)
++{
++      return GIC_RESCHED_INT(cpu);
++}
++#endif
++
++asmlinkage void
++plat_irq_dispatch(void)
++{
++      unsigned int pending = read_c0_status() & read_c0_cause() & ST0_IM;
++
++      if (unlikely(!pending)) {
++              pr_err("Spurious CP0 Interrupt!\n");
++              spurious_interrupt();
++      } else {
++              if (pending & CAUSEF_IP7)
++                      do_IRQ(cp0_compare_irq);
++
++              if (pending & (CAUSEF_IP4 | CAUSEF_IP3 | CAUSEF_IP2))
++                      gic_irqdispatch();
++      }
++}
++
++unsigned int __cpuinit
++get_c0_compare_int(void)
++{
++      return CP0_LEGACY_COMPARE_IRQ;
++}
++
++static int
++gic_map(struct irq_domain *d, unsigned int irq, irq_hw_number_t hw)
++{
++      irq_set_chip_and_handler(irq, irq_gic,
++#if defined(CONFIG_MIPS_MT_SMP)
++              (hw >= gic_resched_int_base) ?
++                      handle_percpu_irq :
++#endif
++                      handle_level_irq);
++
++      return 0;
++}
++
++static const struct irq_domain_ops irq_domain_ops = {
++      .xlate = irq_domain_xlate_onecell,
++      .map = gic_map,
++};
++
++static int __init
++of_gic_init(struct device_node *node,
++                              struct device_node *parent)
++{
++      struct irq_domain *domain;
++      struct resource gcmp = { 0 }, gic = { 0 };
++      unsigned int gic_rev;
++      int i;
++
++      if (of_address_to_resource(node, 0, &gic))
++              panic("Failed to get gic memory range");
++      if (request_mem_region(gic.start, resource_size(&gic),
++                              gic.name) < 0)
++              panic("Failed to request gic memory");
++      if (of_address_to_resource(node, 2, &gcmp))
++              panic("Failed to get gic memory range");
++      if (request_mem_region(gcmp.start, resource_size(&gcmp),
++                              gcmp.name) < 0)
++              panic("Failed to request gcmp memory");
++
++      _gcmp_base = (unsigned long) ioremap_nocache(gcmp.start, resource_size(&gcmp));
++      if (!_gcmp_base)
++              panic("Failed to remap gcmp memory\n");
++
++      if ((GCMPGCB(GCMPB) & GCMP_GCB_GCMPB_GCMPBASE_MSK) != gcmp.start)
++              panic("Failed to find gcmp core\n");
++
++      /* tell the gcmp where to find the gic */
++      GCMPGCB(GICBA) = gic.start | GCMP_GCB_GICBA_EN_MSK;
++      gic_present = 1;
++      if (cpu_has_vint) {
++              set_vi_handler(2, gic_irqdispatch);
++              set_vi_handler(3, gic_irqdispatch);
++              set_vi_handler(4, gic_irqdispatch);
++              set_vi_handler(7, vi_timer_irqdispatch);
++      }
++
++      gic_fill_map();
++
++      gic_init(gic.start, resource_size(&gic), gic_intr_map,
++              ARRAY_SIZE(gic_intr_map), MIPS_GIC_IRQ_BASE);
++
++      GICREAD(GIC_REG(SHARED, GIC_SH_REVISIONID), gic_rev);
++      pr_info("gic: revision %d.%d\n", (gic_rev >> 8) & 0xff, gic_rev & 0xff);
++
++      domain = irq_domain_add_legacy(node, GIC_NUM_INTRS, MIPS_GIC_IRQ_BASE,
++                      0, &irq_domain_ops, NULL);
++      if (!domain)
++              panic("Failed to add irqdomain");
++
++#if defined(CONFIG_MIPS_MT_SMP)
++      for (i = 0; i < nr_cpu_ids; i++) {
++              setup_irq(MIPS_GIC_IRQ_BASE + GIC_RESCHED_INT(i), &irq_resched);
++              setup_irq(MIPS_GIC_IRQ_BASE + GIC_CALL_INT(i), &irq_call);
++      }
++#endif
++
++      change_c0_status(ST0_IM, STATUSF_IP7 | STATUSF_IP4 | STATUSF_IP3 |
++                              STATUSF_IP2);
++      return 0;
++}
++
++static struct of_device_id __initdata of_irq_ids[] = {
++      { .compatible = "mti,cpu-interrupt-controller", .data = mips_cpu_intc_init },
++      { .compatible = "ralink,mt7621-gic", .data = of_gic_init },
++      {},
++};
++
++void __init
++arch_init_irq(void)
++{
++      of_irq_init(of_irq_ids);
++}
+diff --git a/arch/mips/ralink/malta-amon.c b/arch/mips/ralink/malta-amon.c
+new file mode 100644
+index 0000000..1e47844
+--- /dev/null
++++ b/arch/mips/ralink/malta-amon.c
+@@ -0,0 +1,81 @@
++/*
++ * Copyright (C) 2007  MIPS Technologies, Inc.
++ *    All rights reserved.
++
++ *  This program is free software; you can distribute it and/or modify it
++ *  under the terms 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.
++ *
++ *  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.,
++ *  59 Temple Place - Suite 330, Boston MA 02111-1307, USA.
++ *
++ * Arbitrary Monitor interface
++ */
++
++#include <linux/kernel.h>
++#include <linux/init.h>
++#include <linux/smp.h>
++
++#include <asm/addrspace.h>
++#include <asm/mips-boards/launch.h>
++#include <asm/mipsmtregs.h>
++
++int amon_cpu_avail(int cpu)
++{
++      struct cpulaunch *launch = (struct cpulaunch *)CKSEG0ADDR(CPULAUNCH);
++
++      if (cpu < 0 || cpu >= NCPULAUNCH) {
++              pr_debug("avail: cpu%d is out of range\n", cpu);
++              return 0;
++      }
++
++      launch += cpu;
++      if (!(launch->flags & LAUNCH_FREADY)) {
++              pr_debug("avail: cpu%d is not ready\n", cpu);
++              return 0;
++      }
++      if (launch->flags & (LAUNCH_FGO|LAUNCH_FGONE)) {
++              pr_debug("avail: too late.. cpu%d is already gone\n", cpu);
++              return 0;
++      }
++
++      return 1;
++}
++
++void amon_cpu_start(int cpu,
++                  unsigned long pc, unsigned long sp,
++                  unsigned long gp, unsigned long a0)
++{
++      volatile struct cpulaunch *launch =
++              (struct cpulaunch  *)CKSEG0ADDR(CPULAUNCH);
++
++      if (!amon_cpu_avail(cpu))
++              return;
++      if (cpu == smp_processor_id()) {
++              pr_debug("launch: I am cpu%d!\n", cpu);
++              return;
++      }
++      launch += cpu;
++
++      pr_debug("launch: starting cpu%d\n", cpu);
++
++      launch->pc = pc;
++      launch->gp = gp;
++      launch->sp = sp;
++      launch->a0 = a0;
++
++      smp_wmb();              /* Target must see parameters before go */
++      launch->flags |= LAUNCH_FGO;
++      smp_wmb();              /* Target must see go before we poll  */
++
++      while ((launch->flags & LAUNCH_FGONE) == 0)
++              ;
++      smp_rmb();      /* Target will be updating flags soon */
++      pr_debug("launch: cpu%d gone!\n", cpu);
++}
+diff --git a/arch/mips/ralink/mt7621.c b/arch/mips/ralink/mt7621.c
+new file mode 100644
+index 0000000..2aac87c
+--- /dev/null
++++ b/arch/mips/ralink/mt7621.c
+@@ -0,0 +1,183 @@
++/*
++ * This program is free software; you can redistribute it and/or modify it
++ * under the terms of the GNU General Public License version 2 as published
++ * by the Free Software Foundation.
++ *
++ * Parts of this file are based on Ralink's 2.6.21 BSP
++ *
++ * Copyright (C) 2008-2011 Gabor Juhos <juhosg@openwrt.org>
++ * Copyright (C) 2008 Imre Kaloz <kaloz@openwrt.org>
++ * Copyright (C) 2013 John Crispin <blogic@openwrt.org>
++ */
++
++#include <linux/kernel.h>
++#include <linux/init.h>
++#include <linux/module.h>
++#include <asm/gcmpregs.h>
++
++#include <asm/mipsregs.h>
++#include <asm/smp-ops.h>
++#include <asm/mach-ralink/ralink_regs.h>
++#include <asm/mach-ralink/mt7621.h>
++
++#include <pinmux.h>
++
++#include "common.h"
++
++#define SYSC_REG_SYSCFG               0x10
++#define SYSC_REG_CPLL_CLKCFG0 0x2c
++#define SYSC_REG_CUR_CLK_STS  0x44
++#define CPU_CLK_SEL           (BIT(30) | BIT(31))
++
++#define MT7621_GPIO_MODE_UART1                1
++#define MT7621_GPIO_MODE_I2C          2
++#define MT7621_GPIO_MODE_UART2                3
++#define MT7621_GPIO_MODE_UART3                5
++#define MT7621_GPIO_MODE_JTAG         7
++#define MT7621_GPIO_MODE_WDT_MASK     0x3
++#define MT7621_GPIO_MODE_WDT_SHIFT    8
++#define MT7621_GPIO_MODE_WDT_GPIO     1
++#define MT7621_GPIO_MODE_PCIE_RST     0
++#define MT7621_GPIO_MODE_PCIE_REF     2
++#define MT7621_GPIO_MODE_PCIE_MASK    0x3
++#define MT7621_GPIO_MODE_PCIE_SHIFT   10
++#define MT7621_GPIO_MODE_PCIE_GPIO    1
++#define MT7621_GPIO_MODE_MDIO         12
++#define MT7621_GPIO_MODE_RGMII1               14
++#define MT7621_GPIO_MODE_RGMII2               15
++#define MT7621_GPIO_MODE_SPI_MASK     0x3
++#define MT7621_GPIO_MODE_SPI_SHIFT    16
++#define MT7621_GPIO_MODE_SPI_GPIO     1
++#define MT7621_GPIO_MODE_SDHCI_MASK   0x3
++#define MT7621_GPIO_MODE_SDHCI_SHIFT  18
++#define MT7621_GPIO_MODE_SDHCI_GPIO   1
++
++static struct rt2880_pmx_func uart1_grp[] =  { FUNC("uart1", 0, 1, 2) };
++static struct rt2880_pmx_func i2c_grp[] =  { FUNC("i2c", 0, 3, 2) };
++static struct rt2880_pmx_func uart3_grp[] = { FUNC("uart3", 0, 5, 4) };
++static struct rt2880_pmx_func uart2_grp[] = { FUNC("uart2", 0, 9, 4) };
++static struct rt2880_pmx_func jtag_grp[] = { FUNC("jtag", 0, 13, 5) };
++static struct rt2880_pmx_func wdt_grp[] = {
++      FUNC("wdt rst", 0, 18, 1),
++      FUNC("wdt refclk", 2, 18, 1),
++};
++static struct rt2880_pmx_func pcie_rst_grp[] = {
++      FUNC("pcie rst", MT7621_GPIO_MODE_PCIE_RST, 19, 1),
++      FUNC("pcie refclk", MT7621_GPIO_MODE_PCIE_REF, 19, 1)
++};
++static struct rt2880_pmx_func mdio_grp[] = { FUNC("mdio", 0, 20, 2) };
++static struct rt2880_pmx_func rgmii2_grp[] = { FUNC("rgmii2", 0, 22, 12) };
++static struct rt2880_pmx_func spi_grp[] = {
++      FUNC("spi", 0, 34, 7),
++      FUNC("nand", 2, 34, 8),
++};
++static struct rt2880_pmx_func sdhci_grp[] = {
++      FUNC("sdhci", 0, 41, 8),
++      FUNC("nand", 2, 41, 8),
++};
++static struct rt2880_pmx_func rgmii1_grp[] = { FUNC("rgmii1", 0, 49, 12) };
++
++static struct rt2880_pmx_group mt7621_pinmux_data[] = {
++      GRP("uart1", uart1_grp, 1, MT7621_GPIO_MODE_UART1),
++      GRP("i2c", i2c_grp, 1, MT7621_GPIO_MODE_I2C),
++      GRP("uart3", uart2_grp, 1, MT7621_GPIO_MODE_UART2),
++      GRP("uart2", uart3_grp, 1, MT7621_GPIO_MODE_UART3),
++      GRP("jtag", jtag_grp, 1, MT7621_GPIO_MODE_JTAG),
++      GRP_G("wdt", wdt_grp, MT7621_GPIO_MODE_WDT_MASK,
++              MT7621_GPIO_MODE_WDT_GPIO, MT7621_GPIO_MODE_WDT_SHIFT),
++      GRP_G("pcie", pcie_rst_grp, MT7621_GPIO_MODE_PCIE_MASK,
++              MT7621_GPIO_MODE_PCIE_GPIO, MT7621_GPIO_MODE_PCIE_SHIFT),
++      GRP("mdio", mdio_grp, 1, MT7621_GPIO_MODE_MDIO),
++      GRP("rgmii2", rgmii2_grp, 1, MT7621_GPIO_MODE_RGMII2),
++      GRP_G("spi", spi_grp, MT7621_GPIO_MODE_SPI_MASK,
++              MT7621_GPIO_MODE_SPI_GPIO, MT7621_GPIO_MODE_SPI_SHIFT),
++      GRP_G("sdhci", sdhci_grp, MT7621_GPIO_MODE_SDHCI_MASK,
++              MT7621_GPIO_MODE_SDHCI_GPIO, MT7621_GPIO_MODE_SDHCI_SHIFT),
++      GRP("rgmii1", rgmii1_grp, 1, MT7621_GPIO_MODE_RGMII1),
++      { 0 }
++};
++
++void __init ralink_clk_init(void)
++{
++      int cpu_fdiv = 0;
++      int cpu_ffrac = 0;
++      int fbdiv = 0;
++      u32 clk_sts, syscfg;
++      u8 clk_sel = 0, xtal_mode;
++      u32 cpu_clk;
++
++      if ((rt_sysc_r32(SYSC_REG_CPLL_CLKCFG0) & CPU_CLK_SEL) != 0)
++              clk_sel = 1;
++
++      switch (clk_sel) {
++      case 0:
++              clk_sts = rt_sysc_r32(SYSC_REG_CUR_CLK_STS);
++              cpu_fdiv = ((clk_sts >> 8) & 0x1F);
++              cpu_ffrac = (clk_sts & 0x1F);
++              cpu_clk = (500 * cpu_ffrac / cpu_fdiv) * 1000 * 1000;
++              break;
++
++      case 1:
++              fbdiv = ((rt_sysc_r32(0x648) >> 4) & 0x7F) + 1;
++              syscfg = rt_sysc_r32(SYSC_REG_SYSCFG);
++              xtal_mode = (syscfg >> 6) & 0x7;
++              if(xtal_mode >= 6) { //25Mhz Xtal
++                      cpu_clk = 25 * fbdiv * 1000 * 1000;
++              } else if(xtal_mode >=3) { //40Mhz Xtal
++                      cpu_clk = 40 * fbdiv * 1000 * 1000;
++              } else { // 20Mhz Xtal
++                      cpu_clk = 20 * fbdiv * 1000 * 1000;
++              }
++              break;
++      }
++      cpu_clk = 880000000;
++      ralink_clk_add("cpu", cpu_clk);
++      ralink_clk_add("1e000b00.spi", 50000000);
++      ralink_clk_add("1e000c00.uartlite", 50000000);
++      ralink_clk_add("1e000d00.uart", 50000000);
++}
++
++void __init ralink_of_remap(void)
++{
++      rt_sysc_membase = plat_of_remap_node("mtk,mt7621-sysc");
++      rt_memc_membase = plat_of_remap_node("mtk,mt7621-memc");
++
++      if (!rt_sysc_membase || !rt_memc_membase)
++              panic("Failed to remap core resources");
++}
++
++void prom_soc_init(struct ralink_soc_info *soc_info)
++{
++      void __iomem *sysc = (void __iomem *) KSEG1ADDR(MT7621_SYSC_BASE);
++      unsigned char *name = NULL;
++      u32 n0;
++      u32 n1;
++      u32 rev;
++
++      n0 = __raw_readl(sysc + SYSC_REG_CHIP_NAME0);
++      n1 = __raw_readl(sysc + SYSC_REG_CHIP_NAME1);
++
++      if (n0 == MT7621_CHIP_NAME0 && n1 == MT7621_CHIP_NAME1) {
++              name = "MT7621";
++              soc_info->compatible = "mtk,mt7621-soc";
++      } else {
++              panic("mt7621: unknown SoC, n0:%08x n1:%08x\n", n0, n1);
++      }
++
++      rev = __raw_readl(sysc + SYSC_REG_CHIP_REV);
++
++      snprintf(soc_info->sys_type, RAMIPS_SYS_TYPE_LEN,
++              "Mediatek %s ver:%u eco:%u",
++              name,
++              (rev >> CHIP_REV_VER_SHIFT) & CHIP_REV_VER_MASK,
++              (rev & CHIP_REV_ECO_MASK));
++
++      soc_info->mem_size_min = MT7621_DDR2_SIZE_MIN;
++      soc_info->mem_size_max = MT7621_DDR2_SIZE_MAX;
++      soc_info->mem_base = MT7621_DRAM_BASE;
++
++      rt2880_pinmux_data = mt7621_pinmux_data;
++
++      if (register_cmp_smp_ops())
++              panic("failed to register_vsmp_smp_ops()");
++}
+-- 
+1.7.10.4
+
diff --git a/target/linux/ramips/patches-3.14/0013-MIPS-ralink-add-MT7621-defconfig.patch b/target/linux/ramips/patches-3.14/0013-MIPS-ralink-add-MT7621-defconfig.patch
new file mode 100644 (file)
index 0000000..831f2a7
--- /dev/null
@@ -0,0 +1,217 @@
+From 8f92eac5ace0f834ec069b4bb8e9ad38f162de0e Mon Sep 17 00:00:00 2001
+From: John Crispin <blogic@openwrt.org>
+Date: Mon, 27 Jan 2014 13:12:41 +0000
+Subject: [PATCH 13/57] MIPS: ralink: add MT7621 defconfig
+
+Signed-off-by: John Crispin <blogic@openwrt.org>
+---
+ arch/mips/configs/mt7621_defconfig |  197 ++++++++++++++++++++++++++++++++++++
+ 1 file changed, 197 insertions(+)
+ create mode 100644 arch/mips/configs/mt7621_defconfig
+
+diff --git a/arch/mips/configs/mt7621_defconfig b/arch/mips/configs/mt7621_defconfig
+new file mode 100644
+index 0000000..7719471
+--- /dev/null
++++ b/arch/mips/configs/mt7621_defconfig
+@@ -0,0 +1,197 @@
++# CONFIG_LOCALVERSION_AUTO is not set
++CONFIG_SYSVIPC=y
++CONFIG_HIGH_RES_TIMERS=y
++CONFIG_RCU_FANOUT=32
++CONFIG_UIDGID_STRICT_TYPE_CHECKS=y
++CONFIG_BLK_DEV_INITRD=y
++CONFIG_INITRAMFS_SOURCE="/openwrt/trunk/build_dir/target-mipsel_24kec+dsp_uClibc-0.9.33.2/root-ramips /openwrt/trunk/target/linux/generic/image/initramfs-base-files.txt"
++CONFIG_INITRAMFS_ROOT_UID=1000
++CONFIG_INITRAMFS_ROOT_GID=1000
++# CONFIG_RD_GZIP is not set
++CONFIG_CC_OPTIMIZE_FOR_SIZE=y
++# CONFIG_AIO is not set
++CONFIG_EMBEDDED=y
++# CONFIG_VM_EVENT_COUNTERS is not set
++# CONFIG_SLUB_DEBUG is not set
++# CONFIG_COMPAT_BRK is not set
++CONFIG_MODULES=y
++CONFIG_MODULE_UNLOAD=y
++# CONFIG_BLK_DEV_BSG is not set
++CONFIG_PARTITION_ADVANCED=y
++# CONFIG_IOSCHED_CFQ is not set
++CONFIG_SMP=y
++CONFIG_NR_CPUS=4
++CONFIG_SCHED_SMT=y
++# CONFIG_COMPACTION is not set
++# CONFIG_CROSS_MEMORY_ATTACH is not set
++# CONFIG_SECCOMP is not set
++CONFIG_HZ_100=y
++CONFIG_CMDLINE_BOOL=y
++CONFIG_CMDLINE="rootfstype=squashfs,jffs2"
++# CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS is not set
++CONFIG_NET=y
++CONFIG_PACKET=y
++CONFIG_UNIX=y
++CONFIG_INET=y
++CONFIG_IP_MULTICAST=y
++CONFIG_IP_ADVANCED_ROUTER=y
++CONFIG_IP_MULTIPLE_TABLES=y
++CONFIG_IP_ROUTE_MULTIPATH=y
++CONFIG_IP_ROUTE_VERBOSE=y
++CONFIG_IP_MROUTE=y
++CONFIG_IP_MROUTE_MULTIPLE_TABLES=y
++CONFIG_ARPD=y
++CONFIG_SYN_COOKIES=y
++# CONFIG_INET_XFRM_MODE_TRANSPORT is not set
++# CONFIG_INET_XFRM_MODE_TUNNEL is not set
++# CONFIG_INET_XFRM_MODE_BEET is not set
++# CONFIG_INET_LRO is not set
++# CONFIG_INET_DIAG is not set
++CONFIG_TCP_CONG_ADVANCED=y
++# CONFIG_TCP_CONG_BIC is not set
++# CONFIG_TCP_CONG_WESTWOOD is not set
++# CONFIG_TCP_CONG_HTCP is not set
++CONFIG_IPV6_PRIVACY=y
++# CONFIG_INET6_XFRM_MODE_TRANSPORT is not set
++# CONFIG_INET6_XFRM_MODE_TUNNEL is not set
++# CONFIG_INET6_XFRM_MODE_BEET is not set
++# CONFIG_IPV6_SIT is not set
++CONFIG_IPV6_MULTIPLE_TABLES=y
++CONFIG_IPV6_SUBTREES=y
++CONFIG_IPV6_MROUTE=y
++CONFIG_NETFILTER=y
++# CONFIG_BRIDGE_NETFILTER is not set
++CONFIG_NF_CONNTRACK=m
++CONFIG_NF_CONNTRACK_FTP=m
++CONFIG_NF_CONNTRACK_IRC=m
++CONFIG_NETFILTER_XT_MARK=m
++CONFIG_NETFILTER_XT_TARGET_LOG=m
++CONFIG_NETFILTER_XT_TARGET_NOTRACK=m
++CONFIG_NETFILTER_XT_TARGET_TCPMSS=m
++CONFIG_NETFILTER_XT_MATCH_COMMENT=m
++CONFIG_NETFILTER_XT_MATCH_CONNTRACK=m
++CONFIG_NETFILTER_XT_MATCH_LIMIT=m
++CONFIG_NETFILTER_XT_MATCH_MAC=m
++CONFIG_NETFILTER_XT_MATCH_MULTIPORT=m
++CONFIG_NETFILTER_XT_MATCH_STATE=m
++CONFIG_NETFILTER_XT_MATCH_TIME=m
++CONFIG_NF_CONNTRACK_IPV4=m
++# CONFIG_NF_CONNTRACK_PROC_COMPAT is not set
++CONFIG_IP_NF_IPTABLES=m
++CONFIG_IP_NF_FILTER=m
++CONFIG_IP_NF_TARGET_REJECT=m
++CONFIG_NF_NAT_IPV4=m
++CONFIG_IP_NF_TARGET_MASQUERADE=m
++CONFIG_IP_NF_TARGET_REDIRECT=m
++CONFIG_IP_NF_MANGLE=m
++CONFIG_IP_NF_RAW=m
++CONFIG_NF_CONNTRACK_IPV6=m
++CONFIG_IP6_NF_IPTABLES=m
++CONFIG_IP6_NF_MATCH_AH=m
++CONFIG_IP6_NF_MATCH_EUI64=m
++CONFIG_IP6_NF_MATCH_FRAG=m
++CONFIG_IP6_NF_MATCH_OPTS=m
++CONFIG_IP6_NF_MATCH_IPV6HEADER=m
++CONFIG_IP6_NF_MATCH_MH=m
++CONFIG_IP6_NF_MATCH_RT=m
++CONFIG_IP6_NF_FILTER=m
++CONFIG_IP6_NF_TARGET_REJECT=m
++CONFIG_IP6_NF_MANGLE=m
++CONFIG_IP6_NF_RAW=m
++CONFIG_BRIDGE=m
++# CONFIG_BRIDGE_IGMP_SNOOPING is not set
++CONFIG_VLAN_8021Q=y
++CONFIG_NET_SCHED=y
++CONFIG_NET_SCH_FQ_CODEL=y
++CONFIG_HAMRADIO=y
++CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
++# CONFIG_FIRMWARE_IN_KERNEL is not set
++CONFIG_MTD=y
++CONFIG_MTD_CMDLINE_PARTS=y
++CONFIG_MTD_BLOCK=y
++CONFIG_MTD_CFI=y
++CONFIG_MTD_CFI_AMDSTD=y
++CONFIG_MTD_COMPLEX_MAPPINGS=y
++CONFIG_MTD_PHYSMAP=y
++CONFIG_MTD_M25P80=y
++CONFIG_EEPROM_93CX6=m
++CONFIG_SCSI=y
++CONFIG_BLK_DEV_SD=y
++CONFIG_NETDEVICES=y
++# CONFIG_NET_PACKET_ENGINE is not set
++# CONFIG_NET_VENDOR_WIZNET is not set
++CONFIG_PHYLIB=y
++CONFIG_SWCONFIG=y
++CONFIG_PPP=m
++CONFIG_PPP_FILTER=y
++CONFIG_PPP_MULTILINK=y
++CONFIG_PPPOE=m
++CONFIG_PPP_ASYNC=m
++CONFIG_ISDN=y
++# CONFIG_INPUT is not set
++# CONFIG_SERIO is not set
++# CONFIG_VT is not set
++# CONFIG_LEGACY_PTYS is not set
++# CONFIG_DEVKMEM is not set
++CONFIG_SERIAL_8250=y
++# CONFIG_SERIAL_8250_DEPRECATED_OPTIONS is not set
++CONFIG_SERIAL_8250_CONSOLE=y
++# CONFIG_SERIAL_8250_PCI is not set
++CONFIG_SERIAL_8250_RUNTIME_UARTS=2
++CONFIG_SPI=y
++CONFIG_GPIOLIB=y
++CONFIG_GPIO_SYSFS=y
++# CONFIG_HWMON is not set
++CONFIG_WATCHDOG=y
++CONFIG_WATCHDOG_CORE=y
++# CONFIG_VGA_ARB is not set
++CONFIG_USB=y
++CONFIG_USB_XHCI_HCD=y
++CONFIG_USB_XHCI_PLATFORM=y
++CONFIG_USB_MT7621_XHCI_PLATFORM=y
++CONFIG_USB_STORAGE=y
++CONFIG_USB_PHY=y
++CONFIG_NEW_LEDS=y
++CONFIG_LEDS_CLASS=y
++CONFIG_LEDS_GPIO=m
++CONFIG_LEDS_TRIGGERS=y
++CONFIG_LEDS_TRIGGER_TIMER=y
++CONFIG_LEDS_TRIGGER_DEFAULT_ON=y
++CONFIG_STAGING=y
++CONFIG_USB_DWC2=m
++# CONFIG_IOMMU_SUPPORT is not set
++CONFIG_RESET_CONTROLLER=y
++# CONFIG_FIRMWARE_MEMMAP is not set
++# CONFIG_DNOTIFY is not set
++# CONFIG_PROC_PAGE_MONITOR is not set
++CONFIG_TMPFS=y
++CONFIG_TMPFS_XATTR=y
++CONFIG_JFFS2_FS=y
++CONFIG_JFFS2_SUMMARY=y
++CONFIG_JFFS2_FS_XATTR=y
++# CONFIG_JFFS2_FS_POSIX_ACL is not set
++# CONFIG_JFFS2_FS_SECURITY is not set
++CONFIG_JFFS2_COMPRESSION_OPTIONS=y
++# CONFIG_JFFS2_ZLIB is not set
++CONFIG_SQUASHFS=y
++# CONFIG_SQUASHFS_ZLIB is not set
++CONFIG_SQUASHFS_XZ=y
++CONFIG_PRINTK_TIME=y
++# CONFIG_ENABLE_MUST_CHECK is not set
++CONFIG_FRAME_WARN=1024
++CONFIG_MAGIC_SYSRQ=y
++CONFIG_STRIP_ASM_SYMS=y
++# CONFIG_UNUSED_SYMBOLS is not set
++CONFIG_DEBUG_FS=y
++# CONFIG_SCHED_DEBUG is not set
++CONFIG_DEBUG_INFO=y
++CONFIG_DEBUG_INFO_REDUCED=y
++CONFIG_RCU_CPU_STALL_TIMEOUT=60
++# CONFIG_FTRACE is not set
++CONFIG_CRYPTO_ARC4=m
++# CONFIG_CRYPTO_ANSI_CPRNG is not set
++# CONFIG_VIRTUALIZATION is not set
++CONFIG_CRC_ITU_T=m
++CONFIG_CRC32_SARWATE=y
++# CONFIG_XZ_DEC_X86 is not set
++CONFIG_AVERAGE=y
+-- 
+1.7.10.4
+
diff --git a/target/linux/ramips/patches-3.14/0014-MIPS-ralink-add-MT7621-dts-file.patch b/target/linux/ramips/patches-3.14/0014-MIPS-ralink-add-MT7621-dts-file.patch
new file mode 100644 (file)
index 0000000..460a33c
--- /dev/null
@@ -0,0 +1,311 @@
+From 34e2a5ededc6140f311b3b3c88edf4e18e88126a Mon Sep 17 00:00:00 2001
+From: John Crispin <blogic@openwrt.org>
+Date: Fri, 24 Jan 2014 17:01:22 +0100
+Subject: [PATCH 14/57] MIPS: ralink: add MT7621 dts file
+
+Signed-off-by: John Crispin <blogic@openwrt.org>
+---
+ arch/mips/ralink/dts/Makefile        |    1 +
+ arch/mips/ralink/dts/mt7621.dtsi     |  257 ++++++++++++++++++++++++++++++++++
+ arch/mips/ralink/dts/mt7621_eval.dts |   16 +++
+ 3 files changed, 274 insertions(+)
+ create mode 100644 arch/mips/ralink/dts/mt7621.dtsi
+ create mode 100644 arch/mips/ralink/dts/mt7621_eval.dts
+
+diff --git a/arch/mips/ralink/dts/Makefile b/arch/mips/ralink/dts/Makefile
+index 18194fa..9742c73 100644
+--- a/arch/mips/ralink/dts/Makefile
++++ b/arch/mips/ralink/dts/Makefile
+@@ -2,3 +2,4 @@ obj-$(CONFIG_DTB_RT2880_EVAL) := rt2880_eval.dtb.o
+ obj-$(CONFIG_DTB_RT305X_EVAL) := rt3052_eval.dtb.o
+ obj-$(CONFIG_DTB_RT3883_EVAL) := rt3883_eval.dtb.o
+ obj-$(CONFIG_DTB_MT7620A_EVAL) := mt7620a_eval.dtb.o
++obj-$(CONFIG_DTB_MT7621_EVAL) := mt7621_eval.dtb.o
+diff --git a/arch/mips/ralink/dts/mt7621.dtsi b/arch/mips/ralink/dts/mt7621.dtsi
+new file mode 100644
+index 0000000..6db2c57
+--- /dev/null
++++ b/arch/mips/ralink/dts/mt7621.dtsi
+@@ -0,0 +1,257 @@
++/ {
++      #address-cells = <1>;
++      #size-cells = <1>;
++      compatible = "ralink,mtk7620a-soc";
++
++      cpus {
++              cpu@0 {
++                      compatible = "mips,mips24KEc";
++              };
++      };
++
++      cpuintc: cpuintc@0 {
++              #address-cells = <0>;
++              #interrupt-cells = <1>;
++              interrupt-controller;
++              compatible = "mti,cpu-interrupt-controller";
++      };
++
++      palmbus@1E000000 {
++              compatible = "palmbus";
++              reg = <0x1E000000 0x100000>;
++                ranges = <0x0 0x1E000000 0x0FFFFF>;
++
++              #address-cells = <1>;
++              #size-cells = <1>;
++
++              sysc@0 {
++                      compatible = "mtk,mt7621-sysc";
++                      reg = <0x0 0x100>;
++              };
++
++              wdt@100 {
++                      compatible = "mtk,mt7621-wdt";
++                      reg = <0x100 0x100>;
++              };
++
++              gpio@600 {
++                      #address-cells = <1>;
++                      #size-cells = <0>;
++
++                      compatible = "mtk,mt7621-gpio";
++                      reg = <0x600 0x100>;
++
++                      gpio0: bank@0 {
++                              reg = <0>;
++                              compatible = "mtk,mt7621-gpio-bank";
++                              gpio-controller;
++                              #gpio-cells = <2>;
++                      };
++
++                      gpio1: bank@1 {
++                              reg = <1>;
++                              compatible = "mtk,mt7621-gpio-bank";
++                              gpio-controller;
++                              #gpio-cells = <2>;
++                      };
++
++                      gpio2: bank@2 {
++                              reg = <2>;
++                              compatible = "mtk,mt7621-gpio-bank";
++                              gpio-controller;
++                              #gpio-cells = <2>;
++                      };
++              };
++
++              memc@5000 {
++                      compatible = "mtk,mt7621-memc";
++                      reg = <0x300 0x100>;
++              };
++
++              uartlite@c00 {
++                      compatible = "ns16550a";
++                      reg = <0xc00 0x100>;
++
++                      interrupt-parent = <&gic>;
++                      interrupts = <26>;
++
++                      reg-shift = <2>;
++                      reg-io-width = <4>;
++                      no-loopback-test;
++              };
++
++              uart@d00 {
++                      compatible = "ns16550a";
++                      reg = <0xd00 0x100>;
++
++                      interrupt-parent = <&gic>;
++                      interrupts = <27>;
++
++                      fifo-size = <16>;
++                      reg-shift = <2>;
++                      reg-io-width = <4>;
++                      no-loopback-test;
++              };
++
++              spi@b00 {
++                      status = "okay";
++
++                      compatible = "ralink,mt7621-spi";
++                      reg = <0xb00 0x100>;
++
++                      resets = <&rstctrl 18>;
++                      reset-names = "spi";
++
++                      #address-cells = <1>;
++                      #size-cells = <1>;
++
++/*                    pinctrl-names = "default";
++                      pinctrl-0 = <&spi_pins>;*/
++
++                      m25p80@0 {
++                              #address-cells = <1>;
++                              #size-cells = <1>;
++                              compatible = "en25q64";
++                              reg = <0 0>;
++                              linux,modalias = "m25p80", "en25q64";
++                              spi-max-frequency = <10000000>;
++
++                              m25p,chunked-io;
++
++                              partition@0 {
++                                      label = "u-boot";
++                                      reg = <0x0 0x30000>;
++                                      read-only;
++                              };
++
++                              partition@30000 {
++                                      label = "u-boot-env";
++                                      reg = <0x30000 0x10000>;
++                                      read-only;
++                              };
++
++                              factory: partition@40000 {
++                                      label = "factory";
++                                      reg = <0x40000 0x10000>;
++                                      read-only;
++                              };
++
++                              partition@50000 {
++                                      label = "firmware";
++                                      reg = <0x50000 0x7a0000>;
++                              };
++
++                              partition@7f0000 {
++                                      label = "test";
++                                      reg = <0x7f0000 0x10000>;
++                              };
++                      };
++              };
++      };
++
++      rstctrl: rstctrl {
++              compatible = "ralink,rt2880-reset";
++              #reset-cells = <1>;
++      };
++
++      sdhci@1E130000 {
++              compatible = "ralink,mt7620a-sdhci";
++              reg = <0x1E130000 4000>;
++
++              interrupt-parent = <&gic>;
++              interrupts = <20>;
++      };
++
++      xhci@1E1C0000 {
++              compatible = "xhci-platform";
++              reg = <0x1E1C0000 4000>;
++
++              interrupt-parent = <&gic>;
++              interrupts = <22>;
++      };
++
++      gic: gic@1fbc0000 {
++              #address-cells = <0>;
++              #interrupt-cells = <1>;
++              interrupt-controller;
++              compatible = "ralink,mt7621-gic";
++              reg = < 0x1fbc0000 0x80 /* gic */
++                      0x1fbf0000 0x8000 /* cpc */
++                      0x1fbf8000 0x8000 /* gpmc */
++              >;
++      };
++
++      nand@1e003000 {
++              compatible = "mtk,mt7621-nand";
++              bank-width = <2>;
++              reg = <0x1e003000 0x800
++                      0x1e003800 0x800>;
++              #address-cells = <1>;
++              #size-cells = <1>;
++
++              partition@0 {
++                      label = "uboot";
++                      reg = <0x00000 0x80000>; /* 64 KB */
++              };
++              partition@80000 {
++                      label = "uboot_env";
++                      reg = <0x80000 0x80000>; /* 64 KB */
++              };
++              partition@100000 {
++                      label = "factory";
++                      reg = <0x100000 0x40000>;
++              };
++              partition@140000 {
++                      label = "rootfs";
++                      reg = <0x140000 0xec0000>;
++              };
++      };
++
++      ethernet@1e100000 {
++              compatible = "ralink,mt7621-eth";
++              reg = <0x1e100000 10000>;
++
++              #address-cells = <1>;
++              #size-cells = <0>;
++
++              ralink,port-map = "llllw";
++              
++              interrupt-parent = <&gic>;
++              interrupts = <3>;
++
++/*            resets = <&rstctrl 21 &rstctrl 23>;
++              reset-names = "fe", "esw";
++
++              port@4 {
++                      compatible = "ralink,mt7620a-gsw-port", "ralink,eth-port";
++                      reg = <4>;
++
++                      status = "disabled";
++              };
++
++              port@5 {
++                      compatible = "ralink,mt7620a-gsw-port", "ralink,eth-port";
++                      reg = <5>;
++
++                      status = "disabled";
++              };
++*/
++              mdio-bus {
++                      #address-cells = <1>;
++                      #size-cells = <0>;
++
++                      phy1f: ethernet-phy@1f {
++                              reg = <0x1f>;
++                              phy-mode = "rgmii";
++              
++/*                            interrupt-parent = <&gic>;
++                              interrupts = <23>;
++*/                    };
++              };
++      };
++
++      gsw@1e110000 {
++              compatible = "ralink,mt7620a-gsw";
++              reg = <0x1e110000 8000>;
++      };
++};
+diff --git a/arch/mips/ralink/dts/mt7621_eval.dts b/arch/mips/ralink/dts/mt7621_eval.dts
+new file mode 100644
+index 0000000..834f59c
+--- /dev/null
++++ b/arch/mips/ralink/dts/mt7621_eval.dts
+@@ -0,0 +1,16 @@
++/dts-v1/;
++
++/include/ "mt7621.dtsi"
++
++/ {
++      compatible = "ralink,mt7621-eval-board", "ralink,mt7621-soc";
++      model = "Ralink MT7621 evaluation board";
++
++      memory@0 {
++              reg = <0x0 0x2000000>;
++      };
++
++      chosen {
++              bootargs = "console=ttyS0,57600";
++      };
++};
+-- 
+1.7.10.4
+
diff --git a/target/linux/ramips/patches-3.14/0015-MIPS-ralink-cleanup-early_printk.patch b/target/linux/ramips/patches-3.14/0015-MIPS-ralink-cleanup-early_printk.patch
new file mode 100644 (file)
index 0000000..a874c4a
--- /dev/null
@@ -0,0 +1,84 @@
+From e410b0069ee7c318a5b556f39b8b16814330a208 Mon Sep 17 00:00:00 2001
+From: John Crispin <blogic@openwrt.org>
+Date: Fri, 24 Jan 2014 17:01:17 +0100
+Subject: [PATCH 15/57] MIPS: ralink: cleanup early_printk
+
+Add support for the new MT7621/8 SoC and kill ifdefs.
+Cleanup some whitespace error while we are at it.
+
+Signed-off-by: John Crispin <blogic@openwrt.org>
+---
+ arch/mips/ralink/early_printk.c |   45 ++++++++++++++++++++++++++-------------
+ 1 file changed, 30 insertions(+), 15 deletions(-)
+
+diff --git a/arch/mips/ralink/early_printk.c b/arch/mips/ralink/early_printk.c
+index b46d041..255d695 100644
+--- a/arch/mips/ralink/early_printk.c
++++ b/arch/mips/ralink/early_printk.c
+@@ -12,21 +12,24 @@
+ #include <asm/addrspace.h>
+ #ifdef CONFIG_SOC_RT288X
+-#define EARLY_UART_BASE         0x300c00
++#define EARLY_UART_BASE               0x300c00
++#define CHIPID_BASE           0x300004
++#elif defined(CONFIG_SOC_MT7621)
++#define EARLY_UART_BASE               0x1E000c00
++#define CHIPID_BASE           0x1E000004
+ #else
+-#define EARLY_UART_BASE         0x10000c00
++#define EARLY_UART_BASE               0x10000c00
++#define CHIPID_BASE           0x10000004
+ #endif
+-#define UART_REG_RX             0x00
+-#define UART_REG_TX             0x04
+-#define UART_REG_IER            0x08
+-#define UART_REG_IIR            0x0c
+-#define UART_REG_FCR            0x10
+-#define UART_REG_LCR            0x14
+-#define UART_REG_MCR            0x18
+-#define UART_REG_LSR            0x1c
++#define MT7628_CHIP_NAME1     0x20203832
++
++#define UART_REG_TX           0x04
++#define UART_REG_LSR          0x14
++#define UART_REG_LSR_RT2880   0x1c
+ static __iomem void *uart_membase = (__iomem void *) KSEG1ADDR(EARLY_UART_BASE);
++static __iomem void *chipid_membase = (__iomem void *) KSEG1ADDR(CHIPID_BASE);
+ static inline void uart_w32(u32 val, unsigned reg)
+ {
+@@ -38,11 +41,23 @@ static inline u32 uart_r32(unsigned reg)
+       return __raw_readl(uart_membase + reg);
+ }
++static inline int soc_is_mt7628(void)
++{
++      return IS_ENABLED(CONFIG_SOC_MT7620) &&
++              (__raw_readl(chipid_membase) == MT7628_CHIP_NAME1);
++}
++
+ void prom_putchar(unsigned char ch)
+ {
+-      while ((uart_r32(UART_REG_LSR) & UART_LSR_THRE) == 0)
+-              ;
+-      uart_w32(ch, UART_REG_TX);
+-      while ((uart_r32(UART_REG_LSR) & UART_LSR_THRE) == 0)
+-              ;
++      if (IS_ENABLED(CONFIG_SOC_MT7621) || soc_is_mt7628()) {
++              uart_w32(ch, UART_TX);
++              while ((uart_r32(UART_REG_LSR) & UART_LSR_THRE) == 0)
++                      ;
++      } else {
++              while ((uart_r32(UART_REG_LSR_RT2880) & UART_LSR_THRE) == 0)
++                      ;
++              uart_w32(ch, UART_REG_TX);
++              while ((uart_r32(UART_REG_LSR_RT2880) & UART_LSR_THRE) == 0)
++                      ;
++      }
+ }
+-- 
+1.7.10.4
+
diff --git a/target/linux/ramips/patches-3.14/0016-MIPS-ralink-add-MT7621-pcie-driver.patch b/target/linux/ramips/patches-3.14/0016-MIPS-ralink-add-MT7621-pcie-driver.patch
new file mode 100644 (file)
index 0000000..7b73575
--- /dev/null
@@ -0,0 +1,830 @@
+From 95d7eb13a864ef666cea7f0e86349e86d80d28ce Mon Sep 17 00:00:00 2001
+From: John Crispin <blogic@openwrt.org>
+Date: Sun, 16 Mar 2014 05:22:39 +0000
+Subject: [PATCH 16/57] MIPS: ralink: add MT7621 pcie driver
+
+Signed-off-by: John Crispin <blogic@openwrt.org>
+---
+ arch/mips/pci/Makefile     |    1 +
+ arch/mips/pci/pci-mt7621.c |  797 ++++++++++++++++++++++++++++++++++++++++++++
+ 2 files changed, 798 insertions(+)
+ create mode 100644 arch/mips/pci/pci-mt7621.c
+
+diff --git a/arch/mips/pci/Makefile b/arch/mips/pci/Makefile
+index 137f2a6..d054bc8 100644
+--- a/arch/mips/pci/Makefile
++++ b/arch/mips/pci/Makefile
+@@ -41,6 +41,7 @@ obj-$(CONFIG_SIBYTE_BCM1x80) += pci-bcm1480.o pci-bcm1480ht.o
+ obj-$(CONFIG_SNI_RM)          += fixup-sni.o ops-sni.o
+ obj-$(CONFIG_LANTIQ)          += fixup-lantiq.o
+ obj-$(CONFIG_PCI_LANTIQ)      += pci-lantiq.o ops-lantiq.o
++obj-$(CONFIG_SOC_MT7621)      += pci-mt7621.o
+ obj-$(CONFIG_SOC_RT3883)      += pci-rt3883.o
+ obj-$(CONFIG_TANBAC_TB0219)   += fixup-tb0219.o
+ obj-$(CONFIG_TANBAC_TB0226)   += fixup-tb0226.o
+diff --git a/arch/mips/pci/pci-mt7621.c b/arch/mips/pci/pci-mt7621.c
+new file mode 100644
+index 0000000..0b58fce
+--- /dev/null
++++ b/arch/mips/pci/pci-mt7621.c
+@@ -0,0 +1,797 @@
++/**************************************************************************
++ *
++ *  BRIEF MODULE DESCRIPTION
++ *     PCI init for Ralink RT2880 solution
++ *
++ *  Copyright 2007 Ralink Inc. (bruce_chang@ralinktech.com.tw)
++ *
++ *  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  SOFTWARE  IS PROVIDED   ``AS  IS'' AND   ANY  EXPRESS OR IMPLIED
++ *  WARRANTIES,   INCLUDING, BUT NOT  LIMITED  TO, THE IMPLIED WARRANTIES OF
++ *  MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN
++ *  NO  EVENT  SHALL   THE AUTHOR  BE    LIABLE FOR ANY   DIRECT, INDIRECT,
++ *  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
++ *  NOT LIMITED   TO, PROCUREMENT OF  SUBSTITUTE GOODS  OR SERVICES; LOSS OF
++ *  USE, DATA,  OR PROFITS; OR  BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
++ *  ANY THEORY OF LIABILITY, WHETHER IN  CONTRACT, STRICT LIABILITY, OR TORT
++ *  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
++ *  THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
++ *
++ *  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.,
++ *  675 Mass Ave, Cambridge, MA 02139, USA.
++ *
++ *
++ **************************************************************************
++ * May 2007 Bruce Chang
++ * Initial Release
++ *
++ * May 2009 Bruce Chang
++ * support RT2880/RT3883 PCIe
++ *
++ * May 2011 Bruce Chang
++ * support RT6855/MT7620 PCIe
++ *
++ **************************************************************************
++ */
++
++#include <linux/types.h>
++#include <linux/pci.h>
++#include <linux/kernel.h>
++#include <linux/slab.h>
++#include <linux/version.h>
++#include <asm/pci.h>
++#include <asm/io.h>
++//#include <asm/mach-ralink/eureka_ep430.h>
++#include <linux/init.h>
++#include <linux/mod_devicetable.h>
++#include <linux/delay.h>
++//#include <asm/rt2880/surfboardint.h>
++
++#include <ralink_regs.h>
++
++extern void pcie_phy_init(void);
++extern void chk_phy_pll(void);
++
++/*
++ * These functions and structures provide the BIOS scan and mapping of the PCI
++ * devices.
++ */
++
++#define CONFIG_PCIE_PORT0
++#define CONFIG_PCIE_PORT1
++#define CONFIG_PCIE_PORT2
++#define RALINK_PCIE0_CLK_EN             (1<<24)
++#define RALINK_PCIE1_CLK_EN             (1<<25)
++#define RALINK_PCIE2_CLK_EN             (1<<26)
++
++#define RALINK_PCI_CONFIG_ADDR                         0x20
++#define RALINK_PCI_CONFIG_DATA_VIRTUAL_REG     0x24
++#define SURFBOARDINT_PCIE0       12      /* PCIE0 */
++#define RALINK_INT_PCIE0         SURFBOARDINT_PCIE0
++#define RALINK_INT_PCIE1         SURFBOARDINT_PCIE1
++#define RALINK_INT_PCIE2         SURFBOARDINT_PCIE2
++#define SURFBOARDINT_PCIE1       32     /* PCIE1 */
++#define SURFBOARDINT_PCIE2       33     /* PCIE2 */
++#define RALINK_PCI_MEMBASE              *(volatile u32 *)(RALINK_PCI_BASE + 0x0028)
++#define RALINK_PCI_IOBASE               *(volatile u32 *)(RALINK_PCI_BASE + 0x002C)
++#define RALINK_PCIE0_RST                (1<<24)
++#define RALINK_PCIE1_RST                (1<<25)
++#define RALINK_PCIE2_RST                (1<<26)
++#define RALINK_SYSCTL_BASE              0xBE000000
++
++#define RALINK_PCI_PCICFG_ADDR          *(volatile u32 *)(RALINK_PCI_BASE + 0x0000)
++#define RALINK_PCI_PCIMSK_ADDR          *(volatile u32 *)(RALINK_PCI_BASE + 0x000C)
++#define RALINK_PCI_BASE                 0xBE140000
++
++#define RALINK_PCIEPHY_P0P1_CTL_OFFSET (RALINK_PCI_BASE + 0x9000)
++#define RT6855_PCIE0_OFFSET     0x2000
++#define RT6855_PCIE1_OFFSET     0x3000
++#define RT6855_PCIE2_OFFSET     0x4000
++
++#define RALINK_PCI0_BAR0SETUP_ADDR      *(volatile u32 *)(RALINK_PCI_BASE + RT6855_PCIE0_OFFSET + 0x0010)
++#define RALINK_PCI0_IMBASEBAR0_ADDR     *(volatile u32 *)(RALINK_PCI_BASE + RT6855_PCIE0_OFFSET + 0x0018)
++#define RALINK_PCI0_ID                  *(volatile u32 *)(RALINK_PCI_BASE + RT6855_PCIE0_OFFSET + 0x0030)
++#define RALINK_PCI0_CLASS               *(volatile u32 *)(RALINK_PCI_BASE + RT6855_PCIE0_OFFSET + 0x0034)
++#define RALINK_PCI0_SUBID               *(volatile u32 *)(RALINK_PCI_BASE + RT6855_PCIE0_OFFSET + 0x0038)
++#define RALINK_PCI0_STATUS              *(volatile u32 *)(RALINK_PCI_BASE + RT6855_PCIE0_OFFSET + 0x0050)
++#define RALINK_PCI0_DERR                *(volatile u32 *)(RALINK_PCI_BASE + RT6855_PCIE0_OFFSET + 0x0060)
++#define RALINK_PCI0_ECRC                *(volatile u32 *)(RALINK_PCI_BASE + RT6855_PCIE0_OFFSET + 0x0064)
++
++#define RALINK_PCI1_BAR0SETUP_ADDR      *(volatile u32 *)(RALINK_PCI_BASE + RT6855_PCIE1_OFFSET + 0x0010)
++#define RALINK_PCI1_IMBASEBAR0_ADDR     *(volatile u32 *)(RALINK_PCI_BASE + RT6855_PCIE1_OFFSET + 0x0018)
++#define RALINK_PCI1_ID                  *(volatile u32 *)(RALINK_PCI_BASE + RT6855_PCIE1_OFFSET + 0x0030)
++#define RALINK_PCI1_CLASS               *(volatile u32 *)(RALINK_PCI_BASE + RT6855_PCIE1_OFFSET + 0x0034)
++#define RALINK_PCI1_SUBID               *(volatile u32 *)(RALINK_PCI_BASE + RT6855_PCIE1_OFFSET + 0x0038)
++#define RALINK_PCI1_STATUS              *(volatile u32 *)(RALINK_PCI_BASE + RT6855_PCIE1_OFFSET + 0x0050)
++#define RALINK_PCI1_DERR                *(volatile u32 *)(RALINK_PCI_BASE + RT6855_PCIE1_OFFSET + 0x0060)
++#define RALINK_PCI1_ECRC                *(volatile u32 *)(RALINK_PCI_BASE + RT6855_PCIE1_OFFSET + 0x0064)
++
++#define RALINK_PCI2_BAR0SETUP_ADDR      *(volatile u32 *)(RALINK_PCI_BASE + RT6855_PCIE2_OFFSET + 0x0010)
++#define RALINK_PCI2_IMBASEBAR0_ADDR     *(volatile u32 *)(RALINK_PCI_BASE + RT6855_PCIE2_OFFSET + 0x0018)
++#define RALINK_PCI2_ID                  *(volatile u32 *)(RALINK_PCI_BASE + RT6855_PCIE2_OFFSET + 0x0030)
++#define RALINK_PCI2_CLASS               *(volatile u32 *)(RALINK_PCI_BASE + RT6855_PCIE2_OFFSET + 0x0034)
++#define RALINK_PCI2_SUBID               *(volatile u32 *)(RALINK_PCI_BASE + RT6855_PCIE2_OFFSET + 0x0038)
++#define RALINK_PCI2_STATUS              *(volatile u32 *)(RALINK_PCI_BASE + RT6855_PCIE2_OFFSET + 0x0050)
++#define RALINK_PCI2_DERR                *(volatile u32 *)(RALINK_PCI_BASE + RT6855_PCIE2_OFFSET + 0x0060)
++#define RALINK_PCI2_ECRC                *(volatile u32 *)(RALINK_PCI_BASE + RT6855_PCIE2_OFFSET + 0x0064)
++
++#define RALINK_PCIEPHY_P0P1_CTL_OFFSET  (RALINK_PCI_BASE + 0x9000)
++#define RALINK_PCIEPHY_P2_CTL_OFFSET    (RALINK_PCI_BASE + 0xA000)
++
++
++#define MV_WRITE(ofs, data)  \
++        *(volatile u32 *)(RALINK_PCI_BASE+(ofs)) = cpu_to_le32(data)
++#define MV_READ(ofs, data)   \
++              *(data) = le32_to_cpu(*(volatile u32 *)(RALINK_PCI_BASE+(ofs)))
++#define MV_READ_DATA(ofs)    \
++                      le32_to_cpu(*(volatile u32 *)(RALINK_PCI_BASE+(ofs)))
++
++#define MV_WRITE_16(ofs, data)  \
++        *(volatile u16 *)(RALINK_PCI_BASE+(ofs)) = cpu_to_le16(data)
++#define MV_READ_16(ofs, data)   \
++              *(data) = le16_to_cpu(*(volatile u16 *)(RALINK_PCI_BASE+(ofs)))
++
++#define MV_WRITE_8(ofs, data)  \
++        *(volatile u8 *)(RALINK_PCI_BASE+(ofs)) = data
++#define MV_READ_8(ofs, data)   \
++              *(data) = *(volatile u8 *)(RALINK_PCI_BASE+(ofs))
++
++
++
++#define RALINK_PCI_MM_MAP_BASE        0x60000000
++#define RALINK_PCI_IO_MAP_BASE        0x1e160000
++
++#define RALINK_SYSTEM_CONTROL_BASE    0xbe000000
++#define GPIO_PERST
++#define ASSERT_SYSRST_PCIE(val)               do {    \
++                                              if (*(unsigned int *)(0xbe00000c) == 0x00030101)        \
++                                                      RALINK_RSTCTRL |= val;  \
++                                              else    \
++                                                      RALINK_RSTCTRL &= ~val; \
++                                      } while(0)
++#define DEASSERT_SYSRST_PCIE(val)     do {    \
++                                              if (*(unsigned int *)(0xbe00000c) == 0x00030101)        \
++                                                      RALINK_RSTCTRL &= ~val; \
++                                              else    \
++                                                      RALINK_RSTCTRL |= val;  \
++                                      } while(0)
++#define RALINK_SYSCFG1                        *(unsigned int *)(RALINK_SYSTEM_CONTROL_BASE + 0x14)
++#define RALINK_CLKCFG1                        *(unsigned int *)(RALINK_SYSTEM_CONTROL_BASE + 0x30)
++#define RALINK_RSTCTRL                        *(unsigned int *)(RALINK_SYSTEM_CONTROL_BASE + 0x34)
++#define RALINK_GPIOMODE                       *(unsigned int *)(RALINK_SYSTEM_CONTROL_BASE + 0x60)
++#define RALINK_PCIE_CLK_GEN           *(unsigned int *)(RALINK_SYSTEM_CONTROL_BASE + 0x7c)
++#define RALINK_PCIE_CLK_GEN1          *(unsigned int *)(RALINK_SYSTEM_CONTROL_BASE + 0x80)
++#define PPLL_CFG1                     *(unsigned int *)(RALINK_SYSTEM_CONTROL_BASE + 0x9c)
++#define PPLL_DRV                      *(unsigned int *)(RALINK_SYSTEM_CONTROL_BASE + 0xa0)
++//RALINK_SYSCFG1 bit
++#define RALINK_PCI_HOST_MODE_EN               (1<<7)
++#define RALINK_PCIE_RC_MODE_EN                (1<<8)
++//RALINK_RSTCTRL bit
++#define RALINK_PCIE_RST                       (1<<23)
++#define RALINK_PCI_RST                        (1<<24)
++//RALINK_CLKCFG1 bit
++#define RALINK_PCI_CLK_EN             (1<<19)
++#define RALINK_PCIE_CLK_EN            (1<<21)
++//RALINK_GPIOMODE bit
++#define PCI_SLOTx2                    (1<<11)
++#define PCI_SLOTx1                    (2<<11)
++//MTK PCIE PLL bit
++#define PDRV_SW_SET                   (1<<31)
++#define LC_CKDRVPD_                   (1<<19)
++
++#define MEMORY_BASE 0x0
++int pcie_link_status = 0;
++
++void __inline__ read_config(unsigned long bus, unsigned long dev, unsigned long func, unsigned long reg, unsigned long *val);
++void __inline__ write_config(unsigned long bus, unsigned long dev, unsigned long func, unsigned long reg, unsigned long val);
++
++#define PCI_ACCESS_READ_1  0
++#define PCI_ACCESS_READ_2  1
++#define PCI_ACCESS_READ_4  2
++#define PCI_ACCESS_WRITE_1 3
++#define PCI_ACCESS_WRITE_2 4
++#define PCI_ACCESS_WRITE_4 5
++
++static int config_access(unsigned char access_type, struct pci_bus *bus,
++                      unsigned int devfn, unsigned int where, u32 * data)
++{
++      unsigned int slot = PCI_SLOT(devfn);
++      u8 func = PCI_FUNC(devfn);
++      uint32_t address_reg, data_reg;
++      unsigned int address;
++
++      address_reg = RALINK_PCI_CONFIG_ADDR;
++      data_reg = RALINK_PCI_CONFIG_DATA_VIRTUAL_REG;
++
++      address = (((where&0xF00)>>8)<<24) |(bus->number << 16) | (slot << 11) | (func << 8) | (where & 0xfc) | 0x80000000;
++      MV_WRITE(address_reg, address);
++
++      switch(access_type) {
++      case PCI_ACCESS_WRITE_1:
++              MV_WRITE_8(data_reg+(where&0x3), *data);
++              break;
++      case PCI_ACCESS_WRITE_2:
++              MV_WRITE_16(data_reg+(where&0x3), *data);
++              break;
++      case PCI_ACCESS_WRITE_4:
++              MV_WRITE(data_reg, *data);
++              break;
++      case PCI_ACCESS_READ_1:
++              MV_READ_8( data_reg+(where&0x3), data);
++              break;
++      case PCI_ACCESS_READ_2:
++              MV_READ_16(data_reg+(where&0x3), data);
++              break;
++      case PCI_ACCESS_READ_4:
++              MV_READ(data_reg, data);
++              break;
++      default:
++              printk("no specify access type\n");
++              break;
++      }
++      return 0;
++}
++
++static int
++read_config_byte(struct pci_bus *bus, unsigned int devfn, int where, u8 * val)
++{
++      return config_access(PCI_ACCESS_READ_1, bus, devfn, (unsigned int)where, (u32 *)val);
++}
++
++static int
++read_config_word(struct pci_bus *bus, unsigned int devfn, int where, u16 * val)
++{
++      return config_access(PCI_ACCESS_READ_2, bus, devfn, (unsigned int)where, (u32 *)val);
++}
++
++static int
++read_config_dword(struct pci_bus *bus, unsigned int devfn, int where, u32 * val)
++{
++      return config_access(PCI_ACCESS_READ_4, bus, devfn, (unsigned int)where, (u32 *)val);
++}
++
++static int
++write_config_byte(struct pci_bus *bus, unsigned int devfn, int where, u8 val)
++{
++      if (config_access(PCI_ACCESS_WRITE_1, bus, devfn, (unsigned int)where, (u32 *)&val))
++              return -1;
++
++      return PCIBIOS_SUCCESSFUL;
++}
++
++static int
++write_config_word(struct pci_bus *bus, unsigned int devfn, int where, u16 val)
++{
++      if (config_access(PCI_ACCESS_WRITE_2, bus, devfn, where, (u32 *)&val))
++              return -1;
++
++      return PCIBIOS_SUCCESSFUL;
++}
++
++static int
++write_config_dword(struct pci_bus *bus, unsigned int devfn, int where, u32 val)
++{
++      if (config_access(PCI_ACCESS_WRITE_4, bus, devfn, where, &val))
++              return -1;
++
++      return PCIBIOS_SUCCESSFUL;
++}
++
++
++static int
++pci_config_read(struct pci_bus *bus, unsigned int devfn, int where, int size, u32 * val)
++{
++      switch (size) {
++      case 1:
++              return read_config_byte(bus, devfn, where, (u8 *) val);
++      case 2:
++              return read_config_word(bus, devfn, where, (u16 *) val);
++      default:
++              return read_config_dword(bus, devfn, where, val);
++      }
++}
++
++static int
++pci_config_write(struct pci_bus *bus, unsigned int devfn, int where, int size, u32 val)
++{
++      switch (size) {
++      case 1:
++              return write_config_byte(bus, devfn, where, (u8) val);
++      case 2:
++              return write_config_word(bus, devfn, where, (u16) val);
++      default:
++              return write_config_dword(bus, devfn, where, val);
++      }
++}
++
++struct pci_ops rt2880_pci_ops= {
++      .read           =  pci_config_read,
++      .write          = pci_config_write,
++};
++
++static struct resource rt2880_res_pci_mem1 = {
++      .name           = "PCI MEM1",
++      .start          = RALINK_PCI_MM_MAP_BASE,
++      .end            = (u32)((RALINK_PCI_MM_MAP_BASE + (unsigned char *)0x0fffffff)),
++      .flags          = IORESOURCE_MEM,
++};
++static struct resource rt2880_res_pci_io1 = {
++      .name           = "PCI I/O1",
++      .start          = RALINK_PCI_IO_MAP_BASE,
++      .end            = (u32)((RALINK_PCI_IO_MAP_BASE + (unsigned char *)0x0ffff)),
++      .flags          = IORESOURCE_IO,
++};
++
++struct pci_controller rt2880_controller = {
++      .pci_ops        = &rt2880_pci_ops,
++      .mem_resource   = &rt2880_res_pci_mem1,
++      .io_resource    = &rt2880_res_pci_io1,
++      .mem_offset     = 0x00000000UL,
++      .io_offset      = 0x00000000UL,
++      .io_map_base    = 0xa0000000,
++};
++
++void __inline__
++read_config(unsigned long bus, unsigned long dev, unsigned long func, unsigned long reg, unsigned long *val)
++{
++      unsigned int address_reg, data_reg, address;
++
++      address_reg = RALINK_PCI_CONFIG_ADDR;
++        data_reg = RALINK_PCI_CONFIG_DATA_VIRTUAL_REG;
++      address = (((reg & 0xF00)>>8)<<24) | (bus << 16) | (dev << 11) | (func << 8) | (reg & 0xfc) | 0x80000000 ;
++        MV_WRITE(address_reg, address);
++        MV_READ(data_reg, val);
++      return;
++}
++
++void __inline__
++write_config(unsigned long bus, unsigned long dev, unsigned long func, unsigned long reg, unsigned long val)
++{
++      unsigned int address_reg, data_reg, address;
++
++      address_reg = RALINK_PCI_CONFIG_ADDR;
++      data_reg = RALINK_PCI_CONFIG_DATA_VIRTUAL_REG;
++      address = (((reg & 0xF00)>>8)<<24) | (bus << 16) | (dev << 11) | (func << 8) | (reg & 0xfc) | 0x80000000 ;
++      MV_WRITE(address_reg, address);
++      MV_WRITE(data_reg, val);
++      return;
++}
++
++
++int __init
++pcibios_map_irq(const struct pci_dev *dev, u8 slot, u8 pin)
++{
++      u16 cmd;
++      u32 val;
++      int irq = 0;
++
++      if ((dev->bus->number == 0) && (slot == 0)) {
++              write_config(0, 0, 0, PCI_BASE_ADDRESS_0, MEMORY_BASE);
++              read_config(0, 0, 0, PCI_BASE_ADDRESS_0, (unsigned long *)&val);
++              printk("BAR0 at slot 0 = %x\n", val);
++              printk("bus=0x%x, slot = 0x%x\n",dev->bus->number, slot);
++      } else if((dev->bus->number == 0) && (slot == 0x1)) {
++              write_config(0, 1, 0, PCI_BASE_ADDRESS_0, MEMORY_BASE);
++              read_config(0, 1, 0, PCI_BASE_ADDRESS_0, (unsigned long *)&val);
++              printk("BAR0 at slot 1 = %x\n", val);
++              printk("bus=0x%x, slot = 0x%x\n",dev->bus->number, slot);
++      } else if((dev->bus->number == 0) && (slot == 0x2)) {
++              write_config(0, 2, 0, PCI_BASE_ADDRESS_0, MEMORY_BASE);
++              read_config(0, 2, 0, PCI_BASE_ADDRESS_0, (unsigned long *)&val);
++              printk("BAR0 at slot 2 = %x\n", val);
++              printk("bus=0x%x, slot = 0x%x\n",dev->bus->number, slot);
++      } else if ((dev->bus->number == 1) && (slot == 0x0)) {
++              switch (pcie_link_status) {
++              case 2:
++              case 6:
++                      irq = RALINK_INT_PCIE1;
++                      break;
++              case 4:
++                      irq = RALINK_INT_PCIE2;
++                      break;
++              default:
++                      irq = RALINK_INT_PCIE0;
++              }
++              printk("bus=0x%x, slot = 0x%x, irq=0x%x\n",dev->bus->number, slot, dev->irq);
++      } else if ((dev->bus->number == 2) && (slot == 0x0)) {
++              switch (pcie_link_status) {
++              case 5:
++              case 6:
++                      irq = RALINK_INT_PCIE2;
++                      break;
++              default:
++                      irq = RALINK_INT_PCIE1;
++              }
++              printk("bus=0x%x, slot = 0x%x, irq=0x%x\n",dev->bus->number, slot, dev->irq);
++      } else if ((dev->bus->number == 2) && (slot == 0x1)) {
++              switch (pcie_link_status) {
++              case 5:
++              case 6:
++                      irq = RALINK_INT_PCIE2;
++                      break;
++              default:
++                      irq = RALINK_INT_PCIE1;
++              }
++              printk("bus=0x%x, slot = 0x%x, irq=0x%x\n",dev->bus->number, slot, dev->irq);
++      } else if ((dev->bus->number ==3) && (slot == 0x0)) {
++              irq = RALINK_INT_PCIE2;
++              printk("bus=0x%x, slot = 0x%x, irq=0x%x\n",dev->bus->number, slot, dev->irq);
++      } else if ((dev->bus->number ==3) && (slot == 0x1)) {
++              irq = RALINK_INT_PCIE2;
++              printk("bus=0x%x, slot = 0x%x, irq=0x%x\n",dev->bus->number, slot, dev->irq);
++      } else if ((dev->bus->number ==3) && (slot == 0x2)) {
++              irq = RALINK_INT_PCIE2;
++              printk("bus=0x%x, slot = 0x%x, irq=0x%x\n",dev->bus->number, slot, dev->irq);
++      } else {
++              printk("bus=0x%x, slot = 0x%x\n",dev->bus->number, slot);
++              return 0;
++      }
++
++      pci_write_config_byte(dev, PCI_CACHE_LINE_SIZE, 0x14);  //configure cache line size 0x14
++      pci_write_config_byte(dev, PCI_LATENCY_TIMER, 0xFF);  //configure latency timer 0x10
++      pci_read_config_word(dev, PCI_COMMAND, &cmd);
++      cmd = cmd | PCI_COMMAND_MASTER | PCI_COMMAND_IO | PCI_COMMAND_MEMORY;
++      pci_write_config_word(dev, PCI_COMMAND, cmd);
++      pci_write_config_byte(dev, PCI_INTERRUPT_LINE, irq);
++      return irq;
++}
++
++void
++set_pcie_phy(u32 *addr, int start_b, int bits, int val)
++{
++//    printk("0x%p:", addr);
++//    printk(" %x", *addr);
++      *(unsigned int *)(addr) &= ~(((1<<bits) - 1)<<start_b);
++      *(unsigned int *)(addr) |= val << start_b;
++//    printk(" -> %x\n", *addr);
++}
++
++void
++bypass_pipe_rst(void)
++{
++#if defined (CONFIG_PCIE_PORT0)
++      /* PCIe Port 0 */
++      set_pcie_phy((u32 *)(RALINK_PCIEPHY_P0P1_CTL_OFFSET + 0x02c), 12, 1, 0x01);     // rg_pe1_pipe_rst_b
++      set_pcie_phy((u32 *)(RALINK_PCIEPHY_P0P1_CTL_OFFSET + 0x02c),  4, 1, 0x01);     // rg_pe1_pipe_cmd_frc[4]
++#endif
++#if defined (CONFIG_PCIE_PORT1)
++      /* PCIe Port 1 */
++      set_pcie_phy((u32 *)(RALINK_PCIEPHY_P0P1_CTL_OFFSET + 0x12c), 12, 1, 0x01);     // rg_pe1_pipe_rst_b
++      set_pcie_phy((u32 *)(RALINK_PCIEPHY_P0P1_CTL_OFFSET + 0x12c),  4, 1, 0x01);     // rg_pe1_pipe_cmd_frc[4]
++#endif
++#if defined (CONFIG_PCIE_PORT2)
++      /* PCIe Port 2 */
++      set_pcie_phy((u32 *)(RALINK_PCIEPHY_P2_CTL_OFFSET + 0x02c), 12, 1, 0x01);       // rg_pe1_pipe_rst_b
++      set_pcie_phy((u32 *)(RALINK_PCIEPHY_P2_CTL_OFFSET + 0x02c),  4, 1, 0x01);       // rg_pe1_pipe_cmd_frc[4]
++#endif
++}
++
++void
++set_phy_for_ssc(void)
++{
++      unsigned long reg = (*(volatile u32 *)(RALINK_SYSCTL_BASE + 0x10));
++
++      reg = (reg >> 6) & 0x7;
++#if defined (CONFIG_PCIE_PORT0) || defined (CONFIG_PCIE_PORT1)
++      /* Set PCIe Port0 & Port1 PHY to disable SSC */
++      /* Debug Xtal Type */
++      set_pcie_phy((u32 *)(RALINK_PCIEPHY_P0P1_CTL_OFFSET + 0x400),  8, 1, 0x01);     // rg_pe1_frc_h_xtal_type
++      set_pcie_phy((u32 *)(RALINK_PCIEPHY_P0P1_CTL_OFFSET + 0x400),  9, 2, 0x00);     // rg_pe1_h_xtal_type
++      set_pcie_phy((u32 *)(RALINK_PCIEPHY_P0P1_CTL_OFFSET + 0x000),  4, 1, 0x01);     // rg_pe1_frc_phy_en               //Force Port 0 enable control
++      set_pcie_phy((u32 *)(RALINK_PCIEPHY_P0P1_CTL_OFFSET + 0x100),  4, 1, 0x01);     // rg_pe1_frc_phy_en               //Force Port 1 enable control
++      set_pcie_phy((u32 *)(RALINK_PCIEPHY_P0P1_CTL_OFFSET + 0x000),  5, 1, 0x00);     // rg_pe1_phy_en                   //Port 0 disable
++      set_pcie_phy((u32 *)(RALINK_PCIEPHY_P0P1_CTL_OFFSET + 0x100),  5, 1, 0x00);     // rg_pe1_phy_en                   //Port 1 disable
++      if(reg <= 5 && reg >= 3) {      // 40MHz Xtal
++              set_pcie_phy((u32 *)(RALINK_PCIEPHY_P0P1_CTL_OFFSET + 0x490),  6, 2, 0x01);     // RG_PE1_H_PLL_PREDIV             //Pre-divider ratio (for host mode)
++              printk("***** Xtal 40MHz *****\n");
++      } else {                        // 25MHz | 20MHz Xtal
++              set_pcie_phy((u32 *)(RALINK_PCIEPHY_P0P1_CTL_OFFSET + 0x490),  6, 2, 0x00);     // RG_PE1_H_PLL_PREDIV             //Pre-divider ratio (for host mode)
++              if (reg >= 6) {         
++                      printk("***** Xtal 25MHz *****\n");
++                      set_pcie_phy((u32 *)(RALINK_PCIEPHY_P0P1_CTL_OFFSET + 0x4bc),  4, 2, 0x01);     // RG_PE1_H_PLL_FBKSEL             //Feedback clock select
++                      set_pcie_phy((u32 *)(RALINK_PCIEPHY_P0P1_CTL_OFFSET + 0x49c),  0,31, 0x18000000);       // RG_PE1_H_LCDDS_PCW_NCPO         //DDS NCPO PCW (for host mode)
++                      set_pcie_phy((u32 *)(RALINK_PCIEPHY_P0P1_CTL_OFFSET + 0x4a4),  0,16, 0x18d);    // RG_PE1_H_LCDDS_SSC_PRD          //DDS SSC dither period control
++                      set_pcie_phy((u32 *)(RALINK_PCIEPHY_P0P1_CTL_OFFSET + 0x4a8),  0,12, 0x4a);     // RG_PE1_H_LCDDS_SSC_DELTA        //DDS SSC dither amplitude control
++                      set_pcie_phy((u32 *)(RALINK_PCIEPHY_P0P1_CTL_OFFSET + 0x4a8), 16,12, 0x4a);     // RG_PE1_H_LCDDS_SSC_DELTA1       //DDS SSC dither amplitude control for initial
++              } else {
++                      printk("***** Xtal 20MHz *****\n");
++              }
++      }
++      set_pcie_phy((u32 *)(RALINK_PCIEPHY_P0P1_CTL_OFFSET + 0x4a0),  5, 1, 0x01);     // RG_PE1_LCDDS_CLK_PH_INV         //DDS clock inversion
++      set_pcie_phy((u32 *)(RALINK_PCIEPHY_P0P1_CTL_OFFSET + 0x490), 22, 2, 0x02);     // RG_PE1_H_PLL_BC                 
++      set_pcie_phy((u32 *)(RALINK_PCIEPHY_P0P1_CTL_OFFSET + 0x490), 18, 4, 0x06);     // RG_PE1_H_PLL_BP                 
++      set_pcie_phy((u32 *)(RALINK_PCIEPHY_P0P1_CTL_OFFSET + 0x490), 12, 4, 0x02);     // RG_PE1_H_PLL_IR                 
++      set_pcie_phy((u32 *)(RALINK_PCIEPHY_P0P1_CTL_OFFSET + 0x490),  8, 4, 0x01);     // RG_PE1_H_PLL_IC                 
++      set_pcie_phy((u32 *)(RALINK_PCIEPHY_P0P1_CTL_OFFSET + 0x4ac), 16, 3, 0x00);     // RG_PE1_H_PLL_BR                 
++      set_pcie_phy((u32 *)(RALINK_PCIEPHY_P0P1_CTL_OFFSET + 0x490),  1, 3, 0x02);     // RG_PE1_PLL_DIVEN                
++      if(reg <= 5 && reg >= 3) {      // 40MHz Xtal
++              set_pcie_phy((u32 *)(RALINK_PCIEPHY_P0P1_CTL_OFFSET + 0x414),  6, 2, 0x01);     // rg_pe1_mstckdiv              //value of da_pe1_mstckdiv when force mode enable
++              set_pcie_phy((u32 *)(RALINK_PCIEPHY_P0P1_CTL_OFFSET + 0x414),  5, 1, 0x01);     // rg_pe1_frc_mstckdiv          //force mode enable of da_pe1_mstckdiv      
++      }
++      /* Enable PHY and disable force mode */
++      set_pcie_phy((u32 *)(RALINK_PCIEPHY_P0P1_CTL_OFFSET + 0x000),  5, 1, 0x01);     // rg_pe1_phy_en                   //Port 0 enable
++      set_pcie_phy((u32 *)(RALINK_PCIEPHY_P0P1_CTL_OFFSET + 0x100),  5, 1, 0x01);     // rg_pe1_phy_en                   //Port 1 enable
++      set_pcie_phy((u32 *)(RALINK_PCIEPHY_P0P1_CTL_OFFSET + 0x000),  4, 1, 0x00);     // rg_pe1_frc_phy_en               //Force Port 0 disable control
++      set_pcie_phy((u32 *)(RALINK_PCIEPHY_P0P1_CTL_OFFSET + 0x100),  4, 1, 0x00);     // rg_pe1_frc_phy_en               //Force Port 1 disable control
++#endif
++#if defined (CONFIG_PCIE_PORT2)
++      /* Set PCIe Port2 PHY to disable SSC */
++      /* Debug Xtal Type */
++      set_pcie_phy((u32 *)(RALINK_PCIEPHY_P2_CTL_OFFSET + 0x400),  8, 1, 0x01);       // rg_pe1_frc_h_xtal_type
++      set_pcie_phy((u32 *)(RALINK_PCIEPHY_P2_CTL_OFFSET + 0x400),  9, 2, 0x00);       // rg_pe1_h_xtal_type
++      set_pcie_phy((u32 *)(RALINK_PCIEPHY_P2_CTL_OFFSET + 0x000),  4, 1, 0x01);       // rg_pe1_frc_phy_en               //Force Port 0 enable control
++      set_pcie_phy((u32 *)(RALINK_PCIEPHY_P2_CTL_OFFSET + 0x000),  5, 1, 0x00);       // rg_pe1_phy_en                   //Port 0 disable
++      if(reg <= 5 && reg >= 3) {      // 40MHz Xtal
++              set_pcie_phy((u32 *)(RALINK_PCIEPHY_P2_CTL_OFFSET + 0x490),  6, 2, 0x01);       // RG_PE1_H_PLL_PREDIV             //Pre-divider ratio (for host mode)
++      } else {                        // 25MHz | 20MHz Xtal
++              set_pcie_phy((u32 *)(RALINK_PCIEPHY_P2_CTL_OFFSET + 0x490),  6, 2, 0x00);       // RG_PE1_H_PLL_PREDIV             //Pre-divider ratio (for host mode)
++              if (reg >= 6) {         // 25MHz Xtal
++                      set_pcie_phy((u32 *)(RALINK_PCIEPHY_P2_CTL_OFFSET + 0x4bc),  4, 2, 0x01);       // RG_PE1_H_PLL_FBKSEL             //Feedback clock select
++                      set_pcie_phy((u32 *)(RALINK_PCIEPHY_P2_CTL_OFFSET + 0x49c),  0,31, 0x18000000); // RG_PE1_H_LCDDS_PCW_NCPO         //DDS NCPO PCW (for host mode)
++                      set_pcie_phy((u32 *)(RALINK_PCIEPHY_P2_CTL_OFFSET + 0x4a4),  0,16, 0x18d);      // RG_PE1_H_LCDDS_SSC_PRD          //DDS SSC dither period control
++                      set_pcie_phy((u32 *)(RALINK_PCIEPHY_P2_CTL_OFFSET + 0x4a8),  0,12, 0x4a);       // RG_PE1_H_LCDDS_SSC_DELTA        //DDS SSC dither amplitude control
++                      set_pcie_phy((u32 *)(RALINK_PCIEPHY_P2_CTL_OFFSET + 0x4a8), 16,12, 0x4a);       // RG_PE1_H_LCDDS_SSC_DELTA1       //DDS SSC dither amplitude control for initial
++              }
++      }
++      set_pcie_phy((u32 *)(RALINK_PCIEPHY_P2_CTL_OFFSET + 0x4a0),  5, 1, 0x01);       // RG_PE1_LCDDS_CLK_PH_INV         //DDS clock inversion
++      set_pcie_phy((u32 *)(RALINK_PCIEPHY_P2_CTL_OFFSET + 0x490), 22, 2, 0x02);       // RG_PE1_H_PLL_BC                 
++      set_pcie_phy((u32 *)(RALINK_PCIEPHY_P2_CTL_OFFSET + 0x490), 18, 4, 0x06);       // RG_PE1_H_PLL_BP                 
++      set_pcie_phy((u32 *)(RALINK_PCIEPHY_P2_CTL_OFFSET + 0x490), 12, 4, 0x02);       // RG_PE1_H_PLL_IR                 
++      set_pcie_phy((u32 *)(RALINK_PCIEPHY_P2_CTL_OFFSET + 0x490),  8, 4, 0x01);       // RG_PE1_H_PLL_IC                 
++      set_pcie_phy((u32 *)(RALINK_PCIEPHY_P2_CTL_OFFSET + 0x4ac), 16, 3, 0x00);       // RG_PE1_H_PLL_BR                 
++      set_pcie_phy((u32 *)(RALINK_PCIEPHY_P2_CTL_OFFSET + 0x490),  1, 3, 0x02);       // RG_PE1_PLL_DIVEN                
++      if(reg <= 5 && reg >= 3) {      // 40MHz Xtal
++              set_pcie_phy((u32 *)(RALINK_PCIEPHY_P2_CTL_OFFSET + 0x414),  6, 2, 0x01);       // rg_pe1_mstckdiv              //value of da_pe1_mstckdiv when force mode enable
++              set_pcie_phy((u32 *)(RALINK_PCIEPHY_P2_CTL_OFFSET + 0x414),  5, 1, 0x01);       // rg_pe1_frc_mstckdiv          //force mode enable of da_pe1_mstckdiv      
++      }
++      /* Enable PHY and disable force mode */
++      set_pcie_phy((u32 *)(RALINK_PCIEPHY_P2_CTL_OFFSET + 0x000),  5, 1, 0x01);       // rg_pe1_phy_en                   //Port 0 enable
++      set_pcie_phy((u32 *)(RALINK_PCIEPHY_P2_CTL_OFFSET + 0x000),  4, 1, 0x00);       // rg_pe1_frc_phy_en               //Force Port 0 disable control
++#endif
++}
++
++int init_rt2880pci(void)
++{
++      unsigned long val = 0;
++       iomem_resource.start = 0;
++       iomem_resource.end= ~0;
++       ioport_resource.start= 0;
++       ioport_resource.end = ~0;
++
++#if defined (CONFIG_PCIE_PORT0)
++      val = RALINK_PCIE0_RST;
++#endif
++#if defined (CONFIG_PCIE_PORT1)
++      val |= RALINK_PCIE1_RST;
++#endif
++#if defined (CONFIG_PCIE_PORT2)
++      val |= RALINK_PCIE2_RST;
++#endif
++      DEASSERT_SYSRST_PCIE(val);
++      printk("release PCIe RST: RALINK_RSTCTRL = %x\n", RALINK_RSTCTRL);
++
++      bypass_pipe_rst();
++      set_phy_for_ssc();
++      ASSERT_SYSRST_PCIE(RALINK_PCIE0_RST | RALINK_PCIE1_RST | RALINK_PCIE2_RST);
++      printk("pull PCIe RST: RALINK_RSTCTRL = %x\n", RALINK_RSTCTRL);
++#if defined GPIO_PERST /* add GPIO control instead of PERST_N */ /*chhung*/
++      *(unsigned int *)(0xbe000060) &= ~(0x3<<10 | 0x3<<3);
++      *(unsigned int *)(0xbe000060) |= 0x1<<10 | 0x1<<3;
++      mdelay(100);
++      *(unsigned int *)(0xbe000600) |= 0x1<<19 | 0x1<<8 | 0x1<<7; // use GPIO19/GPIO8/GPIO7 (PERST_N/UART_RXD3/UART_TXD3)
++      mdelay(100);
++      *(unsigned int *)(0xbe000620) &= ~(0x1<<19 | 0x1<<8 | 0x1<<7);          // clear DATA
++
++      mdelay(100);
++#else
++      *(unsigned int *)(0xbe000060) &= ~0x00000c00;
++#endif
++#if defined (CONFIG_PCIE_PORT0)
++      val = RALINK_PCIE0_RST;
++#endif
++#if defined (CONFIG_PCIE_PORT1)
++      val |= RALINK_PCIE1_RST;
++#endif
++#if defined (CONFIG_PCIE_PORT2)
++      val |= RALINK_PCIE2_RST;
++#endif
++      DEASSERT_SYSRST_PCIE(val);
++      printk("release PCIe RST: RALINK_RSTCTRL = %x\n", RALINK_RSTCTRL);
++#if defined (CONFIG_PCIE_PORT0)
++      read_config(0, 0, 0, 0x70c, &val);
++      val &= ~(0xff)<<8;
++      val |= 0x50<<8;
++      write_config(0, 0, 0, 0x70c, val);
++#endif
++#if defined (CONFIG_PCIE_PORT1)
++      read_config(0, 1, 0, 0x70c, &val);
++      val &= ~(0xff)<<8;
++      val |= 0x50<<8;
++      write_config(0, 1, 0, 0x70c, val);
++#endif
++#if defined (CONFIG_PCIE_PORT2)
++      read_config(0, 2, 0, 0x70c, &val);
++      val &= ~(0xff)<<8;
++      val |= 0x50<<8;
++      write_config(0, 2, 0, 0x70c, val);
++#endif
++
++#if defined (CONFIG_PCIE_PORT0)
++      read_config(0, 0, 0, 0x70c, &val);
++      printk("Port 0 N_FTS = %x\n", (unsigned int)val);
++#endif
++#if defined (CONFIG_PCIE_PORT1)
++      read_config(0, 1, 0, 0x70c, &val);
++      printk("Port 1 N_FTS = %x\n", (unsigned int)val);
++#endif
++#if defined (CONFIG_PCIE_PORT2)
++      read_config(0, 2, 0, 0x70c, &val);
++      printk("Port 2 N_FTS = %x\n", (unsigned int)val);
++#endif
++
++      RALINK_RSTCTRL = (RALINK_RSTCTRL | RALINK_PCIE_RST);
++      RALINK_SYSCFG1 &= ~(0x30);
++      RALINK_SYSCFG1 |= (2<<4);
++      RALINK_PCIE_CLK_GEN &= 0x7fffffff;
++      RALINK_PCIE_CLK_GEN1 &= 0x80ffffff;
++      RALINK_PCIE_CLK_GEN1 |= 0xa << 24;
++      RALINK_PCIE_CLK_GEN |= 0x80000000;
++      mdelay(50);
++      RALINK_RSTCTRL = (RALINK_RSTCTRL & ~RALINK_PCIE_RST);
++      
++
++#if defined GPIO_PERST /* add GPIO control instead of PERST_N */  /*chhung*/
++      *(unsigned int *)(0xbe000620) |= 0x1<<19 | 0x1<<8 | 0x1<<7;             // set DATA
++      mdelay(100);
++#else
++      RALINK_PCI_PCICFG_ADDR &= ~(1<<1); //de-assert PERST
++#endif
++      mdelay(500);
++
++
++      mdelay(500);
++#if defined (CONFIG_PCIE_PORT0)
++      if(( RALINK_PCI0_STATUS & 0x1) == 0)
++      {
++              printk("PCIE0 no card, disable it(RST&CLK)\n");
++              ASSERT_SYSRST_PCIE(RALINK_PCIE0_RST);
++              RALINK_CLKCFG1 = (RALINK_CLKCFG1 & ~RALINK_PCIE0_CLK_EN);
++              pcie_link_status &= ~(1<<0);
++      } else {
++              pcie_link_status |= 1<<0;
++              RALINK_PCI_PCIMSK_ADDR |= (1<<20); // enable pcie1 interrupt
++      }
++#endif
++#if defined (CONFIG_PCIE_PORT1)
++      if(( RALINK_PCI1_STATUS & 0x1) == 0)
++      {
++              printk("PCIE1 no card, disable it(RST&CLK)\n");
++              ASSERT_SYSRST_PCIE(RALINK_PCIE1_RST);
++              RALINK_CLKCFG1 = (RALINK_CLKCFG1 & ~RALINK_PCIE1_CLK_EN);
++              pcie_link_status &= ~(1<<1);
++      } else {
++              pcie_link_status |= 1<<1;
++              RALINK_PCI_PCIMSK_ADDR |= (1<<21); // enable pcie1 interrupt
++      }
++#endif
++#if defined (CONFIG_PCIE_PORT2)
++      if (( RALINK_PCI2_STATUS & 0x1) == 0) {
++              printk("PCIE2 no card, disable it(RST&CLK)\n");
++              ASSERT_SYSRST_PCIE(RALINK_PCIE2_RST);
++              RALINK_CLKCFG1 = (RALINK_CLKCFG1 & ~RALINK_PCIE2_CLK_EN);
++              pcie_link_status &= ~(1<<2);
++      } else {
++              pcie_link_status |= 1<<2;
++              RALINK_PCI_PCIMSK_ADDR |= (1<<22); // enable pcie2 interrupt
++      }
++#endif
++      if (pcie_link_status == 0)
++              return 0;
++
++/*
++pcie(2/1/0) link status       pcie2_num       pcie1_num       pcie0_num
++3'b000                        x               x               x
++3'b001                        x               x               0
++3'b010                        x               0               x
++3'b011                        x               1               0
++3'b100                        0               x               x
++3'b101                        1               x               0
++3'b110                        1               0               x
++3'b111                        2               1               0
++*/
++      switch(pcie_link_status) {
++      case 2:
++              RALINK_PCI_PCICFG_ADDR &= ~0x00ff0000;
++              RALINK_PCI_PCICFG_ADDR |= 0x1 << 16;    //port0
++              RALINK_PCI_PCICFG_ADDR |= 0x0 << 20;    //port1
++              break;
++      case 4:
++              RALINK_PCI_PCICFG_ADDR &= ~0x0fff0000;
++              RALINK_PCI_PCICFG_ADDR |= 0x1 << 16;    //port0
++              RALINK_PCI_PCICFG_ADDR |= 0x2 << 20;    //port1
++              RALINK_PCI_PCICFG_ADDR |= 0x0 << 24;    //port2
++              break;
++      case 5:
++              RALINK_PCI_PCICFG_ADDR &= ~0x0fff0000;
++              RALINK_PCI_PCICFG_ADDR |= 0x0 << 16;    //port0
++              RALINK_PCI_PCICFG_ADDR |= 0x2 << 20;    //port1
++              RALINK_PCI_PCICFG_ADDR |= 0x1 << 24;    //port2
++              break;
++      case 6:
++              RALINK_PCI_PCICFG_ADDR &= ~0x0fff0000;
++              RALINK_PCI_PCICFG_ADDR |= 0x2 << 16;    //port0
++              RALINK_PCI_PCICFG_ADDR |= 0x0 << 20;    //port1
++              RALINK_PCI_PCICFG_ADDR |= 0x1 << 24;    //port2
++              break;
++      }
++      printk(" -> %x\n", RALINK_PCI_PCICFG_ADDR);
++      //printk(" RALINK_PCI_ARBCTL = %x\n", RALINK_PCI_ARBCTL);
++
++/*
++      ioport_resource.start = rt2880_res_pci_io1.start;
++      ioport_resource.end = rt2880_res_pci_io1.end;
++*/
++
++      RALINK_PCI_MEMBASE = 0xffffffff; //RALINK_PCI_MM_MAP_BASE;
++      RALINK_PCI_IOBASE = RALINK_PCI_IO_MAP_BASE;
++
++#if defined (CONFIG_PCIE_PORT0)
++      //PCIe0
++      if((pcie_link_status & 0x1) != 0) {
++              RALINK_PCI0_BAR0SETUP_ADDR = 0x7FFF0001;        //open 7FFF:2G; ENABLE
++              RALINK_PCI0_IMBASEBAR0_ADDR = MEMORY_BASE;
++              RALINK_PCI0_CLASS = 0x06040001;
++              printk("PCIE0 enabled\n");
++      }
++#endif
++#if defined (CONFIG_PCIE_PORT1)
++      //PCIe1
++      if ((pcie_link_status & 0x2) != 0) {
++              RALINK_PCI1_BAR0SETUP_ADDR = 0x7FFF0001;        //open 7FFF:2G; ENABLE
++              RALINK_PCI1_IMBASEBAR0_ADDR = MEMORY_BASE;
++              RALINK_PCI1_CLASS = 0x06040001;
++              printk("PCIE1 enabled\n");
++      }
++#endif
++#if defined (CONFIG_PCIE_PORT2)
++      //PCIe2
++      if ((pcie_link_status & 0x4) != 0) {
++              RALINK_PCI2_BAR0SETUP_ADDR = 0x7FFF0001;        //open 7FFF:2G; ENABLE
++              RALINK_PCI2_IMBASEBAR0_ADDR = MEMORY_BASE;
++              RALINK_PCI2_CLASS = 0x06040001;
++              printk("PCIE2 enabled\n");
++      }
++#endif
++
++
++      switch(pcie_link_status) {
++      case 7:
++              read_config(0, 2, 0, 0x4, &val);
++              write_config(0, 2, 0, 0x4, val|0x4);
++              // write_config(0, 1, 0, 0x4, val|0x7);
++      case 3:
++      case 5:
++      case 6:
++              read_config(0, 1, 0, 0x4, &val);
++              write_config(0, 1, 0, 0x4, val|0x4);
++              // write_config(0, 1, 0, 0x4, val|0x7);
++      default:
++              read_config(0, 0, 0, 0x4, &val);
++              write_config(0, 0, 0, 0x4, val|0x4); //bus master enable
++              // write_config(0, 0, 0, 0x4, val|0x7); //bus master enable
++      }
++      register_pci_controller(&rt2880_controller);
++      return 0;
++
++}
++arch_initcall(init_rt2880pci);
++
++int pcibios_plat_dev_init(struct pci_dev *dev)
++{
++      return 0;
++}
+-- 
+1.7.10.4
+
diff --git a/target/linux/ramips/patches-3.14/0017-MIPS-use-set_mode-to-enable-disable-the-cevt-r4k-irq.patch b/target/linux/ramips/patches-3.14/0017-MIPS-use-set_mode-to-enable-disable-the-cevt-r4k-irq.patch
new file mode 100644 (file)
index 0000000..fc9a70b
--- /dev/null
@@ -0,0 +1,85 @@
+From f8da5caf65926d44581d4e7914b28ceab3d28a7c Mon Sep 17 00:00:00 2001
+From: John Crispin <blogic@openwrt.org>
+Date: Sun, 14 Jul 2013 23:08:11 +0200
+Subject: [PATCH 17/57] MIPS: use set_mode() to enable/disable the cevt-r4k
+ irq
+
+Signed-off-by: John Crispin <blogic@openwrt.org>
+---
+ arch/mips/kernel/cevt-r4k.c |   37 +++++++++++++++++++++++++++++++------
+ 1 file changed, 31 insertions(+), 6 deletions(-)
+
+diff --git a/arch/mips/kernel/cevt-r4k.c b/arch/mips/kernel/cevt-r4k.c
+index 50d3f5a..99585e6 100644
+--- a/arch/mips/kernel/cevt-r4k.c
++++ b/arch/mips/kernel/cevt-r4k.c
+@@ -38,12 +38,6 @@ static int mips_next_event(unsigned long delta,
+ #endif /* CONFIG_MIPS_MT_SMTC */
+-void mips_set_clock_mode(enum clock_event_mode mode,
+-                              struct clock_event_device *evt)
+-{
+-      /* Nothing to do ...  */
+-}
+-
+ DEFINE_PER_CPU(struct clock_event_device, mips_clockevent_device);
+ int cp0_timer_irq_installed;
+@@ -90,9 +84,38 @@ struct irqaction c0_compare_irqaction = {
+       .name = "timer",
+ };
++void mips_set_clock_mode(enum clock_event_mode mode,
++                              struct clock_event_device *evt)
++{
++#ifdef CONFIG_CEVT_SYSTICK_QUIRK
++      switch (mode) {
++      case CLOCK_EVT_MODE_ONESHOT:
++              if (cp0_timer_irq_installed)
++                      break;
++
++              cp0_timer_irq_installed = 1;
++
++              setup_irq(evt->irq, &c0_compare_irqaction);
++              break;
++
++      case CLOCK_EVT_MODE_SHUTDOWN:
++              if (!cp0_timer_irq_installed)
++                      break;
++
++              cp0_timer_irq_installed = 0;
++              free_irq(evt->irq, &c0_compare_irqaction);
++              break;
++
++      default:
++              pr_err("Unhandeled mips clock_mode\n");
++              break;
++      }
++#endif
++}
+ void mips_event_handler(struct clock_event_device *dev)
+ {
++
+ }
+ /*
+@@ -215,12 +238,14 @@ int r4k_clockevent_init(void)
+ #endif
+       clockevents_register_device(cd);
++#ifndef CONFIG_CEVT_SYSTICK_QUIRK
+       if (cp0_timer_irq_installed)
+               return 0;
+       cp0_timer_irq_installed = 1;
+       setup_irq(irq, &c0_compare_irqaction);
++#endif
+       return 0;
+ }
+-- 
+1.7.10.4
+
diff --git a/target/linux/ramips/patches-3.14/0018-MIPS-ralink-workaround-DTB-memory-issue.patch b/target/linux/ramips/patches-3.14/0018-MIPS-ralink-workaround-DTB-memory-issue.patch
new file mode 100644 (file)
index 0000000..0f61933
--- /dev/null
@@ -0,0 +1,29 @@
+From 35297af46f17092785930f32a616331c8df8f75c Mon Sep 17 00:00:00 2001
+From: John Crispin <blogic@openwrt.org>
+Date: Thu, 23 May 2013 18:50:56 +0200
+Subject: [PATCH 18/57] MIPS: ralink: workaround DTB memory issue
+
+If the DTB is too big a bug happens on boot when init ram is freed.
+This is a temporary fix until the real cause is found.
+
+Signed-off-by: John Crispin <blogic@openwrt.org>
+---
+ arch/mips/ralink/of.c |    2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/arch/mips/ralink/of.c b/arch/mips/ralink/of.c
+index 1b81e8f..885cf50 100644
+--- a/arch/mips/ralink/of.c
++++ b/arch/mips/ralink/of.c
+@@ -75,7 +75,7 @@ void __init device_tree_init(void)
+       unflatten_device_tree();
+       /* free the space reserved for the dt blob */
+-      free_bootmem(base, size);
++      //free_bootmem(base, size);
+ }
+ static int memory_dtb;
+-- 
+1.7.10.4
+
diff --git a/target/linux/ramips/patches-3.14/0019-MIPS-ralink-add-pseudo-pwm-led-trigger-based-on-time.patch b/target/linux/ramips/patches-3.14/0019-MIPS-ralink-add-pseudo-pwm-led-trigger-based-on-time.patch
new file mode 100644 (file)
index 0000000..cec6e8f
--- /dev/null
@@ -0,0 +1,306 @@
+From 9de00286e20a5f5edc419698373010f1cb6ff0ce Mon Sep 17 00:00:00 2001
+From: John Crispin <blogic@openwrt.org>
+Date: Sun, 27 Jul 2014 09:25:02 +0100
+Subject: [PATCH 19/57] MIPS: ralink: add pseudo pwm led trigger based on
+ timer0
+
+Signed-off-by: John Crispin <blogic@openwrt.org>
+---
+ arch/mips/ralink/timer.c |  213 ++++++++++++++++++++++++++++++++++++++++++----
+ 1 file changed, 197 insertions(+), 16 deletions(-)
+
+diff --git a/arch/mips/ralink/timer.c b/arch/mips/ralink/timer.c
+index e38692a..a71a7cb 100644
+--- a/arch/mips/ralink/timer.c
++++ b/arch/mips/ralink/timer.c
+@@ -12,6 +12,8 @@
+ #include <linux/timer.h>
+ #include <linux/of_gpio.h>
+ #include <linux/clk.h>
++#include <linux/leds.h>
++#include <linux/slab.h>
+ #include <asm/mach-ralink/ralink_regs.h>
+@@ -23,16 +25,34 @@
+ #define TMR0CTL_ENABLE                        BIT(7)
+ #define TMR0CTL_MODE_PERIODIC         BIT(4)
+-#define TMR0CTL_PRESCALER             1
++#define TMR0CTL_PRESCALER             2
+ #define TMR0CTL_PRESCALE_VAL          (0xf - TMR0CTL_PRESCALER)
+ #define TMR0CTL_PRESCALE_DIV          (65536 / BIT(TMR0CTL_PRESCALER))
++struct rt_timer_gpio {
++      struct list_head        list;
++      struct led_classdev     *led;
++};
++
+ struct rt_timer {
+-      struct device   *dev;
+-      void __iomem    *membase;
+-      int             irq;
+-      unsigned long   timer_freq;
+-      unsigned long   timer_div;
++      struct device           *dev;
++      void __iomem            *membase;
++      int                     irq;
++
++      unsigned long           timer_freq;
++      unsigned long           timer_div;
++
++      struct list_head        gpios;
++      struct led_trigger      led_trigger;
++      unsigned int            duty_cycle;
++      unsigned int            duty;
++
++      unsigned int            fade;
++      unsigned int            fade_min;
++      unsigned int            fade_max;
++      unsigned int            fade_speed;
++      unsigned int            fade_dir;
++      unsigned int            fade_count;
+ };
+ static inline void rt_timer_w32(struct rt_timer *rt, u8 reg, u32 val)
+@@ -48,18 +68,46 @@ static inline u32 rt_timer_r32(struct rt_timer *rt, u8 reg)
+ static irqreturn_t rt_timer_irq(int irq, void *_rt)
+ {
+       struct rt_timer *rt =  (struct rt_timer *) _rt;
++      struct rt_timer_gpio *gpio;
++      unsigned int val;
+-      rt_timer_w32(rt, TIMER_REG_TMR0LOAD, rt->timer_freq / rt->timer_div);
++      if (rt->fade && (rt->fade_count++ > rt->fade_speed)) {
++              rt->fade_count = 0;
++              if (rt->duty_cycle <= rt->fade_min)
++                      rt->fade_dir = 1;
++              else if (rt->duty_cycle >= rt->fade_max)
++                      rt->fade_dir = 0;
++
++              if (rt->fade_dir)
++                      rt->duty_cycle += 1;
++              else
++                      rt->duty_cycle -= 1;
++
++      }
++
++      val = rt->timer_freq / rt->timer_div;
++      if (rt->duty)
++              val *= rt->duty_cycle;
++      else
++              val *= (100 - rt->duty_cycle);
++      val /= 100;
++
++      if (!list_empty(&rt->gpios))
++              list_for_each_entry(gpio, &rt->gpios, list)
++                      led_set_brightness(gpio->led, !!rt->duty);
++
++      rt->duty = !rt->duty;
++
++      rt_timer_w32(rt, TIMER_REG_TMR0LOAD, val + 1);
+       rt_timer_w32(rt, TIMER_REG_TMRSTAT, TMRSTAT_TMR0INT);
+       return IRQ_HANDLED;
+ }
+-
+ static int rt_timer_request(struct rt_timer *rt)
+ {
+-      int err = request_irq(rt->irq, rt_timer_irq, IRQF_DISABLED,
+-                                              dev_name(rt->dev), rt);
++      int err = devm_request_irq(rt->dev, rt->irq, rt_timer_irq,
++                                      IRQF_DISABLED, dev_name(rt->dev), rt);
+       if (err) {
+               dev_err(rt->dev, "failed to request irq\n");
+       } else {
+@@ -81,8 +129,6 @@ static int rt_timer_config(struct rt_timer *rt, unsigned long divisor)
+       else
+               rt->timer_div = divisor;
+-      rt_timer_w32(rt, TIMER_REG_TMR0LOAD, rt->timer_freq / rt->timer_div);
+-
+       return 0;
+ }
+@@ -108,11 +154,128 @@ static void rt_timer_disable(struct rt_timer *rt)
+       rt_timer_w32(rt, TIMER_REG_TMR0CTL, t);
+ }
++static ssize_t led_fade_show(struct device *dev,
++                              struct device_attribute *attr, char *buf)
++{
++      struct led_classdev *led_cdev = dev_get_drvdata(dev);
++      struct rt_timer *rt = container_of(led_cdev->trigger, struct rt_timer, led_trigger);
++
++      return sprintf(buf, "speed: %d, min: %d, max: %d\n", rt->fade_speed, rt->fade_min, rt->fade_max);
++}
++
++static ssize_t led_fade_store(struct device *dev,
++              struct device_attribute *attr, const char *buf, size_t size)
++{
++      struct led_classdev *led_cdev = dev_get_drvdata(dev);
++      struct rt_timer *rt = container_of(led_cdev->trigger, struct rt_timer, led_trigger);
++      unsigned int speed = 0, min = 0, max = 0;
++      ssize_t ret = -EINVAL;
++
++      ret = sscanf(buf, "%u %u %u", &speed, &min, &max);
++
++      if (ret == 3) {
++              rt->fade_speed = speed;
++              rt->fade_min = min;
++              rt->fade_max = max;
++              rt->fade = 1;
++      } else {
++              rt->fade = 0;
++      }
++
++      return size;
++}
++
++static DEVICE_ATTR(fade, 0644, led_fade_show, led_fade_store);
++
++static ssize_t led_duty_cycle_show(struct device *dev,
++                              struct device_attribute *attr, char *buf)
++{
++      struct led_classdev *led_cdev = dev_get_drvdata(dev);
++      struct rt_timer *rt = container_of(led_cdev->trigger, struct rt_timer, led_trigger);
++
++      return sprintf(buf, "%u\n", rt->duty_cycle);
++}
++
++static ssize_t led_duty_cycle_store(struct device *dev,
++              struct device_attribute *attr, const char *buf, size_t size)
++{
++      struct led_classdev *led_cdev = dev_get_drvdata(dev);
++      struct rt_timer *rt = container_of(led_cdev->trigger, struct rt_timer, led_trigger);
++      unsigned long state;
++      ssize_t ret = -EINVAL;
++
++      ret = kstrtoul(buf, 10, &state);
++      if (ret)
++              return ret;
++
++      if (state <= 100)
++              rt->duty_cycle = state;
++      else
++              rt->duty_cycle = 100;
++
++      rt->fade = 0;
++
++      return size;
++}
++
++static DEVICE_ATTR(duty_cycle, 0644, led_duty_cycle_show, led_duty_cycle_store);
++
++static void rt_timer_trig_activate(struct led_classdev *led_cdev)
++{
++      struct rt_timer *rt = container_of(led_cdev->trigger, struct rt_timer, led_trigger);
++      struct rt_timer_gpio *gpio_data;
++      int rc;
++
++      led_cdev->trigger_data = NULL;
++      gpio_data = kzalloc(sizeof(*gpio_data), GFP_KERNEL);
++      if (!gpio_data)
++              return;
++
++      rc = device_create_file(led_cdev->dev, &dev_attr_duty_cycle);
++      if (rc)
++              goto err_gpio;
++      rc = device_create_file(led_cdev->dev, &dev_attr_fade);
++      if (rc)
++              goto err_out_duty_cycle;
++
++      led_cdev->activated = true;
++      led_cdev->trigger_data = gpio_data;
++      gpio_data->led = led_cdev;
++      list_add(&gpio_data->list, &rt->gpios);
++      led_cdev->trigger_data = gpio_data;
++      rt_timer_enable(rt);
++      return;
++
++err_out_duty_cycle:
++      device_remove_file(led_cdev->dev, &dev_attr_duty_cycle);
++
++err_gpio:
++      kfree(gpio_data);
++}
++
++static void rt_timer_trig_deactivate(struct led_classdev *led_cdev)
++{
++      struct rt_timer *rt = container_of(led_cdev->trigger, struct rt_timer, led_trigger);
++      struct rt_timer_gpio *gpio_data = (struct rt_timer_gpio*) led_cdev->trigger_data;
++
++      if (led_cdev->activated) {
++              device_remove_file(led_cdev->dev, &dev_attr_duty_cycle);
++              device_remove_file(led_cdev->dev, &dev_attr_fade);
++              led_cdev->activated = false;
++      }
++
++      list_del(&gpio_data->list);
++      rt_timer_disable(rt);
++      led_set_brightness(led_cdev, LED_OFF);
++}
++
+ static int rt_timer_probe(struct platform_device *pdev)
+ {
+       struct resource *res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
++      const __be32 *divisor;
+       struct rt_timer *rt;
+       struct clk *clk;
++      int ret;
+       rt = devm_kzalloc(&pdev->dev, sizeof(*rt), GFP_KERNEL);
+       if (!rt) {
+@@ -140,12 +303,29 @@ static int rt_timer_probe(struct platform_device *pdev)
+       if (!rt->timer_freq)
+               return -EINVAL;
++      rt->duty_cycle = 100;
+       rt->dev = &pdev->dev;
+       platform_set_drvdata(pdev, rt);
+-      rt_timer_request(rt);
+-      rt_timer_config(rt, 2);
+-      rt_timer_enable(rt);
++      ret = rt_timer_request(rt);
++      if (ret)
++              return ret;
++
++      divisor = of_get_property(pdev->dev.of_node, "ralink,divisor", NULL);
++      if (divisor)
++              rt_timer_config(rt, be32_to_cpu(*divisor));
++      else
++              rt_timer_config(rt, 200);
++
++      rt->led_trigger.name = "pwmtimer",
++      rt->led_trigger.activate = rt_timer_trig_activate,
++      rt->led_trigger.deactivate = rt_timer_trig_deactivate,
++
++      ret = led_trigger_register(&rt->led_trigger);
++      if (ret)
++              return ret;
++
++      INIT_LIST_HEAD(&rt->gpios);
+       dev_info(&pdev->dev, "maximum frequency is %luHz\n", rt->timer_freq);
+@@ -156,6 +336,7 @@ static int rt_timer_remove(struct platform_device *pdev)
+ {
+       struct rt_timer *rt = platform_get_drvdata(pdev);
++      led_trigger_unregister(&rt->led_trigger);
+       rt_timer_disable(rt);
+       rt_timer_free(rt);
+@@ -180,6 +361,6 @@ static struct platform_driver rt_timer_driver = {
+ module_platform_driver(rt_timer_driver);
+-MODULE_DESCRIPTION("Ralink RT2880 timer");
++MODULE_DESCRIPTION("Ralink RT2880 timer / pseudo pwm");
+ MODULE_AUTHOR("John Crispin <blogic@openwrt.org");
+ MODULE_LICENSE("GPL");
+-- 
+1.7.10.4
+
diff --git a/target/linux/ramips/patches-3.14/0020-MIPS-ralink-update-dts-files.patch b/target/linux/ramips/patches-3.14/0020-MIPS-ralink-update-dts-files.patch
new file mode 100644 (file)
index 0000000..52fd321
--- /dev/null
@@ -0,0 +1,638 @@
+From 0c1e8630dca36c2d5a9bf98a5f1f8c15f75d0253 Mon Sep 17 00:00:00 2001
+From: John Crispin <blogic@openwrt.org>
+Date: Mon, 12 Aug 2013 18:11:33 +0200
+Subject: [PATCH 20/57] MIPS: ralink: update dts files
+
+Add the devicetree nodes needed to make the newly merged drivers work.
+
+Signed-off-by: John Crispin <blogic@openwrt.org>
+---
+ arch/mips/ralink/dts/mt7620a.dtsi |  135 +++++++++++++++++++++++
+ arch/mips/ralink/dts/rt3050.dtsi  |  156 ++++++++++++++++++++++++++
+ arch/mips/ralink/dts/rt3883.dtsi  |  219 +++++++++++++++++++++++++++++++++++++
+ 3 files changed, 510 insertions(+)
+
+diff --git a/arch/mips/ralink/dts/mt7620a.dtsi b/arch/mips/ralink/dts/mt7620a.dtsi
+index 08bf24f..df6cb79 100644
+--- a/arch/mips/ralink/dts/mt7620a.dtsi
++++ b/arch/mips/ralink/dts/mt7620a.dtsi
+@@ -29,10 +29,32 @@
+                       reg = <0x0 0x100>;
+               };
++              timer@100 {
++                      compatible = "ralink,mt7620a-timer", "ralink,rt2880-timer";
++                      reg = <0x100 0x20>;
++
++                      interrupt-parent = <&intc>;
++                      interrupts = <1>;
++              };
++
++              watchdog@120 {
++                      compatible = "ralink,mt7620a-wdt", "ralink,rt2880-wdt";
++                      reg = <0x120 0x10>;
++
++                      resets = <&rstctrl 8>;
++                      reset-names = "wdt";
++
++                      interrupt-parent = <&intc>;
++                      interrupts = <1>;
++              };
++
+               intc: intc@200 {
+                       compatible = "ralink,mt7620a-intc", "ralink,rt2880-intc";
+                       reg = <0x200 0x100>;
++                      resets = <&rstctrl 19>;
++                      reset-names = "intc";
++
+                       interrupt-controller;
+                       #interrupt-cells = <1>;
+@@ -43,16 +65,129 @@
+               memc@300 {
+                       compatible = "ralink,mt7620a-memc", "ralink,rt3050-memc";
+                       reg = <0x300 0x100>;
++
++                      resets = <&rstctrl 20>;
++                      reset-names = "mc";
++
++                      interrupt-parent = <&intc>;
++                      interrupts = <3>;
++              };
++
++              uart@500 {
++                      compatible = "ralink,mt7620a-uart", "ralink,rt2880-uart", "ns16550a";
++                      reg = <0x500 0x100>;
++
++                      resets = <&rstctrl 12>;
++                      reset-names = "uart";
++
++                      interrupt-parent = <&intc>;
++                      interrupts = <5>;
++
++                      reg-shift = <2>;
++
++                      status = "disabled";
++              };
++
++              gpio0: gpio@600 {
++                      compatible = "ralink,mt7620a-gpio", "ralink,rt2880-gpio";
++                      reg = <0x600 0x34>;
++
++                      resets = <&rstctrl 13>;
++                      reset-names = "pio";
++
++                      interrupt-parent = <&intc>;
++                      interrupts = <6>;
++
++                      gpio-controller;
++                      #gpio-cells = <2>;
++
++                      ralink,gpio-base = <0>;
++                      ralink,num-gpios = <24>;
++                      ralink,register-map = [ 00 04 08 0c
++                                              20 24 28 2c
++                                              30 34 ];
++
++                      status = "disabled";
++              };
++
++              gpio1: gpio@638 {
++                      compatible = "ralink,mt7620a-gpio", "ralink,rt2880-gpio";
++                      reg = <0x638 0x24>;
++
++                      interrupt-parent = <&intc>;
++                      interrupts = <6>;
++
++                      gpio-controller;
++                      #gpio-cells = <2>;
++
++                      ralink,gpio-base = <24>;
++                      ralink,num-gpios = <16>;
++                      ralink,register-map = [ 00 04 08 0c
++                                              10 14 18 1c
++                                              20 24 ];
++
++                      status = "disabled";
++              };
++
++              gpio2: gpio@660 {
++                      compatible = "ralink,mt7620a-gpio", "ralink,rt2880-gpio";
++                      reg = <0x660 0x24>;
++
++                      interrupt-parent = <&intc>;
++                      interrupts = <6>;
++
++                      gpio-controller;
++                      #gpio-cells = <2>;
++
++                      ralink,gpio-base = <40>;
++                      ralink,num-gpios = <32>;
++                      ralink,register-map = [ 00 04 08 0c
++                                              10 14 18 1c
++                                              20 24 ];
++
++                      status = "disabled";
++              };
++
++              spi@b00 {
++                      compatible = "ralink,mt7620a-spi", "ralink,rt2880-spi";
++                      reg = <0xb00 0x100>;
++
++                      resets = <&rstctrl 18>;
++                      reset-names = "spi";
++
++                      #address-cells = <1>;
++                      #size-cells = <1>;
++
++                      status = "disabled";
+               };
+               uartlite@c00 {
+                       compatible = "ralink,mt7620a-uart", "ralink,rt2880-uart", "ns16550a";
+                       reg = <0xc00 0x100>;
++                      resets = <&rstctrl 19>;
++                      reset-names = "uartl";
++
+                       interrupt-parent = <&intc>;
+                       interrupts = <12>;
+                       reg-shift = <2>;
+               };
++
++              systick@d00 {
++                      compatible = "ralink,mt7620a-systick", "ralink,cevt-systick";
++                      reg = <0xd00 0x10>;
++
++                      resets = <&rstctrl 28>;
++                      reset-names = "intc";
++
++                      interrupt-parent = <&cpuintc>;
++                      interrupts = <7>;
++              };
++      };
++
++      rstctrl: rstctrl {
++              compatible = "ralink,mt7620a-reset", "ralink,rt2880-reset";
++              #reset-cells = <1>;
+       };
+ };
+diff --git a/arch/mips/ralink/dts/rt3050.dtsi b/arch/mips/ralink/dts/rt3050.dtsi
+index e3203d4..49622d7 100644
+--- a/arch/mips/ralink/dts/rt3050.dtsi
++++ b/arch/mips/ralink/dts/rt3050.dtsi
+@@ -9,6 +9,10 @@
+               };
+       };
++      chosen {
++              bootargs = "console=ttyS0,57600";
++      };
++
+       cpuintc: cpuintc@0 {
+               #address-cells = <0>;
+               #interrupt-cells = <1>;
+@@ -29,10 +33,32 @@
+                       reg = <0x0 0x100>;
+               };
++              timer@100 {
++                      compatible = "ralink,rt3052-timer", "ralink,rt2880-timer";
++                      reg = <0x100 0x20>;
++
++                      interrupt-parent = <&intc>;
++                      interrupts = <1>;
++              };
++
++              watchdog@120 {
++                      compatible = "ralink,rt3052-wdt", "ralink,rt2880-wdt";
++                      reg = <0x120 0x10>;
++
++                      resets = <&rstctrl 8>;
++                      reset-names = "wdt";
++
++                      interrupt-parent = <&intc>;
++                      interrupts = <1>;
++              };
++
+               intc: intc@200 {
+                       compatible = "ralink,rt3052-intc", "ralink,rt2880-intc";
+                       reg = <0x200 0x100>;
++                      resets = <&rstctrl 19>;
++                      reset-names = "intc";
++
+                       interrupt-controller;
+                       #interrupt-cells = <1>;
+@@ -43,17 +69,144 @@
+               memc@300 {
+                       compatible = "ralink,rt3052-memc", "ralink,rt3050-memc";
+                       reg = <0x300 0x100>;
++
++                      resets = <&rstctrl 20>;
++                      reset-names = "mc";
++
++                      interrupt-parent = <&intc>;
++                      interrupts = <3>;
++              };
++
++              uart@500 {
++                      compatible = "ralink,rt5350-uart", "ralink,rt2880-uart", "ns16550a";
++                      reg = <0x500 0x100>;
++
++                      resets = <&rstctrl 12>;
++                      reset-names = "uart";
++
++                      interrupt-parent = <&intc>;
++                      interrupts = <5>;
++
++                      reg-shift = <2>;
++
++                      status = "disabled";
++              };
++
++              gpio0: gpio@600 {
++                      compatible = "ralink,rt3052-gpio", "ralink,rt2880-gpio";
++                      reg = <0x600 0x34>;
++
++                      gpio-controller;
++                      #gpio-cells = <2>;
++
++                      ralink,gpio-base = <0>;
++                      ralink,num-gpios = <24>;
++                      ralink,register-map = [ 00 04 08 0c
++                                              20 24 28 2c
++                                              30 34 ];
++
++                      resets = <&rstctrl 13>;
++                      reset-names = "pio";
++
++                      interrupt-parent = <&intc>;
++                      interrupts = <6>;
++
++                      status = "disabled";
++              };
++
++              gpio1: gpio@638 {
++                      compatible = "ralink,rt3052-gpio", "ralink,rt2880-gpio";
++                      reg = <0x638 0x24>;
++
++                      gpio-controller;
++                      #gpio-cells = <2>;
++
++                      ralink,gpio-base = <24>;
++                      ralink,num-gpios = <16>;
++                      ralink,register-map = [ 00 04 08 0c
++                                              10 14 18 1c
++                                              20 24 ];
++
++                      status = "disabled";
++              };
++
++              gpio2: gpio@660 {
++                      compatible = "ralink,rt3052-gpio", "ralink,rt2880-gpio";
++                      reg = <0x660 0x24>;
++
++                      gpio-controller;
++                      #gpio-cells = <2>;
++
++                      ralink,gpio-base = <40>;
++                      ralink,num-gpios = <12>;
++                      ralink,register-map = [ 00 04 08 0c
++                                              10 14 18 1c
++                                              20 24 ];
++
++                      status = "disabled";
++              };
++
++              spi@b00 {
++                      compatible = "ralink,rt3050-spi", "ralink,rt2880-spi";
++                      reg = <0xb00 0x100>;
++
++                      resets = <&rstctrl 18>;
++                      reset-names = "spi";
++
++                      #address-cells = <1>;
++                      #size-cells = <0>;
++
++                      status = "disabled";
+               };
+               uartlite@c00 {
+                       compatible = "ralink,rt3052-uart", "ralink,rt2880-uart", "ns16550a";
+                       reg = <0xc00 0x100>;
++                      resets = <&rstctrl 19>;
++                      reset-names = "uartl";
++
+                       interrupt-parent = <&intc>;
+                       interrupts = <12>;
+                       reg-shift = <2>;
+               };
++
++      };
++
++      rstctrl: rstctrl {
++              compatible = "ralink,rt3050-reset", "ralink,rt2880-reset";
++              #reset-cells = <1>;
++      };
++
++      ethernet@10100000 {
++              compatible = "ralink,rt3050-eth";
++              reg = <0x10100000 10000>;
++
++              interrupt-parent = <&cpuintc>;
++              interrupts = <5>;
++
++              status = "disabled";
++      };
++
++      esw@10110000 {
++              compatible = "ralink,rt3050-esw";
++              reg = <0x10110000 8000>;
++
++              interrupt-parent = <&intc>;
++              interrupts = <17>;
++
++              status = "disabled";
++      };
++
++      wmac@10180000 {
++              compatible = "ralink,rt3050-wmac", "ralink,rt2880-wmac";
++              reg = <0x10180000 40000>;
++
++              interrupt-parent = <&cpuintc>;
++              interrupts = <6>;
++
++              status = "disabled";
+       };
+       usb@101c0000 {
+@@ -63,6 +216,9 @@
+               interrupt-parent = <&intc>;
+               interrupts = <18>;
++              resets = <&rstctrl 22>;
++              reset-names = "otg";
++
+               status = "disabled";
+       };
+ };
+diff --git a/arch/mips/ralink/dts/rt3883.dtsi b/arch/mips/ralink/dts/rt3883.dtsi
+index 3b131dd..4d092b1 100644
+--- a/arch/mips/ralink/dts/rt3883.dtsi
++++ b/arch/mips/ralink/dts/rt3883.dtsi
+@@ -29,10 +29,32 @@
+                       reg = <0x0 0x100>;
+               };
++              timer@100 {
++                      compatible = "ralink,rt3883-timer", "ralink,rt2880-timer";
++                      reg = <0x100 0x20>;
++
++                      interrupt-parent = <&intc>;
++                      interrupts = <1>;
++              };
++
++              watchdog@120 {
++                      compatible = "ralink,rt3883-wdt", "ralink,rt2880-wdt";
++                      reg = <0x120 0x10>;
++
++                      resets = <&rstctrl 8>;
++                      reset-names = "wdt";
++
++                      interrupt-parent = <&intc>;
++                      interrupts = <1>;
++              };
++
+               intc: intc@200 {
+                       compatible = "ralink,rt3883-intc", "ralink,rt2880-intc";
+                       reg = <0x200 0x100>;
++                      resets = <&rstctrl 19>;
++                      reset-names = "intc";
++
+                       interrupt-controller;
+                       #interrupt-cells = <1>;
+@@ -43,16 +65,213 @@
+               memc@300 {
+                       compatible = "ralink,rt3883-memc", "ralink,rt3050-memc";
+                       reg = <0x300 0x100>;
++
++                      resets = <&rstctrl 20>;
++                      reset-names = "mc";
++
++                      interrupt-parent = <&intc>;
++                      interrupts = <3>;
++              };
++
++              uart@500 {
++                      compatible = "ralink,rt3883-uart", "ralink,rt2880-uart", "ns16550a";
++                      reg = <0x500 0x100>;
++
++                      resets = <&rstctrl 12>;
++                      reset-names = "uart";
++
++                      interrupt-parent = <&intc>;
++                      interrupts = <5>;
++
++                      reg-shift = <2>;
++
++                      status = "disabled";
++              };
++
++              gpio0: gpio@600 {
++                      compatible = "ralink,rt3883-gpio", "ralink,rt2880-gpio";
++                      reg = <0x600 0x34>;
++
++                      resets = <&rstctrl 13>;
++                      reset-names = "pio";
++
++                      interrupt-parent = <&intc>;
++                      interrupts = <6>;
++
++                      gpio-controller;
++                      #gpio-cells = <2>;
++
++                      ralink,gpio-base = <0>;
++                      ralink,num-gpios = <24>;
++                      ralink,register-map = [ 00 04 08 0c
++                                              20 24 28 2c
++                                              30 34 ];
++
++                      status = "disabled";
++              };
++
++              gpio1: gpio@638 {
++                      compatible = "ralink,rt3883-gpio", "ralink,rt2880-gpio";
++                      reg = <0x638 0x24>;
++
++                      gpio-controller;
++                      #gpio-cells = <2>;
++
++                      ralink,gpio-base = <24>;
++                      ralink,num-gpios = <16>;
++                      ralink,register-map = [ 00 04 08 0c
++                                              10 14 18 1c
++                                              20 24 ];
++
++                      status = "disabled";
++              };
++
++              gpio2: gpio@660 {
++                      compatible = "ralink,rt3883-gpio", "ralink,rt2880-gpio";
++                      reg = <0x660 0x24>;
++
++                      gpio-controller;
++                      #gpio-cells = <2>;
++
++                      ralink,gpio-base = <40>;
++                      ralink,num-gpios = <32>;
++                      ralink,register-map = [ 00 04 08 0c
++                                              10 14 18 1c
++                                              20 24 ];
++
++                      status = "disabled";
++              };
++
++              gpio3: gpio@688 {
++                      compatible = "ralink,rt3883-gpio", "ralink,rt2880-gpio";
++                      reg = <0x688 0x24>;
++
++                      gpio-controller;
++                      #gpio-cells = <2>;
++
++                      ralink,gpio-base = <72>;
++                      ralink,num-gpios = <24>;
++                      ralink,register-map = [ 00 04 08 0c
++                                              10 14 18 1c
++                                              20 24 ];
++
++                      status = "disabled";
++              };
++
++              spi0: spi@b00 {
++                      compatible = "ralink,rt3883-spi", "ralink,rt2880-spi";
++                      reg = <0xb00 0x100>;
++                      #address-cells = <1>;
++                      #size-cells = <0>;
++
++                      resets = <&rstctrl 18>;
++                      reset-names = "spi";
++
++                      status = "disabled";
+               };
+               uartlite@c00 {
+                       compatible = "ralink,rt3883-uart", "ralink,rt2880-uart", "ns16550a";
+                       reg = <0xc00 0x100>;
++                      resets = <&rstctrl 19>;
++                      reset-names = "uartl";
++
+                       interrupt-parent = <&intc>;
+                       interrupts = <12>;
+                       reg-shift = <2>;
+               };
+       };
++
++      rstctrl: rstctrl {
++              compatible = "ralink,rt3883-reset", "ralink,rt2880-reset";
++              #reset-cells = <1>;
++      };
++
++      pci@10140000 {
++              compatible = "ralink,rt3883-pci";
++              reg = <0x10140000 0x20000>;
++              #address-cells = <1>;
++              #size-cells = <1>;
++              ranges; /* direct mapping */
++
++              status = "disabled";
++
++              pciintc: interrupt-controller {
++                      interrupt-controller;
++                      #address-cells = <0>;
++                      #interrupt-cells = <1>;
++
++                      interrupt-parent = <&cpuintc>;
++                      interrupts = <4>;
++              };
++
++              host-bridge {
++                      #address-cells = <3>;
++                      #size-cells = <2>;
++                      #interrupt-cells = <1>;
++
++                      device_type = "pci";
++
++                      bus-range = <0 255>;
++                      ranges = <
++                              0x02000000 0 0x00000000 0x20000000 0 0x10000000 /* pci memory */
++                              0x01000000 0 0x00000000 0x10160000 0 0x00010000 /* io space */
++                      >;
++
++                      interrupt-map-mask = <0xf800 0 0 7>;
++                      interrupt-map = <
++                              /* IDSEL 17 */
++                              0x8800 0 0 1 &pciintc 18
++                              0x8800 0 0 2 &pciintc 18
++                              0x8800 0 0 3 &pciintc 18
++                              0x8800 0 0 4 &pciintc 18
++                              /* IDSEL 18 */
++                              0x9000 0 0 1 &pciintc 19
++                              0x9000 0 0 2 &pciintc 19
++                              0x9000 0 0 3 &pciintc 19
++                              0x9000 0 0 4 &pciintc 19
++                      >;
++
++                      pci-bridge@1 {
++                              reg = <0x0800 0 0 0 0>;
++                              device_type = "pci";
++                              #interrupt-cells = <1>;
++                              #address-cells = <3>;
++                              #size-cells = <2>;
++
++                              status = "disabled";
++
++                              ralink,pci-slot = <1>;
++
++                              interrupt-map-mask = <0x0 0 0 0>;
++                              interrupt-map = <0x0 0 0 0 &pciintc 20>;
++                      };
++
++                      pci-slot@17 {
++                              reg = <0x8800 0 0 0 0>;
++                              device_type = "pci";
++                              #interrupt-cells = <1>;
++                              #address-cells = <3>;
++                              #size-cells = <2>;
++
++                              ralink,pci-slot = <17>;
++
++                              status = "disabled";
++                      };
++
++                      pci-slot@18 {
++                              reg = <0x9000 0 0 0 0>;
++                              device_type = "pci";
++                              #interrupt-cells = <1>;
++                              #address-cells = <3>;
++                              #size-cells = <2>;
++
++                              ralink,pci-slot = <18>;
++
++                              status = "disabled";
++                      };
++              };
++      };
+ };
+-- 
+1.7.10.4
+
diff --git a/target/linux/ramips/patches-3.14/0021-MIPS-ralink-add-cpu-frequency-scaling.patch b/target/linux/ramips/patches-3.14/0021-MIPS-ralink-add-cpu-frequency-scaling.patch
new file mode 100644 (file)
index 0000000..d60d651
--- /dev/null
@@ -0,0 +1,100 @@
+From e76ecd496c9b074ab21b17f12494d823a407e89a Mon Sep 17 00:00:00 2001
+From: John Crispin <blogic@openwrt.org>
+Date: Sun, 28 Jul 2013 16:26:41 +0200
+Subject: [PATCH 21/57] MIPS: ralink: add cpu frequency scaling
+
+This feature will break udelay() and cause the delay loop to have longer delays
+when the frequency is scaled causing a performance hit.
+
+Signed-off-by: John Crispin <blogic@openwrt.org>
+---
+ arch/mips/ralink/cevt-rt3352.c |   36 ++++++++++++++++++++++++++++++++++++
+ 1 file changed, 36 insertions(+)
+
+diff --git a/arch/mips/ralink/cevt-rt3352.c b/arch/mips/ralink/cevt-rt3352.c
+index 24bf057..4174b40 100644
+--- a/arch/mips/ralink/cevt-rt3352.c
++++ b/arch/mips/ralink/cevt-rt3352.c
+@@ -29,6 +29,10 @@
+ /* enable the counter */
+ #define CFG_CNT_EN            0x1
++/* mt7620 frequency scaling defines */
++#define CLK_LUT_CFG   0x40
++#define SLEEP_EN      BIT(31)
++
+ struct systick_device {
+       void __iomem *membase;
+       struct clock_event_device dev;
+@@ -36,6 +40,8 @@ struct systick_device {
+       int freq_scale;
+ };
++static void (*systick_freq_scaling)(struct systick_device *sdev, int status);
++
+ static void systick_set_clock_mode(enum clock_event_mode mode,
+                               struct clock_event_device *evt);
+@@ -87,6 +93,21 @@ static struct irqaction systick_irqaction = {
+       .dev_id = &systick.dev,
+ };
++static inline void mt7620_freq_scaling(struct systick_device *sdev, int status)
++{
++      if (sdev->freq_scale == status)
++              return;
++
++      sdev->freq_scale = status;
++
++      pr_info("%s: %s autosleep mode\n", systick.dev.name,
++                      (status) ? ("enable") : ("disable"));
++      if (status)
++              rt_sysc_w32(rt_sysc_r32(CLK_LUT_CFG) | SLEEP_EN, CLK_LUT_CFG);
++      else
++              rt_sysc_w32(rt_sysc_r32(CLK_LUT_CFG) & ~SLEEP_EN, CLK_LUT_CFG);
++}
++
+ static void systick_set_clock_mode(enum clock_event_mode mode,
+                               struct clock_event_device *evt)
+ {
+@@ -101,9 +122,13 @@ static void systick_set_clock_mode(enum clock_event_mode mode,
+               sdev->irq_requested = 1;
+               iowrite32(CFG_EXT_STK_EN | CFG_CNT_EN,
+                               systick.membase + SYSTICK_CONFIG);
++              if (systick_freq_scaling)
++                      systick_freq_scaling(sdev, 1);
+               break;
+       case CLOCK_EVT_MODE_SHUTDOWN:
++              if (systick_freq_scaling)
++                      systick_freq_scaling(sdev, 0);
+               if (sdev->irq_requested)
+                       free_irq(systick.dev.irq, &systick_irqaction);
+               sdev->irq_requested = 0;
+@@ -116,12 +141,23 @@ static void systick_set_clock_mode(enum clock_event_mode mode,
+       }
+ }
++static const struct of_device_id systick_match[] = {
++      { .compatible = "ralink,mt7620-systick", .data = mt7620_freq_scaling},
++      {},
++};
++
+ static void __init ralink_systick_init(struct device_node *np)
+ {
++      const struct of_device_id *match;
++
+       systick.membase = of_iomap(np, 0);
+       if (!systick.membase)
+               return;
++      match = of_match_node(systick_match, np);
++      if (match)
++              systick_freq_scaling = match->data;
++
+       systick_irqaction.name = np->name;
+       systick.dev.name = np->name;
+       clockevents_calc_mult_shift(&systick.dev, SYSTICK_FREQ, 60);
+-- 
+1.7.10.4
+
diff --git a/target/linux/ramips/patches-3.14/0022-MIPS-ralink-copy-the-commandline-from-the-devicetree.patch b/target/linux/ramips/patches-3.14/0022-MIPS-ralink-copy-the-commandline-from-the-devicetree.patch
new file mode 100644 (file)
index 0000000..8ce47a9
--- /dev/null
@@ -0,0 +1,26 @@
+From ec26251ea980b1ee88733f178a4e86e3c70fd244 Mon Sep 17 00:00:00 2001
+From: John Crispin <blogic@openwrt.org>
+Date: Mon, 4 Aug 2014 18:46:02 +0200
+Subject: [PATCH 22/57] MIPS: ralink: copy the commandline from the devicetree
+
+Signed-off-by: John Crispin <blogic@openwrt.org>
+---
+ arch/mips/ralink/of.c |    2 ++
+ 1 file changed, 2 insertions(+)
+
+diff --git a/arch/mips/ralink/of.c b/arch/mips/ralink/of.c
+index 885cf50..405b79c 100644
+--- a/arch/mips/ralink/of.c
++++ b/arch/mips/ralink/of.c
+@@ -99,6 +99,8 @@ void __init plat_mem_setup(void)
+        */
+       __dt_setup_arch(&__dtb_start);
++      strlcpy(arcs_cmdline, boot_command_line, COMMAND_LINE_SIZE);
++
+       of_scan_flat_dt(early_init_dt_find_memory, NULL);
+       if (memory_dtb)
+               of_scan_flat_dt(early_init_dt_scan_memory, NULL);
+-- 
+1.7.10.4
+
diff --git a/target/linux/ramips/patches-3.14/0023-MIPS-ralink-mt7620-fix-usb-issue-during-frequency-sc.patch b/target/linux/ramips/patches-3.14/0023-MIPS-ralink-mt7620-fix-usb-issue-during-frequency-sc.patch
new file mode 100644 (file)
index 0000000..c6bf547
--- /dev/null
@@ -0,0 +1,57 @@
+From 1f1c12e85defba9459b41ec95b86f23b4791f1ab Mon Sep 17 00:00:00 2001
+From: John Crispin <blogic@openwrt.org>
+Date: Mon, 4 Aug 2014 20:43:25 +0200
+Subject: [PATCH 23/57] MIPS: ralink: mt7620: fix usb issue during frequency
+ scaling
+
+ If the USB HCD is running and the cpu is scaled too low, then the USB stops
+ working. Increase the idle speed of the core to fix this if the kernel is
+ built with USB support.
+
+ The values are taken from the Ralink SDK Kernel.
+
+ Signed-off-by: John Crispin <blogic@openwrt.org>
+---
+ arch/mips/ralink/mt7620.c |   19 +++++++++++++++++++
+ 1 file changed, 19 insertions(+)
+
+diff --git a/arch/mips/ralink/mt7620.c b/arch/mips/ralink/mt7620.c
+index c883973..d68b8ff 100644
+--- a/arch/mips/ralink/mt7620.c
++++ b/arch/mips/ralink/mt7620.c
+@@ -36,6 +36,12 @@
+ #define PMU1_CFG              0x8C
+ #define DIG_SW_SEL            BIT(25)
++/* clock scaling */
++#define CLKCFG_FDIV_MASK      0x1f00
++#define CLKCFG_FDIV_USB_VAL   0x0300
++#define CLKCFG_FFRAC_MASK     0x001f
++#define CLKCFG_FFRAC_USB_VAL  0x0003
++
+ /* does the board have sdram or ddram */
+ static int dram_type;
+@@ -337,6 +343,19 @@ void __init ralink_clk_init(void)
+       ralink_clk_add("10000b00.spi", sys_rate);
+       ralink_clk_add("10000c00.uartlite", periph_rate);
+       ralink_clk_add("10180000.wmac", xtal_rate);
++
++      if (IS_ENABLED(CONFIG_USB)) {
++              /*
++               * When the CPU goes into sleep mode, the BUS clock will be too low for
++               * USB to function properly
++               */
++              u32 val = rt_sysc_r32(SYSC_REG_CPU_SYS_CLKCFG);
++
++              val &= ~(CLKCFG_FDIV_MASK | CLKCFG_FFRAC_MASK);
++              val |= CLKCFG_FDIV_USB_VAL | CLKCFG_FFRAC_USB_VAL;
++
++              rt_sysc_w32(val, SYSC_REG_CPU_SYS_CLKCFG);
++      }
+ }
+ void __init ralink_of_remap(void)
+-- 
+1.7.10.4
+
diff --git a/target/linux/ramips/patches-3.14/0024-MIPS-ralink-add-mt7628an-devicetree-files.patch b/target/linux/ramips/patches-3.14/0024-MIPS-ralink-add-mt7628an-devicetree-files.patch
new file mode 100644 (file)
index 0000000..b1814f4
--- /dev/null
@@ -0,0 +1,292 @@
+From fbc9fb0c2d30f2141e1b0b824f473276c3aef528 Mon Sep 17 00:00:00 2001
+From: John Crispin <blogic@openwrt.org>
+Date: Wed, 6 Aug 2014 17:53:24 +0200
+Subject: [PATCH 24/57] MIPS: ralink: add mt7628an devicetree files
+
+Signed-off-by: John Crispin <blogic@openwrt.org>
+---
+ arch/mips/ralink/Kconfig               |    4 +
+ arch/mips/ralink/dts/Makefile          |    1 +
+ arch/mips/ralink/dts/mt7628an.dtsi     |  184 ++++++++++++++++++++++++++++++++
+ arch/mips/ralink/dts/mt7628an_eval.dts |   54 ++++++++++
+ 4 files changed, 243 insertions(+)
+ create mode 100644 arch/mips/ralink/dts/mt7628an.dtsi
+ create mode 100644 arch/mips/ralink/dts/mt7628an_eval.dts
+
+diff --git a/arch/mips/ralink/Kconfig b/arch/mips/ralink/Kconfig
+index 6a04360..9174dbc 100644
+--- a/arch/mips/ralink/Kconfig
++++ b/arch/mips/ralink/Kconfig
+@@ -75,6 +75,10 @@ choice
+               bool "MT7620A eval kit"
+               depends on SOC_MT7620
++      config DTB_MT7628AN_EVAL
++              bool "MT7620A eval kit"
++              depends on SOC_MT7620
++
+       config DTB_MT7621_EVAL
+               bool "MT7621 eval kit"
+               depends on SOC_MT7621
+diff --git a/arch/mips/ralink/dts/Makefile b/arch/mips/ralink/dts/Makefile
+index 9742c73..9f4e1c7 100644
+--- a/arch/mips/ralink/dts/Makefile
++++ b/arch/mips/ralink/dts/Makefile
+@@ -3,3 +3,4 @@ obj-$(CONFIG_DTB_RT305X_EVAL) := rt3052_eval.dtb.o
+ obj-$(CONFIG_DTB_RT3883_EVAL) := rt3883_eval.dtb.o
+ obj-$(CONFIG_DTB_MT7620A_EVAL) := mt7620a_eval.dtb.o
+ obj-$(CONFIG_DTB_MT7621_EVAL) := mt7621_eval.dtb.o
++obj-$(CONFIG_DTB_MT7628AN_EVAL) := mt7628an_eval.dtb.o
+diff --git a/arch/mips/ralink/dts/mt7628an.dtsi b/arch/mips/ralink/dts/mt7628an.dtsi
+new file mode 100644
+index 0000000..fd17d0a
+--- /dev/null
++++ b/arch/mips/ralink/dts/mt7628an.dtsi
+@@ -0,0 +1,184 @@
++/ {
++      #address-cells = <1>;
++      #size-cells = <1>;
++      compatible = "ralink,mtk7628an-soc";
++
++      cpus {
++              cpu@0 {
++                      compatible = "mips,mips24KEc";
++              };
++      };
++
++      cpuintc: cpuintc@0 {
++              #address-cells = <0>;
++              #interrupt-cells = <1>;
++              interrupt-controller;
++              compatible = "mti,cpu-interrupt-controller";
++      };
++
++      palmbus@10000000 {
++              compatible = "palmbus";
++              reg = <0x10000000 0x200000>;
++                ranges = <0x0 0x10000000 0x1FFFFF>;
++
++              #address-cells = <1>;
++              #size-cells = <1>;
++
++              sysc@0 {
++                      compatible = "ralink,mt7620a-sysc";
++                      reg = <0x0 0x100>;
++              };
++
++              watchdog@120 {
++                      compatible = "ralink,mt7628an-wdt", "mtk,mt7621-wdt";
++                      reg = <0x120 0x10>;
++
++                      resets = <&rstctrl 8>;
++                      reset-names = "wdt";
++
++                      interrupt-parent = <&intc>;
++                      interrupts = <24>;
++              };
++
++              intc: intc@200 {
++                      compatible = "ralink,mt7628an-intc", "ralink,rt2880-intc";
++                      reg = <0x200 0x100>;
++
++                      resets = <&rstctrl 9>;
++                      reset-names = "intc";
++
++                      interrupt-controller;
++                      #interrupt-cells = <1>;
++
++                      interrupt-parent = <&cpuintc>;
++                      interrupts = <2>;
++
++                      ralink,intc-registers = <0x9c 0xa0
++                                               0x6c 0xa4
++                                               0x80 0x78>;
++              };
++
++              memc@300 {
++                      compatible = "ralink,mt7620a-memc", "ralink,rt3050-memc";
++                      reg = <0x300 0x100>;
++
++                      resets = <&rstctrl 20>;
++                      reset-names = "mc";
++
++                      interrupt-parent = <&intc>;
++                      interrupts = <3>;
++              };
++
++              gpio@600 {
++                      #address-cells = <1>;
++                      #size-cells = <0>;
++
++                      compatible = "mtk,mt7628-gpio", "mtk,mt7621-gpio";
++                      reg = <0x600 0x100>;
++
++                      gpio0: bank@0 {
++                              reg = <0>;
++                              compatible = "mtk,mt7621-gpio-bank";
++                              gpio-controller;
++                              #gpio-cells = <2>;
++                      };
++
++                      gpio1: bank@1 {
++                              reg = <1>;
++                              compatible = "mtk,mt7621-gpio-bank";
++                              gpio-controller;
++                              #gpio-cells = <2>;
++                      };
++
++                      gpio2: bank@2 {
++                              reg = <2>;
++                              compatible = "mtk,mt7621-gpio-bank";
++                              gpio-controller;
++                              #gpio-cells = <2>;
++                      };
++              };
++
++              spi@b00 {
++                      compatible = "ralink,mt7621-spi";
++                      reg = <0xb00 0x100>;
++
++                      resets = <&rstctrl 18>;
++                      reset-names = "spi";
++
++                      #address-cells = <1>;
++                      #size-cells = <1>;
++
++                      pinctrl-names = "default";
++                      pinctrl-0 = <&spi_pins>;
++
++                      status = "disabled";
++              };
++
++              uartlite@c00 {
++                      compatible = "ns16550a";
++                      reg = <0xc00 0x100>;
++
++                      reg-shift = <2>;
++                      reg-io-width = <4>;
++                      no-loopback-test;
++
++                      resets = <&rstctrl 12>;
++                      reset-names = "uartl";
++
++                      interrupt-parent = <&intc>;
++                      interrupts = <20>;
++
++                      pinctrl-names = "default";
++                      pinctrl-0 = <&uart0_pins>;
++              };
++      };
++
++      pinctrl {
++              compatible = "ralink,rt2880-pinmux";
++              pinctrl-names = "default";
++              pinctrl-0 = <&state_default>;
++              state_default: pinctrl0 {
++              };
++              spi_pins: spi {
++                      spi {
++                              ralink,group = "spi";
++                              ralink,function = "spi";
++                      };
++              };
++              uart0_pins: uartlite {
++                      uart {
++                              ralink,group = "uart0";
++                              ralink,function = "uart";
++                      };
++              };
++      };
++
++      rstctrl: rstctrl {
++              compatible = "ralink,mt7620a-reset", "ralink,rt2880-reset";
++              #reset-cells = <1>;
++      };
++
++      usbphy {
++              compatible = "ralink,mt7628an-usbphy", "ralink,mt7620a-usbphy";
++
++              resets = <&rstctrl 22>;
++              reset-names = "host";
++      };
++
++      ehci@101c0000 {
++              compatible = "ralink,rt3xxx-ehci";
++              reg = <0x101c0000 0x1000>;
++
++              interrupt-parent = <&intc>;
++              interrupts = <18>;
++      };
++
++      ohci@101c1000 {
++              compatible = "ralink,rt3xxx-ohci";
++              reg = <0x101c1000 0x1000>;
++
++              interrupt-parent = <&intc>;
++              interrupts = <18>;
++      };
++
++};
+diff --git a/arch/mips/ralink/dts/mt7628an_eval.dts b/arch/mips/ralink/dts/mt7628an_eval.dts
+new file mode 100644
+index 0000000..132c29e
+--- /dev/null
++++ b/arch/mips/ralink/dts/mt7628an_eval.dts
+@@ -0,0 +1,54 @@
++/dts-v1/;
++
++/include/ "mt7628an.dtsi"
++
++/ {
++      compatible = "ralink,mt7628an-eval-board", "ralink,mt7628an-soc";
++      model = "Ralink MT7628AN evaluation board";
++
++      memory@0 {
++              reg = <0x0 0x2000000>;
++      };
++
++      chosen {
++              bootargs = "console=ttyS0,57600 init=/init";
++      };
++
++      palmbus@10000000 {
++              spi@b00 {
++                      status = "okay";
++
++                      m25p80@0 {
++                              #address-cells = <1>;
++                              #size-cells = <1>;
++                              compatible = "en25q64";
++                              reg = <0 0>;
++                              linux,modalias = "m25p80", "en25q64";
++                              spi-max-frequency = <10000000>;
++
++                              partition@0 {
++                                      label = "u-boot";
++                                      reg = <0x0 0x30000>;
++                                      read-only;
++                              };
++
++                              partition@30000 {
++                                      label = "u-boot-env";
++                                      reg = <0x30000 0x10000>;
++                                      read-only;
++                              };
++
++                              factory: partition@40000 {
++                                      label = "factory";
++                                      reg = <0x40000 0x10000>;
++                                      read-only;
++                              };
++
++                              partition@50000 {
++                                      label = "firmware";
++                                      reg = <0x50000 0x7b0000>;
++                              };
++                      };
++              };
++      };
++};
+-- 
+1.7.10.4
+
diff --git a/target/linux/ramips/patches-3.14/0025-MIPS-ralink-allow-loading-irq-registers-from-the-dev.patch b/target/linux/ramips/patches-3.14/0025-MIPS-ralink-allow-loading-irq-registers-from-the-dev.patch
new file mode 100644 (file)
index 0000000..3a114d0
--- /dev/null
@@ -0,0 +1,80 @@
+From b1cc9a15f6ead8dbd849257e42d69a5799fb7597 Mon Sep 17 00:00:00 2001
+From: John Crispin <blogic@openwrt.org>
+Date: Wed, 6 Aug 2014 18:24:36 +0200
+Subject: [PATCH 25/57] MIPS: ralink: allow loading irq registers from the
+ devicetree
+
+Signed-off-by: John Crispin <blogic@openwrt.org>
+---
+ arch/mips/ralink/irq.c |   33 +++++++++++++++++++++++----------
+ 1 file changed, 23 insertions(+), 10 deletions(-)
+
+diff --git a/arch/mips/ralink/irq.c b/arch/mips/ralink/irq.c
+index 781b3d1..82c3146 100644
+--- a/arch/mips/ralink/irq.c
++++ b/arch/mips/ralink/irq.c
+@@ -20,14 +20,6 @@
+ #include "common.h"
+-/* INTC register offsets */
+-#define INTC_REG_STATUS0      0x00
+-#define INTC_REG_STATUS1      0x04
+-#define INTC_REG_TYPE         0x20
+-#define INTC_REG_RAW_STATUS   0x30
+-#define INTC_REG_ENABLE               0x34
+-#define INTC_REG_DISABLE      0x38
+-
+ #define INTC_INT_GLOBAL               BIT(31)
+ #define RALINK_CPU_IRQ_INTC   (MIPS_CPU_IRQ_BASE + 2)
+@@ -44,16 +36,34 @@
+ #define RALINK_INTC_IRQ_PERFC   (RALINK_INTC_IRQ_BASE + 9)
++enum rt_intc_regs_enum {
++      INTC_REG_STATUS0 = 0,
++      INTC_REG_STATUS1,
++      INTC_REG_TYPE,
++      INTC_REG_RAW_STATUS,
++      INTC_REG_ENABLE,
++      INTC_REG_DISABLE,
++};
++
++static u32 rt_intc_regs[] = {
++      [INTC_REG_STATUS0] = 0x00,
++      [INTC_REG_STATUS1] = 0x04,
++      [INTC_REG_TYPE] = 0x20,
++      [INTC_REG_RAW_STATUS] = 0x30,
++      [INTC_REG_ENABLE] = 0x34,
++      [INTC_REG_DISABLE] = 0x38,
++};
++
+ static void __iomem *rt_intc_membase;
+ static inline void rt_intc_w32(u32 val, unsigned reg)
+ {
+-      __raw_writel(val, rt_intc_membase + reg);
++      __raw_writel(val, rt_intc_membase + rt_intc_regs[reg]);
+ }
+ static inline u32 rt_intc_r32(unsigned reg)
+ {
+-      return __raw_readl(rt_intc_membase + reg);
++      return __raw_readl(rt_intc_membase + rt_intc_regs[reg]);
+ }
+ static void ralink_intc_irq_unmask(struct irq_data *d)
+@@ -134,6 +144,9 @@ static int __init intc_of_init(struct device_node *node,
+       struct irq_domain *domain;
+       int irq;
++      if (!of_property_read_u32_array(node, "ralink,intc-registers", rt_intc_regs, 6))
++              pr_info("intc: using register map from devicetree\n");
++
+       irq = irq_of_parse_and_map(node, 0);
+       if (!irq)
+               panic("Failed to get INTC IRQ");
+-- 
+1.7.10.4
+
diff --git a/target/linux/ramips/patches-3.14/0026-MIPS-ralink-add-mt7628an-support.patch b/target/linux/ramips/patches-3.14/0026-MIPS-ralink-add-mt7628an-support.patch
new file mode 100644 (file)
index 0000000..f5b2610
--- /dev/null
@@ -0,0 +1,405 @@
+From a375beba066516ecafddebc765454ac6ec599f3d Mon Sep 17 00:00:00 2001
+From: John Crispin <blogic@openwrt.org>
+Date: Wed, 6 Aug 2014 18:26:08 +0200
+Subject: [PATCH 26/57] MIPS: ralink: add mt7628an support
+
+Signed-off-by: John Crispin <blogic@openwrt.org>
+---
+ arch/mips/include/asm/mach-ralink/mt7620.h |   11 ++
+ arch/mips/ralink/Kconfig                   |    2 +-
+ arch/mips/ralink/mt7620.c                  |  266 +++++++++++++++++++++++-----
+ 3 files changed, 232 insertions(+), 47 deletions(-)
+
+diff --git a/arch/mips/include/asm/mach-ralink/mt7620.h b/arch/mips/include/asm/mach-ralink/mt7620.h
+index 27b2fa9..c8590df 100644
+--- a/arch/mips/include/asm/mach-ralink/mt7620.h
++++ b/arch/mips/include/asm/mach-ralink/mt7620.h
+@@ -13,6 +13,13 @@
+ #ifndef _MT7620_REGS_H_
+ #define _MT7620_REGS_H_
++enum mt762x_soc_type {
++      MT762X_SOC_UNKNOWN = 0,
++      MT762X_SOC_MT7620A,
++      MT762X_SOC_MT7620N,
++      MT762X_SOC_MT7628AN,
++};
++
+ #define MT7620_SYSC_BASE              0x10000000
+ #define SYSC_REG_CHIP_NAME0           0x00
+@@ -27,6 +34,7 @@
+ #define MT7620_CHIP_NAME0             0x3637544d
+ #define MT7620_CHIP_NAME1             0x20203032
++#define MT7628_CHIP_NAME1             0x20203832
+ #define SYSCFG0_XTAL_FREQ_SEL         BIT(6)
+@@ -71,6 +79,9 @@
+ #define SYSCFG0_DRAM_TYPE_DDR1                1
+ #define SYSCFG0_DRAM_TYPE_DDR2                2
++#define SYSCFG0_DRAM_TYPE_DDR2_MT7628 0
++#define SYSCFG0_DRAM_TYPE_DDR1_MT7628 1
++
+ #define MT7620_DRAM_BASE              0x0
+ #define MT7620_SDRAM_SIZE_MIN         2
+ #define MT7620_SDRAM_SIZE_MAX         64
+diff --git a/arch/mips/ralink/Kconfig b/arch/mips/ralink/Kconfig
+index 9174dbc..f93835f 100644
+--- a/arch/mips/ralink/Kconfig
++++ b/arch/mips/ralink/Kconfig
+@@ -35,7 +35,7 @@ choice
+               select HW_HAS_PCI
+       config SOC_MT7620
+-              bool "MT7620"
++              bool "MT7620/8"
+               select USB_ARCH_HAS_OHCI
+               select USB_ARCH_HAS_EHCI
+diff --git a/arch/mips/ralink/mt7620.c b/arch/mips/ralink/mt7620.c
+index d68b8ff..e590ccf 100644
+--- a/arch/mips/ralink/mt7620.c
++++ b/arch/mips/ralink/mt7620.c
+@@ -42,6 +42,8 @@
+ #define CLKCFG_FFRAC_MASK     0x001f
+ #define CLKCFG_FFRAC_USB_VAL  0x0003
++enum mt762x_soc_type mt762x_soc;
++
+ /* does the board have sdram or ddram */
+ static int dram_type;
+@@ -159,6 +161,125 @@ struct ralink_pinmux rt_gpio_pinmux = {
+       .uart_mask = MT7620_GPIO_MODE_UART0_MASK,
+ };
++static struct rt2880_pmx_func pwm1_grp_mt7628[] = {
++      FUNC("sdcx", 3, 19, 1),
++      FUNC("utif", 2, 19, 1),
++      FUNC("gpio", 1, 19, 1),
++      FUNC("pwm", 0, 19, 1),
++};
++
++static struct rt2880_pmx_func pwm0_grp_mt7628[] = {
++      FUNC("sdcx", 3, 18, 1),
++      FUNC("utif", 2, 18, 1),
++      FUNC("gpio", 1, 18, 1),
++      FUNC("pwm", 0, 18, 1),
++};
++
++static struct rt2880_pmx_func uart2_grp_mt7628[] = {
++      FUNC("sdcx", 3, 20, 2),
++      FUNC("pwm", 2, 20, 2),
++      FUNC("gpio", 1, 20, 2),
++      FUNC("uart", 0, 20, 2),
++};
++
++static struct rt2880_pmx_func uart1_grp_mt7628[] = {
++      FUNC("sdcx", 3, 45, 2),
++      FUNC("pwm", 2, 45, 2),
++      FUNC("gpio", 1, 45, 2),
++      FUNC("uart", 0, 45, 2),
++};
++
++static struct rt2880_pmx_func i2c_grp_mt7628[] = {
++      FUNC("-", 3, 4, 2),
++      FUNC("debug", 2, 4, 2),
++      FUNC("gpio", 1, 4, 2),
++      FUNC("i2c", 0, 4, 2),
++};
++
++static struct rt2880_pmx_func refclk_grp_mt7628[] = { FUNC("reclk", 0, 36, 1) };
++static struct rt2880_pmx_func perst_grp_mt7628[] = { FUNC("perst", 0, 37, 1) };
++static struct rt2880_pmx_func wdt_grp_mt7628[] = { FUNC("wdt", 0, 15, 38) };
++static struct rt2880_pmx_func spi_grp_mt7628[] = { FUNC("spi", 0, 7, 4) };
++
++static struct rt2880_pmx_func sd_mode_grp_mt7628[] = {
++      FUNC("jtag", 3, 22, 8),
++      FUNC("utif", 2, 22, 8),
++      FUNC("gpio", 1, 22, 8),
++      FUNC("sdcx", 0, 22, 8),
++};
++
++static struct rt2880_pmx_func uart0_grp_mt7628[] = {
++      FUNC("-", 3, 12, 2),
++      FUNC("-", 2, 12, 2),
++      FUNC("gpio", 1, 12, 2),
++      FUNC("uart", 0, 12, 2),
++};
++
++static struct rt2880_pmx_func i2s_grp_mt7628[] = {
++      FUNC("antenna", 3, 0, 4),
++      FUNC("pcm", 2, 0, 4),
++      FUNC("gpio", 1, 0, 4),
++      FUNC("i2s", 0, 0, 4),
++};
++
++static struct rt2880_pmx_func spi_cs1_grp_mt7628[] = {
++      FUNC("-", 3, 6, 1),
++      FUNC("refclk", 2, 6, 1),
++      FUNC("gpio", 1, 6, 1),
++      FUNC("spi", 0, 6, 1),
++};
++
++static struct rt2880_pmx_func spis_grp_mt7628[] = {
++      FUNC("pwm", 3, 14, 4),
++      FUNC("util", 2, 14, 4),
++      FUNC("gpio", 1, 14, 4),
++      FUNC("spis", 0, 14, 4),
++};
++
++static struct rt2880_pmx_func gpio_grp_mt7628[] = {
++      FUNC("pcie", 3, 11, 1),
++      FUNC("refclk", 2, 11, 1),
++      FUNC("gpio", 1, 11, 1),
++      FUNC("gpio", 0, 11, 1),
++};
++
++#define MT7628_GPIO_MODE_MASK 0x3
++
++#define MT7628_GPIO_MODE_PWM1 30
++#define MT7628_GPIO_MODE_PWM0 28
++#define MT7628_GPIO_MODE_UART2        26
++#define MT7628_GPIO_MODE_UART1        24
++#define MT7628_GPIO_MODE_I2C  20
++#define MT7628_GPIO_MODE_REFCLK       18
++#define MT7628_GPIO_MODE_PERST        16
++#define MT7628_GPIO_MODE_WDT  14
++#define MT7628_GPIO_MODE_SPI  12
++#define MT7628_GPIO_MODE_SDMODE       10
++#define MT7628_GPIO_MODE_UART0        8
++#define MT7628_GPIO_MODE_I2S  6
++#define MT7628_GPIO_MODE_CS1  4
++#define MT7628_GPIO_MODE_SPIS 2
++#define MT7628_GPIO_MODE_GPIO 0
++
++static struct rt2880_pmx_group mt7628an_pinmux_data[] = {
++      GRP_G("pmw1", pwm1_grp_mt7628, MT7628_GPIO_MODE_MASK, 1, MT7628_GPIO_MODE_PWM1),
++      GRP_G("pmw1", pwm0_grp_mt7628, MT7628_GPIO_MODE_MASK, 1, MT7628_GPIO_MODE_PWM0),
++      GRP_G("uart2", uart2_grp_mt7628, MT7628_GPIO_MODE_MASK, 1, MT7628_GPIO_MODE_UART2),
++      GRP_G("uart1", uart1_grp_mt7628, MT7628_GPIO_MODE_MASK, 1, MT7628_GPIO_MODE_UART1),
++      GRP_G("i2c", i2c_grp_mt7628, MT7628_GPIO_MODE_MASK, 1, MT7628_GPIO_MODE_I2C),
++      GRP("refclk", refclk_grp_mt7628, 1, MT7628_GPIO_MODE_REFCLK),
++      GRP("perst", perst_grp_mt7628, 1, MT7628_GPIO_MODE_PERST),
++      GRP("wdt", wdt_grp_mt7628, 1, MT7628_GPIO_MODE_WDT),
++      GRP("spi", spi_grp_mt7628, 1, MT7628_GPIO_MODE_SPI),
++      GRP_G("sdmode", sd_mode_grp_mt7628, MT7628_GPIO_MODE_MASK, 1, MT7628_GPIO_MODE_SDMODE),
++      GRP_G("uart0", uart0_grp_mt7628, MT7628_GPIO_MODE_MASK, 1, MT7628_GPIO_MODE_UART0),
++      GRP_G("i2s", i2s_grp_mt7628, MT7628_GPIO_MODE_MASK, 1, MT7628_GPIO_MODE_I2S),
++      GRP_G("spi cs1", spi_cs1_grp_mt7628, MT7628_GPIO_MODE_MASK, 1, MT7628_GPIO_MODE_CS1),
++      GRP_G("spis", spis_grp_mt7628, MT7628_GPIO_MODE_MASK, 1, MT7628_GPIO_MODE_SPIS),
++      GRP_G("gpio", gpio_grp_mt7628, MT7628_GPIO_MODE_MASK, 1, MT7628_GPIO_MODE_GPIO),
++      { 0 }
++};
++
+ static __init u32
+ mt7620_calc_rate(u32 ref_rate, u32 mul, u32 div)
+ {
+@@ -309,29 +430,42 @@ void __init ralink_clk_init(void)
+       xtal_rate = mt7620_get_xtal_rate();
+-      cpu_pll_rate = mt7620_get_cpu_pll_rate(xtal_rate);
+-      pll_rate = mt7620_get_pll_rate(xtal_rate, cpu_pll_rate);
+-
+-      cpu_rate = mt7620_get_cpu_rate(pll_rate);
+-      dram_rate = mt7620_get_dram_rate(pll_rate);
+-      sys_rate = mt7620_get_sys_rate(cpu_rate);
+-      periph_rate = mt7620_get_periph_rate(xtal_rate);
+-
+ #define RFMT(label)   label ":%lu.%03luMHz "
+ #define RINT(x)               ((x) / 1000000)
+ #define RFRAC(x)      (((x) / 1000) % 1000)
+-      pr_debug(RFMT("XTAL") RFMT("CPU_PLL") RFMT("PLL"),
+-               RINT(xtal_rate), RFRAC(xtal_rate),
+-               RINT(cpu_pll_rate), RFRAC(cpu_pll_rate),
+-               RINT(pll_rate), RFRAC(pll_rate));
++      if (mt762x_soc == MT762X_SOC_MT7628AN) {
++              if (xtal_rate == MHZ(40))
++                      cpu_rate = MHZ(580);
++              else
++                      cpu_rate = MHZ(575);
++              dram_rate = sys_rate = cpu_rate / 3;
++              periph_rate = MHZ(40);
++
++              ralink_clk_add("10000d00.uartlite", periph_rate);
++              ralink_clk_add("10000e00.uartlite", periph_rate);
++      } else {
++              cpu_pll_rate = mt7620_get_cpu_pll_rate(xtal_rate);
++              pll_rate = mt7620_get_pll_rate(xtal_rate, cpu_pll_rate);
++
++              cpu_rate = mt7620_get_cpu_rate(pll_rate);
++              dram_rate = mt7620_get_dram_rate(pll_rate);
++              sys_rate = mt7620_get_sys_rate(cpu_rate);
++              periph_rate = mt7620_get_periph_rate(xtal_rate);
++
++              pr_debug(RFMT("XTAL") RFMT("CPU_PLL") RFMT("PLL"),
++                       RINT(xtal_rate), RFRAC(xtal_rate),
++                       RINT(cpu_pll_rate), RFRAC(cpu_pll_rate),
++                       RINT(pll_rate), RFRAC(pll_rate));
++
++              ralink_clk_add("10000500.uart", periph_rate);
++      }
+       pr_debug(RFMT("CPU") RFMT("DRAM") RFMT("SYS") RFMT("PERIPH"),
+                RINT(cpu_rate), RFRAC(cpu_rate),
+                RINT(dram_rate), RFRAC(dram_rate),
+                RINT(sys_rate), RFRAC(sys_rate),
+                RINT(periph_rate), RFRAC(periph_rate));
+-
+ #undef RFRAC
+ #undef RINT
+ #undef RFMT
+@@ -339,12 +473,11 @@ void __init ralink_clk_init(void)
+       ralink_clk_add("cpu", cpu_rate);
+       ralink_clk_add("10000100.timer", periph_rate);
+       ralink_clk_add("10000120.watchdog", periph_rate);
+-      ralink_clk_add("10000500.uart", periph_rate);
+       ralink_clk_add("10000b00.spi", sys_rate);
+       ralink_clk_add("10000c00.uartlite", periph_rate);
+       ralink_clk_add("10180000.wmac", xtal_rate);
+-      if (IS_ENABLED(CONFIG_USB)) {
++      if (IS_ENABLED(CONFIG_USB) && mt762x_soc != MT762X_SOC_MT7628AN) {
+               /*
+                * When the CPU goes into sleep mode, the BUS clock will be too low for
+                * USB to function properly
+@@ -367,6 +500,52 @@ void __init ralink_of_remap(void)
+               panic("Failed to remap core resources");
+ }
++static __init void
++mt7620_dram_init(struct ralink_soc_info *soc_info)
++{
++      switch (dram_type) {
++      case SYSCFG0_DRAM_TYPE_SDRAM:
++              pr_info("Board has SDRAM\n");
++              soc_info->mem_size_min = MT7620_SDRAM_SIZE_MIN;
++              soc_info->mem_size_max = MT7620_SDRAM_SIZE_MAX;
++              break;
++
++      case SYSCFG0_DRAM_TYPE_DDR1:
++              pr_info("Board has DDR1\n");
++              soc_info->mem_size_min = MT7620_DDR1_SIZE_MIN;
++              soc_info->mem_size_max = MT7620_DDR1_SIZE_MAX;
++              break;
++
++      case SYSCFG0_DRAM_TYPE_DDR2:
++              pr_info("Board has DDR2\n");
++              soc_info->mem_size_min = MT7620_DDR2_SIZE_MIN;
++              soc_info->mem_size_max = MT7620_DDR2_SIZE_MAX;
++              break;
++      default:
++              BUG();
++      }
++}
++
++static __init void
++mt7628_dram_init(struct ralink_soc_info *soc_info)
++{
++      switch (dram_type) {
++      case SYSCFG0_DRAM_TYPE_DDR1_MT7628:
++              pr_info("Board has DDR1\n");
++              soc_info->mem_size_min = MT7620_DDR1_SIZE_MIN;
++              soc_info->mem_size_max = MT7620_DDR1_SIZE_MAX;
++              break;
++
++      case SYSCFG0_DRAM_TYPE_DDR2_MT7628:
++              pr_info("Board has DDR2\n");
++              soc_info->mem_size_min = MT7620_DDR2_SIZE_MIN;
++              soc_info->mem_size_max = MT7620_DDR2_SIZE_MAX;
++              break;
++      default:
++              BUG();
++      }
++}
++
+ void prom_soc_init(struct ralink_soc_info *soc_info)
+ {
+       void __iomem *sysc = (void __iomem *) KSEG1ADDR(MT7620_SYSC_BASE);
+@@ -384,18 +563,25 @@ void prom_soc_init(struct ralink_soc_info *soc_info)
+       rev = __raw_readl(sysc + SYSC_REG_CHIP_REV);
+       bga = (rev >> CHIP_REV_PKG_SHIFT) & CHIP_REV_PKG_MASK;
+-      if (n0 != MT7620_CHIP_NAME0 || n1 != MT7620_CHIP_NAME1)
+-              panic("mt7620: unknown SoC, n0:%08x n1:%08x\n", n0, n1);
+-
+-      if (bga) {
+-              name = "MT7620A";
+-              soc_info->compatible = "ralink,mt7620a-soc";
+-      } else {
+-              name = "MT7620N";
+-              soc_info->compatible = "ralink,mt7620n-soc";
++      if (n0 == MT7620_CHIP_NAME0 && n1 == MT7620_CHIP_NAME1) {
++              if (bga) {
++                      mt762x_soc = MT762X_SOC_MT7620A;
++                      name = "MT7620A";
++                      soc_info->compatible = "ralink,mt7620a-soc";
++              } else {
++                      mt762x_soc = MT762X_SOC_MT7620N;
++                      name = "MT7620N";
++                      soc_info->compatible = "ralink,mt7620n-soc";
+ #ifdef CONFIG_PCI
+-              panic("mt7620n is only supported for non pci kernels");
++                      panic("mt7620n is only supported for non pci kernels");
+ #endif
++              }
++      } else if (n0 == MT7620_CHIP_NAME0 && n1 == MT7628_CHIP_NAME1) {
++              mt762x_soc = MT762X_SOC_MT7628AN;
++              name = "MT7628AN";
++              soc_info->compatible = "ralink,mt7628an-soc";
++      } else {
++              panic("mt762x: unknown SoC, n0:%08x n1:%08x\n", n0, n1);
+       }
+       snprintf(soc_info->sys_type, RAMIPS_SYS_TYPE_LEN,
+@@ -407,28 +593,11 @@ void prom_soc_init(struct ralink_soc_info *soc_info)
+       cfg0 = __raw_readl(sysc + SYSC_REG_SYSTEM_CONFIG0);
+       dram_type = (cfg0 >> SYSCFG0_DRAM_TYPE_SHIFT) & SYSCFG0_DRAM_TYPE_MASK;
+-      switch (dram_type) {
+-      case SYSCFG0_DRAM_TYPE_SDRAM:
+-              pr_info("Board has SDRAM\n");
+-              soc_info->mem_size_min = MT7620_SDRAM_SIZE_MIN;
+-              soc_info->mem_size_max = MT7620_SDRAM_SIZE_MAX;
+-              break;
+-
+-      case SYSCFG0_DRAM_TYPE_DDR1:
+-              pr_info("Board has DDR1\n");
+-              soc_info->mem_size_min = MT7620_DDR1_SIZE_MIN;
+-              soc_info->mem_size_max = MT7620_DDR1_SIZE_MAX;
+-              break;
+-
+-      case SYSCFG0_DRAM_TYPE_DDR2:
+-              pr_info("Board has DDR2\n");
+-              soc_info->mem_size_min = MT7620_DDR2_SIZE_MIN;
+-              soc_info->mem_size_max = MT7620_DDR2_SIZE_MAX;
+-              break;
+-      default:
+-              BUG();
+-      }
+       soc_info->mem_base = MT7620_DRAM_BASE;
++      if (mt762x_soc == MT762X_SOC_MT7628AN)
++              mt7628_dram_init(soc_info);
++      else
++              mt7620_dram_init(soc_info);
+       pmu0 = __raw_readl(sysc + PMU0_CFG);
+       pmu1 = __raw_readl(sysc + PMU1_CFG);
+@@ -437,4 +606,9 @@ void prom_soc_init(struct ralink_soc_info *soc_info)
+               (pmu0 & PMU_SW_SET) ? ("sw") : ("hw"));
+       pr_info("Digital PMU set to %s control\n",
+               (pmu1 & DIG_SW_SEL) ? ("sw") : ("hw"));
++
++      if (mt762x_soc == MT762X_SOC_MT7628AN)
++              rt2880_pinmux_data = mt7628an_pinmux_data;
++      else
++              rt2880_pinmux_data = mt7620a_pinmux_data;
+ }
+-- 
+1.7.10.4
+
diff --git a/target/linux/ramips/patches-3.14/0027-serial-ralink-adds-mt7620-serial.patch b/target/linux/ramips/patches-3.14/0027-serial-ralink-adds-mt7620-serial.patch
new file mode 100644 (file)
index 0000000..1d95f9c
--- /dev/null
@@ -0,0 +1,28 @@
+From 0b24e0e6bf2d9a1ca5f95446bc025dafc226998c Mon Sep 17 00:00:00 2001
+From: John Crispin <blogic@openwrt.org>
+Date: Fri, 15 Mar 2013 18:16:01 +0100
+Subject: [PATCH 27/57] serial: ralink: adds mt7620 serial
+
+Add the config symbol for Mediatek7620 SoC to SERIAL_8250_RT288X
+
+Signed-off-by: John Crispin <blogic@openwrt.org>
+---
+ drivers/tty/serial/8250/Kconfig |    2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/tty/serial/8250/Kconfig b/drivers/tty/serial/8250/Kconfig
+index 2332991..7fb6873 100644
+--- a/drivers/tty/serial/8250/Kconfig
++++ b/drivers/tty/serial/8250/Kconfig
+@@ -297,7 +297,7 @@ config SERIAL_8250_EM
+ config SERIAL_8250_RT288X
+       bool "Ralink RT288x/RT305x/RT3662/RT3883 serial port support"
+-      depends on SERIAL_8250 && (SOC_RT288X || SOC_RT305X || SOC_RT3883)
++      depends on SERIAL_8250 && (SOC_RT288X || SOC_RT305X || SOC_RT3883 || SOC_MT7620)
+       help
+         If you have a Ralink RT288x/RT305x SoC based board and want to use the
+         serial port, say Y to this option. The driver can handle up to 2 serial
+-- 
+1.7.10.4
+
diff --git a/target/linux/ramips/patches-3.14/0028-serial-ralink-the-core-has-a-size-of-0x100-and-not-0.patch b/target/linux/ramips/patches-3.14/0028-serial-ralink-the-core-has-a-size-of-0x100-and-not-0.patch
new file mode 100644 (file)
index 0000000..072380c
--- /dev/null
@@ -0,0 +1,27 @@
+From b9ba09038dab4d824176ea2c2f2b73f49b567217 Mon Sep 17 00:00:00 2001
+From: John Crispin <blogic@openwrt.org>
+Date: Sun, 16 Mar 2014 04:52:01 +0000
+Subject: [PATCH 28/57] serial: ralink: the core has a size of 0x100 and not
+ 0x1000
+
+Signed-off-by: John Crispin <blogic@openwrt.org>
+---
+ drivers/tty/serial/8250/8250_core.c |    2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/tty/serial/8250/8250_core.c b/drivers/tty/serial/8250/8250_core.c
+index 69932b7..606cbc6 100644
+--- a/drivers/tty/serial/8250/8250_core.c
++++ b/drivers/tty/serial/8250/8250_core.c
+@@ -2517,7 +2517,7 @@ serial8250_pm(struct uart_port *port, unsigned int state,
+ static unsigned int serial8250_port_size(struct uart_8250_port *pt)
+ {
+       if (pt->port.iotype == UPIO_AU)
+-              return 0x1000;
++              return 0x100;
+       if (is_omap1_8250(pt))
+               return 0x16 << pt->port.regshift;
+-- 
+1.7.10.4
+
diff --git a/target/linux/ramips/patches-3.14/0029-serial-of-allow-au1x00-and-rt288x-to-load-from-OF.patch b/target/linux/ramips/patches-3.14/0029-serial-of-allow-au1x00-and-rt288x-to-load-from-OF.patch
new file mode 100644 (file)
index 0000000..baae397
--- /dev/null
@@ -0,0 +1,32 @@
+From 49b47dfcef1353cd28eac8f64170e75d28ce4311 Mon Sep 17 00:00:00 2001
+From: John Crispin <blogic@openwrt.org>
+Date: Sun, 14 Jul 2013 23:18:57 +0200
+Subject: [PATCH 29/57] serial: of: allow au1x00 and rt288x to load from OF
+
+In order to make serial_8250 loadable via OF on Au1x00 and Ralink WiSoC we need
+to default the iotype to UPIO_AU.
+
+Signed-off-by: John Crispin <blogic@openwrt.org>
+---
+ drivers/tty/serial/of_serial.c |    5 ++++-
+ 1 file changed, 4 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/tty/serial/of_serial.c b/drivers/tty/serial/of_serial.c
+index 9924660..42853b4 100644
+--- a/drivers/tty/serial/of_serial.c
++++ b/drivers/tty/serial/of_serial.c
+@@ -102,7 +102,10 @@ static int of_platform_serial_setup(struct platform_device *ofdev,
+               port->fifosize = prop;
+       port->irq = irq_of_parse_and_map(np, 0);
+-      port->iotype = UPIO_MEM;
++      if (of_device_is_compatible(np, "ralink,rt2880-uart"))
++              port->iotype = UPIO_AU;
++      else
++              port->iotype = UPIO_MEM;
+       if (of_property_read_u32(np, "reg-io-width", &prop) == 0) {
+               switch (prop) {
+               case 1:
+-- 
+1.7.10.4
+
diff --git a/target/linux/ramips/patches-3.14/0030-pinctrl-ralink-add-pinctrl-driver.patch b/target/linux/ramips/patches-3.14/0030-pinctrl-ralink-add-pinctrl-driver.patch
new file mode 100644 (file)
index 0000000..9e006b5
--- /dev/null
@@ -0,0 +1,1429 @@
+From 675c6ddd9432c39f508f9d6bdda17d9c675788cf Mon Sep 17 00:00:00 2001
+From: John Crispin <blogic@openwrt.org>
+Date: Sun, 27 Jul 2014 09:34:05 +0100
+Subject: [PATCH 30/57] pinctrl: ralink: add pinctrl driver
+
+Signed-off-by: John Crispin <blogic@openwrt.org>
+---
+ arch/mips/Kconfig                          |    2 +
+ arch/mips/include/asm/mach-ralink/mt7620.h |   41 ++-
+ arch/mips/include/asm/mach-ralink/pinmux.h |   53 ++++
+ arch/mips/include/asm/mach-ralink/rt305x.h |   35 ++-
+ arch/mips/include/asm/mach-ralink/rt3883.h |   16 +-
+ arch/mips/ralink/common.h                  |   19 --
+ arch/mips/ralink/mt7620.c                  |  159 +++-------
+ arch/mips/ralink/rt288x.c                  |   62 ++--
+ arch/mips/ralink/rt305x.c                  |  151 ++++-----
+ arch/mips/ralink/rt3883.c                  |  173 +++--------
+ drivers/pinctrl/Kconfig                    |    5 +
+ drivers/pinctrl/Makefile                   |    1 +
+ drivers/pinctrl/pinctrl-rt2880.c           |  467 ++++++++++++++++++++++++++++
+ 13 files changed, 764 insertions(+), 420 deletions(-)
+ create mode 100644 arch/mips/include/asm/mach-ralink/pinmux.h
+ create mode 100644 drivers/pinctrl/pinctrl-rt2880.c
+
+diff --git a/arch/mips/Kconfig b/arch/mips/Kconfig
+index 95fa1f1..4ac98ca 100644
+--- a/arch/mips/Kconfig
++++ b/arch/mips/Kconfig
+@@ -435,6 +435,8 @@ config RALINK
+       select CLKDEV_LOOKUP
+       select ARCH_HAS_RESET_CONTROLLER
+       select RESET_CONTROLLER
++      select PINCTRL
++      select PINCTRL_RT2880
+ config SGI_IP22
+       bool "SGI IP22 (Indy/Indigo2)"
+diff --git a/arch/mips/include/asm/mach-ralink/mt7620.h b/arch/mips/include/asm/mach-ralink/mt7620.h
+index c8590df..1976fb8 100644
+--- a/arch/mips/include/asm/mach-ralink/mt7620.h
++++ b/arch/mips/include/asm/mach-ralink/mt7620.h
+@@ -90,7 +90,6 @@ enum mt762x_soc_type {
+ #define MT7620_DDR2_SIZE_MIN          32
+ #define MT7620_DDR2_SIZE_MAX          256
+-#define MT7620_GPIO_MODE_I2C          BIT(0)
+ #define MT7620_GPIO_MODE_UART0_SHIFT  2
+ #define MT7620_GPIO_MODE_UART0_MASK   0x7
+ #define MT7620_GPIO_MODE_UART0(x)     ((x) << MT7620_GPIO_MODE_UART0_SHIFT)
+@@ -102,16 +101,36 @@ enum mt762x_soc_type {
+ #define MT7620_GPIO_MODE_GPIO_UARTF   0x5
+ #define MT7620_GPIO_MODE_GPIO_I2S     0x6
+ #define MT7620_GPIO_MODE_GPIO         0x7
+-#define MT7620_GPIO_MODE_UART1                BIT(5)
+-#define MT7620_GPIO_MODE_MDIO         BIT(8)
+-#define MT7620_GPIO_MODE_RGMII1               BIT(9)
+-#define MT7620_GPIO_MODE_RGMII2               BIT(10)
+-#define MT7620_GPIO_MODE_SPI          BIT(11)
+-#define MT7620_GPIO_MODE_SPI_REF_CLK  BIT(12)
+-#define MT7620_GPIO_MODE_WLED         BIT(13)
+-#define MT7620_GPIO_MODE_JTAG         BIT(15)
+-#define MT7620_GPIO_MODE_EPHY         BIT(15)
+-#define MT7620_GPIO_MODE_WDT          BIT(22)
++
++#define MT7620_GPIO_MODE_NAND         0
++#define MT7620_GPIO_MODE_SD           1
++#define MT7620_GPIO_MODE_ND_SD_GPIO   2
++#define MT7620_GPIO_MODE_ND_SD_MASK   0x3
++#define MT7620_GPIO_MODE_ND_SD_SHIFT  18
++
++#define MT7620_GPIO_MODE_PCIE_RST     0
++#define MT7620_GPIO_MODE_PCIE_REF     1
++#define MT7620_GPIO_MODE_PCIE_GPIO    2
++#define MT7620_GPIO_MODE_PCIE_MASK    0x3
++#define MT7620_GPIO_MODE_PCIE_SHIFT   16
++
++#define MT7620_GPIO_MODE_WDT_RST      0
++#define MT7620_GPIO_MODE_WDT_REF      1
++#define MT7620_GPIO_MODE_WDT_GPIO     2
++#define MT7620_GPIO_MODE_WDT_MASK     0x3
++#define MT7620_GPIO_MODE_WDT_SHIFT    21
++
++#define MT7620_GPIO_MODE_I2C          0
++#define MT7620_GPIO_MODE_UART1                5
++#define MT7620_GPIO_MODE_MDIO         8
++#define MT7620_GPIO_MODE_RGMII1               9
++#define MT7620_GPIO_MODE_RGMII2               10
++#define MT7620_GPIO_MODE_SPI          11
++#define MT7620_GPIO_MODE_SPI_REF_CLK  12
++#define MT7620_GPIO_MODE_WLED         13
++#define MT7620_GPIO_MODE_JTAG         15
++#define MT7620_GPIO_MODE_EPHY         15
++#define MT7620_GPIO_MODE_PA           20
+ static inline int mt7620_get_eco(void)
+ {
+diff --git a/arch/mips/include/asm/mach-ralink/pinmux.h b/arch/mips/include/asm/mach-ralink/pinmux.h
+new file mode 100644
+index 0000000..324fa40
+--- /dev/null
++++ b/arch/mips/include/asm/mach-ralink/pinmux.h
+@@ -0,0 +1,53 @@
++/*
++ *  This program is free software; you can redistribute it and/or modify
++ *  it under the terms of the GNU General Public License version 2 as
++ *  publishhed by the Free Software Foundation.
++ *
++ *  Copyright (C) 2012 John Crispin <blogic@openwrt.org>
++ */
++
++#ifndef _RT288X_PINMUX_H__
++#define _RT288X_PINMUX_H__
++
++#define FUNC(name, value, pin_first, pin_count) { name, value, pin_first, pin_count }
++#define GRP(_name, _func, _mask, _shift) \
++      { .name = _name, .mask = _mask, .shift = _shift, \
++        .func = _func, .gpio = _mask, \
++        .func_count = ARRAY_SIZE(_func) }
++
++#define GRP_G(_name, _func, _mask, _gpio, _shift) \
++      { .name = _name, .mask = _mask, .shift = _shift, \
++        .func = _func, .gpio = _gpio, \
++        .func_count = ARRAY_SIZE(_func) }
++
++struct rt2880_pmx_group;
++
++struct rt2880_pmx_func {
++      const char *name;
++      const char value;
++
++      int pin_first;
++      int pin_count;
++      int *pins;
++
++      int *groups;
++      int group_count;
++
++      int enabled;
++};
++
++struct rt2880_pmx_group {
++      const char *name;
++      int enabled;
++
++      const u32 shift;
++      const char mask;
++      const char gpio;
++
++      struct rt2880_pmx_func *func;
++      int func_count;
++};
++
++extern struct rt2880_pmx_group *rt2880_pinmux_data;
++
++#endif
+diff --git a/arch/mips/include/asm/mach-ralink/rt305x.h b/arch/mips/include/asm/mach-ralink/rt305x.h
+index 069bf37..96f731b 100644
+--- a/arch/mips/include/asm/mach-ralink/rt305x.h
++++ b/arch/mips/include/asm/mach-ralink/rt305x.h
+@@ -125,24 +125,29 @@ static inline int soc_is_rt5350(void)
+ #define RT305X_GPIO_GE0_TXD0          40
+ #define RT305X_GPIO_GE0_RXCLK         51
+-#define RT305X_GPIO_MODE_I2C          BIT(0)
+-#define RT305X_GPIO_MODE_SPI          BIT(1)
+ #define RT305X_GPIO_MODE_UART0_SHIFT  2
+ #define RT305X_GPIO_MODE_UART0_MASK   0x7
+ #define RT305X_GPIO_MODE_UART0(x)     ((x) << RT305X_GPIO_MODE_UART0_SHIFT)
+-#define RT305X_GPIO_MODE_UARTF                0x0
+-#define RT305X_GPIO_MODE_PCM_UARTF    0x1
+-#define RT305X_GPIO_MODE_PCM_I2S      0x2
+-#define RT305X_GPIO_MODE_I2S_UARTF    0x3
+-#define RT305X_GPIO_MODE_PCM_GPIO     0x4
+-#define RT305X_GPIO_MODE_GPIO_UARTF   0x5
+-#define RT305X_GPIO_MODE_GPIO_I2S     0x6
+-#define RT305X_GPIO_MODE_GPIO         0x7
+-#define RT305X_GPIO_MODE_UART1                BIT(5)
+-#define RT305X_GPIO_MODE_JTAG         BIT(6)
+-#define RT305X_GPIO_MODE_MDIO         BIT(7)
+-#define RT305X_GPIO_MODE_SDRAM                BIT(8)
+-#define RT305X_GPIO_MODE_RGMII                BIT(9)
++#define RT305X_GPIO_MODE_UARTF                0
++#define RT305X_GPIO_MODE_PCM_UARTF    1
++#define RT305X_GPIO_MODE_PCM_I2S      2
++#define RT305X_GPIO_MODE_I2S_UARTF    3
++#define RT305X_GPIO_MODE_PCM_GPIO     4
++#define RT305X_GPIO_MODE_GPIO_UARTF   5
++#define RT305X_GPIO_MODE_GPIO_I2S     6
++#define RT305X_GPIO_MODE_GPIO         7
++
++#define RT305X_GPIO_MODE_I2C          0
++#define RT305X_GPIO_MODE_SPI          1
++#define RT305X_GPIO_MODE_UART1                5
++#define RT305X_GPIO_MODE_JTAG         6
++#define RT305X_GPIO_MODE_MDIO         7
++#define RT305X_GPIO_MODE_SDRAM                8
++#define RT305X_GPIO_MODE_RGMII                9
++#define RT5350_GPIO_MODE_PHY_LED      14
++#define RT5350_GPIO_MODE_SPI_CS1      21
++#define RT3352_GPIO_MODE_LNA          18
++#define RT3352_GPIO_MODE_PA           20
+ #define RT3352_SYSC_REG_SYSCFG0               0x010
+ #define RT3352_SYSC_REG_SYSCFG1         0x014
+diff --git a/arch/mips/include/asm/mach-ralink/rt3883.h b/arch/mips/include/asm/mach-ralink/rt3883.h
+index 058382f..0fbe6f9 100644
+--- a/arch/mips/include/asm/mach-ralink/rt3883.h
++++ b/arch/mips/include/asm/mach-ralink/rt3883.h
+@@ -112,8 +112,6 @@
+ #define RT3883_CLKCFG1_PCI_CLK_EN     BIT(19)
+ #define RT3883_CLKCFG1_UPHY0_CLK_EN   BIT(18)
+-#define RT3883_GPIO_MODE_I2C          BIT(0)
+-#define RT3883_GPIO_MODE_SPI          BIT(1)
+ #define RT3883_GPIO_MODE_UART0_SHIFT  2
+ #define RT3883_GPIO_MODE_UART0_MASK   0x7
+ #define RT3883_GPIO_MODE_UART0(x)     ((x) << RT3883_GPIO_MODE_UART0_SHIFT)
+@@ -125,11 +123,15 @@
+ #define RT3883_GPIO_MODE_GPIO_UARTF   0x5
+ #define RT3883_GPIO_MODE_GPIO_I2S     0x6
+ #define RT3883_GPIO_MODE_GPIO         0x7
+-#define RT3883_GPIO_MODE_UART1                BIT(5)
+-#define RT3883_GPIO_MODE_JTAG         BIT(6)
+-#define RT3883_GPIO_MODE_MDIO         BIT(7)
+-#define RT3883_GPIO_MODE_GE1          BIT(9)
+-#define RT3883_GPIO_MODE_GE2          BIT(10)
++
++#define RT3883_GPIO_MODE_I2C          0
++#define RT3883_GPIO_MODE_SPI          1
++#define RT3883_GPIO_MODE_UART1                5
++#define RT3883_GPIO_MODE_JTAG         6
++#define RT3883_GPIO_MODE_MDIO         7
++#define RT3883_GPIO_MODE_GE1          9
++#define RT3883_GPIO_MODE_GE2          10
++
+ #define RT3883_GPIO_MODE_PCI_SHIFT    11
+ #define RT3883_GPIO_MODE_PCI_MASK     0x7
+ #define RT3883_GPIO_MODE_PCI          (RT3883_GPIO_MODE_PCI_MASK << RT3883_GPIO_MODE_PCI_SHIFT)
+diff --git a/arch/mips/ralink/common.h b/arch/mips/ralink/common.h
+index 42dfd61..8e7d8e6 100644
+--- a/arch/mips/ralink/common.h
++++ b/arch/mips/ralink/common.h
+@@ -11,25 +11,6 @@
+ #define RAMIPS_SYS_TYPE_LEN   32
+-struct ralink_pinmux_grp {
+-      const char *name;
+-      u32 mask;
+-      int gpio_first;
+-      int gpio_last;
+-};
+-
+-struct ralink_pinmux {
+-      struct ralink_pinmux_grp *mode;
+-      struct ralink_pinmux_grp *uart;
+-      int uart_shift;
+-      u32 uart_mask;
+-      void (*wdt_reset)(void);
+-      struct ralink_pinmux_grp *pci;
+-      int pci_shift;
+-      u32 pci_mask;
+-};
+-extern struct ralink_pinmux rt_gpio_pinmux;
+-
+ struct ralink_soc_info {
+       unsigned char sys_type[RAMIPS_SYS_TYPE_LEN];
+       unsigned char *compatible;
+diff --git a/arch/mips/ralink/mt7620.c b/arch/mips/ralink/mt7620.c
+index e590ccf..818a7db 100644
+--- a/arch/mips/ralink/mt7620.c
++++ b/arch/mips/ralink/mt7620.c
+@@ -17,6 +17,7 @@
+ #include <asm/mipsregs.h>
+ #include <asm/mach-ralink/ralink_regs.h>
+ #include <asm/mach-ralink/mt7620.h>
++#include <asm/mach-ralink/pinmux.h>
+ #include "common.h"
+@@ -47,118 +48,58 @@ enum mt762x_soc_type mt762x_soc;
+ /* does the board have sdram or ddram */
+ static int dram_type;
+-static struct ralink_pinmux_grp mode_mux[] = {
+-      {
+-              .name = "i2c",
+-              .mask = MT7620_GPIO_MODE_I2C,
+-              .gpio_first = 1,
+-              .gpio_last = 2,
+-      }, {
+-              .name = "spi",
+-              .mask = MT7620_GPIO_MODE_SPI,
+-              .gpio_first = 3,
+-              .gpio_last = 6,
+-      }, {
+-              .name = "uartlite",
+-              .mask = MT7620_GPIO_MODE_UART1,
+-              .gpio_first = 15,
+-              .gpio_last = 16,
+-      }, {
+-              .name = "wdt",
+-              .mask = MT7620_GPIO_MODE_WDT,
+-              .gpio_first = 17,
+-              .gpio_last = 17,
+-      }, {
+-              .name = "mdio",
+-              .mask = MT7620_GPIO_MODE_MDIO,
+-              .gpio_first = 22,
+-              .gpio_last = 23,
+-      }, {
+-              .name = "rgmii1",
+-              .mask = MT7620_GPIO_MODE_RGMII1,
+-              .gpio_first = 24,
+-              .gpio_last = 35,
+-      }, {
+-              .name = "spi refclk",
+-              .mask = MT7620_GPIO_MODE_SPI_REF_CLK,
+-              .gpio_first = 37,
+-              .gpio_last = 39,
+-      }, {
+-              .name = "jtag",
+-              .mask = MT7620_GPIO_MODE_JTAG,
+-              .gpio_first = 40,
+-              .gpio_last = 44,
+-      }, {
+-              /* shared lines with jtag */
+-              .name = "ephy",
+-              .mask = MT7620_GPIO_MODE_EPHY,
+-              .gpio_first = 40,
+-              .gpio_last = 44,
+-      }, {
+-              .name = "nand",
+-              .mask = MT7620_GPIO_MODE_JTAG,
+-              .gpio_first = 45,
+-              .gpio_last = 59,
+-      }, {
+-              .name = "rgmii2",
+-              .mask = MT7620_GPIO_MODE_RGMII2,
+-              .gpio_first = 60,
+-              .gpio_last = 71,
+-      }, {
+-              .name = "wled",
+-              .mask = MT7620_GPIO_MODE_WLED,
+-              .gpio_first = 72,
+-              .gpio_last = 72,
+-      }, {0}
++static struct rt2880_pmx_func i2c_grp[] =  { FUNC("i2c", 0, 1, 2) };
++static struct rt2880_pmx_func spi_grp[] = { FUNC("spi", 0, 3, 4) };
++static struct rt2880_pmx_func uartlite_grp[] = { FUNC("uartlite", 0, 15, 2) };
++static struct rt2880_pmx_func mdio_grp[] = { FUNC("mdio", 0, 22, 2) };
++static struct rt2880_pmx_func rgmii1_grp[] = { FUNC("rgmii1", 0, 24, 12) };
++static struct rt2880_pmx_func refclk_grp[] = { FUNC("spi refclk", 0, 37, 3) };
++static struct rt2880_pmx_func ephy_grp[] = { FUNC("ephy", 0, 40, 5) };
++static struct rt2880_pmx_func rgmii2_grp[] = { FUNC("rgmii2", 0, 60, 12) };
++static struct rt2880_pmx_func wled_grp[] = { FUNC("wled", 0, 72, 1) };
++static struct rt2880_pmx_func pa_grp[] = { FUNC("pa", 0, 18, 4) };
++static struct rt2880_pmx_func uartf_grp[] = {
++      FUNC("uartf", MT7620_GPIO_MODE_UARTF, 7, 8),
++      FUNC("pcm uartf", MT7620_GPIO_MODE_PCM_UARTF, 7, 8),
++      FUNC("pcm i2s", MT7620_GPIO_MODE_PCM_I2S, 7, 8),
++      FUNC("i2s uartf", MT7620_GPIO_MODE_I2S_UARTF, 7, 8),
++      FUNC("pcm gpio", MT7620_GPIO_MODE_PCM_GPIO, 11, 4),
++      FUNC("gpio uartf", MT7620_GPIO_MODE_GPIO_UARTF, 7, 4),
++      FUNC("gpio i2s", MT7620_GPIO_MODE_GPIO_I2S, 7, 4),
+ };
+-
+-static struct ralink_pinmux_grp uart_mux[] = {
+-      {
+-              .name = "uartf",
+-              .mask = MT7620_GPIO_MODE_UARTF,
+-              .gpio_first = 7,
+-              .gpio_last = 14,
+-      }, {
+-              .name = "pcm uartf",
+-              .mask = MT7620_GPIO_MODE_PCM_UARTF,
+-              .gpio_first = 7,
+-              .gpio_last = 14,
+-      }, {
+-              .name = "pcm i2s",
+-              .mask = MT7620_GPIO_MODE_PCM_I2S,
+-              .gpio_first = 7,
+-              .gpio_last = 14,
+-      }, {
+-              .name = "i2s uartf",
+-              .mask = MT7620_GPIO_MODE_I2S_UARTF,
+-              .gpio_first = 7,
+-              .gpio_last = 14,
+-      }, {
+-              .name = "pcm gpio",
+-              .mask = MT7620_GPIO_MODE_PCM_GPIO,
+-              .gpio_first = 11,
+-              .gpio_last = 14,
+-      }, {
+-              .name = "gpio uartf",
+-              .mask = MT7620_GPIO_MODE_GPIO_UARTF,
+-              .gpio_first = 7,
+-              .gpio_last = 10,
+-      }, {
+-              .name = "gpio i2s",
+-              .mask = MT7620_GPIO_MODE_GPIO_I2S,
+-              .gpio_first = 7,
+-              .gpio_last = 10,
+-      }, {
+-              .name = "gpio",
+-              .mask = MT7620_GPIO_MODE_GPIO,
+-      }, {0}
++static struct rt2880_pmx_func wdt_grp[] = {
++      FUNC("wdt rst", 0, 17, 1),
++      FUNC("wdt refclk", 0, 17, 1),
++      };
++static struct rt2880_pmx_func pcie_rst_grp[] = {
++      FUNC("pcie rst", MT7620_GPIO_MODE_PCIE_RST, 36, 1),
++      FUNC("pcie refclk", MT7620_GPIO_MODE_PCIE_REF, 36, 1)
++};
++static struct rt2880_pmx_func nd_sd_grp[] = {
++      FUNC("nand", MT7620_GPIO_MODE_NAND, 45, 15),
++      FUNC("sd", MT7620_GPIO_MODE_SD, 45, 15)
+ };
+-struct ralink_pinmux rt_gpio_pinmux = {
+-      .mode = mode_mux,
+-      .uart = uart_mux,
+-      .uart_shift = MT7620_GPIO_MODE_UART0_SHIFT,
+-      .uart_mask = MT7620_GPIO_MODE_UART0_MASK,
++static struct rt2880_pmx_group mt7620a_pinmux_data[] = {
++      GRP("i2c", i2c_grp, 1, MT7620_GPIO_MODE_I2C),
++      GRP("uartf", uartf_grp, MT7620_GPIO_MODE_UART0_MASK,
++              MT7620_GPIO_MODE_UART0_SHIFT),
++      GRP("spi", spi_grp, 1, MT7620_GPIO_MODE_SPI),
++      GRP("uartlite", uartlite_grp, 1, MT7620_GPIO_MODE_UART1),
++      GRP_G("wdt", wdt_grp, MT7620_GPIO_MODE_WDT_MASK,
++              MT7620_GPIO_MODE_WDT_GPIO, MT7620_GPIO_MODE_WDT_SHIFT),
++      GRP("mdio", mdio_grp, 1, MT7620_GPIO_MODE_MDIO),
++      GRP("rgmii1", rgmii1_grp, 1, MT7620_GPIO_MODE_RGMII1),
++      GRP("spi refclk", refclk_grp, 1, MT7620_GPIO_MODE_SPI_REF_CLK),
++      GRP_G("pcie", pcie_rst_grp, MT7620_GPIO_MODE_PCIE_MASK,
++              MT7620_GPIO_MODE_PCIE_GPIO, MT7620_GPIO_MODE_PCIE_SHIFT),
++      GRP_G("nd_sd", nd_sd_grp, MT7620_GPIO_MODE_ND_SD_MASK,
++              MT7620_GPIO_MODE_ND_SD_GPIO, MT7620_GPIO_MODE_ND_SD_SHIFT),
++      GRP("rgmii2", rgmii2_grp, 1, MT7620_GPIO_MODE_RGMII2),
++      GRP("wled", wled_grp, 1, MT7620_GPIO_MODE_WLED),
++      GRP("ephy", ephy_grp, 1, MT7620_GPIO_MODE_EPHY),
++      GRP("pa", pa_grp, 1, MT7620_GPIO_MODE_PA),
++      { 0 }
+ };
+ static struct rt2880_pmx_func pwm1_grp_mt7628[] = {
+diff --git a/arch/mips/ralink/rt288x.c b/arch/mips/ralink/rt288x.c
+index 90e8934..2bfc660 100644
+--- a/arch/mips/ralink/rt288x.c
++++ b/arch/mips/ralink/rt288x.c
+@@ -17,46 +17,27 @@
+ #include <asm/mipsregs.h>
+ #include <asm/mach-ralink/ralink_regs.h>
+ #include <asm/mach-ralink/rt288x.h>
++#include <asm/mach-ralink/pinmux.h>
+ #include "common.h"
+-static struct ralink_pinmux_grp mode_mux[] = {
+-      {
+-              .name = "i2c",
+-              .mask = RT2880_GPIO_MODE_I2C,
+-              .gpio_first = 1,
+-              .gpio_last = 2,
+-      }, {
+-              .name = "spi",
+-              .mask = RT2880_GPIO_MODE_SPI,
+-              .gpio_first = 3,
+-              .gpio_last = 6,
+-      }, {
+-              .name = "uartlite",
+-              .mask = RT2880_GPIO_MODE_UART0,
+-              .gpio_first = 7,
+-              .gpio_last = 14,
+-      }, {
+-              .name = "jtag",
+-              .mask = RT2880_GPIO_MODE_JTAG,
+-              .gpio_first = 17,
+-              .gpio_last = 21,
+-      }, {
+-              .name = "mdio",
+-              .mask = RT2880_GPIO_MODE_MDIO,
+-              .gpio_first = 22,
+-              .gpio_last = 23,
+-      }, {
+-              .name = "sdram",
+-              .mask = RT2880_GPIO_MODE_SDRAM,
+-              .gpio_first = 24,
+-              .gpio_last = 39,
+-      }, {
+-              .name = "pci",
+-              .mask = RT2880_GPIO_MODE_PCI,
+-              .gpio_first = 40,
+-              .gpio_last = 71,
+-      }, {0}
++static struct rt2880_pmx_func i2c_func[] = { FUNC("i2c", 0, 1, 2) };
++static struct rt2880_pmx_func spi_func[] = { FUNC("spi", 0, 3, 4) };
++static struct rt2880_pmx_func uartlite_func[] = { FUNC("uartlite", 0, 7, 8) };
++static struct rt2880_pmx_func jtag_func[] = { FUNC("jtag", 0, 17, 5) };
++static struct rt2880_pmx_func mdio_func[] = { FUNC("mdio", 0, 22, 2) };
++static struct rt2880_pmx_func sdram_func[] = { FUNC("sdram", 0, 24, 16) };
++static struct rt2880_pmx_func pci_func[] = { FUNC("pci", 0, 40, 32) };
++
++static struct rt2880_pmx_group rt2880_pinmux_data_act[] = {
++    GRP("i2c", i2c_func, 1, RT2880_GPIO_MODE_I2C),
++    GRP("spi", spi_func, 1, RT2880_GPIO_MODE_SPI),
++    GRP("uartlite", uartlite_func, 1, RT2880_GPIO_MODE_UART0),
++    GRP("jtag", jtag_func, 1, RT2880_GPIO_MODE_JTAG),
++    GRP("mdio", mdio_func, 1, RT2880_GPIO_MODE_MDIO),
++    GRP("sdram", sdram_func, 1, RT2880_GPIO_MODE_SDRAM),
++    GRP("pci", pci_func, 1, RT2880_GPIO_MODE_PCI),
++    { 0 }
+ };
+ static void rt288x_wdt_reset(void)
+@@ -69,11 +50,6 @@ static void rt288x_wdt_reset(void)
+       rt_sysc_w32(t, SYSC_REG_CLKCFG);
+ }
+-struct ralink_pinmux rt_gpio_pinmux = {
+-      .mode = mode_mux,
+-      .wdt_reset = rt288x_wdt_reset,
+-};
+-
+ void __init ralink_clk_init(void)
+ {
+       unsigned long cpu_rate, wmac_rate = 40000000;
+@@ -141,4 +117,6 @@ void prom_soc_init(struct ralink_soc_info *soc_info)
+       soc_info->mem_base = RT2880_SDRAM_BASE;
+       soc_info->mem_size_min = RT2880_MEM_SIZE_MIN;
+       soc_info->mem_size_max = RT2880_MEM_SIZE_MAX;
++
++        rt2880_pinmux_data = rt2880_pinmux_data_act;
+ }
+diff --git a/arch/mips/ralink/rt305x.c b/arch/mips/ralink/rt305x.c
+index bb82a82..356d6a0 100644
+--- a/arch/mips/ralink/rt305x.c
++++ b/arch/mips/ralink/rt305x.c
+@@ -17,90 +17,76 @@
+ #include <asm/mipsregs.h>
+ #include <asm/mach-ralink/ralink_regs.h>
+ #include <asm/mach-ralink/rt305x.h>
++#include <asm/mach-ralink/pinmux.h>
+ #include "common.h"
+ enum rt305x_soc_type rt305x_soc;
+-static struct ralink_pinmux_grp mode_mux[] = {
+-      {
+-              .name = "i2c",
+-              .mask = RT305X_GPIO_MODE_I2C,
+-              .gpio_first = RT305X_GPIO_I2C_SD,
+-              .gpio_last = RT305X_GPIO_I2C_SCLK,
+-      }, {
+-              .name = "spi",
+-              .mask = RT305X_GPIO_MODE_SPI,
+-              .gpio_first = RT305X_GPIO_SPI_EN,
+-              .gpio_last = RT305X_GPIO_SPI_CLK,
+-      }, {
+-              .name = "uartlite",
+-              .mask = RT305X_GPIO_MODE_UART1,
+-              .gpio_first = RT305X_GPIO_UART1_TXD,
+-              .gpio_last = RT305X_GPIO_UART1_RXD,
+-      }, {
+-              .name = "jtag",
+-              .mask = RT305X_GPIO_MODE_JTAG,
+-              .gpio_first = RT305X_GPIO_JTAG_TDO,
+-              .gpio_last = RT305X_GPIO_JTAG_TDI,
+-      }, {
+-              .name = "mdio",
+-              .mask = RT305X_GPIO_MODE_MDIO,
+-              .gpio_first = RT305X_GPIO_MDIO_MDC,
+-              .gpio_last = RT305X_GPIO_MDIO_MDIO,
+-      }, {
+-              .name = "sdram",
+-              .mask = RT305X_GPIO_MODE_SDRAM,
+-              .gpio_first = RT305X_GPIO_SDRAM_MD16,
+-              .gpio_last = RT305X_GPIO_SDRAM_MD31,
+-      }, {
+-              .name = "rgmii",
+-              .mask = RT305X_GPIO_MODE_RGMII,
+-              .gpio_first = RT305X_GPIO_GE0_TXD0,
+-              .gpio_last = RT305X_GPIO_GE0_RXCLK,
+-      }, {0}
++static struct rt2880_pmx_func i2c_func[] =  { FUNC("i2c", 0, 1, 2) };
++static struct rt2880_pmx_func spi_func[] = { FUNC("spi", 0, 3, 4) };
++static struct rt2880_pmx_func uartf_func[] = {
++      FUNC("uartf", RT305X_GPIO_MODE_UARTF, 7, 8),
++      FUNC("pcm uartf", RT305X_GPIO_MODE_PCM_UARTF, 7, 8),
++      FUNC("pcm i2s", RT305X_GPIO_MODE_PCM_I2S, 7, 8),
++      FUNC("i2s uartf", RT305X_GPIO_MODE_I2S_UARTF, 7, 8),
++      FUNC("pcm gpio", RT305X_GPIO_MODE_PCM_GPIO, 11, 4),
++      FUNC("gpio uartf", RT305X_GPIO_MODE_GPIO_UARTF, 7, 4),
++      FUNC("gpio i2s", RT305X_GPIO_MODE_GPIO_I2S, 7, 4),
++};
++static struct rt2880_pmx_func uartlite_func[] = { FUNC("uartlite", 0, 15, 2) };
++static struct rt2880_pmx_func jtag_func[] = { FUNC("jtag", 0, 17, 5) };
++static struct rt2880_pmx_func mdio_func[] = { FUNC("mdio", 0, 22, 2) };
++static struct rt2880_pmx_func rt5350_led_func[] = { FUNC("led", 0, 22, 5) };
++static struct rt2880_pmx_func rt5350_cs1_func[] = {
++      FUNC("spi_cs1", 0, 27, 1),
++      FUNC("wdg_cs1", 1, 27, 1),
++};
++static struct rt2880_pmx_func sdram_func[] = { FUNC("sdram", 0, 24, 16) };
++static struct rt2880_pmx_func rt3352_rgmii_func[] = { FUNC("rgmii", 0, 24, 12) };
++static struct rt2880_pmx_func rgmii_func[] = { FUNC("rgmii", 0, 40, 12) };
++static struct rt2880_pmx_func rt3352_lna_func[] = { FUNC("lna", 0, 36, 2) };
++static struct rt2880_pmx_func rt3352_pa_func[] = { FUNC("pa", 0, 38, 2) };
++static struct rt2880_pmx_func rt3352_led_func[] = { FUNC("led", 0, 40, 5) };
++
++static struct rt2880_pmx_group rt3050_pinmux_data[] = {
++      GRP("i2c", i2c_func, 1, RT305X_GPIO_MODE_I2C),
++      GRP("spi", spi_func, 1, RT305X_GPIO_MODE_SPI),
++      GRP("uartf", uartf_func, RT305X_GPIO_MODE_UART0_MASK,
++              RT305X_GPIO_MODE_UART0_SHIFT),
++      GRP("uartlite", uartlite_func, 1, RT305X_GPIO_MODE_UART1),
++      GRP("jtag", jtag_func, 1, RT305X_GPIO_MODE_JTAG),
++      GRP("mdio", mdio_func, 1, RT305X_GPIO_MODE_MDIO),
++      GRP("rgmii", rgmii_func, 1, RT305X_GPIO_MODE_RGMII),
++      GRP("sdram", sdram_func, 1, RT305X_GPIO_MODE_SDRAM),
++      { 0 }
+ };
+-static struct ralink_pinmux_grp uart_mux[] = {
+-      {
+-              .name = "uartf",
+-              .mask = RT305X_GPIO_MODE_UARTF,
+-              .gpio_first = RT305X_GPIO_7,
+-              .gpio_last = RT305X_GPIO_14,
+-      }, {
+-              .name = "pcm uartf",
+-              .mask = RT305X_GPIO_MODE_PCM_UARTF,
+-              .gpio_first = RT305X_GPIO_7,
+-              .gpio_last = RT305X_GPIO_14,
+-      }, {
+-              .name = "pcm i2s",
+-              .mask = RT305X_GPIO_MODE_PCM_I2S,
+-              .gpio_first = RT305X_GPIO_7,
+-              .gpio_last = RT305X_GPIO_14,
+-      }, {
+-              .name = "i2s uartf",
+-              .mask = RT305X_GPIO_MODE_I2S_UARTF,
+-              .gpio_first = RT305X_GPIO_7,
+-              .gpio_last = RT305X_GPIO_14,
+-      }, {
+-              .name = "pcm gpio",
+-              .mask = RT305X_GPIO_MODE_PCM_GPIO,
+-              .gpio_first = RT305X_GPIO_10,
+-              .gpio_last = RT305X_GPIO_14,
+-      }, {
+-              .name = "gpio uartf",
+-              .mask = RT305X_GPIO_MODE_GPIO_UARTF,
+-              .gpio_first = RT305X_GPIO_7,
+-              .gpio_last = RT305X_GPIO_10,
+-      }, {
+-              .name = "gpio i2s",
+-              .mask = RT305X_GPIO_MODE_GPIO_I2S,
+-              .gpio_first = RT305X_GPIO_7,
+-              .gpio_last = RT305X_GPIO_10,
+-      }, {
+-              .name = "gpio",
+-              .mask = RT305X_GPIO_MODE_GPIO,
+-      }, {0}
++static struct rt2880_pmx_group rt3352_pinmux_data[] = {
++      GRP("i2c", i2c_func, 1, RT305X_GPIO_MODE_I2C),
++      GRP("spi", spi_func, 1, RT305X_GPIO_MODE_SPI),
++      GRP("uartf", uartf_func, RT305X_GPIO_MODE_UART0_MASK,
++              RT305X_GPIO_MODE_UART0_SHIFT),
++      GRP("uartlite", uartlite_func, 1, RT305X_GPIO_MODE_UART1),
++      GRP("jtag", jtag_func, 1, RT305X_GPIO_MODE_JTAG),
++      GRP("mdio", mdio_func, 1, RT305X_GPIO_MODE_MDIO),
++      GRP("rgmii", rt3352_rgmii_func, 1, RT305X_GPIO_MODE_RGMII),
++      GRP("lna", rt3352_lna_func, 1, RT3352_GPIO_MODE_LNA),
++      GRP("pa", rt3352_pa_func, 1, RT3352_GPIO_MODE_PA),
++      GRP("led", rt3352_led_func, 1, RT5350_GPIO_MODE_PHY_LED),
++      { 0 }
++};
++
++static struct rt2880_pmx_group rt5350_pinmux_data[] = {
++      GRP("i2c", i2c_func, 1, RT305X_GPIO_MODE_I2C),
++      GRP("spi", spi_func, 1, RT305X_GPIO_MODE_SPI),
++      GRP("uartf", uartf_func, RT305X_GPIO_MODE_UART0_MASK,
++              RT305X_GPIO_MODE_UART0_SHIFT),
++      GRP("uartlite", uartlite_func, 1, RT305X_GPIO_MODE_UART1),
++      GRP("jtag", jtag_func, 1, RT305X_GPIO_MODE_JTAG),
++      GRP("led", rt5350_led_func, 1, RT5350_GPIO_MODE_PHY_LED),
++      GRP("spi_cs1", rt5350_cs1_func, 2, RT5350_GPIO_MODE_SPI_CS1),
++      { 0 }
+ };
+ static void rt305x_wdt_reset(void)
+@@ -114,14 +100,6 @@ static void rt305x_wdt_reset(void)
+       rt_sysc_w32(t, SYSC_REG_SYSTEM_CONFIG);
+ }
+-struct ralink_pinmux rt_gpio_pinmux = {
+-      .mode = mode_mux,
+-      .uart = uart_mux,
+-      .uart_shift = RT305X_GPIO_MODE_UART0_SHIFT,
+-      .uart_mask = RT305X_GPIO_MODE_UART0_MASK,
+-      .wdt_reset = rt305x_wdt_reset,
+-};
+-
+ static unsigned long rt5350_get_mem_size(void)
+ {
+       void __iomem *sysc = (void __iomem *) KSEG1ADDR(RT305X_SYSC_BASE);
+@@ -290,11 +268,14 @@ void prom_soc_init(struct ralink_soc_info *soc_info)
+       soc_info->mem_base = RT305X_SDRAM_BASE;
+       if (soc_is_rt5350()) {
+               soc_info->mem_size = rt5350_get_mem_size();
++              rt2880_pinmux_data = rt5350_pinmux_data;
+       } else if (soc_is_rt305x() || soc_is_rt3350()) {
+               soc_info->mem_size_min = RT305X_MEM_SIZE_MIN;
+               soc_info->mem_size_max = RT305X_MEM_SIZE_MAX;
++              rt2880_pinmux_data = rt3050_pinmux_data;
+       } else if (soc_is_rt3352()) {
+               soc_info->mem_size_min = RT3352_MEM_SIZE_MIN;
+               soc_info->mem_size_max = RT3352_MEM_SIZE_MAX;
++              rt2880_pinmux_data = rt3352_pinmux_data;
+       }
+ }
+diff --git a/arch/mips/ralink/rt3883.c b/arch/mips/ralink/rt3883.c
+index 58b5b9f..86a535c 100644
+--- a/arch/mips/ralink/rt3883.c
++++ b/arch/mips/ralink/rt3883.c
+@@ -17,132 +17,50 @@
+ #include <asm/mipsregs.h>
+ #include <asm/mach-ralink/ralink_regs.h>
+ #include <asm/mach-ralink/rt3883.h>
++#include <asm/mach-ralink/pinmux.h>
+ #include "common.h"
+-static struct ralink_pinmux_grp mode_mux[] = {
+-      {
+-              .name = "i2c",
+-              .mask = RT3883_GPIO_MODE_I2C,
+-              .gpio_first = RT3883_GPIO_I2C_SD,
+-              .gpio_last = RT3883_GPIO_I2C_SCLK,
+-      }, {
+-              .name = "spi",
+-              .mask = RT3883_GPIO_MODE_SPI,
+-              .gpio_first = RT3883_GPIO_SPI_CS0,
+-              .gpio_last = RT3883_GPIO_SPI_MISO,
+-      }, {
+-              .name = "uartlite",
+-              .mask = RT3883_GPIO_MODE_UART1,
+-              .gpio_first = RT3883_GPIO_UART1_TXD,
+-              .gpio_last = RT3883_GPIO_UART1_RXD,
+-      }, {
+-              .name = "jtag",
+-              .mask = RT3883_GPIO_MODE_JTAG,
+-              .gpio_first = RT3883_GPIO_JTAG_TDO,
+-              .gpio_last = RT3883_GPIO_JTAG_TCLK,
+-      }, {
+-              .name = "mdio",
+-              .mask = RT3883_GPIO_MODE_MDIO,
+-              .gpio_first = RT3883_GPIO_MDIO_MDC,
+-              .gpio_last = RT3883_GPIO_MDIO_MDIO,
+-      }, {
+-              .name = "ge1",
+-              .mask = RT3883_GPIO_MODE_GE1,
+-              .gpio_first = RT3883_GPIO_GE1_TXD0,
+-              .gpio_last = RT3883_GPIO_GE1_RXCLK,
+-      }, {
+-              .name = "ge2",
+-              .mask = RT3883_GPIO_MODE_GE2,
+-              .gpio_first = RT3883_GPIO_GE2_TXD0,
+-              .gpio_last = RT3883_GPIO_GE2_RXCLK,
+-      }, {
+-              .name = "pci",
+-              .mask = RT3883_GPIO_MODE_PCI,
+-              .gpio_first = RT3883_GPIO_PCI_AD0,
+-              .gpio_last = RT3883_GPIO_PCI_AD31,
+-      }, {
+-              .name = "lna a",
+-              .mask = RT3883_GPIO_MODE_LNA_A,
+-              .gpio_first = RT3883_GPIO_LNA_PE_A0,
+-              .gpio_last = RT3883_GPIO_LNA_PE_A2,
+-      }, {
+-              .name = "lna g",
+-              .mask = RT3883_GPIO_MODE_LNA_G,
+-              .gpio_first = RT3883_GPIO_LNA_PE_G0,
+-              .gpio_last = RT3883_GPIO_LNA_PE_G2,
+-      }, {0}
++static struct rt2880_pmx_func i2c_func[] =  { FUNC("i2c", 0, 1, 2) };
++static struct rt2880_pmx_func spi_func[] = { FUNC("spi", 0, 3, 4) };
++static struct rt2880_pmx_func uartf_func[] = {
++      FUNC("uartf", RT3883_GPIO_MODE_UARTF, 7, 8),
++      FUNC("pcm uartf", RT3883_GPIO_MODE_PCM_UARTF, 7, 8),
++      FUNC("pcm i2s", RT3883_GPIO_MODE_PCM_I2S, 7, 8),
++      FUNC("i2s uartf", RT3883_GPIO_MODE_I2S_UARTF, 7, 8),
++      FUNC("pcm gpio", RT3883_GPIO_MODE_PCM_GPIO, 11, 4),
++      FUNC("gpio uartf", RT3883_GPIO_MODE_GPIO_UARTF, 7, 4),
++      FUNC("gpio i2s", RT3883_GPIO_MODE_GPIO_I2S, 7, 4),
+ };
+-
+-static struct ralink_pinmux_grp uart_mux[] = {
+-      {
+-              .name = "uartf",
+-              .mask = RT3883_GPIO_MODE_UARTF,
+-              .gpio_first = RT3883_GPIO_7,
+-              .gpio_last = RT3883_GPIO_14,
+-      }, {
+-              .name = "pcm uartf",
+-              .mask = RT3883_GPIO_MODE_PCM_UARTF,
+-              .gpio_first = RT3883_GPIO_7,
+-              .gpio_last = RT3883_GPIO_14,
+-      }, {
+-              .name = "pcm i2s",
+-              .mask = RT3883_GPIO_MODE_PCM_I2S,
+-              .gpio_first = RT3883_GPIO_7,
+-              .gpio_last = RT3883_GPIO_14,
+-      }, {
+-              .name = "i2s uartf",
+-              .mask = RT3883_GPIO_MODE_I2S_UARTF,
+-              .gpio_first = RT3883_GPIO_7,
+-              .gpio_last = RT3883_GPIO_14,
+-      }, {
+-              .name = "pcm gpio",
+-              .mask = RT3883_GPIO_MODE_PCM_GPIO,
+-              .gpio_first = RT3883_GPIO_11,
+-              .gpio_last = RT3883_GPIO_14,
+-      }, {
+-              .name = "gpio uartf",
+-              .mask = RT3883_GPIO_MODE_GPIO_UARTF,
+-              .gpio_first = RT3883_GPIO_7,
+-              .gpio_last = RT3883_GPIO_10,
+-      }, {
+-              .name = "gpio i2s",
+-              .mask = RT3883_GPIO_MODE_GPIO_I2S,
+-              .gpio_first = RT3883_GPIO_7,
+-              .gpio_last = RT3883_GPIO_10,
+-      }, {
+-              .name = "gpio",
+-              .mask = RT3883_GPIO_MODE_GPIO,
+-      }, {0}
++static struct rt2880_pmx_func uartlite_func[] = { FUNC("uartlite", 0, 15, 2) };
++static struct rt2880_pmx_func jtag_func[] = { FUNC("jtag", 0, 17, 5) };
++static struct rt2880_pmx_func mdio_func[] = { FUNC("mdio", 0, 22, 2) };
++static struct rt2880_pmx_func lna_a_func[] = { FUNC("lna a", 0, 32, 3) };
++static struct rt2880_pmx_func lna_g_func[] = { FUNC("lna a", 0, 35, 3) };
++static struct rt2880_pmx_func pci_func[] = {
++      FUNC("pci-dev", 0, 40, 32),
++      FUNC("pci-host2", 1, 40, 32),
++      FUNC("pci-host1", 2, 40, 32),
++      FUNC("pci-fnc", 3, 40, 32)
+ };
+-
+-static struct ralink_pinmux_grp pci_mux[] = {
+-      {
+-              .name = "pci-dev",
+-              .mask = 0,
+-              .gpio_first = RT3883_GPIO_PCI_AD0,
+-              .gpio_last = RT3883_GPIO_PCI_AD31,
+-      }, {
+-              .name = "pci-host2",
+-              .mask = 1,
+-              .gpio_first = RT3883_GPIO_PCI_AD0,
+-              .gpio_last = RT3883_GPIO_PCI_AD31,
+-      }, {
+-              .name = "pci-host1",
+-              .mask = 2,
+-              .gpio_first = RT3883_GPIO_PCI_AD0,
+-              .gpio_last = RT3883_GPIO_PCI_AD31,
+-      }, {
+-              .name = "pci-fnc",
+-              .mask = 3,
+-              .gpio_first = RT3883_GPIO_PCI_AD0,
+-              .gpio_last = RT3883_GPIO_PCI_AD31,
+-      }, {
+-              .name = "pci-gpio",
+-              .mask = 7,
+-              .gpio_first = RT3883_GPIO_PCI_AD0,
+-              .gpio_last = RT3883_GPIO_PCI_AD31,
+-      }, {0}
++static struct rt2880_pmx_func ge1_func[] = { FUNC("ge1", 0, 72, 12) };
++static struct rt2880_pmx_func ge2_func[] = { FUNC("ge1", 0, 84, 12) };
++
++static struct rt2880_pmx_group rt3883_pinmux_data[] = {
++      GRP("i2c", i2c_func, 1, RT3883_GPIO_MODE_I2C),
++      GRP("spi", spi_func, 1, RT3883_GPIO_MODE_SPI),
++      GRP("uartf", uartf_func, RT3883_GPIO_MODE_UART0_MASK,
++              RT3883_GPIO_MODE_UART0_SHIFT),
++      GRP("uartlite", uartlite_func, 1, RT3883_GPIO_MODE_UART1),
++      GRP("jtag", jtag_func, 1, RT3883_GPIO_MODE_JTAG),
++      GRP("mdio", mdio_func, 1, RT3883_GPIO_MODE_MDIO),
++      GRP("lna a", lna_a_func, 1, RT3883_GPIO_MODE_LNA_A),
++      GRP("lna g", lna_g_func, 1, RT3883_GPIO_MODE_LNA_G),
++      GRP("pci", pci_func, RT3883_GPIO_MODE_PCI_MASK,
++              RT3883_GPIO_MODE_PCI_SHIFT),
++      GRP("ge1", ge1_func, 1, RT3883_GPIO_MODE_GE1),
++      GRP("ge2", ge2_func, 1, RT3883_GPIO_MODE_GE2),
++      { 0 }
+ };
+ static void rt3883_wdt_reset(void)
+@@ -155,17 +73,6 @@ static void rt3883_wdt_reset(void)
+       rt_sysc_w32(t, RT3883_SYSC_REG_SYSCFG1);
+ }
+-struct ralink_pinmux rt_gpio_pinmux = {
+-      .mode = mode_mux,
+-      .uart = uart_mux,
+-      .uart_shift = RT3883_GPIO_MODE_UART0_SHIFT,
+-      .uart_mask = RT3883_GPIO_MODE_UART0_MASK,
+-      .wdt_reset = rt3883_wdt_reset,
+-      .pci = pci_mux,
+-      .pci_shift = RT3883_GPIO_MODE_PCI_SHIFT,
+-      .pci_mask = RT3883_GPIO_MODE_PCI_MASK,
+-};
+-
+ void __init ralink_clk_init(void)
+ {
+       unsigned long cpu_rate, sys_rate;
+@@ -244,4 +151,6 @@ void prom_soc_init(struct ralink_soc_info *soc_info)
+       soc_info->mem_base = RT3883_SDRAM_BASE;
+       soc_info->mem_size_min = RT3883_MEM_SIZE_MIN;
+       soc_info->mem_size_max = RT3883_MEM_SIZE_MAX;
++
++      rt2880_pinmux_data = rt3883_pinmux_data;
+ }
+diff --git a/drivers/pinctrl/Kconfig b/drivers/pinctrl/Kconfig
+index 1e4e693..1ff1491 100644
+--- a/drivers/pinctrl/Kconfig
++++ b/drivers/pinctrl/Kconfig
+@@ -198,6 +198,11 @@ config PINCTRL_LANTIQ
+       select PINMUX
+       select PINCONF
++config PINCTRL_RT2880
++      bool
++      depends on RALINK
++      select PINMUX
++
+ config PINCTRL_FALCON
+       bool
+       depends on SOC_FALCON
+diff --git a/drivers/pinctrl/Makefile b/drivers/pinctrl/Makefile
+index 4b83588..3160836 100644
+--- a/drivers/pinctrl/Makefile
++++ b/drivers/pinctrl/Makefile
+@@ -45,6 +45,7 @@ obj-$(CONFIG_PINCTRL_DB8500) += pinctrl-nomadik-db8500.o
+ obj-$(CONFIG_PINCTRL_DB8540)  += pinctrl-nomadik-db8540.o
+ obj-$(CONFIG_PINCTRL_PALMAS)  += pinctrl-palmas.o
+ obj-$(CONFIG_PINCTRL_ROCKCHIP)        += pinctrl-rockchip.o
++obj-$(CONFIG_PINCTRL_RT2880)  += pinctrl-rt2880.o
+ obj-$(CONFIG_PINCTRL_SINGLE)  += pinctrl-single.o
+ obj-$(CONFIG_PINCTRL_SIRF)    += sirf/
+ obj-$(CONFIG_PINCTRL_SUNXI)   += pinctrl-sunxi.o
+diff --git a/drivers/pinctrl/pinctrl-rt2880.c b/drivers/pinctrl/pinctrl-rt2880.c
+new file mode 100644
+index 0000000..378ed52
+--- /dev/null
++++ b/drivers/pinctrl/pinctrl-rt2880.c
+@@ -0,0 +1,467 @@
++/*
++ *  linux/drivers/pinctrl/pinctrl-rt2880.c
++ *
++ *  This program is free software; you can redistribute it and/or modify
++ *  it under the terms of the GNU General Public License version 2 as
++ *  publishhed by the Free Software Foundation.
++ *
++ *  Copyright (C) 2013 John Crispin <blogic@openwrt.org>
++ */
++
++#include <linux/module.h>
++#include <linux/device.h>
++#include <linux/io.h>
++#include <linux/platform_device.h>
++#include <linux/slab.h>
++#include <linux/of.h>
++#include <linux/pinctrl/pinctrl.h>
++#include <linux/pinctrl/pinconf.h>
++#include <linux/pinctrl/pinmux.h>
++#include <linux/pinctrl/consumer.h>
++#include <linux/pinctrl/machine.h>
++
++#include <asm/mach-ralink/ralink_regs.h>
++#include <asm/mach-ralink/pinmux.h>
++#include <asm/mach-ralink/mt7620.h>
++
++#include "core.h"
++
++#define SYSC_REG_GPIO_MODE    0x60
++
++struct rt2880_priv {
++      struct device *dev;
++
++      struct pinctrl_pin_desc *pads;
++      struct pinctrl_desc *desc;
++
++      struct rt2880_pmx_func **func;
++      int func_count;
++
++      struct rt2880_pmx_group *groups;
++      const char **group_names;
++      int group_count;
++
++      uint8_t *gpio;
++      int max_pins;
++};
++
++struct rt2880_pmx_group *rt2880_pinmux_data = NULL;
++
++static int rt2880_get_group_count(struct pinctrl_dev *pctrldev)
++{
++      struct rt2880_priv *p = pinctrl_dev_get_drvdata(pctrldev);
++
++      return p->group_count;
++}
++
++static const char *rt2880_get_group_name(struct pinctrl_dev *pctrldev,
++                                       unsigned group)
++{
++      struct rt2880_priv *p = pinctrl_dev_get_drvdata(pctrldev);
++
++      if (group >= p->group_count)
++              return NULL;
++
++      return p->group_names[group];
++}
++
++static int rt2880_get_group_pins(struct pinctrl_dev *pctrldev,
++                               unsigned group,
++                               const unsigned **pins,
++                               unsigned *num_pins)
++{
++      struct rt2880_priv *p = pinctrl_dev_get_drvdata(pctrldev);
++
++      if (group >= p->group_count)
++              return -EINVAL;
++
++      *pins = p->groups[group].func[0].pins;
++      *num_pins = p->groups[group].func[0].pin_count;
++
++      return 0;
++}
++
++static void rt2880_pinctrl_dt_free_map(struct pinctrl_dev *pctrldev,
++                                  struct pinctrl_map *map, unsigned num_maps)
++{
++      int i;
++
++      for (i = 0; i < num_maps; i++)
++              if (map[i].type == PIN_MAP_TYPE_CONFIGS_PIN ||
++                  map[i].type == PIN_MAP_TYPE_CONFIGS_GROUP)
++                      kfree(map[i].data.configs.configs);
++      kfree(map);
++}
++
++static void rt2880_pinctrl_pin_dbg_show(struct pinctrl_dev *pctrldev,
++                                      struct seq_file *s,
++                                      unsigned offset)
++{
++      seq_printf(s, "ralink pio");
++}
++
++static void rt2880_pinctrl_dt_subnode_to_map(struct pinctrl_dev *pctrldev,
++                              struct device_node *np,
++                              struct pinctrl_map **map)
++{
++        const char *function;
++      int func = of_property_read_string(np, "ralink,function", &function);
++      int grps = of_property_count_strings(np, "ralink,group");
++      int i;
++
++      if (func || !grps)
++              return;
++
++      for (i = 0; i < grps; i++) {
++              const char *group;
++
++              of_property_read_string_index(np, "ralink,group", i, &group);
++
++              (*map)->type = PIN_MAP_TYPE_MUX_GROUP;
++              (*map)->name = function;
++              (*map)->data.mux.group = group;
++              (*map)->data.mux.function = function;
++              (*map)++;
++      }
++}
++
++static int rt2880_pinctrl_dt_node_to_map(struct pinctrl_dev *pctrldev,
++                              struct device_node *np_config,
++                              struct pinctrl_map **map,
++                              unsigned *num_maps)
++{
++      int max_maps = 0;
++      struct pinctrl_map *tmp;
++      struct device_node *np;
++
++      for_each_child_of_node(np_config, np) {
++              int ret = of_property_count_strings(np, "ralink,group");
++
++              if (ret >= 0)
++                      max_maps += ret;
++      }
++
++      if (!max_maps)
++              return max_maps;
++
++      *map = kzalloc(max_maps * sizeof(struct pinctrl_map), GFP_KERNEL);
++      if (!*map)
++              return -ENOMEM;
++
++      tmp = *map;
++
++      for_each_child_of_node(np_config, np)
++              rt2880_pinctrl_dt_subnode_to_map(pctrldev, np, &tmp);
++      *num_maps = max_maps;
++
++      return 0;
++}
++
++static const struct pinctrl_ops rt2880_pctrl_ops = {
++      .get_groups_count       = rt2880_get_group_count,
++      .get_group_name         = rt2880_get_group_name,
++      .get_group_pins         = rt2880_get_group_pins,
++      .pin_dbg_show           = rt2880_pinctrl_pin_dbg_show,
++      .dt_node_to_map         = rt2880_pinctrl_dt_node_to_map,
++      .dt_free_map            = rt2880_pinctrl_dt_free_map,
++};
++
++static int rt2880_pmx_func_count(struct pinctrl_dev *pctrldev)
++{
++      struct rt2880_priv *p = pinctrl_dev_get_drvdata(pctrldev);
++
++      return p->func_count;
++}
++
++static const char *rt2880_pmx_func_name(struct pinctrl_dev *pctrldev,
++                                       unsigned func)
++{
++      struct rt2880_priv *p = pinctrl_dev_get_drvdata(pctrldev);
++
++      return p->func[func]->name;
++}
++
++static int rt2880_pmx_group_get_groups(struct pinctrl_dev *pctrldev,
++                              unsigned func,
++                              const char * const **groups,
++                              unsigned * const num_groups)
++{
++      struct rt2880_priv *p = pinctrl_dev_get_drvdata(pctrldev);
++
++      if (p->func[func]->group_count == 1)
++              *groups = &p->group_names[p->func[func]->groups[0]];
++      else
++              *groups = p->group_names;
++
++      *num_groups = p->func[func]->group_count;
++
++      return 0;
++}
++
++static int rt2880_pmx_group_enable(struct pinctrl_dev *pctrldev,
++                              unsigned func,
++                              unsigned group)
++{
++      struct rt2880_priv *p = pinctrl_dev_get_drvdata(pctrldev);
++        u32 mode = 0;
++      int i;
++
++      /* dont allow double use */
++      if (p->groups[group].enabled) {
++              dev_err(p->dev, "%s is already enabled\n", p->groups[group].name);
++              return -EBUSY;
++      }
++
++      p->groups[group].enabled = 1;
++      p->func[func]->enabled = 1;
++
++      mode = rt_sysc_r32(SYSC_REG_GPIO_MODE);
++      mode &= ~(p->groups[group].mask << p->groups[group].shift);
++
++      /* mark the pins as gpio */
++      for (i = 0; i < p->groups[group].func[0].pin_count; i++)
++              p->gpio[p->groups[group].func[0].pins[i]] = 1;
++
++      /* function 0 is gpio and needs special handling */
++      if (func == 0) {
++              mode |= p->groups[group].gpio << p->groups[group].shift;
++      } else {
++              for (i = 0; i < p->func[func]->pin_count; i++)
++                      p->gpio[p->func[func]->pins[i]] = 0;
++              mode |= p->func[func]->value << p->groups[group].shift;
++      }
++      rt_sysc_w32(mode, SYSC_REG_GPIO_MODE);
++
++
++      return 0;
++}
++
++static int rt2880_pmx_group_gpio_request_enable(struct pinctrl_dev *pctrldev,
++                              struct pinctrl_gpio_range *range,
++                              unsigned pin)
++{
++      struct rt2880_priv *p = pinctrl_dev_get_drvdata(pctrldev);
++
++      if (!p->gpio[pin]) {
++              dev_err(p->dev, "pin %d is not set to gpio mux\n", pin);
++              return -EINVAL;
++      }
++
++      return 0;
++}
++
++static const struct pinmux_ops rt2880_pmx_group_ops = {
++      .get_functions_count    = rt2880_pmx_func_count,
++      .get_function_name      = rt2880_pmx_func_name,
++      .get_function_groups    = rt2880_pmx_group_get_groups,
++      .enable                 = rt2880_pmx_group_enable,
++      .gpio_request_enable    = rt2880_pmx_group_gpio_request_enable,
++};
++
++static struct pinctrl_desc rt2880_pctrl_desc = {
++      .owner          = THIS_MODULE,
++      .name           = "rt2880-pinmux",
++      .pctlops        = &rt2880_pctrl_ops,
++      .pmxops         = &rt2880_pmx_group_ops,
++};
++
++static struct rt2880_pmx_func gpio_func = {
++      .name = "gpio",
++};
++
++static int rt2880_pinmux_index(struct rt2880_priv *p)
++{
++      struct rt2880_pmx_func **f;
++      struct rt2880_pmx_group *mux = p->groups;
++      int i, j, c = 0;
++
++      /* count the mux functions */
++      while (mux->name) {
++              p->group_count++;
++              mux++;
++      }
++
++      /* allocate the group names array needed by the gpio function */
++      p->group_names = devm_kzalloc(p->dev, sizeof(char *) * p->group_count, GFP_KERNEL);
++      if (!p->group_names)
++              return -1;
++
++      for (i = 0; i < p->group_count; i++) {
++              p->group_names[i] = p->groups[i].name;
++              p->func_count += p->groups[i].func_count;
++      }
++
++      /* we have a dummy function[0] for gpio */
++      p->func_count++;
++
++      /* allocate our function and group mapping index buffers */
++      f = p->func = devm_kzalloc(p->dev, sizeof(struct rt2880_pmx_func) * p->func_count, GFP_KERNEL);
++      gpio_func.groups = devm_kzalloc(p->dev, sizeof(int) * p->group_count, GFP_KERNEL);
++      if (!f || !gpio_func.groups)
++              return -1;
++
++      /* add a backpointer to the function so it knows its group */
++      gpio_func.group_count = p->group_count;
++      for (i = 0; i < gpio_func.group_count; i++)
++              gpio_func.groups[i] = i;
++
++      f[c] = &gpio_func;
++      c++;
++
++      /* add remaining functions */
++      for (i = 0; i < p->group_count; i++) {
++              for (j = 0; j < p->groups[i].func_count; j++) {
++                      f[c] = &p->groups[i].func[j];
++                      f[c]->groups = devm_kzalloc(p->dev, sizeof(int), GFP_KERNEL);
++                      f[c]->groups[0] = i;
++                      f[c]->group_count = 1;
++                      c++;
++              }
++      }
++      return 0;
++}
++
++static int rt2880_pinmux_pins(struct rt2880_priv *p)
++{
++      int i, j;
++
++      /* loop over the functions and initialize the pins array. also work out the highest pin used */
++      for (i = 0; i < p->func_count; i++) {
++              int pin;
++
++              if (!p->func[i]->pin_count)
++                      continue;
++
++              p->func[i]->pins = devm_kzalloc(p->dev, sizeof(int) * p->func[i]->pin_count, GFP_KERNEL);
++              for (j = 0; j < p->func[i]->pin_count; j++)
++                      p->func[i]->pins[j] = p->func[i]->pin_first + j;
++
++              pin = p->func[i]->pin_first + p->func[i]->pin_count;
++              if (pin > p->max_pins)
++                      p->max_pins = pin;
++      }
++
++      /* the buffer that tells us which pins are gpio */
++      p->gpio = devm_kzalloc(p->dev,sizeof(uint8_t) * p->max_pins,
++              GFP_KERNEL);
++      /* the pads needed to tell pinctrl about our pins */
++      p->pads = devm_kzalloc(p->dev,
++              sizeof(struct pinctrl_pin_desc) * p->max_pins,
++              GFP_KERNEL);
++      if (!p->pads || !p->gpio ) {
++              dev_err(p->dev, "Failed to allocate gpio data\n");
++              return -ENOMEM;
++      }
++
++      memset(p->gpio, 1, sizeof(uint8_t) * p->max_pins);
++      for (i = 0; i < p->func_count; i++) {
++              if (!p->func[i]->pin_count)
++                      continue;
++
++              for (j = 0; j < p->func[i]->pin_count; j++)
++                      p->gpio[p->func[i]->pins[j]] = 0;
++      }
++
++      /* pin 0 is always a gpio */
++      p->gpio[0] = 1;
++
++      /* set the pads */
++      for (i = 0; i < p->max_pins; i++) {
++              /* strlen("ioXY") + 1 = 5 */
++              char *name = devm_kzalloc(p->dev, 5, GFP_KERNEL);
++
++              if (!name) {
++                      dev_err(p->dev, "Failed to allocate pad name\n");
++                      return -ENOMEM;
++              }
++              snprintf(name, 5, "io%d", i);
++              p->pads[i].number = i;
++              p->pads[i].name = name;
++      }
++      p->desc->pins = p->pads;
++      p->desc->npins = p->max_pins;
++
++      return 0;
++}
++
++static int rt2880_pinmux_probe(struct platform_device *pdev)
++{
++      struct rt2880_priv *p;
++      struct pinctrl_dev *dev;
++      struct device_node *np;
++
++      if (!rt2880_pinmux_data)
++              return -ENOSYS;
++
++      /* setup the private data */
++      p = devm_kzalloc(&pdev->dev, sizeof(struct rt2880_priv), GFP_KERNEL);
++      if (!p)
++              return -ENOMEM;
++
++      p->dev = &pdev->dev;
++      p->desc = &rt2880_pctrl_desc;
++      p->groups = rt2880_pinmux_data;
++      platform_set_drvdata(pdev, p);
++
++      /* init the device */
++      if (rt2880_pinmux_index(p)) {
++              dev_err(&pdev->dev, "failed to load index\n");
++              return -EINVAL;
++      }
++      if (rt2880_pinmux_pins(p)) {
++              dev_err(&pdev->dev, "failed to load pins\n");
++              return -EINVAL;
++      }
++      dev = pinctrl_register(p->desc, &pdev->dev, p);
++      if (IS_ERR(dev))
++              return PTR_ERR(dev);
++
++      /* finalize by adding gpio ranges for enables gpio controllers */
++      for_each_compatible_node(np, NULL, "ralink,rt2880-gpio") {
++              const __be32 *ngpio, *gpiobase;
++              struct pinctrl_gpio_range *range;
++              char *name;
++
++              if (!of_device_is_available(np))
++                      continue;
++
++              ngpio = of_get_property(np, "ralink,num-gpios", NULL);
++              gpiobase = of_get_property(np, "ralink,gpio-base", NULL);
++              if (!ngpio || !gpiobase) {
++                      dev_err(&pdev->dev, "failed to load chip info\n");
++                      return -EINVAL;
++              }
++
++              range = devm_kzalloc(p->dev, sizeof(struct pinctrl_gpio_range) + 4, GFP_KERNEL);
++              range->name = name = (char *) &range[1];
++              sprintf(name, "pio");
++              range->npins = __be32_to_cpu(*ngpio);
++              range->base = __be32_to_cpu(*gpiobase);
++              range->pin_base = range->base;
++              pinctrl_add_gpio_range(dev, range);
++      }
++
++      return 0;
++}
++
++static const struct of_device_id rt2880_pinmux_match[] = {
++      { .compatible = "ralink,rt2880-pinmux" },
++      {},
++};
++MODULE_DEVICE_TABLE(of, rt2880_pinmux_match);
++
++static struct platform_driver rt2880_pinmux_driver = {
++      .probe = rt2880_pinmux_probe,
++      .driver = {
++              .name = "rt2880-pinmux",
++              .owner = THIS_MODULE,
++              .of_match_table = rt2880_pinmux_match,
++      },
++};
++
++int __init rt2880_pinmux_init(void)
++{
++      return platform_driver_register(&rt2880_pinmux_driver);
++}
++
++core_initcall_sync(rt2880_pinmux_init);
+-- 
+1.7.10.4
+
diff --git a/target/linux/ramips/patches-3.14/0031-PCI-MIPS-adds-rt2880-pci-support.patch b/target/linux/ramips/patches-3.14/0031-PCI-MIPS-adds-rt2880-pci-support.patch
new file mode 100644 (file)
index 0000000..3af4da6
--- /dev/null
@@ -0,0 +1,329 @@
+From 5b0bcc314005dd14eeae190948165a81eef7da1f Mon Sep 17 00:00:00 2001
+From: John Crispin <blogic@openwrt.org>
+Date: Sun, 27 Jul 2014 09:36:02 +0100
+Subject: [PATCH 31/57] PCI: MIPS: adds rt2880 pci support
+
+Add support for the pci found on the rt2880 SoC.
+
+Signed-off-by: John Crispin <blogic@openwrt.org>
+---
+ arch/mips/pci/Makefile     |    1 +
+ arch/mips/pci/pci-rt2880.c |  281 ++++++++++++++++++++++++++++++++++++++++++++
+ arch/mips/ralink/Kconfig   |    1 +
+ 3 files changed, 283 insertions(+)
+ create mode 100644 arch/mips/pci/pci-rt2880.c
+
+diff --git a/arch/mips/pci/Makefile b/arch/mips/pci/Makefile
+index d054bc8..6a0f453 100644
+--- a/arch/mips/pci/Makefile
++++ b/arch/mips/pci/Makefile
+@@ -42,6 +42,7 @@ obj-$(CONFIG_SNI_RM)         += fixup-sni.o ops-sni.o
+ obj-$(CONFIG_LANTIQ)          += fixup-lantiq.o
+ obj-$(CONFIG_PCI_LANTIQ)      += pci-lantiq.o ops-lantiq.o
+ obj-$(CONFIG_SOC_MT7621)      += pci-mt7621.o
++obj-$(CONFIG_SOC_RT2880)      += pci-rt2880.o
+ obj-$(CONFIG_SOC_RT3883)      += pci-rt3883.o
+ obj-$(CONFIG_TANBAC_TB0219)   += fixup-tb0219.o
+ obj-$(CONFIG_TANBAC_TB0226)   += fixup-tb0226.o
+diff --git a/arch/mips/pci/pci-rt2880.c b/arch/mips/pci/pci-rt2880.c
+new file mode 100644
+index 0000000..e2c4730
+--- /dev/null
++++ b/arch/mips/pci/pci-rt2880.c
+@@ -0,0 +1,281 @@
++/*
++ *  Ralink RT288x SoC PCI register definitions
++ *
++ *  Copyright (C) 2009 John Crispin <blogic@openwrt.org>
++ *  Copyright (C) 2009 Gabor Juhos <juhosg@openwrt.org>
++ *
++ *  Parts of this file are based on Ralink's 2.6.21 BSP
++ *
++ *  This program is free software; you can redistribute it and/or modify it
++ *  under the terms of the GNU General Public License version 2 as published
++ *  by the Free Software Foundation.
++ */
++
++#include <linux/types.h>
++#include <linux/pci.h>
++#include <linux/io.h>
++#include <linux/init.h>
++#include <linux/module.h>
++#include <linux/of_platform.h>
++#include <linux/of_irq.h>
++#include <linux/of_pci.h>
++
++#include <asm/mach-ralink/rt288x.h>
++
++#define RT2880_PCI_BASE               0x00440000
++#define RT288X_CPU_IRQ_PCI    4
++
++#define RT2880_PCI_MEM_BASE   0x20000000
++#define RT2880_PCI_MEM_SIZE   0x10000000
++#define RT2880_PCI_IO_BASE    0x00460000
++#define RT2880_PCI_IO_SIZE    0x00010000
++
++#define RT2880_PCI_REG_PCICFG_ADDR    0x00
++#define RT2880_PCI_REG_PCIMSK_ADDR    0x0c
++#define RT2880_PCI_REG_BAR0SETUP_ADDR 0x10
++#define RT2880_PCI_REG_IMBASEBAR0_ADDR        0x18
++#define RT2880_PCI_REG_CONFIG_ADDR    0x20
++#define RT2880_PCI_REG_CONFIG_DATA    0x24
++#define RT2880_PCI_REG_MEMBASE                0x28
++#define RT2880_PCI_REG_IOBASE         0x2c
++#define RT2880_PCI_REG_ID             0x30
++#define RT2880_PCI_REG_CLASS          0x34
++#define RT2880_PCI_REG_SUBID          0x38
++#define RT2880_PCI_REG_ARBCTL         0x80
++
++static void __iomem *rt2880_pci_base;
++static DEFINE_SPINLOCK(rt2880_pci_lock);
++
++static u32 rt2880_pci_reg_read(u32 reg)
++{
++      return readl(rt2880_pci_base + reg);
++}
++
++static void rt2880_pci_reg_write(u32 val, u32 reg)
++{
++      writel(val, rt2880_pci_base + reg);
++}
++
++static inline u32 rt2880_pci_get_cfgaddr(unsigned int bus, unsigned int slot,
++                                       unsigned int func, unsigned int where)
++{
++      return ((bus << 16) | (slot << 11) | (func << 8) | (where & 0xfc) |
++              0x80000000);
++}
++
++static int rt2880_pci_config_read(struct pci_bus *bus, unsigned int devfn,
++                                int where, int size, u32 *val)
++{
++      unsigned long flags;
++      u32 address;
++      u32 data;
++
++      address = rt2880_pci_get_cfgaddr(bus->number, PCI_SLOT(devfn),
++                                       PCI_FUNC(devfn), where);
++
++      spin_lock_irqsave(&rt2880_pci_lock, flags);
++      rt2880_pci_reg_write(address, RT2880_PCI_REG_CONFIG_ADDR);
++      data = rt2880_pci_reg_read(RT2880_PCI_REG_CONFIG_DATA);
++      spin_unlock_irqrestore(&rt2880_pci_lock, flags);
++
++      switch (size) {
++      case 1:
++              *val = (data >> ((where & 3) << 3)) & 0xff;
++              break;
++      case 2:
++              *val = (data >> ((where & 3) << 3)) & 0xffff;
++              break;
++      case 4:
++              *val = data;
++              break;
++      }
++
++      return PCIBIOS_SUCCESSFUL;
++}
++
++static int rt2880_pci_config_write(struct pci_bus *bus, unsigned int devfn,
++                                 int where, int size, u32 val)
++{
++      unsigned long flags;
++      u32 address;
++      u32 data;
++
++      address = rt2880_pci_get_cfgaddr(bus->number, PCI_SLOT(devfn),
++                                       PCI_FUNC(devfn), where);
++
++      spin_lock_irqsave(&rt2880_pci_lock, flags);
++      rt2880_pci_reg_write(address, RT2880_PCI_REG_CONFIG_ADDR);
++      data = rt2880_pci_reg_read(RT2880_PCI_REG_CONFIG_DATA);
++
++      switch (size) {
++      case 1:
++              data = (data & ~(0xff << ((where & 3) << 3))) |
++                     (val << ((where & 3) << 3));
++              break;
++      case 2:
++              data = (data & ~(0xffff << ((where & 3) << 3))) |
++                     (val << ((where & 3) << 3));
++              break;
++      case 4:
++              data = val;
++              break;
++      }
++
++      rt2880_pci_reg_write(data, RT2880_PCI_REG_CONFIG_DATA);
++      spin_unlock_irqrestore(&rt2880_pci_lock, flags);
++
++      return PCIBIOS_SUCCESSFUL;
++}
++
++static struct pci_ops rt2880_pci_ops = {
++      .read   = rt2880_pci_config_read,
++      .write  = rt2880_pci_config_write,
++};
++
++static struct resource rt2880_pci_mem_resource = {
++      .name   = "PCI MEM space",
++      .start  = RT2880_PCI_MEM_BASE,
++      .end    = RT2880_PCI_MEM_BASE + RT2880_PCI_MEM_SIZE - 1,
++      .flags  = IORESOURCE_MEM,
++};
++
++static struct resource rt2880_pci_io_resource = {
++      .name   = "PCI IO space",
++      .start  = RT2880_PCI_IO_BASE,
++      .end    = RT2880_PCI_IO_BASE + RT2880_PCI_IO_SIZE - 1,
++      .flags  = IORESOURCE_IO,
++};
++
++static struct pci_controller rt2880_pci_controller = {
++      .pci_ops        = &rt2880_pci_ops,
++      .mem_resource   = &rt2880_pci_mem_resource,
++      .io_resource    = &rt2880_pci_io_resource,
++};
++
++static inline u32 rt2880_pci_read_u32(unsigned long reg)
++{
++      unsigned long flags;
++      u32 address;
++      u32 ret;
++
++      address = rt2880_pci_get_cfgaddr(0, 0, 0, reg);
++
++      spin_lock_irqsave(&rt2880_pci_lock, flags);
++      rt2880_pci_reg_write(address, RT2880_PCI_REG_CONFIG_ADDR);
++      ret = rt2880_pci_reg_read(RT2880_PCI_REG_CONFIG_DATA);
++      spin_unlock_irqrestore(&rt2880_pci_lock, flags);
++
++      return ret;
++}
++
++static inline void rt2880_pci_write_u32(unsigned long reg, u32 val)
++{
++      unsigned long flags;
++      u32 address;
++
++      address = rt2880_pci_get_cfgaddr(0, 0, 0, reg);
++
++      spin_lock_irqsave(&rt2880_pci_lock, flags);
++      rt2880_pci_reg_write(address, RT2880_PCI_REG_CONFIG_ADDR);
++      rt2880_pci_reg_write(val, RT2880_PCI_REG_CONFIG_DATA);
++      spin_unlock_irqrestore(&rt2880_pci_lock, flags);
++}
++
++int __init pcibios_map_irq(const struct pci_dev *dev, u8 slot, u8 pin)
++{
++      u16 cmd;
++      int irq = -1;
++
++      if (dev->bus->number != 0)
++              return irq;
++
++      switch (PCI_SLOT(dev->devfn)) {
++      case 0x00:
++              rt2880_pci_write_u32(PCI_BASE_ADDRESS_0, 0x08000000);
++              (void) rt2880_pci_read_u32(PCI_BASE_ADDRESS_0);
++              break;
++      case 0x11:
++              irq = RT288X_CPU_IRQ_PCI;
++              break;
++      default:
++              printk("%s:%s[%d] trying to alloc unknown pci irq\n",
++                     __FILE__, __func__, __LINE__);
++              BUG();
++              break;
++      }
++
++      pci_write_config_byte((struct pci_dev*)dev, PCI_CACHE_LINE_SIZE, 0x14);
++      pci_write_config_byte((struct pci_dev*)dev, PCI_LATENCY_TIMER, 0xFF);
++      pci_read_config_word((struct pci_dev*)dev, PCI_COMMAND, &cmd);
++      cmd |= PCI_COMMAND_MASTER | PCI_COMMAND_IO | PCI_COMMAND_MEMORY |
++             PCI_COMMAND_INVALIDATE | PCI_COMMAND_FAST_BACK |
++             PCI_COMMAND_SERR | PCI_COMMAND_WAIT | PCI_COMMAND_PARITY;
++      pci_write_config_word((struct pci_dev*)dev, PCI_COMMAND, cmd);
++      pci_write_config_byte((struct pci_dev*)dev, PCI_INTERRUPT_LINE,
++                            dev->irq);
++      return irq;
++}
++
++static int rt288x_pci_probe(struct platform_device *pdev)
++{
++      void __iomem *io_map_base;
++      int i;
++
++      rt2880_pci_base = ioremap_nocache(RT2880_PCI_BASE, PAGE_SIZE);
++
++      io_map_base = ioremap(RT2880_PCI_IO_BASE, RT2880_PCI_IO_SIZE);
++      rt2880_pci_controller.io_map_base = (unsigned long) io_map_base;
++      set_io_port_base((unsigned long) io_map_base);
++
++      ioport_resource.start = RT2880_PCI_IO_BASE;
++      ioport_resource.end = RT2880_PCI_IO_BASE + RT2880_PCI_IO_SIZE - 1;
++
++      rt2880_pci_reg_write(0, RT2880_PCI_REG_PCICFG_ADDR);
++      for(i = 0; i < 0xfffff; i++) {}
++
++      rt2880_pci_reg_write(0x79, RT2880_PCI_REG_ARBCTL);
++      rt2880_pci_reg_write(0x07FF0001, RT2880_PCI_REG_BAR0SETUP_ADDR);
++      rt2880_pci_reg_write(RT2880_PCI_MEM_BASE, RT2880_PCI_REG_MEMBASE);
++      rt2880_pci_reg_write(RT2880_PCI_IO_BASE, RT2880_PCI_REG_IOBASE);
++      rt2880_pci_reg_write(0x08000000, RT2880_PCI_REG_IMBASEBAR0_ADDR);
++      rt2880_pci_reg_write(0x08021814, RT2880_PCI_REG_ID);
++      rt2880_pci_reg_write(0x00800001, RT2880_PCI_REG_CLASS);
++      rt2880_pci_reg_write(0x28801814, RT2880_PCI_REG_SUBID);
++      rt2880_pci_reg_write(0x000c0000, RT2880_PCI_REG_PCIMSK_ADDR);
++
++      rt2880_pci_write_u32(PCI_BASE_ADDRESS_0, 0x08000000);
++      (void) rt2880_pci_read_u32(PCI_BASE_ADDRESS_0);
++
++      register_pci_controller(&rt2880_pci_controller);
++      return 0;
++}
++
++int pcibios_plat_dev_init(struct pci_dev *dev)
++{
++      return 0;
++}
++
++static const struct of_device_id rt288x_pci_match[] = {
++      { .compatible = "ralink,rt288x-pci" },
++      {},
++};
++MODULE_DEVICE_TABLE(of, rt288x_pci_match);
++
++static struct platform_driver rt288x_pci_driver = {
++      .probe = rt288x_pci_probe,
++      .driver = {
++              .name = "rt288x-pci",
++              .owner = THIS_MODULE,
++              .of_match_table = rt288x_pci_match,
++      },
++};
++
++int __init pcibios_init(void)
++{
++      int ret = platform_driver_register(&rt288x_pci_driver);
++      if (ret)
++              pr_info("rt288x-pci: Error registering platform driver!");
++      return ret;
++}
++
++arch_initcall(pcibios_init);
+diff --git a/arch/mips/ralink/Kconfig b/arch/mips/ralink/Kconfig
+index f93835f..eb2b2cd 100644
+--- a/arch/mips/ralink/Kconfig
++++ b/arch/mips/ralink/Kconfig
+@@ -21,6 +21,7 @@ choice
+       config SOC_RT288X
+               bool "RT288x"
+               select MIPS_L1_CACHE_SHIFT_4
++              select HW_HAS_PCI
+       config SOC_RT305X
+               bool "RT305x"
+-- 
+1.7.10.4
+
diff --git a/target/linux/ramips/patches-3.14/0032-PCI-MIPS-adds-mt7620a-pcie-driver.patch b/target/linux/ramips/patches-3.14/0032-PCI-MIPS-adds-mt7620a-pcie-driver.patch
new file mode 100644 (file)
index 0000000..48dae70
--- /dev/null
@@ -0,0 +1,409 @@
+From 307b7a71a634ae3848fb7c5c05759d647e140e12 Mon Sep 17 00:00:00 2001
+From: John Crispin <blogic@openwrt.org>
+Date: Sat, 18 May 2013 22:06:15 +0200
+Subject: [PATCH 32/57] PCI: MIPS: adds mt7620a pcie driver
+
+Signed-off-by: John Crispin <blogic@openwrt.org>
+---
+ arch/mips/pci/Makefile      |    1 +
+ arch/mips/pci/pci-mt7620a.c |  363 +++++++++++++++++++++++++++++++++++++++++++
+ arch/mips/ralink/Kconfig    |    1 +
+ 3 files changed, 365 insertions(+)
+ create mode 100644 arch/mips/pci/pci-mt7620a.c
+
+diff --git a/arch/mips/pci/Makefile b/arch/mips/pci/Makefile
+index 6a0f453..b140299 100644
+--- a/arch/mips/pci/Makefile
++++ b/arch/mips/pci/Makefile
+@@ -42,6 +42,7 @@ obj-$(CONFIG_SNI_RM)         += fixup-sni.o ops-sni.o
+ obj-$(CONFIG_LANTIQ)          += fixup-lantiq.o
+ obj-$(CONFIG_PCI_LANTIQ)      += pci-lantiq.o ops-lantiq.o
+ obj-$(CONFIG_SOC_MT7621)      += pci-mt7621.o
++obj-$(CONFIG_SOC_MT7620)      += pci-mt7620a.o
+ obj-$(CONFIG_SOC_RT2880)      += pci-rt2880.o
+ obj-$(CONFIG_SOC_RT3883)      += pci-rt3883.o
+ obj-$(CONFIG_TANBAC_TB0219)   += fixup-tb0219.o
+diff --git a/arch/mips/pci/pci-mt7620a.c b/arch/mips/pci/pci-mt7620a.c
+new file mode 100644
+index 0000000..271763c
+--- /dev/null
++++ b/arch/mips/pci/pci-mt7620a.c
+@@ -0,0 +1,363 @@
++/*
++ *  Ralink MT7620A SoC PCI support
++ *
++ *  Copyright (C) 2007-2013 Bruce Chang
++ *  Copyright (C) 2013 John Crispin <blogic@openwrt.org>
++ *
++ *  This program is free software; you can redistribute it and/or modify it
++ *  under the terms of the GNU General Public License version 2 as published
++ *  by the Free Software Foundation.
++ */
++
++#include <linux/types.h>
++#include <linux/pci.h>
++#include <linux/io.h>
++#include <linux/init.h>
++#include <linux/delay.h>
++#include <linux/interrupt.h>
++#include <linux/module.h>
++#include <linux/of.h>
++#include <linux/of_irq.h>
++#include <linux/of_pci.h>
++#include <linux/reset.h>
++#include <linux/platform_device.h>
++
++#include <asm/mach-ralink/ralink_regs.h>
++
++#define RALINK_PCI_MM_MAP_BASE                0x20000000
++#define RALINK_PCI_IO_MAP_BASE                0x10160000
++
++#define RALINK_INT_PCIE0              4
++#define RALINK_SYSTEM_CONTROL_BASE    0xb0000000
++#define RALINK_SYSCFG1                        0x14
++#define RALINK_CLKCFG1                        0x30
++#define RALINK_GPIOMODE                       0x60
++#define RALINK_PCIE_CLK_GEN           0x7c
++#define RALINK_PCIE_CLK_GEN1          0x80
++#define PCIEPHY0_CFG                  0x90
++#define PPLL_CFG1                     0x9c
++#define PPLL_DRV                      0xa0
++#define RALINK_PCI_HOST_MODE_EN               (1<<7)
++#define RALINK_PCIE_RC_MODE_EN                (1<<8)
++#define RALINK_PCIE_RST                       (1<<23)
++#define RALINK_PCI_RST                        (1<<24)
++#define RALINK_PCI_CLK_EN             (1<<19)
++#define RALINK_PCIE_CLK_EN            (1<<21)
++#define PCI_SLOTx2                    (1<<11)
++#define PCI_SLOTx1                    (2<<11)
++#define PDRV_SW_SET                   (1<<31)
++#define LC_CKDRVPD_                   (1<<19)
++
++#define RALINK_PCI_CONFIG_ADDR                0x20
++#define RALINK_PCI_CONFIG_DATA_VIRTUAL_REG    0x24
++#define MEMORY_BASE                   0x0
++#define RALINK_PCIE0_RST              (1<<26)
++#define RALINK_PCI_BASE                       0xB0140000
++#define RALINK_PCI_MEMBASE            0x28
++#define RALINK_PCI_IOBASE             0x2C
++
++#define RT6855_PCIE0_OFFSET           0x2000
++
++#define RALINK_PCI_PCICFG_ADDR                0x00
++#define RALINK_PCI0_BAR0SETUP_ADDR    0x10
++#define RALINK_PCI0_IMBASEBAR0_ADDR   0x18
++#define RALINK_PCI0_ID                        0x30
++#define RALINK_PCI0_CLASS             0x34
++#define RALINK_PCI0_SUBID             0x38
++#define RALINK_PCI0_STATUS            0x50
++#define RALINK_PCI_PCIMSK_ADDR                0x0C
++
++#define RALINK_PCIE0_CLK_EN           (1 << 26)
++
++#define BUSY                          0x80000000
++#define WAITRETRY_MAX                 10
++#define WRITE_MODE                    (1UL << 23)
++#define DATA_SHIFT                    0
++#define ADDR_SHIFT                    8
++
++
++static void __iomem *bridge_base;
++static void __iomem *pcie_base;
++
++static struct reset_control *rstpcie0;
++
++static inline void bridge_w32(u32 val, unsigned reg)
++{
++      iowrite32(val, bridge_base + reg);
++}
++
++static inline u32 bridge_r32(unsigned reg)
++{
++      return ioread32(bridge_base + reg);
++}
++
++static inline void pcie_w32(u32 val, unsigned reg)
++{
++      iowrite32(val, pcie_base + reg);
++}
++
++static inline u32 pcie_r32(unsigned reg)
++{
++      return ioread32(pcie_base + reg);
++}
++
++static inline void pcie_m32(u32 clr, u32 set, unsigned reg)
++{
++      u32 val = pcie_r32(reg);
++      val &= ~clr;
++      val |= set;
++      pcie_w32(val, reg);
++}
++
++int wait_pciephy_busy(void)
++{
++      unsigned long reg_value = 0x0, retry = 0;
++
++      while (1) {
++              //reg_value = rareg(READMODE, PCIEPHY0_CFG, 0);
++              reg_value = pcie_r32(PCIEPHY0_CFG);
++
++              if (reg_value & BUSY)
++                      mdelay(100);
++              else
++                      break;
++              if (retry++ > WAITRETRY_MAX){
++                      printk("PCIE-PHY retry failed.\n");
++                      return -1;
++              }
++      }
++      return 0;
++}
++
++static void pcie_phy(unsigned long addr, unsigned long val)
++{
++      wait_pciephy_busy();
++      pcie_w32(WRITE_MODE | (val << DATA_SHIFT) | (addr << ADDR_SHIFT), PCIEPHY0_CFG);
++      mdelay(1);
++      wait_pciephy_busy();
++}
++
++static int pci_config_read(struct pci_bus *bus, unsigned int devfn, int where, int size, u32 * val)
++{
++      unsigned int slot = PCI_SLOT(devfn);
++      u8 func = PCI_FUNC(devfn);
++      u32 address;
++      u32 data;
++
++      address = (((where & 0xF00) >> 8) << 24) | (bus->number << 16) | (slot << 11) | (func << 8) | (where & 0xfc) | 0x80000000;
++      bridge_w32(address, RALINK_PCI_CONFIG_ADDR);
++      data = bridge_r32(RALINK_PCI_CONFIG_DATA_VIRTUAL_REG);
++
++      switch (size) {
++      case 1:
++              *val = (data >> ((where & 3) << 3)) & 0xff;
++              break;
++      case 2:
++              *val = (data >> ((where & 3) << 3)) & 0xffff;
++              break;
++      case 4:
++              *val = data;
++              break;
++      }
++
++      return PCIBIOS_SUCCESSFUL;
++}
++
++static int pci_config_write(struct pci_bus *bus, unsigned int devfn, int where, int size, u32 val)
++{
++      unsigned int slot = PCI_SLOT(devfn);
++      u8 func = PCI_FUNC(devfn);
++      u32 address;
++      u32 data;
++
++      address = (((where & 0xF00) >> 8) << 24) | (bus->number << 16) | (slot << 11) | (func << 8) | (where & 0xfc) | 0x80000000;
++      bridge_w32(address, RALINK_PCI_CONFIG_ADDR);
++      data = bridge_r32(RALINK_PCI_CONFIG_DATA_VIRTUAL_REG);
++
++      switch (size) {
++      case 1:
++              data = (data & ~(0xff << ((where & 3) << 3))) |
++                      (val << ((where & 3) << 3));
++              break;
++      case 2:
++              data = (data & ~(0xffff << ((where & 3) << 3))) |
++                      (val << ((where & 3) << 3));
++              break;
++      case 4:
++              data = val;
++              break;
++      }
++
++      bridge_w32(data, RALINK_PCI_CONFIG_DATA_VIRTUAL_REG);
++
++      return PCIBIOS_SUCCESSFUL;
++}
++
++struct pci_ops mt7620a_pci_ops= {
++      .read   = pci_config_read,
++      .write  = pci_config_write,
++};
++
++static struct resource mt7620a_res_pci_mem1 = {
++      .name   = "pci memory",
++      .start  = RALINK_PCI_MM_MAP_BASE,
++      .end    = (u32) ((RALINK_PCI_MM_MAP_BASE + (unsigned char *)0x0fffffff)),
++      .flags  = IORESOURCE_MEM,
++};
++static struct resource mt7620a_res_pci_io1 = {
++      .name   = "pci io",
++      .start  = RALINK_PCI_IO_MAP_BASE,
++      .end    = (u32) ((RALINK_PCI_IO_MAP_BASE + (unsigned char *)0x0ffff)),
++      .flags  = IORESOURCE_IO,
++};
++
++struct pci_controller mt7620a_controller = {
++      .pci_ops        = &mt7620a_pci_ops,
++      .mem_resource   = &mt7620a_res_pci_mem1,
++      .io_resource    = &mt7620a_res_pci_io1,
++      .mem_offset     = 0x00000000UL,
++      .io_offset      = 0x00000000UL,
++      .io_map_base    = 0xa0000000,
++};
++
++static int mt7620a_pci_probe(struct platform_device *pdev)
++{
++      struct resource *bridge_res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
++      struct resource *pcie_res = platform_get_resource(pdev, IORESOURCE_MEM, 1);
++
++      rstpcie0 = devm_reset_control_get(&pdev->dev, "pcie0");
++      if (IS_ERR(rstpcie0))
++              return PTR_ERR(rstpcie0);
++
++      bridge_base = devm_request_and_ioremap(&pdev->dev, bridge_res);
++        if (!bridge_base)
++              return -ENOMEM;
++
++      pcie_base = devm_request_and_ioremap(&pdev->dev, pcie_res);
++        if (!pcie_base)
++              return -ENOMEM;
++
++      iomem_resource.start = 0;
++      iomem_resource.end= ~0;
++      ioport_resource.start= 0;
++      ioport_resource.end = ~0;
++
++      /* PCIE: bypass PCIe DLL */
++      pcie_phy(0x0, 0x80);
++      pcie_phy(0x1, 0x04);
++      /* PCIE: Elastic buffer control */
++      pcie_phy(0x68, 0xB4);
++
++      reset_control_assert(rstpcie0);
++      rt_sysc_m32(RALINK_PCIE0_CLK_EN, 0, RALINK_CLKCFG1);
++      rt_sysc_m32(1<<19, 1<<31, PPLL_DRV);
++      rt_sysc_m32(0x3 << 16, 0, RALINK_GPIOMODE);
++
++      reset_control_deassert(rstpcie0);
++      rt_sysc_m32(0, RALINK_PCIE0_CLK_EN, RALINK_CLKCFG1);
++
++      mdelay(100);
++
++      if (!(rt_sysc_r32(PPLL_CFG1) & 1<<23)) {
++              printk("MT7620 PPLL unlock\n");
++              reset_control_assert(rstpcie0);
++              rt_sysc_m32(BIT(26), 0, RALINK_CLKCFG1);
++              return 0;
++      }
++      rt_sysc_m32((0x1<<18) | (0x1<<17), (0x1 << 19) | (0x1 << 31), PPLL_DRV);
++
++      mdelay(100);
++      reset_control_assert(rstpcie0);
++      rt_sysc_m32(0x30, 2 << 4, RALINK_SYSCFG1);
++
++      rt_sysc_m32(~0x7fffffff, 0x80000000, RALINK_PCIE_CLK_GEN);
++      rt_sysc_m32(~0x80ffffff, 0xa << 24, RALINK_PCIE_CLK_GEN1);
++
++      mdelay(50);
++      reset_control_deassert(rstpcie0);
++      pcie_m32(BIT(1), 0, RALINK_PCI_PCICFG_ADDR);
++      mdelay(100);
++
++      if (( pcie_r32(RALINK_PCI0_STATUS) & 0x1) == 0) {
++              reset_control_assert(rstpcie0);
++              rt_sysc_m32(RALINK_PCIE0_CLK_EN, 0, RALINK_CLKCFG1);
++              rt_sysc_m32(LC_CKDRVPD_, PDRV_SW_SET, PPLL_DRV);
++              printk("PCIE0 no card, disable it(RST&CLK)\n");
++      }
++
++      bridge_w32(0xffffffff, RALINK_PCI_MEMBASE);
++      bridge_w32(RALINK_PCI_IO_MAP_BASE, RALINK_PCI_IOBASE);
++
++      pcie_w32(0x7FFF0000, RALINK_PCI0_BAR0SETUP_ADDR);
++      pcie_w32(MEMORY_BASE, RALINK_PCI0_IMBASEBAR0_ADDR);
++      pcie_w32(0x08021814, RALINK_PCI0_ID);
++      pcie_w32(0x06040001, RALINK_PCI0_CLASS);
++      pcie_w32(0x28801814, RALINK_PCI0_SUBID);
++      pcie_m32(0, BIT(20), RALINK_PCI_PCIMSK_ADDR);
++
++      register_pci_controller(&mt7620a_controller);
++
++      return 0;
++}
++
++int __init pcibios_map_irq(const struct pci_dev *dev, u8 slot, u8 pin)
++{
++      const struct resource *res;
++      u16 cmd;
++      u32 val;
++      int i, irq = 0;
++
++      if ((dev->bus->number == 0) && (slot == 0)) {
++              pcie_w32(0x7FFF0001, RALINK_PCI0_BAR0SETUP_ADDR); //open 7FFF:2G; ENABLE
++              pci_config_write(dev->bus, 0, PCI_BASE_ADDRESS_0, 4, MEMORY_BASE);
++              pci_config_read(dev->bus, 0, PCI_BASE_ADDRESS_0, 4, &val);
++      } else if ((dev->bus->number == 1) && (slot == 0x0)) {
++              irq = RALINK_INT_PCIE0;
++      } else {
++              printk("bus=0x%x, slot = 0x%x\n", dev->bus->number, slot);
++              return 0;
++      }
++
++      for (i = 0; i < 6; i++) {
++              res = &dev->resource[i];
++      }
++
++      pci_write_config_byte(dev, PCI_CACHE_LINE_SIZE, 0x14);  //configure cache line size 0x14
++      pci_write_config_byte(dev, PCI_LATENCY_TIMER, 0xFF);  //configure latency timer 0x10
++      pci_read_config_word(dev, PCI_COMMAND, &cmd);
++
++      // FIXME
++      cmd = cmd | PCI_COMMAND_MASTER | PCI_COMMAND_IO | PCI_COMMAND_MEMORY;
++      pci_write_config_word(dev, PCI_COMMAND, cmd);
++      pci_write_config_byte(dev, PCI_INTERRUPT_LINE, dev->irq);
++      //pci_write_config_byte(dev, PCI_INTERRUPT_PIN, dev->irq);
++
++      return irq;
++}
++
++int pcibios_plat_dev_init(struct pci_dev *dev)
++{
++      return 0;
++}
++
++static const struct of_device_id mt7620a_pci_ids[] = {
++      { .compatible = "ralink,mt7620a-pci" },
++      {},
++};
++MODULE_DEVICE_TABLE(of, mt7620a_pci_ids);
++
++static struct platform_driver mt7620a_pci_driver = {
++      .probe = mt7620a_pci_probe,
++      .driver = {
++              .name = "mt7620a-pci",
++              .owner = THIS_MODULE,
++              .of_match_table = of_match_ptr(mt7620a_pci_ids),
++      },
++};
++
++static int __init mt7620a_pci_init(void)
++{
++      return platform_driver_register(&mt7620a_pci_driver);
++}
++
++arch_initcall(mt7620a_pci_init);
+diff --git a/arch/mips/ralink/Kconfig b/arch/mips/ralink/Kconfig
+index eb2b2cd..ce84aad 100644
+--- a/arch/mips/ralink/Kconfig
++++ b/arch/mips/ralink/Kconfig
+@@ -39,6 +39,7 @@ choice
+               bool "MT7620/8"
+               select USB_ARCH_HAS_OHCI
+               select USB_ARCH_HAS_EHCI
++              select HW_HAS_PCI
+       config SOC_MT7621
+               bool "MT7621"
+-- 
+1.7.10.4
+
diff --git a/target/linux/ramips/patches-3.14/0033-NET-multi-phy-support.patch b/target/linux/ramips/patches-3.14/0033-NET-multi-phy-support.patch
new file mode 100644 (file)
index 0000000..99dd092
--- /dev/null
@@ -0,0 +1,60 @@
+From 9c34372c25519234add1cfdfe2b69c0847f2037e Mon Sep 17 00:00:00 2001
+From: John Crispin <blogic@openwrt.org>
+Date: Sun, 27 Jul 2014 09:38:50 +0100
+Subject: [PATCH 33/57] NET: multi phy support
+
+Signed-off-by: John Crispin <blogic@openwrt.org>
+---
+ drivers/net/phy/phy.c |    9 ++++++---
+ include/linux/phy.h   |    1 +
+ 2 files changed, 7 insertions(+), 3 deletions(-)
+
+diff --git a/drivers/net/phy/phy.c b/drivers/net/phy/phy.c
+index 76d96b9..371f0b6 100644
+--- a/drivers/net/phy/phy.c
++++ b/drivers/net/phy/phy.c
+@@ -715,7 +715,8 @@ void phy_state_machine(struct work_struct *work)
+               /* If the link is down, give up on negotiation for now */
+               if (!phydev->link) {
+                       phydev->state = PHY_NOLINK;
+-                      netif_carrier_off(phydev->attached_dev);
++                      if (!phydev->no_auto_carrier_off)
++                              netif_carrier_off(phydev->attached_dev);
+                       phydev->adjust_link(phydev->attached_dev);
+                       break;
+               }
+@@ -781,7 +782,8 @@ void phy_state_machine(struct work_struct *work)
+                       netif_carrier_on(phydev->attached_dev);
+               } else {
+                       phydev->state = PHY_NOLINK;
+-                      netif_carrier_off(phydev->attached_dev);
++                      if (!phydev->no_auto_carrier_off)
++                              netif_carrier_off(phydev->attached_dev);
+               }
+               phydev->adjust_link(phydev->attached_dev);
+@@ -793,7 +795,8 @@ void phy_state_machine(struct work_struct *work)
+       case PHY_HALTED:
+               if (phydev->link) {
+                       phydev->link = 0;
+-                      netif_carrier_off(phydev->attached_dev);
++                      if (!phydev->no_auto_carrier_off)
++                              netif_carrier_off(phydev->attached_dev);
+                       phydev->adjust_link(phydev->attached_dev);
+                       do_suspend = 1;
+               }
+diff --git a/include/linux/phy.h b/include/linux/phy.h
+index 565188c..91b93f7 100644
+--- a/include/linux/phy.h
++++ b/include/linux/phy.h
+@@ -308,6 +308,7 @@ struct phy_device {
+       struct phy_c45_device_ids c45_ids;
+       bool is_c45;
+       bool is_internal;
++      bool no_auto_carrier_off;
+       enum phy_state state;
+-- 
+1.7.10.4
+
diff --git a/target/linux/ramips/patches-3.14/0034-NET-add-of_get_mac_address_mtd.patch b/target/linux/ramips/patches-3.14/0034-NET-add-of_get_mac_address_mtd.patch
new file mode 100644 (file)
index 0000000..0934ac2
--- /dev/null
@@ -0,0 +1,83 @@
+From 92f38460229a8816404408f036f0a374f1013d0e Mon Sep 17 00:00:00 2001
+From: John Crispin <blogic@openwrt.org>
+Date: Sun, 27 Jul 2014 09:40:01 +0100
+Subject: [PATCH 34/57] NET: add of_get_mac_address_mtd()
+
+Many embedded devices have information such as mac addresses stored inside mtd
+devices. This patch allows us to add a property inside a node describing a
+network interface. The new property points at a mtd partition with an offset
+where the mac address can be found.
+
+Signed-off-by: John Crispin <blogic@openwrt.org>
+---
+ drivers/of/of_net.c    |   37 +++++++++++++++++++++++++++++++++++++
+ include/linux/of_net.h |    1 +
+ 2 files changed, 38 insertions(+)
+
+diff --git a/drivers/of/of_net.c b/drivers/of/of_net.c
+index a208a45..de93111 100644
+--- a/drivers/of/of_net.c
++++ b/drivers/of/of_net.c
+@@ -10,6 +10,7 @@
+ #include <linux/of_net.h>
+ #include <linux/phy.h>
+ #include <linux/export.h>
++#include <linux/mtd/mtd.h>
+ /**
+  * It maps 'enum phy_interface_t' found in include/linux/phy.h
+@@ -94,3 +95,39 @@ const void *of_get_mac_address(struct device_node *np)
+       return NULL;
+ }
+ EXPORT_SYMBOL(of_get_mac_address);
++
++int of_get_mac_address_mtd(struct device_node *np, void *mac)
++{
++      struct device_node *mtd_np = NULL;
++      size_t retlen;
++      int size, ret;
++      struct mtd_info *mtd;
++      const char *part;
++      const __be32 *list;
++      phandle phandle;
++
++      list = of_get_property(np, "mtd-mac-address", &size);
++      if (!list || (size != (2 * sizeof(*list))))
++              return -ENOENT;
++
++      phandle = be32_to_cpup(list++);
++      if (phandle)
++              mtd_np = of_find_node_by_phandle(phandle);
++
++      if (!mtd_np)
++              return -ENOENT;
++
++      part = of_get_property(mtd_np, "label", NULL);
++      if (!part)
++              part = mtd_np->name;
++
++      mtd = get_mtd_device_nm(part);
++      if (IS_ERR(mtd))
++              return PTR_ERR(mtd);
++
++      ret = mtd_read(mtd, be32_to_cpup(list), 6, &retlen, (u_char *) mac);
++      put_mtd_device(mtd);
++
++      return ret;
++}
++EXPORT_SYMBOL_GPL(of_get_mac_address_mtd);
+diff --git a/include/linux/of_net.h b/include/linux/of_net.h
+index 34597c8..cdfbc60 100644
+--- a/include/linux/of_net.h
++++ b/include/linux/of_net.h
+@@ -11,6 +11,7 @@
+ #include <linux/of.h>
+ extern int of_get_phy_mode(struct device_node *np);
+ extern const void *of_get_mac_address(struct device_node *np);
++extern int of_get_mac_address_mtd(struct device_node *np, void *mac);
+ #else
+ static inline int of_get_phy_mode(struct device_node *np)
+ {
+-- 
+1.7.10.4
+
diff --git a/target/linux/ramips/patches-3.14/0035-NET-MIPS-add-ralink-SoC-ethernet-driver.patch b/target/linux/ramips/patches-3.14/0035-NET-MIPS-add-ralink-SoC-ethernet-driver.patch
new file mode 100644 (file)
index 0000000..6a7c0c2
--- /dev/null
@@ -0,0 +1,5128 @@
+From c55d6cf3e2c593bf7d228c6532ec9bd8da82e09d Mon Sep 17 00:00:00 2001
+From: John Crispin <blogic@openwrt.org>
+Date: Mon, 22 Apr 2013 23:20:03 +0200
+Subject: [PATCH 35/57] NET: MIPS: add ralink SoC ethernet driver
+
+Add support for Ralink FE and ESW.
+
+Signed-off-by: John Crispin <blogic@openwrt.org>
+---
+ .../include/asm/mach-ralink/rt305x_esw_platform.h  |   27 +
+ arch/mips/ralink/rt305x.c                          |    1 +
+ drivers/net/ethernet/Kconfig                       |    1 +
+ drivers/net/ethernet/Makefile                      |    1 +
+ drivers/net/ethernet/ralink/Kconfig                |   32 +
+ drivers/net/ethernet/ralink/Makefile               |   18 +
+ drivers/net/ethernet/ralink/esw_rt3052.c           | 1463 ++++++++++++++++++++
+ drivers/net/ethernet/ralink/esw_rt3052.h           |   32 +
+ drivers/net/ethernet/ralink/gsw_mt7620a.c          |  566 ++++++++
+ drivers/net/ethernet/ralink/gsw_mt7620a.h          |   30 +
+ drivers/net/ethernet/ralink/mdio.c                 |  244 ++++
+ drivers/net/ethernet/ralink/mdio.h                 |   29 +
+ drivers/net/ethernet/ralink/mdio_rt2880.c          |  232 ++++
+ drivers/net/ethernet/ralink/mdio_rt2880.h          |   26 +
+ drivers/net/ethernet/ralink/mt7530.c               |  579 ++++++++
+ drivers/net/ethernet/ralink/mt7530.h               |   20 +
+ drivers/net/ethernet/ralink/ralink_soc_eth.c       |  844 +++++++++++
+ drivers/net/ethernet/ralink/ralink_soc_eth.h       |  384 +++++
+ drivers/net/ethernet/ralink/soc_mt7620.c           |  172 +++
+ drivers/net/ethernet/ralink/soc_rt2880.c           |   52 +
+ drivers/net/ethernet/ralink/soc_rt305x.c           |  113 ++
+ drivers/net/ethernet/ralink/soc_rt3883.c           |   60 +
+ 22 files changed, 4926 insertions(+)
+ create mode 100644 arch/mips/include/asm/mach-ralink/rt305x_esw_platform.h
+ create mode 100644 drivers/net/ethernet/ralink/Kconfig
+ create mode 100644 drivers/net/ethernet/ralink/Makefile
+ create mode 100644 drivers/net/ethernet/ralink/esw_rt3052.c
+ create mode 100644 drivers/net/ethernet/ralink/esw_rt3052.h
+ create mode 100644 drivers/net/ethernet/ralink/gsw_mt7620a.c
+ create mode 100644 drivers/net/ethernet/ralink/gsw_mt7620a.h
+ create mode 100644 drivers/net/ethernet/ralink/mdio.c
+ create mode 100644 drivers/net/ethernet/ralink/mdio.h
+ create mode 100644 drivers/net/ethernet/ralink/mdio_rt2880.c
+ create mode 100644 drivers/net/ethernet/ralink/mdio_rt2880.h
+ create mode 100644 drivers/net/ethernet/ralink/mt7530.c
+ create mode 100644 drivers/net/ethernet/ralink/mt7530.h
+ create mode 100644 drivers/net/ethernet/ralink/ralink_soc_eth.c
+ create mode 100644 drivers/net/ethernet/ralink/ralink_soc_eth.h
+ create mode 100644 drivers/net/ethernet/ralink/soc_mt7620.c
+ create mode 100644 drivers/net/ethernet/ralink/soc_rt2880.c
+ create mode 100644 drivers/net/ethernet/ralink/soc_rt305x.c
+ create mode 100644 drivers/net/ethernet/ralink/soc_rt3883.c
+
+diff --git a/arch/mips/include/asm/mach-ralink/rt305x_esw_platform.h b/arch/mips/include/asm/mach-ralink/rt305x_esw_platform.h
+new file mode 100644
+index 0000000..2098c5c
+--- /dev/null
++++ b/arch/mips/include/asm/mach-ralink/rt305x_esw_platform.h
+@@ -0,0 +1,27 @@
++/*
++ *  Ralink RT305x SoC platform device registration
++ *
++ *  Copyright (C) 2010 Gabor Juhos <juhosg@openwrt.org>
++ *
++ *  This program is free software; you can redistribute it and/or modify it
++ *  under the terms of the GNU General Public License version 2 as published
++ *  by the Free Software Foundation.
++ */
++
++#ifndef _RT305X_ESW_PLATFORM_H
++#define _RT305X_ESW_PLATFORM_H
++
++enum {
++      RT305X_ESW_VLAN_CONFIG_NONE = 0,
++      RT305X_ESW_VLAN_CONFIG_LLLLW,
++      RT305X_ESW_VLAN_CONFIG_WLLLL,
++};
++
++struct rt305x_esw_platform_data
++{
++      u8 vlan_config;
++      u32 reg_initval_fct2;
++      u32 reg_initval_fpa2;
++};
++
++#endif /* _RT305X_ESW_PLATFORM_H */
+diff --git a/arch/mips/ralink/rt305x.c b/arch/mips/ralink/rt305x.c
+index 356d6a0..ef99d78 100644
+--- a/arch/mips/ralink/rt305x.c
++++ b/arch/mips/ralink/rt305x.c
+@@ -199,6 +199,7 @@ void __init ralink_clk_init(void)
+       }
+       ralink_clk_add("cpu", cpu_rate);
++      ralink_clk_add("sys", sys_rate);
+       ralink_clk_add("10000b00.spi", sys_rate);
+       ralink_clk_add("10000100.timer", wdt_rate);
+       ralink_clk_add("10000120.watchdog", wdt_rate);
+diff --git a/drivers/net/ethernet/Kconfig b/drivers/net/ethernet/Kconfig
+index 506b024..ef6a274 100644
+--- a/drivers/net/ethernet/Kconfig
++++ b/drivers/net/ethernet/Kconfig
+@@ -134,6 +134,7 @@ config ETHOC
+ source "drivers/net/ethernet/packetengines/Kconfig"
+ source "drivers/net/ethernet/pasemi/Kconfig"
+ source "drivers/net/ethernet/qlogic/Kconfig"
++source "drivers/net/ethernet/ralink/Kconfig"
+ source "drivers/net/ethernet/realtek/Kconfig"
+ source "drivers/net/ethernet/renesas/Kconfig"
+ source "drivers/net/ethernet/rdc/Kconfig"
+diff --git a/drivers/net/ethernet/Makefile b/drivers/net/ethernet/Makefile
+index c0b8789..7c3eb7b 100644
+--- a/drivers/net/ethernet/Makefile
++++ b/drivers/net/ethernet/Makefile
+@@ -56,6 +56,7 @@ obj-$(CONFIG_ETHOC) += ethoc.o
+ obj-$(CONFIG_NET_PACKET_ENGINE) += packetengines/
+ obj-$(CONFIG_NET_VENDOR_PASEMI) += pasemi/
+ obj-$(CONFIG_NET_VENDOR_QLOGIC) += qlogic/
++obj-$(CONFIG_NET_RALINK) += ralink/
+ obj-$(CONFIG_NET_VENDOR_REALTEK) += realtek/
+ obj-$(CONFIG_SH_ETH) += renesas/
+ obj-$(CONFIG_NET_VENDOR_RDC) += rdc/
+diff --git a/drivers/net/ethernet/ralink/Kconfig b/drivers/net/ethernet/ralink/Kconfig
+new file mode 100644
+index 0000000..727ed78
+--- /dev/null
++++ b/drivers/net/ethernet/ralink/Kconfig
+@@ -0,0 +1,32 @@
++config NET_RALINK
++      tristate "Ralink RT288X/RT3X5X/RT3662/RT3883/MT7620 ethernet driver"
++      depends on RALINK
++      help
++        This driver supports the ethernet mac inside the ralink wisocs
++
++if NET_RALINK
++
++config NET_RALINK_MDIO
++      def_bool NET_RALINK
++      depends on (SOC_RT288X || SOC_RT3883 || SOC_MT7620)
++      select PHYLIB
++
++config NET_RALINK_MDIO_RT2880
++      def_bool NET_RALINK
++      depends on (SOC_RT288X || SOC_RT3883)
++      select NET_RALINK_MDIO
++
++config NET_RALINK_ESW_RT3052
++      def_bool NET_RALINK
++      depends on SOC_RT305X
++      select PHYLIB
++      select SWCONFIG
++
++config NET_RALINK_GSW_MT7620
++      def_bool NET_RALINK
++      depends on SOC_MT7620
++      select INET_LRO
++      select NET_RALINK_MDIO
++      select PHYLIB
++      select SWCONFIG
++endif
+diff --git a/drivers/net/ethernet/ralink/Makefile b/drivers/net/ethernet/ralink/Makefile
+new file mode 100644
+index 0000000..de64edf
+--- /dev/null
++++ b/drivers/net/ethernet/ralink/Makefile
+@@ -0,0 +1,18 @@
++#
++# Makefile for the Ralink SoCs built-in ethernet macs
++#
++
++ralink-eth-y                                  += ralink_soc_eth.o
++
++ralink-eth-$(CONFIG_NET_RALINK_MDIO)          += mdio.o
++ralink-eth-$(CONFIG_NET_RALINK_MDIO_RT2880)   += mdio_rt2880.o
++
++ralink-eth-$(CONFIG_NET_RALINK_ESW_RT3052)    += esw_rt3052.o
++ralink-eth-$(CONFIG_NET_RALINK_GSW_MT7620)    += gsw_mt7620a.o mt7530.o
++
++ralink-eth-$(CONFIG_SOC_RT288X)                       += soc_rt2880.o
++ralink-eth-$(CONFIG_SOC_RT305X)                       += soc_rt305x.o
++ralink-eth-$(CONFIG_SOC_RT3883)                       += soc_rt3883.o
++ralink-eth-$(CONFIG_SOC_MT7620)                       += soc_mt7620.o
++
++obj-$(CONFIG_NET_RALINK)                      += ralink-eth.o
+diff --git a/drivers/net/ethernet/ralink/esw_rt3052.c b/drivers/net/ethernet/ralink/esw_rt3052.c
+new file mode 100644
+index 0000000..b937062
+--- /dev/null
++++ b/drivers/net/ethernet/ralink/esw_rt3052.c
+@@ -0,0 +1,1463 @@
++/*
++ *   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; version 2 of the License
++ *
++ *   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., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
++ *
++ *   Copyright (C) 2009-2013 John Crispin <blogic@openwrt.org>
++ */
++
++#include <linux/module.h>
++#include <linux/kernel.h>
++#include <linux/types.h>
++#include <linux/dma-mapping.h>
++#include <linux/init.h>
++#include <linux/skbuff.h>
++#include <linux/etherdevice.h>
++#include <linux/ethtool.h>
++#include <linux/platform_device.h>
++#include <linux/of_device.h>
++#include <linux/clk.h>
++#include <linux/of_net.h>
++#include <linux/of_mdio.h>
++
++#include <asm/mach-ralink/ralink_regs.h>
++
++#include "ralink_soc_eth.h"
++
++#include <linux/ioport.h>
++#include <linux/switch.h>
++#include <linux/mii.h>
++
++#include <ralink_regs.h>
++#include <asm/mach-ralink/rt305x.h>
++#include <asm/mach-ralink/rt305x_esw_platform.h>
++
++/*
++ * HW limitations for this switch:
++ * - No large frame support (PKT_MAX_LEN at most 1536)
++ * - Can't have untagged vlan and tagged vlan on one port at the same time,
++ *   though this might be possible using the undocumented PPE.
++ */
++
++#define RT305X_ESW_REG_ISR            0x00
++#define RT305X_ESW_REG_IMR            0x04
++#define RT305X_ESW_REG_FCT0           0x08
++#define RT305X_ESW_REG_PFC1           0x14
++#define RT305X_ESW_REG_ATS            0x24
++#define RT305X_ESW_REG_ATS0           0x28
++#define RT305X_ESW_REG_ATS1           0x2c
++#define RT305X_ESW_REG_ATS2           0x30
++#define RT305X_ESW_REG_PVIDC(_n)      (0x40 + 4 * (_n))
++#define RT305X_ESW_REG_VLANI(_n)      (0x50 + 4 * (_n))
++#define RT305X_ESW_REG_VMSC(_n)               (0x70 + 4 * (_n))
++#define RT305X_ESW_REG_POA            0x80
++#define RT305X_ESW_REG_FPA            0x84
++#define RT305X_ESW_REG_SOCPC          0x8c
++#define RT305X_ESW_REG_POC0           0x90
++#define RT305X_ESW_REG_POC1           0x94
++#define RT305X_ESW_REG_POC2           0x98
++#define RT305X_ESW_REG_SGC            0x9c
++#define RT305X_ESW_REG_STRT           0xa0
++#define RT305X_ESW_REG_PCR0           0xc0
++#define RT305X_ESW_REG_PCR1           0xc4
++#define RT305X_ESW_REG_FPA2           0xc8
++#define RT305X_ESW_REG_FCT2           0xcc
++#define RT305X_ESW_REG_SGC2           0xe4
++#define RT305X_ESW_REG_P0LED          0xa4
++#define RT305X_ESW_REG_P1LED          0xa8
++#define RT305X_ESW_REG_P2LED          0xac
++#define RT305X_ESW_REG_P3LED          0xb0
++#define RT305X_ESW_REG_P4LED          0xb4
++#define RT305X_ESW_REG_PXPC(_x)               (0xe8 + (4 * _x))
++#define RT305X_ESW_REG_P1PC           0xec
++#define RT305X_ESW_REG_P2PC           0xf0
++#define RT305X_ESW_REG_P3PC           0xf4
++#define RT305X_ESW_REG_P4PC           0xf8
++#define RT305X_ESW_REG_P5PC           0xfc
++
++#define RT305X_ESW_LED_LINK           0
++#define RT305X_ESW_LED_100M           1
++#define RT305X_ESW_LED_DUPLEX         2
++#define RT305X_ESW_LED_ACTIVITY               3
++#define RT305X_ESW_LED_COLLISION      4
++#define RT305X_ESW_LED_LINKACT                5
++#define RT305X_ESW_LED_DUPLCOLL               6
++#define RT305X_ESW_LED_10MACT         7
++#define RT305X_ESW_LED_100MACT                8
++/* Additional led states not in datasheet: */
++#define RT305X_ESW_LED_BLINK          10
++#define RT305X_ESW_LED_ON             12
++
++#define RT305X_ESW_LINK_S             25
++#define RT305X_ESW_DUPLEX_S           9
++#define RT305X_ESW_SPD_S              0
++
++#define RT305X_ESW_PCR0_WT_NWAY_DATA_S        16
++#define RT305X_ESW_PCR0_WT_PHY_CMD    BIT(13)
++#define RT305X_ESW_PCR0_CPU_PHY_REG_S 8
++
++#define RT305X_ESW_PCR1_WT_DONE               BIT(0)
++
++#define RT305X_ESW_ATS_TIMEOUT                (5 * HZ)
++#define RT305X_ESW_PHY_TIMEOUT                (5 * HZ)
++
++#define RT305X_ESW_PVIDC_PVID_M               0xfff
++#define RT305X_ESW_PVIDC_PVID_S               12
++
++#define RT305X_ESW_VLANI_VID_M                0xfff
++#define RT305X_ESW_VLANI_VID_S                12
++
++#define RT305X_ESW_VMSC_MSC_M         0xff
++#define RT305X_ESW_VMSC_MSC_S         8
++
++#define RT305X_ESW_SOCPC_DISUN2CPU_S  0
++#define RT305X_ESW_SOCPC_DISMC2CPU_S  8
++#define RT305X_ESW_SOCPC_DISBC2CPU_S  16
++#define RT305X_ESW_SOCPC_CRC_PADDING  BIT(25)
++
++#define RT305X_ESW_POC0_EN_BP_S               0
++#define RT305X_ESW_POC0_EN_FC_S               8
++#define RT305X_ESW_POC0_DIS_RMC2CPU_S 16
++#define RT305X_ESW_POC0_DIS_PORT_M    0x7f
++#define RT305X_ESW_POC0_DIS_PORT_S    23
++
++#define RT305X_ESW_POC2_UNTAG_EN_M    0xff
++#define RT305X_ESW_POC2_UNTAG_EN_S    0
++#define RT305X_ESW_POC2_ENAGING_S     8
++#define RT305X_ESW_POC2_DIS_UC_PAUSE_S        16
++
++#define RT305X_ESW_SGC2_DOUBLE_TAG_M  0x7f
++#define RT305X_ESW_SGC2_DOUBLE_TAG_S  0
++#define RT305X_ESW_SGC2_LAN_PMAP_M    0x3f
++#define RT305X_ESW_SGC2_LAN_PMAP_S    24
++
++#define RT305X_ESW_PFC1_EN_VLAN_M     0xff
++#define RT305X_ESW_PFC1_EN_VLAN_S     16
++#define RT305X_ESW_PFC1_EN_TOS_S      24
++
++#define RT305X_ESW_VLAN_NONE          0xfff
++
++#define RT305X_ESW_GSC_BC_STROM_MASK  0x3
++#define RT305X_ESW_GSC_BC_STROM_SHIFT 4
++
++#define RT305X_ESW_GSC_LED_FREQ_MASK  0x3
++#define RT305X_ESW_GSC_LED_FREQ_SHIFT 23
++
++#define RT305X_ESW_POA_LINK_MASK      0x1f
++#define RT305X_ESW_POA_LINK_SHIFT     25
++
++#define RT305X_ESW_PORT_ST_CHG                BIT(26)
++#define RT305X_ESW_PORT0              0
++#define RT305X_ESW_PORT1              1
++#define RT305X_ESW_PORT2              2
++#define RT305X_ESW_PORT3              3
++#define RT305X_ESW_PORT4              4
++#define RT305X_ESW_PORT5              5
++#define RT305X_ESW_PORT6              6
++
++#define RT305X_ESW_PORTS_NONE         0
++
++#define RT305X_ESW_PMAP_LLLLLL                0x3f
++#define RT305X_ESW_PMAP_LLLLWL                0x2f
++#define RT305X_ESW_PMAP_WLLLLL                0x3e
++
++#define RT305X_ESW_PORTS_INTERNAL                                     \
++              (BIT(RT305X_ESW_PORT0) | BIT(RT305X_ESW_PORT1) |        \
++               BIT(RT305X_ESW_PORT2) | BIT(RT305X_ESW_PORT3) |        \
++               BIT(RT305X_ESW_PORT4))
++
++#define RT305X_ESW_PORTS_NOCPU                                                \
++              (RT305X_ESW_PORTS_INTERNAL | BIT(RT305X_ESW_PORT5))
++
++#define RT305X_ESW_PORTS_CPU  BIT(RT305X_ESW_PORT6)
++
++#define RT305X_ESW_PORTS_ALL                                          \
++              (RT305X_ESW_PORTS_NOCPU | RT305X_ESW_PORTS_CPU)
++
++#define RT305X_ESW_NUM_VLANS          16
++#define RT305X_ESW_NUM_VIDS           4096
++#define RT305X_ESW_NUM_PORTS          7
++#define RT305X_ESW_NUM_LANWAN         6
++#define RT305X_ESW_NUM_LEDS           5
++
++#define RT5350_ESW_REG_PXTPC(_x)      (0x150 + (4 * _x))
++#define RT5350_EWS_REG_LED_POLARITY   0x168
++#define RT5350_RESET_EPHY             BIT(24)
++#define SYSC_REG_RESET_CTRL           0x34
++
++enum {
++      /* Global attributes. */
++      RT305X_ESW_ATTR_ENABLE_VLAN,
++      RT305X_ESW_ATTR_ALT_VLAN_DISABLE,
++      RT305X_ESW_ATTR_BC_STATUS,
++      RT305X_ESW_ATTR_LED_FREQ,
++      /* Port attributes. */
++      RT305X_ESW_ATTR_PORT_DISABLE,
++      RT305X_ESW_ATTR_PORT_DOUBLETAG,
++      RT305X_ESW_ATTR_PORT_UNTAG,
++      RT305X_ESW_ATTR_PORT_LED,
++      RT305X_ESW_ATTR_PORT_LAN,
++      RT305X_ESW_ATTR_PORT_RECV_BAD,
++      RT305X_ESW_ATTR_PORT_RECV_GOOD,
++      RT5350_ESW_ATTR_PORT_TR_BAD,
++      RT5350_ESW_ATTR_PORT_TR_GOOD,
++};
++
++struct esw_port {
++      bool    disable;
++      bool    doubletag;
++      bool    untag;
++      u8      led;
++      u16     pvid;
++};
++
++struct esw_vlan {
++      u8      ports;
++      u16     vid;
++};
++
++struct rt305x_esw {
++      struct device           *dev;
++      void __iomem            *base;
++      int                     irq;
++      const struct rt305x_esw_platform_data *pdata;
++      /* Protects against concurrent register rmw operations. */
++      spinlock_t              reg_rw_lock;
++
++      unsigned char           port_map;
++      unsigned int            reg_initval_fct2;
++      unsigned int            reg_initval_fpa2;
++      unsigned int            reg_led_polarity;
++
++
++      struct switch_dev       swdev;
++      bool                    global_vlan_enable;
++      bool                    alt_vlan_disable;
++      int                     bc_storm_protect;
++      int                     led_frequency;
++      struct esw_vlan vlans[RT305X_ESW_NUM_VLANS];
++      struct esw_port ports[RT305X_ESW_NUM_PORTS];
++
++};
++
++static inline void esw_w32(struct rt305x_esw *esw, u32 val, unsigned reg)
++{
++      __raw_writel(val, esw->base + reg);
++}
++
++static inline u32 esw_r32(struct rt305x_esw *esw, unsigned reg)
++{
++      return __raw_readl(esw->base + reg);
++}
++
++static inline void esw_rmw_raw(struct rt305x_esw *esw, unsigned reg, unsigned long mask,
++                 unsigned long val)
++{
++      unsigned long t;
++
++      t = __raw_readl(esw->base + reg) & ~mask;
++      __raw_writel(t | val, esw->base + reg);
++}
++
++static void esw_rmw(struct rt305x_esw *esw, unsigned reg, unsigned long mask,
++             unsigned long val)
++{
++      unsigned long flags;
++
++      spin_lock_irqsave(&esw->reg_rw_lock, flags);
++      esw_rmw_raw(esw, reg, mask, val);
++      spin_unlock_irqrestore(&esw->reg_rw_lock, flags);
++}
++
++static u32 rt305x_mii_write(struct rt305x_esw *esw, u32 phy_addr, u32 phy_register,
++               u32 write_data)
++{
++      unsigned long t_start = jiffies;
++      int ret = 0;
++
++      while (1) {
++              if (!(esw_r32(esw, RT305X_ESW_REG_PCR1) &
++                    RT305X_ESW_PCR1_WT_DONE))
++                      break;
++              if (time_after(jiffies, t_start + RT305X_ESW_PHY_TIMEOUT)) {
++                      ret = 1;
++                      goto out;
++              }
++      }
++
++      write_data &= 0xffff;
++      esw_w32(esw,
++                    (write_data << RT305X_ESW_PCR0_WT_NWAY_DATA_S) |
++                    (phy_register << RT305X_ESW_PCR0_CPU_PHY_REG_S) |
++                    (phy_addr) | RT305X_ESW_PCR0_WT_PHY_CMD,
++                    RT305X_ESW_REG_PCR0);
++
++      t_start = jiffies;
++      while (1) {
++              if (esw_r32(esw, RT305X_ESW_REG_PCR1) &
++                  RT305X_ESW_PCR1_WT_DONE)
++                      break;
++
++              if (time_after(jiffies, t_start + RT305X_ESW_PHY_TIMEOUT)) {
++                      ret = 1;
++                      break;
++              }
++      }
++out:
++      if (ret)
++              printk(KERN_ERR "ramips_eth: MDIO timeout\n");
++      return ret;
++}
++
++static unsigned esw_get_vlan_id(struct rt305x_esw *esw, unsigned vlan)
++{
++      unsigned s;
++      unsigned val;
++
++      s = RT305X_ESW_VLANI_VID_S * (vlan % 2);
++      val = esw_r32(esw, RT305X_ESW_REG_VLANI(vlan / 2));
++      val = (val >> s) & RT305X_ESW_VLANI_VID_M;
++
++      return val;
++}
++
++static void esw_set_vlan_id(struct rt305x_esw *esw, unsigned vlan, unsigned vid)
++{
++      unsigned s;
++
++      s = RT305X_ESW_VLANI_VID_S * (vlan % 2);
++      esw_rmw(esw,
++                     RT305X_ESW_REG_VLANI(vlan / 2),
++                     RT305X_ESW_VLANI_VID_M << s,
++                     (vid & RT305X_ESW_VLANI_VID_M) << s);
++}
++
++static unsigned esw_get_pvid(struct rt305x_esw *esw, unsigned port)
++{
++      unsigned s, val;
++
++      s = RT305X_ESW_PVIDC_PVID_S * (port % 2);
++      val = esw_r32(esw, RT305X_ESW_REG_PVIDC(port / 2));
++      return (val >> s) & RT305X_ESW_PVIDC_PVID_M;
++}
++
++static void esw_set_pvid(struct rt305x_esw *esw, unsigned port, unsigned pvid)
++{
++      unsigned s;
++
++      s = RT305X_ESW_PVIDC_PVID_S * (port % 2);
++      esw_rmw(esw,
++                     RT305X_ESW_REG_PVIDC(port / 2),
++                     RT305X_ESW_PVIDC_PVID_M << s,
++                     (pvid & RT305X_ESW_PVIDC_PVID_M) << s);
++}
++
++static unsigned esw_get_vmsc(struct rt305x_esw *esw, unsigned vlan)
++{
++      unsigned s, val;
++
++      s = RT305X_ESW_VMSC_MSC_S * (vlan % 4);
++      val = esw_r32(esw, RT305X_ESW_REG_VMSC(vlan / 4));
++      val = (val >> s) & RT305X_ESW_VMSC_MSC_M;
++
++      return val;
++}
++
++static void esw_set_vmsc(struct rt305x_esw *esw, unsigned vlan, unsigned msc)
++{
++      unsigned s;
++
++      s = RT305X_ESW_VMSC_MSC_S * (vlan % 4);
++      esw_rmw(esw,
++                     RT305X_ESW_REG_VMSC(vlan / 4),
++                     RT305X_ESW_VMSC_MSC_M << s,
++                     (msc & RT305X_ESW_VMSC_MSC_M) << s);
++}
++
++static unsigned esw_get_port_disable(struct rt305x_esw *esw)
++{
++      unsigned reg;
++      reg = esw_r32(esw, RT305X_ESW_REG_POC0);
++      return (reg >> RT305X_ESW_POC0_DIS_PORT_S) &
++             RT305X_ESW_POC0_DIS_PORT_M;
++}
++
++static void esw_set_port_disable(struct rt305x_esw *esw, unsigned disable_mask)
++{
++      unsigned old_mask;
++      unsigned enable_mask;
++      unsigned changed;
++      int i;
++
++      old_mask = esw_get_port_disable(esw);
++      changed = old_mask ^ disable_mask;
++      enable_mask = old_mask & disable_mask;
++
++      /* enable before writing to MII */
++      esw_rmw(esw, RT305X_ESW_REG_POC0,
++                     (RT305X_ESW_POC0_DIS_PORT_M <<
++                      RT305X_ESW_POC0_DIS_PORT_S),
++                     enable_mask << RT305X_ESW_POC0_DIS_PORT_S);
++
++      for (i = 0; i < RT305X_ESW_NUM_LEDS; i++) {
++              if (!(changed & (1 << i)))
++                      continue;
++              if (disable_mask & (1 << i)) {
++                      /* disable */
++                      rt305x_mii_write(esw, i, MII_BMCR,
++                                       BMCR_PDOWN);
++              } else {
++                      /* enable */
++                      rt305x_mii_write(esw, i, MII_BMCR,
++                                       BMCR_FULLDPLX |
++                                       BMCR_ANENABLE |
++                                       BMCR_ANRESTART |
++                                       BMCR_SPEED100);
++              }
++      }
++
++      /* disable after writing to MII */
++      esw_rmw(esw, RT305X_ESW_REG_POC0,
++                     (RT305X_ESW_POC0_DIS_PORT_M <<
++                      RT305X_ESW_POC0_DIS_PORT_S),
++                     disable_mask << RT305X_ESW_POC0_DIS_PORT_S);
++}
++
++static void esw_set_gsc(struct rt305x_esw *esw)
++{
++      esw_rmw(esw, RT305X_ESW_REG_SGC,
++              RT305X_ESW_GSC_BC_STROM_MASK << RT305X_ESW_GSC_BC_STROM_SHIFT,
++              esw->bc_storm_protect << RT305X_ESW_GSC_BC_STROM_SHIFT);
++      esw_rmw(esw, RT305X_ESW_REG_SGC,
++              RT305X_ESW_GSC_LED_FREQ_MASK << RT305X_ESW_GSC_LED_FREQ_SHIFT,
++              esw->led_frequency << RT305X_ESW_GSC_LED_FREQ_SHIFT);
++}
++
++static int esw_apply_config(struct switch_dev *dev);
++
++static void esw_hw_init(struct rt305x_esw *esw)
++{
++      int i;
++      u8 port_disable = 0;
++      u8 port_map = RT305X_ESW_PMAP_LLLLLL;
++
++      /* vodoo from original driver */
++      esw_w32(esw, 0xC8A07850, RT305X_ESW_REG_FCT0);
++      esw_w32(esw, 0x00000000, RT305X_ESW_REG_SGC2);
++      /* Port priority 1 for all ports, vlan enabled. */
++      esw_w32(esw, 0x00005555 |
++                    (RT305X_ESW_PORTS_ALL << RT305X_ESW_PFC1_EN_VLAN_S),
++                    RT305X_ESW_REG_PFC1);
++
++      /* Enable Back Pressure, and Flow Control */
++      esw_w32(esw,
++                    ((RT305X_ESW_PORTS_ALL << RT305X_ESW_POC0_EN_BP_S) |
++                     (RT305X_ESW_PORTS_ALL << RT305X_ESW_POC0_EN_FC_S)),
++                    RT305X_ESW_REG_POC0);
++
++      /* Enable Aging, and VLAN TAG removal */
++      esw_w32(esw,
++                    ((RT305X_ESW_PORTS_ALL << RT305X_ESW_POC2_ENAGING_S) |
++                     (RT305X_ESW_PORTS_NOCPU << RT305X_ESW_POC2_UNTAG_EN_S)),
++                    RT305X_ESW_REG_POC2);
++
++      if (esw->reg_initval_fct2)
++              esw_w32(esw, esw->reg_initval_fct2, RT305X_ESW_REG_FCT2);
++      else
++              esw_w32(esw, esw->pdata->reg_initval_fct2, RT305X_ESW_REG_FCT2);
++
++      /*
++       * 300s aging timer, max packet len 1536, broadcast storm prevention
++       * disabled, disable collision abort, mac xor48 hash, 10 packet back
++       * pressure jam, GMII disable was_transmit, back pressure disabled,
++       * 30ms led flash, unmatched IGMP as broadcast, rmc tb fault to all
++       * ports.
++       */
++      esw_w32(esw, 0x0008a301, RT305X_ESW_REG_SGC);
++
++      /* Setup SoC Port control register */
++      esw_w32(esw,
++                    (RT305X_ESW_SOCPC_CRC_PADDING |
++                     (RT305X_ESW_PORTS_CPU << RT305X_ESW_SOCPC_DISUN2CPU_S) |
++                     (RT305X_ESW_PORTS_CPU << RT305X_ESW_SOCPC_DISMC2CPU_S) |
++                     (RT305X_ESW_PORTS_CPU << RT305X_ESW_SOCPC_DISBC2CPU_S)),
++                    RT305X_ESW_REG_SOCPC);
++
++      if (esw->reg_initval_fpa2)
++              esw_w32(esw, esw->reg_initval_fpa2, RT305X_ESW_REG_FPA2);
++      else
++              esw_w32(esw, esw->pdata->reg_initval_fpa2, RT305X_ESW_REG_FPA2);
++      esw_w32(esw, 0x00000000, RT305X_ESW_REG_FPA);
++
++      /* Force Link/Activity on ports */
++      esw_w32(esw, 0x00000005, RT305X_ESW_REG_P0LED);
++      esw_w32(esw, 0x00000005, RT305X_ESW_REG_P1LED);
++      esw_w32(esw, 0x00000005, RT305X_ESW_REG_P2LED);
++      esw_w32(esw, 0x00000005, RT305X_ESW_REG_P3LED);
++      esw_w32(esw, 0x00000005, RT305X_ESW_REG_P4LED);
++
++      /* Copy disabled port configuration from bootloader setup */
++      port_disable = esw_get_port_disable(esw);
++      for (i = 0; i < 6; i++)
++              esw->ports[i].disable = (port_disable & (1 << i)) != 0;
++
++      if (soc_is_rt3352()) {
++              /* reset EPHY */
++              u32 val = rt_sysc_r32(SYSC_REG_RESET_CTRL);
++              rt_sysc_w32(val | RT5350_RESET_EPHY, SYSC_REG_RESET_CTRL);
++              rt_sysc_w32(val, SYSC_REG_RESET_CTRL);
++
++              rt305x_mii_write(esw, 0, 31, 0x8000);
++              for (i = 0; i < 5; i++) {
++                      if (esw->ports[i].disable) {
++                              rt305x_mii_write(esw, i, MII_BMCR, BMCR_PDOWN);
++                      } else {
++                              rt305x_mii_write(esw, i, MII_BMCR,
++                                       BMCR_FULLDPLX |
++                                       BMCR_ANENABLE |
++                                       BMCR_SPEED100);
++                      }
++                      /* TX10 waveform coefficient LSB=0 disable PHY */
++                      rt305x_mii_write(esw, i, 26, 0x1601);
++                      /* TX100/TX10 AD/DA current bias */
++                      rt305x_mii_write(esw, i, 29, 0x7016);
++                      /* TX100 slew rate control */
++                      rt305x_mii_write(esw, i, 30, 0x0038);
++              }
++
++              /* select global register */
++              rt305x_mii_write(esw, 0, 31, 0x0);
++              /* enlarge agcsel threshold 3 and threshold 2 */
++              rt305x_mii_write(esw, 0, 1, 0x4a40);
++              /* enlarge agcsel threshold 5 and threshold 4 */
++              rt305x_mii_write(esw, 0, 2, 0x6254);
++              /* enlarge agcsel threshold  */
++              rt305x_mii_write(esw, 0, 3, 0xa17f);
++              rt305x_mii_write(esw, 0,12, 0x7eaa);
++              /* longer TP_IDL tail length */
++              rt305x_mii_write(esw, 0, 14, 0x65);
++              /* increased squelch pulse count threshold. */
++              rt305x_mii_write(esw, 0, 16, 0x0684);
++              /* set TX10 signal amplitude threshold to minimum */
++              rt305x_mii_write(esw, 0, 17, 0x0fe0);
++              /* set squelch amplitude to higher threshold */
++              rt305x_mii_write(esw, 0, 18, 0x40ba);
++              /* tune TP_IDL tail and head waveform, enable power down slew rate control */
++              rt305x_mii_write(esw, 0, 22, 0x253f);
++              /* set PLL/Receive bias current are calibrated */
++              rt305x_mii_write(esw, 0, 27, 0x2fda);
++              /* change PLL/Receive bias current to internal(RT3350) */
++              rt305x_mii_write(esw, 0, 28, 0xc410);
++              /* change PLL bias current to internal(RT3052_MP3) */
++              rt305x_mii_write(esw, 0, 29, 0x598b);
++              /* select local register */
++              rt305x_mii_write(esw, 0, 31, 0x8000);
++      } else if (soc_is_rt5350()) {
++              /* reset EPHY */
++              u32 val = rt_sysc_r32(SYSC_REG_RESET_CTRL);
++              rt_sysc_w32(val | RT5350_RESET_EPHY, SYSC_REG_RESET_CTRL);
++              rt_sysc_w32(val, SYSC_REG_RESET_CTRL);
++
++              /* set the led polarity */
++              esw_w32(esw, esw->reg_led_polarity & 0x1F, RT5350_EWS_REG_LED_POLARITY);
++
++              /* local registers */
++              rt305x_mii_write(esw, 0, 31, 0x8000);
++              for (i = 0; i < 5; i++) {
++                      if (esw->ports[i].disable) {
++                              rt305x_mii_write(esw, i, MII_BMCR, BMCR_PDOWN);
++                      } else {
++                              rt305x_mii_write(esw, i, MII_BMCR,
++                                       BMCR_FULLDPLX |
++                                       BMCR_ANENABLE |
++                                       BMCR_SPEED100);
++                      }
++                      /* TX10 waveform coefficient LSB=0 disable PHY */
++                      rt305x_mii_write(esw, i, 26, 0x1601);
++                      /* TX100/TX10 AD/DA current bias */
++                      rt305x_mii_write(esw, i, 29, 0x7015);
++                      /* TX100 slew rate control */
++                      rt305x_mii_write(esw, i, 30, 0x0038);
++              }
++
++              /* global registers */
++              rt305x_mii_write(esw, 0, 31, 0x0);
++              /* enlarge agcsel threshold 3 and threshold 2 */
++              rt305x_mii_write(esw, 0, 1, 0x4a40);
++              /* enlarge agcsel threshold 5 and threshold 4 */
++              rt305x_mii_write(esw, 0, 2, 0x6254);
++              /* enlarge agcsel threshold 6 */
++              rt305x_mii_write(esw, 0, 3, 0xa17f);
++              rt305x_mii_write(esw, 0, 12, 0x7eaa);
++              /* longer TP_IDL tail length */
++              rt305x_mii_write(esw, 0, 14, 0x65);
++              /* increased squelch pulse count threshold. */