ralink: add 3.14 support

Signed-off-by: John Crispin <blogic@openwrt.org>

SVN-Revision: 42040
This commit is contained in:
John Crispin 2014-08-07 14:41:19 +00:00
parent e41a0cafff
commit bc67bd2295
66 changed files with 64992 additions and 0 deletions

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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

File diff suppressed because it is too large Load diff

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,240 @@
From 900fa0abfea0cb7562c523769981dadc25f1f8cd Mon Sep 17 00:00:00 2001
From: John Crispin <blogic@openwrt.org>
Date: Sun, 27 Jul 2014 09:43:42 +0100
Subject: [PATCH 37/57] USB: phy: add ralink SoC driver
Signed-off-by: John Crispin <blogic@openwrt.org>
---
drivers/usb/phy/Kconfig | 8 ++
drivers/usb/phy/Makefile | 1 +
drivers/usb/phy/ralink-phy.c | 190 ++++++++++++++++++++++++++++++++++++++++++
3 files changed, 199 insertions(+)
create mode 100644 drivers/usb/phy/ralink-phy.c
diff --git a/drivers/usb/phy/Kconfig b/drivers/usb/phy/Kconfig
index 7d1451d..fc04d76 100644
--- a/drivers/usb/phy/Kconfig
+++ b/drivers/usb/phy/Kconfig
@@ -251,6 +251,14 @@ config USB_RCAR_GEN2_PHY
To compile this driver as a module, choose M here: the
module will be called phy-rcar-gen2-usb.
+config RALINK_USBPHY
+ bool "Ralink USB PHY controller Driver"
+ depends on MIPS && RALINK
+ select USB_PHY
+ help
+ Enable this to support ralink USB phy controller for ralink
+ SoCs.
+
config USB_ULPI
bool "Generic ULPI Transceiver Driver"
depends on ARM
diff --git a/drivers/usb/phy/Makefile b/drivers/usb/phy/Makefile
index be58ada..52d59c1 100644
--- a/drivers/usb/phy/Makefile
+++ b/drivers/usb/phy/Makefile
@@ -33,3 +33,4 @@ obj-$(CONFIG_USB_RCAR_GEN2_PHY) += phy-rcar-gen2-usb.o
obj-$(CONFIG_USB_ULPI) += phy-ulpi.o
obj-$(CONFIG_USB_ULPI_VIEWPORT) += phy-ulpi-viewport.o
obj-$(CONFIG_KEYSTONE_USB_PHY) += phy-keystone.o
+obj-$(CONFIG_RALINK_USBPHY) += ralink-phy.o
diff --git a/drivers/usb/phy/ralink-phy.c b/drivers/usb/phy/ralink-phy.c
new file mode 100644
index 0000000..28046e5
--- /dev/null
+++ b/drivers/usb/phy/ralink-phy.c
@@ -0,0 +1,190 @@
+/*
+ * Copyright (C) 2013 John Crispin <blogic@openwrt.org>
+ *
+ * based on: Renesas R-Car USB phy driver
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/delay.h>
+#include <linux/io.h>
+#include <linux/usb/otg.h>
+#include <linux/of_platform.h>
+#include <linux/platform_device.h>
+#include <linux/spinlock.h>
+#include <linux/module.h>
+#include <linux/reset.h>
+
+#include <asm/mach-ralink/ralink_regs.h>
+
+#define RT_SYSC_REG_SYSCFG1 0x014
+#define RT_SYSC_REG_CLKCFG1 0x030
+#define RT_SYSC_REG_USB_PHY_CFG 0x05c
+
+#define RT_RSTCTRL_UDEV BIT(25)
+#define RT_RSTCTRL_UHST BIT(22)
+#define RT_SYSCFG1_USB0_HOST_MODE BIT(10)
+
+#define MT7620_CLKCFG1_UPHY0_CLK_EN BIT(25)
+#define RT_CLKCFG1_UPHY1_CLK_EN BIT(20)
+#define RT_CLKCFG1_UPHY0_CLK_EN BIT(18)
+
+#define USB_PHY_UTMI_8B60M BIT(1)
+#define UDEV_WAKEUP BIT(0)
+
+static atomic_t usb_pwr_ref = ATOMIC_INIT(0);
+static struct reset_control *rstdev;
+static struct reset_control *rsthost;
+static u32 phy_clk;
+
+static void usb_phy_enable(int state)
+{
+ if (state)
+ rt_sysc_m32(0, phy_clk, RT_SYSC_REG_CLKCFG1);
+ else
+ rt_sysc_m32(phy_clk, 0, RT_SYSC_REG_CLKCFG1);
+ mdelay(100);
+}
+
+static int usb_power_on(struct usb_phy *phy)
+{
+ if (atomic_inc_return(&usb_pwr_ref) == 1) {
+ u32 t;
+
+ usb_phy_enable(1);
+
+// reset_control_assert(rstdev);
+// reset_control_assert(rsthost);
+
+ if (OTG_STATE_B_HOST) {
+ rt_sysc_m32(0, RT_SYSCFG1_USB0_HOST_MODE, RT_SYSC_REG_SYSCFG1);
+ if (!IS_ERR(rsthost))
+ reset_control_deassert(rsthost);
+ } else {
+ rt_sysc_m32(RT_SYSCFG1_USB0_HOST_MODE, 0, RT_SYSC_REG_SYSCFG1);
+ if (!IS_ERR(rstdev))
+ reset_control_deassert(rstdev);
+ }
+ mdelay(100);
+
+ t = rt_sysc_r32(RT_SYSC_REG_USB_PHY_CFG);
+ dev_info(phy->dev, "remote usb device wakeup %s\n",
+ (t & UDEV_WAKEUP) ? ("enabbled") : ("disabled"));
+ if (t & USB_PHY_UTMI_8B60M)
+ dev_info(phy->dev, "UTMI 8bit 60MHz\n");
+ else
+ dev_info(phy->dev, "UTMI 16bit 30MHz\n");
+ }
+
+ return 0;
+}
+
+static void usb_power_off(struct usb_phy *phy)
+{
+ if (atomic_dec_return(&usb_pwr_ref) == 0) {
+ usb_phy_enable(0);
+ if (!IS_ERR(rstdev))
+ reset_control_assert(rstdev);
+ if (!IS_ERR(rsthost))
+ reset_control_assert(rsthost);
+ }
+}
+
+static int usb_set_host(struct usb_otg *otg, struct usb_bus *host)
+{
+ otg->gadget = NULL;
+ otg->host = host;
+
+ return 0;
+}
+
+static int usb_set_peripheral(struct usb_otg *otg,
+ struct usb_gadget *gadget)
+{
+ otg->host = NULL;
+ otg->gadget = gadget;
+
+ return 0;
+}
+
+static const struct of_device_id ralink_usbphy_dt_match[] = {
+ { .compatible = "ralink,rt3xxx-usbphy", .data = (void *) (RT_CLKCFG1_UPHY1_CLK_EN | RT_CLKCFG1_UPHY0_CLK_EN) },
+ { .compatible = "ralink,mt7620a-usbphy", .data = (void *) MT7620_CLKCFG1_UPHY0_CLK_EN },
+ {},
+};
+MODULE_DEVICE_TABLE(of, ralink_usbphy_dt_match);
+
+static int usb_phy_probe(struct platform_device *pdev)
+{
+ const struct of_device_id *match;
+ struct device *dev = &pdev->dev;
+ struct usb_otg *otg;
+ struct usb_phy *phy;
+ int ret;
+
+ match = of_match_device(ralink_usbphy_dt_match, &pdev->dev);
+ phy_clk = (int) match->data;
+
+ rsthost = devm_reset_control_get(&pdev->dev, "host");
+ rstdev = devm_reset_control_get(&pdev->dev, "device");
+
+ phy = devm_kzalloc(dev, sizeof(*phy), GFP_KERNEL);
+ if (!phy) {
+ dev_err(&pdev->dev, "unable to allocate memory for USB PHY\n");
+ return -ENOMEM;
+ }
+
+ otg = devm_kzalloc(&pdev->dev, sizeof(*otg), GFP_KERNEL);
+ if (!otg) {
+ dev_err(&pdev->dev, "unable to allocate memory for USB OTG\n");
+ return -ENOMEM;
+ }
+
+ phy->dev = dev;
+ phy->label = dev_name(dev);
+ phy->init = usb_power_on;
+ phy->shutdown = usb_power_off;
+ otg->set_host = usb_set_host;
+ otg->set_peripheral = usb_set_peripheral;
+ otg->phy = phy;
+ phy->otg = otg;
+ ret = usb_add_phy(phy, USB_PHY_TYPE_USB2);
+
+ if (ret < 0) {
+ dev_err(dev, "usb phy addition error\n");
+ return ret;
+ }
+
+ platform_set_drvdata(pdev, phy);
+
+ dev_info(&pdev->dev, "loaded\n");
+
+ return ret;
+}
+
+static int usb_phy_remove(struct platform_device *pdev)
+{
+ struct usb_phy *phy = platform_get_drvdata(pdev);
+
+ usb_remove_phy(phy);
+
+ return 0;
+}
+
+static struct platform_driver usb_phy_driver = {
+ .driver = {
+ .owner = THIS_MODULE,
+ .name = "rt3xxx-usbphy",
+ .of_match_table = of_match_ptr(ralink_usbphy_dt_match),
+ },
+ .probe = usb_phy_probe,
+ .remove = usb_phy_remove,
+};
+
+module_platform_driver(usb_phy_driver);
+
+MODULE_LICENSE("GPL v2");
+MODULE_DESCRIPTION("Ralink USB phy");
+MODULE_AUTHOR("John Crispin <blogic@openwrt.org>");
--
1.7.10.4

View file

@ -0,0 +1,191 @@
From ffb27de4760595c356ef619c97f25722c8db28e7 Mon Sep 17 00:00:00 2001
From: John Crispin <blogic@openwrt.org>
Date: Sun, 27 Jul 2014 09:49:07 +0100
Subject: [PATCH 38/57] USB: add OHCI/EHCI OF binding
based on f3bc64d6d1f21c1b92d75f233a37b75d77af6963
Signed-off-by: John Crispin <blogic@openwrt.org>
---
drivers/usb/Makefile | 3 ++-
drivers/usb/host/ehci-platform.c | 21 +++++++++++++++++----
drivers/usb/host/ohci-platform.c | 37 +++++++++++++++++++++++++++++++------
3 files changed, 50 insertions(+), 11 deletions(-)
diff --git a/drivers/usb/Makefile b/drivers/usb/Makefile
index 1ae2bf3..aaa15d9 100644
--- a/drivers/usb/Makefile
+++ b/drivers/usb/Makefile
@@ -11,6 +11,8 @@ obj-$(CONFIG_USB_DWC2) += dwc2/
obj-$(CONFIG_USB_MON) += mon/
+obj-$(CONFIG_USB_PHY) += phy/
+
obj-$(CONFIG_PCI) += host/
obj-$(CONFIG_USB_EHCI_HCD) += host/
obj-$(CONFIG_USB_ISP116X_HCD) += host/
@@ -41,7 +43,6 @@ obj-$(CONFIG_USB_TMC) += class/
obj-$(CONFIG_USB_STORAGE) += storage/
obj-$(CONFIG_USB) += storage/
-obj-$(CONFIG_USB_MDC800) += image/
obj-$(CONFIG_USB_MICROTEK) += image/
obj-$(CONFIG_USB_SERIAL) += serial/
diff --git a/drivers/usb/host/ehci-platform.c b/drivers/usb/host/ehci-platform.c
index 01536cf..1b9a8f4 100644
--- a/drivers/usb/host/ehci-platform.c
+++ b/drivers/usb/host/ehci-platform.c
@@ -29,6 +29,8 @@
#include <linux/usb.h>
#include <linux/usb/hcd.h>
#include <linux/usb/ehci_pdriver.h>
+#include <linux/usb/phy.h>
+#include <linux/usb/otg.h>
#include "ehci.h"
@@ -123,6 +125,15 @@ static int ehci_platform_probe(struct platform_device *dev)
hcd->rsrc_start = res_mem->start;
hcd->rsrc_len = resource_size(res_mem);
+#ifdef CONFIG_USB_PHY
+ hcd->phy = devm_usb_get_phy(&dev->dev, USB_PHY_TYPE_USB2);
+ if (!IS_ERR_OR_NULL(hcd->phy)) {
+ otg_set_host(hcd->phy->otg,
+ &hcd->self);
+ usb_phy_init(hcd->phy);
+ }
+#endif
+
hcd->regs = devm_ioremap_resource(&dev->dev, res_mem);
if (IS_ERR(hcd->regs)) {
err = PTR_ERR(hcd->regs);
@@ -160,6 +171,9 @@ static int ehci_platform_remove(struct platform_device *dev)
if (pdata == &ehci_platform_defaults)
dev->dev.platform_data = NULL;
+ if (pdata == &ehci_platform_defaults)
+ dev->dev.platform_data = NULL;
+
return 0;
}
@@ -204,9 +218,8 @@ static int ehci_platform_resume(struct device *dev)
#define ehci_platform_resume NULL
#endif /* CONFIG_PM */
-static const struct of_device_id vt8500_ehci_ids[] = {
- { .compatible = "via,vt8500-ehci", },
- { .compatible = "wm,prizm-ehci", },
+static const struct of_device_id ralink_ehci_ids[] = {
+ { .compatible = "ralink,rt3xxx-ehci", },
{}
};
@@ -230,7 +243,7 @@ static struct platform_driver ehci_platform_driver = {
.owner = THIS_MODULE,
.name = "ehci-platform",
.pm = &ehci_platform_pm_ops,
- .of_match_table = vt8500_ehci_ids,
+ .of_match_table = ralink_ehci_ids,
}
};
diff --git a/drivers/usb/host/ohci-platform.c b/drivers/usb/host/ohci-platform.c
index 68f674c..2a73fed 100644
--- a/drivers/usb/host/ohci-platform.c
+++ b/drivers/usb/host/ohci-platform.c
@@ -23,17 +23,20 @@
#include <linux/usb/ohci_pdriver.h>
#include <linux/usb.h>
#include <linux/usb/hcd.h>
+#include <linux/dma-mapping.h>
+#include <linux/of.h>
#include "ohci.h"
#define DRIVER_DESC "OHCI generic platform driver"
+static struct usb_ohci_pdata ohci_platform_defaults;
static const char hcd_name[] = "ohci-platform";
static int ohci_platform_reset(struct usb_hcd *hcd)
{
struct platform_device *pdev = to_platform_device(hcd->self.controller);
- struct usb_ohci_pdata *pdata = dev_get_platdata(&pdev->dev);
+ struct usb_ohci_pdata *pdata;
struct ohci_hcd *ohci = hcd_to_ohci(hcd);
if (pdata->big_endian_desc)
@@ -63,11 +66,18 @@ static int ohci_platform_probe(struct platform_device *dev)
int irq;
int err = -ENOMEM;
- if (!pdata) {
- WARN_ON(1);
- return -ENODEV;
- }
-
+ /*
+ * use reasonable defaults so platforms don't have to provide these.
+ * with DT probing on ARM, none of these are set.
+ */
+ if (!dev->dev.platform_data)
+ dev->dev.platform_data = &ohci_platform_defaults;
+ if (!dev->dev.dma_mask)
+ dev->dev.dma_mask = &dev->dev.coherent_dma_mask;
+ if (!dev->dev.coherent_dma_mask)
+ dev->dev.coherent_dma_mask = DMA_BIT_MASK(32);
+
+ pdata = dev->dev.platform_data;
if (usb_disabled())
return -ENODEV;
@@ -99,6 +109,12 @@ static int ohci_platform_probe(struct platform_device *dev)
hcd->rsrc_start = res_mem->start;
hcd->rsrc_len = resource_size(res_mem);
+#ifdef CONFIG_USB_PHY
+ hcd->phy = devm_usb_get_phy(&dev->dev, USB_PHY_TYPE_USB2);
+ if (!IS_ERR_OR_NULL(hcd->phy))
+ usb_phy_init(hcd->phy);
+#endif
+
hcd->regs = devm_ioremap_resource(&dev->dev, res_mem);
if (IS_ERR(hcd->regs)) {
err = PTR_ERR(hcd->regs);
@@ -134,6 +150,9 @@ static int ohci_platform_remove(struct platform_device *dev)
if (pdata->power_off)
pdata->power_off(dev);
+ if (pdata == &ohci_platform_defaults)
+ dev->dev.platform_data = NULL;
+
return 0;
}
@@ -180,6 +199,11 @@ static int ohci_platform_resume(struct device *dev)
#define ohci_platform_resume NULL
#endif /* CONFIG_PM */
+static const struct of_device_id ralink_ohci_ids[] = {
+ { .compatible = "ralink,rt3xxx-ohci", },
+ {}
+};
+
static const struct platform_device_id ohci_platform_table[] = {
{ "ohci-platform", 0 },
{ }
@@ -200,6 +224,7 @@ static struct platform_driver ohci_platform_driver = {
.owner = THIS_MODULE,
.name = "ohci-platform",
.pm = &ohci_platform_pm_ops,
+ .of_match_table = of_match_ptr(ralink_ohci_ids),
}
};
--
1.7.10.4

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,34 @@
From f0df443ca7d5d0e4d31aa6769ea12a8cf24d2cd8 Mon Sep 17 00:00:00 2001
From: John Crispin <blogic@openwrt.org>
Date: Mon, 15 Jul 2013 00:38:51 +0200
Subject: [PATCH 41/57] mtd: fix cfi cmdset 0002 erase status check
---
drivers/mtd/chips/cfi_cmdset_0002.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/drivers/mtd/chips/cfi_cmdset_0002.c b/drivers/mtd/chips/cfi_cmdset_0002.c
index 89b9d68..8d92fc1 100644
--- a/drivers/mtd/chips/cfi_cmdset_0002.c
+++ b/drivers/mtd/chips/cfi_cmdset_0002.c
@@ -1956,7 +1956,7 @@ static int __xipram do_erase_chip(struct map_info *map, struct flchip *chip)
chip->erase_suspended = 0;
}
- if (chip_ready(map, adr))
+ if (chip_good(map, adr, map_word_ff(map)))
break;
if (time_after(jiffies, timeo)) {
@@ -2045,7 +2045,7 @@ static int __xipram do_erase_oneblock(struct map_info *map, struct flchip *chip,
chip->erase_suspended = 0;
}
- if (chip_ready(map, adr)) {
+ if (chip_good(map, adr, map_word_ff(map))) {
xip_enable(map, chip, adr);
break;
}
--
1.7.10.4

View file

@ -0,0 +1,75 @@
From 39010a26a34a56a7928f9217ac23e5138c5ea952 Mon Sep 17 00:00:00 2001
From: John Crispin <blogic@openwrt.org>
Date: Mon, 15 Jul 2013 00:39:21 +0200
Subject: [PATCH 42/57] mtd: cfi cmdset 0002 force word write
---
drivers/mtd/chips/cfi_cmdset_0002.c | 9 +++++++--
1 file changed, 7 insertions(+), 2 deletions(-)
diff --git a/drivers/mtd/chips/cfi_cmdset_0002.c b/drivers/mtd/chips/cfi_cmdset_0002.c
index 8d92fc1..aa06d16 100644
--- a/drivers/mtd/chips/cfi_cmdset_0002.c
+++ b/drivers/mtd/chips/cfi_cmdset_0002.c
@@ -41,7 +41,7 @@
#include <linux/mtd/xip.h>
#define AMD_BOOTLOC_BUG
-#define FORCE_WORD_WRITE 0
+#define FORCE_WORD_WRITE 1
#define MAX_WORD_RETRIES 3
@@ -52,7 +52,9 @@
static int cfi_amdstd_read (struct mtd_info *, loff_t, size_t, size_t *, u_char *);
static int cfi_amdstd_write_words(struct mtd_info *, loff_t, size_t, size_t *, const u_char *);
+#if !FORCE_WORD_WRITE
static int cfi_amdstd_write_buffers(struct mtd_info *, loff_t, size_t, size_t *, const u_char *);
+#endif
static int cfi_amdstd_erase_chip(struct mtd_info *, struct erase_info *);
static int cfi_amdstd_erase_varsize(struct mtd_info *, struct erase_info *);
static void cfi_amdstd_sync (struct mtd_info *);
@@ -192,6 +194,7 @@ static void fixup_amd_bootblock(struct mtd_info *mtd)
}
#endif
+#if !FORCE_WORD_WRITE
static void fixup_use_write_buffers(struct mtd_info *mtd)
{
struct map_info *map = mtd->priv;
@@ -201,6 +204,7 @@ static void fixup_use_write_buffers(struct mtd_info *mtd)
mtd->_write = cfi_amdstd_write_buffers;
}
}
+#endif /* !FORCE_WORD_WRITE */
/* Atmel chips don't use the same PRI format as AMD chips */
static void fixup_convert_atmel_pri(struct mtd_info *mtd)
@@ -1461,6 +1465,7 @@ static int cfi_amdstd_write_words(struct mtd_info *mtd, loff_t to, size_t len,
/*
* FIXME: interleaved mode not tested, and probably not supported!
*/
+#if !FORCE_WORD_WRITE
static int __xipram do_write_buffer(struct map_info *map, struct flchip *chip,
unsigned long adr, const u_char *buf,
int len)
@@ -1584,7 +1589,6 @@ static int __xipram do_write_buffer(struct map_info *map, struct flchip *chip,
return ret;
}
-
static int cfi_amdstd_write_buffers(struct mtd_info *mtd, loff_t to, size_t len,
size_t *retlen, const u_char *buf)
{
@@ -1659,6 +1663,7 @@ static int cfi_amdstd_write_buffers(struct mtd_info *mtd, loff_t to, size_t len,
return 0;
}
+#endif /* !FORCE_WORD_WRITE */
/*
* Wait for the flash chip to become ready to write data
--
1.7.10.4

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,166 @@
From b6d5d4c3d595b4cfb6a052ac7151fdb1d9a776ea Mon Sep 17 00:00:00 2001
From: John Crispin <blogic@openwrt.org>
Date: Sun, 27 Jul 2014 09:58:09 +0100
Subject: [PATCH 44/57] mtd: add chunked read io to m25p80
Signed-off-by: John Crispin <blogic@openwrt.org>
---
drivers/mtd/devices/m25p80.c | 128 ++++++++++++++++++++++++++++++++++++++++++
1 file changed, 128 insertions(+)
diff --git a/drivers/mtd/devices/m25p80.c b/drivers/mtd/devices/m25p80.c
index ad19139..6f4290e 100644
--- a/drivers/mtd/devices/m25p80.c
+++ b/drivers/mtd/devices/m25p80.c
@@ -556,6 +556,58 @@ static int m25p80_read(struct mtd_info *mtd, loff_t from, size_t len,
return 0;
}
+static int m25p80_read_chunked(struct mtd_info *mtd, loff_t from, size_t len,
+ size_t *retlen, u_char *buf)
+{
+ struct m25p *flash = mtd_to_m25p(mtd);
+ struct spi_transfer t[2];
+ struct spi_message m;
+ uint8_t opcode;
+ int idx = 0;
+
+ pr_debug("%s: %s from 0x%08x, len %zd\n", dev_name(&flash->spi->dev),
+ __func__, (u32)from, len);
+
+ spi_message_init(&m);
+ memset(t, 0, (sizeof t));
+
+ t[0].tx_buf = flash->command;
+ t[0].len = m25p_cmdsz(flash);
+ spi_message_add_tail(&t[0], &m);
+ spi_message_add_tail(&t[1], &m);
+
+ *retlen = 0;
+
+ while (idx < len) {
+ int rlen = (len - idx > 4) ? (4) : (len - idx);
+
+ t[1].rx_buf = &buf[idx];
+ t[1].len = rlen;
+
+ mutex_lock(&flash->lock);
+
+ /* Wait till previous write/erase is done. */
+ if (wait_till_ready(flash)) {
+ /* REVISIT status return?? */
+ mutex_unlock(&flash->lock);
+ return 1;
+ }
+
+ /* Set up the write data buffer. */
+ opcode = OPCODE_NORM_READ;
+ flash->command[0] = opcode;
+ m25p_addr2cmd(flash, from + idx, flash->command);
+
+ spi_sync(flash->spi, &m);
+
+ *retlen += m.actual_length - m25p_cmdsz(flash);
+
+ mutex_unlock(&flash->lock);
+ idx += rlen;
+ }
+ return 0;
+}
+
/*
* Write an address range to the flash chip. Data must be written in
* FLASH_PAGESIZE chunks. The address range may be any size provided
@@ -643,6 +695,76 @@ static int m25p80_write(struct mtd_info *mtd, loff_t to, size_t len,
return 0;
}
+static int m25p80_write_chunked(struct mtd_info *mtd, loff_t to, size_t len,
+ size_t *retlen, const u_char *buf)
+{
+ struct m25p *flash = mtd_to_m25p(mtd);
+ struct spi_transfer t;
+ struct spi_message m;
+ u32 i, page_size;
+ u8 tmp[8];
+
+ pr_debug("%s: %s to 0x%08x, len %zd\n", dev_name(&flash->spi->dev),
+ __func__, (u32)to, len);
+
+ spi_message_init(&m);
+ memset(&t, 0, (sizeof t));
+
+ t.tx_buf = tmp;
+ t.len = 8;
+ spi_message_add_tail(&t, &m);
+
+ mutex_lock(&flash->lock);
+
+ /* Wait until finished previous write command. */
+ if (wait_till_ready(flash)) {
+ mutex_unlock(&flash->lock);
+ return 1;
+ }
+
+ write_enable(flash);
+
+ /* Set up the opcode in the write buffer. */
+ flash->command[0] = OPCODE_PP;
+ m25p_addr2cmd(flash, to, flash->command);
+
+ t.len = 4 + (to & 0x3);
+ if (t.len == 4)
+ t.len = 8;
+ memcpy(tmp, flash->command, 4);
+ memcpy(&tmp[4], buf, t.len - 4);
+ spi_sync(flash->spi, &m);
+ page_size = t.len - 4;
+
+ *retlen = m.actual_length - m25p_cmdsz(flash);
+
+ /* write everything in flash->page_size chunks */
+ for (i = page_size; i < len; i += page_size) {
+ page_size = len - i;
+ if (page_size > 4)
+ page_size = 4;
+
+ /* write the next page to flash */
+ m25p_addr2cmd(flash, to + i, flash->command);
+
+ memcpy(tmp, flash->command, 4);
+ memcpy(&tmp[4], buf + i, page_size);
+ t.len = 4 + page_size;
+
+ wait_till_ready(flash);
+
+ write_enable(flash);
+
+ spi_sync(flash->spi, &m);
+
+ *retlen += m.actual_length - m25p_cmdsz(flash);
+ }
+
+ mutex_unlock(&flash->lock);
+
+ return 0;
+}
+
static int sst_write(struct mtd_info *mtd, loff_t to, size_t len,
size_t *retlen, const u_char *buf)
{
@@ -1252,6 +1374,12 @@ static int m25p_probe(struct spi_device *spi)
return -EINVAL;
}
+ if (np && of_property_read_bool(np, "m25p,chunked-io")) {
+ dev_warn(&spi->dev, "using chunked io\n");
+ flash->mtd._read = m25p80_read_chunked;
+ flash->mtd._write = m25p80_write_chunked;
+ }
+
flash->program_opcode = OPCODE_PP;
if (info->addr_width)
--
1.7.10.4

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,65 @@
From 6827bd971fc4f323fc91e4506771a13b827c49a3 Mon Sep 17 00:00:00 2001
From: John Crispin <blogic@openwrt.org>
Date: Sun, 28 Jul 2013 19:45:30 +0200
Subject: [PATCH 46/57] DT: Add documentation for gpio-ralink
Describe gpio-ralink binding.
Signed-off-by: John Crispin <blogic@openwrt.org>
Cc: linux-mips@linux-mips.org
Cc: devicetree@vger.kernel.org
Cc: linux-gpio@vger.kernel.org
---
.../devicetree/bindings/gpio/gpio-ralink.txt | 40 ++++++++++++++++++++
1 file changed, 40 insertions(+)
create mode 100644 Documentation/devicetree/bindings/gpio/gpio-ralink.txt
diff --git a/Documentation/devicetree/bindings/gpio/gpio-ralink.txt b/Documentation/devicetree/bindings/gpio/gpio-ralink.txt
new file mode 100644
index 0000000..b4acf02
--- /dev/null
+++ b/Documentation/devicetree/bindings/gpio/gpio-ralink.txt
@@ -0,0 +1,40 @@
+Ralink SoC GPIO controller bindings
+
+Required properties:
+- compatible:
+ - "ralink,rt2880-gpio" for Ralink controllers
+- #gpio-cells : Should be two.
+ - first cell is the pin number
+ - second cell is used to specify optional parameters (unused)
+- gpio-controller : Marks the device node as a GPIO controller
+- reg : Physical base address and length of the controller's registers
+- interrupt-parent: phandle to the INTC device node
+- interrupts : Specify the INTC interrupt number
+- ralink,num-gpios : Specify the number of GPIOs
+- ralink,register-map : The register layout depends on the GPIO bank and actual
+ SoC type. Register offsets need to be in this order.
+ [ INT, EDGE, RENA, FENA, DATA, DIR, POL, SET, RESET, TOGGLE ]
+
+Optional properties:
+- ralink,gpio-base : Specify the GPIO chips base number
+
+Example:
+
+ gpio0: gpio@600 {
+ compatible = "ralink,rt5350-gpio", "ralink,rt2880-gpio";
+
+ #gpio-cells = <2>;
+ gpio-controller;
+
+ reg = <0x600 0x34>;
+
+ interrupt-parent = <&intc>;
+ interrupts = <6>;
+
+ ralink,gpio-base = <0>;
+ ralink,num-gpios = <24>;
+ ralink,register-map = [ 00 04 08 0c
+ 20 24 28 2c
+ 30 34 ];
+
+ };
--
1.7.10.4

