ralink: add mt7621 support
there are still various missing pieces for full support. Signed-off-by: John Crispin <blogic@openwrt.org> SVN-Revision: 39040
This commit is contained in:
parent
594442a37e
commit
b4b0a55aab
20 changed files with 7513 additions and 1 deletions
|
@ -9,7 +9,7 @@ include $(TOPDIR)/rules.mk
|
|||
ARCH:=mipsel
|
||||
BOARD:=ramips
|
||||
BOARDNAME:=Ralink RT288x/RT3xxx
|
||||
SUBTARGETS:=rt305x mt7620a mt7620n rt3883 rt288x
|
||||
SUBTARGETS:=rt305x mt7620a mt7620n mt7621 rt3883 rt288x
|
||||
FEATURES:=squashfs gpio
|
||||
|
||||
LINUX_VERSION:=3.10.21
|
||||
|
|
16
target/linux/ramips/dts/MT7621.dts
Normal file
16
target/linux/ramips/dts/MT7621.dts
Normal file
|
@ -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";
|
||||
};
|
||||
};
|
245
target/linux/ramips/dts/mt7621.dtsi
Normal file
245
target/linux/ramips/dts/mt7621.dtsi
Normal file
|
@ -0,0 +1,245 @@
|
|||
/ {
|
||||
#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;
|
||||
};
|
||||
|
||||
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-platform1";
|
||||
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>;
|
||||
|
||||
};
|
||||
};
|
|
@ -29,10 +29,16 @@ define kernel_entry
|
|||
-a 0x88000000 -e 0x88000000
|
||||
endef
|
||||
else
|
||||
ifeq ($(CONFIG_SOC_MT7621),y)
|
||||
define kernel_entry
|
||||
-a 0x80001000 -e 0x80001000
|
||||
endef
|
||||
else
|
||||
define kernel_entry
|
||||
-a 0x80000000 -e 0x80000000
|
||||
endef
|
||||
endif
|
||||
endif
|
||||
|
||||
define MkCombineduImage
|
||||
$(call PatchKernelLzma,$(2),$(3))
|
||||
|
@ -648,6 +654,19 @@ endef
|
|||
endif
|
||||
|
||||
|
||||
#
|
||||
# MT7621 Profiles
|
||||
#
|
||||
|
||||
Image/Build/Profile/MT7621=$(call BuildFirmware/Default4M/$(1),$(1),mt7621,MT7621)
|
||||
|
||||
ifeq ($(SUBTARGET),mt7621)
|
||||
define Image/Build/Profile/Default
|
||||
$(call Image/Build/Profile/MT7621,$(1))
|
||||
endef
|
||||
endif
|
||||
|
||||
|
||||
#
|
||||
# Generic Targets
|
||||
#
|
||||
|
|
|
@ -147,6 +147,7 @@ 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
|
||||
|
|
|
@ -144,6 +144,7 @@ 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
|
||||
|
|
200
target/linux/ramips/mt7621/config-3.10
Normal file
200
target/linux/ramips/mt7621/config-3.10
Normal file
|
@ -0,0 +1,200 @@
|
|||
CONFIG_ARCH_BINFMT_ELF_RANDOMIZE_PIE=y
|
||||
CONFIG_ARCH_DISCARD_MEMBLOCK=y
|
||||
CONFIG_ARCH_HAS_ATOMIC64_DEC_IF_POSITIVE=y
|
||||
CONFIG_ARCH_HAVE_CUSTOM_GPIO_H=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_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_PCI_IOMAP=y
|
||||
CONFIG_GENERIC_SMP_IDLE_THREAD=y
|
||||
CONFIG_GPIOLIB=y
|
||||
CONFIG_GPIO_DEVRES=y
|
||||
# CONFIG_GPIO_MT7621 is not set
|
||||
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_BOOTMEM_INFO_NODE is not set
|
||||
CONFIG_HAVE_CLK=y
|
||||
CONFIG_HAVE_C_RECORDMCOUNT=y
|
||||
CONFIG_HAVE_DEBUG_KMEMLEAK=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_GENERIC_HARDIRQS=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_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_M25PXX_USE_FAST_READ=y
|
||||
CONFIG_MDIO_BOARDINFO=y
|
||||
# CONFIG_MII is not set
|
||||
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_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_PERF_SHARED_TC_COUNTERS=y
|
||||
# CONFIG_MIPS_VPE_LOADER is not set
|
||||
CONFIG_MODULES_USE_ELF_REL=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_OF_PARTS=y
|
||||
CONFIG_MTD_PHYSMAP=y
|
||||
CONFIG_MTD_PHYSMAP_OF=y
|
||||
CONFIG_MTD_SPLIT_FIRMWARE=y
|
||||
CONFIG_MTD_UIMAGE_SPLIT=y
|
||||
CONFIG_MUTEX_SPIN_ON_OWNER=y
|
||||
CONFIG_NEED_DMA_MAP_STATE=y
|
||||
# CONFIG_NET_RALINK is not set
|
||||
CONFIG_NLS=m
|
||||
CONFIG_NO_GENERIC_PCI_IOPORT_MAP=y
|
||||
CONFIG_NR_CPUS=4
|
||||
CONFIG_NR_CPUS_DEFAULT_2=y
|
||||
CONFIG_OF=y
|
||||
CONFIG_OF_ADDRESS=y
|
||||
CONFIG_OF_DEVICE=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_PINMUX=y
|
||||
# CONFIG_PREEMPT_RCU is not set
|
||||
CONFIG_RALINK=y
|
||||
CONFIG_RALINK_USBPHY=y
|
||||
CONFIG_RCU_STALL_COMMON=y
|
||||
CONFIG_RESET_CONTROLLER=y
|
||||
CONFIG_RFS_ACCEL=y
|
||||
CONFIG_RPS=y
|
||||
# CONFIG_SAMSUNG_USB2PHY is not set
|
||||
# CONFIG_SAMSUNG_USB3PHY is not set
|
||||
# CONFIG_SAMSUNG_USBPHY is not set
|
||||
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_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_UIDGID_CONVERTED=y
|
||||
CONFIG_USB=m
|
||||
CONFIG_USB_ARCH_HAS_XHCI=y
|
||||
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_GENERIC_SMP_HELPERS=y
|
||||
CONFIG_USE_OF=y
|
||||
CONFIG_WATCHDOG_CORE=y
|
||||
CONFIG_WEAK_ORDERING=y
|
||||
CONFIG_XPS=y
|
||||
CONFIG_ZONE_DMA_FLAG=0
|
18
target/linux/ramips/mt7621/profiles/00-default.mk
Normal file
18
target/linux/ramips/mt7621/profiles/00-default.mk
Normal file
|
@ -0,0 +1,18 @@
|
|||
#
|
||||
# Copyright (C) 2011 OpenWrt.org
|
||||
#
|
||||
# This is free software, licensed under the GNU General Public License v2.
|
||||
# See /LICENSE for more information.
|
||||
#
|
||||
|
||||
define Profile/Default
|
||||
NAME:=Default Profile
|
||||
PACKAGES:=\
|
||||
kmod-usb-core kmod-usb-dwc2 \
|
||||
kmod-ledtrig-usbdev
|
||||
endef
|
||||
|
||||
define Profile/Default/Description
|
||||
Default package set compatible with most boards.
|
||||
endef
|
||||
$(eval $(call Profile,Default))
|
15
target/linux/ramips/mt7621/target.mk
Normal file
15
target/linux/ramips/mt7621/target.mk
Normal file
|
@ -0,0 +1,15 @@
|
|||
#
|
||||
# Copyright (C) 2009 OpenWrt.org
|
||||
#
|
||||
|
||||
SUBTARGET:=mt7621
|
||||
BOARDNAME:=MT7621 based boards
|
||||
ARCH_PACKAGES:=ramips_24kec
|
||||
FEATURES+=usb
|
||||
CPU_TYPE:=24kec
|
||||
CPU_SUBTYPE:=dsp
|
||||
|
||||
define Target/Description
|
||||
Build firmware images for Ralink MT7621 based boards.
|
||||
endef
|
||||
|
|
@ -0,0 +1,162 @@
|
|||
From 926ae0ca5017a421709ab0478582683c29988b05 Mon Sep 17 00:00:00 2001
|
||||
From: John Crispin <blogic@openwrt.org>
|
||||
Date: Wed, 27 Nov 2013 20:58:16 +0100
|
||||
Subject: [PATCH 10/20] MTD: add chunked read io to m25p80
|
||||
|
||||
Signed-off-by: John Crispin <blogic@openwrt.org>
|
||||
---
|
||||
drivers/mtd/devices/m25p80.c | 127 ++++++++++++++++++++++++++++++++++++++++++
|
||||
1 file changed, 127 insertions(+)
|
||||
|
||||
Index: linux-3.10.21/drivers/mtd/devices/m25p80.c
|
||||
===================================================================
|
||||
--- linux-3.10.21.orig/drivers/mtd/devices/m25p80.c 2013-12-09 19:34:40.828651303 +0100
|
||||
+++ linux-3.10.21/drivers/mtd/devices/m25p80.c 2013-12-09 19:40:37.636659793 +0100
|
||||
@@ -392,6 +392,57 @@
|
||||
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);
|
||||
+
|
||||
+ 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) -
|
||||
+ (flash->fast_read ? 1 : 0);
|
||||
+
|
||||
+ 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
|
||||
@@ -479,6 +530,76 @@
|
||||
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)
|
||||
{
|
||||
@@ -1057,6 +1178,12 @@
|
||||
flash->fast_read = true;
|
||||
#endif
|
||||
|
||||
+ 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;
|
||||
+ }
|
||||
+
|
||||
#ifdef CONFIG_M25PXX_USE_FAST_READ
|
||||
flash->fast_read = true;
|
||||
#endif
|
336
target/linux/ramips/patches-3.10/0500-spi-mt7621.patch
Normal file
336
target/linux/ramips/patches-3.10/0500-spi-mt7621.patch
Normal file
|
@ -0,0 +1,336 @@
|
|||
Index: linux-3.10.21/drivers/spi/spi-rt2880.c
|
||||
===================================================================
|
||||
--- linux-3.10.21.orig/drivers/spi/spi-rt2880.c 2013-12-09 20:17:54.380713104 +0100
|
||||
+++ linux-3.10.21/drivers/spi/spi-rt2880.c 2013-12-09 20:35:08.004737585 +0100
|
||||
@@ -21,8 +21,11 @@
|
||||
#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 DRIVER_NAME "spi-rt2880"
|
||||
/* only one slave is supported*/
|
||||
#define RALINK_NUM_CHIPSELECTS 1
|
||||
@@ -63,6 +66,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 +92,8 @@
|
||||
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 +173,17 @@
|
||||
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 +199,7 @@
|
||||
|
||||
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 +215,17 @@
|
||||
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 +244,26 @@
|
||||
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 +303,100 @@
|
||||
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 +438,25 @@
|
||||
}
|
||||
|
||||
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 +492,41 @@
|
||||
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 +535,10 @@
|
||||
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 +577,13 @@
|
||||
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 +604,6 @@
|
||||
|
||||
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,
|
|
@ -0,0 +1,26 @@
|
|||
From e5327a1c6969316370af5cae7cfe6b8163178575 Mon Sep 17 00:00:00 2001
|
||||
From: John Crispin <blogic@openwrt.org>
|
||||
Date: Mon, 2 Dec 2013 16:07:23 +0100
|
||||
Subject: [PATCH 500/507] MIPS: increase GIC_INTR_MAX
|
||||
|
||||
Signed-off-by: John Crispin <blogic@openwrt.org>
|
||||
---
|
||||
arch/mips/include/asm/gic.h | 2 +-
|
||||
1 file changed, 1 insertion(+), 1 deletion(-)
|
||||
|
||||
diff --git a/arch/mips/include/asm/gic.h b/arch/mips/include/asm/gic.h
|
||||
index b2e3e93..2902d93 100644
|
||||
--- a/arch/mips/include/asm/gic.h
|
||||
+++ b/arch/mips/include/asm/gic.h
|
||||
@@ -19,7 +19,7 @@
|
||||
#define GIC_TRIG_EDGE 1
|
||||
#define GIC_TRIG_LEVEL 0
|
||||
|
||||
-#define GIC_NUM_INTRS (24 + NR_CPUS * 2)
|
||||
+#define GIC_NUM_INTRS (56 + NR_CPUS * 2)
|
||||
|
||||
#define MSK(n) ((1 << (n)) - 1)
|
||||
#define REG32(addr) (*(volatile unsigned int *) (addr))
|
||||
--
|
||||
1.7.10.4
|
||||
|
|
@ -0,0 +1,683 @@
|
|||
From 99342a0481d49b6e1ade90fdb02f597cb75f103f Mon Sep 17 00:00:00 2001
|
||||
From: John Crispin <blogic@openwrt.org>
|
||||
Date: Mon, 2 Dec 2013 16:11:09 +0100
|
||||
Subject: [PATCH 502/507] MIPS: ralink: add MT7621 support
|
||||
|
||||
Signed-off-by: John Crispin <blogic@openwrt.org>
|
||||
---
|
||||
arch/mips/include/asm/mach-ralink/mt7621.h | 39 +++++
|
||||
arch/mips/ralink/Kconfig | 18 ++
|
||||
arch/mips/ralink/Makefile | 7 +-
|
||||
arch/mips/ralink/Platform | 5 +
|
||||
arch/mips/ralink/irq-gic.c | 255 ++++++++++++++++++++++++++++
|
||||
arch/mips/ralink/malta-amon.c | 81 +++++++++
|
||||
arch/mips/ralink/mt7621.c | 186 ++++++++++++++++++++
|
||||
7 files changed, 590 insertions(+), 1 deletion(-)
|
||||
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
|
||||
|
||||
Index: linux-3.10.21/arch/mips/include/asm/mach-ralink/mt7621.h
|
||||
===================================================================
|
||||
--- /dev/null 1970-01-01 00:00:00.000000000 +0000
|
||||
+++ linux-3.10.21/arch/mips/include/asm/mach-ralink/mt7621.h 2013-12-09 19:52:51.752677298 +0100
|
||||
@@ -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
|
||||
Index: linux-3.10.21/arch/mips/ralink/Kconfig
|
||||
===================================================================
|
||||
--- linux-3.10.21.orig/arch/mips/ralink/Kconfig 2013-12-09 19:51:55.600675960 +0100
|
||||
+++ linux-3.10.21/arch/mips/ralink/Kconfig 2013-12-09 19:52:51.756677296 +0100
|
||||
@@ -1,5 +1,10 @@
|
||||
if RALINK
|
||||
|
||||
+config IRQ_INTC
|
||||
+ bool
|
||||
+ default y
|
||||
+ depends on !SOC_MT7621
|
||||
+
|
||||
config CLKEVT_RT3352
|
||||
bool "Systick Clockevent source"
|
||||
depends on SOC_RT305X || SOC_MT7620
|
||||
@@ -35,6 +40,15 @@
|
||||
select USB_ARCH_HAS_EHCI
|
||||
select HW_HAS_PCI
|
||||
|
||||
+ 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
|
||||
@@ -62,6 +76,10 @@
|
||||
bool "MT7620A eval kit"
|
||||
depends on SOC_MT7620
|
||||
|
||||
+ config DTB_MT7621_EVAL
|
||||
+ bool "MT7621 eval kit"
|
||||
+ depends on SOC_MT7621
|
||||
+
|
||||
endchoice
|
||||
|
||||
endif
|
||||
Index: linux-3.10.21/arch/mips/ralink/Makefile
|
||||
===================================================================
|
||||
--- linux-3.10.21.orig/arch/mips/ralink/Makefile 2013-12-09 19:51:55.600675960 +0100
|
||||
+++ linux-3.10.21/arch/mips/ralink/Makefile 2013-12-09 19:52:51.756677296 +0100
|
||||
@@ -6,7 +6,11 @@
|
||||
# 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_IRQ_INTC) += irq.o
|
||||
+obj-$(CONFIG_IRQ_GIC) += irq-gic.o
|
||||
+obj-$(CONFIG_MIPS_MT_SMP) += malta-amon.o
|
||||
|
||||
obj-$(CONFIG_CLKEVT_RT3352) += cevt-rt3352.o
|
||||
|
||||
@@ -16,6 +20,7 @@
|
||||
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
|
||||
|
||||
Index: linux-3.10.21/arch/mips/ralink/Platform
|
||||
===================================================================
|
||||
--- linux-3.10.21.orig/arch/mips/ralink/Platform 2013-12-09 19:51:55.000000000 +0100
|
||||
+++ linux-3.10.21/arch/mips/ralink/Platform 2013-12-09 19:53:54.660678800 +0100
|
||||
@@ -26,3 +26,10 @@
|
||||
# Ralink MT7620
|
||||
#
|
||||
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_MT7620) += -I$(srctree)/arch/mips/include/asm/mach-ralink/mt7621
|
||||
Index: linux-3.10.21/arch/mips/ralink/irq-gic.c
|
||||
===================================================================
|
||||
--- /dev/null 1970-01-01 00:00:00.000000000 +0000
|
||||
+++ linux-3.10.21/arch/mips/ralink/irq-gic.c 2013-12-09 19:52:51.756677296 +0100
|
||||
@@ -0,0 +1,255 @@
|
||||
+#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>
|
||||
+
|
||||
+static unsigned long _gcmp_base;
|
||||
+static int gic_resched_int_base = 56;
|
||||
+static int gic_call_int_base = 60;
|
||||
+static struct irq_chip *irq_gic;
|
||||
+
|
||||
+#define GIC_RESCHED_INT(cpu) (gic_resched_int_base+(cpu))
|
||||
+#define GIC_CALL_INT(cpu) (gic_call_int_base+(cpu))
|
||||
+
|
||||
+static struct gic_intr_map gic_intr_map[GIC_NUM_INTRS] = {
|
||||
+ { 0, GIC_CPU_INT0, GIC_POL_POS, GIC_TRIG_LEVEL, GIC_FLAG_TRANSPARENT }, //0
|
||||
+ { 0, GIC_CPU_INT0, GIC_POL_POS, GIC_TRIG_LEVEL, GIC_FLAG_TRANSPARENT },
|
||||
+ { GIC_UNUSED },
|
||||
+ { 0, GIC_CPU_INT3, GIC_POL_POS, GIC_TRIG_LEVEL, GIC_FLAG_TRANSPARENT }, //FE
|
||||
+ { 0, GIC_CPU_INT4, GIC_POL_POS, GIC_TRIG_LEVEL, GIC_FLAG_TRANSPARENT }, //PCIE0
|
||||
+ { GIC_UNUSED},
|
||||
+ { 0, GIC_CPU_INT0, GIC_POL_POS, GIC_TRIG_LEVEL, GIC_FLAG_TRANSPARENT },
|
||||
+ { 0, GIC_CPU_INT0, GIC_POL_POS, GIC_TRIG_LEVEL, GIC_FLAG_TRANSPARENT },
|
||||
+ { 0, GIC_CPU_INT0, GIC_POL_POS, GIC_TRIG_LEVEL, GIC_FLAG_TRANSPARENT },
|
||||
+ { 0, GIC_CPU_INT0, GIC_POL_POS, GIC_TRIG_LEVEL, GIC_FLAG_TRANSPARENT }, //10
|
||||
+ { 0, GIC_CPU_INT0, GIC_POL_POS, GIC_TRIG_LEVEL, GIC_FLAG_TRANSPARENT },
|
||||
+ { 0, GIC_CPU_INT0, GIC_POL_POS, GIC_TRIG_LEVEL, GIC_FLAG_TRANSPARENT },
|
||||
+ { 0, GIC_CPU_INT0, GIC_POL_POS, GIC_TRIG_LEVEL, GIC_FLAG_TRANSPARENT },
|
||||
+ { GIC_UNUSED },
|
||||
+ { GIC_UNUSED },
|
||||
+ { 0, GIC_CPU_INT0, GIC_POL_POS, GIC_TRIG_LEVEL, GIC_FLAG_TRANSPARENT },
|
||||
+ { 0, GIC_CPU_INT0, GIC_POL_POS, GIC_TRIG_LEVEL, GIC_FLAG_TRANSPARENT },
|
||||
+ { 0, GIC_CPU_INT0, GIC_POL_POS, GIC_TRIG_LEVEL, GIC_FLAG_TRANSPARENT },
|
||||
+ { 0, GIC_CPU_INT0, GIC_POL_POS, GIC_TRIG_LEVEL, GIC_FLAG_TRANSPARENT },
|
||||
+ { 0, GIC_CPU_INT0, GIC_POL_POS, GIC_TRIG_LEVEL, GIC_FLAG_TRANSPARENT }, //20
|
||||
+ { 0, GIC_CPU_INT0, GIC_POL_POS, GIC_TRIG_LEVEL, GIC_FLAG_TRANSPARENT },
|
||||
+ { 0, GIC_CPU_INT0, GIC_POL_POS, GIC_TRIG_LEVEL, GIC_FLAG_TRANSPARENT },
|
||||
+ { GIC_UNUSED },
|
||||
+ { 0, GIC_CPU_INT0, GIC_POL_POS, GIC_TRIG_LEVEL, GIC_FLAG_TRANSPARENT },
|
||||
+ { 0, GIC_CPU_INT0, GIC_POL_POS, GIC_TRIG_LEVEL, GIC_FLAG_TRANSPARENT }, //25
|
||||
+ { 0, GIC_CPU_INT0, GIC_POL_POS, GIC_TRIG_LEVEL, GIC_FLAG_TRANSPARENT },
|
||||
+ { 0, GIC_CPU_INT0, GIC_POL_POS, GIC_TRIG_LEVEL, GIC_FLAG_TRANSPARENT },
|
||||
+ { 0, GIC_CPU_INT0, GIC_POL_POS, GIC_TRIG_LEVEL, GIC_FLAG_TRANSPARENT },
|
||||
+ { 0, GIC_CPU_INT0, GIC_POL_POS, GIC_TRIG_LEVEL, GIC_FLAG_TRANSPARENT },
|
||||
+ { 0, GIC_CPU_INT0, GIC_POL_POS, GIC_TRIG_LEVEL, GIC_FLAG_TRANSPARENT },//30
|
||||
+ { 0, GIC_CPU_INT0, GIC_POL_POS, GIC_TRIG_LEVEL, GIC_FLAG_TRANSPARENT },
|
||||
+};
|
||||
+
|
||||
+static struct gic_intr_map ipi_intr_map[8] = {
|
||||
+ { 0, GIC_CPU_INT1, GIC_POL_POS, GIC_TRIG_EDGE, GIC_FLAG_IPI },
|
||||
+ { 1, GIC_CPU_INT1, GIC_POL_POS, GIC_TRIG_EDGE, GIC_FLAG_IPI },
|
||||
+ { 2, GIC_CPU_INT1, GIC_POL_POS, GIC_TRIG_EDGE, GIC_FLAG_IPI },
|
||||
+ { 3, GIC_CPU_INT1, GIC_POL_POS, GIC_TRIG_EDGE, GIC_FLAG_IPI },
|
||||
+ { 0, GIC_CPU_INT2, GIC_POL_POS, GIC_TRIG_EDGE, GIC_FLAG_IPI },
|
||||
+ { 1, GIC_CPU_INT2, GIC_POL_POS, GIC_TRIG_EDGE, GIC_FLAG_IPI },
|
||||
+ { 2, GIC_CPU_INT2, GIC_POL_POS, GIC_TRIG_EDGE, GIC_FLAG_IPI },
|
||||
+ { 3, GIC_CPU_INT2, GIC_POL_POS, GIC_TRIG_EDGE, GIC_FLAG_IPI },
|
||||
+};
|
||||
+
|
||||
+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"
|
||||
+};
|
||||
+
|
||||
+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
|
||||
+vi_gic_irqdispatch(void)
|
||||
+{
|
||||
+ int irq = gic_get_int();
|
||||
+
|
||||
+ if (irq >= 0)
|
||||
+ do_IRQ(MIPS_GIC_IRQ_BASE + irq);
|
||||
+}
|
||||
+
|
||||
+static void
|
||||
+vi_timer_irqdispatch(void)
|
||||
+{
|
||||
+ do_IRQ(cp0_compare_irq);
|
||||
+}
|
||||
+
|
||||
+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);
|
||||
+}
|
||||
+
|
||||
+asmlinkage void
|
||||
+plat_irq_dispatch(void)
|
||||
+{
|
||||
+ unsigned int pending = read_c0_status() & read_c0_cause() & ST0_IM;
|
||||
+
|
||||
+ if (pending & CAUSEF_IP7)
|
||||
+ do_IRQ(cp0_compare_irq);
|
||||
+ else if (pending & (CAUSEF_IP4 | CAUSEF_IP3))
|
||||
+ vi_gic_irqdispatch();
|
||||
+ else
|
||||
+ spurious_interrupt();
|
||||
+}
|
||||
+
|
||||
+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, handle_percpu_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(3, vi_gic_irqdispatch);
|
||||
+ set_vi_handler(4, vi_gic_irqdispatch);
|
||||
+ set_vi_handler(7, vi_timer_irqdispatch);
|
||||
+ }
|
||||
+
|
||||
+ memcpy(&gic_intr_map[gic_resched_int_base], ipi_intr_map, sizeof(ipi_intr_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");
|
||||
+
|
||||
+ for (i = 0; i < NR_CPUS; 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);
|
||||
+ }
|
||||
+
|
||||
+ change_c0_status(ST0_IM, STATUSF_IP3 | STATUSF_IP4 | STATUSF_IP6 |
|
||||
+ STATUSF_IP7);
|
||||
+ 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);
|
||||
+}
|
||||
Index: linux-3.10.21/arch/mips/ralink/malta-amon.c
|
||||
===================================================================
|
||||
--- /dev/null 1970-01-01 00:00:00.000000000 +0000
|
||||
+++ linux-3.10.21/arch/mips/ralink/malta-amon.c 2013-12-09 19:52:51.756677296 +0100
|
||||
@@ -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);
|
||||
+}
|
||||
Index: linux-3.10.21/arch/mips/ralink/mt7621.c
|
||||
===================================================================
|
||||
--- /dev/null 1970-01-01 00:00:00.000000000 +0000
|
||||
+++ linux-3.10.21/arch/mips/ralink/mt7621.c 2013-12-09 19:52:51.760677296 +0100
|
||||
@@ -0,0 +1,186 @@
|
||||
+/*
|
||||
+ * 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/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;
|
||||
+ printk("%s:%s[%d]\n", __FILE__, __func__, __LINE__);
|
||||
+ break;
|
||||
+
|
||||
+ case 1:
|
||||
+ fbdiv = ((rt_sysc_r32(0x648) >> 4) & 0x7F) + 1;
|
||||
+ syscfg = rt_sysc_r32(SYSC_REG_SYSCFG);
|
||||
+ xtal_mode = (syscfg >> 6) & 0x7;
|
||||
+ printk("%s:%s[%d]\n", __FILE__, __func__, __LINE__);
|
||||
+ if(xtal_mode >= 6) { //25Mhz Xtal
|
||||
+ printk("%s:%s[%d]\n", __FILE__, __func__, __LINE__);
|
||||
+ cpu_clk = 25 * fbdiv * 1000 * 1000;
|
||||
+ } else if(xtal_mode >=3) { //40Mhz Xtal
|
||||
+ printk("%s:%s[%d]\n", __FILE__, __func__, __LINE__);
|
||||
+ cpu_clk = 40 * fbdiv * 1000 * 1000;
|
||||
+ } else { // 20Mhz Xtal
|
||||
+ printk("%s:%s[%d]\n", __FILE__, __func__, __LINE__);
|
||||
+ 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);
|
||||
+}
|
||||
+
|
||||
+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()");
|
||||
+}
|
|
@ -0,0 +1,39 @@
|
|||
From 643e61b22155cd95ae6e18e57da50acd120da091 Mon Sep 17 00:00:00 2001
|
||||
From: John Crispin <blogic@openwrt.org>
|
||||
Date: Mon, 2 Dec 2013 16:11:33 +0100
|
||||
Subject: [PATCH 503/507] MIPS: ralink: add MT7621 early_printk support
|
||||
|
||||
Signed-off-by: John Crispin <blogic@openwrt.org>
|
||||
---
|
||||
arch/mips/ralink/early_printk.c | 10 +++++++---
|
||||
1 file changed, 7 insertions(+), 3 deletions(-)
|
||||
|
||||
Index: linux-3.10.21/arch/mips/ralink/early_printk.c
|
||||
===================================================================
|
||||
--- linux-3.10.21.orig/arch/mips/ralink/early_printk.c 2013-11-29 20:12:03.000000000 +0100
|
||||
+++ linux-3.10.21/arch/mips/ralink/early_printk.c 2013-12-09 20:11:51.600704498 +0100
|
||||
@@ -13,6 +13,8 @@
|
||||
|
||||
#ifdef CONFIG_SOC_RT288X
|
||||
#define EARLY_UART_BASE 0x300c00
|
||||
+#elif defined(CONFIG_SOC_MT7621)
|
||||
+#define EARLY_UART_BASE 0x1E000c00
|
||||
#else
|
||||
#define EARLY_UART_BASE 0x10000c00
|
||||
#endif
|
||||
@@ -40,9 +42,13 @@
|
||||
|
||||
void prom_putchar(unsigned char ch)
|
||||
{
|
||||
- while ((uart_r32(UART_REG_LSR) & UART_LSR_THRE) == 0)
|
||||
+#ifdef CONFIG_SOC_MT7621
|
||||
+ uart_w32(ch, UART_TX);
|
||||
+ while ((uart_r32(0x14) & UART_LSR_THRE) == 0)
|
||||
;
|
||||
- uart_w32(ch, UART_REG_TX);
|
||||
+#else
|
||||
while ((uart_r32(UART_REG_LSR) & UART_LSR_THRE) == 0)
|
||||
;
|
||||
+ uart_w32(ch, UART_REG_TX);
|
||||
+#endif
|
||||
}
|
|
@ -0,0 +1,830 @@
|
|||
From 50216a5b7b3cc269043e7123db4bea262e35364e Mon Sep 17 00:00:00 2001
|
||||
From: John Crispin <blogic@openwrt.org>
|
||||
Date: Mon, 2 Dec 2013 16:13:40 +0100
|
||||
Subject: [PATCH 504/507] MIPS: ralink: add 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 719e455..80886fe 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_RT3883) += pci-rt3883.o
|
||||
+obj-$(CONFIG_SOC_MT7621) += pci-mt7621.o
|
||||
obj-$(CONFIG_TANBAC_TB0219) += fixup-tb0219.o
|
||||
obj-$(CONFIG_TANBAC_TB0226) += fixup-tb0226.o
|
||||
obj-$(CONFIG_TANBAC_TB0287) += fixup-tb0287.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
|
||||
|
|
@ -0,0 +1,235 @@
|
|||
From eb50d97682d78af68388d24956a74de4ab751cf7 Mon Sep 17 00:00:00 2001
|
||||
From: John Crispin <blogic@openwrt.org>
|
||||
Date: Mon, 2 Dec 2013 16:18:36 +0100
|
||||
Subject: [PATCH 505/507] 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
|
||||
|
||||
Index: linux-3.10.21/drivers/watchdog/Kconfig
|
||||
===================================================================
|
||||
--- linux-3.10.21.orig/drivers/watchdog/Kconfig 2013-12-09 19:56:09.360682007 +0100
|
||||
+++ linux-3.10.21/drivers/watchdog/Kconfig 2013-12-09 19:59:20.636686594 +0100
|
||||
@@ -1116,7 +1116,14 @@
|
||||
config RALINK_WDT
|
||||
tristate "Ralink SoC watchdog"
|
||||
select WATCHDOG_CORE
|
||||
- depends on RALINK
|
||||
+ depends on RALINK && !SOC_MT7621
|
||||
+ help
|
||||
+ Hardware driver for the Ralink SoC Watchdog Timer.
|
||||
+
|
||||
+config MT7621_WDT
|
||||
+ tristate "Mediatek SoC watchdog"
|
||||
+ select WATCHDOG_CORE
|
||||
+ depends on RALINK && SOC_MT7621
|
||||
help
|
||||
Hardware driver for the Ralink SoC Watchdog Timer.
|
||||
|
||||
Index: linux-3.10.21/drivers/watchdog/Makefile
|
||||
===================================================================
|
||||
--- linux-3.10.21.orig/drivers/watchdog/Makefile 2013-12-09 19:56:09.360682007 +0100
|
||||
+++ linux-3.10.21/drivers/watchdog/Makefile 2013-12-09 19:56:09.752682016 +0100
|
||||
@@ -136,6 +136,7 @@
|
||||
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
|
||||
|
||||
Index: linux-3.10.21/drivers/watchdog/mt7621_wdt.c
|
||||
===================================================================
|
||||
--- /dev/null 1970-01-01 00:00:00.000000000 +0000
|
||||
+++ linux-3.10.21/drivers/watchdog/mt7621_wdt.c 2013-12-09 19:56:09.752682016 +0100
|
||||
@@ -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);
|
|
@ -0,0 +1,228 @@
|
|||
From e19957560170d63c6a5f0b1d7ba63695e4d1f033 Mon Sep 17 00:00:00 2001
|
||||
From: John Crispin <blogic@openwrt.org>
|
||||
Date: Mon, 2 Dec 2013 16:14:28 +0100
|
||||
Subject: [PATCH 506/507] GPIO: ralink: add mt7621 gpio controller
|
||||
|
||||
Signed-off-by: John Crispin <blogic@openwrt.org>
|
||||
---
|
||||
arch/mips/Kconfig | 1 +
|
||||
drivers/gpio/Kconfig | 6 ++
|
||||
drivers/gpio/Makefile | 1 +
|
||||
drivers/gpio/gpio-mt7621.c | 183 ++++++++++++++++++++++++++++++++++++++++++++
|
||||
4 files changed, 191 insertions(+)
|
||||
create mode 100644 drivers/gpio/gpio-mt7621.c
|
||||
|
||||
Index: linux-3.10.21/drivers/gpio/Kconfig
|
||||
===================================================================
|
||||
--- linux-3.10.21.orig/drivers/gpio/Kconfig 2013-12-09 19:56:09.376682007 +0100
|
||||
+++ linux-3.10.21/drivers/gpio/Kconfig 2013-12-09 19:58:35.372685422 +0100
|
||||
@@ -710,6 +710,12 @@
|
||||
Enable support for GPIO on intel MSIC controllers found in
|
||||
intel MID devices
|
||||
|
||||
+config GPIO_MT7621
|
||||
+ bool "Mediatek GPIO Support"
|
||||
+ depends on RALINK && SOC_MT7621
|
||||
+ help
|
||||
+ Say yes here to support the Mediatek SoC GPIO device
|
||||
+
|
||||
comment "USB GPIO expanders:"
|
||||
|
||||
config GPIO_VIPERBOARD
|
||||
Index: linux-3.10.21/drivers/gpio/Makefile
|
||||
===================================================================
|
||||
--- linux-3.10.21.orig/drivers/gpio/Makefile 2013-12-09 19:56:09.376682007 +0100
|
||||
+++ linux-3.10.21/drivers/gpio/Makefile 2013-12-09 19:56:09.760682017 +0100
|
||||
@@ -88,3 +88,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_MT7621) += gpio-mt7621.o
|
||||
Index: linux-3.10.21/drivers/gpio/gpio-mt7621.c
|
||||
===================================================================
|
||||
--- /dev/null 1970-01-01 00:00:00.000000000 +0000
|
||||
+++ linux-3.10.21/drivers/gpio/gpio-mt7621.c 2013-12-09 19:56:09.760682017 +0100
|
||||
@@ -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.
|
||||
+ *
|
||||
+ * 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;
|
||||
+};
|
||||
+
|
||||
+int
|
||||
+gpio_to_irq(unsigned gpio)
|
||||
+{
|
||||
+ return -1;
|
||||
+}
|
||||
+
|
||||
+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);
|
File diff suppressed because it is too large
Load diff
|
@ -142,6 +142,7 @@ 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
|
||||
|
|
|
@ -150,6 +150,7 @@ 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
|
||||
|
|
Loading…
Reference in a new issue