View file

@ -0,0 +1,433 @@
From 4b23ed96930650076caa524ffdde898cb937bdaa Mon Sep 17 00:00:00 2001
From: John Crispin <blogic@openwrt.org>
Date: Mon, 4 Aug 2014 20:36:29 +0200
Subject: [PATCH 47/57] GPIO: MIPS: ralink: add gpio driver for ralink SoC
Add gpio driver for Ralink SoC. This driver makes the gpio core on
RT2880, RT305x, rt3352, rt3662, rt3883, rt5350 and mt7620 work.
Signed-off-by: John Crispin <blogic@openwrt.org>
Cc: linux-mips@linux-mips.org
Cc: linux-gpio@vger.kernel.org
---
arch/mips/include/asm/mach-ralink/gpio.h | 24 +++
drivers/gpio/Kconfig | 6 +
drivers/gpio/Makefile | 1 +
drivers/gpio/gpio-ralink.c | 345 ++++++++++++++++++++++++++++++
4 files changed, 376 insertions(+)
create mode 100644 arch/mips/include/asm/mach-ralink/gpio.h
create mode 100644 drivers/gpio/gpio-ralink.c
diff --git a/arch/mips/include/asm/mach-ralink/gpio.h b/arch/mips/include/asm/mach-ralink/gpio.h
new file mode 100644
index 0000000..f68ee16
--- /dev/null
+++ b/arch/mips/include/asm/mach-ralink/gpio.h
@@ -0,0 +1,24 @@
+/*
+ * Ralink SoC GPIO API support
+ *
+ * Copyright (C) 2008-2009 Gabor Juhos <juhosg@openwrt.org>
+ * Copyright (C) 2008 Imre Kaloz <kaloz@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 __ASM_MACH_RALINK_GPIO_H
+#define __ASM_MACH_RALINK_GPIO_H
+
+#define ARCH_NR_GPIOS 128
+#include <asm-generic/gpio.h>
+
+#define gpio_get_value __gpio_get_value
+#define gpio_set_value __gpio_set_value
+#define gpio_cansleep __gpio_cansleep
+#define gpio_to_irq __gpio_to_irq
+
+#endif /* __ASM_MACH_RALINK_GPIO_H */
diff --git a/drivers/gpio/Kconfig b/drivers/gpio/Kconfig
index 903f24d..2d75a68 100644
--- a/drivers/gpio/Kconfig
+++ b/drivers/gpio/Kconfig
@@ -260,6 +260,12 @@ config GPIO_SCH311X
To compile this driver as a module, choose M here: the module will
be called gpio-sch311x.
+config GPIO_RALINK
+ bool "Ralink GPIO Support"
+ depends on RALINK
+ help
+ Say yes here to support the Ralink SoC GPIO device
+
config GPIO_SPEAR_SPICS
bool "ST SPEAr13xx SPI Chip Select as GPIO support"
depends on PLAT_SPEAR
diff --git a/drivers/gpio/Makefile b/drivers/gpio/Makefile
index 5d50179..2cbdbe6 100644
--- a/drivers/gpio/Makefile
+++ b/drivers/gpio/Makefile
@@ -63,6 +63,7 @@ obj-$(CONFIG_GPIO_PCF857X) += gpio-pcf857x.o
obj-$(CONFIG_GPIO_PCH) += gpio-pch.o
obj-$(CONFIG_GPIO_PL061) += gpio-pl061.o
obj-$(CONFIG_GPIO_PXA) += gpio-pxa.o
+obj-$(CONFIG_GPIO_RALINK) += gpio-ralink.o
obj-$(CONFIG_GPIO_RC5T583) += gpio-rc5t583.o
obj-$(CONFIG_GPIO_RDC321X) += gpio-rdc321x.o
obj-$(CONFIG_GPIO_RCAR) += gpio-rcar.o
diff --git a/drivers/gpio/gpio-ralink.c b/drivers/gpio/gpio-ralink.c
new file mode 100644
index 0000000..7e5a2e9
--- /dev/null
+++ b/drivers/gpio/gpio-ralink.c
@@ -0,0 +1,345 @@
+/*
+ * 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) 2009-2011 Gabor Juhos <juhosg@openwrt.org>
+ * Copyright (C) 2013 John Crispin <blogic@openwrt.org>
+ */
+
+#include <linux/module.h>
+#include <linux/io.h>
+#include <linux/gpio.h>
+#include <linux/spinlock.h>
+#include <linux/platform_device.h>
+#include <linux/of_irq.h>
+#include <linux/irqdomain.h>
+#include <linux/interrupt.h>
+
+enum ralink_gpio_reg {
+ GPIO_REG_INT = 0,
+ GPIO_REG_EDGE,
+ GPIO_REG_RENA,
+ GPIO_REG_FENA,
+ GPIO_REG_DATA,
+ GPIO_REG_DIR,
+ GPIO_REG_POL,
+ GPIO_REG_SET,
+ GPIO_REG_RESET,
+ GPIO_REG_TOGGLE,
+ GPIO_REG_MAX
+};
+
+struct ralink_gpio_chip {
+ struct gpio_chip chip;
+ u8 regs[GPIO_REG_MAX];
+
+ spinlock_t lock;
+ void __iomem *membase;
+ struct irq_domain *domain;
+ int irq;
+
+ u32 rising;
+ u32 falling;
+};
+
+#define MAP_MAX 4
+static struct irq_domain *irq_map[MAP_MAX];
+static int irq_map_count;
+static atomic_t irq_refcount = ATOMIC_INIT(0);
+
+static inline struct ralink_gpio_chip *to_ralink_gpio(struct gpio_chip *chip)
+{
+ struct ralink_gpio_chip *rg;
+
+ rg = container_of(chip, struct ralink_gpio_chip, chip);
+
+ return rg;
+}
+
+static inline void rt_gpio_w32(struct ralink_gpio_chip *rg, u8 reg, u32 val)
+{
+ iowrite32(val, rg->membase + rg->regs[reg]);
+}
+
+static inline u32 rt_gpio_r32(struct ralink_gpio_chip *rg, u8 reg)
+{
+ return ioread32(rg->membase + rg->regs[reg]);
+}
+
+static void ralink_gpio_set(struct gpio_chip *chip, unsigned offset, int value)
+{
+ struct ralink_gpio_chip *rg = to_ralink_gpio(chip);
+
+ rt_gpio_w32(rg, (value) ? GPIO_REG_SET : GPIO_REG_RESET, BIT(offset));
+}
+
+static int ralink_gpio_get(struct gpio_chip *chip, unsigned offset)
+{
+ struct ralink_gpio_chip *rg = to_ralink_gpio(chip);
+
+ return !!(rt_gpio_r32(rg, GPIO_REG_DATA) & BIT(offset));
+}
+
+static int ralink_gpio_direction_input(struct gpio_chip *chip, unsigned offset)
+{
+ struct ralink_gpio_chip *rg = to_ralink_gpio(chip);
+ unsigned long flags;
+ u32 t;
+
+ spin_lock_irqsave(&rg->lock, flags);
+ t = rt_gpio_r32(rg, GPIO_REG_DIR);
+ t &= ~BIT(offset);
+ rt_gpio_w32(rg, GPIO_REG_DIR, t);
+ spin_unlock_irqrestore(&rg->lock, flags);
+
+ return 0;
+}
+
+static int ralink_gpio_direction_output(struct gpio_chip *chip,
+ unsigned offset, int value)
+{
+ struct ralink_gpio_chip *rg = to_ralink_gpio(chip);
+ unsigned long flags;
+ u32 t;
+
+ spin_lock_irqsave(&rg->lock, flags);
+ ralink_gpio_set(chip, offset, value);
+ t = rt_gpio_r32(rg, GPIO_REG_DIR);
+ t |= BIT(offset);
+ rt_gpio_w32(rg, GPIO_REG_DIR, t);
+ spin_unlock_irqrestore(&rg->lock, flags);
+
+ return 0;
+}
+
+static int ralink_gpio_to_irq(struct gpio_chip *chip, unsigned pin)
+{
+ struct ralink_gpio_chip *rg = to_ralink_gpio(chip);
+
+ if (rg->irq < 1)
+ return -1;
+
+ return irq_create_mapping(rg->domain, pin);
+}
+
+static void ralink_gpio_irq_handler(unsigned int irq, struct irq_desc *desc)
+{
+ int i;
+
+ for (i = 0; i < irq_map_count; i++) {
+ struct irq_domain *domain = irq_map[i];
+ struct ralink_gpio_chip *rg;
+ unsigned long pending;
+ int bit;
+
+ rg = (struct ralink_gpio_chip *) domain->host_data;
+ pending = rt_gpio_r32(rg, GPIO_REG_INT);
+
+ for_each_set_bit(bit, &pending, rg->chip.ngpio) {
+ u32 map = irq_find_mapping(domain, bit);
+ generic_handle_irq(map);
+ rt_gpio_w32(rg, GPIO_REG_INT, BIT(bit));
+ }
+ }
+}
+
+static void ralink_gpio_irq_unmask(struct irq_data *d)
+{
+ struct ralink_gpio_chip *rg;
+ unsigned long flags;
+ u32 val;
+
+ rg = (struct ralink_gpio_chip *) d->domain->host_data;
+ val = rt_gpio_r32(rg, GPIO_REG_RENA);
+
+ spin_lock_irqsave(&rg->lock, flags);
+ rt_gpio_w32(rg, GPIO_REG_RENA, val | (BIT(d->hwirq) & rg->rising));
+ rt_gpio_w32(rg, GPIO_REG_FENA, val | (BIT(d->hwirq) & rg->falling));
+ spin_unlock_irqrestore(&rg->lock, flags);
+}
+
+static void ralink_gpio_irq_mask(struct irq_data *d)
+{
+ struct ralink_gpio_chip *rg;
+ unsigned long flags;
+ u32 val;
+
+ rg = (struct ralink_gpio_chip *) d->domain->host_data;
+ val = rt_gpio_r32(rg, GPIO_REG_RENA);
+
+ spin_lock_irqsave(&rg->lock, flags);
+ rt_gpio_w32(rg, GPIO_REG_FENA, val & ~BIT(d->hwirq));
+ rt_gpio_w32(rg, GPIO_REG_RENA, val & ~BIT(d->hwirq));
+ spin_unlock_irqrestore(&rg->lock, flags);
+}
+
+static int ralink_gpio_irq_type(struct irq_data *d, unsigned int type)
+{
+ struct ralink_gpio_chip *rg;
+ u32 mask = BIT(d->hwirq);
+
+ rg = (struct ralink_gpio_chip *) d->domain->host_data;
+
+ if (type == IRQ_TYPE_PROBE) {
+ if ((rg->rising | rg->falling) & mask)
+ return 0;
+
+ type = IRQ_TYPE_EDGE_RISING | IRQ_TYPE_EDGE_FALLING;
+ }
+
+ if (type & IRQ_TYPE_EDGE_RISING)
+ rg->rising |= mask;
+ else
+ rg->rising &= ~mask;
+
+ if (type & IRQ_TYPE_EDGE_FALLING)
+ rg->falling |= mask;
+ else
+ rg->falling &= ~mask;
+
+ return 0;
+}
+
+static struct irq_chip ralink_gpio_irq_chip = {
+ .name = "GPIO",
+ .irq_unmask = ralink_gpio_irq_unmask,
+ .irq_mask = ralink_gpio_irq_mask,
+ .irq_mask_ack = ralink_gpio_irq_mask,
+ .irq_set_type = ralink_gpio_irq_type,
+};
+
+static int gpio_map(struct irq_domain *d, unsigned int irq, irq_hw_number_t hw)
+{
+ irq_set_chip_and_handler(irq, &ralink_gpio_irq_chip, handle_level_irq);
+ irq_set_handler_data(irq, d);
+
+ return 0;
+}
+
+static const struct irq_domain_ops irq_domain_ops = {
+ .xlate = irq_domain_xlate_onecell,
+ .map = gpio_map,
+};
+
+static void ralink_gpio_irq_init(struct device_node *np,
+ struct ralink_gpio_chip *rg)
+{
+ if (irq_map_count >= MAP_MAX)
+ return;
+
+ rg->irq = irq_of_parse_and_map(np, 0);
+ if (!rg->irq)
+ return;
+
+ rg->domain = irq_domain_add_linear(np, rg->chip.ngpio,
+ &irq_domain_ops, rg);
+ if (!rg->domain) {
+ dev_err(rg->chip.dev, "irq_domain_add_linear failed\n");
+ return;
+ }
+
+ irq_map[irq_map_count++] = rg->domain;
+
+ rt_gpio_w32(rg, GPIO_REG_RENA, 0x0);
+ rt_gpio_w32(rg, GPIO_REG_FENA, 0x0);
+
+ if (!atomic_read(&irq_refcount))
+ irq_set_chained_handler(rg->irq, ralink_gpio_irq_handler);
+ atomic_inc(&irq_refcount);
+
+ dev_info(rg->chip.dev, "registering %d irq handlers\n", rg->chip.ngpio);
+}
+
+static int ralink_gpio_request(struct gpio_chip *chip, unsigned offset)
+{
+ int gpio = chip->base + offset;
+
+ return pinctrl_request_gpio(gpio);
+}
+
+static int ralink_gpio_probe(struct platform_device *pdev)
+{
+ struct device_node *np = pdev->dev.of_node;
+ struct resource *res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+ struct ralink_gpio_chip *rg;
+ const __be32 *ngpio, *gpiobase;
+
+ if (!res) {
+ dev_err(&pdev->dev, "failed to find resource\n");
+ return -ENOMEM;
+ }
+
+ rg = devm_kzalloc(&pdev->dev,
+ sizeof(struct ralink_gpio_chip), GFP_KERNEL);
+ if (!rg)
+ return -ENOMEM;
+
+ rg->membase = devm_request_and_ioremap(&pdev->dev, res);
+ if (!rg->membase) {
+ dev_err(&pdev->dev, "cannot remap I/O memory region\n");
+ return -ENOMEM;
+ }
+
+ if (of_property_read_u8_array(np, "ralink,register-map",
+ rg->regs, GPIO_REG_MAX)) {
+ dev_err(&pdev->dev, "failed to read register definition\n");
+ return -EINVAL;
+ }
+
+ ngpio = of_get_property(np, "ralink,num-gpios", NULL);
+ if (!ngpio) {
+ dev_err(&pdev->dev, "failed to read number of pins\n");
+ return -EINVAL;
+ }
+
+ gpiobase = of_get_property(np, "ralink,gpio-base", NULL);
+ if (gpiobase)
+ rg->chip.base = be32_to_cpu(*gpiobase);
+ else
+ rg->chip.base = -1;
+
+ spin_lock_init(&rg->lock);
+
+ rg->chip.dev = &pdev->dev;
+ rg->chip.label = dev_name(&pdev->dev);
+ rg->chip.of_node = np;
+ rg->chip.ngpio = be32_to_cpu(*ngpio);
+ rg->chip.direction_input = ralink_gpio_direction_input;
+ rg->chip.direction_output = ralink_gpio_direction_output;
+ rg->chip.get = ralink_gpio_get;
+ rg->chip.set = ralink_gpio_set;
+ rg->chip.request = ralink_gpio_request;
+ rg->chip.to_irq = ralink_gpio_to_irq;
+
+ /* set polarity to low for all lines */
+ rt_gpio_w32(rg, GPIO_REG_POL, 0);
+
+ dev_info(&pdev->dev, "registering %d gpios\n", rg->chip.ngpio);
+
+ ralink_gpio_irq_init(np, rg);
+
+ return gpiochip_add(&rg->chip);
+}
+
+static const struct of_device_id ralink_gpio_match[] = {
+ { .compatible = "ralink,rt2880-gpio" },
+ {},
+};
+MODULE_DEVICE_TABLE(of, ralink_gpio_match);
+
+static struct platform_driver ralink_gpio_driver = {
+ .probe = ralink_gpio_probe,
+ .driver = {
+ .name = "rt2880_gpio",
+ .owner = THIS_MODULE,
+ .of_match_table = ralink_gpio_match,
+ },
+};
+
+static int __init ralink_gpio_init(void)
+{
+ return platform_driver_register(&ralink_gpio_driver);
+}
+
+subsys_initcall(ralink_gpio_init);
--
1.7.10.4

View file

@ -0,0 +1,240 @@
From 8481cdf6f96dc16cbcc129d046c021d17a891274 Mon Sep 17 00:00:00 2001
From: John Crispin <blogic@openwrt.org>
Date: Sun, 27 Jul 2014 11:00:32 +0100
Subject: [PATCH 48/57] GPIO: ralink: add mt7621 gpio controller
Signed-off-by: John Crispin <blogic@openwrt.org>
---
arch/mips/Kconfig | 3 +
drivers/gpio/Kconfig | 6 ++
drivers/gpio/Makefile | 1 +
drivers/gpio/gpio-mt7621.c | 177 ++++++++++++++++++++++++++++++++++++++++++++
4 files changed, 187 insertions(+)
create mode 100644 drivers/gpio/gpio-mt7621.c
diff --git a/arch/mips/Kconfig b/arch/mips/Kconfig
index 4ac98ca..fd3bbb1 100644
--- a/arch/mips/Kconfig
+++ b/arch/mips/Kconfig
@@ -437,6 +437,9 @@ config RALINK
select RESET_CONTROLLER
select PINCTRL
select PINCTRL_RT2880
+ select ARCH_HAS_RESET_CONTROLLER
+ select RESET_CONTROLLER
+ select ARCH_REQUIRE_GPIOLIB
config SGI_IP22
bool "SGI IP22 (Indy/Indigo2)"
diff --git a/drivers/gpio/Kconfig b/drivers/gpio/Kconfig
index 2d75a68..5dff8d5 100644
--- a/drivers/gpio/Kconfig
+++ b/drivers/gpio/Kconfig
@@ -827,6 +827,12 @@ config GPIO_BCM_KONA
help
Turn on GPIO support for Broadcom "Kona" chips.
+config GPIO_MT7621
+ bool "Mediatek GPIO Support"
+ depends on SOC_MT7620 || SOC_MT7621
+ help
+ Say yes here to support the Mediatek SoC GPIO device
+
comment "USB GPIO expanders:"
config GPIO_VIPERBOARD
diff --git a/drivers/gpio/Makefile b/drivers/gpio/Makefile
index 2cbdbe6..2365e34 100644
--- a/drivers/gpio/Makefile
+++ b/drivers/gpio/Makefile
@@ -100,3 +100,4 @@ obj-$(CONFIG_GPIO_WM8350) += gpio-wm8350.o
obj-$(CONFIG_GPIO_WM8994) += gpio-wm8994.o
obj-$(CONFIG_GPIO_XILINX) += gpio-xilinx.o
obj-$(CONFIG_GPIO_XTENSA) += gpio-xtensa.o
+obj-$(CONFIG_GPIO_MT7621) += gpio-mt7621.o
diff --git a/drivers/gpio/gpio-mt7621.c b/drivers/gpio/gpio-mt7621.c
new file mode 100644
index 0000000..7ae7eb9
--- /dev/null
+++ b/drivers/gpio/gpio-mt7621.c
@@ -0,0 +1,177 @@
+/*
+ * 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) 2009-2011 Gabor Juhos <juhosg@openwrt.org>
+ * Copyright (C) 2013 John Crispin <blogic@openwrt.org>
+ */
+
+#include <linux/io.h>
+#include <linux/err.h>
+#include <linux/gpio.h>
+#include <linux/module.h>
+#include <linux/of_irq.h>
+#include <linux/spinlock.h>
+#include <linux/irqdomain.h>
+#include <linux/interrupt.h>
+#include <linux/platform_device.h>
+
+#define MTK_BANK_WIDTH 32
+
+enum mediatek_gpio_reg {
+ GPIO_REG_CTRL = 0,
+ GPIO_REG_POL,
+ GPIO_REG_DATA,
+ GPIO_REG_DSET,
+ GPIO_REG_DCLR,
+};
+
+static void __iomem *mtk_gc_membase;
+
+struct mtk_gc {
+ struct gpio_chip chip;
+ spinlock_t lock;
+ int bank;
+};
+
+static inline struct mtk_gc
+*to_mediatek_gpio(struct gpio_chip *chip)
+{
+ struct mtk_gc *mgc;
+
+ mgc = container_of(chip, struct mtk_gc, chip);
+
+ return mgc;
+}
+
+static inline void
+mtk_gpio_w32(struct mtk_gc *rg, u8 reg, u32 val)
+{
+ iowrite32(val, mtk_gc_membase + (reg * 0x10) + (rg->bank * 0x4));
+}
+
+static inline u32
+mtk_gpio_r32(struct mtk_gc *rg, u8 reg)
+{
+ return ioread32(mtk_gc_membase + (reg * 0x10) + (rg->bank * 0x4));
+}
+
+static void
+mediatek_gpio_set(struct gpio_chip *chip, unsigned offset, int value)
+{
+ struct mtk_gc *rg = to_mediatek_gpio(chip);
+
+ mtk_gpio_w32(rg, (value) ? GPIO_REG_DSET : GPIO_REG_DCLR, BIT(offset));
+}
+
+static int
+mediatek_gpio_get(struct gpio_chip *chip, unsigned offset)
+{
+ struct mtk_gc *rg = to_mediatek_gpio(chip);
+
+ return !!(mtk_gpio_r32(rg, GPIO_REG_DATA) & BIT(offset));
+}
+
+static int
+mediatek_gpio_direction_input(struct gpio_chip *chip, unsigned offset)
+{
+ struct mtk_gc *rg = to_mediatek_gpio(chip);
+ unsigned long flags;
+ u32 t;
+
+ spin_lock_irqsave(&rg->lock, flags);
+ t = mtk_gpio_r32(rg, GPIO_REG_CTRL);
+ t &= ~BIT(offset);
+ mtk_gpio_w32(rg, GPIO_REG_CTRL, t);
+ spin_unlock_irqrestore(&rg->lock, flags);
+
+ return 0;
+}
+
+static int
+mediatek_gpio_direction_output(struct gpio_chip *chip,
+ unsigned offset, int value)
+{
+ struct mtk_gc *rg = to_mediatek_gpio(chip);
+ unsigned long flags;
+ u32 t;
+
+ spin_lock_irqsave(&rg->lock, flags);
+ t = mtk_gpio_r32(rg, GPIO_REG_CTRL);
+ t |= BIT(offset);
+ mtk_gpio_w32(rg, GPIO_REG_CTRL, t);
+ mediatek_gpio_set(chip, offset, value);
+ spin_unlock_irqrestore(&rg->lock, flags);
+
+ return 0;
+}
+
+static int
+mediatek_gpio_bank_probe(struct platform_device *pdev, struct device_node *bank)
+{
+ const __be32 *id = of_get_property(bank, "reg", NULL);
+ struct mtk_gc *rg = devm_kzalloc(&pdev->dev,
+ sizeof(struct mtk_gc), GFP_KERNEL);
+ if (!rg || !id)
+ return -ENOMEM;
+
+ spin_lock_init(&rg->lock);
+
+ rg->chip.dev = &pdev->dev;
+ rg->chip.label = dev_name(&pdev->dev);
+ rg->chip.of_node = bank;
+ rg->chip.base = MTK_BANK_WIDTH * be32_to_cpu(*id);
+ rg->chip.ngpio = MTK_BANK_WIDTH;
+ rg->chip.direction_input = mediatek_gpio_direction_input;
+ rg->chip.direction_output = mediatek_gpio_direction_output;
+ rg->chip.get = mediatek_gpio_get;
+ rg->chip.set = mediatek_gpio_set;
+
+ /* set polarity to low for all gpios */
+ mtk_gpio_w32(rg, GPIO_REG_POL, 0);
+
+ dev_info(&pdev->dev, "registering %d gpios\n", rg->chip.ngpio);
+
+ return gpiochip_add(&rg->chip);
+}
+
+static int
+mediatek_gpio_probe(struct platform_device *pdev)
+{
+ struct device_node *bank, *np = pdev->dev.of_node;
+ struct resource *res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+
+ mtk_gc_membase = devm_request_and_ioremap(&pdev->dev, res);
+ if (IS_ERR(mtk_gc_membase))
+ return PTR_ERR(mtk_gc_membase);
+
+ for_each_child_of_node(np, bank)
+ if (of_device_is_compatible(bank, "mtk,mt7621-gpio-bank"))
+ mediatek_gpio_bank_probe(pdev, bank);
+
+ return 0;
+}
+
+static const struct of_device_id mediatek_gpio_match[] = {
+ { .compatible = "mtk,mt7621-gpio" },
+ {},
+};
+MODULE_DEVICE_TABLE(of, mediatek_gpio_match);
+
+static struct platform_driver mediatek_gpio_driver = {
+ .probe = mediatek_gpio_probe,
+ .driver = {
+ .name = "mt7621_gpio",
+ .owner = THIS_MODULE,
+ .of_match_table = mediatek_gpio_match,
+ },
+};
+
+static int __init
+mediatek_gpio_init(void)
+{
+ return platform_driver_register(&mediatek_gpio_driver);
+}
+
+subsys_initcall(mediatek_gpio_init);
--
1.7.10.4

View file

@ -0,0 +1,50 @@
From 6ed8d03e5f4283b60dffea5c10ff1484141824e7 Mon Sep 17 00:00:00 2001
From: John Crispin <blogic@openwrt.org>
Date: Fri, 9 Aug 2013 20:12:59 +0200
Subject: [PATCH 49/57] DT: Add documentation for spi-rt2880
Describe the SPI master found on the MIPS based Ralink RT2880 SoC.
Signed-off-by: John Crispin <blogic@openwrt.org>
---
.../devicetree/bindings/spi/spi-rt2880.txt | 28 ++++++++++++++++++++
1 file changed, 28 insertions(+)
create mode 100644 Documentation/devicetree/bindings/spi/spi-rt2880.txt
diff --git a/Documentation/devicetree/bindings/spi/spi-rt2880.txt b/Documentation/devicetree/bindings/spi/spi-rt2880.txt
new file mode 100644
index 0000000..068bc90
--- /dev/null
+++ b/Documentation/devicetree/bindings/spi/spi-rt2880.txt
@@ -0,0 +1,28 @@
+Ralink SoC RT2880 SPI master controller.
+
+This SPI controller is found on most wireless SoCs made by ralink.
+
+Required properties:
+- compatible : "ralink,rt2880-spi"
+- reg : The register base for the controller.
+- #address-cells : <1>, as required by generic SPI binding.
+- #size-cells : <0>, also as required by generic SPI binding.
+
+Child nodes as per the generic SPI binding.
+
+Example:
+
+ spi@b00 {
+ compatible = "ralink,rt2880-spi";
+ reg = <0xb00 0x100>;
+
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ m25p80@0 {
+ compatible = "m25p80";
+ reg = <0>;
+ spi-max-frequency = <10000000>;
+ };
+ };
+
--
1.7.10.4

View file

@ -0,0 +1,486 @@
From fc006d0622ab8c43086b2c9018c03012db332033 Mon Sep 17 00:00:00 2001
From: John Crispin <blogic@openwrt.org>
Date: Sun, 27 Jul 2014 11:15:12 +0100
Subject: [PATCH 50/57] SPI: ralink: add Ralink SoC spi driver
Add the driver needed to make SPI work on Ralink SoC.
Signed-off-by: Gabor Juhos <juhosg@openwrt.org>
Acked-by: John Crispin <blogic@openwrt.org>
---
drivers/spi/Kconfig | 6 +
drivers/spi/Makefile | 1 +
drivers/spi/spi-rt2880.c | 432 ++++++++++++++++++++++++++++++++++++++++++++++
3 files changed, 439 insertions(+)
create mode 100644 drivers/spi/spi-rt2880.c
diff --git a/drivers/spi/Kconfig b/drivers/spi/Kconfig
index 581ee2a..009f8f3 100644
--- a/drivers/spi/Kconfig
+++ b/drivers/spi/Kconfig
@@ -381,6 +381,12 @@ config SPI_RSPI
help
SPI driver for Renesas RSPI and QSPI blocks.
+config SPI_RT2880
+ tristate "Ralink RT288x SPI Controller"
+ depends on RALINK
+ help
+ This selects a driver for the Ralink RT288x/RT305x SPI Controller.
+
config SPI_S3C24XX
tristate "Samsung S3C24XX series SPI"
depends on ARCH_S3C24XX
diff --git a/drivers/spi/Makefile b/drivers/spi/Makefile
index 95af48d..1f647e5 100644
--- a/drivers/spi/Makefile
+++ b/drivers/spi/Makefile
@@ -60,6 +60,7 @@ spi-pxa2xx-platform-$(CONFIG_SPI_PXA2XX_DMA) += spi-pxa2xx-dma.o
obj-$(CONFIG_SPI_PXA2XX) += spi-pxa2xx-platform.o
obj-$(CONFIG_SPI_PXA2XX_PCI) += spi-pxa2xx-pci.o
obj-$(CONFIG_SPI_RSPI) += spi-rspi.o
+obj-$(CONFIG_SPI_RT2880) += spi-rt2880.o
obj-$(CONFIG_SPI_S3C24XX) += spi-s3c24xx-hw.o
spi-s3c24xx-hw-y := spi-s3c24xx.o
spi-s3c24xx-hw-$(CONFIG_SPI_S3C24XX_FIQ) += spi-s3c24xx-fiq.o
diff --git a/drivers/spi/spi-rt2880.c b/drivers/spi/spi-rt2880.c
new file mode 100644
index 0000000..ac9de67
--- /dev/null
+++ b/drivers/spi/spi-rt2880.c
@@ -0,0 +1,432 @@
+/*
+ * spi-rt2880.c -- Ralink RT288x/RT305x SPI controller driver
+ *
+ * Copyright (C) 2011 Sergiy <piratfm@gmail.com>
+ * Copyright (C) 2011-2013 Gabor Juhos <juhosg@openwrt.org>
+ *
+ * Some parts are based on spi-orion.c:
+ * Author: Shadi Ammouri <shadi@marvell.com>
+ * Copyright (C) 2007-2008 Marvell Ltd.
+ *
+ * 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/init.h>
+#include <linux/module.h>
+#include <linux/clk.h>
+#include <linux/err.h>
+#include <linux/delay.h>
+#include <linux/io.h>
+#include <linux/reset.h>
+#include <linux/spi/spi.h>
+#include <linux/platform_device.h>
+
+#define DRIVER_NAME "spi-rt2880"
+/* only one slave is supported*/
+#define RALINK_NUM_CHIPSELECTS 1
+/* in usec */
+#define RALINK_SPI_WAIT_MAX_LOOP 2000
+
+#define RAMIPS_SPI_STAT 0x00
+#define RAMIPS_SPI_CFG 0x10
+#define RAMIPS_SPI_CTL 0x14
+#define RAMIPS_SPI_DATA 0x20
+#define RAMIPS_SPI_FIFO_STAT 0x38
+
+/* SPISTAT register bit field */
+#define SPISTAT_BUSY BIT(0)
+
+/* SPICFG register bit field */
+#define SPICFG_LSBFIRST 0
+#define SPICFG_MSBFIRST BIT(8)
+#define SPICFG_SPICLKPOL BIT(6)
+#define SPICFG_RXCLKEDGE_FALLING BIT(5)
+#define SPICFG_TXCLKEDGE_FALLING BIT(4)
+#define SPICFG_SPICLK_PRESCALE_MASK 0x7
+#define SPICFG_SPICLK_DIV2 0
+#define SPICFG_SPICLK_DIV4 1
+#define SPICFG_SPICLK_DIV8 2
+#define SPICFG_SPICLK_DIV16 3
+#define SPICFG_SPICLK_DIV32 4
+#define SPICFG_SPICLK_DIV64 5
+#define SPICFG_SPICLK_DIV128 6
+#define SPICFG_SPICLK_DISABLE 7
+
+/* SPICTL register bit field */
+#define SPICTL_HIZSDO BIT(3)
+#define SPICTL_STARTWR BIT(2)
+#define SPICTL_STARTRD BIT(1)
+#define SPICTL_SPIENA BIT(0)
+
+/* SPIFIFOSTAT register bit field */
+#define SPIFIFOSTAT_TXFULL BIT(17)
+
+struct rt2880_spi {
+ struct spi_master *master;
+ void __iomem *base;
+ unsigned int sys_freq;
+ unsigned int speed;
+ struct clk *clk;
+ spinlock_t lock;
+};
+
+static inline struct rt2880_spi *spidev_to_rt2880_spi(struct spi_device *spi)
+{
+ return spi_master_get_devdata(spi->master);
+}
+
+static inline u32 rt2880_spi_read(struct rt2880_spi *rs, u32 reg)
+{
+ return ioread32(rs->base + reg);
+}
+
+static inline void rt2880_spi_write(struct rt2880_spi *rs, u32 reg, u32 val)
+{
+ iowrite32(val, rs->base + reg);
+}
+
+static inline void rt2880_spi_setbits(struct rt2880_spi *rs, u32 reg, u32 mask)
+{
+ void __iomem *addr = rs->base + reg;
+ unsigned long flags;
+ u32 val;
+
+ spin_lock_irqsave(&rs->lock, flags);
+ val = ioread32(addr);
+ val |= mask;
+ iowrite32(val, addr);
+ spin_unlock_irqrestore(&rs->lock, flags);
+}
+
+static inline void rt2880_spi_clrbits(struct rt2880_spi *rs, u32 reg, u32 mask)
+{
+ void __iomem *addr = rs->base + reg;
+ unsigned long flags;
+ u32 val;
+
+ spin_lock_irqsave(&rs->lock, flags);
+ val = ioread32(addr);
+ val &= ~mask;
+ iowrite32(val, addr);
+ spin_unlock_irqrestore(&rs->lock, flags);
+}
+
+static int rt2880_spi_baudrate_set(struct spi_device *spi, unsigned int speed)
+{
+ struct rt2880_spi *rs = spidev_to_rt2880_spi(spi);
+ u32 rate;
+ u32 prescale;
+ u32 reg;
+
+ dev_dbg(&spi->dev, "speed:%u\n", speed);
+
+ /*
+ * the supported rates are: 2, 4, 8, ... 128
+ * round up as we look for equal or less speed
+ */
+ rate = DIV_ROUND_UP(rs->sys_freq, speed);
+ dev_dbg(&spi->dev, "rate-1:%u\n", rate);
+ rate = roundup_pow_of_two(rate);
+ dev_dbg(&spi->dev, "rate-2:%u\n", rate);
+
+ /* check if requested speed is too small */
+ if (rate > 128)
+ return -EINVAL;
+
+ if (rate < 2)
+ rate = 2;
+
+ /* Convert the rate to SPI clock divisor value. */
+ prescale = ilog2(rate / 2);
+ dev_dbg(&spi->dev, "prescale:%u\n", prescale);
+
+ reg = rt2880_spi_read(rs, RAMIPS_SPI_CFG);
+ reg = ((reg & ~SPICFG_SPICLK_PRESCALE_MASK) | prescale);
+ rt2880_spi_write(rs, RAMIPS_SPI_CFG, reg);
+ rs->speed = speed;
+ return 0;
+}
+
+/*
+ * called only when no transfer is active on the bus
+ */
+static int
+rt2880_spi_setup_transfer(struct spi_device *spi, struct spi_transfer *t)
+{
+ struct rt2880_spi *rs = spidev_to_rt2880_spi(spi);
+ unsigned int speed = spi->max_speed_hz;
+ int rc;
+
+ if ((t != NULL) && t->speed_hz)
+ speed = t->speed_hz;
+
+ if (rs->speed != speed) {
+ dev_dbg(&spi->dev, "speed_hz:%u\n", speed);
+ rc = rt2880_spi_baudrate_set(spi, speed);
+ if (rc)
+ return rc;
+ }
+
+ return 0;
+}
+
+static void rt2880_spi_set_cs(struct rt2880_spi *rs, int enable)
+{
+ if (enable)
+ rt2880_spi_clrbits(rs, RAMIPS_SPI_CTL, SPICTL_SPIENA);
+ else
+ rt2880_spi_setbits(rs, RAMIPS_SPI_CTL, SPICTL_SPIENA);
+}
+
+static inline int rt2880_spi_wait_till_ready(struct rt2880_spi *rs)
+{
+ int i;
+
+ for (i = 0; i < RALINK_SPI_WAIT_MAX_LOOP; i++) {
+ u32 status;
+
+ status = rt2880_spi_read(rs, RAMIPS_SPI_STAT);
+ if ((status & SPISTAT_BUSY) == 0)
+ return 0;
+
+ cpu_relax();
+ udelay(1);
+ }
+
+ return -ETIMEDOUT;
+}
+
+static unsigned int
+rt2880_spi_write_read(struct spi_device *spi, struct spi_transfer *xfer)
+{
+ struct rt2880_spi *rs = spidev_to_rt2880_spi(spi);
+ unsigned count = 0;
+ u8 *rx = xfer->rx_buf;
+ const u8 *tx = xfer->tx_buf;
+ int err;
+
+ dev_dbg(&spi->dev, "read (%d): %s %s\n", xfer->len,
+ (tx != NULL) ? "tx" : " ",
+ (rx != NULL) ? "rx" : " ");
+
+ if (tx) {
+ for (count = 0; count < xfer->len; count++) {
+ rt2880_spi_write(rs, RAMIPS_SPI_DATA, tx[count]);
+ rt2880_spi_setbits(rs, RAMIPS_SPI_CTL, SPICTL_STARTWR);
+ err = rt2880_spi_wait_till_ready(rs);
+ if (err) {
+ dev_err(&spi->dev, "TX failed, err=%d\n", err);
+ goto out;
+ }
+ }
+ }
+
+ if (rx) {
+ for (count = 0; count < xfer->len; count++) {
+ rt2880_spi_setbits(rs, RAMIPS_SPI_CTL, SPICTL_STARTRD);
+ err = rt2880_spi_wait_till_ready(rs);
+ if (err) {
+ dev_err(&spi->dev, "RX failed, err=%d\n", err);
+ goto out;
+ }
+ rx[count] = (u8) rt2880_spi_read(rs, RAMIPS_SPI_DATA);
+ }
+ }
+
+out:
+ return count;
+}
+
+static int rt2880_spi_transfer_one_message(struct spi_master *master,
+ struct spi_message *m)
+{
+ struct rt2880_spi *rs = spi_master_get_devdata(master);
+ struct spi_device *spi = m->spi;
+ struct spi_transfer *t = NULL;
+ int par_override = 0;
+ int status = 0;
+ int cs_active = 0;
+
+ /* Load defaults */
+ status = rt2880_spi_setup_transfer(spi, NULL);
+ if (status < 0)
+ goto msg_done;
+
+ list_for_each_entry(t, &m->transfers, transfer_list) {
+ if (t->tx_buf == NULL && t->rx_buf == NULL && t->len) {
+ dev_err(&spi->dev,
+ "message rejected: invalid transfer data buffers\n");
+ status = -EIO;
+ goto msg_done;
+ }
+
+ if (t->speed_hz && t->speed_hz < (rs->sys_freq / 128)) {
+ dev_err(&spi->dev,
+ "message rejected: device min speed (%d Hz) exceeds required transfer speed (%d Hz)\n",
+ (rs->sys_freq / 128), t->speed_hz);
+ status = -EIO;
+ goto msg_done;
+ }
+
+ if (par_override || t->speed_hz || t->bits_per_word) {
+ par_override = 1;
+ status = rt2880_spi_setup_transfer(spi, t);
+ if (status < 0)
+ goto msg_done;
+ if (!t->speed_hz && !t->bits_per_word)
+ par_override = 0;
+ }
+
+ if (!cs_active) {
+ rt2880_spi_set_cs(rs, 1);
+ cs_active = 1;
+ }
+
+ if (t->len)
+ m->actual_length += rt2880_spi_write_read(spi, t);
+
+ if (t->delay_usecs)
+ udelay(t->delay_usecs);
+
+ if (t->cs_change) {
+ rt2880_spi_set_cs(rs, 0);
+ cs_active = 0;
+ }
+ }
+
+msg_done:
+ if (cs_active)
+ rt2880_spi_set_cs(rs, 0);
+
+ m->status = status;
+ spi_finalize_current_message(master);
+
+ return 0;
+}
+
+static int rt2880_spi_setup(struct spi_device *spi)
+{
+ struct rt2880_spi *rs = spidev_to_rt2880_spi(spi);
+
+ if ((spi->max_speed_hz == 0) ||
+ (spi->max_speed_hz > (rs->sys_freq / 2)))
+ spi->max_speed_hz = (rs->sys_freq / 2);
+
+ if (spi->max_speed_hz < (rs->sys_freq / 128)) {
+ dev_err(&spi->dev, "setup: requested speed is too low %d Hz\n",
+ spi->max_speed_hz);
+ return -EINVAL;
+ }
+
+ /*
+ * baudrate & width will be set rt2880_spi_setup_transfer
+ */
+ return 0;
+}
+
+static void rt2880_spi_reset(struct rt2880_spi *rs)
+{
+ rt2880_spi_write(rs, RAMIPS_SPI_CFG,
+ SPICFG_MSBFIRST | SPICFG_TXCLKEDGE_FALLING |
+ SPICFG_SPICLK_DIV16 | SPICFG_SPICLKPOL);
+ rt2880_spi_write(rs, RAMIPS_SPI_CTL, SPICTL_HIZSDO | SPICTL_SPIENA);
+}
+
+static int rt2880_spi_probe(struct platform_device *pdev)
+{
+ struct spi_master *master;
+ struct rt2880_spi *rs;
+ unsigned long flags;
+ void __iomem *base;
+ struct resource *r;
+ int status = 0;
+ struct clk *clk;
+
+ r = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+ base = devm_ioremap_resource(&pdev->dev, r);
+ if (IS_ERR(base))
+ return PTR_ERR(base);
+
+ clk = devm_clk_get(&pdev->dev, NULL);
+ if (IS_ERR(clk)) {
+ dev_err(&pdev->dev, "unable to get SYS clock, err=%d\n",
+ status);
+ return PTR_ERR(clk);
+ }
+
+ status = clk_prepare_enable(clk);
+ if (status)
+ return status;
+
+ master = spi_alloc_master(&pdev->dev, sizeof(*rs));
+ if (master == NULL) {
+ dev_dbg(&pdev->dev, "master allocation failed\n");
+ return -ENOMEM;
+ }
+
+ /* we support only mode 0, and no options */
+ master->mode_bits = 0;
+
+ master->setup = rt2880_spi_setup;
+ master->transfer_one_message = rt2880_spi_transfer_one_message;
+ master->num_chipselect = RALINK_NUM_CHIPSELECTS;
+ master->bits_per_word_mask = SPI_BPW_MASK(8);
+ master->dev.of_node = pdev->dev.of_node;
+
+ dev_set_drvdata(&pdev->dev, master);
+
+ rs = spi_master_get_devdata(master);
+ rs->base = base;
+ rs->clk = clk;
+ rs->master = master;
+ rs->sys_freq = clk_get_rate(rs->clk);
+ dev_dbg(&pdev->dev, "sys_freq: %u\n", rs->sys_freq);
+ spin_lock_irqsave(&rs->lock, flags);
+
+ device_reset(&pdev->dev);
+
+ rt2880_spi_reset(rs);
+
+ return spi_register_master(master);
+}
+
+static int rt2880_spi_remove(struct platform_device *pdev)
+{
+ struct spi_master *master;
+ struct rt2880_spi *rs;
+
+ master = dev_get_drvdata(&pdev->dev);
+ rs = spi_master_get_devdata(master);
+
+ clk_disable(rs->clk);
+ spi_unregister_master(master);
+
+ return 0;
+}
+
+MODULE_ALIAS("platform:" DRIVER_NAME);
+
+static const struct of_device_id rt2880_spi_match[] = {
+ { .compatible = "ralink,rt2880-spi" },
+ {},
+};
+MODULE_DEVICE_TABLE(of, rt2880_spi_match);
+
+static struct platform_driver rt2880_spi_driver = {
+ .driver = {
+ .name = DRIVER_NAME,
+ .owner = THIS_MODULE,
+ .of_match_table = rt2880_spi_match,
+ },
+ .probe = rt2880_spi_probe,
+ .remove = rt2880_spi_remove,
+};
+
+module_platform_driver(rt2880_spi_driver);
+
+MODULE_DESCRIPTION("Ralink SPI driver");
+MODULE_AUTHOR("Sergiy <piratfm@gmail.com>");
+MODULE_AUTHOR("Gabor Juhos <juhosg@openwrt.org>");
+MODULE_LICENSE("GPL");
--
1.7.10.4

View file

@ -0,0 +1,351 @@
From 27b11d4f1888e1a3d6d75b46d4d5a4d86fc03891 Mon Sep 17 00:00:00 2001
From: John Crispin <blogic@openwrt.org>
Date: Wed, 6 Aug 2014 10:53:40 +0200
Subject: [PATCH 51/57] SPI: MIPS: ralink: add mt7621 support
Signed-off-by: John Crispin <blogic@openwrt.org>
---
drivers/spi/spi-rt2880.c | 218 +++++++++++++++++++++++++++++++++++++++++++---
1 file changed, 205 insertions(+), 13 deletions(-)
diff --git a/drivers/spi/spi-rt2880.c b/drivers/spi/spi-rt2880.c
index ac9de67..1c6b72d 100644
--- a/drivers/spi/spi-rt2880.c
+++ b/drivers/spi/spi-rt2880.c
@@ -21,8 +21,13 @@
#include <linux/io.h>
#include <linux/reset.h>
#include <linux/spi/spi.h>
+#include <linux/of_device.h>
#include <linux/platform_device.h>
+#include <ralink_regs.h>
+
+#define SPI_BPW_MASK(bits) BIT((bits) - 1)
+
#define DRIVER_NAME "spi-rt2880"
/* only one slave is supported*/
#define RALINK_NUM_CHIPSELECTS 1
@@ -63,6 +68,25 @@
/* SPIFIFOSTAT register bit field */
#define SPIFIFOSTAT_TXFULL BIT(17)
+#define MT7621_SPI_TRANS 0x00
+#define SPITRANS_BUSY BIT(16)
+#define MT7621_SPI_OPCODE 0x04
+#define MT7621_SPI_DATA0 0x08
+#define SPI_CTL_TX_RX_CNT_MASK 0xff
+#define SPI_CTL_START BIT(8)
+#define MT7621_SPI_POLAR 0x38
+#define MT7621_SPI_MASTER 0x28
+#define MT7621_SPI_SPACE 0x3c
+
+struct rt2880_spi;
+
+struct rt2880_spi_ops {
+ void (*init_hw)(struct rt2880_spi *rs);
+ void (*set_cs)(struct rt2880_spi *rs, int enable);
+ int (*baudrate_set)(struct spi_device *spi, unsigned int speed);
+ unsigned int (*write_read)(struct spi_device *spi, struct list_head *list, struct spi_transfer *xfer);
+};
+
struct rt2880_spi {
struct spi_master *master;
void __iomem *base;
@@ -70,6 +94,8 @@ struct rt2880_spi {
unsigned int speed;
struct clk *clk;
spinlock_t lock;
+
+ struct rt2880_spi_ops *ops;
};
static inline struct rt2880_spi *spidev_to_rt2880_spi(struct spi_device *spi)
@@ -149,6 +175,17 @@ static int rt2880_spi_baudrate_set(struct spi_device *spi, unsigned int speed)
return 0;
}
+static int mt7621_spi_baudrate_set(struct spi_device *spi, unsigned int speed)
+{
+/* u32 master = rt2880_spi_read(rs, MT7621_SPI_MASTER);
+
+ // set default clock to hclk/5
+ master &= ~(0xfff << 16);
+ master |= 0x3 << 16;
+*/
+ return 0;
+}
+
/*
* called only when no transfer is active on the bus
*/
@@ -164,7 +201,7 @@ rt2880_spi_setup_transfer(struct spi_device *spi, struct spi_transfer *t)
if (rs->speed != speed) {
dev_dbg(&spi->dev, "speed_hz:%u\n", speed);
- rc = rt2880_spi_baudrate_set(spi, speed);
+ rc = rs->ops->baudrate_set(spi, speed);
if (rc)
return rc;
}
@@ -180,6 +217,17 @@ static void rt2880_spi_set_cs(struct rt2880_spi *rs, int enable)
rt2880_spi_setbits(rs, RAMIPS_SPI_CTL, SPICTL_SPIENA);
}
+static void mt7621_spi_set_cs(struct rt2880_spi *rs, int enable)
+{
+ u32 polar = rt2880_spi_read(rs, MT7621_SPI_POLAR);
+
+ if (enable)
+ polar |= 1;
+ else
+ polar &= ~1;
+ rt2880_spi_write(rs, MT7621_SPI_POLAR, polar);
+}
+
static inline int rt2880_spi_wait_till_ready(struct rt2880_spi *rs)
{
int i;
@@ -198,8 +246,26 @@ static inline int rt2880_spi_wait_till_ready(struct rt2880_spi *rs)
return -ETIMEDOUT;
}
+static inline int mt7621_spi_wait_till_ready(struct rt2880_spi *rs)
+{
+ int i;
+
+ for (i = 0; i < RALINK_SPI_WAIT_MAX_LOOP; i++) {
+ u32 status;
+
+ status = rt2880_spi_read(rs, MT7621_SPI_TRANS);
+ if ((status & SPITRANS_BUSY) == 0) {
+ return 0;
+ }
+ cpu_relax();
+ udelay(1);
+ }
+
+ return -ETIMEDOUT;
+}
+
static unsigned int
-rt2880_spi_write_read(struct spi_device *spi, struct spi_transfer *xfer)
+rt2880_spi_write_read(struct spi_device *spi, struct list_head *list, struct spi_transfer *xfer)
{
struct rt2880_spi *rs = spidev_to_rt2880_spi(spi);
unsigned count = 0;
@@ -239,6 +305,100 @@ out:
return count;
}
+static unsigned int
+mt7621_spi_write_read(struct spi_device *spi, struct list_head *list, struct spi_transfer *xfer)
+{
+ struct rt2880_spi *rs = spidev_to_rt2880_spi(spi);
+ struct spi_transfer *next = NULL;
+ const u8 *tx = xfer->tx_buf;
+ u8 *rx = NULL;
+ u32 trans;
+ int len = xfer->len;
+
+ if (!tx)
+ return 0;
+
+ if (!list_is_last(&xfer->transfer_list, list)) {
+ next = list_entry(xfer->transfer_list.next, struct spi_transfer, transfer_list);
+ rx = next->rx_buf;
+ }
+
+ trans = rt2880_spi_read(rs, MT7621_SPI_TRANS);
+ trans &= ~SPI_CTL_TX_RX_CNT_MASK;
+
+ if (tx) {
+ u32 data0 = 0, opcode = 0;
+
+ switch (xfer->len) {
+ case 8:
+ data0 |= tx[7] << 24;
+ case 7:
+ data0 |= tx[6] << 16;
+ case 6:
+ data0 |= tx[5] << 8;
+ case 5:
+ data0 |= tx[4];
+ case 4:
+ opcode |= tx[3] << 8;
+ case 3:
+ opcode |= tx[2] << 16;
+ case 2:
+ opcode |= tx[1] << 24;
+ case 1:
+ opcode |= tx[0];
+ break;
+
+ default:
+ dev_err(&spi->dev, "trying to write too many bytes: %d\n", next->len);
+ return -EINVAL;
+ }
+
+ rt2880_spi_write(rs, MT7621_SPI_DATA0, data0);
+ rt2880_spi_write(rs, MT7621_SPI_OPCODE, opcode);
+ trans |= xfer->len;
+ }
+
+ if (rx)
+ trans |= (next->len << 4);
+ rt2880_spi_write(rs, MT7621_SPI_TRANS, trans);
+ trans |= SPI_CTL_START;
+ rt2880_spi_write(rs, MT7621_SPI_TRANS, trans);
+
+ mt7621_spi_wait_till_ready(rs);
+
+ if (rx) {
+ u32 data0 = rt2880_spi_read(rs, MT7621_SPI_DATA0);
+ u32 opcode = rt2880_spi_read(rs, MT7621_SPI_OPCODE);
+
+ switch (next->len) {
+ case 8:
+ rx[7] = (opcode >> 24) & 0xff;
+ case 7:
+ rx[6] = (opcode >> 16) & 0xff;
+ case 6:
+ rx[5] = (opcode >> 8) & 0xff;
+ case 5:
+ rx[4] = opcode & 0xff;
+ case 4:
+ rx[3] = (data0 >> 24) & 0xff;
+ case 3:
+ rx[2] = (data0 >> 16) & 0xff;
+ case 2:
+ rx[1] = (data0 >> 8) & 0xff;
+ case 1:
+ rx[0] = data0 & 0xff;
+ break;
+
+ default:
+ dev_err(&spi->dev, "trying to read too many bytes: %d\n", next->len);
+ return -EINVAL;
+ }
+ len += next->len;
+ }
+
+ return len;
+}
+
static int rt2880_spi_transfer_one_message(struct spi_master *master,
struct spi_message *m)
{
@@ -280,25 +440,25 @@ static int rt2880_spi_transfer_one_message(struct spi_master *master,
}
if (!cs_active) {
- rt2880_spi_set_cs(rs, 1);
+ rs->ops->set_cs(rs, 1);
cs_active = 1;
}
if (t->len)
- m->actual_length += rt2880_spi_write_read(spi, t);
+ m->actual_length += rs->ops->write_read(spi, &m->transfers, t);
if (t->delay_usecs)
udelay(t->delay_usecs);
if (t->cs_change) {
- rt2880_spi_set_cs(rs, 0);
+ rs->ops->set_cs(rs, 0);
cs_active = 0;
}
}
msg_done:
if (cs_active)
- rt2880_spi_set_cs(rs, 0);
+ rs->ops->set_cs(rs, 0);
m->status = status;
spi_finalize_current_message(master);
@@ -334,8 +494,41 @@ static void rt2880_spi_reset(struct rt2880_spi *rs)
rt2880_spi_write(rs, RAMIPS_SPI_CTL, SPICTL_HIZSDO | SPICTL_SPIENA);
}
+static void mt7621_spi_reset(struct rt2880_spi *rs)
+{
+ u32 master = rt2880_spi_read(rs, MT7621_SPI_MASTER);
+
+ master &= ~(0xfff << 16);
+ master |= 3 << 16;
+
+ master |= 7 << 29;
+ rt2880_spi_write(rs, MT7621_SPI_MASTER, master);
+}
+
+static struct rt2880_spi_ops spi_ops[] = {
+ {
+ .init_hw = rt2880_spi_reset,
+ .set_cs = rt2880_spi_set_cs,
+ .baudrate_set = rt2880_spi_baudrate_set,
+ .write_read = rt2880_spi_write_read,
+ }, {
+ .init_hw = mt7621_spi_reset,
+ .set_cs = mt7621_spi_set_cs,
+ .baudrate_set = mt7621_spi_baudrate_set,
+ .write_read = mt7621_spi_write_read,
+ },
+};
+
+static const struct of_device_id rt2880_spi_match[] = {
+ { .compatible = "ralink,rt2880-spi", .data = &spi_ops[0]},
+ { .compatible = "ralink,mt7621-spi", .data = &spi_ops[1] },
+ {},
+};
+MODULE_DEVICE_TABLE(of, rt2880_spi_match);
+
static int rt2880_spi_probe(struct platform_device *pdev)
{
+ const struct of_device_id *match;
struct spi_master *master;
struct rt2880_spi *rs;
unsigned long flags;
@@ -344,6 +537,10 @@ static int rt2880_spi_probe(struct platform_device *pdev)
int status = 0;
struct clk *clk;
+ match = of_match_device(rt2880_spi_match, &pdev->dev);
+ if (!match)
+ return -EINVAL;
+
r = platform_get_resource(pdev, IORESOURCE_MEM, 0);
base = devm_ioremap_resource(&pdev->dev, r);
if (IS_ERR(base))
@@ -382,12 +579,13 @@ static int rt2880_spi_probe(struct platform_device *pdev)
rs->clk = clk;
rs->master = master;
rs->sys_freq = clk_get_rate(rs->clk);
+ rs->ops = (struct rt2880_spi_ops *) match->data;
dev_dbg(&pdev->dev, "sys_freq: %u\n", rs->sys_freq);
spin_lock_irqsave(&rs->lock, flags);
device_reset(&pdev->dev);
- rt2880_spi_reset(rs);
+ rs->ops->init_hw(rs);
return spi_register_master(master);
}
@@ -408,12 +606,6 @@ static int rt2880_spi_remove(struct platform_device *pdev)
MODULE_ALIAS("platform:" DRIVER_NAME);
-static const struct of_device_id rt2880_spi_match[] = {
- { .compatible = "ralink,rt2880-spi" },
- {},
-};
-MODULE_DEVICE_TABLE(of, rt2880_spi_match);
-
static struct platform_driver rt2880_spi_driver = {
.driver = {
.name = DRIVER_NAME,
--
1.7.10.4

View file

@ -0,0 +1,358 @@
From 225f36695bb07dad9510f9affd79e63f1a44a195 Mon Sep 17 00:00:00 2001
From: John Crispin <blogic@openwrt.org>
Date: Sun, 27 Jul 2014 09:52:56 +0100
Subject: [PATCH 52/57] i2c: MIPS: adds ralink I2C driver
Signed-off-by: John Crispin <blogic@openwrt.org>
---
.../devicetree/bindings/i2c/i2c-ralink.txt | 27 ++
drivers/i2c/busses/Kconfig | 4 +
drivers/i2c/busses/Makefile | 1 +
drivers/i2c/busses/i2c-ralink.c | 274 ++++++++++++++++++++
4 files changed, 306 insertions(+)
create mode 100644 Documentation/devicetree/bindings/i2c/i2c-ralink.txt
create mode 100644 drivers/i2c/busses/i2c-ralink.c
diff --git a/Documentation/devicetree/bindings/i2c/i2c-ralink.txt b/Documentation/devicetree/bindings/i2c/i2c-ralink.txt
new file mode 100644
index 0000000..8fa8ac3
--- /dev/null
+++ b/Documentation/devicetree/bindings/i2c/i2c-ralink.txt
@@ -0,0 +1,27 @@
+I2C for Ralink platforms
+
+Required properties :
+- compatible : Must be "link,rt3052-i2c"
+- reg: physical base address of the controller and length of memory mapped
+ region.
+- #address-cells = <1>;
+- #size-cells = <0>;
+
+Optional properties:
+- Child nodes conforming to i2c bus binding
+
+Example :
+
+palmbus@10000000 {
+ i2c@900 {
+ compatible = "link,rt3052-i2c";
+ reg = <0x900 0x100>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ hwmon@4b {
+ compatible = "national,lm92";
+ reg = <0x4b>;
+ };
+ };
+};
diff --git a/drivers/i2c/busses/Kconfig b/drivers/i2c/busses/Kconfig
index de17c55..d773b72 100644
--- a/drivers/i2c/busses/Kconfig
+++ b/drivers/i2c/busses/Kconfig
@@ -658,6 +658,10 @@ config I2C_RIIC
This driver can also be built as a module. If so, the module
will be called i2c-riic.
+config I2C_RALINK
+ tristate "Ralink I2C Controller"
+ select OF_I2C
+
config HAVE_S3C2410_I2C
bool
help
diff --git a/drivers/i2c/busses/Makefile b/drivers/i2c/busses/Makefile
index a08931f..9682895 100644
--- a/drivers/i2c/busses/Makefile
+++ b/drivers/i2c/busses/Makefile
@@ -63,6 +63,7 @@ obj-$(CONFIG_I2C_PNX) += i2c-pnx.o
obj-$(CONFIG_I2C_PUV3) += i2c-puv3.o
obj-$(CONFIG_I2C_PXA) += i2c-pxa.o
obj-$(CONFIG_I2C_PXA_PCI) += i2c-pxa-pci.o
+obj-$(CONFIG_I2C_RALINK) += i2c-ralink.o
obj-$(CONFIG_I2C_RIIC) += i2c-riic.o
obj-$(CONFIG_I2C_S3C2410) += i2c-s3c2410.o
obj-$(CONFIG_I2C_S6000) += i2c-s6000.o
diff --git a/drivers/i2c/busses/i2c-ralink.c b/drivers/i2c/busses/i2c-ralink.c
new file mode 100644
index 0000000..f4dc13d
--- /dev/null
+++ b/drivers/i2c/busses/i2c-ralink.c
@@ -0,0 +1,274 @@
+/*
+ * drivers/i2c/busses/i2c-ralink.c
+ *
+ * Copyright (C) 2013 Steven Liu <steven_liu@mediatek.com>
+ *
+ * This software is licensed under the terms of the GNU General Public
+ * License version 2, as published by the Free Software Foundation, and
+ * may be copied, distributed, and modified under those terms.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ */
+
+#include <linux/interrupt.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/reset.h>
+#include <linux/delay.h>
+#include <linux/slab.h>
+#include <linux/init.h>
+#include <linux/errno.h>
+#include <linux/platform_device.h>
+#include <linux/i2c.h>
+#include <linux/io.h>
+#include <linux/of_i2c.h>
+#include <linux/err.h>
+
+#include <asm/mach-ralink/ralink_regs.h>
+
+#define REG_CONFIG_REG 0x00
+#define REG_CLKDIV_REG 0x04
+#define REG_DEVADDR_REG 0x08
+#define REG_ADDR_REG 0x0C
+#define REG_DATAOUT_REG 0x10
+#define REG_DATAIN_REG 0x14
+#define REG_STATUS_REG 0x18
+#define REG_STARTXFR_REG 0x1C
+#define REG_BYTECNT_REG 0x20
+
+#define I2C_STARTERR BIT(4)
+#define I2C_ACKERR BIT(3)
+#define I2C_DATARDY BIT(2)
+#define I2C_SDOEMPTY BIT(1)
+#define I2C_BUSY BIT(0)
+
+#define I2C_DEVADLEN_7 (6 << 2)
+#define I2C_ADDRDIS BIT(1)
+
+#define I2C_RETRY 0x400
+
+#define CLKDIV_VALUE 200 // clock rate is 40M, 40M / (200*2) = 100k (standard i2c bus rate).
+//#define CLKDIV_VALUE 50 // clock rate is 40M, 40M / (50*2) = 400k (fast i2c bus rate).
+
+#define READ_CMD 0x01
+#define WRITE_CMD 0x00
+#define READ_BLOCK 64
+
+static void __iomem *membase;
+static struct i2c_adapter *adapter;
+
+static void rt_i2c_w32(u32 val, unsigned reg)
+{
+ iowrite32(val, membase + reg);
+}
+
+static u32 rt_i2c_r32(unsigned reg)
+{
+ return ioread32(membase + reg);
+}
+
+static inline int rt_i2c_wait_rx_done(void)
+{
+ int retries = I2C_RETRY;
+
+ do {
+ if (!retries--)
+ break;
+ } while(!(rt_i2c_r32(REG_STATUS_REG) & I2C_DATARDY));
+
+ return (retries < 0);
+}
+
+static inline int rt_i2c_wait_idle(void)
+{
+ int retries = I2C_RETRY;
+
+ do {
+ if (!retries--)
+ break;
+ } while(rt_i2c_r32(REG_STATUS_REG) & I2C_BUSY);
+
+ return (retries < 0);
+}
+
+static inline int rt_i2c_wait_tx_done(void)
+{
+ int retries = I2C_RETRY;
+
+ do {
+ if (!retries--)
+ break;
+ } while(!(rt_i2c_r32(REG_STATUS_REG) & I2C_SDOEMPTY));
+
+ return (retries < 0);
+}
+
+static int rt_i2c_handle_msg(struct i2c_adapter *a, struct i2c_msg* msg)
+{
+ int i = 0, j = 0, pos = 0;
+ int nblock = msg->len / READ_BLOCK;
+ int rem = msg->len % READ_BLOCK;
+
+ if (msg->flags & I2C_M_TEN) {
+ printk("10 bits addr not supported\n");
+ return -EINVAL;
+ }
+
+ if (msg->flags & I2C_M_RD) {
+ for (i = 0; i < nblock; i++) {
+ rt_i2c_wait_idle();
+ rt_i2c_w32(READ_BLOCK - 1, REG_BYTECNT_REG);
+ rt_i2c_w32(READ_CMD, REG_STARTXFR_REG);
+ for (j = 0; j < READ_BLOCK; j++) {
+ if (rt_i2c_wait_rx_done())
+ return -1;
+ msg->buf[pos++] = rt_i2c_r32(REG_DATAIN_REG);
+ }
+ }
+
+ rt_i2c_wait_idle();
+ rt_i2c_w32(rem - 1, REG_BYTECNT_REG);
+ rt_i2c_w32(READ_CMD, REG_STARTXFR_REG);
+ for (i = 0; i < rem; i++) {
+ if (rt_i2c_wait_rx_done())
+ return -1;
+ msg->buf[pos++] = rt_i2c_r32(REG_DATAIN_REG);
+ }
+ } else {
+ rt_i2c_wait_idle();
+ rt_i2c_w32(msg->len - 1, REG_BYTECNT_REG);
+ for (i = 0; i < msg->len; i++) {
+ rt_i2c_w32(msg->buf[i], REG_DATAOUT_REG);
+ rt_i2c_w32(WRITE_CMD, REG_STARTXFR_REG);
+ if (rt_i2c_wait_tx_done())
+ return -1;
+ }
+ }
+
+ return 0;
+}
+
+static int rt_i2c_master_xfer(struct i2c_adapter *a, struct i2c_msg *m, int n)
+{
+ int i = 0;
+ int ret = 0;
+
+ if (rt_i2c_wait_idle()) {
+ printk("i2c transfer failed\n");
+ return 0;
+ }
+
+ device_reset(a->dev.parent);
+
+ rt_i2c_w32(m->addr, REG_DEVADDR_REG);
+ rt_i2c_w32(I2C_DEVADLEN_7 | I2C_ADDRDIS, REG_CONFIG_REG);
+ rt_i2c_w32(CLKDIV_VALUE, REG_CLKDIV_REG);
+
+ for (i = 0; i < n && !ret; i++)
+ ret = rt_i2c_handle_msg(a, &m[i]);
+
+ if (ret) {
+ printk("i2c transfer failed\n");
+ return 0;
+ }
+
+ return n;
+}
+
+static u32 rt_i2c_func(struct i2c_adapter *a)
+{
+ return I2C_FUNC_I2C | I2C_FUNC_SMBUS_EMUL;
+}
+
+static const struct i2c_algorithm rt_i2c_algo = {
+ .master_xfer = rt_i2c_master_xfer,
+ .functionality = rt_i2c_func,
+};
+
+static int rt_i2c_probe(struct platform_device *pdev)
+{
+ struct resource *res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+ int ret;
+
+ if (!res) {
+ dev_err(&pdev->dev, "no memory resource found\n");
+ return -ENODEV;
+ }
+
+ adapter = devm_kzalloc(&pdev->dev, sizeof(struct i2c_adapter), GFP_KERNEL);
+ if (!adapter) {
+ dev_err(&pdev->dev, "failed to allocate i2c_adapter\n");
+ return -ENOMEM;
+ }
+
+ membase = devm_request_and_ioremap(&pdev->dev, res);
+ if (IS_ERR(membase))
+ return PTR_ERR(membase);
+
+ strlcpy(adapter->name, dev_name(&pdev->dev), sizeof(adapter->name));
+ adapter->owner = THIS_MODULE;
+ adapter->nr = pdev->id;
+ adapter->timeout = HZ;
+ adapter->algo = &rt_i2c_algo;
+ adapter->class = I2C_CLASS_HWMON | I2C_CLASS_SPD;
+ adapter->dev.parent = &pdev->dev;
+ adapter->dev.of_node = pdev->dev.of_node;
+
+ ret = i2c_add_numbered_adapter(adapter);
+ if (ret)
+ return ret;
+
+ of_i2c_register_devices(adapter);
+
+ platform_set_drvdata(pdev, adapter);
+
+ dev_info(&pdev->dev, "loaded\n");
+
+ return 0;
+}
+
+static int rt_i2c_remove(struct platform_device *pdev)
+{
+ platform_set_drvdata(pdev, NULL);
+
+ return 0;
+}
+
+static const struct of_device_id i2c_rt_dt_ids[] = {
+ { .compatible = "ralink,rt2880-i2c", },
+ { /* sentinel */ }
+};
+
+MODULE_DEVICE_TABLE(of, i2c_rt_dt_ids);
+
+static struct platform_driver rt_i2c_driver = {
+ .probe = rt_i2c_probe,
+ .remove = rt_i2c_remove,
+ .driver = {
+ .owner = THIS_MODULE,
+ .name = "i2c-ralink",
+ .of_match_table = i2c_rt_dt_ids,
+ },
+};
+
+static int __init i2c_rt_init (void)
+{
+ return platform_driver_register(&rt_i2c_driver);
+}
+subsys_initcall(i2c_rt_init);
+
+static void __exit i2c_rt_exit (void)
+{
+ platform_driver_unregister(&rt_i2c_driver);
+}
+
+module_exit (i2c_rt_exit);
+
+MODULE_AUTHOR("Steven Liu <steven_liu@mediatek.com>");
+MODULE_DESCRIPTION("Ralink I2c host driver");
+MODULE_LICENSE("GPL");
+MODULE_ALIAS("platform:Ralink-I2C");
--
1.7.10.4

View file

@ -0,0 +1,676 @@
From cf93418a4bd5e69f069a65da92537bd4d6191223 Mon Sep 17 00:00:00 2001
From: John Crispin <blogic@openwrt.org>
Date: Sun, 27 Jul 2014 09:29:51 +0100
Subject: [PATCH 54/57] DMA: ralink: add rt2880 dma engine
Signed-off-by: John Crispin <blogic@openwrt.org>
---
drivers/dma/Kconfig | 6 +
drivers/dma/Makefile | 1 +
drivers/dma/dmaengine.c | 26 ++
drivers/dma/ralink-gdma.c | 577 +++++++++++++++++++++++++++++++++++++++++++++
include/linux/dmaengine.h | 1 +
5 files changed, 611 insertions(+)
create mode 100644 drivers/dma/ralink-gdma.c
diff --git a/drivers/dma/Kconfig b/drivers/dma/Kconfig
index 605b016..a9b31ff 100644
--- a/drivers/dma/Kconfig
+++ b/drivers/dma/Kconfig
@@ -351,6 +351,12 @@ config MOXART_DMA
help
Enable support for the MOXA ART SoC DMA controller.
+config DMA_RALINK
+ tristate "RALINK DMA support"
+ depends on RALINK && SOC_MT7620
+ select DMA_ENGINE
+ select DMA_VIRTUAL_CHANNELS
+
config DMA_ENGINE
bool
diff --git a/drivers/dma/Makefile b/drivers/dma/Makefile
index a029d0f4..419ccc2 100644
--- a/drivers/dma/Makefile
+++ b/drivers/dma/Makefile
@@ -44,3 +44,4 @@ obj-$(CONFIG_DMA_JZ4740) += dma-jz4740.o
obj-$(CONFIG_TI_CPPI41) += cppi41.o
obj-$(CONFIG_K3_DMA) += k3dma.o
obj-$(CONFIG_MOXART_DMA) += moxart-dma.o
+obj-$(CONFIG_DMA_RALINK) += ralink-gdma.o
diff --git a/drivers/dma/dmaengine.c b/drivers/dma/dmaengine.c
index ed610b4..cc11e0b 100644
--- a/drivers/dma/dmaengine.c
+++ b/drivers/dma/dmaengine.c
@@ -564,6 +564,32 @@ struct dma_chan *dma_get_any_slave_channel(struct dma_device *device)
EXPORT_SYMBOL_GPL(dma_get_any_slave_channel);
/**
+ * dma_request_slave_channel - try to get specific channel exclusively
+ * @chan: target channel
+ */
+struct dma_chan *dma_get_slave_channel(struct dma_chan *chan)
+{
+ int err = -EBUSY;
+
+ /* lock against __dma_request_channel */
+ mutex_lock(&dma_list_mutex);
+
+ if (chan->client_count == 0) {
+ err = dma_chan_get(chan);
+ if (err)
+ pr_debug("%s: failed to get %s: (%d)\n",
+ __func__, dma_chan_name(chan), err);
+ } else
+ chan = NULL;
+
+ mutex_unlock(&dma_list_mutex);
+
+ return chan;
+}
+EXPORT_SYMBOL_GPL(dma_get_slave_channel);
+
+
+/**
* __dma_request_channel - try to allocate an exclusive channel
* @mask: capabilities that the channel must satisfy
* @fn: optional callback to disposition available channels
diff --git a/drivers/dma/ralink-gdma.c b/drivers/dma/ralink-gdma.c
new file mode 100644
index 0000000..2c3cace
--- /dev/null
+++ b/drivers/dma/ralink-gdma.c
@@ -0,0 +1,577 @@
+/*
+ * Copyright (C) 2013, Lars-Peter Clausen <lars@metafoo.de>
+ * GDMA4740 DMAC support
+ *
+ * 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.
+ *
+ * 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.
+ *
+ */
+
+#include <linux/dmaengine.h>
+#include <linux/dma-mapping.h>
+#include <linux/err.h>
+#include <linux/init.h>
+#include <linux/list.h>
+#include <linux/module.h>
+#include <linux/platform_device.h>
+#include <linux/slab.h>
+#include <linux/spinlock.h>
+#include <linux/irq.h>
+#include <linux/of_dma.h>
+
+#include "virt-dma.h"
+
+#define GDMA_NR_CHANS 16
+
+#define GDMA_REG_SRC_ADDR(x) (0x00 + (x) * 0x10)
+#define GDMA_REG_DST_ADDR(x) (0x04 + (x) * 0x10)
+
+#define GDMA_REG_CTRL0(x) (0x08 + (x) * 0x10)
+#define GDMA_REG_CTRL0_TX_MASK 0xffff
+#define GDMA_REG_CTRL0_TX_SHIFT 16
+#define GDMA_REG_CTRL0_CURR_MASK 0xff
+#define GDMA_REG_CTRL0_CURR_SHIFT 8
+#define GDMA_REG_CTRL0_SRC_ADDR_FIXED BIT(7)
+#define GDMA_REG_CTRL0_DST_ADDR_FIXED BIT(6)
+#define GDMA_REG_CTRL0_BURST_MASK 0x7
+#define GDMA_REG_CTRL0_BURST_SHIFT 3
+#define GDMA_REG_CTRL0_DONE_INT BIT(2)
+#define GDMA_REG_CTRL0_ENABLE BIT(1)
+#define GDMA_REG_CTRL0_HW_MODE 0
+
+#define GDMA_REG_CTRL1(x) (0x0c + (x) * 0x10)
+#define GDMA_REG_CTRL1_SEG_MASK 0xf
+#define GDMA_REG_CTRL1_SEG_SHIFT 22
+#define GDMA_REG_CTRL1_REQ_MASK 0x3f
+#define GDMA_REG_CTRL1_SRC_REQ_SHIFT 16
+#define GDMA_REG_CTRL1_DST_REQ_SHIFT 8
+#define GDMA_REG_CTRL1_CONTINOUS BIT(14)
+#define GDMA_REG_CTRL1_NEXT_MASK 0x1f
+#define GDMA_REG_CTRL1_NEXT_SHIFT 3
+#define GDMA_REG_CTRL1_COHERENT BIT(2)
+#define GDMA_REG_CTRL1_FAIL BIT(1)
+#define GDMA_REG_CTRL1_MASK BIT(0)
+
+#define GDMA_REG_UNMASK_INT 0x200
+#define GDMA_REG_DONE_INT 0x204
+
+#define GDMA_REG_GCT 0x220
+#define GDMA_REG_GCT_CHAN_MASK 0x3
+#define GDMA_REG_GCT_CHAN_SHIFT 3
+#define GDMA_REG_GCT_VER_MASK 0x3
+#define GDMA_REG_GCT_VER_SHIFT 1
+#define GDMA_REG_GCT_ARBIT_RR BIT(0)
+
+enum gdma_dma_transfer_size {
+ GDMA_TRANSFER_SIZE_4BYTE = 0,
+ GDMA_TRANSFER_SIZE_8BYTE = 1,
+ GDMA_TRANSFER_SIZE_16BYTE = 2,
+ GDMA_TRANSFER_SIZE_32BYTE = 3,
+};
+
+struct gdma_dma_sg {
+ dma_addr_t addr;
+ unsigned int len;
+};
+
+struct gdma_dma_desc {
+ struct virt_dma_desc vdesc;
+
+ enum dma_transfer_direction direction;
+ bool cyclic;
+
+ unsigned int num_sgs;
+ struct gdma_dma_sg sg[];
+};
+
+struct gdma_dmaengine_chan {
+ struct virt_dma_chan vchan;
+ unsigned int id;
+
+ dma_addr_t fifo_addr;
+ unsigned int transfer_shift;
+
+ struct gdma_dma_desc *desc;
+ unsigned int next_sg;
+};
+
+struct gdma_dma_dev {
+ struct dma_device ddev;
+ void __iomem *base;
+ struct clk *clk;
+
+ struct gdma_dmaengine_chan chan[GDMA_NR_CHANS];
+};
+
+static struct gdma_dma_dev *gdma_dma_chan_get_dev(
+ struct gdma_dmaengine_chan *chan)
+{
+ return container_of(chan->vchan.chan.device, struct gdma_dma_dev,
+ ddev);
+}
+
+static struct gdma_dmaengine_chan *to_gdma_dma_chan(struct dma_chan *c)
+{
+ return container_of(c, struct gdma_dmaengine_chan, vchan.chan);
+}
+
+static struct gdma_dma_desc *to_gdma_dma_desc(struct virt_dma_desc *vdesc)
+{
+ return container_of(vdesc, struct gdma_dma_desc, vdesc);
+}
+
+static inline uint32_t gdma_dma_read(struct gdma_dma_dev *dma_dev,
+ unsigned int reg)
+{
+ return readl(dma_dev->base + reg);
+}
+
+static inline void gdma_dma_write(struct gdma_dma_dev *dma_dev,
+ unsigned reg, uint32_t val)
+{
+ //printk("gdma --> %p = 0x%08X\n", dma_dev->base + reg, val);
+ writel(val, dma_dev->base + reg);
+}
+
+static inline void gdma_dma_write_mask(struct gdma_dma_dev *dma_dev,
+ unsigned int reg, uint32_t val, uint32_t mask)
+{
+ uint32_t tmp;
+
+ tmp = gdma_dma_read(dma_dev, reg);
+ tmp &= ~mask;
+ tmp |= val;
+ gdma_dma_write(dma_dev, reg, tmp);
+}
+
+static struct gdma_dma_desc *gdma_dma_alloc_desc(unsigned int num_sgs)
+{
+ return kzalloc(sizeof(struct gdma_dma_desc) +
+ sizeof(struct gdma_dma_sg) * num_sgs, GFP_ATOMIC);
+}
+
+static enum gdma_dma_transfer_size gdma_dma_maxburst(u32 maxburst)
+{
+ if (maxburst <= 7)
+ return GDMA_TRANSFER_SIZE_4BYTE;
+ else if (maxburst <= 15)
+ return GDMA_TRANSFER_SIZE_8BYTE;
+ else if (maxburst <= 31)
+ return GDMA_TRANSFER_SIZE_16BYTE;
+
+ return GDMA_TRANSFER_SIZE_32BYTE;
+}
+
+static int gdma_dma_slave_config(struct dma_chan *c,
+ const struct dma_slave_config *config)
+{
+ struct gdma_dmaengine_chan *chan = to_gdma_dma_chan(c);
+ struct gdma_dma_dev *dma_dev = gdma_dma_chan_get_dev(chan);
+ enum gdma_dma_transfer_size transfer_size;
+ uint32_t flags;
+ uint32_t ctrl0, ctrl1;
+
+ switch (config->direction) {
+ case DMA_MEM_TO_DEV:
+ ctrl1 = 32 << GDMA_REG_CTRL1_SRC_REQ_SHIFT;
+ ctrl1 |= config->slave_id << GDMA_REG_CTRL1_DST_REQ_SHIFT;
+ flags = GDMA_REG_CTRL0_DST_ADDR_FIXED;
+ transfer_size = gdma_dma_maxburst(config->dst_maxburst);
+ chan->fifo_addr = config->dst_addr;
+ break;
+
+ case DMA_DEV_TO_MEM:
+ ctrl1 = config->slave_id << GDMA_REG_CTRL1_SRC_REQ_SHIFT;
+ ctrl1 |= 32 << GDMA_REG_CTRL1_DST_REQ_SHIFT;
+ flags = GDMA_REG_CTRL0_SRC_ADDR_FIXED;
+ transfer_size = gdma_dma_maxburst(config->src_maxburst);
+ chan->fifo_addr = config->src_addr;
+ break;
+
+ default:
+ return -EINVAL;
+ }
+
+ chan->transfer_shift = 1 + transfer_size;
+
+ ctrl0 = flags | GDMA_REG_CTRL0_HW_MODE;
+ ctrl0 |= GDMA_REG_CTRL0_DONE_INT;
+
+ ctrl1 &= ~(GDMA_REG_CTRL1_NEXT_MASK << GDMA_REG_CTRL1_NEXT_SHIFT);
+ ctrl1 |= chan->id << GDMA_REG_CTRL1_NEXT_SHIFT;
+ ctrl1 |= GDMA_REG_CTRL1_FAIL;
+ ctrl1 &= ~GDMA_REG_CTRL1_CONTINOUS;
+ gdma_dma_write(dma_dev, GDMA_REG_CTRL0(chan->id), ctrl0);
+ gdma_dma_write(dma_dev, GDMA_REG_CTRL1(chan->id), ctrl1);
+
+ return 0;
+}
+
+static int gdma_dma_terminate_all(struct dma_chan *c)
+{
+ struct gdma_dmaengine_chan *chan = to_gdma_dma_chan(c);
+ struct gdma_dma_dev *dma_dev = gdma_dma_chan_get_dev(chan);
+ unsigned long flags;
+ LIST_HEAD(head);
+
+ spin_lock_irqsave(&chan->vchan.lock, flags);
+ gdma_dma_write_mask(dma_dev, GDMA_REG_CTRL0(chan->id), 0,
+ GDMA_REG_CTRL0_ENABLE);
+ chan->desc = NULL;
+ vchan_get_all_descriptors(&chan->vchan, &head);
+ spin_unlock_irqrestore(&chan->vchan.lock, flags);
+
+ vchan_dma_desc_free_list(&chan->vchan, &head);
+
+ return 0;
+}
+
+static int gdma_dma_control(struct dma_chan *chan, enum dma_ctrl_cmd cmd,
+ unsigned long arg)
+{
+ struct dma_slave_config *config = (struct dma_slave_config *)arg;
+
+ switch (cmd) {
+ case DMA_SLAVE_CONFIG:
+ return gdma_dma_slave_config(chan, config);
+ case DMA_TERMINATE_ALL:
+ return gdma_dma_terminate_all(chan);
+ default:
+ return -ENOSYS;
+ }
+}
+
+static int gdma_dma_start_transfer(struct gdma_dmaengine_chan *chan)
+{
+ struct gdma_dma_dev *dma_dev = gdma_dma_chan_get_dev(chan);
+ dma_addr_t src_addr, dst_addr;
+ struct virt_dma_desc *vdesc;
+ struct gdma_dma_sg *sg;
+
+ gdma_dma_write_mask(dma_dev, GDMA_REG_CTRL0(chan->id), 0,
+ GDMA_REG_CTRL0_ENABLE);
+
+ if (!chan->desc) {
+ vdesc = vchan_next_desc(&chan->vchan);
+ if (!vdesc)
+ return 0;
+ chan->desc = to_gdma_dma_desc(vdesc);
+ chan->next_sg = 0;
+ }
+
+ if (chan->next_sg == chan->desc->num_sgs)
+ chan->next_sg = 0;
+
+ sg = &chan->desc->sg[chan->next_sg];
+
+ if (chan->desc->direction == DMA_MEM_TO_DEV) {
+ src_addr = sg->addr;
+ dst_addr = chan->fifo_addr;
+ } else {
+ src_addr = chan->fifo_addr;
+ dst_addr = sg->addr;
+ }
+ gdma_dma_write(dma_dev, GDMA_REG_SRC_ADDR(chan->id), src_addr);
+ gdma_dma_write(dma_dev, GDMA_REG_DST_ADDR(chan->id), dst_addr);
+ gdma_dma_write_mask(dma_dev, GDMA_REG_CTRL0(chan->id),
+ (sg->len << GDMA_REG_CTRL0_TX_SHIFT) | GDMA_REG_CTRL0_ENABLE,
+ GDMA_REG_CTRL0_TX_MASK << GDMA_REG_CTRL0_TX_SHIFT);
+ chan->next_sg++;
+ gdma_dma_write_mask(dma_dev, GDMA_REG_CTRL1(chan->id), 0, GDMA_REG_CTRL1_MASK);
+
+ return 0;
+}
+
+static void gdma_dma_chan_irq(struct gdma_dmaengine_chan *chan)
+{
+ spin_lock(&chan->vchan.lock);
+ if (chan->desc) {
+ if (chan->desc && chan->desc->cyclic) {
+ vchan_cyclic_callback(&chan->desc->vdesc);
+ } else {
+ if (chan->next_sg == chan->desc->num_sgs) {
+ chan->desc = NULL;
+ vchan_cookie_complete(&chan->desc->vdesc);
+ }
+ }
+ }
+ gdma_dma_start_transfer(chan);
+ spin_unlock(&chan->vchan.lock);
+}
+
+static irqreturn_t gdma_dma_irq(int irq, void *devid)
+{
+ struct gdma_dma_dev *dma_dev = devid;
+ uint32_t unmask, done;
+ unsigned int i;
+
+ unmask = gdma_dma_read(dma_dev, GDMA_REG_UNMASK_INT);
+ gdma_dma_write(dma_dev, GDMA_REG_UNMASK_INT, unmask);
+ done = gdma_dma_read(dma_dev, GDMA_REG_DONE_INT);
+
+ for (i = 0; i < GDMA_NR_CHANS; ++i)
+ if (done & BIT(i))
+ gdma_dma_chan_irq(&dma_dev->chan[i]);
+ gdma_dma_write(dma_dev, GDMA_REG_DONE_INT, done);
+
+ return IRQ_HANDLED;
+}
+
+static void gdma_dma_issue_pending(struct dma_chan *c)
+{
+ struct gdma_dmaengine_chan *chan = to_gdma_dma_chan(c);
+ unsigned long flags;
+
+ spin_lock_irqsave(&chan->vchan.lock, flags);
+ if (vchan_issue_pending(&chan->vchan) && !chan->desc)
+ gdma_dma_start_transfer(chan);
+ spin_unlock_irqrestore(&chan->vchan.lock, flags);
+}
+
+static struct dma_async_tx_descriptor *gdma_dma_prep_slave_sg(
+ struct dma_chan *c, struct scatterlist *sgl,
+ unsigned int sg_len, enum dma_transfer_direction direction,
+ unsigned long flags, void *context)
+{
+ struct gdma_dmaengine_chan *chan = to_gdma_dma_chan(c);
+ struct gdma_dma_desc *desc;
+ struct scatterlist *sg;
+ unsigned int i;
+
+ desc = gdma_dma_alloc_desc(sg_len);
+ if (!desc)
+ return NULL;
+
+ for_each_sg(sgl, sg, sg_len, i) {
+ desc->sg[i].addr = sg_dma_address(sg);
+ desc->sg[i].len = sg_dma_len(sg);
+ }
+
+ desc->num_sgs = sg_len;
+ desc->direction = direction;
+ desc->cyclic = false;
+
+ return vchan_tx_prep(&chan->vchan, &desc->vdesc, flags);
+}
+
+static struct dma_async_tx_descriptor *gdma_dma_prep_dma_cyclic(
+ struct dma_chan *c, dma_addr_t buf_addr, size_t buf_len,
+ size_t period_len, enum dma_transfer_direction direction,
+ unsigned long flags, void *context)
+{
+ struct gdma_dmaengine_chan *chan = to_gdma_dma_chan(c);
+ struct gdma_dma_desc *desc;
+ unsigned int num_periods, i;
+
+ if (buf_len % period_len)
+ return NULL;
+
+ num_periods = buf_len / period_len;
+
+ desc = gdma_dma_alloc_desc(num_periods);
+ if (!desc)
+ return NULL;
+
+ for (i = 0; i < num_periods; i++) {
+ desc->sg[i].addr = buf_addr;
+ desc->sg[i].len = period_len;
+ buf_addr += period_len;
+ }
+
+ desc->num_sgs = num_periods;
+ desc->direction = direction;
+ desc->cyclic = true;
+
+ return vchan_tx_prep(&chan->vchan, &desc->vdesc, flags);
+}
+
+static size_t gdma_dma_desc_residue(struct gdma_dmaengine_chan *chan,
+ struct gdma_dma_desc *desc, unsigned int next_sg)
+{
+ struct gdma_dma_dev *dma_dev = gdma_dma_chan_get_dev(chan);
+ unsigned int residue, count;
+ unsigned int i;
+
+ residue = 0;
+
+ for (i = next_sg; i < desc->num_sgs; i++)
+ residue += desc->sg[i].len;
+
+ if (next_sg != 0) {
+ count = gdma_dma_read(dma_dev, GDMA_REG_CTRL0(chan->id));
+ count >>= GDMA_REG_CTRL0_CURR_SHIFT;
+ count &= GDMA_REG_CTRL0_CURR_MASK;
+ residue += count << chan->transfer_shift;
+ }
+
+ return residue;
+}
+
+static enum dma_status gdma_dma_tx_status(struct dma_chan *c,
+ dma_cookie_t cookie, struct dma_tx_state *state)
+{
+ struct gdma_dmaengine_chan *chan = to_gdma_dma_chan(c);
+ struct virt_dma_desc *vdesc;
+ enum dma_status status;
+ unsigned long flags;
+
+ status = dma_cookie_status(c, cookie, state);
+ if (status == DMA_SUCCESS || !state)
+ return status;
+
+ spin_lock_irqsave(&chan->vchan.lock, flags);
+ vdesc = vchan_find_desc(&chan->vchan, cookie);
+ if (cookie == chan->desc->vdesc.tx.cookie) {
+ state->residue = gdma_dma_desc_residue(chan, chan->desc,
+ chan->next_sg);
+ } else if (vdesc) {
+ state->residue = gdma_dma_desc_residue(chan,
+ to_gdma_dma_desc(vdesc), 0);
+ } else {
+ state->residue = 0;
+ }
+ spin_unlock_irqrestore(&chan->vchan.lock, flags);
+
+ return status;
+}
+
+static int gdma_dma_alloc_chan_resources(struct dma_chan *c)
+{
+ return 0;
+}
+
+static void gdma_dma_free_chan_resources(struct dma_chan *c)
+{
+ vchan_free_chan_resources(to_virt_chan(c));
+}
+
+static void gdma_dma_desc_free(struct virt_dma_desc *vdesc)
+{
+ kfree(container_of(vdesc, struct gdma_dma_desc, vdesc));
+}
+
+static struct dma_chan *
+of_dma_xlate_by_chan_id(struct of_phandle_args *dma_spec,
+ struct of_dma *ofdma)
+{
+ struct gdma_dma_dev *dma_dev = ofdma->of_dma_data;
+ unsigned int request = dma_spec->args[0];
+
+ if (request >= GDMA_NR_CHANS)
+ return NULL;
+
+ return dma_get_slave_channel(&(dma_dev->chan[request].vchan.chan));
+}
+
+static int gdma_dma_probe(struct platform_device *pdev)
+{
+ struct gdma_dmaengine_chan *chan;
+ struct gdma_dma_dev *dma_dev;
+ struct dma_device *dd;
+ unsigned int i;
+ struct resource *res;
+ uint32_t gct;
+ int ret;
+ int irq;
+
+
+ dma_dev = devm_kzalloc(&pdev->dev, sizeof(*dma_dev), GFP_KERNEL);
+ if (!dma_dev)
+ return -EINVAL;
+
+ dd = &dma_dev->ddev;
+
+ res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+ dma_dev->base = devm_ioremap_resource(&pdev->dev, res);
+ if (IS_ERR(dma_dev->base))
+ return PTR_ERR(dma_dev->base);
+
+ dma_cap_set(DMA_SLAVE, dd->cap_mask);
+ dma_cap_set(DMA_CYCLIC, dd->cap_mask);
+ dd->device_alloc_chan_resources = gdma_dma_alloc_chan_resources;
+ dd->device_free_chan_resources = gdma_dma_free_chan_resources;
+ dd->device_tx_status = gdma_dma_tx_status;
+ dd->device_issue_pending = gdma_dma_issue_pending;
+ dd->device_prep_slave_sg = gdma_dma_prep_slave_sg;
+ dd->device_prep_dma_cyclic = gdma_dma_prep_dma_cyclic;
+ dd->device_control = gdma_dma_control;
+ dd->dev = &pdev->dev;
+ dd->chancnt = GDMA_NR_CHANS;
+ INIT_LIST_HEAD(&dd->channels);
+
+ for (i = 0; i < dd->chancnt; i++) {
+ chan = &dma_dev->chan[i];
+ chan->id = i;
+ chan->vchan.desc_free = gdma_dma_desc_free;
+ vchan_init(&chan->vchan, dd);
+ }
+
+ ret = dma_async_device_register(dd);
+ if (ret)
+ return ret;
+
+ ret = of_dma_controller_register(pdev->dev.of_node,
+ of_dma_xlate_by_chan_id, dma_dev);
+ if (ret)
+ goto err_unregister;
+
+ irq = platform_get_irq(pdev, 0);
+ ret = request_irq(irq, gdma_dma_irq, 0, dev_name(&pdev->dev), dma_dev);
+ if (ret)
+ goto err_unregister;
+
+ gdma_dma_write(dma_dev, GDMA_REG_UNMASK_INT, 0);
+ gdma_dma_write(dma_dev, GDMA_REG_DONE_INT, BIT(dd->chancnt) - 1);
+
+ gct = gdma_dma_read(dma_dev, GDMA_REG_GCT);
+ dev_info(&pdev->dev, "revision: %d, channels: %d\n",
+ (gct >> GDMA_REG_GCT_VER_SHIFT) & GDMA_REG_GCT_VER_MASK,
+ 8 << ((gct >> GDMA_REG_GCT_CHAN_SHIFT) & GDMA_REG_GCT_CHAN_MASK));
+ platform_set_drvdata(pdev, dma_dev);
+
+ gdma_dma_write(dma_dev, GDMA_REG_GCT, GDMA_REG_GCT_ARBIT_RR);
+
+ return 0;
+
+err_unregister:
+ dma_async_device_unregister(dd);
+ return ret;
+}
+
+static int gdma_dma_remove(struct platform_device *pdev)
+{
+ struct gdma_dma_dev *dma_dev = platform_get_drvdata(pdev);
+ int irq = platform_get_irq(pdev, 0);
+
+ free_irq(irq, dma_dev);
+ of_dma_controller_free(pdev->dev.of_node);
+ dma_async_device_unregister(&dma_dev->ddev);
+
+ return 0;
+}
+
+static const struct of_device_id gdma_of_match_table[] = {
+ { .compatible = "ralink,rt2880-gdma" },
+ { },
+};
+
+static struct platform_driver gdma_dma_driver = {
+ .probe = gdma_dma_probe,
+ .remove = gdma_dma_remove,
+ .driver = {
+ .name = "gdma-rt2880",
+ .owner = THIS_MODULE,
+ .of_match_table = gdma_of_match_table,
+ },
+};
+module_platform_driver(gdma_dma_driver);
+
+MODULE_AUTHOR("Lars-Peter Clausen <lars@metafoo.de>");
+MODULE_DESCRIPTION("GDMA4740 DMA driver");
+MODULE_LICENSE("GPLv2");
diff --git a/include/linux/dmaengine.h b/include/linux/dmaengine.h
index c5c92d5..482131e 100644
--- a/include/linux/dmaengine.h
+++ b/include/linux/dmaengine.h
@@ -1072,6 +1072,7 @@ struct dma_chan *dma_request_slave_channel_reason(struct device *dev,
const char *name);
struct dma_chan *dma_request_slave_channel(struct device *dev, const char *name);
void dma_release_channel(struct dma_chan *chan);
+struct dma_chan *dma_get_slave_channel(struct dma_chan *chan);
#else
static inline struct dma_chan *dma_find_channel(enum dma_transaction_type tx_type)
{
--
1.7.10.4

View file

@ -0,0 +1,734 @@
From 241188942603dc73f62cf2553c53cae2235c9957 Mon Sep 17 00:00:00 2001
From: John Crispin <blogic@openwrt.org>
Date: Sun, 27 Jul 2014 09:31:47 +0100
Subject: [PATCH 55/57] asoc: add mt7620 support
Signed-off-by: John Crispin <blogic@openwrt.org>
---
arch/mips/ralink/of.c | 2 +
sound/soc/Kconfig | 1 +
sound/soc/Makefile | 1 +
sound/soc/ralink/Kconfig | 15 ++
sound/soc/ralink/Makefile | 11 +
sound/soc/ralink/mt7620-i2s.c | 466 ++++++++++++++++++++++++++++++++++++++
sound/soc/ralink/mt7620-wm8960.c | 125 ++++++++++
sound/soc/soc-io.c | 10 -
8 files changed, 621 insertions(+), 10 deletions(-)
create mode 100644 sound/soc/ralink/Kconfig
create mode 100644 sound/soc/ralink/Makefile
create mode 100644 sound/soc/ralink/mt7620-i2s.c
create mode 100644 sound/soc/ralink/mt7620-wm8960.c
diff --git a/arch/mips/ralink/of.c b/arch/mips/ralink/of.c
index 405b79c..dfda6e6 100644
--- a/arch/mips/ralink/of.c
+++ b/arch/mips/ralink/of.c
@@ -15,6 +15,7 @@
#include <linux/of_fdt.h>
#include <linux/kernel.h>
#include <linux/bootmem.h>
+#include <linux/module.h>
#include <linux/of_platform.h>
#include <linux/of_address.h>
@@ -26,6 +27,7 @@
#include "common.h"
__iomem void *rt_sysc_membase;
+EXPORT_SYMBOL(rt_sysc_membase);
__iomem void *rt_memc_membase;
extern struct boot_param_header __dtb_start;
diff --git a/sound/soc/Kconfig b/sound/soc/Kconfig
index d62ce48..de91f58 100644
--- a/sound/soc/Kconfig
+++ b/sound/soc/Kconfig
@@ -47,6 +47,7 @@ source "sound/soc/kirkwood/Kconfig"
source "sound/soc/intel/Kconfig"
source "sound/soc/mxs/Kconfig"
source "sound/soc/pxa/Kconfig"
+source "sound/soc/ralink/Kconfig"
source "sound/soc/samsung/Kconfig"
source "sound/soc/s6000/Kconfig"
source "sound/soc/sh/Kconfig"
diff --git a/sound/soc/Makefile b/sound/soc/Makefile
index 62a1822..1d9398c 100644
--- a/sound/soc/Makefile
+++ b/sound/soc/Makefile
@@ -24,6 +24,7 @@ obj-$(CONFIG_SND_SOC) += nuc900/
obj-$(CONFIG_SND_SOC) += omap/
obj-$(CONFIG_SND_SOC) += kirkwood/
obj-$(CONFIG_SND_SOC) += pxa/
+obj-$(CONFIG_SND_SOC) += ralink/
obj-$(CONFIG_SND_SOC) += samsung/
obj-$(CONFIG_SND_SOC) += s6000/
obj-$(CONFIG_SND_SOC) += sh/
diff --git a/sound/soc/ralink/Kconfig b/sound/soc/ralink/Kconfig
new file mode 100644
index 0000000..d462622
--- /dev/null
+++ b/sound/soc/ralink/Kconfig
@@ -0,0 +1,15 @@
+config SND_MT7620_SOC_I2S
+ depends on SOC_MT7620 && SND_SOC
+ select SND_SOC_GENERIC_DMAENGINE_PCM
+ tristate "SoC Audio (I2S protocol) for Ralink MT7620 SoC"
+ help
+ Say Y if you want to use I2S protocol and I2S codec on Ingenic MT7620
+ based boards.
+
+config SND_MT7620_SOC_WM8960
+ tristate "SoC Audio support for Ralink WM8960"
+ select SND_MT7620_SOC_I2S
+ select SND_SOC_WM8960
+ help
+ Say Y if you want to add support for ASoC audio on the Qi LB60 board
+ a.k.a Qi Ben NanoNote.
diff --git a/sound/soc/ralink/Makefile b/sound/soc/ralink/Makefile
new file mode 100644
index 0000000..3d79980
--- /dev/null
+++ b/sound/soc/ralink/Makefile
@@ -0,0 +1,11 @@
+#
+# Jz4740 Platform Support
+#
+snd-soc-mt7620-i2s-objs := mt7620-i2s.o
+
+obj-$(CONFIG_SND_MT7620_SOC_I2S) += snd-soc-mt7620-i2s.o
+
+# Jz4740 Machine Support
+snd-soc-mt7620-wm8960-objs := mt7620-wm8960.o
+
+obj-$(CONFIG_SND_MT7620_SOC_WM8960) += snd-soc-mt7620-wm8960.o
diff --git a/sound/soc/ralink/mt7620-i2s.c b/sound/soc/ralink/mt7620-i2s.c
new file mode 100644
index 0000000..846db03
--- /dev/null
+++ b/sound/soc/ralink/mt7620-i2s.c
@@ -0,0 +1,466 @@
+/*
+ * Copyright (C) 2010, Lars-Peter Clausen <lars@metafoo.de>
+ *
+ * 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.
+ *
+ * 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.
+ *
+ */
+
+#include <linux/init.h>
+#include <linux/io.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/platform_device.h>
+#include <linux/slab.h>
+
+#include <linux/delay.h>
+
+#include <linux/dma-mapping.h>
+
+#include <sound/core.h>
+#include <sound/pcm.h>
+#include <sound/pcm_params.h>
+#include <sound/soc.h>
+#include <sound/initval.h>
+#include <sound/dmaengine_pcm.h>
+
+#include <ralink_regs.h>
+
+#define I2S_REG_CFG0 0x00
+#define I2S_REG_CFG0_EN BIT(31)
+#define I2S_REG_CFG0_DMA_EN BIT(30)
+#define I2S_REG_CFG0_BYTE_SWAP BIT(28)
+#define I2S_REG_CFG0_TX_EN BIT(24)
+#define I2S_REG_CFG0_RX_EN BIT(20)
+#define I2S_REG_CFG0_SLAVE BIT(16)
+#define I2S_REG_CFG0_RX_THRES 12
+#define I2S_REG_CFG0_TX_THRES 4
+#define I2S_REG_CFG0_DFT_THRES (4 << I2S_REG_CFG0_RX_THRES) | \
+ (4 << I2S_REG_CFG0_TX_THRES)
+
+#define I2S_REG_INT_STATUS 0x04
+#define I2S_REG_INT_EN 0x08
+#define I2S_REG_FF_STATUS 0x0c
+#define I2S_REG_WREG 0x10
+#define I2S_REG_RREG 0x14
+#define I2S_REG_CFG1 0x18
+
+#define I2S_REG_DIVCMP 0x20
+#define I2S_REG_DIVINT 0x24
+#define I2S_REG_CLK_EN BIT(31)
+
+struct mt7620_i2s {
+ struct resource *mem;
+ void __iomem *base;
+ dma_addr_t phys_base;
+
+ struct snd_dmaengine_dai_dma_data playback_dma_data;
+ struct snd_dmaengine_dai_dma_data capture_dma_data;
+};
+
+static inline uint32_t mt7620_i2s_read(const struct mt7620_i2s *i2s,
+ unsigned int reg)
+{
+ return readl(i2s->base + reg);
+}
+
+static inline void mt7620_i2s_write(const struct mt7620_i2s *i2s,
+ unsigned int reg, uint32_t value)
+{
+ //printk("i2s --> %p = 0x%08X\n", i2s->base + reg, value);
+ writel(value, i2s->base + reg);
+}
+
+static int mt7620_i2s_startup(struct snd_pcm_substream *substream,
+ struct snd_soc_dai *dai)
+{
+ struct mt7620_i2s *i2s = snd_soc_dai_get_drvdata(dai);
+ uint32_t cfg;
+
+ if (dai->active)
+ return 0;
+
+ cfg = mt7620_i2s_read(i2s, I2S_REG_CFG0);
+ cfg |= I2S_REG_CFG0_EN;
+ mt7620_i2s_write(i2s, I2S_REG_CFG0, cfg);
+
+ return 0;
+}
+
+static void mt7620_i2s_shutdown(struct snd_pcm_substream *substream,
+ struct snd_soc_dai *dai)
+{
+ struct mt7620_i2s *i2s = snd_soc_dai_get_drvdata(dai);
+ uint32_t cfg;
+
+ if (dai->active)
+ return;
+
+ cfg = mt7620_i2s_read(i2s, I2S_REG_CFG0);
+ cfg &= ~I2S_REG_CFG0_EN;
+ mt7620_i2s_write(i2s, I2S_REG_CFG0, cfg);
+}
+
+static int mt7620_i2s_trigger(struct snd_pcm_substream *substream, int cmd,
+ struct snd_soc_dai *dai)
+{
+ struct mt7620_i2s *i2s = snd_soc_dai_get_drvdata(dai);
+
+ uint32_t cfg;
+ uint32_t mask;
+
+ if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
+ mask = I2S_REG_CFG0_TX_EN;
+ else
+ mask = I2S_REG_CFG0_RX_EN;
+
+ cfg = mt7620_i2s_read(i2s, I2S_REG_CFG0);
+
+ switch (cmd) {
+ case SNDRV_PCM_TRIGGER_START:
+ case SNDRV_PCM_TRIGGER_RESUME:
+ case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
+ cfg |= mask;
+ break;
+ case SNDRV_PCM_TRIGGER_STOP:
+ case SNDRV_PCM_TRIGGER_SUSPEND:
+ case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
+ cfg &= ~mask;
+ break;
+ default:
+ return -EINVAL;
+ }
+
+ if (cfg & (I2S_REG_CFG0_TX_EN | I2S_REG_CFG0_RX_EN))
+ cfg |= I2S_REG_CFG0_DMA_EN;
+ else
+ cfg &= ~I2S_REG_CFG0_DMA_EN;
+
+ mt7620_i2s_write(i2s, I2S_REG_CFG0, cfg);
+
+ return 0;
+}
+
+static int mt7620_i2s_set_fmt(struct snd_soc_dai *dai, unsigned int fmt)
+{
+ struct mt7620_i2s *i2s = snd_soc_dai_get_drvdata(dai);
+ uint32_t cfg;
+
+ cfg = mt7620_i2s_read(i2s, I2S_REG_CFG0);
+
+ switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
+ case SND_SOC_DAIFMT_CBS_CFS:
+ cfg |= I2S_REG_CFG0_SLAVE;
+ break;
+ case SND_SOC_DAIFMT_CBM_CFM:
+ cfg &= ~I2S_REG_CFG0_SLAVE;
+ break;
+ case SND_SOC_DAIFMT_CBM_CFS:
+ default:
+ return -EINVAL;
+ }
+
+ switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
+ case SND_SOC_DAIFMT_I2S:
+ case SND_SOC_DAIFMT_MSB:
+ cfg &= ~I2S_REG_CFG0_BYTE_SWAP;
+ break;
+ case SND_SOC_DAIFMT_LSB:
+ cfg |= I2S_REG_CFG0_BYTE_SWAP;
+ break;
+ default:
+ return -EINVAL;
+ }
+
+ switch (fmt & SND_SOC_DAIFMT_INV_MASK) {
+ case SND_SOC_DAIFMT_NB_NF:
+ break;
+ default:
+ return -EINVAL;
+ }
+
+ mt7620_i2s_write(i2s, I2S_REG_CFG0, cfg);
+
+ return 0;
+}
+
+static int mt7620_i2s_hw_params(struct snd_pcm_substream *substream,
+ struct snd_pcm_hw_params *params, struct snd_soc_dai *dai)
+{
+
+ return 0;
+}
+
+unsigned long i2sMaster_inclk_int[11] = {
+ 78, 56, 52, 39, 28, 26, 19, 14, 13, 9, 6};
+unsigned long i2sMaster_inclk_comp[11] = {
+ 64, 352, 42, 32, 176, 21, 272, 88, 10, 455, 261};
+
+
+static int mt7620_i2s_set_sysclk(struct snd_soc_dai *dai, int clk_id,
+ unsigned int freq, int dir)
+{
+ struct mt7620_i2s *i2s = snd_soc_dai_get_drvdata(dai);
+
+ printk("Internal REFCLK with fractional division\n");
+
+ mt7620_i2s_write(i2s, I2S_REG_DIVINT, i2sMaster_inclk_int[7]);
+ mt7620_i2s_write(i2s, I2S_REG_DIVCMP,
+ i2sMaster_inclk_comp[7] | I2S_REG_CLK_EN);
+
+/* struct mt7620_i2s *i2s = snd_soc_dai_get_drvdata(dai);
+ struct clk *parent;
+ int ret = 0;
+
+ switch (clk_id) {
+ case JZ4740_I2S_CLKSRC_EXT:
+ parent = clk_get(NULL, "ext");
+ clk_set_parent(i2s->clk_i2s, parent);
+ break;
+ case JZ4740_I2S_CLKSRC_PLL:
+ parent = clk_get(NULL, "pll half");
+ clk_set_parent(i2s->clk_i2s, parent);
+ ret = clk_set_rate(i2s->clk_i2s, freq);
+ break;
+ default:
+ return -EINVAL;
+ }
+ clk_put(parent);
+
+ return ret;*/
+ return 0;
+}
+
+static int mt7620_i2s_suspend(struct snd_soc_dai *dai)
+{
+ struct mt7620_i2s *i2s = snd_soc_dai_get_drvdata(dai);
+ uint32_t cfg;
+
+ if (dai->active) {
+ cfg = mt7620_i2s_read(i2s, I2S_REG_CFG0);
+ cfg &= ~I2S_REG_CFG0_TX_EN;
+ mt7620_i2s_write(i2s, I2S_REG_CFG0, cfg);
+ }
+
+ return 0;
+}
+
+static int mt7620_i2s_resume(struct snd_soc_dai *dai)
+{
+ struct mt7620_i2s *i2s = snd_soc_dai_get_drvdata(dai);
+ uint32_t cfg;
+
+ if (dai->active) {
+ cfg = mt7620_i2s_read(i2s, I2S_REG_CFG0);
+ cfg |= I2S_REG_CFG0_TX_EN;
+ mt7620_i2s_write(i2s, I2S_REG_CFG0, cfg);
+ }
+
+ return 0;
+}
+
+static void mt7620_i2c_init_pcm_config(struct mt7620_i2s *i2s)
+{
+ struct snd_dmaengine_dai_dma_data *dma_data;
+
+ /* Playback */
+ dma_data = &i2s->playback_dma_data;
+ dma_data->maxburst = 16;
+ dma_data->slave_id = 2; //JZ4740_DMA_TYPE_AIC_TRANSMIT;
+ dma_data->addr = i2s->phys_base + I2S_REG_WREG;
+
+ /* Capture */
+ dma_data = &i2s->capture_dma_data;
+ dma_data->maxburst = 16;
+ dma_data->slave_id = 3; //JZ4740_DMA_TYPE_AIC_RECEIVE;
+ dma_data->addr = i2s->phys_base + I2S_REG_RREG;
+}
+
+static int mt7620_i2s_dai_probe(struct snd_soc_dai *dai)
+{
+ struct mt7620_i2s *i2s = snd_soc_dai_get_drvdata(dai);
+ uint32_t data;
+
+ mt7620_i2c_init_pcm_config(i2s);
+ dai->playback_dma_data = &i2s->playback_dma_data;
+ dai->capture_dma_data = &i2s->capture_dma_data;
+
+ /* set share pins to i2s/gpio mode and i2c mode */
+ data = rt_sysc_r32(0x60);
+ data &= 0xFFFFFFE2;
+ data |= 0x00000018;
+ rt_sysc_w32(data, 0x60);
+
+ printk("Internal REFCLK with fractional division\n");
+
+ mt7620_i2s_write(i2s, I2S_REG_CFG0, I2S_REG_CFG0_DFT_THRES);
+ mt7620_i2s_write(i2s, I2S_REG_CFG1, 0);
+ mt7620_i2s_write(i2s, I2S_REG_INT_EN, 0);
+
+ mt7620_i2s_write(i2s, I2S_REG_DIVINT, i2sMaster_inclk_int[7]);
+ mt7620_i2s_write(i2s, I2S_REG_DIVCMP,
+ i2sMaster_inclk_comp[7] | I2S_REG_CLK_EN);
+
+ return 0;
+}
+
+static int mt7620_i2s_dai_remove(struct snd_soc_dai *dai)
+{
+ return 0;
+}
+
+static const struct snd_soc_dai_ops mt7620_i2s_dai_ops = {
+ .startup = mt7620_i2s_startup,
+ .shutdown = mt7620_i2s_shutdown,
+ .trigger = mt7620_i2s_trigger,
+ .hw_params = mt7620_i2s_hw_params,
+ .set_fmt = mt7620_i2s_set_fmt,
+ .set_sysclk = mt7620_i2s_set_sysclk,
+};
+
+#define JZ4740_I2S_FMTS (SNDRV_PCM_FMTBIT_S8 | \
+ SNDRV_PCM_FMTBIT_S16_LE)
+
+static struct snd_soc_dai_driver mt7620_i2s_dai = {
+ .probe = mt7620_i2s_dai_probe,
+ .remove = mt7620_i2s_dai_remove,
+ .playback = {
+ .channels_min = 1,
+ .channels_max = 2,
+ .rates = SNDRV_PCM_RATE_8000_48000,
+ .formats = JZ4740_I2S_FMTS,
+ },
+ .capture = {
+ .channels_min = 2,
+ .channels_max = 2,
+ .rates = SNDRV_PCM_RATE_8000_48000,
+ .formats = JZ4740_I2S_FMTS,
+ },
+ .symmetric_rates = 1,
+ .ops = &mt7620_i2s_dai_ops,
+ .suspend = mt7620_i2s_suspend,
+ .resume = mt7620_i2s_resume,
+};
+
+static const struct snd_pcm_hardware mt7620_pcm_hardware = {
+ .info = SNDRV_PCM_INFO_MMAP |
+ SNDRV_PCM_INFO_MMAP_VALID |
+ SNDRV_PCM_INFO_INTERLEAVED |
+ SNDRV_PCM_INFO_BLOCK_TRANSFER,
+ .formats = SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S8,
+ .period_bytes_min = PAGE_SIZE,
+ .period_bytes_max = 64 * 1024,
+ .periods_min = 2,
+ .periods_max = 128,
+ .buffer_bytes_max = 128 * 1024,
+ .fifo_size = 32,
+};
+
+static const struct snd_dmaengine_pcm_config mt7620_dmaengine_pcm_config = {
+ .prepare_slave_config = snd_dmaengine_pcm_prepare_slave_config,
+ .pcm_hardware = &mt7620_pcm_hardware,
+ .prealloc_buffer_size = 256 * PAGE_SIZE,
+};
+
+static const struct snd_soc_component_driver mt7620_i2s_component = {
+ .name = "mt7620-i2s",
+};
+
+static int mt7620_i2s_dev_probe(struct platform_device *pdev)
+{
+ struct mt7620_i2s *i2s;
+ int ret;
+
+ snd_dmaengine_pcm_register(&pdev->dev,
+ &mt7620_dmaengine_pcm_config,
+ SND_DMAENGINE_PCM_FLAG_COMPAT);
+
+ i2s = kzalloc(sizeof(*i2s), GFP_KERNEL);
+ if (!i2s)
+ return -ENOMEM;
+
+ i2s->mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+ if (!i2s->mem) {
+ ret = -ENOENT;
+ goto err_free;
+ }
+
+ i2s->mem = request_mem_region(i2s->mem->start, resource_size(i2s->mem),
+ pdev->name);
+ if (!i2s->mem) {
+ ret = -EBUSY;
+ goto err_free;
+ }
+
+ i2s->base = ioremap_nocache(i2s->mem->start, resource_size(i2s->mem));
+ if (!i2s->base) {
+ ret = -EBUSY;
+ goto err_release_mem_region;
+ }
+
+ i2s->phys_base = i2s->mem->start;
+
+ platform_set_drvdata(pdev, i2s);
+ ret = snd_soc_register_component(&pdev->dev, &mt7620_i2s_component,
+ &mt7620_i2s_dai, 1);
+
+ if (!ret) {
+ dev_err(&pdev->dev, "loaded\n");
+ return ret;
+ }
+
+ dev_err(&pdev->dev, "Failed to register DAI\n");
+ iounmap(i2s->base);
+
+err_release_mem_region:
+ release_mem_region(i2s->mem->start, resource_size(i2s->mem));
+err_free:
+ kfree(i2s);
+
+ return ret;
+}
+
+static int mt7620_i2s_dev_remove(struct platform_device *pdev)
+{
+ struct mt7620_i2s *i2s = platform_get_drvdata(pdev);
+
+ snd_soc_unregister_component(&pdev->dev);
+
+ iounmap(i2s->base);
+ release_mem_region(i2s->mem->start, resource_size(i2s->mem));
+
+ kfree(i2s);
+
+ snd_dmaengine_pcm_unregister(&pdev->dev);
+
+ return 0;
+}
+
+static const struct of_device_id mt7620_i2s_match[] = {
+ { .compatible = "ralink,mt7620a-i2s" },
+ {},
+};
+MODULE_DEVICE_TABLE(of, mt7620_i2s_match);
+
+static struct platform_driver mt7620_i2s_driver = {
+ .probe = mt7620_i2s_dev_probe,
+ .remove = mt7620_i2s_dev_remove,
+ .driver = {
+ .name = "mt7620-i2s",
+ .owner = THIS_MODULE,
+ .of_match_table = mt7620_i2s_match,
+ },
+};
+
+module_platform_driver(mt7620_i2s_driver);
+
+MODULE_AUTHOR("Lars-Peter Clausen, <lars@metafoo.de>");
+MODULE_DESCRIPTION("Ingenic JZ4740 SoC I2S driver");
+MODULE_LICENSE("GPL");
+MODULE_ALIAS("platform:mt7620-i2s");
diff --git a/sound/soc/ralink/mt7620-wm8960.c b/sound/soc/ralink/mt7620-wm8960.c
new file mode 100644
index 0000000..c0f6389
--- /dev/null
+++ b/sound/soc/ralink/mt7620-wm8960.c
@@ -0,0 +1,125 @@
+/*
+ * Copyright (C) 2009, Lars-Peter Clausen <lars@metafoo.de>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ */
+
+#include <linux/module.h>
+#include <linux/moduleparam.h>
+#include <linux/of.h>
+#include <linux/timer.h>
+#include <linux/interrupt.h>
+#include <linux/platform_device.h>
+#include <sound/core.h>
+#include <sound/pcm.h>
+#include <sound/soc.h>
+
+
+static const struct snd_soc_dapm_widget mt7620_wm8960_widgets[] = {
+ SND_SOC_DAPM_SPK("Speaker", NULL),
+};
+
+static const struct snd_soc_dapm_route mt7620_wm8960_routes[] = {
+ {"Speaker", NULL, "HP_L"},
+ {"Speaker", NULL, "HP_R"},
+};
+
+#define MT7620_DAIFMT (SND_SOC_DAIFMT_I2S | \
+ SND_SOC_DAIFMT_NB_NF | \
+ SND_SOC_DAIFMT_CBM_CFM)
+
+static int mt7620_wm8960_codec_init(struct snd_soc_pcm_runtime *rtd)
+{
+ struct snd_soc_codec *codec = rtd->codec;
+ struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
+ struct snd_soc_dapm_context *dapm = &codec->dapm;
+ int ret;
+
+ snd_soc_dapm_enable_pin(dapm, "HP_L");
+ snd_soc_dapm_enable_pin(dapm, "HP_R");
+
+ ret = snd_soc_dai_set_fmt(cpu_dai, MT7620_DAIFMT);
+ if (ret < 0) {
+ dev_err(codec->dev, "Failed to set cpu dai format: %d\n", ret);
+ return ret;
+ }
+
+ return 0;
+}
+
+static struct snd_soc_dai_link mt7620_wm8960_dai = {
+ .name = "mt7620",
+ .stream_name = "mt7620",
+ .init = mt7620_wm8960_codec_init,
+ .codec_dai_name = "wm8960-hifi",
+};
+
+static struct snd_soc_card mt7620_wm8960 = {
+ .name = "mt7620-wm8960",
+ .owner = THIS_MODULE,
+ .dai_link = &mt7620_wm8960_dai,
+ .num_links = 1,
+
+ .dapm_widgets = mt7620_wm8960_widgets,
+ .num_dapm_widgets = ARRAY_SIZE(mt7620_wm8960_widgets),
+ .dapm_routes = mt7620_wm8960_routes,
+ .num_dapm_routes = ARRAY_SIZE(mt7620_wm8960_routes),
+};
+
+static int mt7620_wm8960_probe(struct platform_device *pdev)
+{
+ struct device_node *np = pdev->dev.of_node;
+ struct snd_soc_card *card = &mt7620_wm8960;
+ int ret;
+
+ card->dev = &pdev->dev;
+
+ mt7620_wm8960_dai.cpu_of_node = of_parse_phandle(np, "cpu-dai", 0);
+ mt7620_wm8960_dai.codec_of_node = of_parse_phandle(np, "codec-dai", 0);
+ mt7620_wm8960_dai.platform_of_node = mt7620_wm8960_dai.cpu_of_node;
+
+ ret = snd_soc_register_card(card);
+ if (ret) {
+ dev_err(&pdev->dev, "snd_soc_register_card() failed: %d\n",
+ ret);
+ }
+ return ret;
+}
+
+static int mt7620_wm8960_remove(struct platform_device *pdev)
+{
+ struct snd_soc_card *card = platform_get_drvdata(pdev);
+
+ snd_soc_unregister_card(card);
+ return 0;
+}
+
+static const struct of_device_id mt7620_audio_match[] = {
+ { .compatible = "ralink,wm8960-audio" },
+ {},
+};
+MODULE_DEVICE_TABLE(of, mt7620_audio_match);
+
+static struct platform_driver mt7620_wm8960_driver = {
+ .driver = {
+ .name = "wm8960-audio",
+ .owner = THIS_MODULE,
+ .of_match_table = mt7620_audio_match,
+ },
+ .probe = mt7620_wm8960_probe,
+ .remove = mt7620_wm8960_remove,
+};
+
+module_platform_driver(mt7620_wm8960_driver);
+
+MODULE_AUTHOR("Lars-Peter Clausen <lars@metafoo.de>");
+MODULE_DESCRIPTION("ALSA SoC QI LB60 Audio support");
+MODULE_LICENSE("GPL v2");
+MODULE_ALIAS("platform:qi-lb60-audio");
diff --git a/sound/soc/soc-io.c b/sound/soc/soc-io.c
index aa886cc..3fdc8c8 100644
--- a/sound/soc/soc-io.c
+++ b/sound/soc/soc-io.c
@@ -19,7 +19,6 @@
#include <trace/events/asoc.h>
-#ifdef CONFIG_REGMAP
static int hw_write(struct snd_soc_codec *codec, unsigned int reg,
unsigned int value)
{
@@ -135,12 +134,3 @@ int snd_soc_codec_set_cache_io(struct snd_soc_codec *codec,
return PTR_ERR_OR_ZERO(codec->control_data);
}
EXPORT_SYMBOL_GPL(snd_soc_codec_set_cache_io);
-#else
-int snd_soc_codec_set_cache_io(struct snd_soc_codec *codec,
- int addr_bits, int data_bits,
- enum snd_soc_control_type control)
-{
- return -ENOTSUPP;
-}
-EXPORT_SYMBOL_GPL(snd_soc_codec_set_cache_io);
-#endif
--
1.7.10.4

View file

@ -0,0 +1,237 @@
From 6a42dd698ddf91b6e9902b17e21dc13c6ae412ff Mon Sep 17 00:00:00 2001
From: John Crispin <blogic@openwrt.org>
Date: Sun, 16 Mar 2014 05:24:42 +0000
Subject: [PATCH 56/57] watchdog: add MT7621 support
Signed-off-by: John Crispin <blogic@openwrt.org>
---
drivers/watchdog/Kconfig | 7 ++
drivers/watchdog/Makefile | 1 +
drivers/watchdog/mt7621_wdt.c | 185 +++++++++++++++++++++++++++++++++++++++++
3 files changed, 193 insertions(+)
create mode 100644 drivers/watchdog/mt7621_wdt.c
diff --git a/drivers/watchdog/Kconfig b/drivers/watchdog/Kconfig
index 79d2589..40f4e5d 100644
--- a/drivers/watchdog/Kconfig
+++ b/drivers/watchdog/Kconfig
@@ -1193,6 +1193,13 @@ config RALINK_WDT
help
Hardware driver for the Ralink SoC Watchdog Timer.
+config MT7621_WDT
+ tristate "Mediatek SoC watchdog"
+ select WATCHDOG_CORE
+ depends on SOC_MT7620 || SOC_MT7621
+ help
+ Hardware driver for the Ralink SoC Watchdog Timer.
+
# PARISC Architecture
# POWERPC Architecture
diff --git a/drivers/watchdog/Makefile b/drivers/watchdog/Makefile
index 985a66c..bbd5d0d 100644
--- a/drivers/watchdog/Makefile
+++ b/drivers/watchdog/Makefile
@@ -138,6 +138,7 @@ obj-$(CONFIG_OCTEON_WDT) += octeon-wdt.o
octeon-wdt-y := octeon-wdt-main.o octeon-wdt-nmi.o
obj-$(CONFIG_LANTIQ_WDT) += lantiq_wdt.o
obj-$(CONFIG_RALINK_WDT) += rt2880_wdt.o
+obj-$(CONFIG_MT7621_WDT) += mt7621_wdt.o
# PARISC Architecture
diff --git a/drivers/watchdog/mt7621_wdt.c b/drivers/watchdog/mt7621_wdt.c
new file mode 100644
index 0000000..29f55c2
--- /dev/null
+++ b/drivers/watchdog/mt7621_wdt.c
@@ -0,0 +1,185 @@
+/*
+ * Ralink RT288x/RT3xxx/MT76xx built-in hardware watchdog timer
+ *
+ * Copyright (C) 2011 Gabor Juhos <juhosg@openwrt.org>
+ * Copyright (C) 2013 John Crispin <blogic@openwrt.org>
+ *
+ * This driver was based on: drivers/watchdog/softdog.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 published
+ * by the Free Software Foundation.
+ */
+
+#include <linux/clk.h>
+#include <linux/reset.h>
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/watchdog.h>
+#include <linux/miscdevice.h>
+#include <linux/moduleparam.h>
+#include <linux/platform_device.h>
+
+#include <asm/mach-ralink/ralink_regs.h>
+
+#define SYSC_RSTSTAT 0x38
+#define WDT_RST_CAUSE BIT(1)
+
+#define RALINK_WDT_TIMEOUT 30
+
+#define TIMER_REG_TMRSTAT 0x00
+#define TIMER_REG_TMR1LOAD 0x24
+#define TIMER_REG_TMR1CTL 0x20
+
+#define TMR1CTL_ENABLE BIT(7)
+#define TMR1CTL_RESTART BIT(9)
+
+static void __iomem *mt762x_wdt_base;
+
+static bool nowayout = WATCHDOG_NOWAYOUT;
+module_param(nowayout, bool, 0);
+MODULE_PARM_DESC(nowayout,
+ "Watchdog cannot be stopped once started (default="
+ __MODULE_STRING(WATCHDOG_NOWAYOUT) ")");
+
+static inline void rt_wdt_w32(unsigned reg, u32 val)
+{
+ iowrite32(val, mt762x_wdt_base + reg);
+}
+
+static inline u32 rt_wdt_r32(unsigned reg)
+{
+ return ioread32(mt762x_wdt_base + reg);
+}
+
+static int mt762x_wdt_ping(struct watchdog_device *w)
+{
+ rt_wdt_w32(TIMER_REG_TMRSTAT, TMR1CTL_RESTART);
+
+ return 0;
+}
+
+static int mt762x_wdt_set_timeout(struct watchdog_device *w, unsigned int t)
+{
+ w->timeout = t;
+ rt_wdt_w32(TIMER_REG_TMR1LOAD, t * 1000);
+ mt762x_wdt_ping(w);
+
+ return 0;
+}
+
+static int mt762x_wdt_start(struct watchdog_device *w)
+{
+ u32 t;
+
+ rt_wdt_w32(TIMER_REG_TMR1CTL, 1000 << 16);
+ mt762x_wdt_set_timeout(w, w->timeout);
+
+ t = rt_wdt_r32(TIMER_REG_TMR1CTL);
+ t |= TMR1CTL_ENABLE;
+ rt_wdt_w32(TIMER_REG_TMR1CTL, t);
+
+ return 0;
+}
+
+static int mt762x_wdt_stop(struct watchdog_device *w)
+{
+ u32 t;
+
+ mt762x_wdt_ping(w);
+
+ t = rt_wdt_r32(TIMER_REG_TMR1CTL);
+ t &= ~TMR1CTL_ENABLE;
+ rt_wdt_w32(TIMER_REG_TMR1CTL, t);
+
+ return 0;
+}
+
+static int mt762x_wdt_bootcause(void)
+{
+ if (rt_sysc_r32(SYSC_RSTSTAT) & WDT_RST_CAUSE)
+ return WDIOF_CARDRESET;
+
+ return 0;
+}
+
+static struct watchdog_info mt762x_wdt_info = {
+ .identity = "Mediatek Watchdog",
+ .options = WDIOF_SETTIMEOUT | WDIOF_KEEPALIVEPING | WDIOF_MAGICCLOSE,
+};
+
+static struct watchdog_ops mt762x_wdt_ops = {
+ .owner = THIS_MODULE,
+ .start = mt762x_wdt_start,
+ .stop = mt762x_wdt_stop,
+ .ping = mt762x_wdt_ping,
+ .set_timeout = mt762x_wdt_set_timeout,
+};
+
+static struct watchdog_device mt762x_wdt_dev = {
+ .info = &mt762x_wdt_info,
+ .ops = &mt762x_wdt_ops,
+ .min_timeout = 1,
+};
+
+static int mt762x_wdt_probe(struct platform_device *pdev)
+{
+ struct resource *res;
+ int ret;
+
+ res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+ mt762x_wdt_base = devm_request_and_ioremap(&pdev->dev, res);
+ if (IS_ERR(mt762x_wdt_base))
+ return PTR_ERR(mt762x_wdt_base);
+
+ device_reset(&pdev->dev);
+
+ mt762x_wdt_dev.dev = &pdev->dev;
+ mt762x_wdt_dev.bootstatus = mt762x_wdt_bootcause();
+ mt762x_wdt_dev.max_timeout = (0xfffful / 1000);
+ mt762x_wdt_dev.timeout = mt762x_wdt_dev.max_timeout;
+
+ watchdog_set_nowayout(&mt762x_wdt_dev, nowayout);
+
+ ret = watchdog_register_device(&mt762x_wdt_dev);
+ if (!ret)
+ dev_info(&pdev->dev, "Initialized\n");
+
+ return 0;
+}
+
+static int mt762x_wdt_remove(struct platform_device *pdev)
+{
+ watchdog_unregister_device(&mt762x_wdt_dev);
+
+ return 0;
+}
+
+static void mt762x_wdt_shutdown(struct platform_device *pdev)
+{
+ mt762x_wdt_stop(&mt762x_wdt_dev);
+}
+
+static const struct of_device_id mt762x_wdt_match[] = {
+ { .compatible = "mtk,mt7621-wdt" },
+ {},
+};
+MODULE_DEVICE_TABLE(of, mt762x_wdt_match);
+
+static struct platform_driver mt762x_wdt_driver = {
+ .probe = mt762x_wdt_probe,
+ .remove = mt762x_wdt_remove,
+ .shutdown = mt762x_wdt_shutdown,
+ .driver = {
+ .name = KBUILD_MODNAME,
+ .owner = THIS_MODULE,
+ .of_match_table = mt762x_wdt_match,
+ },
+};
+
+module_platform_driver(mt762x_wdt_driver);
+
+MODULE_DESCRIPTION("MediaTek MT762x hardware watchdog driver");
+MODULE_AUTHOR("John Crispin <blogic@openwrt.org");
+MODULE_LICENSE("GPL v2");
+MODULE_ALIAS_MISCDEV(WATCHDOG_MINOR);
--
1.7.10.4

View file

@ -0,0 +1,257 @@
From 0d3e92b4d3e2160873b610aabd46bbc4853ff82e Mon Sep 17 00:00:00 2001
From: John Crispin <blogic@openwrt.org>
Date: Thu, 19 Sep 2013 01:50:59 +0200
Subject: [PATCH 57/57] uvc: add iPassion iP2970 support
Signed-off-by: John Crispin <blogic@openwrt.org>
---
drivers/media/usb/uvc/uvc_driver.c | 14 ++++
drivers/media/usb/uvc/uvc_status.c | 2 +
drivers/media/usb/uvc/uvc_video.c | 147 ++++++++++++++++++++++++++++++++++++
drivers/media/usb/uvc/uvcvideo.h | 3 +
4 files changed, 166 insertions(+)
diff --git a/drivers/media/usb/uvc/uvc_driver.c b/drivers/media/usb/uvc/uvc_driver.c
index c3bb250..c6612d4 100644
--- a/drivers/media/usb/uvc/uvc_driver.c
+++ b/drivers/media/usb/uvc/uvc_driver.c
@@ -2467,6 +2467,20 @@ static struct usb_device_id uvc_ids[] = {
.bInterfaceProtocol = 0,
.driver_info = UVC_QUIRK_PROBE_MINMAX
| UVC_QUIRK_IGNORE_SELECTOR_UNIT },
+
+/* iPassion iP2970 */
+ { .match_flags = USB_DEVICE_ID_MATCH_DEVICE
+ | USB_DEVICE_ID_MATCH_INT_INFO,
+ .idVendor = 0x1B3B,
+ .idProduct = 0x2970,
+ .bInterfaceClass = USB_CLASS_VIDEO,
+ .bInterfaceSubClass = 1,
+ .bInterfaceProtocol = 0,
+ .driver_info = UVC_QUIRK_PROBE_MINMAX
+ | UVC_QUIRK_STREAM_NO_FID
+ | UVC_QUIRK_MOTION
+ | UVC_QUIRK_SINGLE_ISO },
+
/* Generic USB Video Class */
{ USB_INTERFACE_INFO(USB_CLASS_VIDEO, 1, 0) },
{}
diff --git a/drivers/media/usb/uvc/uvc_status.c b/drivers/media/usb/uvc/uvc_status.c
index f552ab9..7132ad4 100644
--- a/drivers/media/usb/uvc/uvc_status.c
+++ b/drivers/media/usb/uvc/uvc_status.c
@@ -139,6 +139,7 @@ static void uvc_status_complete(struct urb *urb)
switch (dev->status[0] & 0x0f) {
case UVC_STATUS_TYPE_CONTROL:
uvc_event_control(dev, dev->status, len);
+ dev->motion = 1;
break;
case UVC_STATUS_TYPE_STREAMING:
@@ -182,6 +183,7 @@ int uvc_status_init(struct uvc_device *dev)
}
pipe = usb_rcvintpipe(dev->udev, ep->desc.bEndpointAddress);
+ dev->motion = 0;
/* For high-speed interrupt endpoints, the bInterval value is used as
* an exponent of two. Some developers forgot about it.
diff --git a/drivers/media/usb/uvc/uvc_video.c b/drivers/media/usb/uvc/uvc_video.c
index 898c208..2e06163 100644
--- a/drivers/media/usb/uvc/uvc_video.c
+++ b/drivers/media/usb/uvc/uvc_video.c
@@ -21,6 +21,11 @@
#include <linux/wait.h>
#include <linux/atomic.h>
#include <asm/unaligned.h>
+#include <linux/skbuff.h>
+#include <linux/kobject.h>
+#include <linux/netlink.h>
+#include <linux/kobject.h>
+#include <linux/workqueue.h>
#include <media/v4l2-common.h>
@@ -1075,9 +1080,149 @@ static void uvc_video_decode_data(struct uvc_streaming *stream,
}
}
+struct bh_priv {
+ unsigned long seen;
+};
+
+struct bh_event {
+ const char *name;
+ struct sk_buff *skb;
+ struct work_struct work;
+};
+
+#define BH_ERR(fmt, args...) printk(KERN_ERR "%s: " fmt, "webcam", ##args )
+#define BH_DBG(fmt, args...) do {} while (0)
+#define BH_SKB_SIZE 2048
+
+extern u64 uevent_next_seqnum(void);
+static int seen = 0;
+
+static int bh_event_add_var(struct bh_event *event, int argv,
+ const char *format, ...)
+{
+ static char buf[128];
+ char *s;
+ va_list args;
+ int len;
+
+ if (argv)
+ return 0;
+
+ va_start(args, format);
+ len = vsnprintf(buf, sizeof(buf), format, args);
+ va_end(args);
+
+ if (len >= sizeof(buf)) {
+ BH_ERR("buffer size too small\n");
+ WARN_ON(1);
+ return -ENOMEM;
+ }
+
+ s = skb_put(event->skb, len + 1);
+ strcpy(s, buf);
+
+ BH_DBG("added variable '%s'\n", s);
+
+ return 0;
+}
+
+static int motion_hotplug_fill_event(struct bh_event *event)
+{
+ int s = jiffies;
+ int ret;
+
+ if (!seen)
+ seen = jiffies;
+
+ ret = bh_event_add_var(event, 0, "HOME=%s", "/");
+ if (ret)
+ return ret;
+
+ ret = bh_event_add_var(event, 0, "PATH=%s",
+ "/sbin:/bin:/usr/sbin:/usr/bin");
+ if (ret)
+ return ret;
+
+ ret = bh_event_add_var(event, 0, "SUBSYSTEM=usb");
+ if (ret)
+ return ret;
+
+ ret = bh_event_add_var(event, 0, "ACTION=motion");
+ if (ret)
+ return ret;
+
+ ret = bh_event_add_var(event, 0, "SEEN=%d", s - seen);
+ if (ret)
+ return ret;
+ seen = s;
+
+ ret = bh_event_add_var(event, 0, "SEQNUM=%llu", uevent_next_seqnum());
+
+ return ret;
+}
+
+static void motion_hotplug_work(struct work_struct *work)
+{
+ struct bh_event *event = container_of(work, struct bh_event, work);
+ int ret = 0;
+
+ event->skb = alloc_skb(BH_SKB_SIZE, GFP_KERNEL);
+ if (!event->skb)
+ goto out_free_event;
+
+ ret = bh_event_add_var(event, 0, "%s@", "add");
+ if (ret)
+ goto out_free_skb;
+
+ ret = motion_hotplug_fill_event(event);
+ if (ret)
+ goto out_free_skb;
+
+ NETLINK_CB(event->skb).dst_group = 1;
+ broadcast_uevent(event->skb, 0, 1, GFP_KERNEL);
+
+out_free_skb:
+ if (ret) {
+ BH_ERR("work error %d\n", ret);
+ kfree_skb(event->skb);
+ }
+out_free_event:
+ kfree(event);
+}
+
+static int motion_hotplug_create_event(void)
+{
+ struct bh_event *event;
+
+ event = kzalloc(sizeof(*event), GFP_KERNEL);
+ if (!event)
+ return -ENOMEM;
+
+ event->name = "motion";
+
+ INIT_WORK(&event->work, (void *)(void *)motion_hotplug_work);
+ schedule_work(&event->work);
+
+ return 0;
+}
+
+#define MOTION_FLAG_OFFSET 4
static void uvc_video_decode_end(struct uvc_streaming *stream,
struct uvc_buffer *buf, const __u8 *data, int len)
{
+ if ((stream->dev->quirks & UVC_QUIRK_MOTION) &&
+ (data[len - 2] == 0xff) && (data[len - 1] == 0xd9)) {
+ u8 *mem;
+ buf->state = UVC_BUF_STATE_READY;
+ mem = (u8 *) (buf->mem + MOTION_FLAG_OFFSET);
+ if ( stream->dev->motion ) {
+ stream->dev->motion = 0;
+ motion_hotplug_create_event();
+ } else {
+ *mem &= 0x7f;
+ }
+ }
+
/* Mark the buffer as done if the EOF marker is set. */
if (data[1] & UVC_STREAM_EOF && buf->bytesused != 0) {
uvc_trace(UVC_TRACE_FRAME, "Frame complete (EOF found).\n");
@@ -1478,6 +1623,8 @@ static int uvc_init_video_isoc(struct uvc_streaming *stream,
if (npackets == 0)
return -ENOMEM;
+ if (stream->dev->quirks & UVC_QUIRK_SINGLE_ISO)
+ npackets = 1;
size = npackets * psize;
for (i = 0; i < UVC_URBS; ++i) {
diff --git a/drivers/media/usb/uvc/uvcvideo.h b/drivers/media/usb/uvc/uvcvideo.h
index 9e35982..3cacdfd 100644
--- a/drivers/media/usb/uvc/uvcvideo.h
+++ b/drivers/media/usb/uvc/uvcvideo.h
@@ -137,6 +137,8 @@
#define UVC_QUIRK_FIX_BANDWIDTH 0x00000080
#define UVC_QUIRK_PROBE_DEF 0x00000100
#define UVC_QUIRK_RESTRICT_FRAME_RATE 0x00000200
+#define UVC_QUIRK_MOTION 0x00000400
+#define UVC_QUIRK_SINGLE_ISO 0x00000800
/* Format flags */
#define UVC_FMT_FLAG_COMPRESSED 0x00000001
@@ -539,6 +541,7 @@ struct uvc_device {
__u8 *status;
struct input_dev *input;
char input_phys[64];
+ int motion;
};
enum uvc_handle_state {
--
1.7.10.4

View file

@ -0,0 +1,13 @@
--- a/drivers/mtd/mtdpart.c
+++ b/drivers/mtd/mtdpart.c
@@ -805,10 +805,6 @@ static void split_uimage(struct mtd_info
return;
len = be32_to_cpu(hdr.size) + 0x40;
- len = mtd_pad_erasesize(master, part->offset, len);
- if (len + master->erasesize > part->mtd.size)
- return;
-
__mtd_add_partition(master, "rootfs", part->offset + len,
part->mtd.size - len, false);
}

View file

@ -0,0 +1,28 @@
--- a/drivers/mtd/mtdpart.c
+++ b/drivers/mtd/mtdpart.c
@@ -793,8 +793,11 @@ static void split_uimage(struct mtd_info
{
struct {
__be32 magic;
- __be32 pad[2];
+ __be32 pad0[2];
__be32 size;
+ __be32 pad1[4];
+ __be32 name[7];
+ __be32 kern_size;
} hdr;
size_t len;
@@ -804,7 +807,11 @@ static void split_uimage(struct mtd_info
if (len != sizeof(hdr) || hdr.magic != cpu_to_be32(UBOOT_MAGIC))
return;
- len = be32_to_cpu(hdr.size) + 0x40;
+ if (hdr.kern_size != 0 && hdr.name[0] == 0)
+ len = be32_to_cpu(hdr.kern_size);
+ else
+ len = be32_to_cpu(hdr.size) + 0x40;
+
__mtd_add_partition(master, "rootfs", part->offset + len,
part->mtd.size - len, false);
}

View file

@ -0,0 +1,52 @@
From c174d2250e402399ad7dbdd57d51883d8804bba0 Mon Sep 17 00:00:00 2001
From: John Crispin <blogic@openwrt.org>
Date: Mon, 15 Jul 2013 00:40:37 +0200
Subject: [PATCH 31/33] owrt: MIPS: add OWRTDTB secion
Signed-off-by: John Crispin <blogic@openwrt.org>
---
arch/mips/kernel/head.S | 3 +++
arch/mips/ralink/Makefile | 2 +-
arch/mips/ralink/of.c | 4 +++-
3 files changed, 7 insertions(+), 2 deletions(-)
--- a/arch/mips/kernel/head.S
+++ b/arch/mips/kernel/head.S
@@ -146,6 +146,9 @@ EXPORT(__image_cmdline)
.fill 0x400
#endif /* CONFIG_IMAGE_CMDLINE_HACK */
+ .ascii "OWRTDTB:"
+ EXPORT(__image_dtb)
+ .fill 0x4000
__REF
NESTED(kernel_entry, 16, sp) # kernel entry point
--- a/arch/mips/ralink/Makefile
+++ b/arch/mips/ralink/Makefile
@@ -26,4 +26,4 @@ obj-$(CONFIG_EARLY_PRINTK) += early_prin
obj-$(CONFIG_DEBUG_FS) += bootrom.o
-obj-y += dts/
+#obj-y += dts/
--- a/arch/mips/ralink/of.c
+++ b/arch/mips/ralink/of.c
@@ -90,6 +90,8 @@ static int __init early_init_dt_find_mem
return 0;
}
+extern struct boot_param_header __image_dtb;
+
void __init plat_mem_setup(void)
{
set_io_port_base(KSEG1);
@@ -98,7 +100,7 @@ void __init plat_mem_setup(void)
* Load the builtin devicetree. This causes the chosen node to be
* parsed resulting in our memory appearing
*/
- __dt_setup_arch(&__dtb_start);
+ __dt_setup_arch(&__image_dtb);
of_scan_flat_dt(early_init_dt_find_memory, NULL);
if (memory_dtb)

View file

@ -0,0 +1,167 @@
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_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_DMA_NONCOHERENT=y
# CONFIG_DTB_RT2880_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_INITRAMFS_SOURCE=""
CONFIG_IP17XX_PHY=y
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=4
CONFIG_MIPS_L1_CACHE_SHIFT_4=y
# 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_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_MDIO=y
CONFIG_NET_RALINK_MDIO_RT2880=y
CONFIG_NET_RX_BUSY_POLL=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_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 is not set
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 is not set
# CONFIG_SOC_MT7621 is not set
CONFIG_SOC_RT288X=y
# 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_SUPPORT=y
CONFIG_USE_OF=y
CONFIG_WATCHDOG_CORE=y
# CONFIG_ZBUD is not set
CONFIG_ZONE_DMA_FLAG=0

View file

@ -0,0 +1,171 @@
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_RT305X_EVAL is not set
CONFIG_DTB_RT_NONE=y
CONFIG_DTC=y
# CONFIG_DWC_OTG is not set
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_RANDOM=m
CONFIG_HZ_PERIODIC=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_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_ESW_RT3052=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_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 is not set
# CONFIG_SOC_MT7621 is not set
# CONFIG_SOC_RT288X is not set
CONFIG_SOC_RT305X=y
# 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

View file

@ -0,0 +1,183 @@
CONFIG_AR8216_PHY=y
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_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_RT3883_EVAL is not set
CONFIG_DTB_RT_NONE=y
CONFIG_DTC=y
CONFIG_EARLY_PRINTK=y
# CONFIG_EARLY_PRINTK_8250 is not set
CONFIG_ETHERNET_PACKET_MANGLE=y
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_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_PHYSMAP=y
CONFIG_MTD_SPLIT_FIRMWARE=y
CONFIG_MTD_SPLIT_SEAMA_FW=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_MDIO=y
CONFIG_NET_RALINK_MDIO_RT2880=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_RTL8366_SMI=y
CONFIG_RTL8367B_PHY=y
CONFIG_RTL8367_PHY=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 is not set
# CONFIG_SOC_MT7621 is not set
# CONFIG_SOC_RT288X is not set
# CONFIG_SOC_RT305X is not set
CONFIG_SOC_RT3883=y
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