From deb36359236e3d815aac8c2d062eca87d9cbd639 Mon Sep 17 00:00:00 2001 From: John Crispin Date: Thu, 25 Apr 2013 19:02:42 +0000 Subject: ramips: sync kernel patches with the mips-next tree Signed-off-by: John Crispin SVN-Revision: 36431 --- ...ips_-set-get-_machine_name-to-a-more-gene.patch | 154 + .../0100-MIPS-ralink-fix-RT305x-clock-setup.patch | 47 - .../0101-MIPS-ralink-add-PCI-IRQ-handling.patch | 35 + ...-ralink-add-missing-comment-in-irq-driver.patch | 22 - ...2-MIPS-ralink-add-RT3352-register-defines.patch | 35 + ...-ralink-add-RT5350-sdram-register-defines.patch | 30 - ...PS-ralink-add-RT3352-usb-register-defines.patch | 34 - .../0103-MIPS-ralink-fix-RT305x-clock-setup.patch | 47 + ...-ralink-add-missing-comment-in-irq-driver.patch | 24 + .../0104-MIPS-ralink-add-pinmux-driver.patch | 166 -- .../0105-MIPS-extend-RT3050-dtsi-file.patch | 159 - ...-ralink-add-RT5350-sdram-register-defines.patch | 32 + .../0106-MIPS-add-RT5350-dtsi-file.patch | 198 -- ...S-ralink-make-early_printk-work-on-RT2880.patch | 28 + ...ralink-adds-support-for-RT2880-SoC-family.patch | 266 -- ...link-rename-gpio_pinmux-to-rt_gpio_pinmux.patch | 36 + .../0108-MIPS-add-rt2880-dts-files.patch | 210 -- ...-make-the-RT305x-pinmuxing-structure-stat.patch | 44 + ...ink-add-pci-group-to-struct-ralink_pinmux.patch | 26 + ...ralink-adds-support-for-RT3883-SoC-family.patch | 515 ---- .../0110-MIPS-add-rt3883-dts-files.patch | 282 -- ...ink-add-uart-mask-to-struct-ralink_pinmux.patch | 49 + ...ralink-adds-support-for-MT7620-SoC-family.patch | 340 --- ...ralink-adds-support-for-RT2880-SoC-family.patch | 264 ++ .../0112-MIPS-add-MT7620-dts-files.patch | 204 -- ...ralink-adds-support-for-RT3883-SoC-family.patch | 552 ++++ ...ralink-add-support-for-periodic-timer-irq.patch | 220 -- ...ralink-adds-support-for-MT7620-SoC-family.patch | 351 +++ ...GPIO-MIPS-ralink-adds-ralink-gpio-support.patch | 260 -- ...4-MIPS-ralink-add-cpu-feature-overrides.h.patch | 218 ++ .../0115-DT-add-vendor-prefixes-for-Ralink.patch | 21 + ...0115-SPI-ralink-add-Ralink-SoC-spi-driver.patch | 515 ---- ...dd-documentation-for-the-Ralink-MIPS-SoCs.patch | 38 + ...f-allow-au1x00-and-rt288x-to-load-from-OF.patch | 27 - ...-ralink-clean-up-RT3050-dtsi-and-dts-file.patch | 117 + .../0117-serial-ralink-adds-mt7620-serial.patch | 23 - .../0118-DT-MIPS-ralink-add-RT2880-dts-files.patch | 147 + .../0118-PCI-MIPS-adds-rt2880-pci-support.patch | 319 -- .../0119-DT-MIPS-ralink-add-RT3883-dts-files.patch | 118 + .../0119-PCI-MIPS-adds-rt3883-pci-support.patch | 525 ---- ...0120-DT-MIPS-ralink-add-MT7620A-dts-files.patch | 119 + ...0-NET-MIPS-add-ralink-SoC-ethernet-driver.patch | 3141 -------------------- .../0121-MIPS-add-detect_memory_region.patch | 61 + .../0121-watchdog-adds-ralink-wdt.patch | 395 --- ...-add-memory-definition-to-struct-ralink_s.patch | 29 + ...MIPS-ralink-handle-PCI-interrupts-as-well.patch | 30 - ...S-ralink-add-memory-definition-for-RT305x.patch | 89 + ...23-MIPS-ralink-fix-uartmux-group-handling.patch | 40 - ...S-ralink-add-memory-definition-for-RT2880.patch | 36 + ...ink-add-pci-group-to-struct-ralink_pinmux.patch | 24 - ...S-ralink-add-memory-definition-for-RT3883.patch | 36 + ...0125-MIPS-ralink-process-PCI-pinmux-group.patch | 42 - ...PS-ralink-add-PCI-pinmux-group-for-RT3883.patch | 58 - ...S-ralink-add-memory-definition-for-MT7620.patch | 58 + ...-add-GPIO-mode-to-RT3883-UART-pinmux-grou.patch | 24 - ...-make-use-of-the-new-memory-detection-cod.patch | 40 + ...-add-cpu-feature-overrides.h-for-RT288x-S.patch | 82 - .../0128-MIPS-ralink-add-pinmux-driver.patch | 128 + ...-add-cpu-feature-overrides.h-for-RT3x5x-R.patch | 82 - ...ralink-add-support-for-periodic-timer-irq.patch | 220 ++ ...GPIO-MIPS-ralink-adds-ralink-gpio-support.patch | 260 ++ ...-add-cpu-feature-overrides.h-for-RT3662-3.patch | 81 - .../patches-3.8/0131-MIPS-pci-rt3883-rewrite.patch | 856 ------ ...0131-SPI-ralink-add-Ralink-SoC-spi-driver.patch | 515 ++++ .../0132-NET-ramips-fix-mdio-bus-support.patch | 222 -- ...f-allow-au1x00-and-rt288x-to-load-from-OF.patch | 27 + ...S-ralink-make-early_printk-work-on-RT2880.patch | 26 - .../0133-serial-ralink-adds-mt7620-serial.patch | 23 + .../0134-PCI-MIPS-adds-rt2880-pci-support.patch | 319 ++ .../0135-PCI-MIPS-adds-rt3883-pci-support.patch | 678 +++++ ...6-NET-MIPS-add-ralink-SoC-ethernet-driver.patch | 3137 +++++++++++++++++++ .../0137-watchdog-adds-ralink-wdt.patch | 395 +++ ...he-mips_machine-name-from-OF-and-output-i.patch | 98 - ...owrt-MIPS-ralink-add-usb-platform-support.patch | 8 +- .../0205-owrt-MIPS-add-OWRTDTB-secion.patch | 8 +- ...alink-add-support-for-runtime-memory-dete.patch | 176 -- ...-add-GPIO-mode-to-RT305x-UART-pinmux-grou.patch | 14 - 77 files changed, 8514 insertions(+), 9761 deletions(-) create mode 100644 target/linux/ramips/patches-3.8/0100-MIPS-move-mips_-set-get-_machine_name-to-a-more-gene.patch delete mode 100644 target/linux/ramips/patches-3.8/0100-MIPS-ralink-fix-RT305x-clock-setup.patch create mode 100644 target/linux/ramips/patches-3.8/0101-MIPS-ralink-add-PCI-IRQ-handling.patch delete mode 100644 target/linux/ramips/patches-3.8/0101-MIPS-ralink-add-missing-comment-in-irq-driver.patch create mode 100644 target/linux/ramips/patches-3.8/0102-MIPS-ralink-add-RT3352-register-defines.patch delete mode 100644 target/linux/ramips/patches-3.8/0102-MIPS-ralink-add-RT5350-sdram-register-defines.patch delete mode 100644 target/linux/ramips/patches-3.8/0103-MIPS-ralink-add-RT3352-usb-register-defines.patch create mode 100644 target/linux/ramips/patches-3.8/0103-MIPS-ralink-fix-RT305x-clock-setup.patch create mode 100644 target/linux/ramips/patches-3.8/0104-MIPS-ralink-add-missing-comment-in-irq-driver.patch delete mode 100644 target/linux/ramips/patches-3.8/0104-MIPS-ralink-add-pinmux-driver.patch delete mode 100644 target/linux/ramips/patches-3.8/0105-MIPS-extend-RT3050-dtsi-file.patch create mode 100644 target/linux/ramips/patches-3.8/0105-MIPS-ralink-add-RT5350-sdram-register-defines.patch delete mode 100644 target/linux/ramips/patches-3.8/0106-MIPS-add-RT5350-dtsi-file.patch create mode 100644 target/linux/ramips/patches-3.8/0106-MIPS-ralink-make-early_printk-work-on-RT2880.patch delete mode 100644 target/linux/ramips/patches-3.8/0107-MIPS-ralink-adds-support-for-RT2880-SoC-family.patch create mode 100644 target/linux/ramips/patches-3.8/0107-MIPS-ralink-rename-gpio_pinmux-to-rt_gpio_pinmux.patch delete mode 100644 target/linux/ramips/patches-3.8/0108-MIPS-add-rt2880-dts-files.patch create mode 100644 target/linux/ramips/patches-3.8/0108-MIPS-ralink-make-the-RT305x-pinmuxing-structure-stat.patch create mode 100644 target/linux/ramips/patches-3.8/0109-MIPS-ralink-add-pci-group-to-struct-ralink_pinmux.patch delete mode 100644 target/linux/ramips/patches-3.8/0109-MIPS-ralink-adds-support-for-RT3883-SoC-family.patch delete mode 100644 target/linux/ramips/patches-3.8/0110-MIPS-add-rt3883-dts-files.patch create mode 100644 target/linux/ramips/patches-3.8/0110-MIPS-ralink-add-uart-mask-to-struct-ralink_pinmux.patch delete mode 100644 target/linux/ramips/patches-3.8/0111-MIPS-ralink-adds-support-for-MT7620-SoC-family.patch create mode 100644 target/linux/ramips/patches-3.8/0111-MIPS-ralink-adds-support-for-RT2880-SoC-family.patch delete mode 100644 target/linux/ramips/patches-3.8/0112-MIPS-add-MT7620-dts-files.patch create mode 100644 target/linux/ramips/patches-3.8/0112-MIPS-ralink-adds-support-for-RT3883-SoC-family.patch delete mode 100644 target/linux/ramips/patches-3.8/0113-MIPS-ralink-add-support-for-periodic-timer-irq.patch create mode 100644 target/linux/ramips/patches-3.8/0113-MIPS-ralink-adds-support-for-MT7620-SoC-family.patch delete mode 100644 target/linux/ramips/patches-3.8/0114-GPIO-MIPS-ralink-adds-ralink-gpio-support.patch create mode 100644 target/linux/ramips/patches-3.8/0114-MIPS-ralink-add-cpu-feature-overrides.h.patch create mode 100644 target/linux/ramips/patches-3.8/0115-DT-add-vendor-prefixes-for-Ralink.patch delete mode 100644 target/linux/ramips/patches-3.8/0115-SPI-ralink-add-Ralink-SoC-spi-driver.patch create mode 100644 target/linux/ramips/patches-3.8/0116-DT-add-documentation-for-the-Ralink-MIPS-SoCs.patch delete mode 100644 target/linux/ramips/patches-3.8/0116-serial-of-allow-au1x00-and-rt288x-to-load-from-OF.patch create mode 100644 target/linux/ramips/patches-3.8/0117-DT-MIPS-ralink-clean-up-RT3050-dtsi-and-dts-file.patch delete mode 100644 target/linux/ramips/patches-3.8/0117-serial-ralink-adds-mt7620-serial.patch create mode 100644 target/linux/ramips/patches-3.8/0118-DT-MIPS-ralink-add-RT2880-dts-files.patch delete mode 100644 target/linux/ramips/patches-3.8/0118-PCI-MIPS-adds-rt2880-pci-support.patch create mode 100644 target/linux/ramips/patches-3.8/0119-DT-MIPS-ralink-add-RT3883-dts-files.patch delete mode 100644 target/linux/ramips/patches-3.8/0119-PCI-MIPS-adds-rt3883-pci-support.patch create mode 100644 target/linux/ramips/patches-3.8/0120-DT-MIPS-ralink-add-MT7620A-dts-files.patch delete mode 100644 target/linux/ramips/patches-3.8/0120-NET-MIPS-add-ralink-SoC-ethernet-driver.patch create mode 100644 target/linux/ramips/patches-3.8/0121-MIPS-add-detect_memory_region.patch delete mode 100644 target/linux/ramips/patches-3.8/0121-watchdog-adds-ralink-wdt.patch create mode 100644 target/linux/ramips/patches-3.8/0122-MIPS-ralink-add-memory-definition-to-struct-ralink_s.patch delete mode 100644 target/linux/ramips/patches-3.8/0122-MIPS-ralink-handle-PCI-interrupts-as-well.patch create mode 100644 target/linux/ramips/patches-3.8/0123-MIPS-ralink-add-memory-definition-for-RT305x.patch delete mode 100644 target/linux/ramips/patches-3.8/0123-MIPS-ralink-fix-uartmux-group-handling.patch create mode 100644 target/linux/ramips/patches-3.8/0124-MIPS-ralink-add-memory-definition-for-RT2880.patch delete mode 100644 target/linux/ramips/patches-3.8/0124-MIPS-ralink-add-pci-group-to-struct-ralink_pinmux.patch create mode 100644 target/linux/ramips/patches-3.8/0125-MIPS-ralink-add-memory-definition-for-RT3883.patch delete mode 100644 target/linux/ramips/patches-3.8/0125-MIPS-ralink-process-PCI-pinmux-group.patch delete mode 100644 target/linux/ramips/patches-3.8/0126-MIPS-ralink-add-PCI-pinmux-group-for-RT3883.patch create mode 100644 target/linux/ramips/patches-3.8/0126-MIPS-ralink-add-memory-definition-for-MT7620.patch delete mode 100644 target/linux/ramips/patches-3.8/0127-MIPS-ralink-add-GPIO-mode-to-RT3883-UART-pinmux-grou.patch create mode 100644 target/linux/ramips/patches-3.8/0127-MIPS-ralink-make-use-of-the-new-memory-detection-cod.patch delete mode 100644 target/linux/ramips/patches-3.8/0128-MIPS-ralink-add-cpu-feature-overrides.h-for-RT288x-S.patch create mode 100644 target/linux/ramips/patches-3.8/0128-MIPS-ralink-add-pinmux-driver.patch delete mode 100644 target/linux/ramips/patches-3.8/0129-MIPS-ralink-add-cpu-feature-overrides.h-for-RT3x5x-R.patch create mode 100644 target/linux/ramips/patches-3.8/0129-MIPS-ralink-add-support-for-periodic-timer-irq.patch create mode 100644 target/linux/ramips/patches-3.8/0130-GPIO-MIPS-ralink-adds-ralink-gpio-support.patch delete mode 100644 target/linux/ramips/patches-3.8/0130-MIPS-ralink-add-cpu-feature-overrides.h-for-RT3662-3.patch delete mode 100644 target/linux/ramips/patches-3.8/0131-MIPS-pci-rt3883-rewrite.patch create mode 100644 target/linux/ramips/patches-3.8/0131-SPI-ralink-add-Ralink-SoC-spi-driver.patch delete mode 100644 target/linux/ramips/patches-3.8/0132-NET-ramips-fix-mdio-bus-support.patch create mode 100644 target/linux/ramips/patches-3.8/0132-serial-of-allow-au1x00-and-rt288x-to-load-from-OF.patch delete mode 100644 target/linux/ramips/patches-3.8/0133-MIPS-ralink-make-early_printk-work-on-RT2880.patch create mode 100644 target/linux/ramips/patches-3.8/0133-serial-ralink-adds-mt7620-serial.patch create mode 100644 target/linux/ramips/patches-3.8/0134-PCI-MIPS-adds-rt2880-pci-support.patch create mode 100644 target/linux/ramips/patches-3.8/0135-PCI-MIPS-adds-rt3883-pci-support.patch create mode 100644 target/linux/ramips/patches-3.8/0136-NET-MIPS-add-ralink-SoC-ethernet-driver.patch create mode 100644 target/linux/ramips/patches-3.8/0137-watchdog-adds-ralink-wdt.patch delete mode 100644 target/linux/ramips/patches-3.8/0200-MIPS-read-the-mips_machine-name-from-OF-and-output-i.patch delete mode 100644 target/linux/ramips/patches-3.8/0207-owrt-MIPS-ralink-add-support-for-runtime-memory-dete.patch delete mode 100644 target/linux/ramips/patches-3.8/0212-MIPS-ralink-add-GPIO-mode-to-RT305x-UART-pinmux-grou.patch (limited to 'target/linux/ramips') diff --git a/target/linux/ramips/patches-3.8/0100-MIPS-move-mips_-set-get-_machine_name-to-a-more-gene.patch b/target/linux/ramips/patches-3.8/0100-MIPS-move-mips_-set-get-_machine_name-to-a-more-gene.patch new file mode 100644 index 0000000000..d5fe653c38 --- /dev/null +++ b/target/linux/ramips/patches-3.8/0100-MIPS-move-mips_-set-get-_machine_name-to-a-more-gene.patch @@ -0,0 +1,154 @@ +From dd4bb7e821d112bff981016fd4e7c014ca9425f9 Mon Sep 17 00:00:00 2001 +From: John Crispin +Date: Thu, 11 Apr 2013 05:34:59 +0000 +Subject: [PATCH 100/137] MIPS: move mips_{set,get}_machine_name() to a more + generic place + +Previously this functionality was only available to users of the mips_machine +api. Moving the code to prom.c allows us to also add a OF wrapper. + +Signed-off-by: John Crispin +Patchwork: http://patchwork.linux-mips.org/patch/5164/ +--- + arch/mips/include/asm/mips_machine.h | 4 ---- + arch/mips/include/asm/prom.h | 3 +++ + arch/mips/kernel/mips_machine.c | 21 --------------------- + arch/mips/kernel/proc.c | 2 +- + arch/mips/kernel/prom.c | 31 +++++++++++++++++++++++++++++++ + 5 files changed, 35 insertions(+), 26 deletions(-) + +--- a/arch/mips/include/asm/mips_machine.h ++++ b/arch/mips/include/asm/mips_machine.h +@@ -42,13 +42,9 @@ extern long __mips_machines_end; + #ifdef CONFIG_MIPS_MACHINE + int mips_machtype_setup(char *id) __init; + void mips_machine_setup(void) __init; +-void mips_set_machine_name(const char *name) __init; +-char *mips_get_machine_name(void); + #else + static inline int mips_machtype_setup(char *id) { return 1; } + static inline void mips_machine_setup(void) { } +-static inline void mips_set_machine_name(const char *name) { } +-static inline char *mips_get_machine_name(void) { return NULL; } + #endif /* CONFIG_MIPS_MACHINE */ + + #endif /* __ASM_MIPS_MACHINE_H */ +--- a/arch/mips/include/asm/prom.h ++++ b/arch/mips/include/asm/prom.h +@@ -48,4 +48,7 @@ extern void __dt_setup_arch(struct boot_ + static inline void device_tree_init(void) { } + #endif /* CONFIG_OF */ + ++extern char *mips_get_machine_name(void); ++extern void mips_set_machine_name(const char *name); ++ + #endif /* __ASM_PROM_H */ +--- a/arch/mips/kernel/mips_machine.c ++++ b/arch/mips/kernel/mips_machine.c +@@ -13,7 +13,6 @@ + #include + + static struct mips_machine *mips_machine __initdata; +-static char *mips_machine_name = "Unknown"; + + #define for_each_machine(mach) \ + for ((mach) = (struct mips_machine *)&__mips_machines_start; \ +@@ -21,25 +20,6 @@ static char *mips_machine_name = "Unknow + (unsigned long)(mach) < (unsigned long)&__mips_machines_end; \ + (mach)++) + +-__init void mips_set_machine_name(const char *name) +-{ +- char *p; +- +- if (name == NULL) +- return; +- +- p = kstrdup(name, GFP_KERNEL); +- if (!p) +- pr_err("MIPS: no memory for machine_name\n"); +- +- mips_machine_name = p; +-} +- +-char *mips_get_machine_name(void) +-{ +- return mips_machine_name; +-} +- + __init int mips_machtype_setup(char *id) + { + struct mips_machine *mach; +@@ -79,7 +59,6 @@ __init void mips_machine_setup(void) + return; + + mips_set_machine_name(mips_machine->mach_name); +- pr_info("MIPS: machine is %s\n", mips_machine_name); + + if (mips_machine->mach_setup) + mips_machine->mach_setup(); +--- a/arch/mips/kernel/proc.c ++++ b/arch/mips/kernel/proc.c +@@ -12,7 +12,7 @@ + #include + #include + #include +-#include ++#include + + unsigned int vced_count, vcei_count; + +--- a/arch/mips/kernel/prom.c ++++ b/arch/mips/kernel/prom.c +@@ -23,6 +23,22 @@ + #include + #include + ++static char mips_machine_name[64] = "Unknown"; ++ ++__init void mips_set_machine_name(const char *name) ++{ ++ if (name == NULL) ++ return; ++ ++ strncpy(mips_machine_name, name, sizeof(mips_machine_name)); ++ pr_info("MIPS: machine is %s\n", mips_get_machine_name()); ++} ++ ++char *mips_get_machine_name(void) ++{ ++ return mips_machine_name; ++} ++ + int __init early_init_dt_scan_memory_arch(unsigned long node, + const char *uname, int depth, + void *data) +@@ -50,6 +66,18 @@ void __init early_init_dt_setup_initrd_a + } + #endif + ++int __init early_init_dt_scan_model(unsigned long node, const char *uname, ++ int depth, void *data) ++{ ++ if (!depth) { ++ char *model = of_get_flat_dt_prop(node, "model", NULL); ++ ++ if (model) ++ mips_set_machine_name(model); ++ } ++ return 0; ++} ++ + void __init early_init_devtree(void *params) + { + /* Setup flat device-tree pointer */ +@@ -65,6 +93,9 @@ void __init early_init_devtree(void *par + /* Scan memory nodes */ + of_scan_flat_dt(early_init_dt_scan_root, NULL); + of_scan_flat_dt(early_init_dt_scan_memory_arch, NULL); ++ ++ /* try to load the mips machine name */ ++ of_scan_flat_dt(early_init_dt_scan_model, NULL); + } + + void __init __dt_setup_arch(struct boot_param_header *bph) diff --git a/target/linux/ramips/patches-3.8/0100-MIPS-ralink-fix-RT305x-clock-setup.patch b/target/linux/ramips/patches-3.8/0100-MIPS-ralink-fix-RT305x-clock-setup.patch deleted file mode 100644 index 55b7532310..0000000000 --- a/target/linux/ramips/patches-3.8/0100-MIPS-ralink-fix-RT305x-clock-setup.patch +++ /dev/null @@ -1,47 +0,0 @@ -From eb8d7fbba907df0a51e504930c00b2c9ec837b54 Mon Sep 17 00:00:00 2001 -From: John Crispin -Date: Fri, 22 Mar 2013 19:25:59 +0100 -Subject: [PATCH 100/121] MIPS: ralink: fix RT305x clock setup - -Add a few missing clocks and remove the unused sys clock. - -Signed-off-by: John Crispin ---- - arch/mips/ralink/rt305x.c | 14 ++++++++++++++ - 1 file changed, 14 insertions(+) - ---- a/arch/mips/ralink/rt305x.c -+++ b/arch/mips/ralink/rt305x.c -@@ -125,6 +125,7 @@ void __init ralink_clk_init(void) - { - unsigned long cpu_rate, sys_rate, wdt_rate, uart_rate; - u32 t = rt_sysc_r32(SYSC_REG_SYSTEM_CONFIG); -+ int wmac_20mhz = 0; - - if (soc_is_rt305x() || soc_is_rt3350()) { - t = (t >> RT305X_SYSCFG_CPUCLK_SHIFT) & -@@ -176,11 +177,24 @@ void __init ralink_clk_init(void) - BUG(); - } - -+ if (soc_is_rt3352() || soc_is_rt5350()) { -+ u32 val = rt_sysc_r32(RT3352_SYSC_REG_SYSCFG0); -+ if ((val & RT3352_CLKCFG0_XTAL_SEL) == 0) -+ wmac_20mhz = 1; -+ } -+ - ralink_clk_add("cpu", cpu_rate); - ralink_clk_add("10000b00.spi", sys_rate); - ralink_clk_add("10000100.timer", wdt_rate); -+ ralink_clk_add("10000120.watchdog", wdt_rate); - ralink_clk_add("10000500.uart", uart_rate); - ralink_clk_add("10000c00.uartlite", uart_rate); -+ ralink_clk_add("10100000.ethernet", sys_rate); -+ -+ if (wmac_20mhz) -+ ralink_clk_add("10180000.wmac", 20000000); -+ else -+ ralink_clk_add("10180000.wmac", 40000000); - } - - void __init ralink_of_remap(void) diff --git a/target/linux/ramips/patches-3.8/0101-MIPS-ralink-add-PCI-IRQ-handling.patch b/target/linux/ramips/patches-3.8/0101-MIPS-ralink-add-PCI-IRQ-handling.patch new file mode 100644 index 0000000000..bdb5cfc574 --- /dev/null +++ b/target/linux/ramips/patches-3.8/0101-MIPS-ralink-add-PCI-IRQ-handling.patch @@ -0,0 +1,35 @@ +From 16d9eaf22f30ed0b0deddfe8e11426889ccdb556 Mon Sep 17 00:00:00 2001 +From: Gabor Juhos +Date: Wed, 10 Apr 2013 09:07:27 +0200 +Subject: [PATCH 101/137] MIPS: ralink: add PCI IRQ handling + +The Ralink IRQ code was not handling the PCI IRQ yet. Add this functionaility +to make PCI work on rt3883. + +Signed-off-by: John Crispin +Signed-off-by: Gabor Juhos +Patchwork: http://patchwork.linux-mips.org/patch/5165/ +--- + arch/mips/ralink/irq.c | 4 ++++ + 1 file changed, 4 insertions(+) + +--- a/arch/mips/ralink/irq.c ++++ b/arch/mips/ralink/irq.c +@@ -31,6 +31,7 @@ + #define INTC_INT_GLOBAL BIT(31) + + #define RALINK_CPU_IRQ_INTC (MIPS_CPU_IRQ_BASE + 2) ++#define RALINK_CPU_IRQ_PCI (MIPS_CPU_IRQ_BASE + 4) + #define RALINK_CPU_IRQ_FE (MIPS_CPU_IRQ_BASE + 5) + #define RALINK_CPU_IRQ_WIFI (MIPS_CPU_IRQ_BASE + 6) + #define RALINK_CPU_IRQ_COUNTER (MIPS_CPU_IRQ_BASE + 7) +@@ -104,6 +105,9 @@ asmlinkage void plat_irq_dispatch(void) + else if (pending & STATUSF_IP6) + do_IRQ(RALINK_CPU_IRQ_WIFI); + ++ else if (pending & STATUSF_IP4) ++ do_IRQ(RALINK_CPU_IRQ_PCI); ++ + else if (pending & STATUSF_IP2) + do_IRQ(RALINK_CPU_IRQ_INTC); + diff --git a/target/linux/ramips/patches-3.8/0101-MIPS-ralink-add-missing-comment-in-irq-driver.patch b/target/linux/ramips/patches-3.8/0101-MIPS-ralink-add-missing-comment-in-irq-driver.patch deleted file mode 100644 index 81ae16e90b..0000000000 --- a/target/linux/ramips/patches-3.8/0101-MIPS-ralink-add-missing-comment-in-irq-driver.patch +++ /dev/null @@ -1,22 +0,0 @@ -From 68dba842ed23c9688340444b44951c448f4ff9ba Mon Sep 17 00:00:00 2001 -From: John Crispin -Date: Sat, 16 Mar 2013 16:28:54 +0100 -Subject: [PATCH 101/121] MIPS: ralink: add missing comment in irq driver - -Trivial patch that adds a comment that makes the code more readable. - -Signed-off-by: John Crispin ---- - arch/mips/ralink/irq.c | 1 + - 1 file changed, 1 insertion(+) - ---- a/arch/mips/ralink/irq.c -+++ b/arch/mips/ralink/irq.c -@@ -162,6 +162,7 @@ static int __init intc_of_init(struct de - irq_set_chained_handler(irq, ralink_intc_irq_handler); - irq_set_handler_data(irq, domain); - -+ /* tell the kernel which irq is used for performance monitoring */ - cp0_perfcount_irq = irq_create_mapping(domain, 9); - - return 0; diff --git a/target/linux/ramips/patches-3.8/0102-MIPS-ralink-add-RT3352-register-defines.patch b/target/linux/ramips/patches-3.8/0102-MIPS-ralink-add-RT3352-register-defines.patch new file mode 100644 index 0000000000..2d296db665 --- /dev/null +++ b/target/linux/ramips/patches-3.8/0102-MIPS-ralink-add-RT3352-register-defines.patch @@ -0,0 +1,35 @@ +From e6bcdad6f0811daedc2a448f5d7fb98c116a5241 Mon Sep 17 00:00:00 2001 +From: John Crispin +Date: Thu, 21 Mar 2013 19:01:49 +0100 +Subject: [PATCH 102/137] MIPS: ralink: add RT3352 register defines + +Add a few missing defines that are needed to make USB and clock detection work +on the RT3352. + +Signed-off-by: John Crispin +Acked-by: Gabor Juhos +Patchwork: http://patchwork.linux-mips.org/patch/5166/ +--- + arch/mips/include/asm/mach-ralink/rt305x.h | 13 +++++++++++++ + 1 file changed, 13 insertions(+) + +--- a/arch/mips/include/asm/mach-ralink/rt305x.h ++++ b/arch/mips/include/asm/mach-ralink/rt305x.h +@@ -136,4 +136,17 @@ static inline int soc_is_rt5350(void) + #define RT305X_GPIO_MODE_SDRAM BIT(8) + #define RT305X_GPIO_MODE_RGMII BIT(9) + ++#define RT3352_SYSC_REG_SYSCFG0 0x010 ++#define RT3352_SYSC_REG_SYSCFG1 0x014 ++#define RT3352_SYSC_REG_CLKCFG1 0x030 ++#define RT3352_SYSC_REG_RSTCTRL 0x034 ++#define RT3352_SYSC_REG_USB_PS 0x05c ++ ++#define RT3352_CLKCFG0_XTAL_SEL BIT(20) ++#define RT3352_CLKCFG1_UPHY0_CLK_EN BIT(18) ++#define RT3352_CLKCFG1_UPHY1_CLK_EN BIT(20) ++#define RT3352_RSTCTRL_UHST BIT(22) ++#define RT3352_RSTCTRL_UDEV BIT(25) ++#define RT3352_SYSCFG1_USB0_HOST_MODE BIT(10) ++ + #endif diff --git a/target/linux/ramips/patches-3.8/0102-MIPS-ralink-add-RT5350-sdram-register-defines.patch b/target/linux/ramips/patches-3.8/0102-MIPS-ralink-add-RT5350-sdram-register-defines.patch deleted file mode 100644 index c4bf63aae2..0000000000 --- a/target/linux/ramips/patches-3.8/0102-MIPS-ralink-add-RT5350-sdram-register-defines.patch +++ /dev/null @@ -1,30 +0,0 @@ -From ac2614707be7ddceb0f0b623d55d200f28695d5f Mon Sep 17 00:00:00 2001 -From: John Crispin -Date: Mon, 25 Mar 2013 11:19:58 +0100 -Subject: [PATCH 102/121] MIPS: ralink: add RT5350 sdram register defines - -Add a few missing defines that are needed to make memory detection work on the -RT5350. - -Signed-off-by: John Crispin ---- - arch/mips/include/asm/mach-ralink/rt305x.h | 8 ++++++++ - 1 file changed, 8 insertions(+) - ---- a/arch/mips/include/asm/mach-ralink/rt305x.h -+++ b/arch/mips/include/asm/mach-ralink/rt305x.h -@@ -97,6 +97,14 @@ static inline int soc_is_rt5350(void) - #define RT5350_SYSCFG0_CPUCLK_320 0x2 - #define RT5350_SYSCFG0_CPUCLK_300 0x3 - -+#define RT5350_SYSCFG0_DRAM_SIZE_SHIFT 12 -+#define RT5350_SYSCFG0_DRAM_SIZE_MASK 7 -+#define RT5350_SYSCFG0_DRAM_SIZE_2M 0 -+#define RT5350_SYSCFG0_DRAM_SIZE_8M 1 -+#define RT5350_SYSCFG0_DRAM_SIZE_16M 2 -+#define RT5350_SYSCFG0_DRAM_SIZE_32M 3 -+#define RT5350_SYSCFG0_DRAM_SIZE_64M 4 -+ - /* multi function gpio pins */ - #define RT305X_GPIO_I2C_SD 1 - #define RT305X_GPIO_I2C_SCLK 2 diff --git a/target/linux/ramips/patches-3.8/0103-MIPS-ralink-add-RT3352-usb-register-defines.patch b/target/linux/ramips/patches-3.8/0103-MIPS-ralink-add-RT3352-usb-register-defines.patch deleted file mode 100644 index d99781bf7d..0000000000 --- a/target/linux/ramips/patches-3.8/0103-MIPS-ralink-add-RT3352-usb-register-defines.patch +++ /dev/null @@ -1,34 +0,0 @@ -From 5157985fbc0f071276b0c3381ac8ed191878358a Mon Sep 17 00:00:00 2001 -From: John Crispin -Date: Thu, 21 Mar 2013 19:01:49 +0100 -Subject: [PATCH 103/121] MIPS: ralink: add RT3352 usb register defines - -Add a few missing defines that are needed to make USB work on the RT3352 -and RT5350. - -Signed-off-by: John Crispin ---- - arch/mips/include/asm/mach-ralink/rt305x.h | 11 +++++++++++ - 1 file changed, 11 insertions(+) - ---- a/arch/mips/include/asm/mach-ralink/rt305x.h -+++ b/arch/mips/include/asm/mach-ralink/rt305x.h -@@ -144,4 +144,18 @@ static inline int soc_is_rt5350(void) - #define RT305X_GPIO_MODE_SDRAM BIT(8) - #define RT305X_GPIO_MODE_RGMII BIT(9) - -+#define RT3352_SYSC_REG_SYSCFG1 0x014 -+#define RT3352_SYSC_REG_CLKCFG1 0x030 -+#define RT3352_SYSC_REG_RSTCTRL 0x034 -+#define RT3352_SYSC_REG_USB_PS 0x05c -+ -+#define RT3352_CLKCFG1_UPHY0_CLK_EN BIT(18) -+#define RT3352_CLKCFG1_UPHY1_CLK_EN BIT(20) -+#define RT3352_RSTCTRL_UHST BIT(22) -+#define RT3352_RSTCTRL_UDEV BIT(25) -+#define RT3352_SYSCFG1_USB0_HOST_MODE BIT(10) -+ -+#define RT3352_SYSC_REG_SYSCFG0 0x010 -+#define RT3352_CLKCFG0_XTAL_SEL BIT(20) -+ - #endif diff --git a/target/linux/ramips/patches-3.8/0103-MIPS-ralink-fix-RT305x-clock-setup.patch b/target/linux/ramips/patches-3.8/0103-MIPS-ralink-fix-RT305x-clock-setup.patch new file mode 100644 index 0000000000..7d682e75bd --- /dev/null +++ b/target/linux/ramips/patches-3.8/0103-MIPS-ralink-fix-RT305x-clock-setup.patch @@ -0,0 +1,47 @@ +From 845f786c561c0991d9b4088a2d77b8fd4831d487 Mon Sep 17 00:00:00 2001 +From: John Crispin +Date: Fri, 22 Mar 2013 19:25:59 +0100 +Subject: [PATCH 103/137] MIPS: ralink: fix RT305x clock setup + +Add a few missing clocks. + +Signed-off-by: John Crispin +Acked-by: Gabor Juhos +Patchwork: http://patchwork.linux-mips.org/patch/5167/ +--- + arch/mips/ralink/rt305x.c | 12 ++++++++++++ + 1 file changed, 12 insertions(+) + +--- a/arch/mips/ralink/rt305x.c ++++ b/arch/mips/ralink/rt305x.c +@@ -124,6 +124,8 @@ struct ralink_pinmux gpio_pinmux = { + void __init ralink_clk_init(void) + { + unsigned long cpu_rate, sys_rate, wdt_rate, uart_rate; ++ unsigned long wmac_rate = 40000000; ++ + u32 t = rt_sysc_r32(SYSC_REG_SYSTEM_CONFIG); + + if (soc_is_rt305x() || soc_is_rt3350()) { +@@ -176,11 +178,21 @@ void __init ralink_clk_init(void) + BUG(); + } + ++ if (soc_is_rt3352() || soc_is_rt5350()) { ++ u32 val = rt_sysc_r32(RT3352_SYSC_REG_SYSCFG0); ++ ++ if (!(val & RT3352_CLKCFG0_XTAL_SEL)) ++ wmac_rate = 20000000; ++ } ++ + ralink_clk_add("cpu", cpu_rate); + ralink_clk_add("10000b00.spi", sys_rate); + ralink_clk_add("10000100.timer", wdt_rate); ++ ralink_clk_add("10000120.watchdog", wdt_rate); + ralink_clk_add("10000500.uart", uart_rate); + ralink_clk_add("10000c00.uartlite", uart_rate); ++ ralink_clk_add("10100000.ethernet", sys_rate); ++ ralink_clk_add("10180000.wmac", wmac_rate); + } + + void __init ralink_of_remap(void) diff --git a/target/linux/ramips/patches-3.8/0104-MIPS-ralink-add-missing-comment-in-irq-driver.patch b/target/linux/ramips/patches-3.8/0104-MIPS-ralink-add-missing-comment-in-irq-driver.patch new file mode 100644 index 0000000000..3218384973 --- /dev/null +++ b/target/linux/ramips/patches-3.8/0104-MIPS-ralink-add-missing-comment-in-irq-driver.patch @@ -0,0 +1,24 @@ +From 2747613b1bba0d4497ed2c4a77e2011d02029153 Mon Sep 17 00:00:00 2001 +From: John Crispin +Date: Sat, 16 Mar 2013 16:28:54 +0100 +Subject: [PATCH 104/137] MIPS: ralink: add missing comment in irq driver + +Trivial patch that adds a comment that makes the code more readable. + +Signed-off-by: John Crispin +Acked-by: Gabor Juhos +Patchwork: http://patchwork.linux-mips.org/patch/5168/ +--- + arch/mips/ralink/irq.c | 1 + + 1 file changed, 1 insertion(+) + +--- a/arch/mips/ralink/irq.c ++++ b/arch/mips/ralink/irq.c +@@ -166,6 +166,7 @@ static int __init intc_of_init(struct de + irq_set_chained_handler(irq, ralink_intc_irq_handler); + irq_set_handler_data(irq, domain); + ++ /* tell the kernel which irq is used for performance monitoring */ + cp0_perfcount_irq = irq_create_mapping(domain, 9); + + return 0; diff --git a/target/linux/ramips/patches-3.8/0104-MIPS-ralink-add-pinmux-driver.patch b/target/linux/ramips/patches-3.8/0104-MIPS-ralink-add-pinmux-driver.patch deleted file mode 100644 index 374894793f..0000000000 --- a/target/linux/ramips/patches-3.8/0104-MIPS-ralink-add-pinmux-driver.patch +++ /dev/null @@ -1,166 +0,0 @@ -From 806a489c720767f63bf5046c2ccd87ded9549c1c Mon Sep 17 00:00:00 2001 -From: John Crispin -Date: Sat, 16 Mar 2013 00:50:57 +0100 -Subject: [PATCH 104/121] MIPS: ralink: add pinmux driver - -Add code to setup the pinmux on ralonk SoC. The SoC has a single 32 bit register -for this functionality with simple on/off bits. Building a full featured pinctrl -driver would be overkill. - -Signed-off-by: John Crispin ---- - arch/mips/ralink/Makefile | 2 +- - arch/mips/ralink/common.h | 5 ++- - arch/mips/ralink/of.c | 2 ++ - arch/mips/ralink/pinmux.c | 76 +++++++++++++++++++++++++++++++++++++++++++++ - arch/mips/ralink/rt305x.c | 6 ++-- - 5 files changed, 85 insertions(+), 6 deletions(-) - create mode 100644 arch/mips/ralink/pinmux.c - ---- a/arch/mips/ralink/Makefile -+++ b/arch/mips/ralink/Makefile -@@ -6,7 +6,7 @@ - # Copyright (C) 2009-2011 Gabor Juhos - # Copyright (C) 2013 John Crispin - --obj-y := prom.o of.o reset.o clk.o irq.o -+obj-y := prom.o of.o reset.o clk.o irq.o pinmux.o - - obj-$(CONFIG_SOC_RT305X) += rt305x.o - ---- a/arch/mips/ralink/common.h -+++ b/arch/mips/ralink/common.h -@@ -22,9 +22,10 @@ struct ralink_pinmux { - struct ralink_pinmux_grp *mode; - struct ralink_pinmux_grp *uart; - int uart_shift; -+ u32 uart_mask; - void (*wdt_reset)(void); - }; --extern struct ralink_pinmux gpio_pinmux; -+extern struct ralink_pinmux rt_pinmux; - - struct ralink_soc_info { - unsigned char sys_type[RAMIPS_SYS_TYPE_LEN]; -@@ -41,4 +42,6 @@ extern void prom_soc_init(struct ralink_ - - __iomem void *plat_of_remap_node(const char *node); - -+void ralink_pinmux(void); -+ - #endif /* _RALINK_COMMON_H__ */ ---- a/arch/mips/ralink/of.c -+++ b/arch/mips/ralink/of.c -@@ -101,6 +101,8 @@ static int __init plat_of_setup(void) - if (of_platform_populate(NULL, of_ids, NULL, NULL)) - panic("failed to populate DT\n"); - -+ ralink_pinmux(); -+ - return 0; - } - ---- /dev/null -+++ b/arch/mips/ralink/pinmux.c -@@ -0,0 +1,76 @@ -+/* -+ * This program is free software; you can redistribute it and/or modify it -+ * under the terms of the GNU General Public License version 2 as published -+ * by the Free Software Foundation. -+ * -+ * Copyright (C) 2013 John Crispin -+ */ -+ -+#include -+#include -+ -+#include -+ -+#include "common.h" -+ -+#define SYSC_REG_GPIO_MODE 0x60 -+ -+static u32 ralink_mux_mask(const char *name, struct ralink_pinmux_grp *grps) -+{ -+ for (; grps->name; grps++) -+ if (!strcmp(grps->name, name)) -+ return grps->mask; -+ -+ return 0; -+} -+ -+void ralink_pinmux(void) -+{ -+ const __be32 *wdt; -+ struct device_node *np; -+ struct property *prop; -+ const char *uart, *pin; -+ u32 mode = 0; -+ -+ np = of_find_compatible_node(NULL, NULL, "ralink,rt3050-sysc"); -+ if (!np) -+ return; -+ -+ of_property_for_each_string(np, "ralink,gpiomux", prop, pin) { -+ int m = ralink_mux_mask(pin, rt_pinmux.mode); -+ if (m) { -+ mode |= m; -+ pr_debug("pinmux: registered gpiomux \"%s\"\n", pin); -+ } else { -+ pr_err("pinmux: failed to load \"%s\"\n", pin); -+ } -+ } -+ -+ of_property_for_each_string(np, "ralink,pinmux", prop, pin) { -+ int m = ralink_mux_mask(pin, rt_pinmux.mode); -+ if (m) { -+ mode &= ~m; -+ pr_debug("pinmux: registered pinmux \"%s\"\n", pin); -+ } else { -+ pr_err("pinmux: failed to load group \"%s\"\n", pin); -+ } -+ } -+ -+ of_property_read_string(np, "ralink,uartmux", &uart); -+ if (uart) { -+ int m = ralink_mux_mask(uart, rt_pinmux.uart); -+ mode |= rt_pinmux.uart_mask << rt_pinmux.uart_shift; -+ if (m) { -+ mode &= ~(m << rt_pinmux.uart_shift); -+ pr_debug("pinmux: registered uartmux \"%s\"\n", uart); -+ } else { -+ pr_debug("pinmux: registered uartmux \"gpio\"\n"); -+ } -+ } -+ -+ wdt = of_get_property(np, "ralink,wdtmux", NULL); -+ if (wdt && *wdt && rt_pinmux.wdt_reset) -+ rt_pinmux.wdt_reset(); -+ -+ rt_sysc_w32(mode, SYSC_REG_GPIO_MODE); -+} ---- a/arch/mips/ralink/rt305x.c -+++ b/arch/mips/ralink/rt305x.c -@@ -97,9 +97,6 @@ struct ralink_pinmux_grp uart_mux[] = { - .mask = RT305X_GPIO_MODE_GPIO_I2S, - .gpio_first = RT305X_GPIO_7, - .gpio_last = RT305X_GPIO_14, -- }, { -- .name = "gpio", -- .mask = RT305X_GPIO_MODE_GPIO, - }, {0} - }; - -@@ -114,10 +111,11 @@ void rt305x_wdt_reset(void) - rt_sysc_w32(t, SYSC_REG_SYSTEM_CONFIG); - } - --struct ralink_pinmux gpio_pinmux = { -+struct ralink_pinmux rt_pinmux = { - .mode = mode_mux, - .uart = uart_mux, - .uart_shift = RT305X_GPIO_MODE_UART0_SHIFT, -+ .uart_mask = RT305X_GPIO_MODE_GPIO, - .wdt_reset = rt305x_wdt_reset, - }; - diff --git a/target/linux/ramips/patches-3.8/0105-MIPS-extend-RT3050-dtsi-file.patch b/target/linux/ramips/patches-3.8/0105-MIPS-extend-RT3050-dtsi-file.patch deleted file mode 100644 index 01aa70ba50..0000000000 --- a/target/linux/ramips/patches-3.8/0105-MIPS-extend-RT3050-dtsi-file.patch +++ /dev/null @@ -1,159 +0,0 @@ -From 45e797ec7555c50775d9ac7fc7a17a544344aa3f Mon Sep 17 00:00:00 2001 -From: John Crispin -Date: Thu, 21 Mar 2013 17:47:07 +0100 -Subject: [PATCH 105/121] MIPS: extend RT3050 dtsi file - -Add some additional properties to the dtsi file for ethernet and wifi. - -Signed-off-by: John Crispin ---- - arch/mips/ralink/dts/rt3050.dtsi | 96 ++++++++++++++++++++++++++++++++------ - 1 file changed, 81 insertions(+), 15 deletions(-) - ---- a/arch/mips/ralink/dts/rt3050.dtsi -+++ b/arch/mips/ralink/dts/rt3050.dtsi -@@ -1,7 +1,7 @@ - / { - #address-cells = <1>; - #size-cells = <1>; -- compatible = "ralink,rt3050-soc", "ralink,rt3052-soc"; -+ compatible = "ralink,rt3050-soc", "ralink,rt3052-soc", "ralink,rt3350-soc"; - - cpus { - cpu@0 { -@@ -23,7 +23,7 @@ - palmbus@10000000 { - compatible = "palmbus"; - reg = <0x10000000 0x200000>; -- ranges = <0x0 0x10000000 0x1FFFFF>; -+ ranges = <0x0 0x10000000 0x1FFFFF>; - - #address-cells = <1>; - #size-cells = <1>; -@@ -34,8 +34,18 @@ - }; - - timer@100 { -+ compatible = "ralink,rt3052-timer", "ralink,rt2880-timer"; -+ reg = <0x100 0x20>; -+ -+ interrupt-parent = <&intc>; -+ interrupts = <1>; -+ -+ status = "disabled"; -+ }; -+ -+ watchdog@120 { - compatible = "ralink,rt3052-wdt", "ralink,rt2880-wdt"; -- reg = <0x100 0x100>; -+ reg = <0x120 0x10>; - }; - - intc: intc@200 { -@@ -61,10 +71,12 @@ - gpio-controller; - #gpio-cells = <2>; - -- ralink,ngpio = <24>; -- ralink,regs = [ 00 04 08 0c -- 20 24 28 2c -- 30 34 ]; -+ ralink,num-gpios = <24>; -+ ralink,register-map = [ 00 04 08 0c -+ 20 24 28 2c -+ 30 34 ]; -+ -+ status = "disabled"; - }; - - gpio1: gpio@638 { -@@ -74,10 +86,12 @@ - gpio-controller; - #gpio-cells = <2>; - -- ralink,ngpio = <16>; -- ralink,regs = [ 00 04 08 0c -- 10 14 18 1c -- 20 24 ]; -+ ralink,num-gpios = <16>; -+ ralink,register-map = [ 00 04 08 0c -+ 10 14 18 1c -+ 20 24 ]; -+ -+ status = "disabled"; - }; - - gpio2: gpio@660 { -@@ -87,10 +101,21 @@ - gpio-controller; - #gpio-cells = <2>; - -- ralink,ngpio = <12>; -- ralink,regs = [ 00 04 08 0c -- 10 14 18 1c -- 20 24 ]; -+ ralink,num-gpios = <12>; -+ ralink,register-map = [ 00 04 08 0c -+ 10 14 18 1c -+ 20 24 ]; -+ -+ status = "disabled"; -+ }; -+ -+ spi@b00 { -+ compatible = "ralink,rt3050-spi", "ralink,rt2880-spi"; -+ reg = <0xb00 0x100>; -+ #address-cells = <1>; -+ #size-cells = <0>; -+ -+ status = "disabled"; - }; - - uartlite@c00 { -@@ -102,5 +127,46 @@ - - reg-shift = <2>; - }; -+ -+ }; -+ -+ ethernet@10100000 { -+ compatible = "ralink,rt3050-eth"; -+ reg = <0x10100000 10000>; -+ -+ interrupt-parent = <&cpuintc>; -+ interrupts = <5>; -+ -+ status = "disabled"; -+ }; -+ -+ esw@10110000 { -+ compatible = "ralink,rt3050-esw"; -+ reg = <0x10110000 8000>; -+ -+ interrupt-parent = <&intc>; -+ interrupts = <17>; -+ -+ status = "disabled"; -+ }; -+ -+ wmac@10180000 { -+ compatible = "ralink,rt3050-wmac", "ralink,rt2880-wmac"; -+ reg = <0x10180000 40000>; -+ -+ interrupt-parent = <&cpuintc>; -+ interrupts = <6>; -+ -+ status = "disabled"; -+ }; -+ -+ otg@101c0000 { -+ compatible = "ralink,rt3050-otg"; -+ reg = <0x101c0000 40000>; -+ -+ interrupt-parent = <&intc>; -+ interrupts = <18>; -+ -+ status = "disabled"; - }; - }; diff --git a/target/linux/ramips/patches-3.8/0105-MIPS-ralink-add-RT5350-sdram-register-defines.patch b/target/linux/ramips/patches-3.8/0105-MIPS-ralink-add-RT5350-sdram-register-defines.patch new file mode 100644 index 0000000000..ccabcbd64b --- /dev/null +++ b/target/linux/ramips/patches-3.8/0105-MIPS-ralink-add-RT5350-sdram-register-defines.patch @@ -0,0 +1,32 @@ +From 31f4b3ca1c9bb4bcbbebbe5db5a33ac82f130d9c Mon Sep 17 00:00:00 2001 +From: John Crispin +Date: Mon, 25 Mar 2013 11:19:58 +0100 +Subject: [PATCH 105/137] MIPS: ralink: add RT5350 sdram register defines + +Add a few missing defines that are needed to make memory detection work on the +RT5350. + +Signed-off-by: John Crispin +Acked-by: Gabor Juhos +Patchwork: http://patchwork.linux-mips.org/patch/5169/ +--- + arch/mips/include/asm/mach-ralink/rt305x.h | 8 ++++++++ + 1 file changed, 8 insertions(+) + +--- a/arch/mips/include/asm/mach-ralink/rt305x.h ++++ b/arch/mips/include/asm/mach-ralink/rt305x.h +@@ -97,6 +97,14 @@ static inline int soc_is_rt5350(void) + #define RT5350_SYSCFG0_CPUCLK_320 0x2 + #define RT5350_SYSCFG0_CPUCLK_300 0x3 + ++#define RT5350_SYSCFG0_DRAM_SIZE_SHIFT 12 ++#define RT5350_SYSCFG0_DRAM_SIZE_MASK 7 ++#define RT5350_SYSCFG0_DRAM_SIZE_2M 0 ++#define RT5350_SYSCFG0_DRAM_SIZE_8M 1 ++#define RT5350_SYSCFG0_DRAM_SIZE_16M 2 ++#define RT5350_SYSCFG0_DRAM_SIZE_32M 3 ++#define RT5350_SYSCFG0_DRAM_SIZE_64M 4 ++ + /* multi function gpio pins */ + #define RT305X_GPIO_I2C_SD 1 + #define RT305X_GPIO_I2C_SCLK 2 diff --git a/target/linux/ramips/patches-3.8/0106-MIPS-add-RT5350-dtsi-file.patch b/target/linux/ramips/patches-3.8/0106-MIPS-add-RT5350-dtsi-file.patch deleted file mode 100644 index ee3c851a42..0000000000 --- a/target/linux/ramips/patches-3.8/0106-MIPS-add-RT5350-dtsi-file.patch +++ /dev/null @@ -1,198 +0,0 @@ -From 1238d973f3828a65ccf9aead437b4e04925b100e Mon Sep 17 00:00:00 2001 -From: John Crispin -Date: Thu, 21 Mar 2013 17:47:24 +0100 -Subject: [PATCH 106/121] MIPS: add RT5350 dtsi file - -Add a dtsi file for RT5350 Soc. This SoC is almost the same as RT3050 but has -OHCI/EHCI in favour of the Synopsis DWC2 core. - -Signed-off-by: John Crispin ---- - arch/mips/ralink/dts/rt5350.dtsi | 181 ++++++++++++++++++++++++++++++++++++++ - 1 file changed, 181 insertions(+) - create mode 100644 arch/mips/ralink/dts/rt5350.dtsi - ---- /dev/null -+++ b/arch/mips/ralink/dts/rt5350.dtsi -@@ -0,0 +1,181 @@ -+/ { -+ #address-cells = <1>; -+ #size-cells = <1>; -+ compatible = "ralink,rt5350-soc"; -+ -+ cpus { -+ cpu@0 { -+ compatible = "mips,mips24KEc"; -+ }; -+ }; -+ -+ chosen { -+ bootargs = "console=ttyS0,57600 init=/init"; -+ }; -+ -+ cpuintc: cpuintc@0 { -+ #address-cells = <0>; -+ #interrupt-cells = <1>; -+ interrupt-controller; -+ compatible = "mti,cpu-interrupt-controller"; -+ }; -+ -+ palmbus@10000000 { -+ compatible = "palmbus"; -+ reg = <0x10000000 0x200000>; -+ ranges = <0x0 0x10000000 0x1FFFFF>; -+ -+ #address-cells = <1>; -+ #size-cells = <1>; -+ -+ sysc@0 { -+ compatible = "ralink,rt5350-sysc", "ralink,rt3050-sysc"; -+ reg = <0x0 0x100>; -+ }; -+ -+ timer@100 { -+ compatible = "ralink,rt5350-timer", "ralink,rt2880-timer"; -+ reg = <0x100 0x20>; -+ -+ interrupt-parent = <&intc>; -+ interrupts = <1>; -+ -+ status = "disabled"; -+ }; -+ -+ watchdog@120 { -+ compatible = "ralink,rt5350-wdt", "ralink,rt2880-wdt"; -+ reg = <0x120 0x10>; -+ }; -+ -+ intc: intc@200 { -+ compatible = "ralink,rt5350-intc", "ralink,rt2880-intc"; -+ reg = <0x200 0x100>; -+ -+ interrupt-controller; -+ #interrupt-cells = <1>; -+ -+ interrupt-parent = <&cpuintc>; -+ interrupts = <2>; -+ }; -+ -+ memc@300 { -+ compatible = "ralink,rt5350-memc", "ralink,rt3050-memc"; -+ reg = <0x300 0x100>; -+ }; -+ -+ gpio0: gpio@600 { -+ compatible = "ralink,rt5350-gpio", "ralink,rt2880-gpio"; -+ reg = <0x600 0x34>; -+ -+ gpio-controller; -+ #gpio-cells = <2>; -+ -+ ralink,num-gpios = <24>; -+ ralink,register-map = [ 00 04 08 0c -+ 20 24 28 2c -+ 30 34 ]; -+ -+ status = "disabled"; -+ }; -+ -+ gpio1: gpio@638 { -+ compatible = "ralink,rt5350-gpio", "ralink,rt2880-gpio"; -+ reg = <0x638 0x24>; -+ -+ gpio-controller; -+ #gpio-cells = <2>; -+ -+ ralink,num-gpios = <16>; -+ ralink,register-map = [ 00 04 08 0c -+ 10 14 18 1c -+ 20 24 ]; -+ -+ status = "disabled"; -+ }; -+ -+ gpio2: gpio@660 { -+ compatible = "ralink,rt5350-gpio", "ralink,rt2880-gpio"; -+ reg = <0x660 0x24>; -+ -+ gpio-controller; -+ #gpio-cells = <2>; -+ -+ ralink,num-gpios = <12>; -+ ralink,register-map = [ 00 04 08 0c -+ 10 14 18 1c -+ 20 24 ]; -+ -+ status = "disabled"; -+ }; -+ -+ spi@b00 { -+ compatible = "ralink,rt5350-spi", "ralink,rt2880-spi"; -+ reg = <0xb00 0x100>; -+ #address-cells = <1>; -+ #size-cells = <1>; -+ -+ status = "disabled"; -+ }; -+ -+ uartlite@c00 { -+ compatible = "ralink,rt5350-uart", "ralink,rt2880-uart", "ns16550a"; -+ reg = <0xc00 0x100>; -+ -+ interrupt-parent = <&intc>; -+ interrupts = <12>; -+ -+ reg-shift = <2>; -+ }; -+ }; -+ -+ ethernet@10100000 { -+ compatible = "ralink,rt5350-eth", "ralink,rt3050-eth"; -+ reg = <0x10100000 10000>; -+ -+ interrupt-parent = <&cpuintc>; -+ interrupts = <5>; -+ -+ status = "disabled"; -+ }; -+ -+ esw@10110000 { -+ compatible = "ralink,rt5350-esw", "ralink,rt3050-esw"; -+ reg = <0x10110000 8000>; -+ -+ interrupt-parent = <&intc>; -+ interrupts = <17>; -+ -+ status = "disabled"; -+ }; -+ -+ wmac@10180000 { -+ compatible = "ralink,rt5350-wmac", "ralink,rt2880-wmac"; -+ reg = <0x10180000 40000>; -+ -+ interrupt-parent = <&cpuintc>; -+ interrupts = <6>; -+ -+ status = "disabled"; -+ }; -+ -+ ehci@101c0000 { -+ compatible = "ralink,rt5350-ehci", "ehci-platform"; -+ reg = <0x101c0000 0x1000>; -+ -+ interrupt-parent = <&intc>; -+ interrupts = <18>; -+ -+ status = "disabled"; -+ }; -+ -+ ohci@101c1000 { -+ compatible = "ralink,rt5350-ohci", "ohci-platform"; -+ reg = <0x101c1000 0x1000>; -+ -+ interrupt-parent = <&intc>; -+ interrupts = <18>; -+ -+ status = "disabled"; -+ }; -+}; diff --git a/target/linux/ramips/patches-3.8/0106-MIPS-ralink-make-early_printk-work-on-RT2880.patch b/target/linux/ramips/patches-3.8/0106-MIPS-ralink-make-early_printk-work-on-RT2880.patch new file mode 100644 index 0000000000..4636862fe5 --- /dev/null +++ b/target/linux/ramips/patches-3.8/0106-MIPS-ralink-make-early_printk-work-on-RT2880.patch @@ -0,0 +1,28 @@ +From d83e83a544258b68b4411232a31ccce134244a19 Mon Sep 17 00:00:00 2001 +From: John Crispin +Date: Tue, 9 Apr 2013 18:31:15 +0200 +Subject: [PATCH 106/137] MIPS: ralink: make early_printk work on RT2880 + +RT2880 has a different location for the early serial port. + +Signed-off-by: John Crispin +Acked-by: Gabor Juhos +Patchwork: http://patchwork.linux-mips.org/patch/5170/ +--- + arch/mips/ralink/early_printk.c | 4 ++++ + 1 file changed, 4 insertions(+) + +--- a/arch/mips/ralink/early_printk.c ++++ b/arch/mips/ralink/early_printk.c +@@ -11,7 +11,11 @@ + + #include + ++#ifdef CONFIG_SOC_RT288X ++#define EARLY_UART_BASE 0x300c00 ++#else + #define EARLY_UART_BASE 0x10000c00 ++#endif + + #define UART_REG_RX 0x00 + #define UART_REG_TX 0x04 diff --git a/target/linux/ramips/patches-3.8/0107-MIPS-ralink-adds-support-for-RT2880-SoC-family.patch b/target/linux/ramips/patches-3.8/0107-MIPS-ralink-adds-support-for-RT2880-SoC-family.patch deleted file mode 100644 index 592f2af24c..0000000000 --- a/target/linux/ramips/patches-3.8/0107-MIPS-ralink-adds-support-for-RT2880-SoC-family.patch +++ /dev/null @@ -1,266 +0,0 @@ -From c4429f19cc66951962c171dba90b8747f95a654e Mon Sep 17 00:00:00 2001 -From: John Crispin -Date: Sun, 27 Jan 2013 09:17:20 +0100 -Subject: [PATCH V2 09/16] MIPS: ralink: adds support for RT2880 SoC family - -Add support code for rt2880 SOC. - -The code detects the SoC and registers the clk / pinmux settings. - -Signed-off-by: John Crispin ---- - arch/mips/Kconfig | 2 +- - arch/mips/include/asm/mach-ralink/rt288x.h | 49 ++++++++++ - arch/mips/ralink/Kconfig | 3 + - arch/mips/ralink/Makefile | 1 + - arch/mips/ralink/Platform | 5 + - arch/mips/ralink/rt288x.c | 143 ++++++++++++++++++++++++++++ - 6 files changed, 202 insertions(+), 1 deletion(-) - create mode 100644 arch/mips/include/asm/mach-ralink/rt288x.h - create mode 100644 arch/mips/ralink/rt288x.c - ---- a/arch/mips/Kconfig -+++ b/arch/mips/Kconfig -@@ -1189,7 +1189,7 @@ config BOOT_ELF32 - - config MIPS_L1_CACHE_SHIFT - int -- default "4" if MACH_DECSTATION || MIKROTIK_RB532 || PMC_MSP4200_EVAL -+ default "4" if MACH_DECSTATION || MIKROTIK_RB532 || PMC_MSP4200_EVAL || SOC_RT288X - default "6" if MIPS_CPU_SCACHE - default "7" if SGI_IP22 || SGI_IP27 || SGI_IP28 || SNI_RM || CPU_CAVIUM_OCTEON - default "5" ---- /dev/null -+++ b/arch/mips/include/asm/mach-ralink/rt288x.h -@@ -0,0 +1,49 @@ -+/* -+ * 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 -+ * Copyright (C) 2008 Imre Kaloz -+ * Copyright (C) 2013 John Crispin -+ */ -+ -+#ifndef _RT288X_REGS_H_ -+#define _RT288X_REGS_H_ -+ -+#define RT2880_SYSC_BASE 0x00300000 -+ -+#define SYSC_REG_CHIP_NAME0 0x00 -+#define SYSC_REG_CHIP_NAME1 0x04 -+#define SYSC_REG_CHIP_ID 0x0c -+#define SYSC_REG_SYSTEM_CONFIG 0x10 -+#define SYSC_REG_CLKCFG 0x30 -+ -+#define RT2880_CHIP_NAME0 0x38325452 -+#define RT2880_CHIP_NAME1 0x20203038 -+ -+#define CHIP_ID_ID_MASK 0xff -+#define CHIP_ID_ID_SHIFT 8 -+#define CHIP_ID_REV_MASK 0xff -+ -+#define SYSTEM_CONFIG_CPUCLK_SHIFT 20 -+#define SYSTEM_CONFIG_CPUCLK_MASK 0x3 -+#define SYSTEM_CONFIG_CPUCLK_250 0x0 -+#define SYSTEM_CONFIG_CPUCLK_266 0x1 -+#define SYSTEM_CONFIG_CPUCLK_280 0x2 -+#define SYSTEM_CONFIG_CPUCLK_300 0x3 -+ -+#define RT2880_GPIO_MODE_I2C BIT(0) -+#define RT2880_GPIO_MODE_UART0 BIT(1) -+#define RT2880_GPIO_MODE_SPI BIT(2) -+#define RT2880_GPIO_MODE_UART1 BIT(3) -+#define RT2880_GPIO_MODE_JTAG BIT(4) -+#define RT2880_GPIO_MODE_MDIO BIT(5) -+#define RT2880_GPIO_MODE_SDRAM BIT(6) -+#define RT2880_GPIO_MODE_PCI BIT(7) -+ -+#define CLKCFG_SRAM_CS_N_WDT BIT(9) -+ -+#endif ---- a/arch/mips/ralink/Kconfig -+++ b/arch/mips/ralink/Kconfig -@@ -6,6 +6,9 @@ choice - help - Select Ralink MIPS SoC type. - -+ config SOC_RT288X -+ bool "RT288x" -+ - config SOC_RT305X - bool "RT305x" - select USB_ARCH_HAS_HCD ---- a/arch/mips/ralink/Makefile -+++ b/arch/mips/ralink/Makefile -@@ -8,6 +8,7 @@ - - obj-y := prom.o of.o reset.o clk.o irq.o pinmux.o - -+obj-$(CONFIG_SOC_RT288X) += rt288x.o - obj-$(CONFIG_SOC_RT305X) += rt305x.o - - obj-$(CONFIG_EARLY_PRINTK) += early_printk.o ---- a/arch/mips/ralink/Platform -+++ b/arch/mips/ralink/Platform -@@ -5,6 +5,11 @@ core-$(CONFIG_RALINK) += arch/mips/rali - cflags-$(CONFIG_RALINK) += -I$(srctree)/arch/mips/include/asm/mach-ralink - - # -+# Ralink RT288x -+# -+load-$(CONFIG_SOC_RT288X) += 0xffffffff88000000 -+ -+# - # Ralink RT305x - # - load-$(CONFIG_SOC_RT305X) += 0xffffffff80000000 ---- /dev/null -+++ b/arch/mips/ralink/rt288x.c -@@ -0,0 +1,143 @@ -+/* -+ * 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 -+ * Copyright (C) 2008 Imre Kaloz -+ * Copyright (C) 2013 John Crispin -+ */ -+ -+#include -+#include -+#include -+ -+#include -+#include -+#include -+ -+#include "common.h" -+ -+struct ralink_pinmux_grp mode_mux[] = { -+ { -+ .name = "i2c", -+ .mask = RT2880_GPIO_MODE_I2C, -+ .gpio_first = 1, -+ .gpio_last = 2, -+ }, { -+ .name = "spi", -+ .mask = RT2880_GPIO_MODE_SPI, -+ .gpio_first = 3, -+ .gpio_last = 6, -+ }, { -+ .name = "uartlite", -+ .mask = RT2880_GPIO_MODE_UART0, -+ .gpio_first = 7, -+ .gpio_last = 14, -+ }, { -+ .name = "jtag", -+ .mask = RT2880_GPIO_MODE_JTAG, -+ .gpio_first = 17, -+ .gpio_last = 21, -+ }, { -+ .name = "mdio", -+ .mask = RT2880_GPIO_MODE_MDIO, -+ .gpio_first = 22, -+ .gpio_last = 23, -+ }, { -+ .name = "sdram", -+ .mask = RT2880_GPIO_MODE_SDRAM, -+ .gpio_first = 24, -+ .gpio_last = 39, -+ }, { -+ .name = "pci", -+ .mask = RT2880_GPIO_MODE_PCI, -+ .gpio_first = 40, -+ .gpio_last = 71, -+ }, {0} -+}; -+ -+void rt288x_wdt_reset(void) -+{ -+ u32 t; -+ -+ /* enable WDT reset output on pin SRAM_CS_N */ -+ t = rt_sysc_r32(SYSC_REG_CLKCFG); -+ t |= CLKCFG_SRAM_CS_N_WDT; -+ rt_sysc_w32(t, SYSC_REG_CLKCFG); -+} -+ -+struct ralink_pinmux rt_pinmux = { -+ .mode = mode_mux, -+ .wdt_reset = rt288x_wdt_reset, -+}; -+ -+void ralink_usb_platform(void) -+{ -+} -+ -+void __init ralink_clk_init(void) -+{ -+ unsigned long cpu_rate; -+ u32 t = rt_sysc_r32(SYSC_REG_SYSTEM_CONFIG); -+ t = ((t >> SYSTEM_CONFIG_CPUCLK_SHIFT) & SYSTEM_CONFIG_CPUCLK_MASK); -+ -+ switch (t) { -+ case SYSTEM_CONFIG_CPUCLK_250: -+ cpu_rate = 250000000; -+ break; -+ case SYSTEM_CONFIG_CPUCLK_266: -+ cpu_rate = 266666667; -+ break; -+ case SYSTEM_CONFIG_CPUCLK_280: -+ cpu_rate = 280000000; -+ break; -+ case SYSTEM_CONFIG_CPUCLK_300: -+ cpu_rate = 300000000; -+ break; -+ } -+ -+ ralink_clk_add("cpu", cpu_rate); -+ ralink_clk_add("300100.timer", cpu_rate / 2); -+ ralink_clk_add("300120.watchdog", cpu_rate / 2); -+ ralink_clk_add("300500.uart", cpu_rate / 2); -+ ralink_clk_add("300c00.uartlite", cpu_rate / 2); -+ ralink_clk_add("400000.ethernet", cpu_rate / 2); -+} -+ -+void __init ralink_of_remap(void) -+{ -+ rt_sysc_membase = plat_of_remap_node("ralink,rt2880-sysc"); -+ rt_memc_membase = plat_of_remap_node("ralink,rt2880-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(RT2880_SYSC_BASE); -+ const char *name; -+ u32 n0; -+ u32 n1; -+ u32 id; -+ -+ n0 = __raw_readl(sysc + SYSC_REG_CHIP_NAME0); -+ n1 = __raw_readl(sysc + SYSC_REG_CHIP_NAME1); -+ id = __raw_readl(sysc + SYSC_REG_CHIP_ID); -+ -+ if (n0 == RT2880_CHIP_NAME0 && n1 == RT2880_CHIP_NAME1) { -+ soc_info->compatible = "ralink,r2880-soc"; -+ name = "RT2880"; -+ } else { -+ panic("rt288x: unknown SoC, n0:%08x n1:%08x", n0, n1); -+ } -+ -+ snprintf(soc_info->sys_type, RAMIPS_SYS_TYPE_LEN, -+ "Ralink %s id:%u rev:%u", -+ name, -+ (id >> CHIP_ID_ID_SHIFT) & CHIP_ID_ID_MASK, -+ (id & CHIP_ID_REV_MASK)); -+} diff --git a/target/linux/ramips/patches-3.8/0107-MIPS-ralink-rename-gpio_pinmux-to-rt_gpio_pinmux.patch b/target/linux/ramips/patches-3.8/0107-MIPS-ralink-rename-gpio_pinmux-to-rt_gpio_pinmux.patch new file mode 100644 index 0000000000..d10b159ac8 --- /dev/null +++ b/target/linux/ramips/patches-3.8/0107-MIPS-ralink-rename-gpio_pinmux-to-rt_gpio_pinmux.patch @@ -0,0 +1,36 @@ +From b4c597bd073d5e4c9cee800ac5a25fb9ff1c0ef7 Mon Sep 17 00:00:00 2001 +From: John Crispin +Date: Fri, 12 Apr 2013 22:12:09 +0200 +Subject: [PATCH 107/137] MIPS: ralink: rename gpio_pinmux to rt_gpio_pinmux + +Add proper namespacing to the variable. + +Signed-off-by: John Crispin +Patchwork: http://patchwork.linux-mips.org/patch/5171/ +--- + arch/mips/ralink/common.h | 2 +- + arch/mips/ralink/rt305x.c | 2 +- + 2 files changed, 2 insertions(+), 2 deletions(-) + +--- a/arch/mips/ralink/common.h ++++ b/arch/mips/ralink/common.h +@@ -24,7 +24,7 @@ struct ralink_pinmux { + int uart_shift; + void (*wdt_reset)(void); + }; +-extern struct ralink_pinmux gpio_pinmux; ++extern struct ralink_pinmux rt_gpio_pinmux; + + struct ralink_soc_info { + unsigned char sys_type[RAMIPS_SYS_TYPE_LEN]; +--- a/arch/mips/ralink/rt305x.c ++++ b/arch/mips/ralink/rt305x.c +@@ -114,7 +114,7 @@ void rt305x_wdt_reset(void) + rt_sysc_w32(t, SYSC_REG_SYSTEM_CONFIG); + } + +-struct ralink_pinmux gpio_pinmux = { ++struct ralink_pinmux rt_gpio_pinmux = { + .mode = mode_mux, + .uart = uart_mux, + .uart_shift = RT305X_GPIO_MODE_UART0_SHIFT, diff --git a/target/linux/ramips/patches-3.8/0108-MIPS-add-rt2880-dts-files.patch b/target/linux/ramips/patches-3.8/0108-MIPS-add-rt2880-dts-files.patch deleted file mode 100644 index f0a39ced0d..0000000000 --- a/target/linux/ramips/patches-3.8/0108-MIPS-add-rt2880-dts-files.patch +++ /dev/null @@ -1,210 +0,0 @@ -From b72ae753b73cbc4b488dcdbf997faec199c8bb3f Mon Sep 17 00:00:00 2001 -From: John Crispin -Date: Thu, 21 Mar 2013 18:29:02 +0100 -Subject: [PATCH 108/121] MIPS: add rt2880 dts files - -Add a dtsi file for RT2880 SoC and a sample dts file. This SoC is first one that -was released in this SoC family. - -Signed-off-by: John Crispin ---- - arch/mips/ralink/Kconfig | 4 ++ - arch/mips/ralink/dts/Makefile | 1 + - arch/mips/ralink/dts/rt2880.dtsi | 116 ++++++++++++++++++++++++++++++++++ - arch/mips/ralink/dts/rt2880_eval.dts | 52 +++++++++++++++ - 4 files changed, 173 insertions(+) - create mode 100644 arch/mips/ralink/dts/rt2880.dtsi - create mode 100644 arch/mips/ralink/dts/rt2880_eval.dts - ---- a/arch/mips/ralink/Kconfig -+++ b/arch/mips/ralink/Kconfig -@@ -26,6 +26,10 @@ choice - config DTB_RT_NONE - bool "None" - -+ config DTB_RT2880_EVAL -+ bool "RT2880 eval kit" -+ depends on SOC_RT288X -+ - config DTB_RT305X_EVAL - bool "RT305x eval kit" - depends on SOC_RT305X ---- a/arch/mips/ralink/dts/Makefile -+++ b/arch/mips/ralink/dts/Makefile -@@ -1 +1,2 @@ -+obj-$(CONFIG_DTB_RT2880_EVAL) := rt2880_eval.dtb.o - obj-$(CONFIG_DTB_RT305X_EVAL) := rt3052_eval.dtb.o ---- /dev/null -+++ b/arch/mips/ralink/dts/rt2880.dtsi -@@ -0,0 +1,116 @@ -+/ { -+ #address-cells = <1>; -+ #size-cells = <1>; -+ compatible = "ralink,rt2880-soc"; -+ -+ cpus { -+ cpu@0 { -+ compatible = "mips,mips24KEc"; -+ }; -+ }; -+ -+ chosen { -+ bootargs = "console=ttyS0,57600 init=/init"; -+ }; -+ -+ cpuintc: cpuintc@0 { -+ #address-cells = <0>; -+ #interrupt-cells = <1>; -+ interrupt-controller; -+ compatible = "mti,cpu-interrupt-controller"; -+ }; -+ -+ palmbus@10000000 { -+ compatible = "palmbus"; -+ reg = <0x10000000 0x200000>; -+ ranges = <0x0 0x10000000 0x1FFFFF>; -+ -+ #address-cells = <1>; -+ #size-cells = <1>; -+ -+ sysc@300000 { -+ compatible = "ralink,rt2880-sysc"; -+ reg = <0x300000 0x100>; -+ }; -+ -+ timer@300100 { -+ compatible = "ralink,rt2880-timer"; -+ reg = <0x300100 0x20>; -+ -+ interrupt-parent = <&intc>; -+ interrupts = <1>; -+ -+ status = "disabled"; -+ }; -+ -+ watchdog@300120 { -+ compatible = "ralink,rt2880-wdt"; -+ reg = <0x300120 0x10>; -+ }; -+ -+ intc: intc@300200 { -+ compatible = "ralink,rt2880-intc"; -+ reg = <0x300200 0x100>; -+ -+ interrupt-controller; -+ #interrupt-cells = <1>; -+ -+ interrupt-parent = <&cpuintc>; -+ interrupts = <2>; -+ }; -+ -+ memc@300300 { -+ compatible = "ralink,rt2880-memc"; -+ reg = <0x300300 0x100>; -+ }; -+ -+ gpio0: gpio@300600 { -+ compatible = "ralink,rt2880-gpio"; -+ reg = <0x300600 0x34>; -+ -+ gpio-controller; -+ #gpio-cells = <2>; -+ -+ ralink,num-gpios = <24>; -+ ralink,register-map = [ 00 04 08 0c -+ 20 24 28 2c -+ 30 34 ]; -+ }; -+ -+ gpio1: gpio@300638 { -+ compatible = "ralink,rt2880-gpio"; -+ reg = <0x300638 0x24>; -+ -+ gpio-controller; -+ #gpio-cells = <2>; -+ -+ ralink,num-gpios = <16>; -+ ralink,register-map = [ 00 04 08 0c -+ 10 14 18 1c -+ 20 24 ]; -+ }; -+ -+ gpio2: gpio@300660 { -+ compatible = "ralink,rt2880-gpio"; -+ reg = <0x300660 0x24>; -+ -+ gpio-controller; -+ #gpio-cells = <2>; -+ -+ ralink,num-gpios = <32>; -+ ralink,register-map = [ 00 04 08 0c -+ 10 14 18 1c -+ 20 24 ]; -+ }; -+ -+ uartlite@300c00 { -+ compatible = "ralink,rt2880-uart", "ns16550a"; -+ reg = <0x300c00 0x100>; -+ -+ interrupt-parent = <&intc>; -+ interrupts = <12>; -+ -+ reg-shift = <2>; -+ }; -+ }; -+}; ---- /dev/null -+++ b/arch/mips/ralink/dts/rt2880_eval.dts -@@ -0,0 +1,52 @@ -+/dts-v1/; -+ -+/include/ "rt2880.dtsi" -+ -+/ { -+ #address-cells = <1>; -+ #size-cells = <1>; -+ compatible = "ralink,rt2880-eval-board", "ralink,rt2880-soc"; -+ model = "Ralink RT2880 evaluation board"; -+ -+ memory@8000000 { -+ reg = <0x0 0x2000000>; -+ }; -+ -+ palmbus@10000000 { -+ sysc@300000 { -+ ralink,pinmux = "uartlite", "spi"; -+ ralink,uartmux = "gpio"; -+ ralink,wdtmux = <0>; -+ }; -+ }; -+ -+ cfi@1f000000 { -+ compatible = "cfi-flash"; -+ reg = <0x1f000000 0x800000>; -+ -+ bank-width = <2>; -+ device-width = <2>; -+ #address-cells = <1>; -+ #size-cells = <1>; -+ -+ partition@0 { -+ label = "uboot"; -+ reg = <0x0 0x30000>; -+ read-only; -+ }; -+ partition@30000 { -+ label = "uboot-env"; -+ reg = <0x30000 0x10000>; -+ read-only; -+ }; -+ partition@40000 { -+ label = "calibration"; -+ reg = <0x40000 0x10000>; -+ read-only; -+ }; -+ partition@50000 { -+ label = "linux"; -+ reg = <0x50000 0x7b0000>; -+ }; -+ }; -+}; diff --git a/target/linux/ramips/patches-3.8/0108-MIPS-ralink-make-the-RT305x-pinmuxing-structure-stat.patch b/target/linux/ramips/patches-3.8/0108-MIPS-ralink-make-the-RT305x-pinmuxing-structure-stat.patch new file mode 100644 index 0000000000..f09d57f818 --- /dev/null +++ b/target/linux/ramips/patches-3.8/0108-MIPS-ralink-make-the-RT305x-pinmuxing-structure-stat.patch @@ -0,0 +1,44 @@ +From 96eba63bf18cd3d96ded62fb809c8cf7e0f2e2c1 Mon Sep 17 00:00:00 2001 +From: John Crispin +Date: Fri, 12 Apr 2013 22:16:12 +0200 +Subject: [PATCH 108/137] MIPS: ralink: make the RT305x pinmuxing structure + static + +These structures are exported via struct ralink_pinmux rt_gpio_pinmux and can +hence be static. + +Signed-off-by: John Crispin +Patchwork: http://patchwork.linux-mips.org/patch/5172/ +--- + arch/mips/ralink/rt305x.c | 6 +++--- + 1 file changed, 3 insertions(+), 3 deletions(-) + +--- a/arch/mips/ralink/rt305x.c ++++ b/arch/mips/ralink/rt305x.c +@@ -22,7 +22,7 @@ + + enum rt305x_soc_type rt305x_soc; + +-struct ralink_pinmux_grp mode_mux[] = { ++static struct ralink_pinmux_grp mode_mux[] = { + { + .name = "i2c", + .mask = RT305X_GPIO_MODE_I2C, +@@ -61,7 +61,7 @@ struct ralink_pinmux_grp mode_mux[] = { + }, {0} + }; + +-struct ralink_pinmux_grp uart_mux[] = { ++static struct ralink_pinmux_grp uart_mux[] = { + { + .name = "uartf", + .mask = RT305X_GPIO_MODE_UARTF, +@@ -103,7 +103,7 @@ struct ralink_pinmux_grp uart_mux[] = { + }, {0} + }; + +-void rt305x_wdt_reset(void) ++static void rt305x_wdt_reset(void) + { + u32 t; + diff --git a/target/linux/ramips/patches-3.8/0109-MIPS-ralink-add-pci-group-to-struct-ralink_pinmux.patch b/target/linux/ramips/patches-3.8/0109-MIPS-ralink-add-pci-group-to-struct-ralink_pinmux.patch new file mode 100644 index 0000000000..36e187db2d --- /dev/null +++ b/target/linux/ramips/patches-3.8/0109-MIPS-ralink-add-pci-group-to-struct-ralink_pinmux.patch @@ -0,0 +1,26 @@ +From 61d50d9625dcb454759950ebd45a335c3aaacf84 Mon Sep 17 00:00:00 2001 +From: Gabor Juhos +Date: Fri, 12 Apr 2013 12:40:23 +0200 +Subject: [PATCH 109/137] MIPS: ralink: add pci group to struct ralink_pinmux + +This will be used for RT3662/RT3883. + +Signed-off-by: Gabor Juhos +Acked-by: John Crispin +Patchwork: http://patchwork.linux-mips.org/patch/5173/ +--- + arch/mips/ralink/common.h | 3 +++ + 1 file changed, 3 insertions(+) + +--- a/arch/mips/ralink/common.h ++++ b/arch/mips/ralink/common.h +@@ -23,6 +23,9 @@ struct ralink_pinmux { + struct ralink_pinmux_grp *uart; + int uart_shift; + void (*wdt_reset)(void); ++ struct ralink_pinmux_grp *pci; ++ int pci_shift; ++ u32 pci_mask; + }; + extern struct ralink_pinmux rt_gpio_pinmux; + diff --git a/target/linux/ramips/patches-3.8/0109-MIPS-ralink-adds-support-for-RT3883-SoC-family.patch b/target/linux/ramips/patches-3.8/0109-MIPS-ralink-adds-support-for-RT3883-SoC-family.patch deleted file mode 100644 index 3d822f4f52..0000000000 --- a/target/linux/ramips/patches-3.8/0109-MIPS-ralink-adds-support-for-RT3883-SoC-family.patch +++ /dev/null @@ -1,515 +0,0 @@ -From 45a8644332a85e8b099df9d467a719ded741e749 Mon Sep 17 00:00:00 2001 -From: John Crispin -Date: Sun, 27 Jan 2013 09:39:02 +0100 -Subject: [PATCH 109/121] MIPS: ralink: adds support for RT3883 SoC family - -Add support code for rt3883 SOC. - -The code detects the SoC and registers the clk / pinmux settings. - -Signed-off-by: John Crispin ---- - arch/mips/include/asm/mach-ralink/rt3883.h | 247 ++++++++++++++++++++++++++++ - arch/mips/ralink/Kconfig | 5 + - arch/mips/ralink/Makefile | 1 + - arch/mips/ralink/Platform | 5 + - arch/mips/ralink/rt3883.c | 207 +++++++++++++++++++++++ - 5 files changed, 465 insertions(+) - create mode 100644 arch/mips/include/asm/mach-ralink/rt3883.h - create mode 100644 arch/mips/ralink/rt3883.c - ---- /dev/null -+++ b/arch/mips/include/asm/mach-ralink/rt3883.h -@@ -0,0 +1,247 @@ -+/* -+ * Ralink RT3662/RT3883 SoC register definitions -+ * -+ * Copyright (C) 2011-2012 Gabor Juhos -+ * -+ * This program is free software; you can redistribute it and/or modify it -+ * under the terms of the GNU General Public License version 2 as published -+ * by the Free Software Foundation. -+ */ -+ -+#ifndef _RT3883_REGS_H_ -+#define _RT3883_REGS_H_ -+ -+#include -+ -+#define RT3883_SDRAM_BASE 0x00000000 -+#define RT3883_SYSC_BASE 0x10000000 -+#define RT3883_TIMER_BASE 0x10000100 -+#define RT3883_INTC_BASE 0x10000200 -+#define RT3883_MEMC_BASE 0x10000300 -+#define RT3883_UART0_BASE 0x10000500 -+#define RT3883_PIO_BASE 0x10000600 -+#define RT3883_FSCC_BASE 0x10000700 -+#define RT3883_NANDC_BASE 0x10000810 -+#define RT3883_I2C_BASE 0x10000900 -+#define RT3883_I2S_BASE 0x10000a00 -+#define RT3883_SPI_BASE 0x10000b00 -+#define RT3883_UART1_BASE 0x10000c00 -+#define RT3883_PCM_BASE 0x10002000 -+#define RT3883_GDMA_BASE 0x10002800 -+#define RT3883_CODEC1_BASE 0x10003000 -+#define RT3883_CODEC2_BASE 0x10003800 -+#define RT3883_FE_BASE 0x10100000 -+#define RT3883_ROM_BASE 0x10118000 -+#define RT3883_USBDEV_BASE 0x10112000 -+#define RT3883_PCI_BASE 0x10140000 -+#define RT3883_WLAN_BASE 0x10180000 -+#define RT3883_USBHOST_BASE 0x101c0000 -+#define RT3883_BOOT_BASE 0x1c000000 -+#define RT3883_SRAM_BASE 0x1e000000 -+#define RT3883_PCIMEM_BASE 0x20000000 -+ -+#define RT3883_EHCI_BASE (RT3883_USBHOST_BASE) -+#define RT3883_OHCI_BASE (RT3883_USBHOST_BASE + 0x1000) -+ -+#define RT3883_SYSC_SIZE 0x100 -+#define RT3883_TIMER_SIZE 0x100 -+#define RT3883_INTC_SIZE 0x100 -+#define RT3883_MEMC_SIZE 0x100 -+#define RT3883_UART0_SIZE 0x100 -+#define RT3883_UART1_SIZE 0x100 -+#define RT3883_PIO_SIZE 0x100 -+#define RT3883_FSCC_SIZE 0x100 -+#define RT3883_NANDC_SIZE 0x0f0 -+#define RT3883_I2C_SIZE 0x100 -+#define RT3883_I2S_SIZE 0x100 -+#define RT3883_SPI_SIZE 0x100 -+#define RT3883_PCM_SIZE 0x800 -+#define RT3883_GDMA_SIZE 0x800 -+#define RT3883_CODEC1_SIZE 0x800 -+#define RT3883_CODEC2_SIZE 0x800 -+#define RT3883_FE_SIZE 0x10000 -+#define RT3883_ROM_SIZE 0x4000 -+#define RT3883_USBDEV_SIZE 0x4000 -+#define RT3883_PCI_SIZE 0x40000 -+#define RT3883_WLAN_SIZE 0x40000 -+#define RT3883_USBHOST_SIZE 0x40000 -+#define RT3883_BOOT_SIZE (32 * 1024 * 1024) -+#define RT3883_SRAM_SIZE (32 * 1024 * 1024) -+ -+/* SYSC registers */ -+#define RT3883_SYSC_REG_CHIPID0_3 0x00 /* Chip ID 0 */ -+#define RT3883_SYSC_REG_CHIPID4_7 0x04 /* Chip ID 1 */ -+#define RT3883_SYSC_REG_REVID 0x0c /* Chip Revision Identification */ -+#define RT3883_SYSC_REG_SYSCFG0 0x10 /* System Configuration 0 */ -+#define RT3883_SYSC_REG_SYSCFG1 0x14 /* System Configuration 1 */ -+#define RT3883_SYSC_REG_CLKCFG0 0x2c /* Clock Configuration 0 */ -+#define RT3883_SYSC_REG_CLKCFG1 0x30 /* Clock Configuration 1 */ -+#define RT3883_SYSC_REG_RSTCTRL 0x34 /* Reset Control*/ -+#define RT3883_SYSC_REG_RSTSTAT 0x38 /* Reset Status*/ -+#define RT3883_SYSC_REG_USB_PS 0x5c /* USB Power saving control */ -+#define RT3883_SYSC_REG_GPIO_MODE 0x60 /* GPIO Purpose Select */ -+#define RT3883_SYSC_REG_PCIE_CLK_GEN0 0x7c -+#define RT3883_SYSC_REG_PCIE_CLK_GEN1 0x80 -+#define RT3883_SYSC_REG_PCIE_CLK_GEN2 0x84 -+#define RT3883_SYSC_REG_PMU 0x88 -+#define RT3883_SYSC_REG_PMU1 0x8c -+ -+#define RT3883_CHIP_NAME0 0x38335452 -+#define RT3883_CHIP_NAME1 0x20203338 -+ -+#define RT3883_REVID_VER_ID_MASK 0x0f -+#define RT3883_REVID_VER_ID_SHIFT 8 -+#define RT3883_REVID_ECO_ID_MASK 0x0f -+ -+#define RT3883_SYSCFG0_DRAM_TYPE_DDR2 BIT(17) -+#define RT3883_SYSCFG0_CPUCLK_SHIFT 8 -+#define RT3883_SYSCFG0_CPUCLK_MASK 0x3 -+#define RT3883_SYSCFG0_CPUCLK_250 0x0 -+#define RT3883_SYSCFG0_CPUCLK_384 0x1 -+#define RT3883_SYSCFG0_CPUCLK_480 0x2 -+#define RT3883_SYSCFG0_CPUCLK_500 0x3 -+ -+#define RT3883_SYSCFG1_USB0_HOST_MODE BIT(10) -+#define RT3883_SYSCFG1_PCIE_RC_MODE BIT(8) -+#define RT3883_SYSCFG1_PCI_HOST_MODE BIT(7) -+#define RT3883_SYSCFG1_PCI_66M_MODE BIT(6) -+#define RT3883_SYSCFG1_GPIO2_AS_WDT_OUT BIT(2) -+ -+#define RT3883_CLKCFG1_PCIE_CLK_EN BIT(21) -+#define RT3883_CLKCFG1_UPHY1_CLK_EN BIT(20) -+#define RT3883_CLKCFG1_PCI_CLK_EN BIT(19) -+#define RT3883_CLKCFG1_UPHY0_CLK_EN BIT(18) -+ -+#define RT3883_GPIO_MODE_I2C BIT(0) -+#define RT3883_GPIO_MODE_SPI BIT(1) -+#define RT3883_GPIO_MODE_UART0_SHIFT 2 -+#define RT3883_GPIO_MODE_UART0_MASK 0x7 -+#define RT3883_GPIO_MODE_UART0(x) ((x) << RT3883_GPIO_MODE_UART0_SHIFT) -+#define RT3883_GPIO_MODE_UARTF 0x0 -+#define RT3883_GPIO_MODE_PCM_UARTF 0x1 -+#define RT3883_GPIO_MODE_PCM_I2S 0x2 -+#define RT3883_GPIO_MODE_I2S_UARTF 0x3 -+#define RT3883_GPIO_MODE_PCM_GPIO 0x4 -+#define RT3883_GPIO_MODE_GPIO_UARTF 0x5 -+#define RT3883_GPIO_MODE_GPIO_I2S 0x6 -+#define RT3883_GPIO_MODE_GPIO 0x7 -+#define RT3883_GPIO_MODE_UART1 BIT(5) -+#define RT3883_GPIO_MODE_JTAG BIT(6) -+#define RT3883_GPIO_MODE_MDIO BIT(7) -+#define RT3883_GPIO_MODE_GE1 BIT(9) -+#define RT3883_GPIO_MODE_GE2 BIT(10) -+#define RT3883_GPIO_MODE_PCI_SHIFT 11 -+#define RT3883_GPIO_MODE_PCI_MASK 0x7 -+#define RT3883_GPIO_MODE_PCI (RT3883_GPIO_MODE_PCI_MASK << RT3883_GPIO_MODE_PCI_SHIFT) -+#define RT3883_GPIO_MODE_LNA_A_SHIFT 16 -+#define RT3883_GPIO_MODE_LNA_A_MASK 0x3 -+#define _RT3883_GPIO_MODE_LNA_A(_x) ((_x) << RT3883_GPIO_MODE_LNA_A_SHIFT) -+#define RT3883_GPIO_MODE_LNA_A_GPIO 0x3 -+#define RT3883_GPIO_MODE_LNA_A _RT3883_GPIO_MODE_LNA_A(RT3883_GPIO_MODE_LNA_A_MASK) -+#define RT3883_GPIO_MODE_LNA_G_SHIFT 18 -+#define RT3883_GPIO_MODE_LNA_G_MASK 0x3 -+#define _RT3883_GPIO_MODE_LNA_G(_x) ((_x) << RT3883_GPIO_MODE_LNA_G_SHIFT) -+#define RT3883_GPIO_MODE_LNA_G_GPIO 0x3 -+#define RT3883_GPIO_MODE_LNA_G _RT3883_GPIO_MODE_LNA_G(RT3883_GPIO_MODE_LNA_G_MASK) -+ -+#define RT3883_GPIO_I2C_SD 1 -+#define RT3883_GPIO_I2C_SCLK 2 -+#define RT3883_GPIO_SPI_CS0 3 -+#define RT3883_GPIO_SPI_CLK 4 -+#define RT3883_GPIO_SPI_MOSI 5 -+#define RT3883_GPIO_SPI_MISO 6 -+#define RT3883_GPIO_7 7 -+#define RT3883_GPIO_10 10 -+#define RT3883_GPIO_14 14 -+#define RT3883_GPIO_UART1_TXD 15 -+#define RT3883_GPIO_UART1_RXD 16 -+#define RT3883_GPIO_JTAG_TDO 17 -+#define RT3883_GPIO_JTAG_TDI 18 -+#define RT3883_GPIO_JTAG_TMS 19 -+#define RT3883_GPIO_JTAG_TCLK 20 -+#define RT3883_GPIO_JTAG_TRST_N 21 -+#define RT3883_GPIO_MDIO_MDC 22 -+#define RT3883_GPIO_MDIO_MDIO 23 -+#define RT3883_GPIO_LNA_PE_A0 32 -+#define RT3883_GPIO_LNA_PE_A1 33 -+#define RT3883_GPIO_LNA_PE_A2 34 -+#define RT3883_GPIO_LNA_PE_G0 35 -+#define RT3883_GPIO_LNA_PE_G1 36 -+#define RT3883_GPIO_LNA_PE_G2 37 -+#define RT3883_GPIO_PCI_AD0 40 -+#define RT3883_GPIO_PCI_AD31 71 -+#define RT3883_GPIO_GE2_TXD0 72 -+#define RT3883_GPIO_GE2_TXD1 73 -+#define RT3883_GPIO_GE2_TXD2 74 -+#define RT3883_GPIO_GE2_TXD3 75 -+#define RT3883_GPIO_GE2_TXEN 76 -+#define RT3883_GPIO_GE2_TXCLK 77 -+#define RT3883_GPIO_GE2_RXD0 78 -+#define RT3883_GPIO_GE2_RXD1 79 -+#define RT3883_GPIO_GE2_RXD2 80 -+#define RT3883_GPIO_GE2_RXD3 81 -+#define RT3883_GPIO_GE2_RXDV 82 -+#define RT3883_GPIO_GE2_RXCLK 83 -+#define RT3883_GPIO_GE1_TXD0 84 -+#define RT3883_GPIO_GE1_TXD1 85 -+#define RT3883_GPIO_GE1_TXD2 86 -+#define RT3883_GPIO_GE1_TXD3 87 -+#define RT3883_GPIO_GE1_TXEN 88 -+#define RT3883_GPIO_GE1_TXCLK 89 -+#define RT3883_GPIO_GE1_RXD0 90 -+#define RT3883_GPIO_GE1_RXD1 91 -+#define RT3883_GPIO_GE1_RXD2 92 -+#define RT3883_GPIO_GE1_RXD3 93 -+#define RT3883_GPIO_GE1_RXDV 94 -+#define RT3883_GPIO_GE1_RXCLK 95 -+ -+#define RT3883_RSTCTRL_PCIE_PCI_PDM BIT(27) -+#define RT3883_RSTCTRL_FLASH BIT(26) -+#define RT3883_RSTCTRL_UDEV BIT(25) -+#define RT3883_RSTCTRL_PCI BIT(24) -+#define RT3883_RSTCTRL_PCIE BIT(23) -+#define RT3883_RSTCTRL_UHST BIT(22) -+#define RT3883_RSTCTRL_FE BIT(21) -+#define RT3883_RSTCTRL_WLAN BIT(20) -+#define RT3883_RSTCTRL_UART1 BIT(29) -+#define RT3883_RSTCTRL_SPI BIT(18) -+#define RT3883_RSTCTRL_I2S BIT(17) -+#define RT3883_RSTCTRL_I2C BIT(16) -+#define RT3883_RSTCTRL_NAND BIT(15) -+#define RT3883_RSTCTRL_DMA BIT(14) -+#define RT3883_RSTCTRL_PIO BIT(13) -+#define RT3883_RSTCTRL_UART BIT(12) -+#define RT3883_RSTCTRL_PCM BIT(11) -+#define RT3883_RSTCTRL_MC BIT(10) -+#define RT3883_RSTCTRL_INTC BIT(9) -+#define RT3883_RSTCTRL_TIMER BIT(8) -+#define RT3883_RSTCTRL_SYS BIT(0) -+ -+#define RT3883_INTC_INT_SYSCTL BIT(0) -+#define RT3883_INTC_INT_TIMER0 BIT(1) -+#define RT3883_INTC_INT_TIMER1 BIT(2) -+#define RT3883_INTC_INT_IA BIT(3) -+#define RT3883_INTC_INT_PCM BIT(4) -+#define RT3883_INTC_INT_UART0 BIT(5) -+#define RT3883_INTC_INT_PIO BIT(6) -+#define RT3883_INTC_INT_DMA BIT(7) -+#define RT3883_INTC_INT_NAND BIT(8) -+#define RT3883_INTC_INT_PERFC BIT(9) -+#define RT3883_INTC_INT_I2S BIT(10) -+#define RT3883_INTC_INT_UART1 BIT(12) -+#define RT3883_INTC_INT_UHST BIT(18) -+#define RT3883_INTC_INT_UDEV BIT(19) -+ -+/* FLASH/SRAM/Codec Controller registers */ -+#define RT3883_FSCC_REG_FLASH_CFG0 0x00 -+#define RT3883_FSCC_REG_FLASH_CFG1 0x04 -+#define RT3883_FSCC_REG_CODEC_CFG0 0x40 -+#define RT3883_FSCC_REG_CODEC_CFG1 0x44 -+ -+#define RT3883_FLASH_CFG_WIDTH_SHIFT 26 -+#define RT3883_FLASH_CFG_WIDTH_MASK 0x3 -+#define RT3883_FLASH_CFG_WIDTH_8BIT 0x0 -+#define RT3883_FLASH_CFG_WIDTH_16BIT 0x1 -+#define RT3883_FLASH_CFG_WIDTH_32BIT 0x2 -+ -+#endif /* _RT3883_REGS_H_ */ ---- a/arch/mips/ralink/Kconfig -+++ b/arch/mips/ralink/Kconfig -@@ -15,6 +15,11 @@ choice - select USB_ARCH_HAS_OHCI - select USB_ARCH_HAS_EHCI - -+ config SOC_RT3883 -+ bool "RT3883" -+ select USB_ARCH_HAS_OHCI -+ select USB_ARCH_HAS_EHCI -+ - endchoice - - choice ---- a/arch/mips/ralink/Makefile -+++ b/arch/mips/ralink/Makefile -@@ -10,6 +10,7 @@ obj-y := prom.o of.o reset.o clk.o irq.o - - obj-$(CONFIG_SOC_RT288X) += rt288x.o - obj-$(CONFIG_SOC_RT305X) += rt305x.o -+obj-$(CONFIG_SOC_RT3883) += rt3883.o - - obj-$(CONFIG_EARLY_PRINTK) += early_printk.o - ---- a/arch/mips/ralink/Platform -+++ b/arch/mips/ralink/Platform -@@ -13,3 +13,8 @@ load-$(CONFIG_SOC_RT288X) += 0xffffffff8 - # Ralink RT305x - # - load-$(CONFIG_SOC_RT305X) += 0xffffffff80000000 -+ -+# -+# Ralink RT3883 -+# -+load-$(CONFIG_SOC_RT3883) += 0xffffffff80000000 ---- /dev/null -+++ b/arch/mips/ralink/rt3883.c -@@ -0,0 +1,207 @@ -+/* -+ * 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 Imre Kaloz -+ * Copyright (C) 2008-2011 Gabor Juhos -+ * Copyright (C) 2013 John Crispin -+ */ -+ -+#include -+#include -+#include -+ -+#include -+#include -+#include -+ -+#include "common.h" -+ -+struct ralink_pinmux_grp mode_mux[] = { -+ { -+ .name = "i2c", -+ .mask = RT3883_GPIO_MODE_I2C, -+ .gpio_first = RT3883_GPIO_I2C_SD, -+ .gpio_last = RT3883_GPIO_I2C_SCLK, -+ }, { -+ .name = "spi", -+ .mask = RT3883_GPIO_MODE_SPI, -+ .gpio_first = RT3883_GPIO_SPI_CS0, -+ .gpio_last = RT3883_GPIO_SPI_MISO, -+ }, { -+ .name = "uartlite", -+ .mask = RT3883_GPIO_MODE_UART1, -+ .gpio_first = RT3883_GPIO_UART1_TXD, -+ .gpio_last = RT3883_GPIO_UART1_RXD, -+ }, { -+ .name = "jtag", -+ .mask = RT3883_GPIO_MODE_JTAG, -+ .gpio_first = RT3883_GPIO_JTAG_TDO, -+ .gpio_last = RT3883_GPIO_JTAG_TCLK, -+ }, { -+ .name = "mdio", -+ .mask = RT3883_GPIO_MODE_MDIO, -+ .gpio_first = RT3883_GPIO_MDIO_MDC, -+ .gpio_last = RT3883_GPIO_MDIO_MDIO, -+ }, { -+ .name = "ge1", -+ .mask = RT3883_GPIO_MODE_GE1, -+ .gpio_first = RT3883_GPIO_GE1_TXD0, -+ .gpio_last = RT3883_GPIO_GE1_RXCLK, -+ }, { -+ .name = "ge2", -+ .mask = RT3883_GPIO_MODE_GE2, -+ .gpio_first = RT3883_GPIO_GE2_TXD0, -+ .gpio_last = RT3883_GPIO_GE2_RXCLK, -+ }, { -+ .name = "pci", -+ .mask = RT3883_GPIO_MODE_PCI, -+ .gpio_first = RT3883_GPIO_PCI_AD0, -+ .gpio_last = RT3883_GPIO_PCI_AD31, -+ }, { -+ .name = "lna a", -+ .mask = RT3883_GPIO_MODE_LNA_A, -+ .gpio_first = RT3883_GPIO_LNA_PE_A0, -+ .gpio_last = RT3883_GPIO_LNA_PE_A2, -+ }, { -+ .name = "lna g", -+ .mask = RT3883_GPIO_MODE_LNA_G, -+ .gpio_first = RT3883_GPIO_LNA_PE_G0, -+ .gpio_last = RT3883_GPIO_LNA_PE_G2, -+ }, {0} -+}; -+ -+struct ralink_pinmux_grp uart_mux[] = { -+ { -+ .name = "uartf", -+ .mask = RT3883_GPIO_MODE_UARTF, -+ .gpio_first = RT3883_GPIO_7, -+ .gpio_last = RT3883_GPIO_14, -+ }, { -+ .name = "pcm uartf", -+ .mask = RT3883_GPIO_MODE_PCM_UARTF, -+ .gpio_first = RT3883_GPIO_7, -+ .gpio_last = RT3883_GPIO_14, -+ }, { -+ .name = "pcm i2s", -+ .mask = RT3883_GPIO_MODE_PCM_I2S, -+ .gpio_first = RT3883_GPIO_7, -+ .gpio_last = RT3883_GPIO_14, -+ }, { -+ .name = "i2s uartf", -+ .mask = RT3883_GPIO_MODE_I2S_UARTF, -+ .gpio_first = RT3883_GPIO_7, -+ .gpio_last = RT3883_GPIO_14, -+ }, { -+ .name = "pcm gpio", -+ .mask = RT3883_GPIO_MODE_PCM_GPIO, -+ .gpio_first = RT3883_GPIO_10, -+ .gpio_last = RT3883_GPIO_14, -+ }, { -+ .name = "gpio uartf", -+ .mask = RT3883_GPIO_MODE_GPIO_UARTF, -+ .gpio_first = RT3883_GPIO_7, -+ .gpio_last = RT3883_GPIO_14, -+ }, { -+ .name = "gpio i2s", -+ .mask = RT3883_GPIO_MODE_GPIO_I2S, -+ .gpio_first = RT3883_GPIO_7, -+ .gpio_last = RT3883_GPIO_14, -+ }, {0} -+}; -+ -+static void rt3883_wdt_reset(void) -+{ -+ u32 t; -+ -+ /* enable WDT reset output on GPIO 2 */ -+ t = rt_sysc_r32(RT3883_SYSC_REG_SYSCFG1); -+ t |= RT3883_SYSCFG1_GPIO2_AS_WDT_OUT; -+ rt_sysc_w32(t, RT3883_SYSC_REG_SYSCFG1); -+} -+ -+struct ralink_pinmux rt_pinmux = { -+ .mode = mode_mux, -+ .uart = uart_mux, -+ .uart_shift = RT3883_GPIO_MODE_UART0_SHIFT, -+ .uart_mask = RT3883_GPIO_MODE_GPIO, -+ .wdt_reset = rt3883_wdt_reset, -+}; -+ -+void __init ralink_clk_init(void) -+{ -+ unsigned long cpu_rate, sys_rate; -+ u32 syscfg0; -+ u32 clksel; -+ u32 ddr2; -+ -+ syscfg0 = rt_sysc_r32(RT3883_SYSC_REG_SYSCFG0); -+ clksel = ((syscfg0 >> RT3883_SYSCFG0_CPUCLK_SHIFT) & -+ RT3883_SYSCFG0_CPUCLK_MASK); -+ ddr2 = syscfg0 & RT3883_SYSCFG0_DRAM_TYPE_DDR2; -+ -+ switch (clksel) { -+ case RT3883_SYSCFG0_CPUCLK_250: -+ cpu_rate = 250000000; -+ sys_rate = (ddr2) ? 125000000 : 83000000; -+ break; -+ case RT3883_SYSCFG0_CPUCLK_384: -+ cpu_rate = 384000000; -+ sys_rate = (ddr2) ? 128000000 : 96000000; -+ break; -+ case RT3883_SYSCFG0_CPUCLK_480: -+ cpu_rate = 480000000; -+ sys_rate = (ddr2) ? 160000000 : 120000000; -+ break; -+ case RT3883_SYSCFG0_CPUCLK_500: -+ cpu_rate = 500000000; -+ sys_rate = (ddr2) ? 166000000 : 125000000; -+ break; -+ } -+ -+ ralink_clk_add("cpu", cpu_rate); -+ ralink_clk_add("10000100.timer", sys_rate); -+ ralink_clk_add("10000120.watchdog", sys_rate); -+ ralink_clk_add("10000500.uart", 40000000); -+ ralink_clk_add("10000b00.spi", sys_rate); -+ ralink_clk_add("10000c00.uartlite", 40000000); -+ ralink_clk_add("10100000.ethernet", sys_rate); -+} -+ -+void __init ralink_of_remap(void) -+{ -+ rt_sysc_membase = plat_of_remap_node("ralink,rt3883-sysc"); -+ rt_memc_membase = plat_of_remap_node("ralink,rt3883-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(RT3883_SYSC_BASE); -+ const char *name; -+ u32 n0; -+ u32 n1; -+ u32 id; -+ -+ n0 = __raw_readl(sysc + RT3883_SYSC_REG_CHIPID0_3); -+ n1 = __raw_readl(sysc + RT3883_SYSC_REG_CHIPID4_7); -+ id = __raw_readl(sysc + RT3883_SYSC_REG_REVID); -+ -+ if (n0 == RT3883_CHIP_NAME0 && n1 == RT3883_CHIP_NAME1) { -+ soc_info->compatible = "ralink,rt3883-soc"; -+ name = "RT3883"; -+ } else { -+ panic("rt3883: unknown SoC, n0:%08x n1:%08x", n0, n1); -+ } -+ -+ snprintf(soc_info->sys_type, RAMIPS_SYS_TYPE_LEN, -+ "Ralink %s ver:%u eco:%u", -+ name, -+ (id >> RT3883_REVID_VER_ID_SHIFT) & RT3883_REVID_VER_ID_MASK, -+ (id & RT3883_REVID_ECO_ID_MASK)); -+} diff --git a/target/linux/ramips/patches-3.8/0110-MIPS-add-rt3883-dts-files.patch b/target/linux/ramips/patches-3.8/0110-MIPS-add-rt3883-dts-files.patch deleted file mode 100644 index a99a1ec6a1..0000000000 --- a/target/linux/ramips/patches-3.8/0110-MIPS-add-rt3883-dts-files.patch +++ /dev/null @@ -1,282 +0,0 @@ -From 9d13fedc08f4e2cd9640983c2af8b9e9c64c094b Mon Sep 17 00:00:00 2001 -From: John Crispin -Date: Thu, 21 Mar 2013 18:37:00 +0100 -Subject: [PATCH 110/121] MIPS: add rt3883 dts files - -Add a dtsi file for RT3883 SoC. This SoC is almost the same as RT3050 but has -OHCI/EHCI in favour of the Synopsis DWC2 core. There is also a 3x3 802.11n -wifi core. - -Signed-off-by: John Crispin ---- - arch/mips/ralink/Kconfig | 4 + - arch/mips/ralink/dts/Makefile | 1 + - arch/mips/ralink/dts/rt3883.dtsi | 186 ++++++++++++++++++++++++++++++++++ - arch/mips/ralink/dts/rt3883_eval.dts | 52 ++++++++++ - 4 files changed, 243 insertions(+) - create mode 100644 arch/mips/ralink/dts/rt3883.dtsi - create mode 100644 arch/mips/ralink/dts/rt3883_eval.dts - ---- a/arch/mips/ralink/Kconfig -+++ b/arch/mips/ralink/Kconfig -@@ -39,6 +39,10 @@ choice - bool "RT305x eval kit" - depends on SOC_RT305X - -+ config DTB_RT3883_EVAL -+ bool "RT3883 eval kit" -+ depends on SOC_RT3883 -+ - endchoice - - endif ---- a/arch/mips/ralink/dts/Makefile -+++ b/arch/mips/ralink/dts/Makefile -@@ -1,2 +1,3 @@ - obj-$(CONFIG_DTB_RT2880_EVAL) := rt2880_eval.dtb.o - obj-$(CONFIG_DTB_RT305X_EVAL) := rt3052_eval.dtb.o -+obj-$(CONFIG_DTB_RT3883_EVAL) := rt3883_eval.dtb.o ---- /dev/null -+++ b/arch/mips/ralink/dts/rt3883.dtsi -@@ -0,0 +1,186 @@ -+/ { -+ #address-cells = <1>; -+ #size-cells = <1>; -+ compatible = "ralink,rt3883-soc"; -+ -+ cpus { -+ cpu@0 { -+ compatible = "mips,mips74Kc"; -+ }; -+ }; -+ -+ chosen { -+ bootargs = "console=ttyS0,57600 init=/init"; -+ }; -+ -+ cpuintc: cpuintc@0 { -+ #address-cells = <0>; -+ #interrupt-cells = <1>; -+ interrupt-controller; -+ compatible = "mti,cpu-interrupt-controller"; -+ }; -+ -+ palmbus@10000000 { -+ compatible = "palmbus"; -+ reg = <0x10000000 0x200000>; -+ ranges = <0x0 0x10000000 0x1FFFFF>; -+ -+ #address-cells = <1>; -+ #size-cells = <1>; -+ -+ sysc@0 { -+ compatible = "ralink,rt3883-sysc", "ralink,rt3050-sysc"; -+ reg = <0x0 0x100>; -+ }; -+ -+ timer@100 { -+ compatible = "ralink,rt3883-timer", "ralink,rt2880-timer"; -+ reg = <0x100 0x20>; -+ -+ interrupt-parent = <&intc>; -+ interrupts = <1>; -+ -+ status = "disabled"; -+ }; -+ -+ watchdog@120 { -+ compatible = "ralink,rt3883-wdt", "ralink,rt2880-wdt"; -+ reg = <0x120 0x10>; -+ }; -+ -+ intc: intc@200 { -+ compatible = "ralink,rt3883-intc", "ralink,rt2880-intc"; -+ reg = <0x200 0x100>; -+ -+ interrupt-controller; -+ #interrupt-cells = <1>; -+ -+ interrupt-parent = <&cpuintc>; -+ interrupts = <2>; -+ }; -+ -+ memc@300 { -+ compatible = "ralink,rt3883-memc", "ralink,rt3050-memc"; -+ reg = <0x300 0x100>; -+ }; -+ -+ gpio0: gpio@600 { -+ compatible = "ralink,rt3883-gpio", "ralink,rt2880-gpio"; -+ reg = <0x600 0x34>; -+ -+ gpio-controller; -+ #gpio-cells = <2>; -+ -+ ralink,num-gpios = <24>; -+ ralink,register-map = [ 00 04 08 0c -+ 20 24 28 2c -+ 30 34 ]; -+ -+ status = "disabled"; -+ }; -+ -+ gpio1: gpio@638 { -+ compatible = "ralink,rt3883-gpio", "ralink,rt2880-gpio"; -+ reg = <0x638 0x24>; -+ -+ gpio-controller; -+ #gpio-cells = <2>; -+ -+ ralink,num-gpios = <16>; -+ ralink,register-map = [ 00 04 08 0c -+ 10 14 18 1c -+ 20 24 ]; -+ -+ status = "disabled"; -+ }; -+ -+ gpio2: gpio@660 { -+ compatible = "ralink,rt3883-gpio", "ralink,rt2880-gpio"; -+ reg = <0x660 0x24>; -+ -+ gpio-controller; -+ #gpio-cells = <2>; -+ -+ ralink,num-gpios = <32>; -+ ralink,register-map = [ 00 04 08 0c -+ 10 14 18 1c -+ 20 24 ]; -+ -+ status = "disabled"; -+ }; -+ -+ gpio3: gpio@688 { -+ compatible = "ralink,rt3883-gpio", "ralink,rt2880-gpio"; -+ reg = <0x688 0x24>; -+ -+ gpio-controller; -+ #gpio-cells = <2>; -+ -+ ralink,num-gpios = <24>; -+ ralink,register-map = [ 00 04 08 0c -+ 10 14 18 1c -+ 20 24 ]; -+ -+ status = "disabled"; -+ }; -+ -+ spi@b00 { -+ compatible = "ralink,rt3883-spi", "ralink,rt2880-spi"; -+ reg = <0xb00 0x100>; -+ #address-cells = <1>; -+ #size-cells = <0>; -+ -+ status = "disabled"; -+ }; -+ -+ uartlite@c00 { -+ compatible = "ralink,rt3883-uart", "ralink,rt2880-uart", "ns16550a"; -+ reg = <0xc00 0x100>; -+ -+ interrupt-parent = <&intc>; -+ interrupts = <12>; -+ -+ reg-shift = <2>; -+ }; -+ }; -+ -+ ethernet@10100000 { -+ compatible = "ralink,rt3883-eth"; -+ reg = <0x10100000 10000>; -+ -+ interrupt-parent = <&cpuintc>; -+ interrupts = <5>; -+ -+ status = "disabled"; -+ }; -+ -+ wmac@10180000 { -+ compatible = "ralink,rt3883-wmac", "ralink,rt2880-wmac"; -+ reg = <0x10180000 40000>; -+ -+ interrupt-parent = <&cpuintc>; -+ interrupts = <6>; -+ -+ status = "disabled"; -+ }; -+ -+ ehci@101c0000 { -+ compatible = "ralink,rt3883-ehci", "ehci-platform"; -+ reg = <0x101c0000 0x1000>; -+ -+ interrupt-parent = <&intc>; -+ interrupts = <18>; -+ -+ status = "disabled"; -+ }; -+ -+ ohci@101c1000 { -+ compatible = "ralink,rt3883-ohci", "ohci-platform"; -+ reg = <0x101c1000 0x1000>; -+ -+ interrupt-parent = <&intc>; -+ interrupts = <18>; -+ -+ status = "disabled"; -+ }; -+}; ---- /dev/null -+++ b/arch/mips/ralink/dts/rt3883_eval.dts -@@ -0,0 +1,52 @@ -+/dts-v1/; -+ -+/include/ "rt3883.dtsi" -+ -+/ { -+ #address-cells = <1>; -+ #size-cells = <1>; -+ compatible = "ralink,rt3883-eval-board", "ralink,rt3883-soc"; -+ model = "Ralink RT3883 evaluation board"; -+ -+ memory@0 { -+ reg = <0x0 0x4000000>; -+ }; -+ -+ palmbus@10000000 { -+ sysc@0 { -+ ralink,pinmux = "uartlite", "spi"; -+ ralink,uartmux = "gpio"; -+ ralink,wdtmux = <0>; -+ }; -+ }; -+ -+ cfi@1f000000 { -+ compatible = "cfi-flash"; -+ reg = <0x1f000000 0x800000>; -+ -+ bank-width = <2>; -+ device-width = <2>; -+ #address-cells = <1>; -+ #size-cells = <1>; -+ -+ partition@0 { -+ label = "uboot"; -+ reg = <0x0 0x30000>; -+ read-only; -+ }; -+ partition@30000 { -+ label = "uboot-env"; -+ reg = <0x30000 0x10000>; -+ read-only; -+ }; -+ partition@40000 { -+ label = "calibration"; -+ reg = <0x40000 0x10000>; -+ read-only; -+ }; -+ partition@50000 { -+ label = "linux"; -+ reg = <0x50000 0x7b0000>; -+ }; -+ }; -+}; diff --git a/target/linux/ramips/patches-3.8/0110-MIPS-ralink-add-uart-mask-to-struct-ralink_pinmux.patch b/target/linux/ramips/patches-3.8/0110-MIPS-ralink-add-uart-mask-to-struct-ralink_pinmux.patch new file mode 100644 index 0000000000..d4474e1022 --- /dev/null +++ b/target/linux/ramips/patches-3.8/0110-MIPS-ralink-add-uart-mask-to-struct-ralink_pinmux.patch @@ -0,0 +1,49 @@ +From faf5989efed503b2ee689dad82bb2d60da718d99 Mon Sep 17 00:00:00 2001 +From: John Crispin +Date: Fri, 12 Apr 2013 12:45:27 +0200 +Subject: [PATCH 110/137] MIPS: ralink: add uart mask to struct ralink_pinmux + +Add a field for the uart muxing mask and set it inside the rt305x setup code. + +Signed-off-by: John Crispin +Patchwork: http://patchwork.linux-mips.org/patch/5744/ +--- + arch/mips/ralink/common.h | 1 + + arch/mips/ralink/rt305x.c | 5 +++-- + 2 files changed, 4 insertions(+), 2 deletions(-) + +--- a/arch/mips/ralink/common.h ++++ b/arch/mips/ralink/common.h +@@ -22,6 +22,7 @@ struct ralink_pinmux { + struct ralink_pinmux_grp *mode; + struct ralink_pinmux_grp *uart; + int uart_shift; ++ u32 uart_mask; + void (*wdt_reset)(void); + struct ralink_pinmux_grp *pci; + int pci_shift; +--- a/arch/mips/ralink/rt305x.c ++++ b/arch/mips/ralink/rt305x.c +@@ -91,12 +91,12 @@ static struct ralink_pinmux_grp uart_mux + .name = "gpio uartf", + .mask = RT305X_GPIO_MODE_GPIO_UARTF, + .gpio_first = RT305X_GPIO_7, +- .gpio_last = RT305X_GPIO_14, ++ .gpio_last = RT305X_GPIO_10, + }, { + .name = "gpio i2s", + .mask = RT305X_GPIO_MODE_GPIO_I2S, + .gpio_first = RT305X_GPIO_7, +- .gpio_last = RT305X_GPIO_14, ++ .gpio_last = RT305X_GPIO_10, + }, { + .name = "gpio", + .mask = RT305X_GPIO_MODE_GPIO, +@@ -118,6 +118,7 @@ struct ralink_pinmux rt_gpio_pinmux = { + .mode = mode_mux, + .uart = uart_mux, + .uart_shift = RT305X_GPIO_MODE_UART0_SHIFT, ++ .uart_mask = RT305X_GPIO_MODE_UART0_MASK, + .wdt_reset = rt305x_wdt_reset, + }; + diff --git a/target/linux/ramips/patches-3.8/0111-MIPS-ralink-adds-support-for-MT7620-SoC-family.patch b/target/linux/ramips/patches-3.8/0111-MIPS-ralink-adds-support-for-MT7620-SoC-family.patch deleted file mode 100644 index 948d78c3b5..0000000000 --- a/target/linux/ramips/patches-3.8/0111-MIPS-ralink-adds-support-for-MT7620-SoC-family.patch +++ /dev/null @@ -1,340 +0,0 @@ -From 8831277e0167cdcf3dc3ecc5d5a67d4fd9d0ed77 Mon Sep 17 00:00:00 2001 -From: John Crispin -Date: Thu, 21 Mar 2013 17:49:02 +0100 -Subject: [PATCH 111/121] MIPS: ralink: adds support for MT7620 SoC family - -Add support code for mt7620 SOC. - -The code detects the SoC and registers the clk / pinmux settings. - -Signed-off-by: John Crispin ---- - arch/mips/include/asm/mach-ralink/mt7620.h | 66 +++++++++ - arch/mips/ralink/Kconfig | 3 + - arch/mips/ralink/Makefile | 1 + - arch/mips/ralink/Platform | 5 + - arch/mips/ralink/mt7620.c | 215 ++++++++++++++++++++++++++++ - 5 files changed, 290 insertions(+) - create mode 100644 arch/mips/include/asm/mach-ralink/mt7620.h - create mode 100644 arch/mips/ralink/mt7620.c - ---- /dev/null -+++ b/arch/mips/include/asm/mach-ralink/mt7620.h -@@ -0,0 +1,66 @@ -+/* -+ * 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 -+ * Copyright (C) 2008 Imre Kaloz -+ * Copyright (C) 2013 John Crispin -+ */ -+ -+#ifndef _MT7620_REGS_H_ -+#define _MT7620_REGS_H_ -+ -+#define MT7620_SYSC_BASE 0x10000000 -+ -+#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 SYSC_REG_CPLL_CONFIG0 0x54 -+#define SYSC_REG_CPLL_CONFIG1 0x58 -+ -+#define MT7620N_CHIP_NAME0 0x33365452 -+#define MT7620N_CHIP_NAME1 0x20203235 -+ -+#define MT7620A_CHIP_NAME0 0x3637544d -+#define MT7620A_CHIP_NAME1 0x20203032 -+ -+#define 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 MT7620_CPLL_SW_CONFIG_SHIFT 31 -+#define MT7620_CPLL_SW_CONFIG_MASK 0x1 -+#define MT7620_CPLL_CPU_CLK_SHIFT 24 -+#define MT7620_CPLL_CPU_CLK_MASK 0x1 -+ -+#define MT7620_GPIO_MODE_I2C BIT(0) -+#define MT7620_GPIO_MODE_UART0_SHIFT 2 -+#define MT7620_GPIO_MODE_UART0_MASK 0x7 -+#define MT7620_GPIO_MODE_UART0(x) ((x) << MT7620_GPIO_MODE_UART0_SHIFT) -+#define MT7620_GPIO_MODE_UARTF 0x0 -+#define MT7620_GPIO_MODE_PCM_UARTF 0x1 -+#define MT7620_GPIO_MODE_PCM_I2S 0x2 -+#define MT7620_GPIO_MODE_I2S_UARTF 0x3 -+#define MT7620_GPIO_MODE_PCM_GPIO 0x4 -+#define MT7620_GPIO_MODE_GPIO_UARTF 0x5 -+#define MT7620_GPIO_MODE_GPIO_I2S 0x6 -+#define MT7620_GPIO_MODE_GPIO 0x7 -+#define MT7620_GPIO_MODE_UART1 BIT(5) -+#define MT7620_GPIO_MODE_MDIO BIT(8) -+#define MT7620_GPIO_MODE_RGMII1 BIT(9) -+#define MT7620_GPIO_MODE_RGMII2 BIT(10) -+#define MT7620_GPIO_MODE_SPI BIT(11) -+#define MT7620_GPIO_MODE_SPI_REF_CLK BIT(12) -+#define MT7620_GPIO_MODE_WLED BIT(13) -+#define MT7620_GPIO_MODE_JTAG BIT(15) -+#define MT7620_GPIO_MODE_EPHY BIT(15) -+#define MT7620_GPIO_MODE_WDT BIT(22) -+ -+#endif ---- a/arch/mips/ralink/Kconfig -+++ b/arch/mips/ralink/Kconfig -@@ -20,6 +20,9 @@ choice - select USB_ARCH_HAS_OHCI - select USB_ARCH_HAS_EHCI - -+ config SOC_MT7620 -+ bool "MT7620" -+ - endchoice - - choice ---- a/arch/mips/ralink/Makefile -+++ b/arch/mips/ralink/Makefile -@@ -11,6 +11,7 @@ obj-y := prom.o of.o reset.o clk.o irq.o - obj-$(CONFIG_SOC_RT288X) += rt288x.o - obj-$(CONFIG_SOC_RT305X) += rt305x.o - obj-$(CONFIG_SOC_RT3883) += rt3883.o -+obj-$(CONFIG_SOC_MT7620) += mt7620.o - - obj-$(CONFIG_EARLY_PRINTK) += early_printk.o - ---- a/arch/mips/ralink/Platform -+++ b/arch/mips/ralink/Platform -@@ -18,3 +18,8 @@ load-$(CONFIG_SOC_RT305X) += 0xffffffff8 - # Ralink RT3883 - # - load-$(CONFIG_SOC_RT3883) += 0xffffffff80000000 -+ -+# -+# Ralink MT7620 -+# -+load-$(CONFIG_SOC_MT7620) += 0xffffffff80000000 ---- /dev/null -+++ b/arch/mips/ralink/mt7620.c -@@ -0,0 +1,215 @@ -+/* -+ * 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 -+ * Copyright (C) 2008 Imre Kaloz -+ * Copyright (C) 2013 John Crispin -+ */ -+ -+#include -+#include -+#include -+ -+#include -+#include -+#include -+ -+#include "common.h" -+ -+ -+struct ralink_pinmux_grp mode_mux[] = { -+ { -+ .name = "i2c", -+ .mask = MT7620_GPIO_MODE_I2C, -+ .gpio_first = 1, -+ .gpio_last = 2, -+ }, { -+ .name = "spi", -+ .mask = MT7620_GPIO_MODE_SPI, -+ .gpio_first = 3, -+ .gpio_last = 6, -+ }, { -+ .name = "uartlite", -+ .mask = MT7620_GPIO_MODE_UART1, -+ .gpio_first = 15, -+ .gpio_last = 16, -+ }, { -+ .name = "wdt", -+ .mask = MT7620_GPIO_MODE_WDT, -+ .gpio_first = 17, -+ .gpio_last = 17, -+ }, { -+ .name = "mdio", -+ .mask = MT7620_GPIO_MODE_MDIO, -+ .gpio_first = 22, -+ .gpio_last = 23, -+ }, { -+ .name = "rgmii1", -+ .mask = MT7620_GPIO_MODE_RGMII1, -+ .gpio_first = 24, -+ .gpio_last = 35, -+ }, { -+ .name = "spi refclk", -+ .mask = MT7620_GPIO_MODE_SPI_REF_CLK, -+ .gpio_first = 37, -+ .gpio_last = 39, -+ }, { -+ .name = "jtag", -+ .mask = MT7620_GPIO_MODE_JTAG, -+ .gpio_first = 40, -+ .gpio_last = 44, -+ }, { -+ /* shared lines with jtag */ -+ .name = "ephy", -+ .mask = MT7620_GPIO_MODE_EPHY, -+ .gpio_first = 40, -+ .gpio_last = 44, -+ }, { -+ .name = "nand", -+ .mask = MT7620_GPIO_MODE_JTAG, -+ .gpio_first = 45, -+ .gpio_last = 59, -+ }, { -+ .name = "rgmii2", -+ .mask = MT7620_GPIO_MODE_RGMII2, -+ .gpio_first = 60, -+ .gpio_last = 71, -+ }, { -+ .name = "wled", -+ .mask = MT7620_GPIO_MODE_WLED, -+ .gpio_first = 72, -+ .gpio_last = 72, -+ }, {0} -+}; -+ -+ -+struct ralink_pinmux_grp uart_mux[] = { -+ { -+ .name = "uartf", -+ .mask = MT7620_GPIO_MODE_UARTF, -+ .gpio_first = 7, -+ .gpio_last = 14, -+ }, { -+ .name = "pcm uartf", -+ .mask = MT7620_GPIO_MODE_PCM_UARTF, -+ .gpio_first = 7, -+ .gpio_last = 14, -+ }, { -+ .name = "pcm i2s", -+ .mask = MT7620_GPIO_MODE_PCM_I2S, -+ .gpio_first = 7, -+ .gpio_last = 14, -+ }, { -+ .name = "i2s uartf", -+ .mask = MT7620_GPIO_MODE_I2S_UARTF, -+ .gpio_first = 7, -+ .gpio_last = 14, -+ }, { -+ .name = "pcm gpio", -+ .mask = MT7620_GPIO_MODE_PCM_GPIO, -+ .gpio_first = 11, -+ .gpio_last = 14, -+ }, { -+ .name = "gpio uartf", -+ .mask = MT7620_GPIO_MODE_GPIO_UARTF, -+ .gpio_first = 7, -+ .gpio_last = 10, -+ }, { -+ .name = "gpio i2s", -+ .mask = MT7620_GPIO_MODE_GPIO_I2S, -+ .gpio_first = 7, -+ .gpio_last = 10, -+ }, { -+ .name = "gpio", -+ .mask = MT7620_GPIO_MODE_GPIO, -+ }, {0} -+}; -+/* -+void rt305x_wdt_reset(void) -+{ -+ u32 t; -+ -+ t = rt_sysc_r32(SYSC_REG_SYSTEM_CONFIG); -+ t |= RT305X_SYSCFG_SRAM_CS0_MODE_WDT << -+ RT305X_SYSCFG_SRAM_CS0_MODE_SHIFT; -+ rt_sysc_w32(t, SYSC_REG_SYSTEM_CONFIG); -+} -+*/ -+struct ralink_pinmux rt_pinmux = { -+ .mode = mode_mux, -+ .uart = uart_mux, -+ .uart_shift = MT7620_GPIO_MODE_UART0_SHIFT, -+// .wdt_reset = rt305x_wdt_reset, -+}; -+ -+void __init ralink_clk_init(void) -+{ -+ unsigned long cpu_rate, sys_rate; -+ u32 c0 = rt_sysc_r32(SYSC_REG_CPLL_CONFIG0); -+ u32 c1 = rt_sysc_r32(SYSC_REG_CPLL_CONFIG1); -+ -+ c0 = (c0 >> MT7620_CPLL_SW_CONFIG_SHIFT) & -+ MT7620_CPLL_SW_CONFIG_MASK; -+ c1 = (c1 >> MT7620_CPLL_CPU_CLK_SHIFT) & -+ MT7620_CPLL_CPU_CLK_MASK; -+ if (c1 == 0x01) { -+ cpu_rate = 480000000; -+ } else { -+ if (c1 == 0x0) { -+ cpu_rate = 600000000; -+ } else { -+ /* TODO calculate custom clock from pll settings */ -+ BUG(); -+ } -+ } -+ /* FIXME SDR - 4, DDR - 3 */ -+ sys_rate = cpu_rate / 4; -+ -+ ralink_clk_add("cpu", cpu_rate); -+ ralink_clk_add("10000100.timer", 40000000); -+ ralink_clk_add("10000500.uart", 40000000); -+ ralink_clk_add("10000c00.uartlite", 40000000); -+} -+ -+void __init ralink_of_remap(void) -+{ -+ rt_sysc_membase = plat_of_remap_node("ralink,mt7620-sysc"); -+ rt_memc_membase = plat_of_remap_node("ralink,mt7620-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(MT7620_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 == MT7620N_CHIP_NAME0 && n1 == MT7620N_CHIP_NAME1) { -+ name = "MT7620N"; -+ soc_info->compatible = "ralink,mt7620n-soc"; -+ } else if (n0 == MT7620A_CHIP_NAME0 && n1 == MT7620A_CHIP_NAME1) { -+ name = "MT7620A"; -+ soc_info->compatible = "ralink,mt7620a-soc"; -+ } else { -+ printk("mt7620: 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, -+ "Ralink %s ver:%u eco:%u", -+ name, -+ (rev >> CHIP_REV_VER_SHIFT) & CHIP_REV_VER_MASK, -+ (rev & CHIP_REV_ECO_MASK)); -+} diff --git a/target/linux/ramips/patches-3.8/0111-MIPS-ralink-adds-support-for-RT2880-SoC-family.patch b/target/linux/ramips/patches-3.8/0111-MIPS-ralink-adds-support-for-RT2880-SoC-family.patch new file mode 100644 index 0000000000..9cfa509e54 --- /dev/null +++ b/target/linux/ramips/patches-3.8/0111-MIPS-ralink-adds-support-for-RT2880-SoC-family.patch @@ -0,0 +1,264 @@ +From cccb9a7b42227a442ca42d590c838c8b6fa0eba1 Mon Sep 17 00:00:00 2001 +From: John Crispin +Date: Sun, 27 Jan 2013 09:17:20 +0100 +Subject: [PATCH 111/137] MIPS: ralink: adds support for RT2880 SoC family + +Add support code for rt2880 SOC. + +The code detects the SoC and registers the clk / pinmux settings. + +Signed-off-by: John Crispin +Signed-off-by: Gabor Juhos +Patchwork: http://patchwork.linux-mips.org/patch/5176/ +--- + arch/mips/Kconfig | 2 +- + arch/mips/include/asm/mach-ralink/rt288x.h | 49 ++++++++++ + arch/mips/ralink/Kconfig | 3 + + arch/mips/ralink/Makefile | 1 + + arch/mips/ralink/Platform | 5 + + arch/mips/ralink/rt288x.c | 139 ++++++++++++++++++++++++++++ + 6 files changed, 198 insertions(+), 1 deletion(-) + create mode 100644 arch/mips/include/asm/mach-ralink/rt288x.h + create mode 100644 arch/mips/ralink/rt288x.c + +--- a/arch/mips/Kconfig ++++ b/arch/mips/Kconfig +@@ -1189,7 +1189,7 @@ config BOOT_ELF32 + + config MIPS_L1_CACHE_SHIFT + int +- default "4" if MACH_DECSTATION || MIKROTIK_RB532 || PMC_MSP4200_EVAL ++ default "4" if MACH_DECSTATION || MIKROTIK_RB532 || PMC_MSP4200_EVAL || SOC_RT288X + default "6" if MIPS_CPU_SCACHE + default "7" if SGI_IP22 || SGI_IP27 || SGI_IP28 || SNI_RM || CPU_CAVIUM_OCTEON + default "5" +--- /dev/null ++++ b/arch/mips/include/asm/mach-ralink/rt288x.h +@@ -0,0 +1,49 @@ ++/* ++ * 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 ++ * Copyright (C) 2008 Imre Kaloz ++ * Copyright (C) 2013 John Crispin ++ */ ++ ++#ifndef _RT288X_REGS_H_ ++#define _RT288X_REGS_H_ ++ ++#define RT2880_SYSC_BASE 0x00300000 ++ ++#define SYSC_REG_CHIP_NAME0 0x00 ++#define SYSC_REG_CHIP_NAME1 0x04 ++#define SYSC_REG_CHIP_ID 0x0c ++#define SYSC_REG_SYSTEM_CONFIG 0x10 ++#define SYSC_REG_CLKCFG 0x30 ++ ++#define RT2880_CHIP_NAME0 0x38325452 ++#define RT2880_CHIP_NAME1 0x20203038 ++ ++#define CHIP_ID_ID_MASK 0xff ++#define CHIP_ID_ID_SHIFT 8 ++#define CHIP_ID_REV_MASK 0xff ++ ++#define SYSTEM_CONFIG_CPUCLK_SHIFT 20 ++#define SYSTEM_CONFIG_CPUCLK_MASK 0x3 ++#define SYSTEM_CONFIG_CPUCLK_250 0x0 ++#define SYSTEM_CONFIG_CPUCLK_266 0x1 ++#define SYSTEM_CONFIG_CPUCLK_280 0x2 ++#define SYSTEM_CONFIG_CPUCLK_300 0x3 ++ ++#define RT2880_GPIO_MODE_I2C BIT(0) ++#define RT2880_GPIO_MODE_UART0 BIT(1) ++#define RT2880_GPIO_MODE_SPI BIT(2) ++#define RT2880_GPIO_MODE_UART1 BIT(3) ++#define RT2880_GPIO_MODE_JTAG BIT(4) ++#define RT2880_GPIO_MODE_MDIO BIT(5) ++#define RT2880_GPIO_MODE_SDRAM BIT(6) ++#define RT2880_GPIO_MODE_PCI BIT(7) ++ ++#define CLKCFG_SRAM_CS_N_WDT BIT(9) ++ ++#endif +--- a/arch/mips/ralink/Kconfig ++++ b/arch/mips/ralink/Kconfig +@@ -6,6 +6,9 @@ choice + help + Select Ralink MIPS SoC type. + ++ config SOC_RT288X ++ bool "RT288x" ++ + config SOC_RT305X + bool "RT305x" + select USB_ARCH_HAS_HCD +--- a/arch/mips/ralink/Makefile ++++ b/arch/mips/ralink/Makefile +@@ -8,6 +8,7 @@ + + obj-y := prom.o of.o reset.o clk.o irq.o + ++obj-$(CONFIG_SOC_RT288X) += rt288x.o + obj-$(CONFIG_SOC_RT305X) += rt305x.o + + obj-$(CONFIG_EARLY_PRINTK) += early_printk.o +--- a/arch/mips/ralink/Platform ++++ b/arch/mips/ralink/Platform +@@ -5,6 +5,11 @@ core-$(CONFIG_RALINK) += arch/mips/rali + cflags-$(CONFIG_RALINK) += -I$(srctree)/arch/mips/include/asm/mach-ralink + + # ++# Ralink RT288x ++# ++load-$(CONFIG_SOC_RT288X) += 0xffffffff88000000 ++ ++# + # Ralink RT305x + # + load-$(CONFIG_SOC_RT305X) += 0xffffffff80000000 +--- /dev/null ++++ b/arch/mips/ralink/rt288x.c +@@ -0,0 +1,139 @@ ++/* ++ * 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 ++ * Copyright (C) 2008 Imre Kaloz ++ * Copyright (C) 2013 John Crispin ++ */ ++ ++#include ++#include ++#include ++ ++#include ++#include ++#include ++ ++#include "common.h" ++ ++static struct ralink_pinmux_grp mode_mux[] = { ++ { ++ .name = "i2c", ++ .mask = RT2880_GPIO_MODE_I2C, ++ .gpio_first = 1, ++ .gpio_last = 2, ++ }, { ++ .name = "spi", ++ .mask = RT2880_GPIO_MODE_SPI, ++ .gpio_first = 3, ++ .gpio_last = 6, ++ }, { ++ .name = "uartlite", ++ .mask = RT2880_GPIO_MODE_UART0, ++ .gpio_first = 7, ++ .gpio_last = 14, ++ }, { ++ .name = "jtag", ++ .mask = RT2880_GPIO_MODE_JTAG, ++ .gpio_first = 17, ++ .gpio_last = 21, ++ }, { ++ .name = "mdio", ++ .mask = RT2880_GPIO_MODE_MDIO, ++ .gpio_first = 22, ++ .gpio_last = 23, ++ }, { ++ .name = "sdram", ++ .mask = RT2880_GPIO_MODE_SDRAM, ++ .gpio_first = 24, ++ .gpio_last = 39, ++ }, { ++ .name = "pci", ++ .mask = RT2880_GPIO_MODE_PCI, ++ .gpio_first = 40, ++ .gpio_last = 71, ++ }, {0} ++}; ++ ++static void rt288x_wdt_reset(void) ++{ ++ u32 t; ++ ++ /* enable WDT reset output on pin SRAM_CS_N */ ++ t = rt_sysc_r32(SYSC_REG_CLKCFG); ++ t |= CLKCFG_SRAM_CS_N_WDT; ++ rt_sysc_w32(t, SYSC_REG_CLKCFG); ++} ++ ++struct ralink_pinmux rt_gpio_pinmux = { ++ .mode = mode_mux, ++ .wdt_reset = rt288x_wdt_reset, ++}; ++ ++void __init ralink_clk_init(void) ++{ ++ unsigned long cpu_rate; ++ u32 t = rt_sysc_r32(SYSC_REG_SYSTEM_CONFIG); ++ t = ((t >> SYSTEM_CONFIG_CPUCLK_SHIFT) & SYSTEM_CONFIG_CPUCLK_MASK); ++ ++ switch (t) { ++ case SYSTEM_CONFIG_CPUCLK_250: ++ cpu_rate = 250000000; ++ break; ++ case SYSTEM_CONFIG_CPUCLK_266: ++ cpu_rate = 266666667; ++ break; ++ case SYSTEM_CONFIG_CPUCLK_280: ++ cpu_rate = 280000000; ++ break; ++ case SYSTEM_CONFIG_CPUCLK_300: ++ cpu_rate = 300000000; ++ break; ++ } ++ ++ ralink_clk_add("cpu", cpu_rate); ++ ralink_clk_add("300100.timer", cpu_rate / 2); ++ ralink_clk_add("300120.watchdog", cpu_rate / 2); ++ ralink_clk_add("300500.uart", cpu_rate / 2); ++ ralink_clk_add("300c00.uartlite", cpu_rate / 2); ++ ralink_clk_add("400000.ethernet", cpu_rate / 2); ++} ++ ++void __init ralink_of_remap(void) ++{ ++ rt_sysc_membase = plat_of_remap_node("ralink,rt2880-sysc"); ++ rt_memc_membase = plat_of_remap_node("ralink,rt2880-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(RT2880_SYSC_BASE); ++ const char *name; ++ u32 n0; ++ u32 n1; ++ u32 id; ++ ++ n0 = __raw_readl(sysc + SYSC_REG_CHIP_NAME0); ++ n1 = __raw_readl(sysc + SYSC_REG_CHIP_NAME1); ++ id = __raw_readl(sysc + SYSC_REG_CHIP_ID); ++ ++ if (n0 == RT2880_CHIP_NAME0 && n1 == RT2880_CHIP_NAME1) { ++ soc_info->compatible = "ralink,r2880-soc"; ++ name = "RT2880"; ++ } else { ++ panic("rt288x: unknown SoC, n0:%08x n1:%08x", n0, n1); ++ } ++ ++ snprintf(soc_info->sys_type, RAMIPS_SYS_TYPE_LEN, ++ "Ralink %s id:%u rev:%u", ++ name, ++ (id >> CHIP_ID_ID_SHIFT) & CHIP_ID_ID_MASK, ++ (id & CHIP_ID_REV_MASK)); ++} diff --git a/target/linux/ramips/patches-3.8/0112-MIPS-add-MT7620-dts-files.patch b/target/linux/ramips/patches-3.8/0112-MIPS-add-MT7620-dts-files.patch deleted file mode 100644 index 3ed8efc9a3..0000000000 --- a/target/linux/ramips/patches-3.8/0112-MIPS-add-MT7620-dts-files.patch +++ /dev/null @@ -1,204 +0,0 @@ -From 9c83b58b49f88a48565fad6acea921a0ae222856 Mon Sep 17 00:00:00 2001 -From: John Crispin -Date: Thu, 21 Mar 2013 17:50:05 +0100 -Subject: [PATCH 112/121] MIPS: add MT7620 dts files - -Adds the dtsi file for MT7620 SoC. This is the latest and greatest SoC shipped -by Mediatek. - -Signed-off-by: John Crispin ---- - arch/mips/ralink/Kconfig | 4 + - arch/mips/ralink/dts/Makefile | 1 + - arch/mips/ralink/dts/mt7620.dtsi | 138 ++++++++++++++++++++++++++++++++++ - arch/mips/ralink/dts/mt7620_eval.dts | 22 ++++++ - 4 files changed, 165 insertions(+) - create mode 100644 arch/mips/ralink/dts/mt7620.dtsi - create mode 100644 arch/mips/ralink/dts/mt7620_eval.dts - ---- a/arch/mips/ralink/Kconfig -+++ b/arch/mips/ralink/Kconfig -@@ -46,6 +46,10 @@ choice - bool "RT3883 eval kit" - depends on SOC_RT3883 - -+ config DTB_MT7620_EVAL -+ bool "MT7620 eval kit" -+ depends on SOC_MT7620 -+ - endchoice - - endif ---- a/arch/mips/ralink/dts/Makefile -+++ b/arch/mips/ralink/dts/Makefile -@@ -1,3 +1,4 @@ - obj-$(CONFIG_DTB_RT2880_EVAL) := rt2880_eval.dtb.o - obj-$(CONFIG_DTB_RT305X_EVAL) := rt3052_eval.dtb.o - obj-$(CONFIG_DTB_RT3883_EVAL) := rt3883_eval.dtb.o -+obj-$(CONFIG_DTB_MT7620_EVAL) := mt7620_eval.dtb.o ---- /dev/null -+++ b/arch/mips/ralink/dts/mt7620.dtsi -@@ -0,0 +1,138 @@ -+/ { -+ #address-cells = <1>; -+ #size-cells = <1>; -+ compatible = "ralink,mtk7620n-soc", "ralink,mt7620-soc"; -+ -+ cpus { -+ cpu@0 { -+ compatible = "mips,mips24KEc"; -+ }; -+ }; -+ -+ chosen { -+ bootargs = "console=ttyS0,57600 init=/init"; -+ }; -+ -+ cpuintc: cpuintc@0 { -+ #address-cells = <0>; -+ #interrupt-cells = <1>; -+ interrupt-controller; -+ compatible = "mti,cpu-interrupt-controller"; -+ }; -+ -+ palmbus@10000000 { -+ compatible = "palmbus"; -+ reg = <0x10000000 0x200000>; -+ ranges = <0x0 0x10000000 0x1FFFFF>; -+ -+ #address-cells = <1>; -+ #size-cells = <1>; -+ -+ sysc@0 { -+ compatible = "ralink,mt7620-sysc", "ralink,mt7620n-sysc"; -+ reg = <0x0 0x100>; -+ }; -+ -+ timer@100 { -+ compatible = "ralink,mt7620-timer", "ralink,rt2880-timer"; -+ reg = <0x100 0x20>; -+ -+ interrupt-parent = <&intc>; -+ interrupts = <1>; -+ -+ status = "disabled"; -+ }; -+ -+ watchdog@120 { -+ compatible = "ralink,mt7620-wdt", "ralink,rt2880-wdt"; -+ reg = <0x120 0x10>; -+ }; -+ -+ intc: intc@200 { -+ compatible = "ralink,mt7620-intc", "ralink,rt2880-intc"; -+ reg = <0x200 0x100>; -+ -+ interrupt-controller; -+ #interrupt-cells = <1>; -+ -+ interrupt-parent = <&cpuintc>; -+ interrupts = <2>; -+ }; -+ -+ memc@300 { -+ compatible = "ralink,mt7620-memc", "ralink,rt3050-memc"; -+ reg = <0x300 0x100>; -+ }; -+ -+ gpio0: gpio@600 { -+ compatible = "ralink,mt7620-gpio", "ralink,rt2880-gpio"; -+ reg = <0x600 0x34>; -+ -+ gpio-controller; -+ #gpio-cells = <2>; -+ -+ ralink,num-gpios = <24>; -+ ralink,register-map = [ 00 04 08 0c -+ 20 24 28 2c -+ 30 34 ]; -+ }; -+ -+ gpio1: gpio@638 { -+ compatible = "ralink,mt7620-gpio", "ralink,rt2880-gpio"; -+ reg = <0x638 0x24>; -+ -+ gpio-controller; -+ #gpio-cells = <2>; -+ -+ ralink,num-gpios = <16>; -+ ralink,register-map = [ 00 04 08 0c -+ 10 14 18 1c -+ 20 24 ]; -+ }; -+ -+ gpio2: gpio@660 { -+ compatible = "ralink,mt7620-gpio", "ralink,rt2880-gpio"; -+ reg = <0x660 0x24>; -+ -+ gpio-controller; -+ #gpio-cells = <2>; -+ -+ ralink,num-gpios = <32>; -+ ralink,register-map = [ 00 04 08 0c -+ 10 14 18 1c -+ 20 24 ]; -+ }; -+ -+ gpio3: gpio@688 { -+ compatible = "ralink,mt7620-gpio", "ralink,rt2880-gpio"; -+ reg = <0x688 0x24>; -+ -+ gpio-controller; -+ #gpio-cells = <2>; -+ -+ ralink,num-gpios = <1>; -+ ralink,register-map = [ 00 04 08 0c -+ 10 14 18 1c -+ 20 24 ]; -+ }; -+ -+ spi@b00 { -+ compatible = "ralink,rt3883-spi", "ralink,rt2880-spi"; -+ reg = <0xb00 0x100>; -+ #address-cells = <1>; -+ #size-cells = <0>; -+ -+ status = "disabled"; -+ }; -+ -+ uartlite@c00 { -+ compatible = "ralink,mt7620-uart", "ralink,rt2880-uart", "ns16550a"; -+ reg = <0xc00 0x100>; -+ -+ interrupt-parent = <&intc>; -+ interrupts = <12>; -+ -+ reg-shift = <2>; -+ }; -+ }; -+}; ---- /dev/null -+++ b/arch/mips/ralink/dts/mt7620_eval.dts -@@ -0,0 +1,22 @@ -+/dts-v1/; -+ -+/include/ "mt7620.dtsi" -+ -+/ { -+ #address-cells = <1>; -+ #size-cells = <1>; -+ compatible = "ralink,mt7620a-eval-board", "ralink,mt7620a-soc"; -+ model = "Ralink MT7620 evaluation board"; -+ -+ memory@0 { -+ reg = <0x0 0x4000000>; -+ }; -+ -+ palmbus@10000000 { -+ sysc@0 { -+ ralink,pinmux = "uartlite", "spi"; -+ ralink,uartmux = "gpio"; -+ ralink,wdtmux = <0>; -+ }; -+ }; -+}; diff --git a/target/linux/ramips/patches-3.8/0112-MIPS-ralink-adds-support-for-RT3883-SoC-family.patch b/target/linux/ramips/patches-3.8/0112-MIPS-ralink-adds-support-for-RT3883-SoC-family.patch new file mode 100644 index 0000000000..f744e62248 --- /dev/null +++ b/target/linux/ramips/patches-3.8/0112-MIPS-ralink-adds-support-for-RT3883-SoC-family.patch @@ -0,0 +1,552 @@ +From 5eb4dfe5072595e0706de3364f2da45378dbaca6 Mon Sep 17 00:00:00 2001 +From: John Crispin +Date: Sun, 27 Jan 2013 09:39:02 +0100 +Subject: [PATCH 112/137] MIPS: ralink: adds support for RT3883 SoC family + +Add support code for rt3883 SOC. + +The code detects the SoC and registers the clk / pinmux settings. + +Signed-off-by: John Crispin +Signed-off-by: Gabor Juhos +Patchwork: http://patchwork.linux-mips.org/patch/5185/ +--- + arch/mips/include/asm/mach-ralink/rt3883.h | 247 ++++++++++++++++++++++++++++ + arch/mips/ralink/Kconfig | 5 + + arch/mips/ralink/Makefile | 1 + + arch/mips/ralink/Platform | 5 + + arch/mips/ralink/rt3883.c | 242 +++++++++++++++++++++++++++ + 5 files changed, 500 insertions(+) + create mode 100644 arch/mips/include/asm/mach-ralink/rt3883.h + create mode 100644 arch/mips/ralink/rt3883.c + +--- /dev/null ++++ b/arch/mips/include/asm/mach-ralink/rt3883.h +@@ -0,0 +1,247 @@ ++/* ++ * Ralink RT3662/RT3883 SoC register definitions ++ * ++ * Copyright (C) 2011-2012 Gabor Juhos ++ * ++ * This program is free software; you can redistribute it and/or modify it ++ * under the terms of the GNU General Public License version 2 as published ++ * by the Free Software Foundation. ++ */ ++ ++#ifndef _RT3883_REGS_H_ ++#define _RT3883_REGS_H_ ++ ++#include ++ ++#define RT3883_SDRAM_BASE 0x00000000 ++#define RT3883_SYSC_BASE 0x10000000 ++#define RT3883_TIMER_BASE 0x10000100 ++#define RT3883_INTC_BASE 0x10000200 ++#define RT3883_MEMC_BASE 0x10000300 ++#define RT3883_UART0_BASE 0x10000500 ++#define RT3883_PIO_BASE 0x10000600 ++#define RT3883_FSCC_BASE 0x10000700 ++#define RT3883_NANDC_BASE 0x10000810 ++#define RT3883_I2C_BASE 0x10000900 ++#define RT3883_I2S_BASE 0x10000a00 ++#define RT3883_SPI_BASE 0x10000b00 ++#define RT3883_UART1_BASE 0x10000c00 ++#define RT3883_PCM_BASE 0x10002000 ++#define RT3883_GDMA_BASE 0x10002800 ++#define RT3883_CODEC1_BASE 0x10003000 ++#define RT3883_CODEC2_BASE 0x10003800 ++#define RT3883_FE_BASE 0x10100000 ++#define RT3883_ROM_BASE 0x10118000 ++#define RT3883_USBDEV_BASE 0x10112000 ++#define RT3883_PCI_BASE 0x10140000 ++#define RT3883_WLAN_BASE 0x10180000 ++#define RT3883_USBHOST_BASE 0x101c0000 ++#define RT3883_BOOT_BASE 0x1c000000 ++#define RT3883_SRAM_BASE 0x1e000000 ++#define RT3883_PCIMEM_BASE 0x20000000 ++ ++#define RT3883_EHCI_BASE (RT3883_USBHOST_BASE) ++#define RT3883_OHCI_BASE (RT3883_USBHOST_BASE + 0x1000) ++ ++#define RT3883_SYSC_SIZE 0x100 ++#define RT3883_TIMER_SIZE 0x100 ++#define RT3883_INTC_SIZE 0x100 ++#define RT3883_MEMC_SIZE 0x100 ++#define RT3883_UART0_SIZE 0x100 ++#define RT3883_UART1_SIZE 0x100 ++#define RT3883_PIO_SIZE 0x100 ++#define RT3883_FSCC_SIZE 0x100 ++#define RT3883_NANDC_SIZE 0x0f0 ++#define RT3883_I2C_SIZE 0x100 ++#define RT3883_I2S_SIZE 0x100 ++#define RT3883_SPI_SIZE 0x100 ++#define RT3883_PCM_SIZE 0x800 ++#define RT3883_GDMA_SIZE 0x800 ++#define RT3883_CODEC1_SIZE 0x800 ++#define RT3883_CODEC2_SIZE 0x800 ++#define RT3883_FE_SIZE 0x10000 ++#define RT3883_ROM_SIZE 0x4000 ++#define RT3883_USBDEV_SIZE 0x4000 ++#define RT3883_PCI_SIZE 0x40000 ++#define RT3883_WLAN_SIZE 0x40000 ++#define RT3883_USBHOST_SIZE 0x40000 ++#define RT3883_BOOT_SIZE (32 * 1024 * 1024) ++#define RT3883_SRAM_SIZE (32 * 1024 * 1024) ++ ++/* SYSC registers */ ++#define RT3883_SYSC_REG_CHIPID0_3 0x00 /* Chip ID 0 */ ++#define RT3883_SYSC_REG_CHIPID4_7 0x04 /* Chip ID 1 */ ++#define RT3883_SYSC_REG_REVID 0x0c /* Chip Revision Identification */ ++#define RT3883_SYSC_REG_SYSCFG0 0x10 /* System Configuration 0 */ ++#define RT3883_SYSC_REG_SYSCFG1 0x14 /* System Configuration 1 */ ++#define RT3883_SYSC_REG_CLKCFG0 0x2c /* Clock Configuration 0 */ ++#define RT3883_SYSC_REG_CLKCFG1 0x30 /* Clock Configuration 1 */ ++#define RT3883_SYSC_REG_RSTCTRL 0x34 /* Reset Control*/ ++#define RT3883_SYSC_REG_RSTSTAT 0x38 /* Reset Status*/ ++#define RT3883_SYSC_REG_USB_PS 0x5c /* USB Power saving control */ ++#define RT3883_SYSC_REG_GPIO_MODE 0x60 /* GPIO Purpose Select */ ++#define RT3883_SYSC_REG_PCIE_CLK_GEN0 0x7c ++#define RT3883_SYSC_REG_PCIE_CLK_GEN1 0x80 ++#define RT3883_SYSC_REG_PCIE_CLK_GEN2 0x84 ++#define RT3883_SYSC_REG_PMU 0x88 ++#define RT3883_SYSC_REG_PMU1 0x8c ++ ++#define RT3883_CHIP_NAME0 0x38335452 ++#define RT3883_CHIP_NAME1 0x20203338 ++ ++#define RT3883_REVID_VER_ID_MASK 0x0f ++#define RT3883_REVID_VER_ID_SHIFT 8 ++#define RT3883_REVID_ECO_ID_MASK 0x0f ++ ++#define RT3883_SYSCFG0_DRAM_TYPE_DDR2 BIT(17) ++#define RT3883_SYSCFG0_CPUCLK_SHIFT 8 ++#define RT3883_SYSCFG0_CPUCLK_MASK 0x3 ++#define RT3883_SYSCFG0_CPUCLK_250 0x0 ++#define RT3883_SYSCFG0_CPUCLK_384 0x1 ++#define RT3883_SYSCFG0_CPUCLK_480 0x2 ++#define RT3883_SYSCFG0_CPUCLK_500 0x3 ++ ++#define RT3883_SYSCFG1_USB0_HOST_MODE BIT(10) ++#define RT3883_SYSCFG1_PCIE_RC_MODE BIT(8) ++#define RT3883_SYSCFG1_PCI_HOST_MODE BIT(7) ++#define RT3883_SYSCFG1_PCI_66M_MODE BIT(6) ++#define RT3883_SYSCFG1_GPIO2_AS_WDT_OUT BIT(2) ++ ++#define RT3883_CLKCFG1_PCIE_CLK_EN BIT(21) ++#define RT3883_CLKCFG1_UPHY1_CLK_EN BIT(20) ++#define RT3883_CLKCFG1_PCI_CLK_EN BIT(19) ++#define RT3883_CLKCFG1_UPHY0_CLK_EN BIT(18) ++ ++#define RT3883_GPIO_MODE_I2C BIT(0) ++#define RT3883_GPIO_MODE_SPI BIT(1) ++#define RT3883_GPIO_MODE_UART0_SHIFT 2 ++#define RT3883_GPIO_MODE_UART0_MASK 0x7 ++#define RT3883_GPIO_MODE_UART0(x) ((x) << RT3883_GPIO_MODE_UART0_SHIFT) ++#define RT3883_GPIO_MODE_UARTF 0x0 ++#define RT3883_GPIO_MODE_PCM_UARTF 0x1 ++#define RT3883_GPIO_MODE_PCM_I2S 0x2 ++#define RT3883_GPIO_MODE_I2S_UARTF 0x3 ++#define RT3883_GPIO_MODE_PCM_GPIO 0x4 ++#define RT3883_GPIO_MODE_GPIO_UARTF 0x5 ++#define RT3883_GPIO_MODE_GPIO_I2S 0x6 ++#define RT3883_GPIO_MODE_GPIO 0x7 ++#define RT3883_GPIO_MODE_UART1 BIT(5) ++#define RT3883_GPIO_MODE_JTAG BIT(6) ++#define RT3883_GPIO_MODE_MDIO BIT(7) ++#define RT3883_GPIO_MODE_GE1 BIT(9) ++#define RT3883_GPIO_MODE_GE2 BIT(10) ++#define RT3883_GPIO_MODE_PCI_SHIFT 11 ++#define RT3883_GPIO_MODE_PCI_MASK 0x7 ++#define RT3883_GPIO_MODE_PCI (RT3883_GPIO_MODE_PCI_MASK << RT3883_GPIO_MODE_PCI_SHIFT) ++#define RT3883_GPIO_MODE_LNA_A_SHIFT 16 ++#define RT3883_GPIO_MODE_LNA_A_MASK 0x3 ++#define _RT3883_GPIO_MODE_LNA_A(_x) ((_x) << RT3883_GPIO_MODE_LNA_A_SHIFT) ++#define RT3883_GPIO_MODE_LNA_A_GPIO 0x3 ++#define RT3883_GPIO_MODE_LNA_A _RT3883_GPIO_MODE_LNA_A(RT3883_GPIO_MODE_LNA_A_MASK) ++#define RT3883_GPIO_MODE_LNA_G_SHIFT 18 ++#define RT3883_GPIO_MODE_LNA_G_MASK 0x3 ++#define _RT3883_GPIO_MODE_LNA_G(_x) ((_x) << RT3883_GPIO_MODE_LNA_G_SHIFT) ++#define RT3883_GPIO_MODE_LNA_G_GPIO 0x3 ++#define RT3883_GPIO_MODE_LNA_G _RT3883_GPIO_MODE_LNA_G(RT3883_GPIO_MODE_LNA_G_MASK) ++ ++#define RT3883_GPIO_I2C_SD 1 ++#define RT3883_GPIO_I2C_SCLK 2 ++#define RT3883_GPIO_SPI_CS0 3 ++#define RT3883_GPIO_SPI_CLK 4 ++#define RT3883_GPIO_SPI_MOSI 5 ++#define RT3883_GPIO_SPI_MISO 6 ++#define RT3883_GPIO_7 7 ++#define RT3883_GPIO_10 10 ++#define RT3883_GPIO_14 14 ++#define RT3883_GPIO_UART1_TXD 15 ++#define RT3883_GPIO_UART1_RXD 16 ++#define RT3883_GPIO_JTAG_TDO 17 ++#define RT3883_GPIO_JTAG_TDI 18 ++#define RT3883_GPIO_JTAG_TMS 19 ++#define RT3883_GPIO_JTAG_TCLK 20 ++#define RT3883_GPIO_JTAG_TRST_N 21 ++#define RT3883_GPIO_MDIO_MDC 22 ++#define RT3883_GPIO_MDIO_MDIO 23 ++#define RT3883_GPIO_LNA_PE_A0 32 ++#define RT3883_GPIO_LNA_PE_A1 33 ++#define RT3883_GPIO_LNA_PE_A2 34 ++#define RT3883_GPIO_LNA_PE_G0 35 ++#define RT3883_GPIO_LNA_PE_G1 36 ++#define RT3883_GPIO_LNA_PE_G2 37 ++#define RT3883_GPIO_PCI_AD0 40 ++#define RT3883_GPIO_PCI_AD31 71 ++#define RT3883_GPIO_GE2_TXD0 72 ++#define RT3883_GPIO_GE2_TXD1 73 ++#define RT3883_GPIO_GE2_TXD2 74 ++#define RT3883_GPIO_GE2_TXD3 75 ++#define RT3883_GPIO_GE2_TXEN 76 ++#define RT3883_GPIO_GE2_TXCLK 77 ++#define RT3883_GPIO_GE2_RXD0 78 ++#define RT3883_GPIO_GE2_RXD1 79 ++#define RT3883_GPIO_GE2_RXD2 80 ++#define RT3883_GPIO_GE2_RXD3 81 ++#define RT3883_GPIO_GE2_RXDV 82 ++#define RT3883_GPIO_GE2_RXCLK 83 ++#define RT3883_GPIO_GE1_TXD0 84 ++#define RT3883_GPIO_GE1_TXD1 85 ++#define RT3883_GPIO_GE1_TXD2 86 ++#define RT3883_GPIO_GE1_TXD3 87 ++#define RT3883_GPIO_GE1_TXEN 88 ++#define RT3883_GPIO_GE1_TXCLK 89 ++#define RT3883_GPIO_GE1_RXD0 90 ++#define RT3883_GPIO_GE1_RXD1 91 ++#define RT3883_GPIO_GE1_RXD2 92 ++#define RT3883_GPIO_GE1_RXD3 93 ++#define RT3883_GPIO_GE1_RXDV 94 ++#define RT3883_GPIO_GE1_RXCLK 95 ++ ++#define RT3883_RSTCTRL_PCIE_PCI_PDM BIT(27) ++#define RT3883_RSTCTRL_FLASH BIT(26) ++#define RT3883_RSTCTRL_UDEV BIT(25) ++#define RT3883_RSTCTRL_PCI BIT(24) ++#define RT3883_RSTCTRL_PCIE BIT(23) ++#define RT3883_RSTCTRL_UHST BIT(22) ++#define RT3883_RSTCTRL_FE BIT(21) ++#define RT3883_RSTCTRL_WLAN BIT(20) ++#define RT3883_RSTCTRL_UART1 BIT(29) ++#define RT3883_RSTCTRL_SPI BIT(18) ++#define RT3883_RSTCTRL_I2S BIT(17) ++#define RT3883_RSTCTRL_I2C BIT(16) ++#define RT3883_RSTCTRL_NAND BIT(15) ++#define RT3883_RSTCTRL_DMA BIT(14) ++#define RT3883_RSTCTRL_PIO BIT(13) ++#define RT3883_RSTCTRL_UART BIT(12) ++#define RT3883_RSTCTRL_PCM BIT(11) ++#define RT3883_RSTCTRL_MC BIT(10) ++#define RT3883_RSTCTRL_INTC BIT(9) ++#define RT3883_RSTCTRL_TIMER BIT(8) ++#define RT3883_RSTCTRL_SYS BIT(0) ++ ++#define RT3883_INTC_INT_SYSCTL BIT(0) ++#define RT3883_INTC_INT_TIMER0 BIT(1) ++#define RT3883_INTC_INT_TIMER1 BIT(2) ++#define RT3883_INTC_INT_IA BIT(3) ++#define RT3883_INTC_INT_PCM BIT(4) ++#define RT3883_INTC_INT_UART0 BIT(5) ++#define RT3883_INTC_INT_PIO BIT(6) ++#define RT3883_INTC_INT_DMA BIT(7) ++#define RT3883_INTC_INT_NAND BIT(8) ++#define RT3883_INTC_INT_PERFC BIT(9) ++#define RT3883_INTC_INT_I2S BIT(10) ++#define RT3883_INTC_INT_UART1 BIT(12) ++#define RT3883_INTC_INT_UHST BIT(18) ++#define RT3883_INTC_INT_UDEV BIT(19) ++ ++/* FLASH/SRAM/Codec Controller registers */ ++#define RT3883_FSCC_REG_FLASH_CFG0 0x00 ++#define RT3883_FSCC_REG_FLASH_CFG1 0x04 ++#define RT3883_FSCC_REG_CODEC_CFG0 0x40 ++#define RT3883_FSCC_REG_CODEC_CFG1 0x44 ++ ++#define RT3883_FLASH_CFG_WIDTH_SHIFT 26 ++#define RT3883_FLASH_CFG_WIDTH_MASK 0x3 ++#define RT3883_FLASH_CFG_WIDTH_8BIT 0x0 ++#define RT3883_FLASH_CFG_WIDTH_16BIT 0x1 ++#define RT3883_FLASH_CFG_WIDTH_32BIT 0x2 ++ ++#endif /* _RT3883_REGS_H_ */ +--- a/arch/mips/ralink/Kconfig ++++ b/arch/mips/ralink/Kconfig +@@ -15,6 +15,11 @@ choice + select USB_ARCH_HAS_OHCI + select USB_ARCH_HAS_EHCI + ++ config SOC_RT3883 ++ bool "RT3883" ++ select USB_ARCH_HAS_OHCI ++ select USB_ARCH_HAS_EHCI ++ + endchoice + + choice +--- a/arch/mips/ralink/Makefile ++++ b/arch/mips/ralink/Makefile +@@ -10,6 +10,7 @@ obj-y := prom.o of.o reset.o clk.o irq.o + + obj-$(CONFIG_SOC_RT288X) += rt288x.o + obj-$(CONFIG_SOC_RT305X) += rt305x.o ++obj-$(CONFIG_SOC_RT3883) += rt3883.o + + obj-$(CONFIG_EARLY_PRINTK) += early_printk.o + +--- a/arch/mips/ralink/Platform ++++ b/arch/mips/ralink/Platform +@@ -13,3 +13,8 @@ load-$(CONFIG_SOC_RT288X) += 0xffffffff8 + # Ralink RT305x + # + load-$(CONFIG_SOC_RT305X) += 0xffffffff80000000 ++ ++# ++# Ralink RT3883 ++# ++load-$(CONFIG_SOC_RT3883) += 0xffffffff80000000 +--- /dev/null ++++ b/arch/mips/ralink/rt3883.c +@@ -0,0 +1,242 @@ ++/* ++ * 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 Imre Kaloz ++ * Copyright (C) 2008-2011 Gabor Juhos ++ * Copyright (C) 2013 John Crispin ++ */ ++ ++#include ++#include ++#include ++ ++#include ++#include ++#include ++ ++#include "common.h" ++ ++static struct ralink_pinmux_grp mode_mux[] = { ++ { ++ .name = "i2c", ++ .mask = RT3883_GPIO_MODE_I2C, ++ .gpio_first = RT3883_GPIO_I2C_SD, ++ .gpio_last = RT3883_GPIO_I2C_SCLK, ++ }, { ++ .name = "spi", ++ .mask = RT3883_GPIO_MODE_SPI, ++ .gpio_first = RT3883_GPIO_SPI_CS0, ++ .gpio_last = RT3883_GPIO_SPI_MISO, ++ }, { ++ .name = "uartlite", ++ .mask = RT3883_GPIO_MODE_UART1, ++ .gpio_first = RT3883_GPIO_UART1_TXD, ++ .gpio_last = RT3883_GPIO_UART1_RXD, ++ }, { ++ .name = "jtag", ++ .mask = RT3883_GPIO_MODE_JTAG, ++ .gpio_first = RT3883_GPIO_JTAG_TDO, ++ .gpio_last = RT3883_GPIO_JTAG_TCLK, ++ }, { ++ .name = "mdio", ++ .mask = RT3883_GPIO_MODE_MDIO, ++ .gpio_first = RT3883_GPIO_MDIO_MDC, ++ .gpio_last = RT3883_GPIO_MDIO_MDIO, ++ }, { ++ .name = "ge1", ++ .mask = RT3883_GPIO_MODE_GE1, ++ .gpio_first = RT3883_GPIO_GE1_TXD0, ++ .gpio_last = RT3883_GPIO_GE1_RXCLK, ++ }, { ++ .name = "ge2", ++ .mask = RT3883_GPIO_MODE_GE2, ++ .gpio_first = RT3883_GPIO_GE2_TXD0, ++ .gpio_last = RT3883_GPIO_GE2_RXCLK, ++ }, { ++ .name = "pci", ++ .mask = RT3883_GPIO_MODE_PCI, ++ .gpio_first = RT3883_GPIO_PCI_AD0, ++ .gpio_last = RT3883_GPIO_PCI_AD31, ++ }, { ++ .name = "lna a", ++ .mask = RT3883_GPIO_MODE_LNA_A, ++ .gpio_first = RT3883_GPIO_LNA_PE_A0, ++ .gpio_last = RT3883_GPIO_LNA_PE_A2, ++ }, { ++ .name = "lna g", ++ .mask = RT3883_GPIO_MODE_LNA_G, ++ .gpio_first = RT3883_GPIO_LNA_PE_G0, ++ .gpio_last = RT3883_GPIO_LNA_PE_G2, ++ }, {0} ++}; ++ ++static struct ralink_pinmux_grp uart_mux[] = { ++ { ++ .name = "uartf", ++ .mask = RT3883_GPIO_MODE_UARTF, ++ .gpio_first = RT3883_GPIO_7, ++ .gpio_last = RT3883_GPIO_14, ++ }, { ++ .name = "pcm uartf", ++ .mask = RT3883_GPIO_MODE_PCM_UARTF, ++ .gpio_first = RT3883_GPIO_7, ++ .gpio_last = RT3883_GPIO_14, ++ }, { ++ .name = "pcm i2s", ++ .mask = RT3883_GPIO_MODE_PCM_I2S, ++ .gpio_first = RT3883_GPIO_7, ++ .gpio_last = RT3883_GPIO_14, ++ }, { ++ .name = "i2s uartf", ++ .mask = RT3883_GPIO_MODE_I2S_UARTF, ++ .gpio_first = RT3883_GPIO_7, ++ .gpio_last = RT3883_GPIO_14, ++ }, { ++ .name = "pcm gpio", ++ .mask = RT3883_GPIO_MODE_PCM_GPIO, ++ .gpio_first = RT3883_GPIO_11, ++ .gpio_last = RT3883_GPIO_14, ++ }, { ++ .name = "gpio uartf", ++ .mask = RT3883_GPIO_MODE_GPIO_UARTF, ++ .gpio_first = RT3883_GPIO_7, ++ .gpio_last = RT3883_GPIO_10, ++ }, { ++ .name = "gpio i2s", ++ .mask = RT3883_GPIO_MODE_GPIO_I2S, ++ .gpio_first = RT3883_GPIO_7, ++ .gpio_last = RT3883_GPIO_10, ++ }, { ++ .name = "gpio", ++ .mask = RT3883_GPIO_MODE_GPIO, ++ }, {0} ++}; ++ ++static struct ralink_pinmux_grp pci_mux[] = { ++ { ++ .name = "pci-dev", ++ .mask = 0, ++ .gpio_first = RT3883_GPIO_PCI_AD0, ++ .gpio_last = RT3883_GPIO_PCI_AD31, ++ }, { ++ .name = "pci-host2", ++ .mask = 1, ++ .gpio_first = RT3883_GPIO_PCI_AD0, ++ .gpio_last = RT3883_GPIO_PCI_AD31, ++ }, { ++ .name = "pci-host1", ++ .mask = 2, ++ .gpio_first = RT3883_GPIO_PCI_AD0, ++ .gpio_last = RT3883_GPIO_PCI_AD31, ++ }, { ++ .name = "pci-fnc", ++ .mask = 3, ++ .gpio_first = RT3883_GPIO_PCI_AD0, ++ .gpio_last = RT3883_GPIO_PCI_AD31, ++ }, { ++ .name = "pci-gpio", ++ .mask = 7, ++ .gpio_first = RT3883_GPIO_PCI_AD0, ++ .gpio_last = RT3883_GPIO_PCI_AD31, ++ }, {0} ++}; ++ ++static void rt3883_wdt_reset(void) ++{ ++ u32 t; ++ ++ /* enable WDT reset output on GPIO 2 */ ++ t = rt_sysc_r32(RT3883_SYSC_REG_SYSCFG1); ++ t |= RT3883_SYSCFG1_GPIO2_AS_WDT_OUT; ++ rt_sysc_w32(t, RT3883_SYSC_REG_SYSCFG1); ++} ++ ++struct ralink_pinmux rt_gpio_pinmux = { ++ .mode = mode_mux, ++ .uart = uart_mux, ++ .uart_shift = RT3883_GPIO_MODE_UART0_SHIFT, ++ .uart_mask = RT3883_GPIO_MODE_GPIO, ++ .wdt_reset = rt3883_wdt_reset, ++ .pci = pci_mux, ++ .pci_shift = RT3883_GPIO_MODE_PCI_SHIFT, ++ .pci_mask = RT3883_GPIO_MODE_PCI_MASK, ++}; ++ ++void __init ralink_clk_init(void) ++{ ++ unsigned long cpu_rate, sys_rate; ++ u32 syscfg0; ++ u32 clksel; ++ u32 ddr2; ++ ++ syscfg0 = rt_sysc_r32(RT3883_SYSC_REG_SYSCFG0); ++ clksel = ((syscfg0 >> RT3883_SYSCFG0_CPUCLK_SHIFT) & ++ RT3883_SYSCFG0_CPUCLK_MASK); ++ ddr2 = syscfg0 & RT3883_SYSCFG0_DRAM_TYPE_DDR2; ++ ++ switch (clksel) { ++ case RT3883_SYSCFG0_CPUCLK_250: ++ cpu_rate = 250000000; ++ sys_rate = (ddr2) ? 125000000 : 83000000; ++ break; ++ case RT3883_SYSCFG0_CPUCLK_384: ++ cpu_rate = 384000000; ++ sys_rate = (ddr2) ? 128000000 : 96000000; ++ break; ++ case RT3883_SYSCFG0_CPUCLK_480: ++ cpu_rate = 480000000; ++ sys_rate = (ddr2) ? 160000000 : 120000000; ++ break; ++ case RT3883_SYSCFG0_CPUCLK_500: ++ cpu_rate = 500000000; ++ sys_rate = (ddr2) ? 166000000 : 125000000; ++ break; ++ } ++ ++ ralink_clk_add("cpu", cpu_rate); ++ ralink_clk_add("10000100.timer", sys_rate); ++ ralink_clk_add("10000120.watchdog", sys_rate); ++ ralink_clk_add("10000500.uart", 40000000); ++ ralink_clk_add("10000b00.spi", sys_rate); ++ ralink_clk_add("10000c00.uartlite", 40000000); ++ ralink_clk_add("10100000.ethernet", sys_rate); ++} ++ ++void __init ralink_of_remap(void) ++{ ++ rt_sysc_membase = plat_of_remap_node("ralink,rt3883-sysc"); ++ rt_memc_membase = plat_of_remap_node("ralink,rt3883-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(RT3883_SYSC_BASE); ++ const char *name; ++ u32 n0; ++ u32 n1; ++ u32 id; ++ ++ n0 = __raw_readl(sysc + RT3883_SYSC_REG_CHIPID0_3); ++ n1 = __raw_readl(sysc + RT3883_SYSC_REG_CHIPID4_7); ++ id = __raw_readl(sysc + RT3883_SYSC_REG_REVID); ++ ++ if (n0 == RT3883_CHIP_NAME0 && n1 == RT3883_CHIP_NAME1) { ++ soc_info->compatible = "ralink,rt3883-soc"; ++ name = "RT3883"; ++ } else { ++ panic("rt3883: unknown SoC, n0:%08x n1:%08x", n0, n1); ++ } ++ ++ snprintf(soc_info->sys_type, RAMIPS_SYS_TYPE_LEN, ++ "Ralink %s ver:%u eco:%u", ++ name, ++ (id >> RT3883_REVID_VER_ID_SHIFT) & RT3883_REVID_VER_ID_MASK, ++ (id & RT3883_REVID_ECO_ID_MASK)); ++} diff --git a/target/linux/ramips/patches-3.8/0113-MIPS-ralink-add-support-for-periodic-timer-irq.patch b/target/linux/ramips/patches-3.8/0113-MIPS-ralink-add-support-for-periodic-timer-irq.patch deleted file mode 100644 index 128a606e64..0000000000 --- a/target/linux/ramips/patches-3.8/0113-MIPS-ralink-add-support-for-periodic-timer-irq.patch +++ /dev/null @@ -1,220 +0,0 @@ -From cdbc5a9dbd78a771edb6c211edbc677596cbd17f Mon Sep 17 00:00:00 2001 -From: John Crispin -Date: Sat, 23 Mar 2013 19:44:41 +0100 -Subject: [PATCH 113/121] MIPS: ralink: add support for periodic timer irq - -Adds a driver for the periodic timer found on Ralink SoC. - -Signed-off-by: John Crispin ---- - arch/mips/ralink/Makefile | 2 +- - arch/mips/ralink/timer.c | 192 +++++++++++++++++++++++++++++++++++++++++++++ - 2 files changed, 193 insertions(+), 1 deletion(-) - create mode 100644 arch/mips/ralink/timer.c - ---- a/arch/mips/ralink/Makefile -+++ b/arch/mips/ralink/Makefile -@@ -6,7 +6,7 @@ - # Copyright (C) 2009-2011 Gabor Juhos - # Copyright (C) 2013 John Crispin - --obj-y := prom.o of.o reset.o clk.o irq.o pinmux.o -+obj-y := prom.o of.o reset.o clk.o irq.o pinmux.o timer.o - - obj-$(CONFIG_SOC_RT288X) += rt288x.o - obj-$(CONFIG_SOC_RT305X) += rt305x.o ---- /dev/null -+++ b/arch/mips/ralink/timer.c -@@ -0,0 +1,192 @@ -+/* -+ * This program is free software; you can redistribute it and/or modify it -+ * under the terms of the GNU General Public License version 2 as published -+ * by the Free Software Foundation. -+ * -+ * Copyright (C) 2013 John Crispin -+*/ -+ -+#include -+#include -+#include -+#include -+#include -+#include -+ -+#include -+ -+#define TIMER_REG_TMRSTAT 0x00 -+#define TIMER_REG_TMR0LOAD 0x10 -+#define TIMER_REG_TMR0CTL 0x18 -+ -+#define TMRSTAT_TMR0INT BIT(0) -+ -+#define TMR0CTL_ENABLE BIT(7) -+#define TMR0CTL_MODE_PERIODIC BIT(4) -+#define TMR0CTL_PRESCALER 1 -+#define TMR0CTL_PRESCALE_VAL (0xf - TMR0CTL_PRESCALER) -+#define TMR0CTL_PRESCALE_DIV (65536 / BIT(TMR0CTL_PRESCALER)) -+ -+struct rt_timer { -+ struct device *dev; -+ void __iomem *membase; -+ int irq; -+ unsigned long timer_freq; -+ unsigned long timer_div; -+}; -+ -+static inline void rt_timer_w32(struct rt_timer *rt, u8 reg, u32 val) -+{ -+ __raw_writel(val, rt->membase + reg); -+} -+ -+static inline u32 rt_timer_r32(struct rt_timer *rt, u8 reg) -+{ -+ return __raw_readl(rt->membase + reg); -+} -+ -+static irqreturn_t rt_timer_irq(int irq, void *_rt) -+{ -+ struct rt_timer *rt = (struct rt_timer *) _rt; -+ -+ rt_timer_w32(rt, TIMER_REG_TMR0LOAD, rt->timer_freq / rt->timer_div); -+ rt_timer_w32(rt, TIMER_REG_TMRSTAT, TMRSTAT_TMR0INT); -+ -+ return IRQ_HANDLED; -+} -+ -+ -+static int rt_timer_request(struct rt_timer *rt) -+{ -+ int err = request_irq(rt->irq, rt_timer_irq, IRQF_DISABLED, -+ dev_name(rt->dev), rt); -+ if (err) { -+ dev_err(rt->dev, "failed to request irq\n"); -+ } else { -+ u32 t = TMR0CTL_MODE_PERIODIC | TMR0CTL_PRESCALE_VAL; -+ rt_timer_w32(rt, TIMER_REG_TMR0CTL, t); -+ } -+ return err; -+} -+ -+static void rt_timer_free(struct rt_timer *rt) -+{ -+ free_irq(rt->irq, rt); -+} -+ -+static int rt_timer_config(struct rt_timer *rt, unsigned long divisor) -+{ -+ if (rt->timer_freq < divisor) -+ rt->timer_div = rt->timer_freq; -+ else -+ rt->timer_div = divisor; -+ -+ rt_timer_w32(rt, TIMER_REG_TMR0LOAD, rt->timer_freq / rt->timer_div); -+ -+ return 0; -+} -+ -+static int rt_timer_enable(struct rt_timer *rt) -+{ -+ u32 t; -+ -+ rt_timer_w32(rt, TIMER_REG_TMR0LOAD, rt->timer_freq / rt->timer_div); -+ -+ t = rt_timer_r32(rt, TIMER_REG_TMR0CTL); -+ t |= TMR0CTL_ENABLE; -+ rt_timer_w32(rt, TIMER_REG_TMR0CTL, t); -+ -+ return 0; -+} -+ -+static void rt_timer_disable(struct rt_timer *rt) -+{ -+ u32 t; -+ -+ t = rt_timer_r32(rt, TIMER_REG_TMR0CTL); -+ t &= ~TMR0CTL_ENABLE; -+ rt_timer_w32(rt, TIMER_REG_TMR0CTL, t); -+} -+ -+static int rt_timer_probe(struct platform_device *pdev) -+{ -+ struct resource *res = platform_get_resource(pdev, IORESOURCE_MEM, 0); -+ struct rt_timer *rt; -+ struct clk *clk; -+ -+ if (!res) { -+ dev_err(&pdev->dev, "no memory resource found\n"); -+ return -EINVAL; -+ } -+ -+ rt = devm_kzalloc(&pdev->dev, sizeof(*rt), GFP_KERNEL); -+ if (!rt) { -+ dev_err(&pdev->dev, "failed to allocate memory\n"); -+ return -ENOMEM; -+ } -+ -+ rt->irq = platform_get_irq(pdev, 0); -+ if (!rt->irq) { -+ dev_err(&pdev->dev, "failed to load irq\n"); -+ return -ENOENT; -+ } -+ -+ rt->membase = devm_request_and_ioremap(&pdev->dev, res); -+ if (!rt->membase) { -+ dev_err(&pdev->dev, "failed to ioremap\n"); -+ return -ENOMEM; -+ } -+ -+ clk = devm_clk_get(&pdev->dev, NULL); -+ if (IS_ERR(clk)) { -+ dev_err(&pdev->dev, "failed get clock rate\n"); -+ return PTR_ERR(clk); -+ } -+ -+ rt->timer_freq = clk_get_rate(clk) / TMR0CTL_PRESCALE_DIV; -+ if (!rt->timer_freq) -+ return -EINVAL; -+ -+ rt->dev = &pdev->dev; -+ platform_set_drvdata(pdev, rt); -+ -+ rt_timer_request(rt); -+ rt_timer_config(rt, 2); -+ rt_timer_enable(rt); -+ -+ dev_info(&pdev->dev, "maximum frequncy is %luHz\n", rt->timer_freq); -+ -+ return 0; -+} -+ -+static int rt_timer_remove(struct platform_device *pdev) -+{ -+ struct rt_timer *rt = platform_get_drvdata(pdev); -+ -+ rt_timer_disable(rt); -+ rt_timer_free(rt); -+ -+ return 0; -+} -+ -+static const struct of_device_id rt_timer_match[] = { -+ { .compatible = "ralink,rt2880-timer" }, -+ {}, -+}; -+MODULE_DEVICE_TABLE(of, rt_timer_match); -+ -+static struct platform_driver rt_timer_driver = { -+ .probe = rt_timer_probe, -+ .remove = rt_timer_remove, -+ .driver = { -+ .name = "rt-timer", -+ .owner = THIS_MODULE, -+ .of_match_table = rt_timer_match -+ }, -+}; -+ -+module_platform_driver(rt_timer_driver); -+ -+MODULE_DESCRIPTION("Ralink RT2880 timer"); -+MODULE_AUTHOR("John Crispin +Date: Thu, 21 Mar 2013 17:49:02 +0100 +Subject: [PATCH 113/137] MIPS: ralink: adds support for MT7620 SoC family + +Add support code for mt7620 SOC. + +The code detects the SoC and registers the clk / pinmux settings. + +Signed-off-by: John Crispin +Acked-by: Gabor Juhos +Patchwork: http://patchwork.linux-mips.org/patch/5177/ +--- + arch/mips/include/asm/mach-ralink/mt7620.h | 76 ++++++++++ + arch/mips/ralink/Kconfig | 3 + + arch/mips/ralink/Makefile | 1 + + arch/mips/ralink/Platform | 5 + + arch/mips/ralink/mt7620.c | 214 ++++++++++++++++++++++++++++ + 5 files changed, 299 insertions(+) + create mode 100644 arch/mips/include/asm/mach-ralink/mt7620.h + create mode 100644 arch/mips/ralink/mt7620.c + +--- /dev/null ++++ b/arch/mips/include/asm/mach-ralink/mt7620.h +@@ -0,0 +1,76 @@ ++/* ++ * 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 ++ * Copyright (C) 2008 Imre Kaloz ++ * Copyright (C) 2013 John Crispin ++ */ ++ ++#ifndef _MT7620_REGS_H_ ++#define _MT7620_REGS_H_ ++ ++#define MT7620_SYSC_BASE 0x10000000 ++ ++#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 SYSC_REG_CPLL_CONFIG0 0x54 ++#define SYSC_REG_CPLL_CONFIG1 0x58 ++ ++#define MT7620N_CHIP_NAME0 0x33365452 ++#define MT7620N_CHIP_NAME1 0x20203235 ++ ++#define MT7620A_CHIP_NAME0 0x3637544d ++#define MT7620A_CHIP_NAME1 0x20203032 ++ ++#define 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 CPLL_SW_CONFIG_SHIFT 31 ++#define CPLL_SW_CONFIG_MASK 0x1 ++#define CPLL_CPU_CLK_SHIFT 24 ++#define CPLL_CPU_CLK_MASK 0x1 ++#define CPLL_MULT_RATIO_SHIFT 16 ++#define CPLL_MULT_RATIO 0x7 ++#define CPLL_DIV_RATIO_SHIFT 10 ++#define CPLL_DIV_RATIO 0x3 ++ ++#define SYSCFG0_DRAM_TYPE_MASK 0x3 ++#define SYSCFG0_DRAM_TYPE_SHIFT 4 ++#define SYSCFG0_DRAM_TYPE_SDRAM 0 ++#define SYSCFG0_DRAM_TYPE_DDR1 1 ++#define SYSCFG0_DRAM_TYPE_DDR2 2 ++ ++#define MT7620_GPIO_MODE_I2C BIT(0) ++#define MT7620_GPIO_MODE_UART0_SHIFT 2 ++#define MT7620_GPIO_MODE_UART0_MASK 0x7 ++#define MT7620_GPIO_MODE_UART0(x) ((x) << MT7620_GPIO_MODE_UART0_SHIFT) ++#define MT7620_GPIO_MODE_UARTF 0x0 ++#define MT7620_GPIO_MODE_PCM_UARTF 0x1 ++#define MT7620_GPIO_MODE_PCM_I2S 0x2 ++#define MT7620_GPIO_MODE_I2S_UARTF 0x3 ++#define MT7620_GPIO_MODE_PCM_GPIO 0x4 ++#define MT7620_GPIO_MODE_GPIO_UARTF 0x5 ++#define MT7620_GPIO_MODE_GPIO_I2S 0x6 ++#define MT7620_GPIO_MODE_GPIO 0x7 ++#define MT7620_GPIO_MODE_UART1 BIT(5) ++#define MT7620_GPIO_MODE_MDIO BIT(8) ++#define MT7620_GPIO_MODE_RGMII1 BIT(9) ++#define MT7620_GPIO_MODE_RGMII2 BIT(10) ++#define MT7620_GPIO_MODE_SPI BIT(11) ++#define MT7620_GPIO_MODE_SPI_REF_CLK BIT(12) ++#define MT7620_GPIO_MODE_WLED BIT(13) ++#define MT7620_GPIO_MODE_JTAG BIT(15) ++#define MT7620_GPIO_MODE_EPHY BIT(15) ++#define MT7620_GPIO_MODE_WDT BIT(22) ++ ++#endif +--- a/arch/mips/ralink/Kconfig ++++ b/arch/mips/ralink/Kconfig +@@ -20,6 +20,9 @@ choice + select USB_ARCH_HAS_OHCI + select USB_ARCH_HAS_EHCI + ++ config SOC_MT7620 ++ bool "MT7620" ++ + endchoice + + choice +--- a/arch/mips/ralink/Makefile ++++ b/arch/mips/ralink/Makefile +@@ -11,6 +11,7 @@ obj-y := prom.o of.o reset.o clk.o irq.o + obj-$(CONFIG_SOC_RT288X) += rt288x.o + obj-$(CONFIG_SOC_RT305X) += rt305x.o + obj-$(CONFIG_SOC_RT3883) += rt3883.o ++obj-$(CONFIG_SOC_MT7620) += mt7620.o + + obj-$(CONFIG_EARLY_PRINTK) += early_printk.o + +--- a/arch/mips/ralink/Platform ++++ b/arch/mips/ralink/Platform +@@ -18,3 +18,8 @@ load-$(CONFIG_SOC_RT305X) += 0xffffffff8 + # Ralink RT3883 + # + load-$(CONFIG_SOC_RT3883) += 0xffffffff80000000 ++ ++# ++# Ralink MT7620 ++# ++load-$(CONFIG_SOC_MT7620) += 0xffffffff80000000 +--- /dev/null ++++ b/arch/mips/ralink/mt7620.c +@@ -0,0 +1,214 @@ ++/* ++ * 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 ++ * Copyright (C) 2008 Imre Kaloz ++ * Copyright (C) 2013 John Crispin ++ */ ++ ++#include ++#include ++#include ++ ++#include ++#include ++#include ++ ++#include "common.h" ++ ++/* does the board have sdram or ddram */ ++static int dram_type; ++ ++/* the pll dividers */ ++static u32 mt7620_clk_divider[] = { 2, 3, 4, 8 }; ++ ++static struct ralink_pinmux_grp mode_mux[] = { ++ { ++ .name = "i2c", ++ .mask = MT7620_GPIO_MODE_I2C, ++ .gpio_first = 1, ++ .gpio_last = 2, ++ }, { ++ .name = "spi", ++ .mask = MT7620_GPIO_MODE_SPI, ++ .gpio_first = 3, ++ .gpio_last = 6, ++ }, { ++ .name = "uartlite", ++ .mask = MT7620_GPIO_MODE_UART1, ++ .gpio_first = 15, ++ .gpio_last = 16, ++ }, { ++ .name = "wdt", ++ .mask = MT7620_GPIO_MODE_WDT, ++ .gpio_first = 17, ++ .gpio_last = 17, ++ }, { ++ .name = "mdio", ++ .mask = MT7620_GPIO_MODE_MDIO, ++ .gpio_first = 22, ++ .gpio_last = 23, ++ }, { ++ .name = "rgmii1", ++ .mask = MT7620_GPIO_MODE_RGMII1, ++ .gpio_first = 24, ++ .gpio_last = 35, ++ }, { ++ .name = "spi refclk", ++ .mask = MT7620_GPIO_MODE_SPI_REF_CLK, ++ .gpio_first = 37, ++ .gpio_last = 39, ++ }, { ++ .name = "jtag", ++ .mask = MT7620_GPIO_MODE_JTAG, ++ .gpio_first = 40, ++ .gpio_last = 44, ++ }, { ++ /* shared lines with jtag */ ++ .name = "ephy", ++ .mask = MT7620_GPIO_MODE_EPHY, ++ .gpio_first = 40, ++ .gpio_last = 44, ++ }, { ++ .name = "nand", ++ .mask = MT7620_GPIO_MODE_JTAG, ++ .gpio_first = 45, ++ .gpio_last = 59, ++ }, { ++ .name = "rgmii2", ++ .mask = MT7620_GPIO_MODE_RGMII2, ++ .gpio_first = 60, ++ .gpio_last = 71, ++ }, { ++ .name = "wled", ++ .mask = MT7620_GPIO_MODE_WLED, ++ .gpio_first = 72, ++ .gpio_last = 72, ++ }, {0} ++}; ++ ++static struct ralink_pinmux_grp uart_mux[] = { ++ { ++ .name = "uartf", ++ .mask = MT7620_GPIO_MODE_UARTF, ++ .gpio_first = 7, ++ .gpio_last = 14, ++ }, { ++ .name = "pcm uartf", ++ .mask = MT7620_GPIO_MODE_PCM_UARTF, ++ .gpio_first = 7, ++ .gpio_last = 14, ++ }, { ++ .name = "pcm i2s", ++ .mask = MT7620_GPIO_MODE_PCM_I2S, ++ .gpio_first = 7, ++ .gpio_last = 14, ++ }, { ++ .name = "i2s uartf", ++ .mask = MT7620_GPIO_MODE_I2S_UARTF, ++ .gpio_first = 7, ++ .gpio_last = 14, ++ }, { ++ .name = "pcm gpio", ++ .mask = MT7620_GPIO_MODE_PCM_GPIO, ++ .gpio_first = 11, ++ .gpio_last = 14, ++ }, { ++ .name = "gpio uartf", ++ .mask = MT7620_GPIO_MODE_GPIO_UARTF, ++ .gpio_first = 7, ++ .gpio_last = 10, ++ }, { ++ .name = "gpio i2s", ++ .mask = MT7620_GPIO_MODE_GPIO_I2S, ++ .gpio_first = 7, ++ .gpio_last = 10, ++ }, { ++ .name = "gpio", ++ .mask = MT7620_GPIO_MODE_GPIO, ++ }, {0} ++}; ++ ++struct ralink_pinmux rt_gpio_pinmux = { ++ .mode = mode_mux, ++ .uart = uart_mux, ++ .uart_shift = MT7620_GPIO_MODE_UART0_SHIFT, ++ .uart_mask = MT7620_GPIO_MODE_GPIO, ++}; ++ ++void __init ralink_clk_init(void) ++{ ++ unsigned long cpu_rate, sys_rate; ++ u32 c0 = rt_sysc_r32(SYSC_REG_CPLL_CONFIG0); ++ u32 c1 = rt_sysc_r32(SYSC_REG_CPLL_CONFIG1); ++ u32 swconfig = (c0 >> CPLL_SW_CONFIG_SHIFT) & CPLL_SW_CONFIG_MASK; ++ u32 cpu_clk = (c1 >> CPLL_CPU_CLK_SHIFT) & CPLL_CPU_CLK_MASK; ++ ++ if (cpu_clk) { ++ cpu_rate = 480000000; ++ } else if (!swconfig) { ++ cpu_rate = 600000000; ++ } else { ++ u32 m = (c0 >> CPLL_MULT_RATIO_SHIFT) & CPLL_MULT_RATIO; ++ u32 d = (c0 >> CPLL_DIV_RATIO_SHIFT) & CPLL_DIV_RATIO; ++ ++ cpu_rate = ((40 * (m + 24)) / mt7620_clk_divider[d]) * 1000000; ++ } ++ ++ if (dram_type == SYSCFG0_DRAM_TYPE_SDRAM) ++ sys_rate = cpu_rate / 4; ++ else ++ sys_rate = cpu_rate / 3; ++ ++ ralink_clk_add("cpu", cpu_rate); ++ ralink_clk_add("10000100.timer", 40000000); ++ ralink_clk_add("10000500.uart", 40000000); ++ ralink_clk_add("10000c00.uartlite", 40000000); ++} ++ ++void __init ralink_of_remap(void) ++{ ++ rt_sysc_membase = plat_of_remap_node("ralink,mt7620a-sysc"); ++ rt_memc_membase = plat_of_remap_node("ralink,mt7620a-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(MT7620_SYSC_BASE); ++ unsigned char *name = NULL; ++ u32 n0; ++ u32 n1; ++ u32 rev; ++ u32 cfg0; ++ ++ n0 = __raw_readl(sysc + SYSC_REG_CHIP_NAME0); ++ n1 = __raw_readl(sysc + SYSC_REG_CHIP_NAME1); ++ ++ if (n0 == MT7620N_CHIP_NAME0 && n1 == MT7620N_CHIP_NAME1) { ++ name = "MT7620N"; ++ soc_info->compatible = "ralink,mt7620n-soc"; ++ } else if (n0 == MT7620A_CHIP_NAME0 && n1 == MT7620A_CHIP_NAME1) { ++ name = "MT7620A"; ++ soc_info->compatible = "ralink,mt7620a-soc"; ++ } else { ++ panic("mt7620: 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, ++ "Ralink %s ver:%u eco:%u", ++ name, ++ (rev >> CHIP_REV_VER_SHIFT) & CHIP_REV_VER_MASK, ++ (rev & CHIP_REV_ECO_MASK)); ++ ++ cfg0 = __raw_readl(sysc + SYSC_REG_SYSTEM_CONFIG0); ++ dram_type = (cfg0 >> SYSCFG0_DRAM_TYPE_SHIFT) & SYSCFG0_DRAM_TYPE_MASK; ++} diff --git a/target/linux/ramips/patches-3.8/0114-GPIO-MIPS-ralink-adds-ralink-gpio-support.patch b/target/linux/ramips/patches-3.8/0114-GPIO-MIPS-ralink-adds-ralink-gpio-support.patch deleted file mode 100644 index b0ea011ab5..0000000000 --- a/target/linux/ramips/patches-3.8/0114-GPIO-MIPS-ralink-adds-ralink-gpio-support.patch +++ /dev/null @@ -1,260 +0,0 @@ -From f22c157f44c93d61058d2e2aa5626ee2899fde5a Mon Sep 17 00:00:00 2001 -From: John Crispin -Date: Tue, 22 Jan 2013 18:24:34 +0100 -Subject: [PATCH 114/121] GPIO: MIPS: ralink: adds ralink gpio support - -Add gpio driver for Ralink SoC. This driver makes the gpio core on -RT2880, RT305x, rt3352, rt3662, rt3883, rt5350 and mt7620 work. - -Signed-off-by: John Crispin ---- - arch/mips/Kconfig | 1 + - arch/mips/include/asm/mach-ralink/gpio.h | 24 ++++ - drivers/gpio/Kconfig | 6 + - drivers/gpio/Makefile | 1 + - drivers/gpio/gpio-ralink.c | 176 ++++++++++++++++++++++++++++++ - 5 files changed, 208 insertions(+) - create mode 100644 arch/mips/include/asm/mach-ralink/gpio.h - create mode 100644 drivers/gpio/gpio-ralink.c - ---- a/arch/mips/Kconfig -+++ b/arch/mips/Kconfig -@@ -449,6 +449,7 @@ config RALINK - select SYS_HAS_EARLY_PRINTK - select HAVE_MACH_CLKDEV - select CLKDEV_LOOKUP -+ select ARCH_REQUIRE_GPIOLIB - - config SGI_IP22 - bool "SGI IP22 (Indy/Indigo2)" ---- /dev/null -+++ b/arch/mips/include/asm/mach-ralink/gpio.h -@@ -0,0 +1,24 @@ -+/* -+ * Ralink SoC GPIO API support -+ * -+ * Copyright (C) 2008-2009 Gabor Juhos -+ * Copyright (C) 2008 Imre Kaloz -+ * -+ * This program is free software; you can redistribute it and/or modify it -+ * under the terms of the GNU General Public License version 2 as published -+ * by the Free Software Foundation. -+ * -+ */ -+ -+#ifndef __ASM_MACH_RALINK_GPIO_H -+#define __ASM_MACH_RALINK_GPIO_H -+ -+#define ARCH_NR_GPIOS 128 -+#include -+ -+#define gpio_get_value __gpio_get_value -+#define gpio_set_value __gpio_set_value -+#define gpio_cansleep __gpio_cansleep -+#define gpio_to_irq __gpio_to_irq -+ -+#endif /* __ASM_MACH_RALINK_GPIO_H */ ---- a/drivers/gpio/Kconfig -+++ b/drivers/gpio/Kconfig -@@ -201,6 +201,12 @@ config GPIO_PXA - help - Say yes here to support the PXA GPIO device - -+config GPIO_RALINK -+ bool "Ralink GPIO Support" -+ depends on RALINK -+ help -+ Say yes here to support the Ralink SoC GPIO device -+ - config GPIO_SPEAR_SPICS - bool "ST SPEAr13xx SPI Chip Select as GPIO support" - depends on PLAT_SPEAR ---- a/drivers/gpio/Makefile -+++ b/drivers/gpio/Makefile -@@ -54,6 +54,7 @@ obj-$(CONFIG_GPIO_PCF857X) += gpio-pcf85 - obj-$(CONFIG_GPIO_PCH) += gpio-pch.o - obj-$(CONFIG_GPIO_PL061) += gpio-pl061.o - obj-$(CONFIG_GPIO_PXA) += gpio-pxa.o -+obj-$(CONFIG_GPIO_RALINK) += gpio-ralink.o - obj-$(CONFIG_GPIO_RC5T583) += gpio-rc5t583.o - obj-$(CONFIG_GPIO_RDC321X) += gpio-rdc321x.o - obj-$(CONFIG_PLAT_SAMSUNG) += gpio-samsung.o ---- /dev/null -+++ b/drivers/gpio/gpio-ralink.c -@@ -0,0 +1,176 @@ -+/* -+ * 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 -+ * Copyright (C) 2013 John Crispin -+ */ -+ -+#include -+#include -+#include -+#include -+#include -+ -+enum ralink_gpio_reg { -+ GPIO_REG_INT = 0, -+ GPIO_REG_EDGE, -+ GPIO_REG_RENA, -+ GPIO_REG_FENA, -+ GPIO_REG_DATA, -+ GPIO_REG_DIR, -+ GPIO_REG_POL, -+ GPIO_REG_SET, -+ GPIO_REG_RESET, -+ GPIO_REG_TOGGLE, -+ GPIO_REG_MAX -+}; -+ -+struct ralink_gpio_chip { -+ struct gpio_chip chip; -+ u8 regs[GPIO_REG_MAX]; -+ -+ spinlock_t lock; -+ void __iomem *membase; -+}; -+ -+static inline struct ralink_gpio_chip *to_ralink_gpio(struct gpio_chip *chip) -+{ -+ struct ralink_gpio_chip *rg; -+ -+ rg = container_of(chip, struct ralink_gpio_chip, chip); -+ return rg; -+} -+ -+static inline void rt_gpio_w32(struct ralink_gpio_chip *rg, u8 reg, u32 val) -+{ -+ iowrite32(val, rg->membase + rg->regs[reg]); -+} -+ -+static inline u32 rt_gpio_r32(struct ralink_gpio_chip *rg, u8 reg) -+{ -+ return ioread32(rg->membase + rg->regs[reg]); -+} -+ -+static void ralink_gpio_set(struct gpio_chip *chip, unsigned offset, int value) -+{ -+ struct ralink_gpio_chip *rg = to_ralink_gpio(chip); -+ -+ rt_gpio_w32(rg, (value) ? GPIO_REG_SET : GPIO_REG_RESET, BIT(offset)); -+} -+ -+static int ralink_gpio_get(struct gpio_chip *chip, unsigned offset) -+{ -+ struct ralink_gpio_chip *rg = to_ralink_gpio(chip); -+ -+ return !!(rt_gpio_r32(rg, GPIO_REG_DATA) & BIT(offset)); -+} -+ -+static int ralink_gpio_direction_input(struct gpio_chip *chip, unsigned offset) -+{ -+ struct ralink_gpio_chip *rg = to_ralink_gpio(chip); -+ unsigned long flags; -+ u32 t; -+ -+ spin_lock_irqsave(&rg->lock, flags); -+ t = rt_gpio_r32(rg, GPIO_REG_DIR); -+ t &= ~BIT(offset); -+ rt_gpio_w32(rg, GPIO_REG_DIR, t); -+ spin_unlock_irqrestore(&rg->lock, flags); -+ -+ return 0; -+} -+ -+static int ralink_gpio_direction_output(struct gpio_chip *chip, -+ unsigned offset, int value) -+{ -+ struct ralink_gpio_chip *rg = to_ralink_gpio(chip); -+ unsigned long flags; -+ u32 t; -+ -+ spin_lock_irqsave(&rg->lock, flags); -+ ralink_gpio_set(chip, offset, value); -+ t = rt_gpio_r32(rg, GPIO_REG_DIR); -+ t |= BIT(offset); -+ rt_gpio_w32(rg, GPIO_REG_DIR, t); -+ spin_unlock_irqrestore(&rg->lock, flags); -+ -+ return 0; -+} -+ -+static int ralink_gpio_probe(struct platform_device *pdev) -+{ -+ struct device_node *np = pdev->dev.of_node; -+ struct resource *res = platform_get_resource(pdev, IORESOURCE_MEM, 0); -+ struct ralink_gpio_chip *gc; -+ const __be32 *ngpio; -+ -+ if (!res) { -+ dev_err(&pdev->dev, "failed to find resource\n"); -+ return -ENOMEM; -+ } -+ -+ gc = devm_kzalloc(&pdev->dev, -+ sizeof(struct ralink_gpio_chip), GFP_KERNEL); -+ if (!gc) -+ return -ENOMEM; -+ -+ gc->membase = devm_request_and_ioremap(&pdev->dev, res); -+ if (!gc->membase) { -+ dev_err(&pdev->dev, "cannot remap I/O memory region\n"); -+ return -ENOMEM; -+ } -+ -+ if (of_property_read_u8_array(np, "ralink,register-map", -+ gc->regs, GPIO_REG_MAX)) { -+ dev_err(&pdev->dev, "failed to read register definition\n"); -+ return -EINVAL; -+ } -+ -+ ngpio = of_get_property(np, "ralink,num-gpios", NULL); -+ if (!ngpio) { -+ dev_err(&pdev->dev, "failed to read number of pins\n"); -+ return -EINVAL; -+ } -+ -+ spin_lock_init(&gc->lock); -+ -+ gc->chip.label = dev_name(&pdev->dev); -+ gc->chip.of_node = np; -+ gc->chip.base = -1; -+ gc->chip.ngpio = be32_to_cpu(*ngpio); -+ gc->chip.direction_input = ralink_gpio_direction_input; -+ gc->chip.direction_output = ralink_gpio_direction_output; -+ gc->chip.get = ralink_gpio_get; -+ gc->chip.set = ralink_gpio_set; -+ -+ /* set polarity to low for all lines */ -+ rt_gpio_w32(gc, GPIO_REG_POL, 0); -+ -+ dev_info(&pdev->dev, "registering %d gpios\n", gc->chip.ngpio); -+ -+ return gpiochip_add(&gc->chip); -+} -+ -+static const struct of_device_id ralink_gpio_match[] = { -+ { .compatible = "ralink,rt2880-gpio" }, -+ {}, -+}; -+MODULE_DEVICE_TABLE(of, ralink_gpio_match); -+ -+static struct platform_driver ralink_gpio_driver = { -+ .probe = ralink_gpio_probe, -+ .driver = { -+ .name = "rt2880_gpio", -+ .owner = THIS_MODULE, -+ .of_match_table = ralink_gpio_match, -+ }, -+}; -+ -+static int __init ralink_gpio_init(void) -+{ -+ return platform_driver_register(&ralink_gpio_driver); -+} -+ -+subsys_initcall(ralink_gpio_init); diff --git a/target/linux/ramips/patches-3.8/0114-MIPS-ralink-add-cpu-feature-overrides.h.patch b/target/linux/ramips/patches-3.8/0114-MIPS-ralink-add-cpu-feature-overrides.h.patch new file mode 100644 index 0000000000..dc5dab98a1 --- /dev/null +++ b/target/linux/ramips/patches-3.8/0114-MIPS-ralink-add-cpu-feature-overrides.h.patch @@ -0,0 +1,218 @@ +From 33c525913af22d1b799a7218ee48579c22a50cf8 Mon Sep 17 00:00:00 2001 +From: Gabor Juhos +Date: Wed, 10 Apr 2013 09:19:07 +0200 +Subject: [PATCH 114/137] MIPS: ralink: add cpu-feature-overrides.h + +Add cpu-feature-overrides.h for RT288x, RT305x and RT3883. + +Signed-off-by: Gabor Juhos +Signed-off-by: John Crispin +Patchwork: http://patchwork.linux-mips.org/patch/5175/ +--- + .../asm/mach-ralink/rt288x/cpu-feature-overrides.h | 56 ++++++++++++++++++++ + .../asm/mach-ralink/rt305x/cpu-feature-overrides.h | 56 ++++++++++++++++++++ + .../asm/mach-ralink/rt3883/cpu-feature-overrides.h | 55 +++++++++++++++++++ + arch/mips/ralink/Platform | 3 ++ + 4 files changed, 170 insertions(+) + create mode 100644 arch/mips/include/asm/mach-ralink/rt288x/cpu-feature-overrides.h + create mode 100644 arch/mips/include/asm/mach-ralink/rt305x/cpu-feature-overrides.h + create mode 100644 arch/mips/include/asm/mach-ralink/rt3883/cpu-feature-overrides.h + +--- /dev/null ++++ b/arch/mips/include/asm/mach-ralink/rt288x/cpu-feature-overrides.h +@@ -0,0 +1,56 @@ ++/* ++ * Ralink RT288x specific CPU feature overrides ++ * ++ * Copyright (C) 2008-2009 Gabor Juhos ++ * Copyright (C) 2008 Imre Kaloz ++ * ++ * This file was derived from: include/asm-mips/cpu-features.h ++ * Copyright (C) 2003, 2004 Ralf Baechle ++ * Copyright (C) 2004 Maciej W. Rozycki ++ * ++ * This program is free software; you can redistribute it and/or modify it ++ * under the terms of the GNU General Public License version 2 as published ++ * by the Free Software Foundation. ++ * ++ */ ++#ifndef _RT288X_CPU_FEATURE_OVERRIDES_H ++#define _RT288X_CPU_FEATURE_OVERRIDES_H ++ ++#define cpu_has_tlb 1 ++#define cpu_has_4kex 1 ++#define cpu_has_3k_cache 0 ++#define cpu_has_4k_cache 1 ++#define cpu_has_tx39_cache 0 ++#define cpu_has_sb1_cache 0 ++#define cpu_has_fpu 0 ++#define cpu_has_32fpr 0 ++#define cpu_has_counter 1 ++#define cpu_has_watch 1 ++#define cpu_has_divec 1 ++ ++#define cpu_has_prefetch 1 ++#define cpu_has_ejtag 1 ++#define cpu_has_llsc 1 ++ ++#define cpu_has_mips16 1 ++#define cpu_has_mdmx 0 ++#define cpu_has_mips3d 0 ++#define cpu_has_smartmips 0 ++ ++#define cpu_has_mips32r1 1 ++#define cpu_has_mips32r2 1 ++#define cpu_has_mips64r1 0 ++#define cpu_has_mips64r2 0 ++ ++#define cpu_has_dsp 0 ++#define cpu_has_mipsmt 0 ++ ++#define cpu_has_64bits 0 ++#define cpu_has_64bit_zero_reg 0 ++#define cpu_has_64bit_gp_regs 0 ++#define cpu_has_64bit_addresses 0 ++ ++#define cpu_dcache_line_size() 16 ++#define cpu_icache_line_size() 16 ++ ++#endif /* _RT288X_CPU_FEATURE_OVERRIDES_H */ +--- /dev/null ++++ b/arch/mips/include/asm/mach-ralink/rt305x/cpu-feature-overrides.h +@@ -0,0 +1,56 @@ ++/* ++ * Ralink RT305x specific CPU feature overrides ++ * ++ * Copyright (C) 2008-2009 Gabor Juhos ++ * Copyright (C) 2008 Imre Kaloz ++ * ++ * This file was derived from: include/asm-mips/cpu-features.h ++ * Copyright (C) 2003, 2004 Ralf Baechle ++ * Copyright (C) 2004 Maciej W. Rozycki ++ * ++ * This program is free software; you can redistribute it and/or modify it ++ * under the terms of the GNU General Public License version 2 as published ++ * by the Free Software Foundation. ++ * ++ */ ++#ifndef _RT305X_CPU_FEATURE_OVERRIDES_H ++#define _RT305X_CPU_FEATURE_OVERRIDES_H ++ ++#define cpu_has_tlb 1 ++#define cpu_has_4kex 1 ++#define cpu_has_3k_cache 0 ++#define cpu_has_4k_cache 1 ++#define cpu_has_tx39_cache 0 ++#define cpu_has_sb1_cache 0 ++#define cpu_has_fpu 0 ++#define cpu_has_32fpr 0 ++#define cpu_has_counter 1 ++#define cpu_has_watch 1 ++#define cpu_has_divec 1 ++ ++#define cpu_has_prefetch 1 ++#define cpu_has_ejtag 1 ++#define cpu_has_llsc 1 ++ ++#define cpu_has_mips16 1 ++#define cpu_has_mdmx 0 ++#define cpu_has_mips3d 0 ++#define cpu_has_smartmips 0 ++ ++#define cpu_has_mips32r1 1 ++#define cpu_has_mips32r2 1 ++#define cpu_has_mips64r1 0 ++#define cpu_has_mips64r2 0 ++ ++#define cpu_has_dsp 1 ++#define cpu_has_mipsmt 0 ++ ++#define cpu_has_64bits 0 ++#define cpu_has_64bit_zero_reg 0 ++#define cpu_has_64bit_gp_regs 0 ++#define cpu_has_64bit_addresses 0 ++ ++#define cpu_dcache_line_size() 32 ++#define cpu_icache_line_size() 32 ++ ++#endif /* _RT305X_CPU_FEATURE_OVERRIDES_H */ +--- /dev/null ++++ b/arch/mips/include/asm/mach-ralink/rt3883/cpu-feature-overrides.h +@@ -0,0 +1,55 @@ ++/* ++ * Ralink RT3662/RT3883 specific CPU feature overrides ++ * ++ * Copyright (C) 2011-2013 Gabor Juhos ++ * ++ * This file was derived from: include/asm-mips/cpu-features.h ++ * Copyright (C) 2003, 2004 Ralf Baechle ++ * Copyright (C) 2004 Maciej W. Rozycki ++ * ++ * This program is free software; you can redistribute it and/or modify it ++ * under the terms of the GNU General Public License version 2 as published ++ * by the Free Software Foundation. ++ * ++ */ ++#ifndef _RT3883_CPU_FEATURE_OVERRIDES_H ++#define _RT3883_CPU_FEATURE_OVERRIDES_H ++ ++#define cpu_has_tlb 1 ++#define cpu_has_4kex 1 ++#define cpu_has_3k_cache 0 ++#define cpu_has_4k_cache 1 ++#define cpu_has_tx39_cache 0 ++#define cpu_has_sb1_cache 0 ++#define cpu_has_fpu 0 ++#define cpu_has_32fpr 0 ++#define cpu_has_counter 1 ++#define cpu_has_watch 1 ++#define cpu_has_divec 1 ++ ++#define cpu_has_prefetch 1 ++#define cpu_has_ejtag 1 ++#define cpu_has_llsc 1 ++ ++#define cpu_has_mips16 1 ++#define cpu_has_mdmx 0 ++#define cpu_has_mips3d 0 ++#define cpu_has_smartmips 0 ++ ++#define cpu_has_mips32r1 1 ++#define cpu_has_mips32r2 1 ++#define cpu_has_mips64r1 0 ++#define cpu_has_mips64r2 0 ++ ++#define cpu_has_dsp 1 ++#define cpu_has_mipsmt 0 ++ ++#define cpu_has_64bits 0 ++#define cpu_has_64bit_zero_reg 0 ++#define cpu_has_64bit_gp_regs 0 ++#define cpu_has_64bit_addresses 0 ++ ++#define cpu_dcache_line_size() 32 ++#define cpu_icache_line_size() 32 ++ ++#endif /* _RT3883_CPU_FEATURE_OVERRIDES_H */ +--- a/arch/mips/ralink/Platform ++++ b/arch/mips/ralink/Platform +@@ -8,16 +8,19 @@ cflags-$(CONFIG_RALINK) += -I$(srctree) + # Ralink RT288x + # + load-$(CONFIG_SOC_RT288X) += 0xffffffff88000000 ++cflags-$(CONFIG_SOC_RT288X) += -I$(srctree)/arch/mips/include/asm/mach-ralink/rt288x + + # + # Ralink RT305x + # + load-$(CONFIG_SOC_RT305X) += 0xffffffff80000000 ++cflags-$(CONFIG_SOC_RT305X) += -I$(srctree)/arch/mips/include/asm/mach-ralink/rt305x + + # + # Ralink RT3883 + # + load-$(CONFIG_SOC_RT3883) += 0xffffffff80000000 ++cflags-$(CONFIG_SOC_RT3883) += -I$(srctree)/arch/mips/include/asm/mach-ralink/rt3883 + + # + # Ralink MT7620 diff --git a/target/linux/ramips/patches-3.8/0115-DT-add-vendor-prefixes-for-Ralink.patch b/target/linux/ramips/patches-3.8/0115-DT-add-vendor-prefixes-for-Ralink.patch new file mode 100644 index 0000000000..a9a99b4cae --- /dev/null +++ b/target/linux/ramips/patches-3.8/0115-DT-add-vendor-prefixes-for-Ralink.patch @@ -0,0 +1,21 @@ +From 9377ecb9f1fb5da25a0fbd324e7add7644b1d43d Mon Sep 17 00:00:00 2001 +From: John Crispin +Date: Sat, 13 Apr 2013 10:11:51 +0200 +Subject: [PATCH 115/137] DT: add vendor prefixes for Ralink + +Signed-off-by: John Crispin +Acked-by: Grant Likely +--- + Documentation/devicetree/bindings/vendor-prefixes.txt | 1 + + 1 file changed, 1 insertion(+) + +--- a/Documentation/devicetree/bindings/vendor-prefixes.txt ++++ b/Documentation/devicetree/bindings/vendor-prefixes.txt +@@ -40,6 +40,7 @@ onnn ON Semiconductor Corp. + picochip Picochip Ltd + powervr PowerVR (deprecated, use img) + qcom Qualcomm, Inc. ++ralink Mediatek/Ralink Technology Corp. + ramtron Ramtron International + realtek Realtek Semiconductor Corp. + samsung Samsung Semiconductor diff --git a/target/linux/ramips/patches-3.8/0115-SPI-ralink-add-Ralink-SoC-spi-driver.patch b/target/linux/ramips/patches-3.8/0115-SPI-ralink-add-Ralink-SoC-spi-driver.patch deleted file mode 100644 index b2717d139f..0000000000 --- a/target/linux/ramips/patches-3.8/0115-SPI-ralink-add-Ralink-SoC-spi-driver.patch +++ /dev/null @@ -1,515 +0,0 @@ -e8c5ebbd743dac63178807c0f68fe1b75680474a3 Mon Sep 17 00:00:00 2001 -From: John Crispin -Date: Wed, 30 Jan 2013 17:58:15 +0100 -Subject: [PATCH 115/121] SPI: ralink: add Ralink SoC spi driver - -Add the driver needed to make SPI work on Ralink SoC. - -Signed-off-by: John Crispin ---- - drivers/spi/Kconfig | 6 + - drivers/spi/Makefile | 1 + - drivers/spi/spi-ralink.c | 472 ++++++++++++++++++++++++++++++++++++++++++++++ - 3 files changed, 479 insertions(+) - create mode 100644 drivers/spi/spi-ralink.c - ---- a/drivers/spi/Kconfig -+++ b/drivers/spi/Kconfig -@@ -324,6 +324,12 @@ config SPI_RSPI - help - SPI driver for Renesas RSPI blocks. - -+config SPI_RALINK -+ tristate "Ralink RT288x/RT305x/RT3662 SPI Controller" -+ depends on (SOC_RT288X || SOC_RT305X || SOC_RT3883) -+ help -+ This selects a driver for the Ralink RT288x/RT305x SPI Controller. -+ - config SPI_S3C24XX - tristate "Samsung S3C24XX series SPI" - depends on ARCH_S3C24XX && EXPERIMENTAL ---- a/drivers/spi/Makefile -+++ b/drivers/spi/Makefile -@@ -51,6 +51,7 @@ obj-$(CONFIG_SPI_PPC4xx) += spi-ppc4xx. - obj-$(CONFIG_SPI_PXA2XX) += spi-pxa2xx.o - obj-$(CONFIG_SPI_PXA2XX_PCI) += spi-pxa2xx-pci.o - obj-$(CONFIG_SPI_RSPI) += spi-rspi.o -+obj-$(CONFIG_SPI_RALINK) += spi-ralink.o - obj-$(CONFIG_SPI_S3C24XX) += spi-s3c24xx-hw.o - spi-s3c24xx-hw-y := spi-s3c24xx.o - spi-s3c24xx-hw-$(CONFIG_SPI_S3C24XX_FIQ) += spi-s3c24xx-fiq.o ---- /dev/null -+++ b/drivers/spi/spi-ralink.c -@@ -0,0 +1,472 @@ -+/* -+ * spi-ralink.c -- Ralink RT288x/RT305x SPI controller driver -+ * -+ * Copyright (C) 2011 Sergiy -+ * Copyright (C) 2011-2013 Gabor Juhos -+ * -+ * Some parts are based on spi-orion.c: -+ * Author: Shadi Ammouri -+ * Copyright (C) 2007-2008 Marvell Ltd. -+ * -+ * This program is free software; you can redistribute it and/or modify -+ * it under the terms of the GNU General Public License version 2 as -+ * published by the Free Software Foundation. -+ */ -+ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+ -+#define DRIVER_NAME "spi-ralink" -+#define RALINK_NUM_CHIPSELECTS 1 /* only one slave is supported*/ -+#define RALINK_SPI_WAIT_RDY_MAX_LOOP 2000 /* in usec */ -+ -+#define RAMIPS_SPI_STAT 0x00 -+#define RAMIPS_SPI_CFG 0x10 -+#define RAMIPS_SPI_CTL 0x14 -+#define RAMIPS_SPI_DATA 0x20 -+ -+/* SPISTAT register bit field */ -+#define SPISTAT_BUSY BIT(0) -+ -+/* SPICFG register bit field */ -+#define SPICFG_LSBFIRST 0 -+#define SPICFG_MSBFIRST BIT(8) -+#define SPICFG_SPICLKPOL BIT(6) -+#define SPICFG_RXCLKEDGE_FALLING BIT(5) -+#define SPICFG_TXCLKEDGE_FALLING BIT(4) -+#define SPICFG_SPICLK_PRESCALE_MASK 0x7 -+#define SPICFG_SPICLK_DIV2 0 -+#define SPICFG_SPICLK_DIV4 1 -+#define SPICFG_SPICLK_DIV8 2 -+#define SPICFG_SPICLK_DIV16 3 -+#define SPICFG_SPICLK_DIV32 4 -+#define SPICFG_SPICLK_DIV64 5 -+#define SPICFG_SPICLK_DIV128 6 -+#define SPICFG_SPICLK_DISABLE 7 -+ -+/* SPICTL register bit field */ -+#define SPICTL_HIZSDO BIT(3) -+#define SPICTL_STARTWR BIT(2) -+#define SPICTL_STARTRD BIT(1) -+#define SPICTL_SPIENA BIT(0) -+ -+#ifdef DEBUG -+#define spi_debug(args...) printk(args) -+#else -+#define spi_debug(args...) -+#endif -+ -+struct ralink_spi { -+ struct spi_master *master; -+ void __iomem *base; -+ unsigned int sys_freq; -+ unsigned int speed; -+ struct clk *clk; -+}; -+ -+static inline struct ralink_spi *spidev_to_ralink_spi(struct spi_device *spi) -+{ -+ return spi_master_get_devdata(spi->master); -+} -+ -+static inline u32 ralink_spi_read(struct ralink_spi *rs, u32 reg) -+{ -+ return ioread32(rs->base + reg); -+} -+ -+static inline void ralink_spi_write(struct ralink_spi *rs, u32 reg, u32 val) -+{ -+ iowrite32(val, rs->base + reg); -+} -+ -+static inline void ralink_spi_setbits(struct ralink_spi *rs, u32 reg, u32 mask) -+{ -+ void __iomem *addr = rs->base + reg; -+ u32 val; -+ -+ val = ioread32(addr); -+ val |= mask; -+ iowrite32(val, addr); -+} -+ -+static inline void ralink_spi_clrbits(struct ralink_spi *rs, u32 reg, u32 mask) -+{ -+ void __iomem *addr = rs->base + reg; -+ u32 val; -+ -+ val = ioread32(addr); -+ val &= ~mask; -+ iowrite32(val, addr); -+} -+ -+static int ralink_spi_baudrate_set(struct spi_device *spi, unsigned int speed) -+{ -+ struct ralink_spi *rs = spidev_to_ralink_spi(spi); -+ u32 rate; -+ u32 prescale; -+ u32 reg; -+ -+ spi_debug("%s: speed:%u\n", __func__, speed); -+ -+ /* -+ * the supported rates are: 2, 4, 8, ... 128 -+ * round up as we look for equal or less speed -+ */ -+ rate = DIV_ROUND_UP(rs->sys_freq, speed); -+ spi_debug("%s: rate-1:%u\n", __func__, rate); -+ rate = roundup_pow_of_two(rate); -+ spi_debug("%s: rate-2:%u\n", __func__, rate); -+ -+ /* check if requested speed is too small */ -+ if (rate > 128) -+ return -EINVAL; -+ -+ if (rate < 2) -+ rate = 2; -+ -+ /* Convert the rate to SPI clock divisor value. */ -+ prescale = ilog2(rate/2); -+ spi_debug("%s: prescale:%u\n", __func__, prescale); -+ -+ reg = ralink_spi_read(rs, RAMIPS_SPI_CFG); -+ reg = ((reg & ~SPICFG_SPICLK_PRESCALE_MASK) | prescale); -+ ralink_spi_write(rs, RAMIPS_SPI_CFG, reg); -+ rs->speed = speed; -+ return 0; -+} -+ -+/* -+ * called only when no transfer is active on the bus -+ */ -+static int -+ralink_spi_setup_transfer(struct spi_device *spi, struct spi_transfer *t) -+{ -+ struct ralink_spi *rs = spidev_to_ralink_spi(spi); -+ unsigned int speed = spi->max_speed_hz; -+ int rc; -+ unsigned int bits_per_word = 8; -+ -+ if ((t != NULL) && t->speed_hz) -+ speed = t->speed_hz; -+ -+ if ((t != NULL) && t->bits_per_word) -+ bits_per_word = t->bits_per_word; -+ -+ if (rs->speed != speed) { -+ spi_debug("%s: speed_hz:%u\n", __func__, speed); -+ rc = ralink_spi_baudrate_set(spi, speed); -+ if (rc) -+ return rc; -+ } -+ -+ if (bits_per_word != 8) { -+ spi_debug("%s: bad bits_per_word: %u\n", __func__, -+ bits_per_word); -+ return -EINVAL; -+ } -+ -+ return 0; -+} -+ -+static void ralink_spi_set_cs(struct ralink_spi *rs, int enable) -+{ -+ if (enable) -+ ralink_spi_clrbits(rs, RAMIPS_SPI_CTL, SPICTL_SPIENA); -+ else -+ ralink_spi_setbits(rs, RAMIPS_SPI_CTL, SPICTL_SPIENA); -+} -+ -+static inline int ralink_spi_wait_till_ready(struct ralink_spi *rs) -+{ -+ int i; -+ -+ for (i = 0; i < RALINK_SPI_WAIT_RDY_MAX_LOOP; i++) { -+ u32 status; -+ -+ status = ralink_spi_read(rs, RAMIPS_SPI_STAT); -+ if ((status & SPISTAT_BUSY) == 0) -+ return 0; -+ -+ udelay(1); -+ } -+ -+ return -ETIMEDOUT; -+} -+ -+static unsigned int -+ralink_spi_write_read(struct spi_device *spi, struct spi_transfer *xfer) -+{ -+ struct ralink_spi *rs = spidev_to_ralink_spi(spi); -+ unsigned count = 0; -+ u8 *rx = xfer->rx_buf; -+ const u8 *tx = xfer->tx_buf; -+ int err; -+ -+ spi_debug("%s(%d): %s %s\n", __func__, xfer->len, -+ (tx != NULL) ? "tx" : " ", -+ (rx != NULL) ? "rx" : " "); -+ -+ if (tx) { -+ for (count = 0; count < xfer->len; count++) { -+ ralink_spi_write(rs, RAMIPS_SPI_DATA, tx[count]); -+ ralink_spi_setbits(rs, RAMIPS_SPI_CTL, SPICTL_STARTWR); -+ err = ralink_spi_wait_till_ready(rs); -+ if (err) { -+ dev_err(&spi->dev, "TX failed, err=%d\n", err); -+ goto out; -+ } -+ } -+ } -+ -+ if (rx) { -+ for (count = 0; count < xfer->len; count++) { -+ ralink_spi_setbits(rs, RAMIPS_SPI_CTL, SPICTL_STARTRD); -+ err = ralink_spi_wait_till_ready(rs); -+ if (err) { -+ dev_err(&spi->dev, "RX failed, err=%d\n", err); -+ goto out; -+ } -+ rx[count] = (u8) ralink_spi_read(rs, RAMIPS_SPI_DATA); -+ } -+ } -+ -+out: -+ return count; -+} -+ -+static int ralink_spi_transfer_one_message(struct spi_master *master, -+ struct spi_message *m) -+{ -+ struct ralink_spi *rs = spi_master_get_devdata(master); -+ struct spi_device *spi = m->spi; -+ struct spi_transfer *t = NULL; -+ int par_override = 0; -+ int status = 0; -+ int cs_active = 0; -+ -+ /* Load defaults */ -+ status = ralink_spi_setup_transfer(spi, NULL); -+ if (status < 0) -+ goto msg_done; -+ -+ list_for_each_entry(t, &m->transfers, transfer_list) { -+ unsigned int bits_per_word = spi->bits_per_word; -+ -+ if (t->tx_buf == NULL && t->rx_buf == NULL && t->len) { -+ dev_err(&spi->dev, -+ "message rejected: invalid transfer data buffers\n"); -+ status = -EIO; -+ goto msg_done; -+ } -+ -+ if (t->bits_per_word) -+ bits_per_word = t->bits_per_word; -+ -+ if (bits_per_word != 8) { -+ dev_err(&spi->dev, -+ "message rejected: invalid transfer bits_per_word (%d bits)\n", -+ bits_per_word); -+ status = -EIO; -+ goto msg_done; -+ } -+ -+ if (t->speed_hz && t->speed_hz < (rs->sys_freq / 128)) { -+ dev_err(&spi->dev, -+ "message rejected: device min speed (%d Hz) exceeds required transfer speed (%d Hz)\n", -+ (rs->sys_freq / 128), t->speed_hz); -+ status = -EIO; -+ goto msg_done; -+ } -+ -+ if (par_override || t->speed_hz || t->bits_per_word) { -+ par_override = 1; -+ status = ralink_spi_setup_transfer(spi, t); -+ if (status < 0) -+ goto msg_done; -+ if (!t->speed_hz && !t->bits_per_word) -+ par_override = 0; -+ } -+ -+ if (!cs_active) { -+ ralink_spi_set_cs(rs, 1); -+ cs_active = 1; -+ } -+ -+ if (t->len) -+ m->actual_length += ralink_spi_write_read(spi, t); -+ -+ if (t->delay_usecs) -+ udelay(t->delay_usecs); -+ -+ if (t->cs_change) { -+ ralink_spi_set_cs(rs, 0); -+ cs_active = 0; -+ } -+ } -+ -+msg_done: -+ if (cs_active) -+ ralink_spi_set_cs(rs, 0); -+ -+ m->status = status; -+ spi_finalize_current_message(master); -+ -+ return 0; -+} -+ -+static int ralink_spi_setup(struct spi_device *spi) -+{ -+ struct ralink_spi *rs = spidev_to_ralink_spi(spi); -+ -+ if ((spi->max_speed_hz == 0) || -+ (spi->max_speed_hz > (rs->sys_freq / 2))) -+ spi->max_speed_hz = (rs->sys_freq / 2); -+ -+ if (spi->max_speed_hz < (rs->sys_freq / 128)) { -+ dev_err(&spi->dev, "setup: requested speed is too low %d Hz\n", -+ spi->max_speed_hz); -+ return -EINVAL; -+ } -+ -+ if (spi->bits_per_word != 0 && spi->bits_per_word != 8) { -+ dev_err(&spi->dev, -+ "setup: requested bits per words - os wrong %d bpw\n", -+ spi->bits_per_word); -+ return -EINVAL; -+ } -+ -+ if (spi->bits_per_word == 0) -+ spi->bits_per_word = 8; -+ -+ /* -+ * baudrate & width will be set ralink_spi_setup_transfer -+ */ -+ return 0; -+} -+ -+static void ralink_spi_reset(struct ralink_spi *rs) -+{ -+ ralink_spi_write(rs, RAMIPS_SPI_CFG, -+ SPICFG_MSBFIRST | SPICFG_TXCLKEDGE_FALLING | -+ SPICFG_SPICLK_DIV16 | SPICFG_SPICLKPOL); -+ ralink_spi_write(rs, RAMIPS_SPI_CTL, SPICTL_HIZSDO | SPICTL_SPIENA); -+} -+ -+static int ralink_spi_probe(struct platform_device *pdev) -+{ -+ struct spi_master *master; -+ struct ralink_spi *rs; -+ struct resource *r; -+ int status = 0; -+ -+ master = spi_alloc_master(&pdev->dev, sizeof(*rs)); -+ if (master == NULL) { -+ dev_dbg(&pdev->dev, "master allocation failed\n"); -+ return -ENOMEM; -+ } -+ -+ //if (pdev->id != -1) -+ master->bus_num = 0; -+ -+ /* we support only mode 0, and no options */ -+ master->mode_bits = 0; -+ -+ master->setup = ralink_spi_setup; -+ master->transfer_one_message = ralink_spi_transfer_one_message; -+ master->num_chipselect = RALINK_NUM_CHIPSELECTS; -+ master->dev.of_node = pdev->dev.of_node; -+ -+ dev_set_drvdata(&pdev->dev, master); -+ -+ rs = spi_master_get_devdata(master); -+ rs->master = master; -+ -+ rs->clk = clk_get(&pdev->dev, NULL); -+ if (IS_ERR(rs->clk)) { -+ status = PTR_ERR(rs->clk); -+ dev_err(&pdev->dev, "unable to get SYS clock, err=%d\n", -+ status); -+ goto out_put_master; -+ } -+ -+ status = clk_enable(rs->clk); -+ if (status) -+ goto out_put_clk; -+ -+ rs->sys_freq = clk_get_rate(rs->clk); -+ spi_debug("%s: sys_freq: %u\n", __func__, rs->sys_freq); -+ -+ r = platform_get_resource(pdev, IORESOURCE_MEM, 0); -+ if (r == NULL) { -+ status = -ENODEV; -+ goto out_disable_clk; -+ } -+ -+ rs->base = devm_request_and_ioremap(&pdev->dev, r); -+ if (!rs->base) { -+ status = -EADDRNOTAVAIL; -+ goto out_disable_clk; -+ } -+ -+ ralink_spi_reset(rs); -+ -+ status = spi_register_master(master); -+ if (status) -+ goto out_disable_clk; -+ -+ return 0; -+ -+out_disable_clk: -+ clk_disable(rs->clk); -+out_put_clk: -+ clk_put(rs->clk); -+out_put_master: -+ spi_master_put(master); -+ return status; -+} -+ -+static int ralink_spi_remove(struct platform_device *pdev) -+{ -+ struct spi_master *master; -+ struct ralink_spi *rs; -+ -+ master = dev_get_drvdata(&pdev->dev); -+ rs = spi_master_get_devdata(master); -+ -+ clk_disable(rs->clk); -+ clk_put(rs->clk); -+ spi_unregister_master(master); -+ -+ return 0; -+} -+ -+MODULE_ALIAS("platform:" DRIVER_NAME); -+ -+static const struct of_device_id ralink_spi_match[] = { -+ { .compatible = "ralink,rt2880-spi" }, -+ {}, -+}; -+MODULE_DEVICE_TABLE(of, ralink_spi_match); -+ -+static struct platform_driver ralink_spi_driver = { -+ .driver = { -+ .name = DRIVER_NAME, -+ .owner = THIS_MODULE, -+ .of_match_table = ralink_spi_match, -+ }, -+ .probe = ralink_spi_probe, -+ .remove = ralink_spi_remove, -+}; -+ -+module_platform_driver(ralink_spi_driver); -+ -+MODULE_DESCRIPTION("Ralink SPI driver"); -+MODULE_AUTHOR("Sergiy "); -+MODULE_AUTHOR("Gabor Juhos "); -+MODULE_LICENSE("GPL"); diff --git a/target/linux/ramips/patches-3.8/0116-DT-add-documentation-for-the-Ralink-MIPS-SoCs.patch b/target/linux/ramips/patches-3.8/0116-DT-add-documentation-for-the-Ralink-MIPS-SoCs.patch new file mode 100644 index 0000000000..f9463c4cb0 --- /dev/null +++ b/target/linux/ramips/patches-3.8/0116-DT-add-documentation-for-the-Ralink-MIPS-SoCs.patch @@ -0,0 +1,38 @@ +From fed1ff0d85b481bb3dbebf31e0720d65ce4170c9 Mon Sep 17 00:00:00 2001 +From: Gabor Juhos +Date: Sat, 13 Apr 2013 09:02:40 +0200 +Subject: [PATCH 116/137] DT: add documentation for the Ralink MIPS SoCs + +This patch adds binding documentation for the +compatible values of the Ralink MIPS SoCs. + +Signed-off-by: Gabor Juhos +Signed-off-by: John Crispin +Acked-by: Grant Likely +Patchwork: http://patchwork.linux-mips.org/patch/5187/ +--- + Documentation/devicetree/bindings/mips/ralink.txt | 18 ++++++++++++++++++ + 1 file changed, 18 insertions(+) + create mode 100644 Documentation/devicetree/bindings/mips/ralink.txt + +--- /dev/null ++++ b/Documentation/devicetree/bindings/mips/ralink.txt +@@ -0,0 +1,18 @@ ++Ralink MIPS SoC device tree bindings ++ ++1. SoCs ++ ++Each device tree must specify a compatible value for the Ralink SoC ++it uses in the compatible property of the root node. The compatible ++value must be one of the following values: ++ ++ ralink,rt2880-soc ++ ralink,rt3050-soc ++ ralink,rt3052-soc ++ ralink,rt3350-soc ++ ralink,rt3352-soc ++ ralink,rt3883-soc ++ ralink,rt5350-soc ++ ralink,mt7620a-soc ++ ralink,mt7620n-soc ++ diff --git a/target/linux/ramips/patches-3.8/0116-serial-of-allow-au1x00-and-rt288x-to-load-from-OF.patch b/target/linux/ramips/patches-3.8/0116-serial-of-allow-au1x00-and-rt288x-to-load-from-OF.patch deleted file mode 100644 index a5a3770c14..0000000000 --- a/target/linux/ramips/patches-3.8/0116-serial-of-allow-au1x00-and-rt288x-to-load-from-OF.patch +++ /dev/null @@ -1,27 +0,0 @@ -From 6ffb42870411ca082e8e46d96d72bc5d8881ce8d Mon Sep 17 00:00:00 2001 -From: John Crispin -Date: Tue, 22 Jan 2013 16:01:07 +0100 -Subject: [PATCH 116/121] serial: of: allow au1x00 and rt288x to load from OF - -In order to make serial_8250 loadable via OF on Au1x00 and Ralink WiSoC we need -to default the iotype to UPIO_AU. - -Signed-off-by: John Crispin ---- - drivers/tty/serial/of_serial.c | 5 ++++- - 1 file changed, 4 insertions(+), 1 deletion(-) - ---- a/drivers/tty/serial/of_serial.c -+++ b/drivers/tty/serial/of_serial.c -@@ -97,7 +97,10 @@ static int of_platform_serial_setup(stru - port->regshift = prop; - - port->irq = irq_of_parse_and_map(np, 0); -- port->iotype = UPIO_MEM; -+ if (of_device_is_compatible(np, "ralink,rt2880-uart")) -+ port->iotype = UPIO_AU; -+ else -+ port->iotype = UPIO_MEM; - if (of_property_read_u32(np, "reg-io-width", &prop) == 0) { - switch (prop) { - case 1: diff --git a/target/linux/ramips/patches-3.8/0117-DT-MIPS-ralink-clean-up-RT3050-dtsi-and-dts-file.patch b/target/linux/ramips/patches-3.8/0117-DT-MIPS-ralink-clean-up-RT3050-dtsi-and-dts-file.patch new file mode 100644 index 0000000000..1328b432a8 --- /dev/null +++ b/target/linux/ramips/patches-3.8/0117-DT-MIPS-ralink-clean-up-RT3050-dtsi-and-dts-file.patch @@ -0,0 +1,117 @@ +From 7a30e00a278fe94ac8e42d0967ffde99d1ab74ee Mon Sep 17 00:00:00 2001 +From: John Crispin +Date: Thu, 21 Mar 2013 17:47:07 +0100 +Subject: [PATCH 117/137] DT: MIPS: ralink: clean up RT3050 dtsi and dts file + +* remove nodes for cores whose drivers are not upstream yet +* add compat string for an additional soc +* fix a whitespace error + +Signed-off-by: John Crispin +Acked-by: Grant Likely +Patchwork: http://patchwork.linux-mips.org/patch/5186/ +--- + arch/mips/ralink/dts/rt3050.dtsi | 52 ++-------------------------------- + arch/mips/ralink/dts/rt3052_eval.dts | 10 ++----- + 2 files changed, 4 insertions(+), 58 deletions(-) + +--- a/arch/mips/ralink/dts/rt3050.dtsi ++++ b/arch/mips/ralink/dts/rt3050.dtsi +@@ -1,7 +1,7 @@ + / { + #address-cells = <1>; + #size-cells = <1>; +- compatible = "ralink,rt3050-soc", "ralink,rt3052-soc"; ++ compatible = "ralink,rt3050-soc", "ralink,rt3052-soc", "ralink,rt3350-soc"; + + cpus { + cpu@0 { +@@ -9,10 +9,6 @@ + }; + }; + +- chosen { +- bootargs = "console=ttyS0,57600 init=/init"; +- }; +- + cpuintc: cpuintc@0 { + #address-cells = <0>; + #interrupt-cells = <1>; +@@ -23,7 +19,7 @@ + palmbus@10000000 { + compatible = "palmbus"; + reg = <0x10000000 0x200000>; +- ranges = <0x0 0x10000000 0x1FFFFF>; ++ ranges = <0x0 0x10000000 0x1FFFFF>; + + #address-cells = <1>; + #size-cells = <1>; +@@ -33,11 +29,6 @@ + reg = <0x0 0x100>; + }; + +- timer@100 { +- compatible = "ralink,rt3052-wdt", "ralink,rt2880-wdt"; +- reg = <0x100 0x100>; +- }; +- + intc: intc@200 { + compatible = "ralink,rt3052-intc", "ralink,rt2880-intc"; + reg = <0x200 0x100>; +@@ -54,45 +45,6 @@ + reg = <0x300 0x100>; + }; + +- gpio0: gpio@600 { +- compatible = "ralink,rt3052-gpio", "ralink,rt2880-gpio"; +- reg = <0x600 0x34>; +- +- gpio-controller; +- #gpio-cells = <2>; +- +- ralink,ngpio = <24>; +- ralink,regs = [ 00 04 08 0c +- 20 24 28 2c +- 30 34 ]; +- }; +- +- gpio1: gpio@638 { +- compatible = "ralink,rt3052-gpio", "ralink,rt2880-gpio"; +- reg = <0x638 0x24>; +- +- gpio-controller; +- #gpio-cells = <2>; +- +- ralink,ngpio = <16>; +- ralink,regs = [ 00 04 08 0c +- 10 14 18 1c +- 20 24 ]; +- }; +- +- gpio2: gpio@660 { +- compatible = "ralink,rt3052-gpio", "ralink,rt2880-gpio"; +- reg = <0x660 0x24>; +- +- gpio-controller; +- #gpio-cells = <2>; +- +- ralink,ngpio = <12>; +- ralink,regs = [ 00 04 08 0c +- 10 14 18 1c +- 20 24 ]; +- }; +- + uartlite@c00 { + compatible = "ralink,rt3052-uart", "ralink,rt2880-uart", "ns16550a"; + reg = <0xc00 0x100>; +--- a/arch/mips/ralink/dts/rt3052_eval.dts ++++ b/arch/mips/ralink/dts/rt3052_eval.dts +@@ -3,8 +3,6 @@ + /include/ "rt3050.dtsi" + + / { +- #address-cells = <1>; +- #size-cells = <1>; + compatible = "ralink,rt3052-eval-board", "ralink,rt3052-soc"; + model = "Ralink RT3052 evaluation board"; + diff --git a/target/linux/ramips/patches-3.8/0117-serial-ralink-adds-mt7620-serial.patch b/target/linux/ramips/patches-3.8/0117-serial-ralink-adds-mt7620-serial.patch deleted file mode 100644 index 745a23602a..0000000000 --- a/target/linux/ramips/patches-3.8/0117-serial-ralink-adds-mt7620-serial.patch +++ /dev/null @@ -1,23 +0,0 @@ -From c1e24bf32404bec0032221b9ea37d6fd8c45dbdd Mon Sep 17 00:00:00 2001 -From: John Crispin -Date: Fri, 15 Mar 2013 18:16:01 +0100 -Subject: [PATCH 117/121] serial: ralink: adds mt7620 serial - -Add the config symbol for Mediatek7620 SoC to SERIAL_8250_RT288X - -Signed-off-by: John Crispin ---- - drivers/tty/serial/8250/Kconfig | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - ---- a/drivers/tty/serial/8250/Kconfig -+++ b/drivers/tty/serial/8250/Kconfig -@@ -280,7 +280,7 @@ config SERIAL_8250_EM - - config SERIAL_8250_RT288X - bool "Ralink RT288x/RT305x/RT3662/RT3883 serial port support" -- depends on SERIAL_8250 && (SOC_RT288X || SOC_RT305X || SOC_RT3883) -+ depends on SERIAL_8250 && (SOC_RT288X || SOC_RT305X || SOC_RT3883 || SOC_MT7620) - help - If you have a Ralink RT288x/RT305x SoC based board and want to use the - serial port, say Y to this option. The driver can handle up to 2 serial diff --git a/target/linux/ramips/patches-3.8/0118-DT-MIPS-ralink-add-RT2880-dts-files.patch b/target/linux/ramips/patches-3.8/0118-DT-MIPS-ralink-add-RT2880-dts-files.patch new file mode 100644 index 0000000000..8ad9b18eb8 --- /dev/null +++ b/target/linux/ramips/patches-3.8/0118-DT-MIPS-ralink-add-RT2880-dts-files.patch @@ -0,0 +1,147 @@ +From b39e659770cb71939765de8c9e73c0a0cfa832db Mon Sep 17 00:00:00 2001 +From: John Crispin +Date: Fri, 12 Apr 2013 06:27:37 +0000 +Subject: [PATCH 118/137] DT: MIPS: ralink: add RT2880 dts files + +Add a dtsi file for RT2880 SoC and a sample dts file. + +Signed-off-by: John Crispin +Acked-by: Grant Likely +Patchwork: http://patchwork.linux-mips.org/patch/5188/ +--- + arch/mips/ralink/Kconfig | 4 +++ + arch/mips/ralink/dts/Makefile | 1 + + arch/mips/ralink/dts/rt2880.dtsi | 58 ++++++++++++++++++++++++++++++++++ + arch/mips/ralink/dts/rt2880_eval.dts | 46 +++++++++++++++++++++++++++ + 4 files changed, 109 insertions(+) + create mode 100644 arch/mips/ralink/dts/rt2880.dtsi + create mode 100644 arch/mips/ralink/dts/rt2880_eval.dts + +--- a/arch/mips/ralink/Kconfig ++++ b/arch/mips/ralink/Kconfig +@@ -34,6 +34,10 @@ choice + config DTB_RT_NONE + bool "None" + ++ config DTB_RT2880_EVAL ++ bool "RT2880 eval kit" ++ depends on SOC_RT288X ++ + config DTB_RT305X_EVAL + bool "RT305x eval kit" + depends on SOC_RT305X +--- a/arch/mips/ralink/dts/Makefile ++++ b/arch/mips/ralink/dts/Makefile +@@ -1 +1,2 @@ ++obj-$(CONFIG_DTB_RT2880_EVAL) := rt2880_eval.dtb.o + obj-$(CONFIG_DTB_RT305X_EVAL) := rt3052_eval.dtb.o +--- /dev/null ++++ b/arch/mips/ralink/dts/rt2880.dtsi +@@ -0,0 +1,58 @@ ++/ { ++ #address-cells = <1>; ++ #size-cells = <1>; ++ compatible = "ralink,rt2880-soc"; ++ ++ cpus { ++ cpu@0 { ++ compatible = "mips,mips4KEc"; ++ }; ++ }; ++ ++ cpuintc: cpuintc@0 { ++ #address-cells = <0>; ++ #interrupt-cells = <1>; ++ interrupt-controller; ++ compatible = "mti,cpu-interrupt-controller"; ++ }; ++ ++ palmbus@300000 { ++ compatible = "palmbus"; ++ reg = <0x300000 0x200000>; ++ ranges = <0x0 0x300000 0x1FFFFF>; ++ ++ #address-cells = <1>; ++ #size-cells = <1>; ++ ++ sysc@0 { ++ compatible = "ralink,rt2880-sysc"; ++ reg = <0x0 0x100>; ++ }; ++ ++ intc: intc@200 { ++ compatible = "ralink,rt2880-intc"; ++ reg = <0x200 0x100>; ++ ++ interrupt-controller; ++ #interrupt-cells = <1>; ++ ++ interrupt-parent = <&cpuintc>; ++ interrupts = <2>; ++ }; ++ ++ memc@300 { ++ compatible = "ralink,rt2880-memc"; ++ reg = <0x300 0x100>; ++ }; ++ ++ uartlite@c00 { ++ compatible = "ralink,rt2880-uart", "ns16550a"; ++ reg = <0xc00 0x100>; ++ ++ interrupt-parent = <&intc>; ++ interrupts = <8>; ++ ++ reg-shift = <2>; ++ }; ++ }; ++}; +--- /dev/null ++++ b/arch/mips/ralink/dts/rt2880_eval.dts +@@ -0,0 +1,46 @@ ++/dts-v1/; ++ ++/include/ "rt2880.dtsi" ++ ++/ { ++ compatible = "ralink,rt2880-eval-board", "ralink,rt2880-soc"; ++ model = "Ralink RT2880 evaluation board"; ++ ++ memory@0 { ++ reg = <0x8000000 0x2000000>; ++ }; ++ ++ chosen { ++ bootargs = "console=ttyS0,57600"; ++ }; ++ ++ cfi@1f000000 { ++ compatible = "cfi-flash"; ++ reg = <0x1f000000 0x400000>; ++ ++ bank-width = <2>; ++ device-width = <2>; ++ #address-cells = <1>; ++ #size-cells = <1>; ++ ++ partition@0 { ++ label = "uboot"; ++ reg = <0x0 0x30000>; ++ read-only; ++ }; ++ partition@30000 { ++ label = "uboot-env"; ++ reg = <0x30000 0x10000>; ++ read-only; ++ }; ++ partition@40000 { ++ label = "calibration"; ++ reg = <0x40000 0x10000>; ++ read-only; ++ }; ++ partition@50000 { ++ label = "linux"; ++ reg = <0x50000 0x3b0000>; ++ }; ++ }; ++}; diff --git a/target/linux/ramips/patches-3.8/0118-PCI-MIPS-adds-rt2880-pci-support.patch b/target/linux/ramips/patches-3.8/0118-PCI-MIPS-adds-rt2880-pci-support.patch deleted file mode 100644 index dc0622805b..0000000000 --- a/target/linux/ramips/patches-3.8/0118-PCI-MIPS-adds-rt2880-pci-support.patch +++ /dev/null @@ -1,319 +0,0 @@ -From 028f340b63bf722e8807b31ef955484acf2cce47 Mon Sep 17 00:00:00 2001 -From: John Crispin -Date: Thu, 21 Mar 2013 18:27:29 +0100 -Subject: [PATCH 118/121] PCI: MIPS: adds rt2880 pci support - -Add support for the pci found on the rt2880 SoC. - -Signed-off-by: John Crispin ---- - arch/mips/pci/Makefile | 1 + - arch/mips/pci/pci-rt2880.c | 281 ++++++++++++++++++++++++++++++++++++++++++++ - arch/mips/ralink/Kconfig | 1 + - 3 files changed, 283 insertions(+) - create mode 100644 arch/mips/pci/pci-rt2880.c - ---- a/arch/mips/pci/Makefile -+++ b/arch/mips/pci/Makefile -@@ -42,6 +42,7 @@ obj-$(CONFIG_SIBYTE_BCM1x80) += pci-bcm1 - 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_RT2880) += pci-rt2880.o - obj-$(CONFIG_TANBAC_TB0219) += fixup-tb0219.o - obj-$(CONFIG_TANBAC_TB0226) += fixup-tb0226.o - obj-$(CONFIG_TANBAC_TB0287) += fixup-tb0287.o ---- /dev/null -+++ b/arch/mips/pci/pci-rt2880.c -@@ -0,0 +1,281 @@ -+/* -+ * Ralink RT288x SoC PCI register definitions -+ * -+ * Copyright (C) 2009 John Crispin -+ * Copyright (C) 2009 Gabor Juhos -+ * -+ * Parts of this file are based on Ralink's 2.6.21 BSP -+ * -+ * This program is free software; you can redistribute it and/or modify it -+ * under the terms of the GNU General Public License version 2 as published -+ * by the Free Software Foundation. -+ */ -+ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+ -+#include -+ -+#define RT2880_PCI_BASE 0x00440000 -+#define RT288X_CPU_IRQ_PCI 4 -+ -+#define RT2880_PCI_MEM_BASE 0x20000000 -+#define RT2880_PCI_MEM_SIZE 0x10000000 -+#define RT2880_PCI_IO_BASE 0x00460000 -+#define RT2880_PCI_IO_SIZE 0x00010000 -+ -+#define RT2880_PCI_REG_PCICFG_ADDR 0x00 -+#define RT2880_PCI_REG_PCIMSK_ADDR 0x0c -+#define RT2880_PCI_REG_BAR0SETUP_ADDR 0x10 -+#define RT2880_PCI_REG_IMBASEBAR0_ADDR 0x18 -+#define RT2880_PCI_REG_CONFIG_ADDR 0x20 -+#define RT2880_PCI_REG_CONFIG_DATA 0x24 -+#define RT2880_PCI_REG_MEMBASE 0x28 -+#define RT2880_PCI_REG_IOBASE 0x2c -+#define RT2880_PCI_REG_ID 0x30 -+#define RT2880_PCI_REG_CLASS 0x34 -+#define RT2880_PCI_REG_SUBID 0x38 -+#define RT2880_PCI_REG_ARBCTL 0x80 -+ -+static void __iomem *rt2880_pci_base; -+static DEFINE_SPINLOCK(rt2880_pci_lock); -+ -+static u32 rt2880_pci_reg_read(u32 reg) -+{ -+ return readl(rt2880_pci_base + reg); -+} -+ -+static void rt2880_pci_reg_write(u32 val, u32 reg) -+{ -+ writel(val, rt2880_pci_base + reg); -+} -+ -+static inline u32 rt2880_pci_get_cfgaddr(unsigned int bus, unsigned int slot, -+ unsigned int func, unsigned int where) -+{ -+ return ((bus << 16) | (slot << 11) | (func << 8) | (where & 0xfc) | -+ 0x80000000); -+} -+ -+static int rt2880_pci_config_read(struct pci_bus *bus, unsigned int devfn, -+ int where, int size, u32 *val) -+{ -+ unsigned long flags; -+ u32 address; -+ u32 data; -+ -+ address = rt2880_pci_get_cfgaddr(bus->number, PCI_SLOT(devfn), -+ PCI_FUNC(devfn), where); -+ -+ spin_lock_irqsave(&rt2880_pci_lock, flags); -+ rt2880_pci_reg_write(address, RT2880_PCI_REG_CONFIG_ADDR); -+ data = rt2880_pci_reg_read(RT2880_PCI_REG_CONFIG_DATA); -+ spin_unlock_irqrestore(&rt2880_pci_lock, flags); -+ -+ switch (size) { -+ case 1: -+ *val = (data >> ((where & 3) << 3)) & 0xff; -+ break; -+ case 2: -+ *val = (data >> ((where & 3) << 3)) & 0xffff; -+ break; -+ case 4: -+ *val = data; -+ break; -+ } -+ -+ return PCIBIOS_SUCCESSFUL; -+} -+ -+static int rt2880_pci_config_write(struct pci_bus *bus, unsigned int devfn, -+ int where, int size, u32 val) -+{ -+ unsigned long flags; -+ u32 address; -+ u32 data; -+ -+ address = rt2880_pci_get_cfgaddr(bus->number, PCI_SLOT(devfn), -+ PCI_FUNC(devfn), where); -+ -+ spin_lock_irqsave(&rt2880_pci_lock, flags); -+ rt2880_pci_reg_write(address, RT2880_PCI_REG_CONFIG_ADDR); -+ data = rt2880_pci_reg_read(RT2880_PCI_REG_CONFIG_DATA); -+ -+ switch (size) { -+ case 1: -+ data = (data & ~(0xff << ((where & 3) << 3))) | -+ (val << ((where & 3) << 3)); -+ break; -+ case 2: -+ data = (data & ~(0xffff << ((where & 3) << 3))) | -+ (val << ((where & 3) << 3)); -+ break; -+ case 4: -+ data = val; -+ break; -+ } -+ -+ rt2880_pci_reg_write(data, RT2880_PCI_REG_CONFIG_DATA); -+ spin_unlock_irqrestore(&rt2880_pci_lock, flags); -+ -+ return PCIBIOS_SUCCESSFUL; -+} -+ -+static struct pci_ops rt2880_pci_ops = { -+ .read = rt2880_pci_config_read, -+ .write = rt2880_pci_config_write, -+}; -+ -+static struct resource rt2880_pci_mem_resource = { -+ .name = "PCI MEM space", -+ .start = RT2880_PCI_MEM_BASE, -+ .end = RT2880_PCI_MEM_BASE + RT2880_PCI_MEM_SIZE - 1, -+ .flags = IORESOURCE_MEM, -+}; -+ -+static struct resource rt2880_pci_io_resource = { -+ .name = "PCI IO space", -+ .start = RT2880_PCI_IO_BASE, -+ .end = RT2880_PCI_IO_BASE + RT2880_PCI_IO_SIZE - 1, -+ .flags = IORESOURCE_IO, -+}; -+ -+static struct pci_controller rt2880_pci_controller = { -+ .pci_ops = &rt2880_pci_ops, -+ .mem_resource = &rt2880_pci_mem_resource, -+ .io_resource = &rt2880_pci_io_resource, -+}; -+ -+static inline u32 rt2880_pci_read_u32(unsigned long reg) -+{ -+ unsigned long flags; -+ u32 address; -+ u32 ret; -+ -+ address = rt2880_pci_get_cfgaddr(0, 0, 0, reg); -+ -+ spin_lock_irqsave(&rt2880_pci_lock, flags); -+ rt2880_pci_reg_write(address, RT2880_PCI_REG_CONFIG_ADDR); -+ ret = rt2880_pci_reg_read(RT2880_PCI_REG_CONFIG_DATA); -+ spin_unlock_irqrestore(&rt2880_pci_lock, flags); -+ -+ return ret; -+} -+ -+static inline void rt2880_pci_write_u32(unsigned long reg, u32 val) -+{ -+ unsigned long flags; -+ u32 address; -+ -+ address = rt2880_pci_get_cfgaddr(0, 0, 0, reg); -+ -+ spin_lock_irqsave(&rt2880_pci_lock, flags); -+ rt2880_pci_reg_write(address, RT2880_PCI_REG_CONFIG_ADDR); -+ rt2880_pci_reg_write(val, RT2880_PCI_REG_CONFIG_DATA); -+ spin_unlock_irqrestore(&rt2880_pci_lock, flags); -+} -+ -+int __init pcibios_map_irq(const struct pci_dev *dev, u8 slot, u8 pin) -+{ -+ u16 cmd; -+ int irq = -1; -+ -+ if (dev->bus->number != 0) -+ return irq; -+ -+ switch (PCI_SLOT(dev->devfn)) { -+ case 0x00: -+ rt2880_pci_write_u32(PCI_BASE_ADDRESS_0, 0x08000000); -+ (void) rt2880_pci_read_u32(PCI_BASE_ADDRESS_0); -+ break; -+ case 0x11: -+ irq = RT288X_CPU_IRQ_PCI; -+ break; -+ default: -+ printk("%s:%s[%d] trying to alloc unknown pci irq\n", -+ __FILE__, __func__, __LINE__); -+ BUG(); -+ break; -+ } -+ -+ pci_write_config_byte((struct pci_dev*)dev, PCI_CACHE_LINE_SIZE, 0x14); -+ pci_write_config_byte((struct pci_dev*)dev, PCI_LATENCY_TIMER, 0xFF); -+ pci_read_config_word((struct pci_dev*)dev, PCI_COMMAND, &cmd); -+ cmd |= PCI_COMMAND_MASTER | PCI_COMMAND_IO | PCI_COMMAND_MEMORY | -+ PCI_COMMAND_INVALIDATE | PCI_COMMAND_FAST_BACK | -+ PCI_COMMAND_SERR | PCI_COMMAND_WAIT | PCI_COMMAND_PARITY; -+ pci_write_config_word((struct pci_dev*)dev, PCI_COMMAND, cmd); -+ pci_write_config_byte((struct pci_dev*)dev, PCI_INTERRUPT_LINE, -+ dev->irq); -+ return irq; -+} -+ -+static int rt288x_pci_probe(struct platform_device *pdev) -+{ -+ void __iomem *io_map_base; -+ int i; -+ -+ rt2880_pci_base = ioremap_nocache(RT2880_PCI_BASE, PAGE_SIZE); -+ -+ io_map_base = ioremap(RT2880_PCI_IO_BASE, RT2880_PCI_IO_SIZE); -+ rt2880_pci_controller.io_map_base = (unsigned long) io_map_base; -+ set_io_port_base((unsigned long) io_map_base); -+ -+ ioport_resource.start = RT2880_PCI_IO_BASE; -+ ioport_resource.end = RT2880_PCI_IO_BASE + RT2880_PCI_IO_SIZE - 1; -+ -+ rt2880_pci_reg_write(0, RT2880_PCI_REG_PCICFG_ADDR); -+ for(i = 0; i < 0xfffff; i++) {} -+ -+ rt2880_pci_reg_write(0x79, RT2880_PCI_REG_ARBCTL); -+ rt2880_pci_reg_write(0x07FF0001, RT2880_PCI_REG_BAR0SETUP_ADDR); -+ rt2880_pci_reg_write(RT2880_PCI_MEM_BASE, RT2880_PCI_REG_MEMBASE); -+ rt2880_pci_reg_write(RT2880_PCI_IO_BASE, RT2880_PCI_REG_IOBASE); -+ rt2880_pci_reg_write(0x08000000, RT2880_PCI_REG_IMBASEBAR0_ADDR); -+ rt2880_pci_reg_write(0x08021814, RT2880_PCI_REG_ID); -+ rt2880_pci_reg_write(0x00800001, RT2880_PCI_REG_CLASS); -+ rt2880_pci_reg_write(0x28801814, RT2880_PCI_REG_SUBID); -+ rt2880_pci_reg_write(0x000c0000, RT2880_PCI_REG_PCIMSK_ADDR); -+ -+ rt2880_pci_write_u32(PCI_BASE_ADDRESS_0, 0x08000000); -+ (void) rt2880_pci_read_u32(PCI_BASE_ADDRESS_0); -+ -+ register_pci_controller(&rt2880_pci_controller); -+ return 0; -+} -+ -+int pcibios_plat_dev_init(struct pci_dev *dev) -+{ -+ return 0; -+} -+ -+static const struct of_device_id rt288x_pci_match[] = { -+ { .compatible = "ralink,rt288x-pci" }, -+ {}, -+}; -+MODULE_DEVICE_TABLE(of, rt288x_pci_match); -+ -+static struct platform_driver rt288x_pci_driver = { -+ .probe = rt288x_pci_probe, -+ .driver = { -+ .name = "rt288x-pci", -+ .owner = THIS_MODULE, -+ .of_match_table = rt288x_pci_match, -+ }, -+}; -+ -+int __init pcibios_init(void) -+{ -+ int ret = platform_driver_register(&rt288x_pci_driver); -+ if (ret) -+ pr_info("rt288x-pci: Error registering platform driver!"); -+ return ret; -+} -+ -+arch_initcall(pcibios_init); ---- a/arch/mips/ralink/Kconfig -+++ b/arch/mips/ralink/Kconfig -@@ -8,6 +8,7 @@ choice - - config SOC_RT288X - bool "RT288x" -+ select HW_HAS_PCI - - config SOC_RT305X - bool "RT305x" diff --git a/target/linux/ramips/patches-3.8/0119-DT-MIPS-ralink-add-RT3883-dts-files.patch b/target/linux/ramips/patches-3.8/0119-DT-MIPS-ralink-add-RT3883-dts-files.patch new file mode 100644 index 0000000000..90b50eda72 --- /dev/null +++ b/target/linux/ramips/patches-3.8/0119-DT-MIPS-ralink-add-RT3883-dts-files.patch @@ -0,0 +1,118 @@ +From 8b02459b5aa171dc8726698c4b19341a4e441bb8 Mon Sep 17 00:00:00 2001 +From: John Crispin +Date: Fri, 12 Apr 2013 06:27:39 +0000 +Subject: [PATCH 119/137] DT: MIPS: ralink: add RT3883 dts files + +Add a dtsi file for RT3883 SoC and a sample dts file. + +Signed-off-by: John Crispin +Acked-by: Grant Likely +Patchwork: http://patchwork.linux-mips.org/patch/5189/ +--- + arch/mips/ralink/Kconfig | 4 +++ + arch/mips/ralink/dts/Makefile | 1 + + arch/mips/ralink/dts/rt3883.dtsi | 58 ++++++++++++++++++++++++++++++++++ + arch/mips/ralink/dts/rt3883_eval.dts | 16 ++++++++++ + 4 files changed, 79 insertions(+) + create mode 100644 arch/mips/ralink/dts/rt3883.dtsi + create mode 100644 arch/mips/ralink/dts/rt3883_eval.dts + +--- a/arch/mips/ralink/Kconfig ++++ b/arch/mips/ralink/Kconfig +@@ -42,6 +42,10 @@ choice + bool "RT305x eval kit" + depends on SOC_RT305X + ++ config DTB_RT3883_EVAL ++ bool "RT3883 eval kit" ++ depends on SOC_RT3883 ++ + endchoice + + endif +--- a/arch/mips/ralink/dts/Makefile ++++ b/arch/mips/ralink/dts/Makefile +@@ -1,2 +1,3 @@ + obj-$(CONFIG_DTB_RT2880_EVAL) := rt2880_eval.dtb.o + obj-$(CONFIG_DTB_RT305X_EVAL) := rt3052_eval.dtb.o ++obj-$(CONFIG_DTB_RT3883_EVAL) := rt3883_eval.dtb.o +--- /dev/null ++++ b/arch/mips/ralink/dts/rt3883.dtsi +@@ -0,0 +1,58 @@ ++/ { ++ #address-cells = <1>; ++ #size-cells = <1>; ++ compatible = "ralink,rt3883-soc"; ++ ++ cpus { ++ cpu@0 { ++ compatible = "mips,mips74Kc"; ++ }; ++ }; ++ ++ cpuintc: cpuintc@0 { ++ #address-cells = <0>; ++ #interrupt-cells = <1>; ++ interrupt-controller; ++ compatible = "mti,cpu-interrupt-controller"; ++ }; ++ ++ palmbus@10000000 { ++ compatible = "palmbus"; ++ reg = <0x10000000 0x200000>; ++ ranges = <0x0 0x10000000 0x1FFFFF>; ++ ++ #address-cells = <1>; ++ #size-cells = <1>; ++ ++ sysc@0 { ++ compatible = "ralink,rt3883-sysc", "ralink,rt3050-sysc"; ++ reg = <0x0 0x100>; ++ }; ++ ++ intc: intc@200 { ++ compatible = "ralink,rt3883-intc", "ralink,rt2880-intc"; ++ reg = <0x200 0x100>; ++ ++ interrupt-controller; ++ #interrupt-cells = <1>; ++ ++ interrupt-parent = <&cpuintc>; ++ interrupts = <2>; ++ }; ++ ++ memc@300 { ++ compatible = "ralink,rt3883-memc", "ralink,rt3050-memc"; ++ reg = <0x300 0x100>; ++ }; ++ ++ uartlite@c00 { ++ compatible = "ralink,rt3883-uart", "ralink,rt2880-uart", "ns16550a"; ++ reg = <0xc00 0x100>; ++ ++ interrupt-parent = <&intc>; ++ interrupts = <12>; ++ ++ reg-shift = <2>; ++ }; ++ }; ++}; +--- /dev/null ++++ b/arch/mips/ralink/dts/rt3883_eval.dts +@@ -0,0 +1,16 @@ ++/dts-v1/; ++ ++/include/ "rt3883.dtsi" ++ ++/ { ++ compatible = "ralink,rt3883-eval-board", "ralink,rt3883-soc"; ++ model = "Ralink RT3883 evaluation board"; ++ ++ memory@0 { ++ reg = <0x0 0x2000000>; ++ }; ++ ++ chosen { ++ bootargs = "console=ttyS0,57600"; ++ }; ++}; diff --git a/target/linux/ramips/patches-3.8/0119-PCI-MIPS-adds-rt3883-pci-support.patch b/target/linux/ramips/patches-3.8/0119-PCI-MIPS-adds-rt3883-pci-support.patch deleted file mode 100644 index 32fd20960f..0000000000 --- a/target/linux/ramips/patches-3.8/0119-PCI-MIPS-adds-rt3883-pci-support.patch +++ /dev/null @@ -1,525 +0,0 @@ -From f01830fcc57273bd9ec5f6733ab3d28adeb71955 Mon Sep 17 00:00:00 2001 -From: John Crispin -Date: Thu, 21 Mar 2013 17:34:08 +0100 -Subject: [PATCH 119/121] PCI: MIPS: adds rt3883 pci support - -Add support for the pcie found on the rt3883 SoC. - -Signed-off-by: John Crispin ---- - arch/mips/pci/Makefile | 1 + - arch/mips/pci/pci-rt3883.c | 487 ++++++++++++++++++++++++++++++++++++++++++++ - arch/mips/ralink/Kconfig | 1 + - 3 files changed, 489 insertions(+) - create mode 100644 arch/mips/pci/pci-rt3883.c - ---- a/arch/mips/pci/Makefile -+++ b/arch/mips/pci/Makefile -@@ -43,6 +43,7 @@ obj-$(CONFIG_SNI_RM) += fixup-sni.o ops - obj-$(CONFIG_LANTIQ) += fixup-lantiq.o - obj-$(CONFIG_PCI_LANTIQ) += pci-lantiq.o ops-lantiq.o - obj-$(CONFIG_SOC_RT2880) += pci-rt2880.o -+obj-$(CONFIG_SOC_RT3883) += pci-rt3883.o - obj-$(CONFIG_TANBAC_TB0219) += fixup-tb0219.o - obj-$(CONFIG_TANBAC_TB0226) += fixup-tb0226.o - obj-$(CONFIG_TANBAC_TB0287) += fixup-tb0287.o ---- /dev/null -+++ b/arch/mips/pci/pci-rt3883.c -@@ -0,0 +1,487 @@ -+/* -+ * Ralink RT3883 SoC PCI support -+ * -+ * Copyright (C) 2011-2012 Gabor Juhos -+ * -+ * Parts of this file are based on Ralink's 2.6.21 BSP -+ * -+ * This program is free software; you can redistribute it and/or modify it -+ * under the terms of the GNU General Public License version 2 as published -+ * by the Free Software Foundation. -+ */ -+ -+#include -+#include -+#include -+#include -+#include -+#include -+ -+#include -+#include -+ -+#define RT3883_MEMORY_BASE 0x00000000 -+#define RT3883_MEMORY_SIZE 0x02000000 -+ -+#define RT3883_PCI_MEM_BASE 0x20000000 -+#define RT3883_PCI_MEM_SIZE 0x10000000 -+#define RT3883_PCI_IO_BASE 0x10160000 -+#define RT3883_PCI_IO_SIZE 0x00010000 -+ -+#define RT3883_PCI_REG_PCICFG_ADDR 0x00 -+#define RT3883_PCI_REG_PCIRAW_ADDR 0x04 -+#define RT3883_PCI_REG_PCIINT_ADDR 0x08 -+#define RT3883_PCI_REG_PCIMSK_ADDR 0x0c -+#define RT3833_PCI_PCIINT_PCIE BIT(20) -+#define RT3833_PCI_PCIINT_PCI1 BIT(19) -+#define RT3833_PCI_PCIINT_PCI0 BIT(18) -+ -+#define RT3883_PCI_REG_CONFIG_ADDR 0x20 -+#define RT3883_PCI_REG_CONFIG_DATA 0x24 -+#define RT3883_PCI_REG_MEMBASE 0x28 -+#define RT3883_PCI_REG_IOBASE 0x2c -+#define RT3883_PCI_REG_ARBCTL 0x80 -+ -+#define RT3883_PCI_REG_BASE(_x) (0x1000 + (_x) * 0x1000) -+#define RT3883_PCI_REG_BAR0SETUP_ADDR(_x) (RT3883_PCI_REG_BASE((_x)) + 0x10) -+#define RT3883_PCI_REG_IMBASEBAR0_ADDR(_x) (RT3883_PCI_REG_BASE((_x)) + 0x18) -+#define RT3883_PCI_REG_ID(_x) (RT3883_PCI_REG_BASE((_x)) + 0x30) -+#define RT3883_PCI_REG_CLASS(_x) (RT3883_PCI_REG_BASE((_x)) + 0x34) -+#define RT3883_PCI_REG_SUBID(_x) (RT3883_PCI_REG_BASE((_x)) + 0x38) -+#define RT3883_PCI_REG_STATUS(_x) (RT3883_PCI_REG_BASE((_x)) + 0x50) -+ -+static int (*rt3883_pci_plat_dev_init)(struct pci_dev *dev); -+static void __iomem *rt3883_pci_base; -+static DEFINE_SPINLOCK(rt3883_pci_lock); -+ -+static inline u32 rt3883_pci_rr(unsigned reg) -+{ -+ return readl(rt3883_pci_base + reg); -+} -+ -+static inline void rt3883_pci_wr(u32 val, unsigned reg) -+{ -+ writel(val, rt3883_pci_base + reg); -+} -+ -+static inline u32 rt3883_pci_get_cfgaddr(unsigned int bus, unsigned int slot, -+ unsigned int func, unsigned int where) -+{ -+ return ((bus << 16) | (slot << 11) | (func << 8) | (where & 0xfc) | -+ 0x80000000); -+} -+ -+static u32 rt3883_pci_read_u32(unsigned bus, unsigned slot, -+ unsigned func, unsigned reg) -+{ -+ unsigned long flags; -+ u32 address; -+ u32 ret; -+ -+ address = rt3883_pci_get_cfgaddr(bus, slot, func, reg); -+ -+ spin_lock_irqsave(&rt3883_pci_lock, flags); -+ rt3883_pci_wr(address, RT3883_PCI_REG_CONFIG_ADDR); -+ ret = rt3883_pci_rr(RT3883_PCI_REG_CONFIG_DATA); -+ spin_unlock_irqrestore(&rt3883_pci_lock, flags); -+ -+ return ret; -+} -+ -+static void rt3883_pci_write_u32(unsigned bus, unsigned slot, -+ unsigned func, unsigned reg, u32 val) -+{ -+ unsigned long flags; -+ u32 address; -+ -+ address = rt3883_pci_get_cfgaddr(bus, slot, func, reg); -+ -+ spin_lock_irqsave(&rt3883_pci_lock, flags); -+ rt3883_pci_wr(address, RT3883_PCI_REG_CONFIG_ADDR); -+ rt3883_pci_wr(val, RT3883_PCI_REG_CONFIG_DATA); -+ spin_unlock_irqrestore(&rt3883_pci_lock, flags); -+} -+ -+static void rt3883_pci_irq_handler(unsigned int irq, struct irq_desc *desc) -+{ -+ u32 pending; -+ -+ pending = rt3883_pci_rr(RT3883_PCI_REG_PCIINT_ADDR) & -+ rt3883_pci_rr(RT3883_PCI_REG_PCIMSK_ADDR); -+ -+ if (!pending) { -+ spurious_interrupt(); -+ return; -+ } -+ -+ if (pending & RT3833_PCI_PCIINT_PCI0) -+ generic_handle_irq(RT3883_PCI_IRQ_PCI0); -+ -+ if (pending & RT3833_PCI_PCIINT_PCI1) -+ generic_handle_irq(RT3883_PCI_IRQ_PCI1); -+ -+ if (pending & RT3833_PCI_PCIINT_PCIE) -+ generic_handle_irq(RT3883_PCI_IRQ_PCIE); -+} -+ -+static void rt3883_pci_irq_unmask(struct irq_data *d) -+{ -+ int irq = d->irq; -+ u32 mask; -+ u32 t; -+ -+ switch (irq) { -+ case RT3883_PCI_IRQ_PCI0: -+ mask = RT3833_PCI_PCIINT_PCI0; -+ break; -+ case RT3883_PCI_IRQ_PCI1: -+ mask = RT3833_PCI_PCIINT_PCI1; -+ break; -+ case RT3883_PCI_IRQ_PCIE: -+ mask = RT3833_PCI_PCIINT_PCIE; -+ break; -+ default: -+ BUG(); -+ } -+ -+ t = rt3883_pci_rr(RT3883_PCI_REG_PCIMSK_ADDR); -+ rt3883_pci_wr(t | mask, RT3883_PCI_REG_PCIMSK_ADDR); -+ /* flush write */ -+ rt3883_pci_rr(RT3883_PCI_REG_PCIMSK_ADDR); -+} -+ -+static void rt3883_pci_irq_mask(struct irq_data *d) -+{ -+ int irq = d->irq; -+ u32 mask; -+ u32 t; -+ -+ switch (irq) { -+ case RT3883_PCI_IRQ_PCI0: -+ mask = RT3833_PCI_PCIINT_PCI0; -+ break; -+ case RT3883_PCI_IRQ_PCI1: -+ mask = RT3833_PCI_PCIINT_PCI1; -+ break; -+ case RT3883_PCI_IRQ_PCIE: -+ mask = RT3833_PCI_PCIINT_PCIE; -+ break; -+ default: -+ BUG(); -+ } -+ -+ t = rt3883_pci_rr(RT3883_PCI_REG_PCIMSK_ADDR); -+ rt3883_pci_wr(t & ~mask, RT3883_PCI_REG_PCIMSK_ADDR); -+ /* flush write */ -+ rt3883_pci_rr(RT3883_PCI_REG_PCIMSK_ADDR); -+} -+ -+static struct irq_chip rt3883_pci_irq_chip = { -+ .name = "RT3883 PCI", -+ .irq_mask = rt3883_pci_irq_mask, -+ .irq_unmask = rt3883_pci_irq_unmask, -+ .irq_mask_ack = rt3883_pci_irq_mask, -+}; -+ -+static void __init rt3883_pci_irq_init(void) -+{ -+ int i; -+ -+ /* disable all interrupts */ -+ rt3883_pci_wr(0, RT3883_PCI_REG_PCIMSK_ADDR); -+ -+ for (i = RT3883_PCI_IRQ_BASE; -+ i < RT3883_PCI_IRQ_BASE + RT3883_PCI_IRQ_COUNT; i++) { -+ irq_set_chip_and_handler(i, &rt3883_pci_irq_chip, -+ handle_level_irq); -+ } -+ -+ irq_set_chained_handler(RT3883_CPU_IRQ_PCI, rt3883_pci_irq_handler); -+} -+ -+static int rt3883_pci_config_read(struct pci_bus *bus, unsigned int devfn, -+ int where, int size, u32 *val) -+{ -+ unsigned long flags; -+ u32 address; -+ u32 data; -+ -+ address = rt3883_pci_get_cfgaddr(bus->number, PCI_SLOT(devfn), -+ PCI_FUNC(devfn), where); -+ -+ spin_lock_irqsave(&rt3883_pci_lock, flags); -+ rt3883_pci_wr(address, RT3883_PCI_REG_CONFIG_ADDR); -+ data = rt3883_pci_rr(RT3883_PCI_REG_CONFIG_DATA); -+ spin_unlock_irqrestore(&rt3883_pci_lock, flags); -+ -+ switch (size) { -+ case 1: -+ *val = (data >> ((where & 3) << 3)) & 0xff; -+ break; -+ case 2: -+ *val = (data >> ((where & 3) << 3)) & 0xffff; -+ break; -+ case 4: -+ *val = data; -+ break; -+ } -+ -+ return PCIBIOS_SUCCESSFUL; -+} -+ -+static int rt3883_pci_config_write(struct pci_bus *bus, unsigned int devfn, -+ int where, int size, u32 val) -+{ -+ unsigned long flags; -+ u32 address; -+ u32 data; -+ -+ address = rt3883_pci_get_cfgaddr(bus->number, PCI_SLOT(devfn), -+ PCI_FUNC(devfn), where); -+ -+ spin_lock_irqsave(&rt3883_pci_lock, flags); -+ rt3883_pci_wr(address, RT3883_PCI_REG_CONFIG_ADDR); -+ data = rt3883_pci_rr(RT3883_PCI_REG_CONFIG_DATA); -+ -+ switch (size) { -+ case 1: -+ data = (data & ~(0xff << ((where & 3) << 3))) | -+ (val << ((where & 3) << 3)); -+ break; -+ case 2: -+ data = (data & ~(0xffff << ((where & 3) << 3))) | -+ (val << ((where & 3) << 3)); -+ break; -+ case 4: -+ data = val; -+ break; -+ } -+ -+ rt3883_pci_wr(data, RT3883_PCI_REG_CONFIG_DATA); -+ spin_unlock_irqrestore(&rt3883_pci_lock, flags); -+ -+ return PCIBIOS_SUCCESSFUL; -+} -+ -+static struct pci_ops rt3883_pci_ops = { -+ .read = rt3883_pci_config_read, -+ .write = rt3883_pci_config_write, -+}; -+ -+static struct resource rt3883_pci_mem_resource = { -+ .name = "PCI MEM space", -+ .start = RT3883_PCI_MEM_BASE, -+ .end = RT3883_PCI_MEM_BASE + RT3883_PCI_MEM_SIZE - 1, -+ .flags = IORESOURCE_MEM, -+}; -+ -+static struct resource rt3883_pci_io_resource = { -+ .name = "PCI IO space", -+ .start = RT3883_PCI_IO_BASE, -+ .end = RT3883_PCI_IO_BASE + RT3883_PCI_IO_SIZE - 1, -+ .flags = IORESOURCE_IO, -+}; -+ -+static struct pci_controller rt3883_pci_controller = { -+ .pci_ops = &rt3883_pci_ops, -+ .mem_resource = &rt3883_pci_mem_resource, -+ .io_resource = &rt3883_pci_io_resource, -+}; -+ -+static void rt3883_pci_preinit(unsigned mode) -+{ -+ u32 syscfg1; -+ u32 rstctrl; -+ u32 clkcfg1; -+ -+ if (mode & RT3883_PCI_MODE_PCIE) { -+ u32 val; -+ -+ val = rt3883_sysc_rr(RT3883_SYSC_REG_SYSCFG1); -+ val &= ~(0x30); -+ val |= (2 << 4); -+ rt3883_sysc_wr(val, RT3883_SYSC_REG_SYSCFG1); -+ -+ val = rt3883_sysc_rr(RT3883_SYSC_REG_PCIE_CLK_GEN0); -+ val &= ~BIT(31); -+ rt3883_sysc_wr(val, RT3883_SYSC_REG_PCIE_CLK_GEN0); -+ -+ val = rt3883_sysc_rr(RT3883_SYSC_REG_PCIE_CLK_GEN1); -+ val &= 0x80ffffff; -+ rt3883_sysc_wr(val, RT3883_SYSC_REG_PCIE_CLK_GEN1); -+ -+ val = rt3883_sysc_rr(RT3883_SYSC_REG_PCIE_CLK_GEN1); -+ val |= 0xa << 24; -+ rt3883_sysc_wr(val, RT3883_SYSC_REG_PCIE_CLK_GEN1); -+ -+ val = rt3883_sysc_rr(RT3883_SYSC_REG_PCIE_CLK_GEN0); -+ val |= BIT(31); -+ rt3883_sysc_wr(val, RT3883_SYSC_REG_PCIE_CLK_GEN0); -+ -+ msleep(50); -+ } -+ -+ syscfg1 = rt3883_sysc_rr(RT3883_SYSC_REG_SYSCFG1); -+ syscfg1 &= ~(RT3883_SYSCFG1_PCIE_RC_MODE | -+ RT3883_SYSCFG1_PCI_HOST_MODE); -+ -+ rstctrl = rt3883_sysc_rr(RT3883_SYSC_REG_RSTCTRL); -+ rstctrl |= (RT3883_RSTCTRL_PCI | RT3883_RSTCTRL_PCIE); -+ -+ clkcfg1 = rt3883_sysc_rr(RT3883_SYSC_REG_CLKCFG1); -+ clkcfg1 &= ~(RT3883_CLKCFG1_PCI_CLK_EN | -+ RT3883_CLKCFG1_PCIE_CLK_EN); -+ -+ if (mode & RT3883_PCI_MODE_PCI) { -+ syscfg1 |= RT3883_SYSCFG1_PCI_HOST_MODE; -+ clkcfg1 |= RT3883_CLKCFG1_PCI_CLK_EN; -+ rstctrl &= ~RT3883_RSTCTRL_PCI; -+ } -+ if (mode & RT3883_PCI_MODE_PCIE) { -+ syscfg1 |= RT3883_SYSCFG1_PCI_HOST_MODE | -+ RT3883_SYSCFG1_PCIE_RC_MODE; -+ clkcfg1 |= RT3883_CLKCFG1_PCIE_CLK_EN; -+ rstctrl &= ~RT3883_RSTCTRL_PCIE; -+ } -+ -+ rt3883_sysc_wr(syscfg1, RT3883_SYSC_REG_SYSCFG1); -+ rt3883_sysc_wr(rstctrl, RT3883_SYSC_REG_RSTCTRL); -+ rt3883_sysc_wr(clkcfg1, RT3883_SYSC_REG_CLKCFG1); -+ -+ msleep(500); -+} -+ -+static int rt3883_pcie_ready(void) -+{ -+ u32 status; -+ -+ msleep(500); -+ -+ status = rt3883_pci_rr(RT3883_PCI_REG_STATUS(1)); -+ if (status & BIT(0)) -+ return 0; -+ -+ /* TODO: reset PCIe and turn off PCIe clock */ -+ -+ return -ENODEV; -+} -+ -+void __init rt3883_pci_init(unsigned mode) -+{ -+ u32 val; -+ int err; -+ -+ rt3883_pci_preinit(mode); -+ -+ rt3883_pci_base = ioremap(RT3883_PCI_BASE, PAGE_SIZE); -+ if (rt3883_pci_base == NULL) { -+ pr_err("failed to ioremap PCI registers\n"); -+ return; -+ } -+ -+ rt3883_pci_wr(0, RT3883_PCI_REG_PCICFG_ADDR); -+ if (mode & RT3883_PCI_MODE_PCI) -+ rt3883_pci_wr(BIT(16), RT3883_PCI_REG_PCICFG_ADDR); -+ -+ msleep(500); -+ -+ if (mode & RT3883_PCI_MODE_PCIE) { -+ err = rt3883_pcie_ready(); -+ if (err) -+ return; -+ } -+ -+ if (mode & RT3883_PCI_MODE_PCI) -+ rt3883_pci_wr(0x79, RT3883_PCI_REG_ARBCTL); -+ -+ rt3883_pci_wr(RT3883_PCI_MEM_BASE, RT3883_PCI_REG_MEMBASE); -+ rt3883_pci_wr(RT3883_PCI_IO_BASE, RT3883_PCI_REG_IOBASE); -+ -+ /* PCI */ -+ rt3883_pci_wr(0x03ff0000, RT3883_PCI_REG_BAR0SETUP_ADDR(0)); -+ rt3883_pci_wr(RT3883_MEMORY_BASE, RT3883_PCI_REG_IMBASEBAR0_ADDR(0)); -+ rt3883_pci_wr(0x08021814, RT3883_PCI_REG_ID(0)); -+ rt3883_pci_wr(0x00800001, RT3883_PCI_REG_CLASS(0)); -+ rt3883_pci_wr(0x28801814, RT3883_PCI_REG_SUBID(0)); -+ -+ /* PCIe */ -+ rt3883_pci_wr(0x01ff0000, RT3883_PCI_REG_BAR0SETUP_ADDR(1)); -+ rt3883_pci_wr(RT3883_MEMORY_BASE, RT3883_PCI_REG_IMBASEBAR0_ADDR(1)); -+ rt3883_pci_wr(0x08021814, RT3883_PCI_REG_ID(1)); -+ rt3883_pci_wr(0x06040001, RT3883_PCI_REG_CLASS(1)); -+ rt3883_pci_wr(0x28801814, RT3883_PCI_REG_SUBID(1)); -+ -+ rt3883_pci_irq_init(); -+ -+ /* PCIe */ -+ val = rt3883_pci_read_u32(0, 0x01, 0, PCI_COMMAND); -+ val |= 0x7; -+ rt3883_pci_write_u32(0, 0x01, 0, PCI_COMMAND, val); -+ -+ /* PCI */ -+ val = rt3883_pci_read_u32(0, 0x00, 0, PCI_COMMAND); -+ val |= 0x7; -+ rt3883_pci_write_u32(0, 0x00, 0, PCI_COMMAND, val); -+ -+ ioport_resource.start = rt3883_pci_io_resource.start; -+ ioport_resource.end = rt3883_pci_io_resource.end; -+ -+ register_pci_controller(&rt3883_pci_controller); -+} -+ -+int __init pcibios_map_irq(const struct pci_dev *dev, u8 slot, u8 pin) -+{ -+ int irq = -1; -+ -+ switch (dev->bus->number) { -+ case 0: -+ switch (PCI_SLOT(dev->devfn)) { -+ case 0x00: -+ rt3883_pci_wr(0x03ff0001, -+ RT3883_PCI_REG_BAR0SETUP_ADDR(0)); -+ rt3883_pci_wr(0x03ff0001, -+ RT3883_PCI_REG_BAR0SETUP_ADDR(1)); -+ -+ rt3883_pci_write_u32(0, 0x00, 0, PCI_BASE_ADDRESS_0, -+ RT3883_MEMORY_BASE); -+ rt3883_pci_read_u32(0, 0x00, 0, PCI_BASE_ADDRESS_0); -+ -+ irq = RT3883_CPU_IRQ_PCI; -+ break; -+ case 0x01: -+ rt3883_pci_write_u32(0, 0x01, 0, PCI_IO_BASE, -+ 0x00000101); -+ break; -+ case 0x11: -+ irq = RT3883_PCI_IRQ_PCI0; -+ break; -+ case 0x12: -+ irq = RT3883_PCI_IRQ_PCI1; -+ break; -+ } -+ break; -+ -+ case 1: -+ irq = RT3883_PCI_IRQ_PCIE; -+ break; -+ -+ default: -+ dev_err(&dev->dev, "no IRQ specified\n"); -+ return irq; -+ } -+ -+ return irq; -+} -+ -+void __init rt3883_pci_set_plat_dev_init(int (*f)(struct pci_dev *dev)) -+{ -+ rt3883_pci_plat_dev_init = f; -+} -+ -+int pcibios_plat_dev_init(struct pci_dev *dev) -+{ -+ if (rt3883_pci_plat_dev_init) -+ return rt3883_pci_plat_dev_init(dev); -+ -+ return 0; -+} ---- a/arch/mips/ralink/Kconfig -+++ b/arch/mips/ralink/Kconfig -@@ -20,6 +20,7 @@ choice - bool "RT3883" - select USB_ARCH_HAS_OHCI - select USB_ARCH_HAS_EHCI -+ select HW_HAS_PCI - - config SOC_MT7620 - bool "MT7620" diff --git a/target/linux/ramips/patches-3.8/0120-DT-MIPS-ralink-add-MT7620A-dts-files.patch b/target/linux/ramips/patches-3.8/0120-DT-MIPS-ralink-add-MT7620A-dts-files.patch new file mode 100644 index 0000000000..82a3086c17 --- /dev/null +++ b/target/linux/ramips/patches-3.8/0120-DT-MIPS-ralink-add-MT7620A-dts-files.patch @@ -0,0 +1,119 @@ +From 07741f61fc94fad3c3d21fa1a2ad6f01455cc1dd Mon Sep 17 00:00:00 2001 +From: John Crispin +Date: Fri, 12 Apr 2013 06:27:41 +0000 +Subject: [PATCH 120/137] DT: MIPS: ralink: add MT7620A dts files + +Add a dtsi file for MT7620A SoC and a sample dts file. + +Signed-off-by: John Crispin +Acked-by: Grant Likely +Patchwork: http://patchwork.linux-mips.org/patch/5190/ +--- + arch/mips/ralink/Kconfig | 4 +++ + arch/mips/ralink/dts/Makefile | 1 + + arch/mips/ralink/dts/mt7620a.dtsi | 58 +++++++++++++++++++++++++++++++++ + arch/mips/ralink/dts/mt7620a_eval.dts | 16 +++++++++ + 4 files changed, 79 insertions(+) + create mode 100644 arch/mips/ralink/dts/mt7620a.dtsi + create mode 100644 arch/mips/ralink/dts/mt7620a_eval.dts + +--- a/arch/mips/ralink/Kconfig ++++ b/arch/mips/ralink/Kconfig +@@ -46,6 +46,10 @@ choice + bool "RT3883 eval kit" + depends on SOC_RT3883 + ++ config DTB_MT7620A_EVAL ++ bool "MT7620A eval kit" ++ depends on SOC_MT7620 ++ + endchoice + + endif +--- a/arch/mips/ralink/dts/Makefile ++++ b/arch/mips/ralink/dts/Makefile +@@ -1,3 +1,4 @@ + obj-$(CONFIG_DTB_RT2880_EVAL) := rt2880_eval.dtb.o + obj-$(CONFIG_DTB_RT305X_EVAL) := rt3052_eval.dtb.o + obj-$(CONFIG_DTB_RT3883_EVAL) := rt3883_eval.dtb.o ++obj-$(CONFIG_DTB_MT7620A_EVAL) := mt7620a_eval.dtb.o +--- /dev/null ++++ b/arch/mips/ralink/dts/mt7620a.dtsi +@@ -0,0 +1,58 @@ ++/ { ++ #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@10000000 { ++ compatible = "palmbus"; ++ reg = <0x10000000 0x200000>; ++ ranges = <0x0 0x10000000 0x1FFFFF>; ++ ++ #address-cells = <1>; ++ #size-cells = <1>; ++ ++ sysc@0 { ++ compatible = "ralink,mt7620a-sysc"; ++ reg = <0x0 0x100>; ++ }; ++ ++ intc: intc@200 { ++ compatible = "ralink,mt7620a-intc", "ralink,rt2880-intc"; ++ reg = <0x200 0x100>; ++ ++ interrupt-controller; ++ #interrupt-cells = <1>; ++ ++ interrupt-parent = <&cpuintc>; ++ interrupts = <2>; ++ }; ++ ++ memc@300 { ++ compatible = "ralink,mt7620a-memc", "ralink,rt3050-memc"; ++ reg = <0x300 0x100>; ++ }; ++ ++ uartlite@c00 { ++ compatible = "ralink,mt7620a-uart", "ralink,rt2880-uart", "ns16550a"; ++ reg = <0xc00 0x100>; ++ ++ interrupt-parent = <&intc>; ++ interrupts = <12>; ++ ++ reg-shift = <2>; ++ }; ++ }; ++}; +--- /dev/null ++++ b/arch/mips/ralink/dts/mt7620a_eval.dts +@@ -0,0 +1,16 @@ ++/dts-v1/; ++ ++/include/ "mt7620a.dtsi" ++ ++/ { ++ compatible = "ralink,mt7620a-eval-board", "ralink,mt7620a-soc"; ++ model = "Ralink MT7620A evaluation board"; ++ ++ memory@0 { ++ reg = <0x0 0x2000000>; ++ }; ++ ++ chosen { ++ bootargs = "console=ttyS0,57600"; ++ }; ++}; diff --git a/target/linux/ramips/patches-3.8/0120-NET-MIPS-add-ralink-SoC-ethernet-driver.patch b/target/linux/ramips/patches-3.8/0120-NET-MIPS-add-ralink-SoC-ethernet-driver.patch deleted file mode 100644 index b992650757..0000000000 --- a/target/linux/ramips/patches-3.8/0120-NET-MIPS-add-ralink-SoC-ethernet-driver.patch +++ /dev/null @@ -1,3141 +0,0 @@ -From 1c31c288bc1e853e3226ba593a13a0492b39c9e8 Mon Sep 17 00:00:00 2001 -From: John Crispin -Date: Fri, 15 Mar 2013 19:07:05 +0100 -Subject: [PATCH 120/121] NET: MIPS: add ralink SoC ethernet driver - -Add support for Ralink FE and ESW. - -Signed-off-by: John Crispin ---- - .../include/asm/mach-ralink/rt305x_esw_platform.h | 27 + - arch/mips/ralink/rt305x.c | 1 + - drivers/net/ethernet/Kconfig | 1 + - drivers/net/ethernet/Makefile | 1 + - drivers/net/ethernet/ramips/Kconfig | 18 + - drivers/net/ethernet/ramips/Makefile | 9 + - drivers/net/ethernet/ramips/ramips_debugfs.c | 127 ++ - drivers/net/ethernet/ramips/ramips_esw.c | 1220 +++++++++++++++++++ - drivers/net/ethernet/ramips/ramips_eth.h | 375 ++++++ - drivers/net/ethernet/ramips/ramips_main.c | 1285 ++++++++++++++++++++ - 10 files changed, 3064 insertions(+) - create mode 100644 arch/mips/include/asm/mach-ralink/rt305x_esw_platform.h - create mode 100644 drivers/net/ethernet/ramips/Kconfig - create mode 100644 drivers/net/ethernet/ramips/Makefile - create mode 100644 drivers/net/ethernet/ramips/ramips_debugfs.c - create mode 100644 drivers/net/ethernet/ramips/ramips_esw.c - create mode 100644 drivers/net/ethernet/ramips/ramips_eth.h - create mode 100644 drivers/net/ethernet/ramips/ramips_main.c - ---- /dev/null -+++ b/arch/mips/include/asm/mach-ralink/rt305x_esw_platform.h -@@ -0,0 +1,27 @@ -+/* -+ * Ralink RT305x SoC platform device registration -+ * -+ * Copyright (C) 2010 Gabor Juhos -+ * -+ * This program is free software; you can redistribute it and/or modify it -+ * under the terms of the GNU General Public License version 2 as published -+ * by the Free Software Foundation. -+ */ -+ -+#ifndef _RT305X_ESW_PLATFORM_H -+#define _RT305X_ESW_PLATFORM_H -+ -+enum { -+ RT305X_ESW_VLAN_CONFIG_NONE = 0, -+ RT305X_ESW_VLAN_CONFIG_LLLLW, -+ RT305X_ESW_VLAN_CONFIG_WLLLL, -+}; -+ -+struct rt305x_esw_platform_data -+{ -+ u8 vlan_config; -+ u32 reg_initval_fct2; -+ u32 reg_initval_fpa2; -+}; -+ -+#endif /* _RT305X_ESW_PLATFORM_H */ ---- a/arch/mips/ralink/rt305x.c -+++ b/arch/mips/ralink/rt305x.c -@@ -182,6 +182,7 @@ void __init ralink_clk_init(void) - } - - ralink_clk_add("cpu", cpu_rate); -+ ralink_clk_add("sys", sys_rate); - ralink_clk_add("10000b00.spi", sys_rate); - ralink_clk_add("10000100.timer", wdt_rate); - ralink_clk_add("10000120.watchdog", wdt_rate); ---- a/drivers/net/ethernet/Kconfig -+++ b/drivers/net/ethernet/Kconfig -@@ -136,6 +136,7 @@ source "drivers/net/ethernet/packetengin - source "drivers/net/ethernet/pasemi/Kconfig" - source "drivers/net/ethernet/qlogic/Kconfig" - source "drivers/net/ethernet/racal/Kconfig" -+source "drivers/net/ethernet/ramips/Kconfig" - source "drivers/net/ethernet/realtek/Kconfig" - source "drivers/net/ethernet/renesas/Kconfig" - source "drivers/net/ethernet/rdc/Kconfig" ---- a/drivers/net/ethernet/Makefile -+++ b/drivers/net/ethernet/Makefile -@@ -54,6 +54,7 @@ obj-$(CONFIG_NET_PACKET_ENGINE) += packe - obj-$(CONFIG_NET_VENDOR_PASEMI) += pasemi/ - obj-$(CONFIG_NET_VENDOR_QLOGIC) += qlogic/ - obj-$(CONFIG_NET_VENDOR_RACAL) += racal/ -+obj-$(CONFIG_NET_RAMIPS) += ramips/ - obj-$(CONFIG_NET_VENDOR_REALTEK) += realtek/ - obj-$(CONFIG_SH_ETH) += renesas/ - obj-$(CONFIG_NET_VENDOR_RDC) += rdc/ ---- /dev/null -+++ b/drivers/net/ethernet/ramips/Kconfig -@@ -0,0 +1,18 @@ -+config NET_RAMIPS -+ tristate "Ralink RT288X/RT3X5X/RT3662/RT3883 ethernet driver" -+ depends on RALINK -+ select PHYLIB if (SOC_RT288X || SOC_RT3883) -+ select SWCONFIG if SOC_RT305X -+ help -+ This driver supports the etehrnet mac inside the ralink wisocs -+ -+if NET_RAMIPS -+ -+config NET_RAMIPS_DEBUG -+ bool "Enable debug messages in the Ralink ethernet driver" -+ -+config NET_RAMIPS_DEBUG_FS -+ bool "Enable debugfs support for the Ralink ethernet driver" -+ depends on DEBUG_FS -+ -+endif ---- /dev/null -+++ b/drivers/net/ethernet/ramips/Makefile -@@ -0,0 +1,9 @@ -+# -+# Makefile for the Ramips SoCs built-in ethernet macs -+# -+ -+ramips-y += ramips_main.o -+ -+ramips-$(CONFIG_NET_RAMIPS_DEBUG_FS) += ramips_debugfs.o -+ -+obj-$(CONFIG_NET_RAMIPS) += ramips.o ---- /dev/null -+++ b/drivers/net/ethernet/ramips/ramips_debugfs.c -@@ -0,0 +1,127 @@ -+/* -+ * Ralink SoC ethernet driver debugfs code -+ * -+ * Copyright (C) 2011-2012 Gabor Juhos -+ * -+ * 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 -+#include -+#include -+ -+#include "ramips_eth.h" -+ -+static struct dentry *raeth_debugfs_root; -+ -+static int raeth_debugfs_generic_open(struct inode *inode, struct file *file) -+{ -+ file->private_data = inode->i_private; -+ return 0; -+} -+ -+void raeth_debugfs_update_int_stats(struct raeth_priv *re, u32 status) -+{ -+ re->debug.int_stats.total += !!status; -+ -+ re->debug.int_stats.rx_delayed += !!(status & RAMIPS_RX_DLY_INT); -+ re->debug.int_stats.rx_done0 += !!(status & RAMIPS_RX_DONE_INT0); -+ re->debug.int_stats.rx_coherent += !!(status & RAMIPS_RX_COHERENT); -+ -+ re->debug.int_stats.tx_delayed += !!(status & RAMIPS_TX_DLY_INT); -+ re->debug.int_stats.tx_done0 += !!(status & RAMIPS_TX_DONE_INT0); -+ re->debug.int_stats.tx_done1 += !!(status & RAMIPS_TX_DONE_INT1); -+ re->debug.int_stats.tx_done2 += !!(status & RAMIPS_TX_DONE_INT2); -+ re->debug.int_stats.tx_done3 += !!(status & RAMIPS_TX_DONE_INT3); -+ re->debug.int_stats.tx_coherent += !!(status & RAMIPS_TX_COHERENT); -+ -+ re->debug.int_stats.pse_fq_empty += !!(status & RAMIPS_PSE_FQ_EMPTY); -+ re->debug.int_stats.pse_p0_fc += !!(status & RAMIPS_PSE_P0_FC); -+ re->debug.int_stats.pse_p1_fc += !!(status & RAMIPS_PSE_P1_FC); -+ re->debug.int_stats.pse_p2_fc += !!(status & RAMIPS_PSE_P2_FC); -+ re->debug.int_stats.pse_buf_drop += !!(status & RAMIPS_PSE_BUF_DROP); -+} -+ -+static ssize_t read_file_int_stats(struct file *file, char __user *user_buf, -+ size_t count, loff_t *ppos) -+{ -+#define PR_INT_STAT(_label, _field) \ -+ len += snprintf(buf + len, sizeof(buf) - len, \ -+ "%-18s: %10lu\n", _label, re->debug.int_stats._field); -+ -+ struct raeth_priv *re = file->private_data; -+ char buf[512]; -+ unsigned int len = 0; -+ unsigned long flags; -+ -+ spin_lock_irqsave(&re->page_lock, flags); -+ -+ PR_INT_STAT("RX Delayed", rx_delayed); -+ PR_INT_STAT("RX Done 0", rx_done0); -+ PR_INT_STAT("RX Coherent", rx_coherent); -+ -+ PR_INT_STAT("TX Delayed", tx_delayed); -+ PR_INT_STAT("TX Done 0", tx_done0); -+ PR_INT_STAT("TX Done 1", tx_done1); -+ PR_INT_STAT("TX Done 2", tx_done2); -+ PR_INT_STAT("TX Done 3", tx_done3); -+ PR_INT_STAT("TX Coherent", tx_coherent); -+ -+ PR_INT_STAT("PSE FQ empty", pse_fq_empty); -+ PR_INT_STAT("CDMA Flow control", pse_p0_fc); -+ PR_INT_STAT("GDMA1 Flow control", pse_p1_fc); -+ PR_INT_STAT("GDMA2 Flow control", pse_p2_fc); -+ PR_INT_STAT("PSE discard", pse_buf_drop); -+ -+ len += snprintf(buf + len, sizeof(buf) - len, "\n"); -+ PR_INT_STAT("Total", total); -+ -+ spin_unlock_irqrestore(&re->page_lock, flags); -+ -+ return simple_read_from_buffer(user_buf, count, ppos, buf, len); -+#undef PR_INT_STAT -+} -+ -+static const struct file_operations raeth_fops_int_stats = { -+ .open = raeth_debugfs_generic_open, -+ .read = read_file_int_stats, -+ .owner = THIS_MODULE -+}; -+ -+void raeth_debugfs_exit(struct raeth_priv *re) -+{ -+ debugfs_remove_recursive(re->debug.debugfs_dir); -+} -+ -+int raeth_debugfs_init(struct raeth_priv *re) -+{ -+ re->debug.debugfs_dir = debugfs_create_dir(re->netdev->name, -+ raeth_debugfs_root); -+ if (!re->debug.debugfs_dir) -+ return -ENOMEM; -+ -+ debugfs_create_file("int_stats", S_IRUGO, re->debug.debugfs_dir, -+ re, &raeth_fops_int_stats); -+ -+ return 0; -+} -+ -+int raeth_debugfs_root_init(void) -+{ -+ if (raeth_debugfs_root) -+ return -EBUSY; -+ -+ raeth_debugfs_root = debugfs_create_dir("raeth", NULL); -+ if (!raeth_debugfs_root) -+ return -ENOENT; -+ -+ return 0; -+} -+ -+void raeth_debugfs_root_exit(void) -+{ -+ debugfs_remove(raeth_debugfs_root); -+ raeth_debugfs_root = NULL; -+} ---- /dev/null -+++ b/drivers/net/ethernet/ramips/ramips_esw.c -@@ -0,0 +1,1221 @@ -+#include -+#include -+#include -+ -+#include -+#include -+#include -+ -+/* -+ * HW limitations for this switch: -+ * - No large frame support (PKT_MAX_LEN at most 1536) -+ * - Can't have untagged vlan and tagged vlan on one port at the same time, -+ * though this might be possible using the undocumented PPE. -+ */ -+ -+#define RT305X_ESW_REG_ISR 0x00 -+#define RT305X_ESW_REG_IMR 0x04 -+#define RT305X_ESW_REG_FCT0 0x08 -+#define RT305X_ESW_REG_PFC1 0x14 -+#define RT305X_ESW_REG_ATS 0x24 -+#define RT305X_ESW_REG_ATS0 0x28 -+#define RT305X_ESW_REG_ATS1 0x2c -+#define RT305X_ESW_REG_ATS2 0x30 -+#define RT305X_ESW_REG_PVIDC(_n) (0x40 + 4 * (_n)) -+#define RT305X_ESW_REG_VLANI(_n) (0x50 + 4 * (_n)) -+#define RT305X_ESW_REG_VMSC(_n) (0x70 + 4 * (_n)) -+#define RT305X_ESW_REG_POA 0x80 -+#define RT305X_ESW_REG_FPA 0x84 -+#define RT305X_ESW_REG_SOCPC 0x8c -+#define RT305X_ESW_REG_POC0 0x90 -+#define RT305X_ESW_REG_POC1 0x94 -+#define RT305X_ESW_REG_POC2 0x98 -+#define RT305X_ESW_REG_SGC 0x9c -+#define RT305X_ESW_REG_STRT 0xa0 -+#define RT305X_ESW_REG_PCR0 0xc0 -+#define RT305X_ESW_REG_PCR1 0xc4 -+#define RT305X_ESW_REG_FPA2 0xc8 -+#define RT305X_ESW_REG_FCT2 0xcc -+#define RT305X_ESW_REG_SGC2 0xe4 -+#define RT305X_ESW_REG_P0LED 0xa4 -+#define RT305X_ESW_REG_P1LED 0xa8 -+#define RT305X_ESW_REG_P2LED 0xac -+#define RT305X_ESW_REG_P3LED 0xb0 -+#define RT305X_ESW_REG_P4LED 0xb4 -+#define RT305X_ESW_REG_P0PC 0xe8 -+#define RT305X_ESW_REG_P1PC 0xec -+#define RT305X_ESW_REG_P2PC 0xf0 -+#define RT305X_ESW_REG_P3PC 0xf4 -+#define RT305X_ESW_REG_P4PC 0xf8 -+#define RT305X_ESW_REG_P5PC 0xfc -+ -+#define RT305X_ESW_LED_LINK 0 -+#define RT305X_ESW_LED_100M 1 -+#define RT305X_ESW_LED_DUPLEX 2 -+#define RT305X_ESW_LED_ACTIVITY 3 -+#define RT305X_ESW_LED_COLLISION 4 -+#define RT305X_ESW_LED_LINKACT 5 -+#define RT305X_ESW_LED_DUPLCOLL 6 -+#define RT305X_ESW_LED_10MACT 7 -+#define RT305X_ESW_LED_100MACT 8 -+/* Additional led states not in datasheet: */ -+#define RT305X_ESW_LED_BLINK 10 -+#define RT305X_ESW_LED_ON 12 -+ -+#define RT305X_ESW_LINK_S 25 -+#define RT305X_ESW_DUPLEX_S 9 -+#define RT305X_ESW_SPD_S 0 -+ -+#define RT305X_ESW_PCR0_WT_NWAY_DATA_S 16 -+#define RT305X_ESW_PCR0_WT_PHY_CMD BIT(13) -+#define RT305X_ESW_PCR0_CPU_PHY_REG_S 8 -+ -+#define RT305X_ESW_PCR1_WT_DONE BIT(0) -+ -+#define RT305X_ESW_ATS_TIMEOUT (5 * HZ) -+#define RT305X_ESW_PHY_TIMEOUT (5 * HZ) -+ -+#define RT305X_ESW_PVIDC_PVID_M 0xfff -+#define RT305X_ESW_PVIDC_PVID_S 12 -+ -+#define RT305X_ESW_VLANI_VID_M 0xfff -+#define RT305X_ESW_VLANI_VID_S 12 -+ -+#define RT305X_ESW_VMSC_MSC_M 0xff -+#define RT305X_ESW_VMSC_MSC_S 8 -+ -+#define RT305X_ESW_SOCPC_DISUN2CPU_S 0 -+#define RT305X_ESW_SOCPC_DISMC2CPU_S 8 -+#define RT305X_ESW_SOCPC_DISBC2CPU_S 16 -+#define RT305X_ESW_SOCPC_CRC_PADDING BIT(25) -+ -+#define RT305X_ESW_POC0_EN_BP_S 0 -+#define RT305X_ESW_POC0_EN_FC_S 8 -+#define RT305X_ESW_POC0_DIS_RMC2CPU_S 16 -+#define RT305X_ESW_POC0_DIS_PORT_M 0x7f -+#define RT305X_ESW_POC0_DIS_PORT_S 23 -+ -+#define RT305X_ESW_POC2_UNTAG_EN_M 0xff -+#define RT305X_ESW_POC2_UNTAG_EN_S 0 -+#define RT305X_ESW_POC2_ENAGING_S 8 -+#define RT305X_ESW_POC2_DIS_UC_PAUSE_S 16 -+ -+#define RT305X_ESW_SGC2_DOUBLE_TAG_M 0x7f -+#define RT305X_ESW_SGC2_DOUBLE_TAG_S 0 -+#define RT305X_ESW_SGC2_LAN_PMAP_M 0x3f -+#define RT305X_ESW_SGC2_LAN_PMAP_S 24 -+ -+#define RT305X_ESW_PFC1_EN_VLAN_M 0xff -+#define RT305X_ESW_PFC1_EN_VLAN_S 16 -+#define RT305X_ESW_PFC1_EN_TOS_S 24 -+ -+#define RT305X_ESW_VLAN_NONE 0xfff -+ -+#define RT305X_ESW_POA_LINK_MASK 0x1f -+#define RT305X_ESW_POA_LINK_SHIFT 25 -+ -+#define RT305X_ESW_PORT_ST_CHG BIT(26) -+#define RT305X_ESW_PORT0 0 -+#define RT305X_ESW_PORT1 1 -+#define RT305X_ESW_PORT2 2 -+#define RT305X_ESW_PORT3 3 -+#define RT305X_ESW_PORT4 4 -+#define RT305X_ESW_PORT5 5 -+#define RT305X_ESW_PORT6 6 -+ -+#define RT305X_ESW_PORTS_NONE 0 -+ -+#define RT305X_ESW_PMAP_LLLLLL 0x3f -+#define RT305X_ESW_PMAP_LLLLWL 0x2f -+#define RT305X_ESW_PMAP_WLLLLL 0x3e -+ -+#define RT305X_ESW_PORTS_INTERNAL \ -+ (BIT(RT305X_ESW_PORT0) | BIT(RT305X_ESW_PORT1) | \ -+ BIT(RT305X_ESW_PORT2) | BIT(RT305X_ESW_PORT3) | \ -+ BIT(RT305X_ESW_PORT4)) -+ -+#define RT305X_ESW_PORTS_NOCPU \ -+ (RT305X_ESW_PORTS_INTERNAL | BIT(RT305X_ESW_PORT5)) -+ -+#define RT305X_ESW_PORTS_CPU BIT(RT305X_ESW_PORT6) -+ -+#define RT305X_ESW_PORTS_ALL \ -+ (RT305X_ESW_PORTS_NOCPU | RT305X_ESW_PORTS_CPU) -+ -+#define RT305X_ESW_NUM_VLANS 16 -+#define RT305X_ESW_NUM_VIDS 4096 -+#define RT305X_ESW_NUM_PORTS 7 -+#define RT305X_ESW_NUM_LANWAN 6 -+#define RT305X_ESW_NUM_LEDS 5 -+ -+enum { -+ /* Global attributes. */ -+ RT305X_ESW_ATTR_ENABLE_VLAN, -+ RT305X_ESW_ATTR_ALT_VLAN_DISABLE, -+ /* Port attributes. */ -+ RT305X_ESW_ATTR_PORT_DISABLE, -+ RT305X_ESW_ATTR_PORT_DOUBLETAG, -+ RT305X_ESW_ATTR_PORT_UNTAG, -+ RT305X_ESW_ATTR_PORT_LED, -+ RT305X_ESW_ATTR_PORT_LAN, -+ RT305X_ESW_ATTR_PORT_RECV_BAD, -+ RT305X_ESW_ATTR_PORT_RECV_GOOD, -+}; -+ -+struct rt305x_esw_port { -+ bool disable; -+ bool doubletag; -+ bool untag; -+ u8 led; -+ u16 pvid; -+}; -+ -+struct rt305x_esw_vlan { -+ u8 ports; -+ u16 vid; -+}; -+ -+struct rt305x_esw { -+ struct device *dev; -+ void __iomem *base; -+ int irq; -+ const struct rt305x_esw_platform_data *pdata; -+ /* Protects against concurrent register rmw operations. */ -+ spinlock_t reg_rw_lock; -+ -+ unsigned char port_map; -+ unsigned int reg_initval_fct2; -+ unsigned int reg_initval_fpa2; -+ -+ -+ struct switch_dev swdev; -+ bool global_vlan_enable; -+ bool alt_vlan_disable; -+ struct rt305x_esw_vlan vlans[RT305X_ESW_NUM_VLANS]; -+ struct rt305x_esw_port ports[RT305X_ESW_NUM_PORTS]; -+ -+}; -+ -+static inline void -+rt305x_esw_wr(struct rt305x_esw *esw, u32 val, unsigned reg) -+{ -+ __raw_writel(val, esw->base + reg); -+} -+ -+static inline u32 -+rt305x_esw_rr(struct rt305x_esw *esw, unsigned reg) -+{ -+ return __raw_readl(esw->base + reg); -+} -+ -+static inline void -+rt305x_esw_rmw_raw(struct rt305x_esw *esw, unsigned reg, unsigned long mask, -+ unsigned long val) -+{ -+ unsigned long t; -+ -+ t = __raw_readl(esw->base + reg) & ~mask; -+ __raw_writel(t | val, esw->base + reg); -+} -+ -+static void -+rt305x_esw_rmw(struct rt305x_esw *esw, unsigned reg, unsigned long mask, -+ unsigned long val) -+{ -+ unsigned long flags; -+ -+ spin_lock_irqsave(&esw->reg_rw_lock, flags); -+ rt305x_esw_rmw_raw(esw, reg, mask, val); -+ spin_unlock_irqrestore(&esw->reg_rw_lock, flags); -+} -+ -+static u32 -+rt305x_mii_write(struct rt305x_esw *esw, u32 phy_addr, u32 phy_register, -+ u32 write_data) -+{ -+ unsigned long t_start = jiffies; -+ int ret = 0; -+ -+ while (1) { -+ if (!(rt305x_esw_rr(esw, RT305X_ESW_REG_PCR1) & -+ RT305X_ESW_PCR1_WT_DONE)) -+ break; -+ if (time_after(jiffies, t_start + RT305X_ESW_PHY_TIMEOUT)) { -+ ret = 1; -+ goto out; -+ } -+ } -+ -+ write_data &= 0xffff; -+ rt305x_esw_wr(esw, -+ (write_data << RT305X_ESW_PCR0_WT_NWAY_DATA_S) | -+ (phy_register << RT305X_ESW_PCR0_CPU_PHY_REG_S) | -+ (phy_addr) | RT305X_ESW_PCR0_WT_PHY_CMD, -+ RT305X_ESW_REG_PCR0); -+ -+ t_start = jiffies; -+ while (1) { -+ if (rt305x_esw_rr(esw, RT305X_ESW_REG_PCR1) & -+ RT305X_ESW_PCR1_WT_DONE) -+ break; -+ -+ if (time_after(jiffies, t_start + RT305X_ESW_PHY_TIMEOUT)) { -+ ret = 1; -+ break; -+ } -+ } -+out: -+ if (ret) -+ printk(KERN_ERR "ramips_eth: MDIO timeout\n"); -+ return ret; -+} -+ -+static unsigned -+rt305x_esw_get_vlan_id(struct rt305x_esw *esw, unsigned vlan) -+{ -+ unsigned s; -+ unsigned val; -+ -+ s = RT305X_ESW_VLANI_VID_S * (vlan % 2); -+ val = rt305x_esw_rr(esw, RT305X_ESW_REG_VLANI(vlan / 2)); -+ val = (val >> s) & RT305X_ESW_VLANI_VID_M; -+ -+ return val; -+} -+ -+static void -+rt305x_esw_set_vlan_id(struct rt305x_esw *esw, unsigned vlan, unsigned vid) -+{ -+ unsigned s; -+ -+ s = RT305X_ESW_VLANI_VID_S * (vlan % 2); -+ rt305x_esw_rmw(esw, -+ RT305X_ESW_REG_VLANI(vlan / 2), -+ RT305X_ESW_VLANI_VID_M << s, -+ (vid & RT305X_ESW_VLANI_VID_M) << s); -+} -+ -+static unsigned -+rt305x_esw_get_pvid(struct rt305x_esw *esw, unsigned port) -+{ -+ unsigned s, val; -+ -+ s = RT305X_ESW_PVIDC_PVID_S * (port % 2); -+ val = rt305x_esw_rr(esw, RT305X_ESW_REG_PVIDC(port / 2)); -+ return (val >> s) & RT305X_ESW_PVIDC_PVID_M; -+} -+ -+static void -+rt305x_esw_set_pvid(struct rt305x_esw *esw, unsigned port, unsigned pvid) -+{ -+ unsigned s; -+ -+ s = RT305X_ESW_PVIDC_PVID_S * (port % 2); -+ rt305x_esw_rmw(esw, -+ RT305X_ESW_REG_PVIDC(port / 2), -+ RT305X_ESW_PVIDC_PVID_M << s, -+ (pvid & RT305X_ESW_PVIDC_PVID_M) << s); -+} -+ -+static unsigned -+rt305x_esw_get_vmsc(struct rt305x_esw *esw, unsigned vlan) -+{ -+ unsigned s, val; -+ -+ s = RT305X_ESW_VMSC_MSC_S * (vlan % 4); -+ val = rt305x_esw_rr(esw, RT305X_ESW_REG_VMSC(vlan / 4)); -+ val = (val >> s) & RT305X_ESW_VMSC_MSC_M; -+ -+ return val; -+} -+ -+static void -+rt305x_esw_set_vmsc(struct rt305x_esw *esw, unsigned vlan, unsigned msc) -+{ -+ unsigned s; -+ -+ s = RT305X_ESW_VMSC_MSC_S * (vlan % 4); -+ rt305x_esw_rmw(esw, -+ RT305X_ESW_REG_VMSC(vlan / 4), -+ RT305X_ESW_VMSC_MSC_M << s, -+ (msc & RT305X_ESW_VMSC_MSC_M) << s); -+} -+ -+static unsigned -+rt305x_esw_get_port_disable(struct rt305x_esw *esw) -+{ -+ unsigned reg; -+ reg = rt305x_esw_rr(esw, RT305X_ESW_REG_POC0); -+ return (reg >> RT305X_ESW_POC0_DIS_PORT_S) & -+ RT305X_ESW_POC0_DIS_PORT_M; -+} -+ -+static void -+rt305x_esw_set_port_disable(struct rt305x_esw *esw, unsigned disable_mask) -+{ -+ unsigned old_mask; -+ unsigned enable_mask; -+ unsigned changed; -+ int i; -+ -+ old_mask = rt305x_esw_get_port_disable(esw); -+ changed = old_mask ^ disable_mask; -+ enable_mask = old_mask & disable_mask; -+ -+ /* enable before writing to MII */ -+ rt305x_esw_rmw(esw, RT305X_ESW_REG_POC0, -+ (RT305X_ESW_POC0_DIS_PORT_M << -+ RT305X_ESW_POC0_DIS_PORT_S), -+ enable_mask << RT305X_ESW_POC0_DIS_PORT_S); -+ -+ for (i = 0; i < RT305X_ESW_NUM_LEDS; i++) { -+ if (!(changed & (1 << i))) -+ continue; -+ if (disable_mask & (1 << i)) { -+ /* disable */ -+ rt305x_mii_write(esw, i, MII_BMCR, -+ BMCR_PDOWN); -+ } else { -+ /* enable */ -+ rt305x_mii_write(esw, i, MII_BMCR, -+ BMCR_FULLDPLX | -+ BMCR_ANENABLE | -+ BMCR_ANRESTART | -+ BMCR_SPEED100); -+ } -+ } -+ -+ /* disable after writing to MII */ -+ rt305x_esw_rmw(esw, RT305X_ESW_REG_POC0, -+ (RT305X_ESW_POC0_DIS_PORT_M << -+ RT305X_ESW_POC0_DIS_PORT_S), -+ disable_mask << RT305X_ESW_POC0_DIS_PORT_S); -+} -+ -+static int -+rt305x_esw_apply_config(struct switch_dev *dev); -+ -+static void -+rt305x_esw_hw_init(struct rt305x_esw *esw) -+{ -+ int i; -+ u8 port_disable = 0; -+ u8 port_map = RT305X_ESW_PMAP_LLLLLL; -+ -+ /* vodoo from original driver */ -+ rt305x_esw_wr(esw, 0xC8A07850, RT305X_ESW_REG_FCT0); -+ rt305x_esw_wr(esw, 0x00000000, RT305X_ESW_REG_SGC2); -+ /* Port priority 1 for all ports, vlan enabled. */ -+ rt305x_esw_wr(esw, 0x00005555 | -+ (RT305X_ESW_PORTS_ALL << RT305X_ESW_PFC1_EN_VLAN_S), -+ RT305X_ESW_REG_PFC1); -+ -+ /* Enable Back Pressure, and Flow Control */ -+ rt305x_esw_wr(esw, -+ ((RT305X_ESW_PORTS_ALL << RT305X_ESW_POC0_EN_BP_S) | -+ (RT305X_ESW_PORTS_ALL << RT305X_ESW_POC0_EN_FC_S)), -+ RT305X_ESW_REG_POC0); -+ -+ /* Enable Aging, and VLAN TAG removal */ -+ rt305x_esw_wr(esw, -+ ((RT305X_ESW_PORTS_ALL << RT305X_ESW_POC2_ENAGING_S) | -+ (RT305X_ESW_PORTS_NOCPU << RT305X_ESW_POC2_UNTAG_EN_S)), -+ RT305X_ESW_REG_POC2); -+ -+ if (esw->reg_initval_fct2) -+ rt305x_esw_wr(esw, esw->reg_initval_fct2, RT305X_ESW_REG_FCT2); -+ else -+ rt305x_esw_wr(esw, esw->pdata->reg_initval_fct2, RT305X_ESW_REG_FCT2); -+ -+ /* -+ * 300s aging timer, max packet len 1536, broadcast storm prevention -+ * disabled, disable collision abort, mac xor48 hash, 10 packet back -+ * pressure jam, GMII disable was_transmit, back pressure disabled, -+ * 30ms led flash, unmatched IGMP as broadcast, rmc tb fault to all -+ * ports. -+ */ -+ rt305x_esw_wr(esw, 0x0008a301, RT305X_ESW_REG_SGC); -+ -+ /* Setup SoC Port control register */ -+ rt305x_esw_wr(esw, -+ (RT305X_ESW_SOCPC_CRC_PADDING | -+ (RT305X_ESW_PORTS_CPU << RT305X_ESW_SOCPC_DISUN2CPU_S) | -+ (RT305X_ESW_PORTS_CPU << RT305X_ESW_SOCPC_DISMC2CPU_S) | -+ (RT305X_ESW_PORTS_CPU << RT305X_ESW_SOCPC_DISBC2CPU_S)), -+ RT305X_ESW_REG_SOCPC); -+ -+ if (esw->reg_initval_fpa2) -+ rt305x_esw_wr(esw, esw->reg_initval_fpa2, RT305X_ESW_REG_FPA2); -+ else -+ rt305x_esw_wr(esw, esw->pdata->reg_initval_fpa2, RT305X_ESW_REG_FPA2); -+ rt305x_esw_wr(esw, 0x00000000, RT305X_ESW_REG_FPA); -+ -+ /* Force Link/Activity on ports */ -+ rt305x_esw_wr(esw, 0x00000005, RT305X_ESW_REG_P0LED); -+ rt305x_esw_wr(esw, 0x00000005, RT305X_ESW_REG_P1LED); -+ rt305x_esw_wr(esw, 0x00000005, RT305X_ESW_REG_P2LED); -+ rt305x_esw_wr(esw, 0x00000005, RT305X_ESW_REG_P3LED); -+ rt305x_esw_wr(esw, 0x00000005, RT305X_ESW_REG_P4LED); -+ -+ /* Copy disabled port configuration from bootloader setup */ -+ port_disable = rt305x_esw_get_port_disable(esw); -+ for (i = 0; i < 6; i++) -+ esw->ports[i].disable = (port_disable & (1 << i)) != 0; -+ -+ rt305x_mii_write(esw, 0, 31, 0x8000); -+ for (i = 0; i < 5; i++) { -+ if (esw->ports[i].disable) { -+ rt305x_mii_write(esw, i, MII_BMCR, BMCR_PDOWN); -+ } else { -+ rt305x_mii_write(esw, i, MII_BMCR, -+ BMCR_FULLDPLX | -+ BMCR_ANENABLE | -+ BMCR_SPEED100); -+ } -+ /* TX10 waveform coefficient */ -+ rt305x_mii_write(esw, i, 26, 0x1601); -+ /* TX100/TX10 AD/DA current bias */ -+ rt305x_mii_write(esw, i, 29, 0x7058); -+ /* TX100 slew rate control */ -+ rt305x_mii_write(esw, i, 30, 0x0018); -+ } -+ -+ /* PHY IOT */ -+ /* select global register */ -+ rt305x_mii_write(esw, 0, 31, 0x0); -+ /* tune TP_IDL tail and head waveform */ -+ rt305x_mii_write(esw, 0, 22, 0x052f); -+ /* set TX10 signal amplitude threshold to minimum */ -+ rt305x_mii_write(esw, 0, 17, 0x0fe0); -+ /* set squelch amplitude to higher threshold */ -+ rt305x_mii_write(esw, 0, 18, 0x40ba); -+ /* longer TP_IDL tail length */ -+ rt305x_mii_write(esw, 0, 14, 0x65); -+ /* select local register */ -+ rt305x_mii_write(esw, 0, 31, 0x8000); -+ -+ if (esw->port_map) -+ port_map = esw->port_map; -+ else -+ port_map = RT305X_ESW_PMAP_LLLLLL; -+ -+ /* -+ * Unused HW feature, but still nice to be consistent here... -+ * This is also exported to userspace ('lan' attribute) so it's -+ * conveniently usable to decide which ports go into the wan vlan by -+ * default. -+ */ -+ rt305x_esw_rmw(esw, RT305X_ESW_REG_SGC2, -+ RT305X_ESW_SGC2_LAN_PMAP_M << RT305X_ESW_SGC2_LAN_PMAP_S, -+ port_map << RT305X_ESW_SGC2_LAN_PMAP_S); -+ -+ /* make the switch leds blink */ -+ for (i = 0; i < RT305X_ESW_NUM_LEDS; i++) -+ esw->ports[i].led = 0x05; -+ -+ /* Apply the empty config. */ -+ rt305x_esw_apply_config(&esw->swdev); -+} -+ -+static irqreturn_t -+rt305x_esw_interrupt(int irq, void *_esw) -+{ -+ struct rt305x_esw *esw = (struct rt305x_esw *) _esw; -+ u32 status; -+ -+ status = rt305x_esw_rr(esw, RT305X_ESW_REG_ISR); -+ if (status & RT305X_ESW_PORT_ST_CHG) { -+ u32 link = rt305x_esw_rr(esw, RT305X_ESW_REG_POA); -+ link >>= RT305X_ESW_POA_LINK_SHIFT; -+ link &= RT305X_ESW_POA_LINK_MASK; -+ dev_info(esw->dev, "link changed 0x%02X\n", link); -+ } -+ rt305x_esw_wr(esw, RT305X_ESW_PORT_ST_CHG, RT305X_ESW_REG_ISR); -+ -+ return IRQ_HANDLED; -+} -+ -+static void -+rt305x_esw_request_irq(struct rt305x_esw *esw) -+{ -+ /* Only unmask the port change interrupt */ -+ rt305x_esw_wr(esw, ~RT305X_ESW_PORT_ST_CHG, RT305X_ESW_REG_IMR); -+ -+ /* request the irq handler */ -+ request_irq(esw->irq, rt305x_esw_interrupt, 0, "esw", esw); -+} -+ -+static int -+rt305x_esw_apply_config(struct switch_dev *dev) -+{ -+ struct rt305x_esw *esw = container_of(dev, struct rt305x_esw, swdev); -+ int i; -+ u8 disable = 0; -+ u8 doubletag = 0; -+ u8 en_vlan = 0; -+ u8 untag = 0; -+ -+ for (i = 0; i < RT305X_ESW_NUM_VLANS; i++) { -+ u32 vid, vmsc; -+ if (esw->global_vlan_enable) { -+ vid = esw->vlans[i].vid; -+ vmsc = esw->vlans[i].ports; -+ } else { -+ vid = RT305X_ESW_VLAN_NONE; -+ vmsc = RT305X_ESW_PORTS_NONE; -+ } -+ rt305x_esw_set_vlan_id(esw, i, vid); -+ rt305x_esw_set_vmsc(esw, i, vmsc); -+ } -+ -+ for (i = 0; i < RT305X_ESW_NUM_PORTS; i++) { -+ u32 pvid; -+ disable |= esw->ports[i].disable << i; -+ if (esw->global_vlan_enable) { -+ doubletag |= esw->ports[i].doubletag << i; -+ en_vlan |= 1 << i; -+ untag |= esw->ports[i].untag << i; -+ pvid = esw->ports[i].pvid; -+ } else { -+ int x = esw->alt_vlan_disable ? 0 : 1; -+ doubletag |= x << i; -+ en_vlan |= x << i; -+ untag |= x << i; -+ pvid = 0; -+ } -+ rt305x_esw_set_pvid(esw, i, pvid); -+ if (i < RT305X_ESW_NUM_LEDS) -+ rt305x_esw_wr(esw, esw->ports[i].led, -+ RT305X_ESW_REG_P0LED + 4*i); -+ } -+ -+ rt305x_esw_set_port_disable(esw, disable); -+ rt305x_esw_rmw(esw, RT305X_ESW_REG_SGC2, -+ (RT305X_ESW_SGC2_DOUBLE_TAG_M << -+ RT305X_ESW_SGC2_DOUBLE_TAG_S), -+ doubletag << RT305X_ESW_SGC2_DOUBLE_TAG_S); -+ rt305x_esw_rmw(esw, RT305X_ESW_REG_PFC1, -+ RT305X_ESW_PFC1_EN_VLAN_M << RT305X_ESW_PFC1_EN_VLAN_S, -+ en_vlan << RT305X_ESW_PFC1_EN_VLAN_S); -+ rt305x_esw_rmw(esw, RT305X_ESW_REG_POC2, -+ RT305X_ESW_POC2_UNTAG_EN_M << RT305X_ESW_POC2_UNTAG_EN_S, -+ untag << RT305X_ESW_POC2_UNTAG_EN_S); -+ -+ if (!esw->global_vlan_enable) { -+ /* -+ * Still need to put all ports into vlan 0 or they'll be -+ * isolated. -+ * NOTE: vlan 0 is special, no vlan tag is prepended -+ */ -+ rt305x_esw_set_vlan_id(esw, 0, 0); -+ rt305x_esw_set_vmsc(esw, 0, RT305X_ESW_PORTS_ALL); -+ } -+ -+ return 0; -+} -+ -+static int -+rt305x_esw_reset_switch(struct switch_dev *dev) -+{ -+ struct rt305x_esw *esw = container_of(dev, struct rt305x_esw, swdev); -+ esw->global_vlan_enable = 0; -+ memset(esw->ports, 0, sizeof(esw->ports)); -+ memset(esw->vlans, 0, sizeof(esw->vlans)); -+ rt305x_esw_hw_init(esw); -+ -+ return 0; -+} -+ -+static int -+rt305x_esw_get_vlan_enable(struct switch_dev *dev, -+ const struct switch_attr *attr, -+ struct switch_val *val) -+{ -+ struct rt305x_esw *esw = container_of(dev, struct rt305x_esw, swdev); -+ -+ val->value.i = esw->global_vlan_enable; -+ -+ return 0; -+} -+ -+static int -+rt305x_esw_set_vlan_enable(struct switch_dev *dev, -+ const struct switch_attr *attr, -+ struct switch_val *val) -+{ -+ struct rt305x_esw *esw = container_of(dev, struct rt305x_esw, swdev); -+ -+ esw->global_vlan_enable = val->value.i != 0; -+ -+ return 0; -+} -+ -+static int -+rt305x_esw_get_alt_vlan_disable(struct switch_dev *dev, -+ const struct switch_attr *attr, -+ struct switch_val *val) -+{ -+ struct rt305x_esw *esw = container_of(dev, struct rt305x_esw, swdev); -+ -+ val->value.i = esw->alt_vlan_disable; -+ -+ return 0; -+} -+ -+static int -+rt305x_esw_set_alt_vlan_disable(struct switch_dev *dev, -+ const struct switch_attr *attr, -+ struct switch_val *val) -+{ -+ struct rt305x_esw *esw = container_of(dev, struct rt305x_esw, swdev); -+ -+ esw->alt_vlan_disable = val->value.i != 0; -+ -+ return 0; -+} -+ -+static int -+rt305x_esw_get_port_link(struct switch_dev *dev, -+ int port, -+ struct switch_port_link *link) -+{ -+ struct rt305x_esw *esw = container_of(dev, struct rt305x_esw, swdev); -+ u32 speed, poa; -+ -+ if (port < 0 || port >= RT305X_ESW_NUM_PORTS) -+ return -EINVAL; -+ -+ poa = rt305x_esw_rr(esw, RT305X_ESW_REG_POA) >> port; -+ -+ link->link = (poa >> RT305X_ESW_LINK_S) & 1; -+ link->duplex = (poa >> RT305X_ESW_DUPLEX_S) & 1; -+ if (port < RT305X_ESW_NUM_LEDS) { -+ speed = (poa >> RT305X_ESW_SPD_S) & 1; -+ } else { -+ if (port == RT305X_ESW_NUM_PORTS - 1) -+ poa >>= 1; -+ speed = (poa >> RT305X_ESW_SPD_S) & 3; -+ } -+ switch (speed) { -+ case 0: -+ link->speed = SWITCH_PORT_SPEED_10; -+ break; -+ case 1: -+ link->speed = SWITCH_PORT_SPEED_100; -+ break; -+ case 2: -+ case 3: /* forced gige speed can be 2 or 3 */ -+ link->speed = SWITCH_PORT_SPEED_1000; -+ break; -+ default: -+ link->speed = SWITCH_PORT_SPEED_UNKNOWN; -+ break; -+ } -+ -+ return 0; -+} -+ -+static int -+rt305x_esw_get_port_bool(struct switch_dev *dev, -+ const struct switch_attr *attr, -+ struct switch_val *val) -+{ -+ struct rt305x_esw *esw = container_of(dev, struct rt305x_esw, swdev); -+ int idx = val->port_vlan; -+ u32 x, reg, shift; -+ -+ if (idx < 0 || idx >= RT305X_ESW_NUM_PORTS) -+ return -EINVAL; -+ -+ switch (attr->id) { -+ case RT305X_ESW_ATTR_PORT_DISABLE: -+ reg = RT305X_ESW_REG_POC0; -+ shift = RT305X_ESW_POC0_DIS_PORT_S; -+ break; -+ case RT305X_ESW_ATTR_PORT_DOUBLETAG: -+ reg = RT305X_ESW_REG_SGC2; -+ shift = RT305X_ESW_SGC2_DOUBLE_TAG_S; -+ break; -+ case RT305X_ESW_ATTR_PORT_UNTAG: -+ reg = RT305X_ESW_REG_POC2; -+ shift = RT305X_ESW_POC2_UNTAG_EN_S; -+ break; -+ case RT305X_ESW_ATTR_PORT_LAN: -+ reg = RT305X_ESW_REG_SGC2; -+ shift = RT305X_ESW_SGC2_LAN_PMAP_S; -+ if (idx >= RT305X_ESW_NUM_LANWAN) -+ return -EINVAL; -+ break; -+ default: -+ return -EINVAL; -+ } -+ -+ x = rt305x_esw_rr(esw, reg); -+ val->value.i = (x >> (idx + shift)) & 1; -+ -+ return 0; -+} -+ -+static int -+rt305x_esw_set_port_bool(struct switch_dev *dev, -+ const struct switch_attr *attr, -+ struct switch_val *val) -+{ -+ struct rt305x_esw *esw = container_of(dev, struct rt305x_esw, swdev); -+ int idx = val->port_vlan; -+ -+ if (idx < 0 || idx >= RT305X_ESW_NUM_PORTS || -+ val->value.i < 0 || val->value.i > 1) -+ return -EINVAL; -+ -+ switch (attr->id) { -+ case RT305X_ESW_ATTR_PORT_DISABLE: -+ esw->ports[idx].disable = val->value.i; -+ break; -+ case RT305X_ESW_ATTR_PORT_DOUBLETAG: -+ esw->ports[idx].doubletag = val->value.i; -+ break; -+ case RT305X_ESW_ATTR_PORT_UNTAG: -+ esw->ports[idx].untag = val->value.i; -+ break; -+ default: -+ return -EINVAL; -+ } -+ -+ return 0; -+} -+ -+static int -+rt305x_esw_get_port_recv_badgood(struct switch_dev *dev, -+ const struct switch_attr *attr, -+ struct switch_val *val) -+{ -+ struct rt305x_esw *esw = container_of(dev, struct rt305x_esw, swdev); -+ int idx = val->port_vlan; -+ int shift = attr->id == RT305X_ESW_ATTR_PORT_RECV_GOOD ? 0 : 16; -+ u32 reg; -+ -+ if (idx < 0 || idx >= RT305X_ESW_NUM_LANWAN) -+ return -EINVAL; -+ -+ reg = rt305x_esw_rr(esw, RT305X_ESW_REG_P0PC + 4*idx); -+ val->value.i = (reg >> shift) & 0xffff; -+ -+ return 0; -+} -+ -+static int -+rt305x_esw_get_port_led(struct switch_dev *dev, -+ const struct switch_attr *attr, -+ struct switch_val *val) -+{ -+ struct rt305x_esw *esw = container_of(dev, struct rt305x_esw, swdev); -+ int idx = val->port_vlan; -+ -+ if (idx < 0 || idx >= RT305X_ESW_NUM_PORTS || -+ idx >= RT305X_ESW_NUM_LEDS) -+ return -EINVAL; -+ -+ val->value.i = rt305x_esw_rr(esw, RT305X_ESW_REG_P0LED + 4*idx); -+ -+ return 0; -+} -+ -+static int -+rt305x_esw_set_port_led(struct switch_dev *dev, -+ const struct switch_attr *attr, -+ struct switch_val *val) -+{ -+ struct rt305x_esw *esw = container_of(dev, struct rt305x_esw, swdev); -+ int idx = val->port_vlan; -+ -+ if (idx < 0 || idx >= RT305X_ESW_NUM_LEDS) -+ return -EINVAL; -+ -+ esw->ports[idx].led = val->value.i; -+ -+ return 0; -+} -+ -+static int -+rt305x_esw_get_port_pvid(struct switch_dev *dev, int port, int *val) -+{ -+ struct rt305x_esw *esw = container_of(dev, struct rt305x_esw, swdev); -+ -+ if (port >= RT305X_ESW_NUM_PORTS) -+ return -EINVAL; -+ -+ *val = rt305x_esw_get_pvid(esw, port); -+ -+ return 0; -+} -+ -+static int -+rt305x_esw_set_port_pvid(struct switch_dev *dev, int port, int val) -+{ -+ struct rt305x_esw *esw = container_of(dev, struct rt305x_esw, swdev); -+ -+ if (port >= RT305X_ESW_NUM_PORTS) -+ return -EINVAL; -+ -+ esw->ports[port].pvid = val; -+ -+ return 0; -+} -+ -+static int -+rt305x_esw_get_vlan_ports(struct switch_dev *dev, struct switch_val *val) -+{ -+ struct rt305x_esw *esw = container_of(dev, struct rt305x_esw, swdev); -+ u32 vmsc, poc2; -+ int vlan_idx = -1; -+ int i; -+ -+ val->len = 0; -+ -+ if (val->port_vlan < 0 || val->port_vlan >= RT305X_ESW_NUM_VIDS) -+ return -EINVAL; -+ -+ /* valid vlan? */ -+ for (i = 0; i < RT305X_ESW_NUM_VLANS; i++) { -+ if (rt305x_esw_get_vlan_id(esw, i) == val->port_vlan && -+ rt305x_esw_get_vmsc(esw, i) != RT305X_ESW_PORTS_NONE) { -+ vlan_idx = i; -+ break; -+ } -+ } -+ -+ if (vlan_idx == -1) -+ return -EINVAL; -+ -+ vmsc = rt305x_esw_get_vmsc(esw, vlan_idx); -+ poc2 = rt305x_esw_rr(esw, RT305X_ESW_REG_POC2); -+ -+ for (i = 0; i < RT305X_ESW_NUM_PORTS; i++) { -+ struct switch_port *p; -+ int port_mask = 1 << i; -+ -+ if (!(vmsc & port_mask)) -+ continue; -+ -+ p = &val->value.ports[val->len++]; -+ p->id = i; -+ if (poc2 & (port_mask << RT305X_ESW_POC2_UNTAG_EN_S)) -+ p->flags = 0; -+ else -+ p->flags = 1 << SWITCH_PORT_FLAG_TAGGED; -+ } -+ -+ return 0; -+} -+ -+static int -+rt305x_esw_set_vlan_ports(struct switch_dev *dev, struct switch_val *val) -+{ -+ struct rt305x_esw *esw = container_of(dev, struct rt305x_esw, swdev); -+ int ports; -+ int vlan_idx = -1; -+ int i; -+ -+ if (val->port_vlan < 0 || val->port_vlan >= RT305X_ESW_NUM_VIDS || -+ val->len > RT305X_ESW_NUM_PORTS) -+ return -EINVAL; -+ -+ /* one of the already defined vlans? */ -+ for (i = 0; i < RT305X_ESW_NUM_VLANS; i++) { -+ if (esw->vlans[i].vid == val->port_vlan && -+ esw->vlans[i].ports != RT305X_ESW_PORTS_NONE) { -+ vlan_idx = i; -+ break; -+ } -+ } -+ -+ /* select a free slot */ -+ for (i = 0; vlan_idx == -1 && i < RT305X_ESW_NUM_VLANS; i++) { -+ if (esw->vlans[i].ports == RT305X_ESW_PORTS_NONE) -+ vlan_idx = i; -+ } -+ -+ /* bail if all slots are in use */ -+ if (vlan_idx == -1) -+ return -EINVAL; -+ -+ ports = RT305X_ESW_PORTS_NONE; -+ for (i = 0; i < val->len; i++) { -+ struct switch_port *p = &val->value.ports[i]; -+ int port_mask = 1 << p->id; -+ bool untagged = !(p->flags & (1 << SWITCH_PORT_FLAG_TAGGED)); -+ -+ if (p->id >= RT305X_ESW_NUM_PORTS) -+ return -EINVAL; -+ -+ ports |= port_mask; -+ esw->ports[p->id].untag = untagged; -+ } -+ esw->vlans[vlan_idx].ports = ports; -+ if (ports == RT305X_ESW_PORTS_NONE) -+ esw->vlans[vlan_idx].vid = RT305X_ESW_VLAN_NONE; -+ else -+ esw->vlans[vlan_idx].vid = val->port_vlan; -+ -+ return 0; -+} -+ -+static const struct switch_attr rt305x_esw_global[] = { -+ { -+ .type = SWITCH_TYPE_INT, -+ .name = "enable_vlan", -+ .description = "VLAN mode (1:enabled)", -+ .max = 1, -+ .id = RT305X_ESW_ATTR_ENABLE_VLAN, -+ .get = rt305x_esw_get_vlan_enable, -+ .set = rt305x_esw_set_vlan_enable, -+ }, -+ { -+ .type = SWITCH_TYPE_INT, -+ .name = "alternate_vlan_disable", -+ .description = "Use en_vlan instead of doubletag to disable" -+ " VLAN mode", -+ .max = 1, -+ .id = RT305X_ESW_ATTR_ALT_VLAN_DISABLE, -+ .get = rt305x_esw_get_alt_vlan_disable, -+ .set = rt305x_esw_set_alt_vlan_disable, -+ }, -+}; -+ -+static const struct switch_attr rt305x_esw_port[] = { -+ { -+ .type = SWITCH_TYPE_INT, -+ .name = "disable", -+ .description = "Port state (1:disabled)", -+ .max = 1, -+ .id = RT305X_ESW_ATTR_PORT_DISABLE, -+ .get = rt305x_esw_get_port_bool, -+ .set = rt305x_esw_set_port_bool, -+ }, -+ { -+ .type = SWITCH_TYPE_INT, -+ .name = "doubletag", -+ .description = "Double tagging for incoming vlan packets " -+ "(1:enabled)", -+ .max = 1, -+ .id = RT305X_ESW_ATTR_PORT_DOUBLETAG, -+ .get = rt305x_esw_get_port_bool, -+ .set = rt305x_esw_set_port_bool, -+ }, -+ { -+ .type = SWITCH_TYPE_INT, -+ .name = "untag", -+ .description = "Untag (1:strip outgoing vlan tag)", -+ .max = 1, -+ .id = RT305X_ESW_ATTR_PORT_UNTAG, -+ .get = rt305x_esw_get_port_bool, -+ .set = rt305x_esw_set_port_bool, -+ }, -+ { -+ .type = SWITCH_TYPE_INT, -+ .name = "led", -+ .description = "LED mode (0:link, 1:100m, 2:duplex, 3:activity," -+ " 4:collision, 5:linkact, 6:duplcoll, 7:10mact," -+ " 8:100mact, 10:blink, 12:on)", -+ .max = 15, -+ .id = RT305X_ESW_ATTR_PORT_LED, -+ .get = rt305x_esw_get_port_led, -+ .set = rt305x_esw_set_port_led, -+ }, -+ { -+ .type = SWITCH_TYPE_INT, -+ .name = "lan", -+ .description = "HW port group (0:wan, 1:lan)", -+ .max = 1, -+ .id = RT305X_ESW_ATTR_PORT_LAN, -+ .get = rt305x_esw_get_port_bool, -+ }, -+ { -+ .type = SWITCH_TYPE_INT, -+ .name = "recv_bad", -+ .description = "Receive bad packet counter", -+ .id = RT305X_ESW_ATTR_PORT_RECV_BAD, -+ .get = rt305x_esw_get_port_recv_badgood, -+ }, -+ { -+ .type = SWITCH_TYPE_INT, -+ .name = "recv_good", -+ .description = "Receive good packet counter", -+ .id = RT305X_ESW_ATTR_PORT_RECV_GOOD, -+ .get = rt305x_esw_get_port_recv_badgood, -+ }, -+}; -+ -+static const struct switch_attr rt305x_esw_vlan[] = { -+}; -+ -+static const struct switch_dev_ops rt305x_esw_ops = { -+ .attr_global = { -+ .attr = rt305x_esw_global, -+ .n_attr = ARRAY_SIZE(rt305x_esw_global), -+ }, -+ .attr_port = { -+ .attr = rt305x_esw_port, -+ .n_attr = ARRAY_SIZE(rt305x_esw_port), -+ }, -+ .attr_vlan = { -+ .attr = rt305x_esw_vlan, -+ .n_attr = ARRAY_SIZE(rt305x_esw_vlan), -+ }, -+ .get_vlan_ports = rt305x_esw_get_vlan_ports, -+ .set_vlan_ports = rt305x_esw_set_vlan_ports, -+ .get_port_pvid = rt305x_esw_get_port_pvid, -+ .set_port_pvid = rt305x_esw_set_port_pvid, -+ .get_port_link = rt305x_esw_get_port_link, -+ .apply_config = rt305x_esw_apply_config, -+ .reset_switch = rt305x_esw_reset_switch, -+}; -+ -+static struct rt305x_esw_platform_data rt3050_esw_data = { -+ /* All ports are LAN ports. */ -+ .vlan_config = RT305X_ESW_VLAN_CONFIG_NONE, -+ .reg_initval_fct2 = 0x00d6500c, -+ /* -+ * ext phy base addr 31, enable port 5 polling, rx/tx clock skew 1, -+ * turbo mii off, rgmi 3.3v off -+ * port5: disabled -+ * port6: enabled, gige, full-duplex, rx/tx-flow-control -+ */ -+ .reg_initval_fpa2 = 0x3f502b28, -+}; -+ -+static const struct of_device_id ralink_esw_match[] = { -+ { .compatible = "ralink,rt3050-esw", .data = &rt3050_esw_data }, -+ {}, -+}; -+MODULE_DEVICE_TABLE(of, ralink_esw_match); -+ -+static int -+rt305x_esw_probe(struct platform_device *pdev) -+{ -+ struct device_node *np = pdev->dev.of_node; -+ const struct rt305x_esw_platform_data *pdata; -+ const __be32 *port_map, *reg_init; -+ struct rt305x_esw *esw; -+ struct switch_dev *swdev; -+ struct resource *res, *irq; -+ int err; -+ -+ pdata = pdev->dev.platform_data; -+ if (!pdata) { -+ const struct of_device_id *match; -+ match = of_match_device(ralink_esw_match, &pdev->dev); -+ if (match) -+ pdata = (struct rt305x_esw_platform_data *) match->data; -+ } -+ if (!pdata) -+ return -EINVAL; -+ -+ res = platform_get_resource(pdev, IORESOURCE_MEM, 0); -+ if (!res) { -+ dev_err(&pdev->dev, "no memory resource found\n"); -+ return -ENOMEM; -+ } -+ -+ irq = platform_get_resource(pdev, IORESOURCE_IRQ, 0); -+ if (!irq) { -+ dev_err(&pdev->dev, "no irq resource found\n"); -+ return -ENOMEM; -+ } -+ -+ esw = kzalloc(sizeof(struct rt305x_esw), GFP_KERNEL); -+ if (!esw) { -+ dev_err(&pdev->dev, "no memory for private data\n"); -+ return -ENOMEM; -+ } -+ -+ esw->dev = &pdev->dev; -+ esw->irq = irq->start; -+ esw->base = ioremap(res->start, resource_size(res)); -+ if (!esw->base) { -+ dev_err(&pdev->dev, "ioremap failed\n"); -+ err = -ENOMEM; -+ goto free_esw; -+ } -+ -+ port_map = of_get_property(np, "ralink,portmap", NULL); -+ if (port_map) -+ esw->port_map = be32_to_cpu(*port_map); -+ -+ reg_init = of_get_property(np, "ralink,fct2", NULL); -+ if (reg_init) -+ esw->reg_initval_fct2 = be32_to_cpu(*reg_init); -+ -+ reg_init = of_get_property(np, "ralink,fpa2", NULL); -+ if (reg_init) -+ esw->reg_initval_fpa2 = be32_to_cpu(*reg_init); -+ -+ swdev = &esw->swdev; -+ swdev->of_node = pdev->dev.of_node; -+ swdev->name = "rt305x-esw"; -+ swdev->alias = "rt305x"; -+ swdev->cpu_port = RT305X_ESW_PORT6; -+ swdev->ports = RT305X_ESW_NUM_PORTS; -+ swdev->vlans = RT305X_ESW_NUM_VIDS; -+ swdev->ops = &rt305x_esw_ops; -+ -+ err = register_switch(swdev, NULL); -+ if (err < 0) { -+ dev_err(&pdev->dev, "register_switch failed\n"); -+ goto unmap_base; -+ } -+ -+ platform_set_drvdata(pdev, esw); -+ -+ esw->pdata = pdata; -+ spin_lock_init(&esw->reg_rw_lock); -+ rt305x_esw_hw_init(esw); -+ rt305x_esw_request_irq(esw); -+ -+ return 0; -+ -+unmap_base: -+ iounmap(esw->base); -+free_esw: -+ kfree(esw); -+ return err; -+} -+ -+static int -+rt305x_esw_remove(struct platform_device *pdev) -+{ -+ struct rt305x_esw *esw; -+ -+ esw = platform_get_drvdata(pdev); -+ if (esw) { -+ unregister_switch(&esw->swdev); -+ platform_set_drvdata(pdev, NULL); -+ iounmap(esw->base); -+ kfree(esw); -+ } -+ -+ return 0; -+} -+ -+static struct platform_driver rt305x_esw_driver = { -+ .probe = rt305x_esw_probe, -+ .remove = rt305x_esw_remove, -+ .driver = { -+ .name = "rt305x-esw", -+ .owner = THIS_MODULE, -+ .of_match_table = ralink_esw_match, -+ }, -+}; -+ -+static int __init -+rt305x_esw_init(void) -+{ -+ return platform_driver_register(&rt305x_esw_driver); -+} -+ -+static void -+rt305x_esw_exit(void) -+{ -+ platform_driver_unregister(&rt305x_esw_driver); -+} ---- /dev/null -+++ b/drivers/net/ethernet/ramips/ramips_eth.h -@@ -0,0 +1,375 @@ -+/* -+ * This program is free software; you can redistribute it and/or modify -+ * it under the terms of the GNU General Public License as published by -+ * the Free Software Foundation; version 2 of the License -+ * -+ * This program is distributed in the hope that it will be useful, -+ * but WITHOUT ANY WARRANTY; without even the implied warranty of -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -+ * GNU General Public License for more details. -+ * -+ * You should have received a copy of the GNU General Public License -+ * along with this program; if not, write to the Free Software -+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA. -+ * -+ * based on Ralink SDK3.3 -+ * Copyright (C) 2009 John Crispin -+ */ -+ -+#ifndef RAMIPS_ETH_H -+#define RAMIPS_ETH_H -+ -+#include -+#include -+#include -+#include -+ -+#define NUM_RX_DESC 256 -+#define NUM_TX_DESC 256 -+ -+#define RAMIPS_DELAY_EN_INT 0x80 -+#define RAMIPS_DELAY_MAX_INT 0x04 -+#define RAMIPS_DELAY_MAX_TOUT 0x04 -+#define RAMIPS_DELAY_CHAN (((RAMIPS_DELAY_EN_INT | RAMIPS_DELAY_MAX_INT) << 8) | RAMIPS_DELAY_MAX_TOUT) -+#define RAMIPS_DELAY_INIT ((RAMIPS_DELAY_CHAN << 16) | RAMIPS_DELAY_CHAN) -+#define RAMIPS_PSE_FQFC_CFG_INIT 0x80504000 -+ -+/* interrupt bits */ -+#define RAMIPS_CNT_PPE_AF BIT(31) -+#define RAMIPS_CNT_GDM_AF BIT(29) -+#define RAMIPS_PSE_P2_FC BIT(26) -+#define RAMIPS_PSE_BUF_DROP BIT(24) -+#define RAMIPS_GDM_OTHER_DROP BIT(23) -+#define RAMIPS_PSE_P1_FC BIT(22) -+#define RAMIPS_PSE_P0_FC BIT(21) -+#define RAMIPS_PSE_FQ_EMPTY BIT(20) -+#define RAMIPS_GE1_STA_CHG BIT(18) -+#define RAMIPS_TX_COHERENT BIT(17) -+#define RAMIPS_RX_COHERENT BIT(16) -+#define RAMIPS_TX_DONE_INT3 BIT(11) -+#define RAMIPS_TX_DONE_INT2 BIT(10) -+#define RAMIPS_TX_DONE_INT1 BIT(9) -+#define RAMIPS_TX_DONE_INT0 BIT(8) -+#define RAMIPS_RX_DONE_INT0 BIT(2) -+#define RAMIPS_TX_DLY_INT BIT(1) -+#define RAMIPS_RX_DLY_INT BIT(0) -+ -+#define RT5350_RX_DLY_INT BIT(30) -+#define RT5350_TX_DLY_INT BIT(28) -+ -+/* registers */ -+#define RAMIPS_FE_OFFSET 0x0000 -+#define RAMIPS_GDMA_OFFSET 0x0020 -+#define RAMIPS_PSE_OFFSET 0x0040 -+#define RAMIPS_GDMA2_OFFSET 0x0060 -+#define RAMIPS_CDMA_OFFSET 0x0080 -+#define RAMIPS_PDMA_OFFSET 0x0100 -+#define RAMIPS_PPE_OFFSET 0x0200 -+#define RAMIPS_CMTABLE_OFFSET 0x0400 -+#define RAMIPS_POLICYTABLE_OFFSET 0x1000 -+ -+#define RT5350_PDMA_OFFSET 0x0800 -+#define RT5350_SDM_OFFSET 0x0c00 -+ -+#define RAMIPS_MDIO_ACCESS (RAMIPS_FE_OFFSET + 0x00) -+#define RAMIPS_MDIO_CFG (RAMIPS_FE_OFFSET + 0x04) -+#define RAMIPS_FE_GLO_CFG (RAMIPS_FE_OFFSET + 0x08) -+#define RAMIPS_FE_RST_GL (RAMIPS_FE_OFFSET + 0x0C) -+#define RAMIPS_FE_INT_STATUS (RAMIPS_FE_OFFSET + 0x10) -+#define RAMIPS_FE_INT_ENABLE (RAMIPS_FE_OFFSET + 0x14) -+#define RAMIPS_MDIO_CFG2 (RAMIPS_FE_OFFSET + 0x18) -+#define RAMIPS_FOC_TS_T (RAMIPS_FE_OFFSET + 0x1C) -+ -+#define RAMIPS_GDMA1_FWD_CFG (RAMIPS_GDMA_OFFSET + 0x00) -+#define RAMIPS_GDMA1_SCH_CFG (RAMIPS_GDMA_OFFSET + 0x04) -+#define RAMIPS_GDMA1_SHPR_CFG (RAMIPS_GDMA_OFFSET + 0x08) -+#define RAMIPS_GDMA1_MAC_ADRL (RAMIPS_GDMA_OFFSET + 0x0C) -+#define RAMIPS_GDMA1_MAC_ADRH (RAMIPS_GDMA_OFFSET + 0x10) -+ -+#define RAMIPS_GDMA2_FWD_CFG (RAMIPS_GDMA2_OFFSET + 0x00) -+#define RAMIPS_GDMA2_SCH_CFG (RAMIPS_GDMA2_OFFSET + 0x04) -+#define RAMIPS_GDMA2_SHPR_CFG (RAMIPS_GDMA2_OFFSET + 0x08) -+#define RAMIPS_GDMA2_MAC_ADRL (RAMIPS_GDMA2_OFFSET + 0x0C) -+#define RAMIPS_GDMA2_MAC_ADRH (RAMIPS_GDMA2_OFFSET + 0x10) -+ -+#define RAMIPS_PSE_FQ_CFG (RAMIPS_PSE_OFFSET + 0x00) -+#define RAMIPS_CDMA_FC_CFG (RAMIPS_PSE_OFFSET + 0x04) -+#define RAMIPS_GDMA1_FC_CFG (RAMIPS_PSE_OFFSET + 0x08) -+#define RAMIPS_GDMA2_FC_CFG (RAMIPS_PSE_OFFSET + 0x0C) -+ -+#define RAMIPS_CDMA_CSG_CFG (RAMIPS_CDMA_OFFSET + 0x00) -+#define RAMIPS_CDMA_SCH_CFG (RAMIPS_CDMA_OFFSET + 0x04) -+ -+#define RT5350_TX_BASE_PTR0 (RT5350_PDMA_OFFSET + 0x00) -+#define RT5350_TX_MAX_CNT0 (RT5350_PDMA_OFFSET + 0x04) -+#define RT5350_TX_CTX_IDX0 (RT5350_PDMA_OFFSET + 0x08) -+#define RT5350_TX_DTX_IDX0 (RT5350_PDMA_OFFSET + 0x0C) -+#define RT5350_TX_BASE_PTR1 (RT5350_PDMA_OFFSET + 0x10) -+#define RT5350_TX_MAX_CNT1 (RT5350_PDMA_OFFSET + 0x14) -+#define RT5350_TX_CTX_IDX1 (RT5350_PDMA_OFFSET + 0x18) -+#define RT5350_TX_DTX_IDX1 (RT5350_PDMA_OFFSET + 0x1C) -+#define RT5350_TX_BASE_PTR2 (RT5350_PDMA_OFFSET + 0x20) -+#define RT5350_TX_MAX_CNT2 (RT5350_PDMA_OFFSET + 0x24) -+#define RT5350_TX_CTX_IDX2 (RT5350_PDMA_OFFSET + 0x28) -+#define RT5350_TX_DTX_IDX2 (RT5350_PDMA_OFFSET + 0x2C) -+#define RT5350_TX_BASE_PTR3 (RT5350_PDMA_OFFSET + 0x30) -+#define RT5350_TX_MAX_CNT3 (RT5350_PDMA_OFFSET + 0x34) -+#define RT5350_TX_CTX_IDX3 (RT5350_PDMA_OFFSET + 0x38) -+#define RT5350_TX_DTX_IDX3 (RT5350_PDMA_OFFSET + 0x3C) -+#define RT5350_RX_BASE_PTR0 (RT5350_PDMA_OFFSET + 0x100) -+#define RT5350_RX_MAX_CNT0 (RT5350_PDMA_OFFSET + 0x104) -+#define RT5350_RX_CALC_IDX0 (RT5350_PDMA_OFFSET + 0x108) -+#define RT5350_RX_DRX_IDX0 (RT5350_PDMA_OFFSET + 0x10C) -+#define RT5350_RX_BASE_PTR1 (RT5350_PDMA_OFFSET + 0x110) -+#define RT5350_RX_MAX_CNT1 (RT5350_PDMA_OFFSET + 0x114) -+#define RT5350_RX_CALC_IDX1 (RT5350_PDMA_OFFSET + 0x118) -+#define RT5350_RX_DRX_IDX1 (RT5350_PDMA_OFFSET + 0x11C) -+#define RT5350_PDMA_GLO_CFG (RT5350_PDMA_OFFSET + 0x204) -+#define RT5350_PDMA_RST_CFG (RT5350_PDMA_OFFSET + 0x208) -+#define RT5350_DLY_INT_CFG (RT5350_PDMA_OFFSET + 0x20c) -+#define RT5350_FE_INT_STATUS (RT5350_PDMA_OFFSET + 0x220) -+#define RT5350_FE_INT_ENABLE (RT5350_PDMA_OFFSET + 0x228) -+#define RT5350_PDMA_SCH_CFG (RT5350_PDMA_OFFSET + 0x280) -+ -+ -+#define RAMIPS_PDMA_GLO_CFG (RAMIPS_PDMA_OFFSET + 0x00) -+#define RAMIPS_PDMA_RST_CFG (RAMIPS_PDMA_OFFSET + 0x04) -+#define RAMIPS_PDMA_SCH_CFG (RAMIPS_PDMA_OFFSET + 0x08) -+#define RAMIPS_DLY_INT_CFG (RAMIPS_PDMA_OFFSET + 0x0C) -+#define RAMIPS_TX_BASE_PTR0 (RAMIPS_PDMA_OFFSET + 0x10) -+#define RAMIPS_TX_MAX_CNT0 (RAMIPS_PDMA_OFFSET + 0x14) -+#define RAMIPS_TX_CTX_IDX0 (RAMIPS_PDMA_OFFSET + 0x18) -+#define RAMIPS_TX_DTX_IDX0 (RAMIPS_PDMA_OFFSET + 0x1C) -+#define RAMIPS_TX_BASE_PTR1 (RAMIPS_PDMA_OFFSET + 0x20) -+#define RAMIPS_TX_MAX_CNT1 (RAMIPS_PDMA_OFFSET + 0x24) -+#define RAMIPS_TX_CTX_IDX1 (RAMIPS_PDMA_OFFSET + 0x28) -+#define RAMIPS_TX_DTX_IDX1 (RAMIPS_PDMA_OFFSET + 0x2C) -+#define RAMIPS_RX_BASE_PTR0 (RAMIPS_PDMA_OFFSET + 0x30) -+#define RAMIPS_RX_MAX_CNT0 (RAMIPS_PDMA_OFFSET + 0x34) -+#define RAMIPS_RX_CALC_IDX0 (RAMIPS_PDMA_OFFSET + 0x38) -+#define RAMIPS_RX_DRX_IDX0 (RAMIPS_PDMA_OFFSET + 0x3C) -+#define RAMIPS_TX_BASE_PTR2 (RAMIPS_PDMA_OFFSET + 0x40) -+#define RAMIPS_TX_MAX_CNT2 (RAMIPS_PDMA_OFFSET + 0x44) -+#define RAMIPS_TX_CTX_IDX2 (RAMIPS_PDMA_OFFSET + 0x48) -+#define RAMIPS_TX_DTX_IDX2 (RAMIPS_PDMA_OFFSET + 0x4C) -+#define RAMIPS_TX_BASE_PTR3 (RAMIPS_PDMA_OFFSET + 0x50) -+#define RAMIPS_TX_MAX_CNT3 (RAMIPS_PDMA_OFFSET + 0x54) -+#define RAMIPS_TX_CTX_IDX3 (RAMIPS_PDMA_OFFSET + 0x58) -+#define RAMIPS_TX_DTX_IDX3 (RAMIPS_PDMA_OFFSET + 0x5C) -+#define RAMIPS_RX_BASE_PTR1 (RAMIPS_PDMA_OFFSET + 0x60) -+#define RAMIPS_RX_MAX_CNT1 (RAMIPS_PDMA_OFFSET + 0x64) -+#define RAMIPS_RX_CALC_IDX1 (RAMIPS_PDMA_OFFSET + 0x68) -+#define RAMIPS_RX_DRX_IDX1 (RAMIPS_PDMA_OFFSET + 0x6C) -+ -+#define RT5350_SDM_CFG (RT5350_SDM_OFFSET + 0x00) //Switch DMA configuration -+#define RT5350_SDM_RRING (RT5350_SDM_OFFSET + 0x04) //Switch DMA Rx Ring -+#define RT5350_SDM_TRING (RT5350_SDM_OFFSET + 0x08) //Switch DMA Tx Ring -+#define RT5350_SDM_MAC_ADRL (RT5350_SDM_OFFSET + 0x0C) //Switch MAC address LSB -+#define RT5350_SDM_MAC_ADRH (RT5350_SDM_OFFSET + 0x10) //Switch MAC Address MSB -+#define RT5350_SDM_TPCNT (RT5350_SDM_OFFSET + 0x100) //Switch DMA Tx packet count -+#define RT5350_SDM_TBCNT (RT5350_SDM_OFFSET + 0x104) //Switch DMA Tx byte count -+#define RT5350_SDM_RPCNT (RT5350_SDM_OFFSET + 0x108) //Switch DMA rx packet count -+#define RT5350_SDM_RBCNT (RT5350_SDM_OFFSET + 0x10C) //Switch DMA rx byte count -+#define RT5350_SDM_CS_ERR (RT5350_SDM_OFFSET + 0x110) //Switch DMA rx checksum error count -+ -+#define RT5350_SDM_ICS_EN BIT(16) -+#define RT5350_SDM_TCS_EN BIT(17) -+#define RT5350_SDM_UCS_EN BIT(18) -+ -+ -+/* MDIO_CFG register bits */ -+#define RAMIPS_MDIO_CFG_AUTO_POLL_EN BIT(29) -+#define RAMIPS_MDIO_CFG_GP1_BP_EN BIT(16) -+#define RAMIPS_MDIO_CFG_GP1_FRC_EN BIT(15) -+#define RAMIPS_MDIO_CFG_GP1_SPEED_10 (0 << 13) -+#define RAMIPS_MDIO_CFG_GP1_SPEED_100 (1 << 13) -+#define RAMIPS_MDIO_CFG_GP1_SPEED_1000 (2 << 13) -+#define RAMIPS_MDIO_CFG_GP1_DUPLEX BIT(12) -+#define RAMIPS_MDIO_CFG_GP1_FC_TX BIT(11) -+#define RAMIPS_MDIO_CFG_GP1_FC_RX BIT(10) -+#define RAMIPS_MDIO_CFG_GP1_LNK_DWN BIT(9) -+#define RAMIPS_MDIO_CFG_GP1_AN_FAIL BIT(8) -+#define RAMIPS_MDIO_CFG_MDC_CLK_DIV_1 (0 << 6) -+#define RAMIPS_MDIO_CFG_MDC_CLK_DIV_2 (1 << 6) -+#define RAMIPS_MDIO_CFG_MDC_CLK_DIV_4 (2 << 6) -+#define RAMIPS_MDIO_CFG_MDC_CLK_DIV_8 (3 << 6) -+#define RAMIPS_MDIO_CFG_TURBO_MII_FREQ BIT(5) -+#define RAMIPS_MDIO_CFG_TURBO_MII_MODE BIT(4) -+#define RAMIPS_MDIO_CFG_RX_CLK_SKEW_0 (0 << 2) -+#define RAMIPS_MDIO_CFG_RX_CLK_SKEW_200 (1 << 2) -+#define RAMIPS_MDIO_CFG_RX_CLK_SKEW_400 (2 << 2) -+#define RAMIPS_MDIO_CFG_RX_CLK_SKEW_INV (3 << 2) -+#define RAMIPS_MDIO_CFG_TX_CLK_SKEW_0 0 -+#define RAMIPS_MDIO_CFG_TX_CLK_SKEW_200 1 -+#define RAMIPS_MDIO_CFG_TX_CLK_SKEW_400 2 -+#define RAMIPS_MDIO_CFG_TX_CLK_SKEW_INV 3 -+ -+/* uni-cast port */ -+#define RAMIPS_GDM1_ICS_EN BIT(22) -+#define RAMIPS_GDM1_TCS_EN BIT(21) -+#define RAMIPS_GDM1_UCS_EN BIT(20) -+#define RAMIPS_GDM1_JMB_EN BIT(19) -+#define RAMIPS_GDM1_STRPCRC BIT(16) -+#define RAMIPS_GDM1_UFRC_P_CPU (0 << 12) -+#define RAMIPS_GDM1_UFRC_P_GDMA1 (1 << 12) -+#define RAMIPS_GDM1_UFRC_P_PPE (6 << 12) -+ -+/* checksums */ -+#define RAMIPS_ICS_GEN_EN BIT(2) -+#define RAMIPS_UCS_GEN_EN BIT(1) -+#define RAMIPS_TCS_GEN_EN BIT(0) -+ -+/* dma ring */ -+#define RAMIPS_PST_DRX_IDX0 BIT(16) -+#define RAMIPS_PST_DTX_IDX3 BIT(3) -+#define RAMIPS_PST_DTX_IDX2 BIT(2) -+#define RAMIPS_PST_DTX_IDX1 BIT(1) -+#define RAMIPS_PST_DTX_IDX0 BIT(0) -+ -+#define RAMIPS_TX_WB_DDONE BIT(6) -+#define RAMIPS_RX_DMA_BUSY BIT(3) -+#define RAMIPS_TX_DMA_BUSY BIT(1) -+#define RAMIPS_RX_DMA_EN BIT(2) -+#define RAMIPS_TX_DMA_EN BIT(0) -+ -+#define RAMIPS_PDMA_SIZE_4DWORDS (0 << 4) -+#define RAMIPS_PDMA_SIZE_8DWORDS (1 << 4) -+#define RAMIPS_PDMA_SIZE_16DWORDS (2 << 4) -+ -+#define RAMIPS_US_CYC_CNT_MASK 0xff -+#define RAMIPS_US_CYC_CNT_SHIFT 0x8 -+#define RAMIPS_US_CYC_CNT_DIVISOR 1000000 -+ -+#define RX_DMA_PLEN0(_x) (((_x) >> 16) & 0x3fff) -+#define RX_DMA_LSO BIT(30) -+#define RX_DMA_DONE BIT(31) -+ -+struct ramips_rx_dma { -+ unsigned int rxd1; -+ unsigned int rxd2; -+ unsigned int rxd3; -+ unsigned int rxd4; -+} __packed __aligned(4); -+ -+#define TX_DMA_PLEN0_MASK ((0x3fff) << 16) -+#define TX_DMA_PLEN0(_x) (((_x) & 0x3fff) << 16) -+#define TX_DMA_LSO BIT(30) -+#define TX_DMA_DONE BIT(31) -+#define TX_DMA_QN(_x) ((_x) << 16) -+#define TX_DMA_PN(_x) ((_x) << 24) -+#define TX_DMA_QN_MASK TX_DMA_QN(0x7) -+#define TX_DMA_PN_MASK TX_DMA_PN(0x7) -+ -+struct ramips_tx_dma { -+ unsigned int txd1; -+ unsigned int txd2; -+ unsigned int txd3; -+ unsigned int txd4; -+} __packed __aligned(4); -+ -+struct raeth_tx_info { -+ struct ramips_tx_dma *tx_desc; -+ struct sk_buff *tx_skb; -+}; -+ -+struct raeth_rx_info { -+ struct ramips_rx_dma *rx_desc; -+ struct sk_buff *rx_skb; -+ dma_addr_t rx_dma; -+ unsigned int pad; -+}; -+ -+struct raeth_int_stats { -+ unsigned long rx_delayed; -+ unsigned long tx_delayed; -+ unsigned long rx_done0; -+ unsigned long tx_done0; -+ unsigned long tx_done1; -+ unsigned long tx_done2; -+ unsigned long tx_done3; -+ unsigned long rx_coherent; -+ unsigned long tx_coherent; -+ -+ unsigned long pse_fq_empty; -+ unsigned long pse_p0_fc; -+ unsigned long pse_p1_fc; -+ unsigned long pse_p2_fc; -+ unsigned long pse_buf_drop; -+ -+ unsigned long total; -+}; -+ -+struct raeth_debug { -+ struct dentry *debugfs_dir; -+ -+ struct raeth_int_stats int_stats; -+}; -+ -+struct raeth_priv -+{ -+ struct device_node *of_node; -+ -+ struct raeth_rx_info *rx_info; -+ dma_addr_t rx_desc_dma; -+ struct tasklet_struct rx_tasklet; -+ struct ramips_rx_dma *rx; -+ -+ struct raeth_tx_info *tx_info; -+ dma_addr_t tx_desc_dma; -+ struct tasklet_struct tx_housekeeping_tasklet; -+ struct ramips_tx_dma *tx; -+ -+ unsigned int skb_free_idx; -+ -+ spinlock_t page_lock; -+ struct net_device *netdev; -+ struct device *parent; -+ -+ int link; -+ int speed; -+ int duplex; -+ int tx_fc; -+ int rx_fc; -+ -+ struct mii_bus *mii_bus; -+ int mii_irq[PHY_MAX_ADDR]; -+ struct phy_device *phy_dev; -+ spinlock_t phy_lock; -+ unsigned long sys_freq; -+ -+ unsigned char mac[6]; -+ void (*reset_fe)(void); -+ int min_pkt_len; -+ -+ u32 phy_mask; -+ phy_interface_t phy_if_mode; -+ -+#ifdef CONFIG_NET_RAMIPS_DEBUG_FS -+ struct raeth_debug debug; -+#endif -+}; -+ -+struct ramips_soc_data -+{ -+ unsigned char mac[6]; -+ void (*reset_fe)(void); -+ int min_pkt_len; -+}; -+ -+ -+#ifdef CONFIG_NET_RAMIPS_DEBUG_FS -+int raeth_debugfs_root_init(void); -+void raeth_debugfs_root_exit(void); -+int raeth_debugfs_init(struct raeth_priv *re); -+void raeth_debugfs_exit(struct raeth_priv *re); -+void raeth_debugfs_update_int_stats(struct raeth_priv *re, u32 status); -+#else -+static inline int raeth_debugfs_root_init(void) { return 0; } -+static inline void raeth_debugfs_root_exit(void) {} -+static inline int raeth_debugfs_init(struct raeth_priv *re) { return 0; } -+static inline void raeth_debugfs_exit(struct raeth_priv *re) {} -+static inline void raeth_debugfs_update_int_stats(struct raeth_priv *re, -+ u32 status) {} -+#endif /* CONFIG_NET_RAMIPS_DEBUG_FS */ -+ -+#endif /* RAMIPS_ETH_H */ ---- /dev/null -+++ b/drivers/net/ethernet/ramips/ramips_main.c -@@ -0,0 +1,1285 @@ -+/* -+ * This program is free software; you can redistribute it and/or modify -+ * it under the terms of the GNU General Public License as published by -+ * the Free Software Foundation; version 2 of the License -+ * -+ * This program is distributed in the hope that it will be useful, -+ * but WITHOUT ANY WARRANTY; without even the implied warranty of -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -+ * GNU General Public License for more details. -+ * -+ * You should have received a copy of the GNU General Public License -+ * along with this program; if not, write to the Free Software -+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA. -+ * -+ * Copyright (C) 2009 John Crispin -+ */ -+ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+ -+#include "ramips_eth.h" -+ -+#define TX_TIMEOUT (20 * HZ / 100) -+#define MAX_RX_LENGTH 1600 -+ -+#ifdef CONFIG_SOC_RT305X -+#include -+#include "ramips_esw.c" -+#else -+#include -+static inline int rt305x_esw_init(void) { return 0; } -+static inline void rt305x_esw_exit(void) { } -+static inline int soc_is_rt5350(void) { return 0; } -+#endif -+ -+#define phys_to_bus(a) (a & 0x1FFFFFFF) -+ -+#ifdef CONFIG_NET_RAMIPS_DEBUG -+#define RADEBUG(fmt, args...) printk(KERN_DEBUG fmt, ## args) -+#else -+#define RADEBUG(fmt, args...) do {} while (0) -+#endif -+ -+#define RX_DLY_INT ((soc_is_rt5350())?(RT5350_RX_DLY_INT):(RAMIPS_RX_DLY_INT)) -+#define TX_DLY_INT ((soc_is_rt5350())?(RT5350_TX_DLY_INT):(RAMIPS_TX_DLY_INT)) -+ -+enum raeth_reg { -+ RAETH_REG_PDMA_GLO_CFG = 0, -+ RAETH_REG_PDMA_RST_CFG, -+ RAETH_REG_DLY_INT_CFG, -+ RAETH_REG_TX_BASE_PTR0, -+ RAETH_REG_TX_MAX_CNT0, -+ RAETH_REG_TX_CTX_IDX0, -+ RAETH_REG_RX_BASE_PTR0, -+ RAETH_REG_RX_MAX_CNT0, -+ RAETH_REG_RX_CALC_IDX0, -+ RAETH_REG_FE_INT_ENABLE, -+ RAETH_REG_FE_INT_STATUS, -+ RAETH_REG_COUNT -+}; -+ -+static const u32 ramips_reg_table[RAETH_REG_COUNT] = { -+ [RAETH_REG_PDMA_GLO_CFG] = RAMIPS_PDMA_GLO_CFG, -+ [RAETH_REG_PDMA_RST_CFG] = RAMIPS_PDMA_RST_CFG, -+ [RAETH_REG_DLY_INT_CFG] = RAMIPS_DLY_INT_CFG, -+ [RAETH_REG_TX_BASE_PTR0] = RAMIPS_TX_BASE_PTR0, -+ [RAETH_REG_TX_MAX_CNT0] = RAMIPS_TX_MAX_CNT0, -+ [RAETH_REG_TX_CTX_IDX0] = RAMIPS_TX_CTX_IDX0, -+ [RAETH_REG_RX_BASE_PTR0] = RAMIPS_RX_BASE_PTR0, -+ [RAETH_REG_RX_MAX_CNT0] = RAMIPS_RX_MAX_CNT0, -+ [RAETH_REG_RX_CALC_IDX0] = RAMIPS_RX_CALC_IDX0, -+ [RAETH_REG_FE_INT_ENABLE] = RAMIPS_FE_INT_ENABLE, -+ [RAETH_REG_FE_INT_STATUS] = RAMIPS_FE_INT_STATUS, -+}; -+ -+static const u32 rt5350_reg_table[RAETH_REG_COUNT] = { -+ [RAETH_REG_PDMA_GLO_CFG] = RT5350_PDMA_GLO_CFG, -+ [RAETH_REG_PDMA_RST_CFG] = RT5350_PDMA_RST_CFG, -+ [RAETH_REG_DLY_INT_CFG] = RT5350_DLY_INT_CFG, -+ [RAETH_REG_TX_BASE_PTR0] = RT5350_TX_BASE_PTR0, -+ [RAETH_REG_TX_MAX_CNT0] = RT5350_TX_MAX_CNT0, -+ [RAETH_REG_TX_CTX_IDX0] = RT5350_TX_CTX_IDX0, -+ [RAETH_REG_RX_BASE_PTR0] = RT5350_RX_BASE_PTR0, -+ [RAETH_REG_RX_MAX_CNT0] = RT5350_RX_MAX_CNT0, -+ [RAETH_REG_RX_CALC_IDX0] = RT5350_RX_CALC_IDX0, -+ [RAETH_REG_FE_INT_ENABLE] = RT5350_FE_INT_ENABLE, -+ [RAETH_REG_FE_INT_STATUS] = RT5350_FE_INT_STATUS, -+}; -+ -+static struct net_device * ramips_dev; -+static void __iomem *ramips_fe_base = 0; -+ -+static inline u32 get_reg_offset(enum raeth_reg reg) -+{ -+ const u32 *table; -+ -+ if (soc_is_rt5350()) -+ table = rt5350_reg_table; -+ else -+ table = ramips_reg_table; -+ -+ return table[reg]; -+} -+ -+static inline void -+ramips_fe_wr(u32 val, unsigned reg) -+{ -+ __raw_writel(val, ramips_fe_base + reg); -+} -+ -+static inline u32 -+ramips_fe_rr(unsigned reg) -+{ -+ return __raw_readl(ramips_fe_base + reg); -+} -+ -+static inline void -+ramips_fe_twr(u32 val, enum raeth_reg reg) -+{ -+ ramips_fe_wr(val, get_reg_offset(reg)); -+} -+ -+static inline u32 -+ramips_fe_trr(enum raeth_reg reg) -+{ -+ return ramips_fe_rr(get_reg_offset(reg)); -+} -+ -+static inline void -+ramips_fe_int_disable(u32 mask) -+{ -+ ramips_fe_twr(ramips_fe_trr(RAETH_REG_FE_INT_ENABLE) & ~mask, -+ RAETH_REG_FE_INT_ENABLE); -+ /* flush write */ -+ ramips_fe_trr(RAETH_REG_FE_INT_ENABLE); -+} -+ -+static inline void -+ramips_fe_int_enable(u32 mask) -+{ -+ ramips_fe_twr(ramips_fe_trr(RAETH_REG_FE_INT_ENABLE) | mask, -+ RAETH_REG_FE_INT_ENABLE); -+ /* flush write */ -+ ramips_fe_trr(RAETH_REG_FE_INT_ENABLE); -+} -+ -+static inline void -+ramips_hw_set_macaddr(unsigned char *mac) -+{ -+ if (soc_is_rt5350()) { -+ ramips_fe_wr((mac[0] << 8) | mac[1], RT5350_SDM_MAC_ADRH); -+ ramips_fe_wr((mac[2] << 24) | (mac[3] << 16) | (mac[4] << 8) | mac[5], -+ RT5350_SDM_MAC_ADRL); -+ } else { -+ ramips_fe_wr((mac[0] << 8) | mac[1], RAMIPS_GDMA1_MAC_ADRH); -+ ramips_fe_wr((mac[2] << 24) | (mac[3] << 16) | (mac[4] << 8) | mac[5], -+ RAMIPS_GDMA1_MAC_ADRL); -+ } -+} -+ -+static struct sk_buff * -+ramips_alloc_skb(struct raeth_priv *re) -+{ -+ struct sk_buff *skb; -+ -+ skb = netdev_alloc_skb(re->netdev, MAX_RX_LENGTH + NET_IP_ALIGN); -+ if (!skb) -+ return NULL; -+ -+ skb_reserve(skb, NET_IP_ALIGN); -+ -+ return skb; -+} -+ -+static void -+ramips_ring_setup(struct raeth_priv *re) -+{ -+ int len; -+ int i; -+ -+ memset(re->tx_info, 0, NUM_TX_DESC * sizeof(struct raeth_tx_info)); -+ -+ len = NUM_TX_DESC * sizeof(struct ramips_tx_dma); -+ memset(re->tx, 0, len); -+ -+ for (i = 0; i < NUM_TX_DESC; i++) { -+ struct raeth_tx_info *txi; -+ struct ramips_tx_dma *txd; -+ -+ txd = &re->tx[i]; -+ txd->txd4 = TX_DMA_QN(3) | TX_DMA_PN(1); -+ txd->txd2 = TX_DMA_LSO | TX_DMA_DONE; -+ -+ txi = &re->tx_info[i]; -+ txi->tx_desc = txd; -+ if (txi->tx_skb != NULL) { -+ netdev_warn(re->netdev, -+ "dirty skb for TX desc %d\n", i); -+ txi->tx_skb = NULL; -+ } -+ } -+ -+ len = NUM_RX_DESC * sizeof(struct ramips_rx_dma); -+ memset(re->rx, 0, len); -+ -+ for (i = 0; i < NUM_RX_DESC; i++) { -+ struct raeth_rx_info *rxi; -+ struct ramips_rx_dma *rxd; -+ dma_addr_t dma_addr; -+ -+ rxd = &re->rx[i]; -+ rxi = &re->rx_info[i]; -+ BUG_ON(rxi->rx_skb == NULL); -+ dma_addr = dma_map_single(&re->netdev->dev, rxi->rx_skb->data, -+ MAX_RX_LENGTH, DMA_FROM_DEVICE); -+ rxi->rx_dma = dma_addr; -+ rxi->rx_desc = rxd; -+ -+ rxd->rxd1 = (unsigned int) dma_addr; -+ rxd->rxd2 = RX_DMA_LSO; -+ } -+ -+ /* flush descriptors */ -+ wmb(); -+} -+ -+static void -+ramips_ring_cleanup(struct raeth_priv *re) -+{ -+ int i; -+ -+ for (i = 0; i < NUM_RX_DESC; i++) { -+ struct raeth_rx_info *rxi; -+ -+ rxi = &re->rx_info[i]; -+ if (rxi->rx_skb) -+ dma_unmap_single(&re->netdev->dev, rxi->rx_dma, -+ MAX_RX_LENGTH, DMA_FROM_DEVICE); -+ } -+ -+ for (i = 0; i < NUM_TX_DESC; i++) { -+ struct raeth_tx_info *txi; -+ -+ txi = &re->tx_info[i]; -+ if (txi->tx_skb) { -+ dev_kfree_skb_any(txi->tx_skb); -+ txi->tx_skb = NULL; -+ } -+ } -+ -+ netdev_reset_queue(re->netdev); -+} -+ -+#if defined(CONFIG_SOC_RT288X) || defined(CONFIG_SOC_RT3883) -+ -+#define RAMIPS_MDIO_RETRY 1000 -+ -+static unsigned char *ramips_speed_str(struct raeth_priv *re) -+{ -+ switch (re->speed) { -+ case SPEED_1000: -+ return "1000"; -+ case SPEED_100: -+ return "100"; -+ case SPEED_10: -+ return "10"; -+ } -+ -+ return "?"; -+} -+ -+static void ramips_link_adjust(struct raeth_priv *re) -+{ -+ u32 mdio_cfg; -+ -+ if (!re->link) { -+ netif_carrier_off(re->netdev); -+ netdev_info(re->netdev, "link down\n"); -+ return; -+ } -+ -+ mdio_cfg = RAMIPS_MDIO_CFG_TX_CLK_SKEW_200 | -+ RAMIPS_MDIO_CFG_TX_CLK_SKEW_200 | -+ RAMIPS_MDIO_CFG_GP1_FRC_EN; -+ -+ if (re->duplex == DUPLEX_FULL) -+ mdio_cfg |= RAMIPS_MDIO_CFG_GP1_DUPLEX; -+ -+ if (re->tx_fc) -+ mdio_cfg |= RAMIPS_MDIO_CFG_GP1_FC_TX; -+ -+ if (re->rx_fc) -+ mdio_cfg |= RAMIPS_MDIO_CFG_GP1_FC_RX; -+ -+ switch (re->speed) { -+ case SPEED_10: -+ mdio_cfg |= RAMIPS_MDIO_CFG_GP1_SPEED_10; -+ break; -+ case SPEED_100: -+ mdio_cfg |= RAMIPS_MDIO_CFG_GP1_SPEED_100; -+ break; -+ case SPEED_1000: -+ mdio_cfg |= RAMIPS_MDIO_CFG_GP1_SPEED_1000; -+ break; -+ default: -+ BUG(); -+ } -+ -+ ramips_fe_wr(mdio_cfg, RAMIPS_MDIO_CFG); -+ -+ netif_carrier_on(re->netdev); -+ netdev_info(re->netdev, "link up (%sMbps/%s duplex)\n", -+ ramips_speed_str(re), -+ (DUPLEX_FULL == re->duplex) ? "Full" : "Half"); -+} -+ -+static int -+ramips_mdio_wait_ready(struct raeth_priv *re) -+{ -+ int retries; -+ -+ retries = RAMIPS_MDIO_RETRY; -+ while (1) { -+ u32 t; -+ -+ t = ramips_fe_rr(RAMIPS_MDIO_ACCESS); -+ if ((t & (0x1 << 31)) == 0) -+ return 0; -+ -+ if (retries-- == 0) -+ break; -+ -+ udelay(1); -+ } -+ -+ dev_err(re->parent, "MDIO operation timed out\n"); -+ return -ETIMEDOUT; -+} -+ -+static int -+ramips_mdio_read(struct mii_bus *bus, int phy_addr, int phy_reg) -+{ -+ struct raeth_priv *re = bus->priv; -+ int err; -+ u32 t; -+ -+ err = ramips_mdio_wait_ready(re); -+ if (err) -+ return 0xffff; -+ -+ t = (phy_addr << 24) | (phy_reg << 16); -+ ramips_fe_wr(t, RAMIPS_MDIO_ACCESS); -+ t |= (1 << 31); -+ ramips_fe_wr(t, RAMIPS_MDIO_ACCESS); -+ -+ err = ramips_mdio_wait_ready(re); -+ if (err) -+ return 0xffff; -+ -+ RADEBUG("%s: addr=%04x, reg=%04x, value=%04x\n", __func__, -+ phy_addr, phy_reg, ramips_fe_rr(RAMIPS_MDIO_ACCESS) & 0xffff); -+ -+ return ramips_fe_rr(RAMIPS_MDIO_ACCESS) & 0xffff; -+} -+ -+static int -+ramips_mdio_write(struct mii_bus *bus, int phy_addr, int phy_reg, u16 val) -+{ -+ struct raeth_priv *re = bus->priv; -+ int err; -+ u32 t; -+ -+ RADEBUG("%s: addr=%04x, reg=%04x, value=%04x\n", __func__, -+ phy_addr, phy_reg, ramips_fe_rr(RAMIPS_MDIO_ACCESS) & 0xffff); -+ -+ err = ramips_mdio_wait_ready(re); -+ if (err) -+ return err; -+ -+ t = (1 << 30) | (phy_addr << 24) | (phy_reg << 16) | val; -+ ramips_fe_wr(t, RAMIPS_MDIO_ACCESS); -+ t |= (1 << 31); -+ ramips_fe_wr(t, RAMIPS_MDIO_ACCESS); -+ -+ return ramips_mdio_wait_ready(re); -+} -+ -+static int -+ramips_mdio_reset(struct mii_bus *bus) -+{ -+ /* TODO */ -+ return 0; -+} -+ -+static int -+ramips_mdio_init(struct raeth_priv *re) -+{ -+ int err; -+ int i; -+ -+ re->mii_bus = mdiobus_alloc(); -+ if (re->mii_bus == NULL) -+ return -ENOMEM; -+ -+ re->mii_bus->name = "ramips_mdio"; -+ re->mii_bus->read = ramips_mdio_read; -+ re->mii_bus->write = ramips_mdio_write; -+ re->mii_bus->reset = ramips_mdio_reset; -+ re->mii_bus->irq = re->mii_irq; -+ re->mii_bus->priv = re; -+ re->mii_bus->parent = re->parent; -+ -+ snprintf(re->mii_bus->id, MII_BUS_ID_SIZE, "%s", "ramips_mdio"); -+ re->mii_bus->phy_mask = 0; -+ -+ for (i = 0; i < PHY_MAX_ADDR; i++) -+ re->mii_irq[i] = PHY_POLL; -+ -+ err = mdiobus_register(re->mii_bus); -+ if (err) -+ goto err_free_bus; -+ -+ return 0; -+ -+err_free_bus: -+ kfree(re->mii_bus); -+ return err; -+} -+ -+static void -+ramips_mdio_cleanup(struct raeth_priv *re) -+{ -+ mdiobus_unregister(re->mii_bus); -+ kfree(re->mii_bus); -+} -+ -+static void -+ramips_phy_link_adjust(struct net_device *dev) -+{ -+ struct raeth_priv *re = netdev_priv(dev); -+ struct phy_device *phydev = re->phy_dev; -+ unsigned long flags; -+ int status_change = 0; -+ -+ spin_lock_irqsave(&re->phy_lock, flags); -+ -+ if (phydev->link) -+ if (re->duplex != phydev->duplex || -+ re->speed != phydev->speed) -+ status_change = 1; -+ -+ if (phydev->link != re->link) -+ status_change = 1; -+ -+ re->link = phydev->link; -+ re->duplex = phydev->duplex; -+ re->speed = phydev->speed; -+ -+ if (status_change) -+ ramips_link_adjust(re); -+ -+ spin_unlock_irqrestore(&re->phy_lock, flags); -+} -+ -+static int -+ramips_phy_connect_multi(struct raeth_priv *re) -+{ -+ struct net_device *netdev = re->netdev; -+ struct phy_device *phydev = NULL; -+ int phy_addr; -+ int ret = 0; -+ -+ for (phy_addr = 0; phy_addr < PHY_MAX_ADDR; phy_addr++) { -+ if (!(re->phy_mask & (1 << phy_addr))) -+ continue; -+ -+ if (re->mii_bus->phy_map[phy_addr] == NULL) -+ continue; -+ -+ RADEBUG("%s: PHY found at %s, uid=%08x\n", -+ netdev->name, -+ dev_name(&re->mii_bus->phy_map[phy_addr]->dev), -+ re->mii_bus->phy_map[phy_addr]->phy_id); -+ -+ if (phydev == NULL) -+ phydev = re->mii_bus->phy_map[phy_addr]; -+ } -+ -+ if (!phydev) { -+ netdev_err(netdev, "no PHY found with phy_mask=%08x\n", -+ re->phy_mask); -+ return -ENODEV; -+ } -+ -+ re->phy_dev = phy_connect(netdev, dev_name(&phydev->dev), -+ ramips_phy_link_adjust, 0, re->phy_if_mode); -+ -+ if (IS_ERR(re->phy_dev)) { -+ netdev_err(netdev, "could not connect to PHY at %s\n", -+ dev_name(&phydev->dev)); -+ return PTR_ERR(re->phy_dev); -+ } -+ -+ phydev->supported &= PHY_GBIT_FEATURES; -+ phydev->advertising = phydev->supported; -+ -+ RADEBUG("%s: connected to PHY at %s [uid=%08x, driver=%s]\n", -+ netdev->name, dev_name(&phydev->dev), -+ phydev->phy_id, phydev->drv->name); -+ -+ re->link = 0; -+ re->speed = 0; -+ re->duplex = -1; -+ re->rx_fc = 0; -+ re->tx_fc = 0; -+ -+ return ret; -+} -+ -+static int -+ramips_phy_connect_fixed(struct raeth_priv *re) -+{ -+ if (!re->speed) { -+ const __be32 *link; -+ int size; -+ -+ link = of_get_property(re->of_node, -+ "ralink,fixed-link", &size); -+ if (!link || size != (4 * sizeof(*link))) -+ return -ENOENT; -+ -+ re->speed = be32_to_cpup(link++); -+ re->duplex = be32_to_cpup(link++); -+ re->tx_fc = be32_to_cpup(link++); -+ re->rx_fc = be32_to_cpup(link++); -+ } -+ -+ switch (re->speed) { -+ case SPEED_10: -+ case SPEED_100: -+ case SPEED_1000: -+ break; -+ default: -+ netdev_err(re->netdev, "invalid speed specified\n"); -+ return -EINVAL; -+ } -+ -+ pr_info("%s: using fixed link parameters\n", re->netdev->name); -+ return 0; -+} -+ -+static int -+ramips_phy_connect(struct raeth_priv *re) -+{ -+ const __be32 *mask; -+ -+ mask = of_get_property(re->of_node, "ralink,phy-mask", NULL); -+ re->phy_if_mode = of_get_phy_mode(re->of_node); -+ -+ if (!re->phy_if_mode || !mask) -+ return ramips_phy_connect_fixed(re); -+ -+ re->phy_mask = be32_to_cpup(mask); -+ return ramips_phy_connect_multi(re); -+ -+} -+ -+static void -+ramips_phy_disconnect(struct raeth_priv *re) -+{ -+ if (re->phy_dev) -+ phy_disconnect(re->phy_dev); -+} -+ -+static void -+ramips_phy_start(struct raeth_priv *re) -+{ -+ unsigned long flags; -+ -+ if (re->phy_dev) { -+ phy_start(re->phy_dev); -+ } else { -+ spin_lock_irqsave(&re->phy_lock, flags); -+ re->link = 1; -+ ramips_link_adjust(re); -+ spin_unlock_irqrestore(&re->phy_lock, flags); -+ } -+} -+ -+static void -+ramips_phy_stop(struct raeth_priv *re) -+{ -+ unsigned long flags; -+ -+ if (re->phy_dev) -+ phy_stop(re->phy_dev); -+ -+ spin_lock_irqsave(&re->phy_lock, flags); -+ re->link = 0; -+ ramips_link_adjust(re); -+ spin_unlock_irqrestore(&re->phy_lock, flags); -+} -+#else -+static inline int -+ramips_mdio_init(struct raeth_priv *re) -+{ -+ return 0; -+} -+ -+static inline void -+ramips_mdio_cleanup(struct raeth_priv *re) -+{ -+} -+ -+static inline int -+ramips_phy_connect(struct raeth_priv *re) -+{ -+ return 0; -+} -+ -+static inline void -+ramips_phy_disconnect(struct raeth_priv *re) -+{ -+} -+ -+static inline void -+ramips_phy_start(struct raeth_priv *re) -+{ -+} -+ -+static inline void -+ramips_phy_stop(struct raeth_priv *re) -+{ -+} -+#endif /* CONFIG_SOC_RT288X || CONFIG_SOC_RT3883 */ -+ -+static void -+ramips_ring_free(struct raeth_priv *re) -+{ -+ int len; -+ int i; -+ -+ if (re->rx_info) { -+ for (i = 0; i < NUM_RX_DESC; i++) { -+ struct raeth_rx_info *rxi; -+ -+ rxi = &re->rx_info[i]; -+ if (rxi->rx_skb) -+ dev_kfree_skb_any(rxi->rx_skb); -+ } -+ kfree(re->rx_info); -+ } -+ -+ if (re->rx) { -+ len = NUM_RX_DESC * sizeof(struct ramips_rx_dma); -+ dma_free_coherent(&re->netdev->dev, len, re->rx, -+ re->rx_desc_dma); -+ } -+ -+ if (re->tx) { -+ len = NUM_TX_DESC * sizeof(struct ramips_tx_dma); -+ dma_free_coherent(&re->netdev->dev, len, re->tx, -+ re->tx_desc_dma); -+ } -+ -+ kfree(re->tx_info); -+} -+ -+static int -+ramips_ring_alloc(struct raeth_priv *re) -+{ -+ int len; -+ int err = -ENOMEM; -+ int i; -+ -+ re->tx_info = kzalloc(NUM_TX_DESC * sizeof(struct raeth_tx_info), -+ GFP_ATOMIC); -+ if (!re->tx_info) -+ goto err_cleanup; -+ -+ re->rx_info = kzalloc(NUM_RX_DESC * sizeof(struct raeth_rx_info), -+ GFP_ATOMIC); -+ if (!re->rx_info) -+ goto err_cleanup; -+ -+ /* allocate tx ring */ -+ len = NUM_TX_DESC * sizeof(struct ramips_tx_dma); -+ re->tx = dma_alloc_coherent(&re->netdev->dev, len, -+ &re->tx_desc_dma, GFP_ATOMIC); -+ if (!re->tx) -+ goto err_cleanup; -+ -+ /* allocate rx ring */ -+ len = NUM_RX_DESC * sizeof(struct ramips_rx_dma); -+ re->rx = dma_alloc_coherent(&re->netdev->dev, len, -+ &re->rx_desc_dma, GFP_ATOMIC); -+ if (!re->rx) -+ goto err_cleanup; -+ -+ for (i = 0; i < NUM_RX_DESC; i++) { -+ struct sk_buff *skb; -+ -+ skb = ramips_alloc_skb(re); -+ if (!skb) -+ goto err_cleanup; -+ -+ re->rx_info[i].rx_skb = skb; -+ } -+ -+ return 0; -+ -+err_cleanup: -+ ramips_ring_free(re); -+ return err; -+} -+ -+static void -+ramips_setup_dma(struct raeth_priv *re) -+{ -+ ramips_fe_twr(re->tx_desc_dma, RAETH_REG_TX_BASE_PTR0); -+ ramips_fe_twr(NUM_TX_DESC, RAETH_REG_TX_MAX_CNT0); -+ ramips_fe_twr(0, RAETH_REG_TX_CTX_IDX0); -+ ramips_fe_twr(RAMIPS_PST_DTX_IDX0, RAETH_REG_PDMA_RST_CFG); -+ -+ ramips_fe_twr(re->rx_desc_dma, RAETH_REG_RX_BASE_PTR0); -+ ramips_fe_twr(NUM_RX_DESC, RAETH_REG_RX_MAX_CNT0); -+ ramips_fe_twr((NUM_RX_DESC - 1), RAETH_REG_RX_CALC_IDX0); -+ ramips_fe_twr(RAMIPS_PST_DRX_IDX0, RAETH_REG_PDMA_RST_CFG); -+} -+ -+static int -+ramips_eth_hard_start_xmit(struct sk_buff *skb, struct net_device *dev) -+{ -+ struct raeth_priv *re = netdev_priv(dev); -+ struct raeth_tx_info *txi, *txi_next; -+ struct ramips_tx_dma *txd, *txd_next; -+ unsigned long tx; -+ unsigned int tx_next; -+ dma_addr_t mapped_addr; -+ -+ if (re->min_pkt_len) { -+ if (skb->len < re->min_pkt_len) { -+ if (skb_padto(skb, re->min_pkt_len)) { -+ printk(KERN_ERR -+ "ramips_eth: skb_padto failed\n"); -+ kfree_skb(skb); -+ return 0; -+ } -+ skb_put(skb, re->min_pkt_len - skb->len); -+ } -+ } -+ -+ dev->trans_start = jiffies; -+ mapped_addr = dma_map_single(&re->netdev->dev, skb->data, skb->len, -+ DMA_TO_DEVICE); -+ -+ spin_lock(&re->page_lock); -+ tx = ramips_fe_trr(RAETH_REG_TX_CTX_IDX0); -+ tx_next = (tx + 1) % NUM_TX_DESC; -+ -+ txi = &re->tx_info[tx]; -+ txd = txi->tx_desc; -+ txi_next = &re->tx_info[tx_next]; -+ txd_next = txi_next->tx_desc; -+ -+ if ((txi->tx_skb) || (txi_next->tx_skb) || -+ !(txd->txd2 & TX_DMA_DONE) || -+ !(txd_next->txd2 & TX_DMA_DONE)) -+ goto out; -+ -+ txi->tx_skb = skb; -+ -+ txd->txd1 = (unsigned int) mapped_addr; -+ wmb(); -+ txd->txd2 = TX_DMA_LSO | TX_DMA_PLEN0(skb->len); -+ dev->stats.tx_packets++; -+ dev->stats.tx_bytes += skb->len; -+ ramips_fe_twr(tx_next, RAETH_REG_TX_CTX_IDX0); -+ netdev_sent_queue(dev, skb->len); -+ spin_unlock(&re->page_lock); -+ return NETDEV_TX_OK; -+ -+ out: -+ spin_unlock(&re->page_lock); -+ dev->stats.tx_dropped++; -+ kfree_skb(skb); -+ return NETDEV_TX_OK; -+} -+ -+static void -+ramips_eth_rx_hw(unsigned long ptr) -+{ -+ struct net_device *dev = (struct net_device *) ptr; -+ struct raeth_priv *re = netdev_priv(dev); -+ int rx; -+ int max_rx = 16; -+ -+ rx = ramips_fe_trr(RAETH_REG_RX_CALC_IDX0); -+ -+ while (max_rx) { -+ struct raeth_rx_info *rxi; -+ struct ramips_rx_dma *rxd; -+ struct sk_buff *rx_skb, *new_skb; -+ int pktlen; -+ -+ rx = (rx + 1) % NUM_RX_DESC; -+ -+ rxi = &re->rx_info[rx]; -+ rxd = rxi->rx_desc; -+ if (!(rxd->rxd2 & RX_DMA_DONE)) -+ break; -+ -+ rx_skb = rxi->rx_skb; -+ pktlen = RX_DMA_PLEN0(rxd->rxd2); -+ -+ new_skb = ramips_alloc_skb(re); -+ /* Reuse the buffer on allocation failures */ -+ if (new_skb) { -+ dma_addr_t dma_addr; -+ -+ dma_unmap_single(&re->netdev->dev, rxi->rx_dma, -+ MAX_RX_LENGTH, DMA_FROM_DEVICE); -+ -+ skb_put(rx_skb, pktlen); -+ rx_skb->dev = dev; -+ rx_skb->protocol = eth_type_trans(rx_skb, dev); -+ rx_skb->ip_summed = CHECKSUM_NONE; -+ dev->stats.rx_packets++; -+ dev->stats.rx_bytes += pktlen; -+ netif_rx(rx_skb); -+ -+ rxi->rx_skb = new_skb; -+ -+ dma_addr = dma_map_single(&re->netdev->dev, -+ new_skb->data, -+ MAX_RX_LENGTH, -+ DMA_FROM_DEVICE); -+ rxi->rx_dma = dma_addr; -+ rxd->rxd1 = (unsigned int) dma_addr; -+ wmb(); -+ } else { -+ dev->stats.rx_dropped++; -+ } -+ -+ rxd->rxd2 = RX_DMA_LSO; -+ ramips_fe_twr(rx, RAETH_REG_RX_CALC_IDX0); -+ max_rx--; -+ } -+ -+ if (max_rx == 0) -+ tasklet_schedule(&re->rx_tasklet); -+ else -+ ramips_fe_int_enable(RX_DLY_INT); -+} -+ -+static void -+ramips_eth_tx_housekeeping(unsigned long ptr) -+{ -+ struct net_device *dev = (struct net_device*)ptr; -+ struct raeth_priv *re = netdev_priv(dev); -+ unsigned int bytes_compl = 0, pkts_compl = 0; -+ -+ spin_lock(&re->page_lock); -+ while (1) { -+ struct raeth_tx_info *txi; -+ struct ramips_tx_dma *txd; -+ -+ txi = &re->tx_info[re->skb_free_idx]; -+ txd = txi->tx_desc; -+ -+ if (!(txd->txd2 & TX_DMA_DONE) || !(txi->tx_skb)) -+ break; -+ -+ pkts_compl++; -+ bytes_compl += txi->tx_skb->len; -+ -+ dev_kfree_skb_irq(txi->tx_skb); -+ txi->tx_skb = NULL; -+ re->skb_free_idx++; -+ if (re->skb_free_idx >= NUM_TX_DESC) -+ re->skb_free_idx = 0; -+ } -+ netdev_completed_queue(dev, pkts_compl, bytes_compl); -+ spin_unlock(&re->page_lock); -+ -+ ramips_fe_int_enable(TX_DLY_INT); -+} -+ -+static void -+ramips_eth_timeout(struct net_device *dev) -+{ -+ struct raeth_priv *re = netdev_priv(dev); -+ -+ tasklet_schedule(&re->tx_housekeeping_tasklet); -+} -+ -+static irqreturn_t -+ramips_eth_irq(int irq, void *dev) -+{ -+ struct raeth_priv *re = netdev_priv(dev); -+ unsigned int status; -+ -+ status = ramips_fe_trr(RAETH_REG_FE_INT_STATUS); -+ status &= ramips_fe_trr(RAETH_REG_FE_INT_ENABLE); -+ -+ if (!status) -+ return IRQ_NONE; -+ -+ ramips_fe_twr(status, RAETH_REG_FE_INT_STATUS); -+ -+ if (status & RX_DLY_INT) { -+ ramips_fe_int_disable(RX_DLY_INT); -+ tasklet_schedule(&re->rx_tasklet); -+ } -+ -+ if (status & TX_DLY_INT) { -+ ramips_fe_int_disable(TX_DLY_INT); -+ tasklet_schedule(&re->tx_housekeeping_tasklet); -+ } -+ -+ raeth_debugfs_update_int_stats(re, status); -+ -+ return IRQ_HANDLED; -+} -+ -+static int -+ramips_eth_hw_init(struct net_device *dev) -+{ -+ struct raeth_priv *re = netdev_priv(dev); -+ int err; -+ -+ err = request_irq(dev->irq, ramips_eth_irq, IRQF_DISABLED, -+ dev_name(re->parent), dev); -+ if (err) -+ return err; -+ -+ err = ramips_ring_alloc(re); -+ if (err) -+ goto err_free_irq; -+ -+ ramips_ring_setup(re); -+ ramips_hw_set_macaddr(dev->dev_addr); -+ -+ ramips_setup_dma(re); -+ ramips_fe_wr((ramips_fe_rr(RAMIPS_FE_GLO_CFG) & -+ ~(RAMIPS_US_CYC_CNT_MASK << RAMIPS_US_CYC_CNT_SHIFT)) | -+ ((re->sys_freq / RAMIPS_US_CYC_CNT_DIVISOR) << RAMIPS_US_CYC_CNT_SHIFT), -+ RAMIPS_FE_GLO_CFG); -+ -+ tasklet_init(&re->tx_housekeeping_tasklet, ramips_eth_tx_housekeeping, -+ (unsigned long)dev); -+ tasklet_init(&re->rx_tasklet, ramips_eth_rx_hw, (unsigned long)dev); -+ -+ -+ ramips_fe_twr(RAMIPS_DELAY_INIT, RAETH_REG_DLY_INT_CFG); -+ ramips_fe_twr(TX_DLY_INT | RX_DLY_INT, RAETH_REG_FE_INT_ENABLE); -+ if (soc_is_rt5350()) { -+ ramips_fe_wr(ramips_fe_rr(RT5350_SDM_CFG) & -+ ~(RT5350_SDM_ICS_EN | RT5350_SDM_TCS_EN | RT5350_SDM_UCS_EN | 0xffff), -+ RT5350_SDM_CFG); -+ } else { -+ ramips_fe_wr(ramips_fe_rr(RAMIPS_GDMA1_FWD_CFG) & -+ ~(RAMIPS_GDM1_ICS_EN | RAMIPS_GDM1_TCS_EN | RAMIPS_GDM1_UCS_EN | 0xffff), -+ RAMIPS_GDMA1_FWD_CFG); -+ ramips_fe_wr(ramips_fe_rr(RAMIPS_CDMA_CSG_CFG) & -+ ~(RAMIPS_ICS_GEN_EN | RAMIPS_TCS_GEN_EN | RAMIPS_UCS_GEN_EN), -+ RAMIPS_CDMA_CSG_CFG); -+ ramips_fe_wr(RAMIPS_PSE_FQFC_CFG_INIT, RAMIPS_PSE_FQ_CFG); -+ } -+ ramips_fe_wr(1, RAMIPS_FE_RST_GL); -+ ramips_fe_wr(0, RAMIPS_FE_RST_GL); -+ -+ return 0; -+ -+err_free_irq: -+ free_irq(dev->irq, dev); -+ return err; -+} -+ -+static int -+ramips_eth_open(struct net_device *dev) -+{ -+ struct raeth_priv *re = netdev_priv(dev); -+ -+ ramips_fe_twr((ramips_fe_trr(RAETH_REG_PDMA_GLO_CFG) & 0xff) | -+ (RAMIPS_TX_WB_DDONE | RAMIPS_RX_DMA_EN | -+ RAMIPS_TX_DMA_EN | RAMIPS_PDMA_SIZE_4DWORDS), -+ RAETH_REG_PDMA_GLO_CFG); -+ ramips_phy_start(re); -+ netif_start_queue(dev); -+ return 0; -+} -+ -+static int -+ramips_eth_stop(struct net_device *dev) -+{ -+ struct raeth_priv *re = netdev_priv(dev); -+ -+ ramips_fe_twr(ramips_fe_trr(RAETH_REG_PDMA_GLO_CFG) & -+ ~(RAMIPS_TX_WB_DDONE | RAMIPS_RX_DMA_EN | RAMIPS_TX_DMA_EN), -+ RAETH_REG_PDMA_GLO_CFG); -+ -+ netif_stop_queue(dev); -+ ramips_phy_stop(re); -+ RADEBUG("ramips_eth: stopped\n"); -+ return 0; -+} -+ -+static int __init -+ramips_eth_probe(struct net_device *dev) -+{ -+ struct raeth_priv *re = netdev_priv(dev); -+ int err; -+ -+ BUG_ON(!re->reset_fe); -+ re->reset_fe(); -+ net_srandom(jiffies); -+ memcpy(dev->dev_addr, re->mac, ETH_ALEN); -+ of_get_mac_address_mtd(re->of_node, dev->dev_addr); -+ ether_setup(dev); -+ dev->mtu = 1500; -+ dev->watchdog_timeo = TX_TIMEOUT; -+ spin_lock_init(&re->page_lock); -+ spin_lock_init(&re->phy_lock); -+ -+ err = ramips_mdio_init(re); -+ if (err) -+ return err; -+ -+ err = ramips_phy_connect(re); -+ if (err) -+ goto err_mdio_cleanup; -+ -+ err = raeth_debugfs_init(re); -+ if (err) -+ goto err_phy_disconnect; -+ -+ err = ramips_eth_hw_init(dev); -+ if (err) -+ goto err_debugfs; -+ -+ return 0; -+ -+err_debugfs: -+ raeth_debugfs_exit(re); -+err_phy_disconnect: -+ ramips_phy_disconnect(re); -+err_mdio_cleanup: -+ ramips_mdio_cleanup(re); -+ return err; -+} -+ -+static void -+ramips_eth_uninit(struct net_device *dev) -+{ -+ struct raeth_priv *re = netdev_priv(dev); -+ -+ raeth_debugfs_exit(re); -+ ramips_phy_disconnect(re); -+ ramips_mdio_cleanup(re); -+ ramips_fe_twr(0, RAETH_REG_FE_INT_ENABLE); -+ free_irq(dev->irq, dev); -+ tasklet_kill(&re->tx_housekeeping_tasklet); -+ tasklet_kill(&re->rx_tasklet); -+ ramips_ring_cleanup(re); -+ ramips_ring_free(re); -+} -+ -+static const struct net_device_ops ramips_eth_netdev_ops = { -+ .ndo_init = ramips_eth_probe, -+ .ndo_uninit = ramips_eth_uninit, -+ .ndo_open = ramips_eth_open, -+ .ndo_stop = ramips_eth_stop, -+ .ndo_start_xmit = ramips_eth_hard_start_xmit, -+ .ndo_tx_timeout = ramips_eth_timeout, -+ .ndo_change_mtu = eth_change_mtu, -+ .ndo_set_mac_address = eth_mac_addr, -+ .ndo_validate_addr = eth_validate_addr, -+}; -+ -+#ifdef CONFIG_SOC_RT305X -+static void rt305x_fe_reset(void) -+{ -+#define RT305X_RESET_FE BIT(21) -+#define RT305X_RESET_ESW BIT(23) -+#define SYSC_REG_RESET_CTRL 0x034 -+ u32 reset_bits = RT305X_RESET_FE; -+ -+ if (soc_is_rt5350()) -+ reset_bits |= RT305X_RESET_ESW; -+ rt_sysc_w32(reset_bits, SYSC_REG_RESET_CTRL); -+ rt_sysc_w32(0, SYSC_REG_RESET_CTRL); -+} -+ -+struct ramips_soc_data rt3050_data = { -+ .mac = { 0x00, 0x11, 0x22, 0x33, 0x44, 0x55 }, -+ .reset_fe = rt305x_fe_reset, -+ .min_pkt_len = 64, -+}; -+ -+static const struct of_device_id ralink_eth_match[] = { -+ { .compatible = "ralink,rt3050-eth", .data = &rt3050_data }, -+ {}, -+}; -+#else -+static void rt3883_fe_reset(void) -+{ -+#define RT3883_SYSC_REG_RSTCTRL 0x34 -+#define RT3883_RSTCTRL_FE BIT(21) -+ u32 t; -+ -+ t = rt_sysc_r32(RT3883_SYSC_REG_RSTCTRL); -+ t |= RT3883_RSTCTRL_FE; -+ rt_sysc_w32(t , RT3883_SYSC_REG_RSTCTRL); -+ -+ t &= ~RT3883_RSTCTRL_FE; -+ rt_sysc_w32(t, RT3883_SYSC_REG_RSTCTRL); -+} -+ -+struct ramips_soc_data rt3883_data = { -+ .mac = { 0x00, 0x11, 0x22, 0x33, 0x44, 0x55 }, -+ .reset_fe = rt3883_fe_reset, -+ .min_pkt_len = 64, -+}; -+ -+static const struct of_device_id ralink_eth_match[] = { -+ { .compatible = "ralink,rt3883-eth", .data = &rt3883_data }, -+ {}, -+}; -+#endif -+MODULE_DEVICE_TABLE(of, ralink_eth_match); -+ -+static int -+ramips_eth_plat_probe(struct platform_device *plat) -+{ -+ struct raeth_priv *re; -+ struct resource *res; -+ struct clk *clk; -+ int err; -+ const struct of_device_id *match; -+ const struct ramips_soc_data *soc = NULL; -+ -+ match = of_match_device(ralink_eth_match, &plat->dev); -+ if (match) -+ soc = (const struct ramips_soc_data *) match->data; -+ -+ if (!soc) { -+ dev_err(&plat->dev, "no platform data specified\n"); -+ return -EINVAL; -+ } -+ -+ res = platform_get_resource(plat, IORESOURCE_MEM, 0); -+ if (!res) { -+ dev_err(&plat->dev, "no memory resource found\n"); -+ return -ENXIO; -+ } -+ -+ ramips_fe_base = ioremap_nocache(res->start, res->end - res->start + 1); -+ if (!ramips_fe_base) -+ return -ENOMEM; -+ -+ ramips_dev = alloc_etherdev(sizeof(struct raeth_priv)); -+ if (!ramips_dev) { -+ dev_err(&plat->dev, "alloc_etherdev failed\n"); -+ err = -ENOMEM; -+ goto err_unmap; -+ } -+ -+ strcpy(ramips_dev->name, "eth%d"); -+ ramips_dev->irq = platform_get_irq(plat, 0); -+ if (ramips_dev->irq < 0) { -+ dev_err(&plat->dev, "no IRQ resource found\n"); -+ err = -ENXIO; -+ goto err_free_dev; -+ } -+ ramips_dev->addr_len = ETH_ALEN; -+ ramips_dev->base_addr = (unsigned long)ramips_fe_base; -+ ramips_dev->netdev_ops = &ramips_eth_netdev_ops; -+ -+ re = netdev_priv(ramips_dev); -+ -+ clk = clk_get(&plat->dev, NULL); -+ if (IS_ERR(clk)) -+ panic("unable to get SYS clock, err=%ld", PTR_ERR(clk)); -+ re->sys_freq = clk_get_rate(clk); -+ -+ re->netdev = ramips_dev; -+ re->of_node = plat->dev.of_node; -+ re->parent = &plat->dev; -+ memcpy(re->mac, soc->mac, 6); -+ re->reset_fe = soc->reset_fe; -+ re->min_pkt_len = soc->min_pkt_len; -+ -+ err = register_netdev(ramips_dev); -+ if (err) { -+ dev_err(&plat->dev, "error bringing up device\n"); -+ goto err_free_dev; -+ } -+ -+ netdev_info(ramips_dev, "done loading\n"); -+ return 0; -+ -+ err_free_dev: -+ kfree(ramips_dev); -+ err_unmap: -+ iounmap(ramips_fe_base); -+ return err; -+} -+ -+static int -+ramips_eth_plat_remove(struct platform_device *plat) -+{ -+ unregister_netdev(ramips_dev); -+ free_netdev(ramips_dev); -+ RADEBUG("ramips_eth: unloaded\n"); -+ return 0; -+} -+ -+ -+ -+static struct platform_driver ramips_eth_driver = { -+ .probe = ramips_eth_plat_probe, -+ .remove = ramips_eth_plat_remove, -+ .driver = { -+ .name = "ramips_eth", -+ .owner = THIS_MODULE, -+ .of_match_table = ralink_eth_match -+ }, -+}; -+ -+static int __init -+ramips_eth_init(void) -+{ -+ int ret; -+ -+ ret = raeth_debugfs_root_init(); -+ if (ret) -+ goto err_out; -+ -+ ret = rt305x_esw_init(); -+ if (ret) -+ goto err_debugfs_exit; -+ -+ ret = platform_driver_register(&ramips_eth_driver); -+ if (ret) { -+ printk(KERN_ERR -+ "ramips_eth: Error registering platfom driver!\n"); -+ goto esw_cleanup; -+ } -+ -+ return 0; -+ -+esw_cleanup: -+ rt305x_esw_exit(); -+err_debugfs_exit: -+ raeth_debugfs_root_exit(); -+err_out: -+ return ret; -+} -+ -+static void __exit -+ramips_eth_cleanup(void) -+{ -+ platform_driver_unregister(&ramips_eth_driver); -+ rt305x_esw_exit(); -+ raeth_debugfs_root_exit(); -+} -+ -+module_init(ramips_eth_init); -+module_exit(ramips_eth_cleanup); -+ -+MODULE_LICENSE("GPL"); -+MODULE_AUTHOR("John Crispin "); -+MODULE_DESCRIPTION("ethernet driver for ramips boards"); diff --git a/target/linux/ramips/patches-3.8/0121-MIPS-add-detect_memory_region.patch b/target/linux/ramips/patches-3.8/0121-MIPS-add-detect_memory_region.patch new file mode 100644 index 0000000000..8736e246b6 --- /dev/null +++ b/target/linux/ramips/patches-3.8/0121-MIPS-add-detect_memory_region.patch @@ -0,0 +1,61 @@ +From 9041c96ab5bd29d85ca95cffa44c755f68ae6bb1 Mon Sep 17 00:00:00 2001 +From: John Crispin +Date: Sat, 13 Apr 2013 13:15:47 +0200 +Subject: [PATCH 121/137] MIPS: add detect_memory_region() + +Add a generic way of detecting the available RAM. This function is based on the +implementation already used by ath79. + +Signed-off-by: John Crispin +Patchwork: http://patchwork.linux-mips.org/patch/5178/ +--- + arch/mips/include/asm/bootinfo.h | 1 + + arch/mips/kernel/setup.c | 20 ++++++++++++++++++++ + 2 files changed, 21 insertions(+) + +--- a/arch/mips/include/asm/bootinfo.h ++++ b/arch/mips/include/asm/bootinfo.h +@@ -104,6 +104,7 @@ struct boot_mem_map { + extern struct boot_mem_map boot_mem_map; + + extern void add_memory_region(phys_t start, phys_t size, long type); ++extern void detect_memory_region(phys_t start, phys_t sz_min, phys_t sz_max); + + extern void prom_init(void); + extern void prom_free_prom_memory(void); +--- a/arch/mips/kernel/setup.c ++++ b/arch/mips/kernel/setup.c +@@ -23,6 +23,7 @@ + #include + #include + #include ++#include + + #include + #include +@@ -122,6 +123,25 @@ void __init add_memory_region(phys_t sta + boot_mem_map.nr_map++; + } + ++void __init detect_memory_region(phys_t start, phys_t sz_min, phys_t sz_max) ++{ ++ phys_t size; ++ ++ for (size = sz_min; size < sz_max; size <<= 1) { ++ if (!memcmp(detect_memory_region, ++ detect_memory_region + size, 1024)) ++ break; ++ } ++ ++ pr_debug("Memory: %lluMB of RAM detected at 0x%llx (min: %lluMB, max: %lluMB)\n", ++ ((unsigned long long) size) / SZ_1M, ++ (unsigned long long) start, ++ ((unsigned long long) sz_min) / SZ_1M, ++ ((unsigned long long) sz_max) / SZ_1M); ++ ++ add_memory_region(start, size, BOOT_MEM_RAM); ++} ++ + static void __init print_memory_map(void) + { + int i; diff --git a/target/linux/ramips/patches-3.8/0121-watchdog-adds-ralink-wdt.patch b/target/linux/ramips/patches-3.8/0121-watchdog-adds-ralink-wdt.patch deleted file mode 100644 index 7e2d9adea0..0000000000 --- a/target/linux/ramips/patches-3.8/0121-watchdog-adds-ralink-wdt.patch +++ /dev/null @@ -1,395 +0,0 @@ -From 8dd2c6ae6d9c858d9c4c4d55aa4bf180669ddfe9 Mon Sep 17 00:00:00 2001 -From: John Crispin -Date: Tue, 22 Jan 2013 18:23:50 +0100 -Subject: [PATCH 121/121] watchdog: adds ralink wdt - -Adds the watchdog driver for ralink SoC. - -Signed-off-by: John Crispin ---- - drivers/watchdog/Kconfig | 6 + - drivers/watchdog/Makefile | 1 + - drivers/watchdog/ralink_wdt.c | 352 +++++++++++++++++++++++++++++++++++++++++ - 3 files changed, 359 insertions(+) - create mode 100644 drivers/watchdog/ralink_wdt.c - ---- a/drivers/watchdog/Kconfig -+++ b/drivers/watchdog/Kconfig -@@ -1077,6 +1077,12 @@ config LANTIQ_WDT - help - Hardware driver for the Lantiq SoC Watchdog Timer. - -+config RALINK_WDT -+ tristate "Ralink SoC watchdog" -+ depends on RALINK -+ help -+ Hardware driver for the Ralink SoC Watchdog Timer. -+ - # PARISC Architecture - - # POWERPC Architecture ---- a/drivers/watchdog/Makefile -+++ b/drivers/watchdog/Makefile -@@ -132,6 +132,7 @@ obj-$(CONFIG_TXX9_WDT) += txx9wdt.o - obj-$(CONFIG_OCTEON_WDT) += octeon-wdt.o - octeon-wdt-y := octeon-wdt-main.o octeon-wdt-nmi.o - obj-$(CONFIG_LANTIQ_WDT) += lantiq_wdt.o -+obj-$(CONFIG_RALINK_WDT) += ralink_wdt.o - - # PARISC Architecture - ---- /dev/null -+++ b/drivers/watchdog/ralink_wdt.c -@@ -0,0 +1,352 @@ -+/* -+ * Ralink RT288X/RT305X built-in hardware watchdog timer -+ * -+ * Copyright (C) 2011 Gabor Juhos -+ * -+ * This driver was based on: drivers/watchdog/ixp4xx_wdt.c -+ * Author: Deepak Saxena -+ * Copyright 2004 (c) MontaVista, Software, Inc. -+ * -+ * which again was based on sa1100 driver, -+ * Copyright (C) 2000 Oleg Drokin -+ * -+ * parts of the driver are based on Ralink's 2.6.21 BSP -+ * -+ * This program is free software; you can redistribute it and/or modify it -+ * under the terms of the GNU General Public License version 2 as published -+ * by the Free Software Foundation. -+ */ -+ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+ -+#define DRIVER_NAME "ralink-wdt" -+ -+#define RALINK_WDT_TIMEOUT 30 /* seconds */ -+#define RALINK_WDT_PRESCALE 65536 -+ -+#define TIMER_REG_TMR1LOAD 0x00 -+#define TIMER_REG_TMR1CTL 0x08 -+ -+#define TMRSTAT_TMR1RST BIT(5) -+ -+#define TMR1CTL_ENABLE BIT(7) -+#define TMR1CTL_MODE_SHIFT 4 -+#define TMR1CTL_MODE_MASK 0x3 -+#define TMR1CTL_MODE_FREE_RUNNING 0x0 -+#define TMR1CTL_MODE_PERIODIC 0x1 -+#define TMR1CTL_MODE_TIMEOUT 0x2 -+#define TMR1CTL_MODE_WDT 0x3 -+#define TMR1CTL_PRESCALE_MASK 0xf -+#define TMR1CTL_PRESCALE_65536 0xf -+ -+static int nowayout = WATCHDOG_NOWAYOUT; -+module_param(nowayout, int, 0); -+MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started " -+ "(default=" __MODULE_STRING(WATCHDOG_NOWAYOUT) ")"); -+ -+static int ralink_wdt_timeout = RALINK_WDT_TIMEOUT; -+module_param_named(timeout, ralink_wdt_timeout, int, 0); -+MODULE_PARM_DESC(timeout, "Watchdog timeout in seconds, 0 means use maximum " -+ "(default=" __MODULE_STRING(RALINK_WDT_TIMEOUT) "s)"); -+ -+static unsigned long ralink_wdt_flags; -+ -+#define WDT_FLAGS_BUSY 0 -+#define WDT_FLAGS_EXPECT_CLOSE 1 -+ -+static struct clk *ralink_wdt_clk; -+static unsigned long ralink_wdt_freq; -+static int ralink_wdt_max_timeout; -+static void __iomem *ralink_wdt_base; -+ -+static inline void rt_wdt_w32(unsigned reg, u32 val) -+{ -+ __raw_writel(val, ralink_wdt_base + reg); -+} -+ -+static inline u32 rt_wdt_r32(unsigned reg) -+{ -+ return __raw_readl(ralink_wdt_base + reg); -+} -+ -+static inline void ralink_wdt_keepalive(void) -+{ -+ rt_wdt_w32(TIMER_REG_TMR1LOAD, ralink_wdt_timeout * ralink_wdt_freq); -+} -+ -+static inline void ralink_wdt_enable(void) -+{ -+ u32 t; -+ -+ ralink_wdt_keepalive(); -+ -+ t = rt_wdt_r32(TIMER_REG_TMR1CTL); -+ t |= TMR1CTL_ENABLE; -+ rt_wdt_w32(TIMER_REG_TMR1CTL, t); -+} -+ -+static inline void ralink_wdt_disable(void) -+{ -+ u32 t; -+ -+ ralink_wdt_keepalive(); -+ -+ t = rt_wdt_r32(TIMER_REG_TMR1CTL); -+ t &= ~TMR1CTL_ENABLE; -+ rt_wdt_w32(TIMER_REG_TMR1CTL, t); -+} -+ -+static int ralink_wdt_set_timeout(int val) -+{ -+ if (val < 1 || val > ralink_wdt_max_timeout) { -+ pr_warn(DRIVER_NAME -+ ": timeout value %d must be 0 < timeout <= %d, using %d\n", -+ val, ralink_wdt_max_timeout, ralink_wdt_timeout); -+ return -EINVAL; -+ } -+ -+ ralink_wdt_timeout = val; -+ ralink_wdt_keepalive(); -+ -+ return 0; -+} -+ -+static int ralink_wdt_open(struct inode *inode, struct file *file) -+{ -+ u32 t; -+ -+ if (test_and_set_bit(WDT_FLAGS_BUSY, &ralink_wdt_flags)) -+ return -EBUSY; -+ -+ clear_bit(WDT_FLAGS_EXPECT_CLOSE, &ralink_wdt_flags); -+ -+ t = rt_wdt_r32(TIMER_REG_TMR1CTL); -+ t &= ~(TMR1CTL_MODE_MASK << TMR1CTL_MODE_SHIFT | -+ TMR1CTL_PRESCALE_MASK); -+ t |= (TMR1CTL_MODE_WDT << TMR1CTL_MODE_SHIFT | -+ TMR1CTL_PRESCALE_65536); -+ rt_wdt_w32(TIMER_REG_TMR1CTL, t); -+ -+ ralink_wdt_enable(); -+ -+ return nonseekable_open(inode, file); -+} -+ -+static int ralink_wdt_release(struct inode *inode, struct file *file) -+{ -+ if (test_bit(WDT_FLAGS_EXPECT_CLOSE, &ralink_wdt_flags)) -+ ralink_wdt_disable(); -+ else { -+ pr_crit(DRIVER_NAME ": device closed unexpectedly, " -+ "watchdog timer will not stop!\n"); -+ ralink_wdt_keepalive(); -+ } -+ -+ clear_bit(WDT_FLAGS_BUSY, &ralink_wdt_flags); -+ clear_bit(WDT_FLAGS_EXPECT_CLOSE, &ralink_wdt_flags); -+ -+ return 0; -+} -+ -+static ssize_t rt_wdt_w32ite(struct file *file, const char *data, -+ size_t len, loff_t *ppos) -+{ -+ if (len) { -+ if (!nowayout) { -+ size_t i; -+ -+ clear_bit(WDT_FLAGS_EXPECT_CLOSE, &ralink_wdt_flags); -+ -+ for (i = 0; i != len; i++) { -+ char c; -+ -+ if (get_user(c, data + i)) -+ return -EFAULT; -+ -+ if (c == 'V') -+ set_bit(WDT_FLAGS_EXPECT_CLOSE, -+ &ralink_wdt_flags); -+ } -+ } -+ -+ ralink_wdt_keepalive(); -+ } -+ -+ return len; -+} -+ -+static const struct watchdog_info ralink_wdt_info = { -+ .options = WDIOF_SETTIMEOUT | WDIOF_KEEPALIVEPING | -+ WDIOF_MAGICCLOSE, -+ .firmware_version = 0, -+ .identity = "RALINK watchdog", -+}; -+ -+static long ralink_wdt_ioctl(struct file *file, unsigned int cmd, -+ unsigned long arg) -+{ -+ void __user *argp = (void __user *)arg; -+ int __user *p = argp; -+ int err; -+ int t; -+ -+ switch (cmd) { -+ case WDIOC_GETSUPPORT: -+ err = copy_to_user(argp, &ralink_wdt_info, -+ sizeof(ralink_wdt_info)) ? -EFAULT : 0; -+ break; -+ -+ case WDIOC_GETSTATUS: -+ err = put_user(0, p); -+ break; -+ -+ case WDIOC_KEEPALIVE: -+ ralink_wdt_keepalive(); -+ err = 0; -+ break; -+ -+ case WDIOC_SETTIMEOUT: -+ err = get_user(t, p); -+ if (err) -+ break; -+ -+ err = ralink_wdt_set_timeout(t); -+ if (err) -+ break; -+ -+ /* fallthrough */ -+ case WDIOC_GETTIMEOUT: -+ err = put_user(ralink_wdt_timeout, p); -+ break; -+ -+ default: -+ err = -ENOTTY; -+ break; -+ } -+ -+ return err; -+} -+ -+static const struct file_operations ralink_wdt_fops = { -+ .owner = THIS_MODULE, -+ .llseek = no_llseek, -+ .write = rt_wdt_w32ite, -+ .unlocked_ioctl = ralink_wdt_ioctl, -+ .open = ralink_wdt_open, -+ .release = ralink_wdt_release, -+}; -+ -+static struct miscdevice ralink_wdt_miscdev = { -+ .minor = WATCHDOG_MINOR, -+ .name = "watchdog", -+ .fops = &ralink_wdt_fops, -+}; -+ -+static int ralink_wdt_probe(struct platform_device *pdev) -+{ -+ struct resource *res; -+ int err; -+ -+ res = platform_get_resource(pdev, IORESOURCE_MEM, 0); -+ if (!res) { -+ dev_err(&pdev->dev, "no memory resource found\n"); -+ return -EINVAL; -+ } -+ -+ ralink_wdt_base = ioremap(res->start, resource_size(res)); -+ if (!ralink_wdt_base) -+ return -ENOMEM; -+ -+ ralink_wdt_clk = clk_get(&pdev->dev, NULL); -+ if (IS_ERR(ralink_wdt_clk)) { -+ err = PTR_ERR(ralink_wdt_clk); -+ goto err_unmap; -+ } -+ -+ err = clk_enable(ralink_wdt_clk); -+ if (err) -+ goto err_clk_put; -+ -+ ralink_wdt_freq = clk_get_rate(ralink_wdt_clk) / RALINK_WDT_PRESCALE; -+ if (!ralink_wdt_freq) { -+ err = -EINVAL; -+ goto err_clk_disable; -+ } -+ -+ ralink_wdt_max_timeout = (0xfffful / ralink_wdt_freq); -+ if (ralink_wdt_timeout < 1 || -+ ralink_wdt_timeout > ralink_wdt_max_timeout) { -+ ralink_wdt_timeout = ralink_wdt_max_timeout; -+ dev_info(&pdev->dev, -+ "timeout value must be 0 < timeout <= %d, using %d\n", -+ ralink_wdt_max_timeout, ralink_wdt_timeout); -+ } -+ -+ err = misc_register(&ralink_wdt_miscdev); -+ if (err) { -+ dev_err(&pdev->dev, -+ "unable to register misc device, err=%d\n", err); -+ goto err_clk_disable; -+ } -+ -+ return 0; -+ -+err_clk_disable: -+ clk_disable(ralink_wdt_clk); -+err_clk_put: -+ clk_put(ralink_wdt_clk); -+err_unmap: -+ iounmap(ralink_wdt_base); -+ return err; -+} -+ -+static int ralink_wdt_remove(struct platform_device *pdev) -+{ -+ misc_deregister(&ralink_wdt_miscdev); -+ clk_disable(ralink_wdt_clk); -+ clk_put(ralink_wdt_clk); -+ iounmap(ralink_wdt_base); -+ return 0; -+} -+ -+static void ralink_wdt_shutdown(struct platform_device *pdev) -+{ -+ ralink_wdt_disable(); -+} -+ -+static const struct of_device_id ralink_wdt_match[] = { -+ { .compatible = "ralink,rt2880-wdt" }, -+ {}, -+}; -+MODULE_DEVICE_TABLE(of, ralink_wdt_match); -+ -+static struct platform_driver ralink_wdt_driver = { -+ .probe = ralink_wdt_probe, -+ .remove = ralink_wdt_remove, -+ .shutdown = ralink_wdt_shutdown, -+ .driver = { -+ .name = DRIVER_NAME, -+ .owner = THIS_MODULE, -+ .of_match_table = ralink_wdt_match, -+ }, -+}; -+ -+module_platform_driver(ralink_wdt_driver); -+ -+MODULE_DESCRIPTION("MediaTek/Ralink RT288X/RT305X hardware watchdog driver"); -+MODULE_AUTHOR("Gabor Juhos +Date: Sat, 13 Apr 2013 15:10:14 +0200 +Subject: [PATCH 122/137] MIPS: ralink: add memory definition to struct + ralink_soc_info + +Depending on the actual SoC we have a different base address as well as minimum +and maximum size for RAM. Add these fields to the per SoC structure. + +Signed-off-by: John Crispin +Patchwork: http://patchwork.linux-mips.org/patch/5179/ +--- + arch/mips/ralink/common.h | 5 +++++ + 1 file changed, 5 insertions(+) + +--- a/arch/mips/ralink/common.h ++++ b/arch/mips/ralink/common.h +@@ -33,6 +33,11 @@ extern struct ralink_pinmux rt_gpio_pinm + struct ralink_soc_info { + unsigned char sys_type[RAMIPS_SYS_TYPE_LEN]; + unsigned char *compatible; ++ ++ unsigned long mem_base; ++ unsigned long mem_size; ++ unsigned long mem_size_min; ++ unsigned long mem_size_max; + }; + extern struct ralink_soc_info soc_info; + diff --git a/target/linux/ramips/patches-3.8/0122-MIPS-ralink-handle-PCI-interrupts-as-well.patch b/target/linux/ramips/patches-3.8/0122-MIPS-ralink-handle-PCI-interrupts-as-well.patch deleted file mode 100644 index b898a0a53f..0000000000 --- a/target/linux/ramips/patches-3.8/0122-MIPS-ralink-handle-PCI-interrupts-as-well.patch +++ /dev/null @@ -1,30 +0,0 @@ -From e0fbc01d33265d32fe7f5f34269cb88be2a13c24 Mon Sep 17 00:00:00 2001 -From: Gabor Juhos -Date: Sun, 31 Mar 2013 10:17:26 +0200 -Subject: [PATCH] MIPS: ralink: handle PCI interrupts as well - -Signed-off-by: Gabor Juhos ---- - arch/mips/ralink/irq.c | 4 ++++ - 1 file changed, 4 insertions(+) - ---- a/arch/mips/ralink/irq.c -+++ b/arch/mips/ralink/irq.c -@@ -31,6 +31,7 @@ - #define INTC_INT_GLOBAL BIT(31) - - #define RALINK_CPU_IRQ_INTC (MIPS_CPU_IRQ_BASE + 2) -+#define RALINK_CPU_IRQ_PCI (MIPS_CPU_IRQ_BASE + 4) - #define RALINK_CPU_IRQ_FE (MIPS_CPU_IRQ_BASE + 5) - #define RALINK_CPU_IRQ_WIFI (MIPS_CPU_IRQ_BASE + 6) - #define RALINK_CPU_IRQ_COUNTER (MIPS_CPU_IRQ_BASE + 7) -@@ -104,6 +105,9 @@ asmlinkage void plat_irq_dispatch(void) - else if (pending & STATUSF_IP6) - do_IRQ(RALINK_CPU_IRQ_WIFI); - -+ else if (pending & STATUSF_IP4) -+ do_IRQ(RALINK_CPU_IRQ_PCI); -+ - else if (pending & STATUSF_IP2) - do_IRQ(RALINK_CPU_IRQ_INTC); - diff --git a/target/linux/ramips/patches-3.8/0123-MIPS-ralink-add-memory-definition-for-RT305x.patch b/target/linux/ramips/patches-3.8/0123-MIPS-ralink-add-memory-definition-for-RT305x.patch new file mode 100644 index 0000000000..877e442b62 --- /dev/null +++ b/target/linux/ramips/patches-3.8/0123-MIPS-ralink-add-memory-definition-for-RT305x.patch @@ -0,0 +1,89 @@ +From 016f1f659cf70cc78e72e12a2130d8f3e1a6e0d3 Mon Sep 17 00:00:00 2001 +From: John Crispin +Date: Sat, 13 Apr 2013 15:13:40 +0200 +Subject: [PATCH 123/137] MIPS: ralink: add memory definition for RT305x + +Populate struct soc_info with the data that describes our RAM window. + +As memory detection fails on RT5350 we read the amount of available memory +from the system controller. + +Signed-off-by: John Crispin +Patchwork: http://patchwork.linux-mips.org/patch/5180/ +--- + arch/mips/include/asm/mach-ralink/rt305x.h | 6 ++++ + arch/mips/ralink/rt305x.c | 45 ++++++++++++++++++++++++++++ + 2 files changed, 51 insertions(+) + +--- a/arch/mips/include/asm/mach-ralink/rt305x.h ++++ b/arch/mips/include/asm/mach-ralink/rt305x.h +@@ -157,4 +157,10 @@ static inline int soc_is_rt5350(void) + #define RT3352_RSTCTRL_UDEV BIT(25) + #define RT3352_SYSCFG1_USB0_HOST_MODE BIT(10) + ++#define RT305X_SDRAM_BASE 0x00000000 ++#define RT305X_MEM_SIZE_MIN 2 ++#define RT305X_MEM_SIZE_MAX 64 ++#define RT3352_MEM_SIZE_MIN 2 ++#define RT3352_MEM_SIZE_MAX 256 ++ + #endif +--- a/arch/mips/ralink/rt305x.c ++++ b/arch/mips/ralink/rt305x.c +@@ -122,6 +122,40 @@ struct ralink_pinmux rt_gpio_pinmux = { + .wdt_reset = rt305x_wdt_reset, + }; + ++static unsigned long rt5350_get_mem_size(void) ++{ ++ void __iomem *sysc = (void __iomem *) KSEG1ADDR(RT305X_SYSC_BASE); ++ unsigned long ret; ++ u32 t; ++ ++ t = __raw_readl(sysc + SYSC_REG_SYSTEM_CONFIG); ++ t = (t >> RT5350_SYSCFG0_DRAM_SIZE_SHIFT) & ++ RT5350_SYSCFG0_DRAM_SIZE_MASK; ++ ++ switch (t) { ++ case RT5350_SYSCFG0_DRAM_SIZE_2M: ++ ret = 2; ++ break; ++ case RT5350_SYSCFG0_DRAM_SIZE_8M: ++ ret = 8; ++ break; ++ case RT5350_SYSCFG0_DRAM_SIZE_16M: ++ ret = 16; ++ break; ++ case RT5350_SYSCFG0_DRAM_SIZE_32M: ++ ret = 32; ++ break; ++ case RT5350_SYSCFG0_DRAM_SIZE_64M: ++ ret = 64; ++ break; ++ default: ++ panic("rt5350: invalid DRAM size: %u", t); ++ break; ++ } ++ ++ return ret; ++} ++ + void __init ralink_clk_init(void) + { + unsigned long cpu_rate, sys_rate, wdt_rate, uart_rate; +@@ -252,4 +286,15 @@ void prom_soc_init(struct ralink_soc_inf + name, + (id >> CHIP_ID_ID_SHIFT) & CHIP_ID_ID_MASK, + (id & CHIP_ID_REV_MASK)); ++ ++ soc_info->mem_base = RT305X_SDRAM_BASE; ++ if (soc_is_rt5350()) { ++ soc_info->mem_size = rt5350_get_mem_size(); ++ } else if (soc_is_rt305x() || soc_is_rt3350()) { ++ soc_info->mem_size_min = RT305X_MEM_SIZE_MIN; ++ soc_info->mem_size_max = RT305X_MEM_SIZE_MAX; ++ } else if (soc_is_rt3352()) { ++ soc_info->mem_size_min = RT3352_MEM_SIZE_MIN; ++ soc_info->mem_size_max = RT3352_MEM_SIZE_MAX; ++ } + } diff --git a/target/linux/ramips/patches-3.8/0123-MIPS-ralink-fix-uartmux-group-handling.patch b/target/linux/ramips/patches-3.8/0123-MIPS-ralink-fix-uartmux-group-handling.patch deleted file mode 100644 index dee504fe50..0000000000 --- a/target/linux/ramips/patches-3.8/0123-MIPS-ralink-fix-uartmux-group-handling.patch +++ /dev/null @@ -1,40 +0,0 @@ -From 34a9a634432a95d8ae9af86d41fdaf32fb039c2c Mon Sep 17 00:00:00 2001 -From: Gabor Juhos -Date: Wed, 27 Mar 2013 21:10:14 +0100 -Subject: [PATCH 1/5] MIPS: ralink: fix uartmux group handling - - * don't try get 'ralink,uartmux' porperty if the pinmux.uart is - not initialized, - * don't touch 'mode' value if mux mask is zero - -Signed-off-by: Gabor Juhos ---- - arch/mips/ralink/pinmux.c | 12 ++++++++---- - 1 file changed, 8 insertions(+), 4 deletions(-) - ---- a/arch/mips/ralink/pinmux.c -+++ b/arch/mips/ralink/pinmux.c -@@ -56,15 +56,19 @@ void ralink_pinmux(void) - } - } - -- of_property_read_string(np, "ralink,uartmux", &uart); -+ uart = NULL; -+ if (rt_pinmux.uart) -+ of_property_read_string(np, "ralink,uartmux", &uart); -+ - if (uart) { - int m = ralink_mux_mask(uart, rt_pinmux.uart); -- mode |= rt_pinmux.uart_mask << rt_pinmux.uart_shift; -+ - if (m) { -- mode &= ~(m << rt_pinmux.uart_shift); -+ mode &= ~(rt_pinmux.uart_mask << rt_pinmux.uart_shift); -+ mode |= m << rt_pinmux.uart_shift; - pr_debug("pinmux: registered uartmux \"%s\"\n", uart); - } else { -- pr_debug("pinmux: registered uartmux \"gpio\"\n"); -+ pr_debug("pinmux: unknown uartmux \"%s\"\n", uart); - } - } - diff --git a/target/linux/ramips/patches-3.8/0124-MIPS-ralink-add-memory-definition-for-RT2880.patch b/target/linux/ramips/patches-3.8/0124-MIPS-ralink-add-memory-definition-for-RT2880.patch new file mode 100644 index 0000000000..975fb48a4b --- /dev/null +++ b/target/linux/ramips/patches-3.8/0124-MIPS-ralink-add-memory-definition-for-RT2880.patch @@ -0,0 +1,36 @@ +From 0151f5f0dbf43b6b3718b0d1d403c87429ac0313 Mon Sep 17 00:00:00 2001 +From: John Crispin +Date: Sat, 13 Apr 2013 15:37:37 +0200 +Subject: [PATCH 124/137] MIPS: ralink: add memory definition for RT2880 + +Populate struct soc_info with the data that describes our RAM window. + +Signed-off-by: John Crispin +Patchwork: http://patchwork.linux-mips.org/patch/5181/ +--- + arch/mips/include/asm/mach-ralink/rt288x.h | 4 ++++ + arch/mips/ralink/rt288x.c | 4 ++++ + 2 files changed, 8 insertions(+) + +--- a/arch/mips/include/asm/mach-ralink/rt288x.h ++++ b/arch/mips/include/asm/mach-ralink/rt288x.h +@@ -46,4 +46,8 @@ + + #define CLKCFG_SRAM_CS_N_WDT BIT(9) + ++#define RT2880_SDRAM_BASE 0x08000000 ++#define RT2880_MEM_SIZE_MIN 2 ++#define RT2880_MEM_SIZE_MAX 128 ++ + #endif +--- a/arch/mips/ralink/rt288x.c ++++ b/arch/mips/ralink/rt288x.c +@@ -136,4 +136,8 @@ void prom_soc_init(struct ralink_soc_inf + name, + (id >> CHIP_ID_ID_SHIFT) & CHIP_ID_ID_MASK, + (id & CHIP_ID_REV_MASK)); ++ ++ soc_info->mem_base = RT2880_SDRAM_BASE; ++ soc_info->mem_size_min = RT2880_MEM_SIZE_MIN; ++ soc_info->mem_size_max = RT2880_MEM_SIZE_MAX; + } diff --git a/target/linux/ramips/patches-3.8/0124-MIPS-ralink-add-pci-group-to-struct-ralink_pinmux.patch b/target/linux/ramips/patches-3.8/0124-MIPS-ralink-add-pci-group-to-struct-ralink_pinmux.patch deleted file mode 100644 index 32747e1a19..0000000000 --- a/target/linux/ramips/patches-3.8/0124-MIPS-ralink-add-pci-group-to-struct-ralink_pinmux.patch +++ /dev/null @@ -1,24 +0,0 @@ -From 8818e2d260e7f98fd5388f9ba56f54b788e175f0 Mon Sep 17 00:00:00 2001 -From: Gabor Juhos -Date: Wed, 27 Mar 2013 20:42:18 +0100 -Subject: [PATCH 2/5] MIPS: ralink: add pci group to struct ralink_pinmux - -This will be used for RT3662/RT3883. - -Signed-off-by: Gabor Juhos ---- - arch/mips/ralink/common.h | 3 +++ - 1 file changed, 3 insertions(+) - ---- a/arch/mips/ralink/common.h -+++ b/arch/mips/ralink/common.h -@@ -24,6 +24,9 @@ struct ralink_pinmux { - int uart_shift; - u32 uart_mask; - void (*wdt_reset)(void); -+ struct ralink_pinmux_grp *pci; -+ int pci_shift; -+ u32 pci_mask; - }; - extern struct ralink_pinmux rt_pinmux; - diff --git a/target/linux/ramips/patches-3.8/0125-MIPS-ralink-add-memory-definition-for-RT3883.patch b/target/linux/ramips/patches-3.8/0125-MIPS-ralink-add-memory-definition-for-RT3883.patch new file mode 100644 index 0000000000..f1fa46b331 --- /dev/null +++ b/target/linux/ramips/patches-3.8/0125-MIPS-ralink-add-memory-definition-for-RT3883.patch @@ -0,0 +1,36 @@ +From de85c6c3e2d5ed9c721a282d91af504a845e1fad Mon Sep 17 00:00:00 2001 +From: John Crispin +Date: Sat, 13 Apr 2013 20:23:19 +0200 +Subject: [PATCH 125/137] MIPS: ralink: add memory definition for RT3883 + +Populate struct soc_info with the data that describes our RAM window. + +Signed-off-by: John Crispin +Patchwork: http://patchwork.linux-mips.org/patch/5182/ +--- + arch/mips/include/asm/mach-ralink/rt3883.h | 4 ++++ + arch/mips/ralink/rt3883.c | 4 ++++ + 2 files changed, 8 insertions(+) + +--- a/arch/mips/include/asm/mach-ralink/rt3883.h ++++ b/arch/mips/include/asm/mach-ralink/rt3883.h +@@ -244,4 +244,8 @@ + #define RT3883_FLASH_CFG_WIDTH_16BIT 0x1 + #define RT3883_FLASH_CFG_WIDTH_32BIT 0x2 + ++#define RT3883_SDRAM_BASE 0x00000000 ++#define RT3883_MEM_SIZE_MIN 2 ++#define RT3883_MEM_SIZE_MAX 256 ++ + #endif /* _RT3883_REGS_H_ */ +--- a/arch/mips/ralink/rt3883.c ++++ b/arch/mips/ralink/rt3883.c +@@ -239,4 +239,8 @@ void prom_soc_init(struct ralink_soc_inf + name, + (id >> RT3883_REVID_VER_ID_SHIFT) & RT3883_REVID_VER_ID_MASK, + (id & RT3883_REVID_ECO_ID_MASK)); ++ ++ soc_info->mem_base = RT3883_SDRAM_BASE; ++ soc_info->mem_size_min = RT3883_MEM_SIZE_MIN; ++ soc_info->mem_size_max = RT3883_MEM_SIZE_MAX; + } diff --git a/target/linux/ramips/patches-3.8/0125-MIPS-ralink-process-PCI-pinmux-group.patch b/target/linux/ramips/patches-3.8/0125-MIPS-ralink-process-PCI-pinmux-group.patch deleted file mode 100644 index d5c037e2e3..0000000000 --- a/target/linux/ramips/patches-3.8/0125-MIPS-ralink-process-PCI-pinmux-group.patch +++ /dev/null @@ -1,42 +0,0 @@ -From fe26f3e7d1329fc2a5ac14808dbecb7d324d0a41 Mon Sep 17 00:00:00 2001 -From: Gabor Juhos -Date: Wed, 27 Mar 2013 20:56:22 +0100 -Subject: [PATCH 3/5] MIPS: ralink: process PCI pinmux group - -Signed-off-by: Gabor Juhos ---- - arch/mips/ralink/pinmux.c | 14 +++++++++++++- - 1 file changed, 13 insertions(+), 1 deletion(-) - ---- a/arch/mips/ralink/pinmux.c -+++ b/arch/mips/ralink/pinmux.c -@@ -29,7 +29,7 @@ void ralink_pinmux(void) - const __be32 *wdt; - struct device_node *np; - struct property *prop; -- const char *uart, *pin; -+ const char *uart, *pci, *pin; - u32 mode = 0; - - np = of_find_compatible_node(NULL, NULL, "ralink,rt3050-sysc"); -@@ -76,5 +76,20 @@ void ralink_pinmux(void) - if (wdt && *wdt && rt_pinmux.wdt_reset) - rt_pinmux.wdt_reset(); - -+ pci = NULL; -+ if (rt_pinmux.pci) -+ of_property_read_string(np, "ralink,pcimux", &pci); -+ -+ if (pci) { -+ int m = ralink_mux_mask(pci, rt_pinmux.pci); -+ mode &= ~(rt_pinmux.pci_mask << rt_pinmux.pci_shift); -+ if (m) { -+ mode |= (m << rt_pinmux.pci_shift); -+ pr_debug("pinmux: registered pcimux \"%s\"\n", pci); -+ } else { -+ pr_debug("pinmux: registered pcimux \"gpio\"\n"); -+ } -+ } -+ - rt_sysc_w32(mode, SYSC_REG_GPIO_MODE); - } diff --git a/target/linux/ramips/patches-3.8/0126-MIPS-ralink-add-PCI-pinmux-group-for-RT3883.patch b/target/linux/ramips/patches-3.8/0126-MIPS-ralink-add-PCI-pinmux-group-for-RT3883.patch deleted file mode 100644 index 6f0b1c1aa4..0000000000 --- a/target/linux/ramips/patches-3.8/0126-MIPS-ralink-add-PCI-pinmux-group-for-RT3883.patch +++ /dev/null @@ -1,58 +0,0 @@ -From 2c868d77c161ce7dea8facf203c155924d776c33 Mon Sep 17 00:00:00 2001 -From: Gabor Juhos -Date: Wed, 27 Mar 2013 20:50:40 +0100 -Subject: [PATCH 4/5] MIPS: ralink: add PCI pinmux group for RT3883 - -Signed-off-by: Gabor Juhos ---- - arch/mips/ralink/rt3883.c | 32 ++++++++++++++++++++++++++++++++ - 1 file changed, 32 insertions(+) - ---- a/arch/mips/ralink/rt3883.c -+++ b/arch/mips/ralink/rt3883.c -@@ -113,6 +113,35 @@ struct ralink_pinmux_grp uart_mux[] = { - }, {0} - }; - -+struct ralink_pinmux_grp pci_mux[] = { -+ { -+ .name = "pci-dev", -+ .mask = 0, -+ .gpio_first = RT3883_GPIO_PCI_AD0, -+ .gpio_last = RT3883_GPIO_PCI_AD31, -+ }, { -+ .name = "pci-host2", -+ .mask = 1, -+ .gpio_first = RT3883_GPIO_PCI_AD0, -+ .gpio_last = RT3883_GPIO_PCI_AD31, -+ }, { -+ .name = "pci-host1", -+ .mask = 2, -+ .gpio_first = RT3883_GPIO_PCI_AD0, -+ .gpio_last = RT3883_GPIO_PCI_AD31, -+ }, { -+ .name = "pci-fnc", -+ .mask = 3, -+ .gpio_first = RT3883_GPIO_PCI_AD0, -+ .gpio_last = RT3883_GPIO_PCI_AD31, -+ }, { -+ .name = "pci-gpio", -+ .mask = 7, -+ .gpio_first = RT3883_GPIO_PCI_AD0, -+ .gpio_last = RT3883_GPIO_PCI_AD31, -+ }, {0} -+}; -+ - static void rt3883_wdt_reset(void) - { - u32 t; -@@ -129,6 +158,9 @@ struct ralink_pinmux rt_pinmux = { - .uart_shift = RT3883_GPIO_MODE_UART0_SHIFT, - .uart_mask = RT3883_GPIO_MODE_GPIO, - .wdt_reset = rt3883_wdt_reset, -+ .pci = pci_mux, -+ .pci_shift = RT3883_GPIO_MODE_PCI_SHIFT, -+ .pci_mask = RT3883_GPIO_MODE_PCI_MASK, - }; - - void __init ralink_clk_init(void) diff --git a/target/linux/ramips/patches-3.8/0126-MIPS-ralink-add-memory-definition-for-MT7620.patch b/target/linux/ramips/patches-3.8/0126-MIPS-ralink-add-memory-definition-for-MT7620.patch new file mode 100644 index 0000000000..b36ab33071 --- /dev/null +++ b/target/linux/ramips/patches-3.8/0126-MIPS-ralink-add-memory-definition-for-MT7620.patch @@ -0,0 +1,58 @@ +From c1d35c42d697e9c28c817921a79c5f814529a4c6 Mon Sep 17 00:00:00 2001 +From: John Crispin +Date: Sun, 14 Apr 2013 09:55:29 +0200 +Subject: [PATCH 126/137] MIPS: ralink: add memory definition for MT7620 + +Populate struct soc_info with the data that describes our RAM window. + +Signed-off-by: John Crispin +Patchwork: http://patchwork.linux-mips.org/patch/5183/ +--- + arch/mips/include/asm/mach-ralink/mt7620.h | 8 ++++++++ + arch/mips/ralink/mt7620.c | 20 ++++++++++++++++++++ + 2 files changed, 28 insertions(+) + +--- a/arch/mips/include/asm/mach-ralink/mt7620.h ++++ b/arch/mips/include/asm/mach-ralink/mt7620.h +@@ -50,6 +50,14 @@ + #define SYSCFG0_DRAM_TYPE_DDR1 1 + #define SYSCFG0_DRAM_TYPE_DDR2 2 + ++#define MT7620_DRAM_BASE 0x0 ++#define MT7620_SDRAM_SIZE_MIN 2 ++#define MT7620_SDRAM_SIZE_MAX 64 ++#define MT7620_DDR1_SIZE_MIN 32 ++#define MT7620_DDR1_SIZE_MAX 128 ++#define MT7620_DDR2_SIZE_MIN 32 ++#define MT7620_DDR2_SIZE_MAX 256 ++ + #define MT7620_GPIO_MODE_I2C BIT(0) + #define MT7620_GPIO_MODE_UART0_SHIFT 2 + #define MT7620_GPIO_MODE_UART0_MASK 0x7 +--- a/arch/mips/ralink/mt7620.c ++++ b/arch/mips/ralink/mt7620.c +@@ -211,4 +211,24 @@ void prom_soc_init(struct ralink_soc_inf + + cfg0 = __raw_readl(sysc + SYSC_REG_SYSTEM_CONFIG0); + dram_type = (cfg0 >> SYSCFG0_DRAM_TYPE_SHIFT) & SYSCFG0_DRAM_TYPE_MASK; ++ ++ switch (dram_type) { ++ case SYSCFG0_DRAM_TYPE_SDRAM: ++ soc_info->mem_size_min = MT7620_SDRAM_SIZE_MIN; ++ soc_info->mem_size_max = MT7620_SDRAM_SIZE_MAX; ++ break; ++ ++ case SYSCFG0_DRAM_TYPE_DDR1: ++ soc_info->mem_size_min = MT7620_DDR1_SIZE_MIN; ++ soc_info->mem_size_max = MT7620_DDR1_SIZE_MAX; ++ break; ++ ++ case SYSCFG0_DRAM_TYPE_DDR2: ++ soc_info->mem_size_min = MT7620_DDR2_SIZE_MIN; ++ soc_info->mem_size_max = MT7620_DDR2_SIZE_MAX; ++ break; ++ default: ++ BUG(); ++ } ++ soc_info->mem_base = MT7620_DRAM_BASE; + } diff --git a/target/linux/ramips/patches-3.8/0127-MIPS-ralink-add-GPIO-mode-to-RT3883-UART-pinmux-grou.patch b/target/linux/ramips/patches-3.8/0127-MIPS-ralink-add-GPIO-mode-to-RT3883-UART-pinmux-grou.patch deleted file mode 100644 index 7b2f48b390..0000000000 --- a/target/linux/ramips/patches-3.8/0127-MIPS-ralink-add-GPIO-mode-to-RT3883-UART-pinmux-grou.patch +++ /dev/null @@ -1,24 +0,0 @@ -From 79a01992e15216544dcfdc0be9f2f7695952d047 Mon Sep 17 00:00:00 2001 -From: Gabor Juhos -Date: Wed, 27 Mar 2013 20:59:26 +0100 -Subject: [PATCH 5/5] MIPS: ralink: add GPIO mode to RT3883 UART pinmux group - -Signed-off-by: Gabor Juhos ---- - arch/mips/ralink/rt3883.c | 5 +++++ - 1 file changed, 5 insertions(+) - ---- a/arch/mips/ralink/rt3883.c -+++ b/arch/mips/ralink/rt3883.c -@@ -110,6 +110,11 @@ struct ralink_pinmux_grp uart_mux[] = { - .mask = RT3883_GPIO_MODE_GPIO_I2S, - .gpio_first = RT3883_GPIO_7, - .gpio_last = RT3883_GPIO_14, -+ }, { -+ .name = "gpio", -+ .mask = RT3883_GPIO_MODE_GPIO, -+ .gpio_first = RT3883_GPIO_7, -+ .gpio_last = RT3883_GPIO_14, - }, {0} - }; - diff --git a/target/linux/ramips/patches-3.8/0127-MIPS-ralink-make-use-of-the-new-memory-detection-cod.patch b/target/linux/ramips/patches-3.8/0127-MIPS-ralink-make-use-of-the-new-memory-detection-cod.patch new file mode 100644 index 0000000000..59bdaddbe5 --- /dev/null +++ b/target/linux/ramips/patches-3.8/0127-MIPS-ralink-make-use-of-the-new-memory-detection-cod.patch @@ -0,0 +1,40 @@ +From 1618a00f709817cbcdebf038d0b5e251c8d67237 Mon Sep 17 00:00:00 2001 +From: John Crispin +Date: Sat, 13 Apr 2013 15:15:51 +0200 +Subject: [PATCH 127/137] MIPS: ralink: make use of the new memory detection + code + +Call detect_memory_region() from plat_mem_setup() unless the size was already +read from the system controller. + +Signed-off-by: John Crispin +Patchwork: http://patchwork.linux-mips.org/patch/5184/ +--- + arch/mips/ralink/of.c | 9 +++++++++ + 1 file changed, 9 insertions(+) + +--- a/arch/mips/ralink/of.c ++++ b/arch/mips/ralink/of.c +@@ -11,6 +11,7 @@ + #include + #include + #include ++#include + #include + #include + #include +@@ -85,6 +86,14 @@ void __init plat_mem_setup(void) + * parsed resulting in our memory appearing + */ + __dt_setup_arch(&__dtb_start); ++ ++ if (soc_info.mem_size) ++ add_memory_region(soc_info.mem_base, soc_info.mem_size, ++ BOOT_MEM_RAM); ++ else ++ detect_memory_region(soc_info.mem_base, ++ soc_info.mem_size_min * SZ_1M, ++ soc_info.mem_size_max * SZ_1M); + } + + static int __init plat_of_setup(void) diff --git a/target/linux/ramips/patches-3.8/0128-MIPS-ralink-add-cpu-feature-overrides.h-for-RT288x-S.patch b/target/linux/ramips/patches-3.8/0128-MIPS-ralink-add-cpu-feature-overrides.h-for-RT288x-S.patch deleted file mode 100644 index f9ed59bacd..0000000000 --- a/target/linux/ramips/patches-3.8/0128-MIPS-ralink-add-cpu-feature-overrides.h-for-RT288x-S.patch +++ /dev/null @@ -1,82 +0,0 @@ -From 9830273b0c7f2e58a9226cc38bb0c4363e1fd8a2 Mon Sep 17 00:00:00 2001 -From: Gabor Juhos -Date: Sun, 7 Apr 2013 17:00:40 +0200 -Subject: [PATCH 1/3] MIPS: ralink: add cpu-feature-overrides.h for RT288x - SoCs - -Signed-off-by: Gabor Juhos ---- - .../asm/mach-ralink/rt288x/cpu-feature-overrides.h | 56 ++++++++++++++++++++ - arch/mips/ralink/Platform | 1 + - 2 files changed, 57 insertions(+) - create mode 100644 arch/mips/include/asm/mach-ralink/rt288x/cpu-feature-overrides.h - ---- /dev/null -+++ b/arch/mips/include/asm/mach-ralink/rt288x/cpu-feature-overrides.h -@@ -0,0 +1,56 @@ -+/* -+ * Ralink RT288x specific CPU feature overrides -+ * -+ * Copyright (C) 2008-2009 Gabor Juhos -+ * Copyright (C) 2008 Imre Kaloz -+ * -+ * This file was derived from: include/asm-mips/cpu-features.h -+ * Copyright (C) 2003, 2004 Ralf Baechle -+ * Copyright (C) 2004 Maciej W. Rozycki -+ * -+ * This program is free software; you can redistribute it and/or modify it -+ * under the terms of the GNU General Public License version 2 as published -+ * by the Free Software Foundation. -+ * -+ */ -+#ifndef _RT288X_CPU_FEATURE_OVERRIDES_H -+#define _RT288X_CPU_FEATURE_OVERRIDES_H -+ -+#define cpu_has_tlb 1 -+#define cpu_has_4kex 1 -+#define cpu_has_3k_cache 0 -+#define cpu_has_4k_cache 1 -+#define cpu_has_tx39_cache 0 -+#define cpu_has_sb1_cache 0 -+#define cpu_has_fpu 0 -+#define cpu_has_32fpr 0 -+#define cpu_has_counter 1 -+#define cpu_has_watch 1 -+#define cpu_has_divec 1 -+ -+#define cpu_has_prefetch 1 -+#define cpu_has_ejtag 1 -+#define cpu_has_llsc 1 -+ -+#define cpu_has_mips16 1 -+#define cpu_has_mdmx 0 -+#define cpu_has_mips3d 0 -+#define cpu_has_smartmips 0 -+ -+#define cpu_has_mips32r1 1 -+#define cpu_has_mips32r2 1 -+#define cpu_has_mips64r1 0 -+#define cpu_has_mips64r2 0 -+ -+#define cpu_has_dsp 0 -+#define cpu_has_mipsmt 0 -+ -+#define cpu_has_64bits 0 -+#define cpu_has_64bit_zero_reg 0 -+#define cpu_has_64bit_gp_regs 0 -+#define cpu_has_64bit_addresses 0 -+ -+#define cpu_dcache_line_size() 16 -+#define cpu_icache_line_size() 16 -+ -+#endif /* _RT288X_CPU_FEATURE_OVERRIDES_H */ ---- a/arch/mips/ralink/Platform -+++ b/arch/mips/ralink/Platform -@@ -8,6 +8,7 @@ cflags-$(CONFIG_RALINK) += -I$(srctree) - # Ralink RT288x - # - load-$(CONFIG_SOC_RT288X) += 0xffffffff88000000 -+cflags-$(CONFIG_SOC_RT288X) += -I$(srctree)/arch/mips/include/asm/mach-ralink/rt288x - - # - # Ralink RT305x diff --git a/target/linux/ramips/patches-3.8/0128-MIPS-ralink-add-pinmux-driver.patch b/target/linux/ramips/patches-3.8/0128-MIPS-ralink-add-pinmux-driver.patch new file mode 100644 index 0000000000..bf84dd9ebe --- /dev/null +++ b/target/linux/ramips/patches-3.8/0128-MIPS-ralink-add-pinmux-driver.patch @@ -0,0 +1,128 @@ +From 5a2079532dfaf5762f658370ee7a0afb686f066e Mon Sep 17 00:00:00 2001 +From: John Crispin +Date: Mon, 22 Apr 2013 23:11:42 +0200 +Subject: [PATCH 128/137] MIPS: ralink: add pinmux driver + +Add code to setup the pinmux on ralonk SoC. The SoC has a single 32 bit register +for this functionality with simple on/off bits. Building a full featured pinctrl +driver would be overkill. + +Signed-off-by: John Crispin +--- + arch/mips/ralink/Makefile | 2 +- + arch/mips/ralink/common.h | 2 ++ + arch/mips/ralink/of.c | 2 ++ + arch/mips/ralink/pinmux.c | 76 +++++++++++++++++++++++++++++++++++++++++++++ + 4 files changed, 81 insertions(+), 1 deletion(-) + create mode 100644 arch/mips/ralink/pinmux.c + +--- a/arch/mips/ralink/Makefile ++++ b/arch/mips/ralink/Makefile +@@ -6,7 +6,7 @@ + # Copyright (C) 2009-2011 Gabor Juhos + # Copyright (C) 2013 John Crispin + +-obj-y := prom.o of.o reset.o clk.o irq.o ++obj-y := prom.o of.o reset.o clk.o irq.o pinmux.o + + obj-$(CONFIG_SOC_RT288X) += rt288x.o + obj-$(CONFIG_SOC_RT305X) += rt305x.o +--- a/arch/mips/ralink/common.h ++++ b/arch/mips/ralink/common.h +@@ -50,4 +50,6 @@ extern void prom_soc_init(struct ralink_ + + __iomem void *plat_of_remap_node(const char *node); + ++void ralink_pinmux(void); ++ + #endif /* _RALINK_COMMON_H__ */ +--- a/arch/mips/ralink/of.c ++++ b/arch/mips/ralink/of.c +@@ -110,6 +110,8 @@ static int __init plat_of_setup(void) + if (of_platform_populate(NULL, of_ids, NULL, NULL)) + panic("failed to populate DT\n"); + ++ ralink_pinmux(); ++ + return 0; + } + +--- /dev/null ++++ b/arch/mips/ralink/pinmux.c +@@ -0,0 +1,76 @@ ++/* ++ * This program is free software; you can redistribute it and/or modify it ++ * under the terms of the GNU General Public License version 2 as published ++ * by the Free Software Foundation. ++ * ++ * Copyright (C) 2013 John Crispin ++ */ ++ ++#include ++#include ++ ++#include ++ ++#include "common.h" ++ ++#define SYSC_REG_GPIO_MODE 0x60 ++ ++static u32 ralink_mux_mask(const char *name, struct ralink_pinmux_grp *grps) ++{ ++ for (; grps->name; grps++) ++ if (!strcmp(grps->name, name)) ++ return grps->mask; ++ ++ return 0; ++} ++ ++void ralink_pinmux(void) ++{ ++ const __be32 *wdt; ++ struct device_node *np; ++ struct property *prop; ++ const char *uart, *pin; ++ u32 mode = 0; ++ ++ np = of_find_compatible_node(NULL, NULL, "ralink,rt3050-sysc"); ++ if (!np) ++ return; ++ ++ of_property_for_each_string(np, "ralink,gpiomux", prop, pin) { ++ int m = ralink_mux_mask(pin, rt_gpio_pinmux.mode); ++ if (m) { ++ mode |= m; ++ pr_debug("pinmux: registered gpiomux \"%s\"\n", pin); ++ } else { ++ pr_err("pinmux: failed to load \"%s\"\n", pin); ++ } ++ } ++ ++ of_property_for_each_string(np, "ralink,pinmux", prop, pin) { ++ int m = ralink_mux_mask(pin, rt_gpio_pinmux.mode); ++ if (m) { ++ mode &= ~m; ++ pr_debug("pinmux: registered pinmux \"%s\"\n", pin); ++ } else { ++ pr_err("pinmux: failed to load group \"%s\"\n", pin); ++ } ++ } ++ ++ of_property_read_string(np, "ralink,uartmux", &uart); ++ if (uart) { ++ int m = ralink_mux_mask(uart, rt_gpio_pinmux.uart); ++ mode |= rt_gpio_pinmux.uart_mask << rt_gpio_pinmux.uart_shift; ++ if (m) { ++ mode &= ~(m << rt_gpio_pinmux.uart_shift); ++ pr_debug("pinmux: registered uartmux \"%s\"\n", uart); ++ } else { ++ pr_debug("pinmux: registered uartmux \"gpio\"\n"); ++ } ++ } ++ ++ wdt = of_get_property(np, "ralink,wdtmux", NULL); ++ if (wdt && *wdt && rt_gpio_pinmux.wdt_reset) ++ rt_gpio_pinmux.wdt_reset(); ++ ++ rt_sysc_w32(mode, SYSC_REG_GPIO_MODE); ++} diff --git a/target/linux/ramips/patches-3.8/0129-MIPS-ralink-add-cpu-feature-overrides.h-for-RT3x5x-R.patch b/target/linux/ramips/patches-3.8/0129-MIPS-ralink-add-cpu-feature-overrides.h-for-RT3x5x-R.patch deleted file mode 100644 index 52f73203de..0000000000 --- a/target/linux/ramips/patches-3.8/0129-MIPS-ralink-add-cpu-feature-overrides.h-for-RT3x5x-R.patch +++ /dev/null @@ -1,82 +0,0 @@ -From 0eccf6e501337213d1de75dcf8f158d194ae0f77 Mon Sep 17 00:00:00 2001 -From: Gabor Juhos -Date: Sun, 7 Apr 2013 17:02:27 +0200 -Subject: [PATCH 2/3] MIPS: ralink: add cpu-feature-overrides.h for - RT3x5x/RT5350 SoCs - -Signed-off-by: Gabor Juhos ---- - .../asm/mach-ralink/rt305x/cpu-feature-overrides.h | 56 ++++++++++++++++++++ - arch/mips/ralink/Platform | 1 + - 2 files changed, 57 insertions(+) - create mode 100644 arch/mips/include/asm/mach-ralink/rt305x/cpu-feature-overrides.h - ---- /dev/null -+++ b/arch/mips/include/asm/mach-ralink/rt305x/cpu-feature-overrides.h -@@ -0,0 +1,56 @@ -+/* -+ * Ralink RT305x specific CPU feature overrides -+ * -+ * Copyright (C) 2008-2009 Gabor Juhos -+ * Copyright (C) 2008 Imre Kaloz -+ * -+ * This file was derived from: include/asm-mips/cpu-features.h -+ * Copyright (C) 2003, 2004 Ralf Baechle -+ * Copyright (C) 2004 Maciej W. Rozycki -+ * -+ * This program is free software; you can redistribute it and/or modify it -+ * under the terms of the GNU General Public License version 2 as published -+ * by the Free Software Foundation. -+ * -+ */ -+#ifndef _RT305X_CPU_FEATURE_OVERRIDES_H -+#define _RT305X_CPU_FEATURE_OVERRIDES_H -+ -+#define cpu_has_tlb 1 -+#define cpu_has_4kex 1 -+#define cpu_has_3k_cache 0 -+#define cpu_has_4k_cache 1 -+#define cpu_has_tx39_cache 0 -+#define cpu_has_sb1_cache 0 -+#define cpu_has_fpu 0 -+#define cpu_has_32fpr 0 -+#define cpu_has_counter 1 -+#define cpu_has_watch 1 -+#define cpu_has_divec 1 -+ -+#define cpu_has_prefetch 1 -+#define cpu_has_ejtag 1 -+#define cpu_has_llsc 1 -+ -+#define cpu_has_mips16 1 -+#define cpu_has_mdmx 0 -+#define cpu_has_mips3d 0 -+#define cpu_has_smartmips 0 -+ -+#define cpu_has_mips32r1 1 -+#define cpu_has_mips32r2 1 -+#define cpu_has_mips64r1 0 -+#define cpu_has_mips64r2 0 -+ -+#define cpu_has_dsp 1 -+#define cpu_has_mipsmt 0 -+ -+#define cpu_has_64bits 0 -+#define cpu_has_64bit_zero_reg 0 -+#define cpu_has_64bit_gp_regs 0 -+#define cpu_has_64bit_addresses 0 -+ -+#define cpu_dcache_line_size() 32 -+#define cpu_icache_line_size() 32 -+ -+#endif /* _RT305X_CPU_FEATURE_OVERRIDES_H */ ---- a/arch/mips/ralink/Platform -+++ b/arch/mips/ralink/Platform -@@ -14,6 +14,7 @@ cflags-$(CONFIG_SOC_RT288X) += -I$(srctr - # Ralink RT305x - # - load-$(CONFIG_SOC_RT305X) += 0xffffffff80000000 -+cflags-$(CONFIG_SOC_RT305X) += -I$(srctree)/arch/mips/include/asm/mach-ralink/rt305x - - # - # Ralink RT3883 diff --git a/target/linux/ramips/patches-3.8/0129-MIPS-ralink-add-support-for-periodic-timer-irq.patch b/target/linux/ramips/patches-3.8/0129-MIPS-ralink-add-support-for-periodic-timer-irq.patch new file mode 100644 index 0000000000..6664e11e45 --- /dev/null +++ b/target/linux/ramips/patches-3.8/0129-MIPS-ralink-add-support-for-periodic-timer-irq.patch @@ -0,0 +1,220 @@ +From 1f307fd0fdca585d5c7c32963e8a8a6f38d8a78c Mon Sep 17 00:00:00 2001 +From: John Crispin +Date: Sat, 23 Mar 2013 19:44:41 +0100 +Subject: [PATCH 129/137] MIPS: ralink: add support for periodic timer irq + +Adds a driver for the periodic timer found on Ralink SoC. + +Signed-off-by: John Crispin +--- + arch/mips/ralink/Makefile | 2 +- + arch/mips/ralink/timer.c | 192 +++++++++++++++++++++++++++++++++++++++++++++ + 2 files changed, 193 insertions(+), 1 deletion(-) + create mode 100644 arch/mips/ralink/timer.c + +--- a/arch/mips/ralink/Makefile ++++ b/arch/mips/ralink/Makefile +@@ -6,7 +6,7 @@ + # Copyright (C) 2009-2011 Gabor Juhos + # Copyright (C) 2013 John Crispin + +-obj-y := prom.o of.o reset.o clk.o irq.o pinmux.o ++obj-y := prom.o of.o reset.o clk.o irq.o pinmux.o timer.o + + obj-$(CONFIG_SOC_RT288X) += rt288x.o + obj-$(CONFIG_SOC_RT305X) += rt305x.o +--- /dev/null ++++ b/arch/mips/ralink/timer.c +@@ -0,0 +1,192 @@ ++/* ++ * This program is free software; you can redistribute it and/or modify it ++ * under the terms of the GNU General Public License version 2 as published ++ * by the Free Software Foundation. ++ * ++ * Copyright (C) 2013 John Crispin ++*/ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#include ++ ++#define TIMER_REG_TMRSTAT 0x00 ++#define TIMER_REG_TMR0LOAD 0x10 ++#define TIMER_REG_TMR0CTL 0x18 ++ ++#define TMRSTAT_TMR0INT BIT(0) ++ ++#define TMR0CTL_ENABLE BIT(7) ++#define TMR0CTL_MODE_PERIODIC BIT(4) ++#define TMR0CTL_PRESCALER 1 ++#define TMR0CTL_PRESCALE_VAL (0xf - TMR0CTL_PRESCALER) ++#define TMR0CTL_PRESCALE_DIV (65536 / BIT(TMR0CTL_PRESCALER)) ++ ++struct rt_timer { ++ struct device *dev; ++ void __iomem *membase; ++ int irq; ++ unsigned long timer_freq; ++ unsigned long timer_div; ++}; ++ ++static inline void rt_timer_w32(struct rt_timer *rt, u8 reg, u32 val) ++{ ++ __raw_writel(val, rt->membase + reg); ++} ++ ++static inline u32 rt_timer_r32(struct rt_timer *rt, u8 reg) ++{ ++ return __raw_readl(rt->membase + reg); ++} ++ ++static irqreturn_t rt_timer_irq(int irq, void *_rt) ++{ ++ struct rt_timer *rt = (struct rt_timer *) _rt; ++ ++ rt_timer_w32(rt, TIMER_REG_TMR0LOAD, rt->timer_freq / rt->timer_div); ++ rt_timer_w32(rt, TIMER_REG_TMRSTAT, TMRSTAT_TMR0INT); ++ ++ return IRQ_HANDLED; ++} ++ ++ ++static int rt_timer_request(struct rt_timer *rt) ++{ ++ int err = request_irq(rt->irq, rt_timer_irq, IRQF_DISABLED, ++ dev_name(rt->dev), rt); ++ if (err) { ++ dev_err(rt->dev, "failed to request irq\n"); ++ } else { ++ u32 t = TMR0CTL_MODE_PERIODIC | TMR0CTL_PRESCALE_VAL; ++ rt_timer_w32(rt, TIMER_REG_TMR0CTL, t); ++ } ++ return err; ++} ++ ++static void rt_timer_free(struct rt_timer *rt) ++{ ++ free_irq(rt->irq, rt); ++} ++ ++static int rt_timer_config(struct rt_timer *rt, unsigned long divisor) ++{ ++ if (rt->timer_freq < divisor) ++ rt->timer_div = rt->timer_freq; ++ else ++ rt->timer_div = divisor; ++ ++ rt_timer_w32(rt, TIMER_REG_TMR0LOAD, rt->timer_freq / rt->timer_div); ++ ++ return 0; ++} ++ ++static int rt_timer_enable(struct rt_timer *rt) ++{ ++ u32 t; ++ ++ rt_timer_w32(rt, TIMER_REG_TMR0LOAD, rt->timer_freq / rt->timer_div); ++ ++ t = rt_timer_r32(rt, TIMER_REG_TMR0CTL); ++ t |= TMR0CTL_ENABLE; ++ rt_timer_w32(rt, TIMER_REG_TMR0CTL, t); ++ ++ return 0; ++} ++ ++static void rt_timer_disable(struct rt_timer *rt) ++{ ++ u32 t; ++ ++ t = rt_timer_r32(rt, TIMER_REG_TMR0CTL); ++ t &= ~TMR0CTL_ENABLE; ++ rt_timer_w32(rt, TIMER_REG_TMR0CTL, t); ++} ++ ++static int rt_timer_probe(struct platform_device *pdev) ++{ ++ struct resource *res = platform_get_resource(pdev, IORESOURCE_MEM, 0); ++ struct rt_timer *rt; ++ struct clk *clk; ++ ++ if (!res) { ++ dev_err(&pdev->dev, "no memory resource found\n"); ++ return -EINVAL; ++ } ++ ++ rt = devm_kzalloc(&pdev->dev, sizeof(*rt), GFP_KERNEL); ++ if (!rt) { ++ dev_err(&pdev->dev, "failed to allocate memory\n"); ++ return -ENOMEM; ++ } ++ ++ rt->irq = platform_get_irq(pdev, 0); ++ if (!rt->irq) { ++ dev_err(&pdev->dev, "failed to load irq\n"); ++ return -ENOENT; ++ } ++ ++ rt->membase = devm_request_and_ioremap(&pdev->dev, res); ++ if (!rt->membase) { ++ dev_err(&pdev->dev, "failed to ioremap\n"); ++ return -ENOMEM; ++ } ++ ++ clk = devm_clk_get(&pdev->dev, NULL); ++ if (IS_ERR(clk)) { ++ dev_err(&pdev->dev, "failed get clock rate\n"); ++ return PTR_ERR(clk); ++ } ++ ++ rt->timer_freq = clk_get_rate(clk) / TMR0CTL_PRESCALE_DIV; ++ if (!rt->timer_freq) ++ return -EINVAL; ++ ++ rt->dev = &pdev->dev; ++ platform_set_drvdata(pdev, rt); ++ ++ rt_timer_request(rt); ++ rt_timer_config(rt, 2); ++ rt_timer_enable(rt); ++ ++ dev_info(&pdev->dev, "maximum frequncy is %luHz\n", rt->timer_freq); ++ ++ return 0; ++} ++ ++static int rt_timer_remove(struct platform_device *pdev) ++{ ++ struct rt_timer *rt = platform_get_drvdata(pdev); ++ ++ rt_timer_disable(rt); ++ rt_timer_free(rt); ++ ++ return 0; ++} ++ ++static const struct of_device_id rt_timer_match[] = { ++ { .compatible = "ralink,rt2880-timer" }, ++ {}, ++}; ++MODULE_DEVICE_TABLE(of, rt_timer_match); ++ ++static struct platform_driver rt_timer_driver = { ++ .probe = rt_timer_probe, ++ .remove = rt_timer_remove, ++ .driver = { ++ .name = "rt-timer", ++ .owner = THIS_MODULE, ++ .of_match_table = rt_timer_match ++ }, ++}; ++ ++module_platform_driver(rt_timer_driver); ++ ++MODULE_DESCRIPTION("Ralink RT2880 timer"); ++MODULE_AUTHOR("John Crispin +Date: Tue, 22 Jan 2013 18:24:34 +0100 +Subject: [PATCH 130/137] GPIO: MIPS: ralink: adds ralink gpio support + +Add gpio driver for Ralink SoC. This driver makes the gpio core on +RT2880, RT305x, rt3352, rt3662, rt3883, rt5350 and mt7620 work. + +Signed-off-by: John Crispin +--- + arch/mips/Kconfig | 1 + + arch/mips/include/asm/mach-ralink/gpio.h | 24 ++++ + drivers/gpio/Kconfig | 6 + + drivers/gpio/Makefile | 1 + + drivers/gpio/gpio-ralink.c | 176 ++++++++++++++++++++++++++++++ + 5 files changed, 208 insertions(+) + create mode 100644 arch/mips/include/asm/mach-ralink/gpio.h + create mode 100644 drivers/gpio/gpio-ralink.c + +--- a/arch/mips/Kconfig ++++ b/arch/mips/Kconfig +@@ -449,6 +449,7 @@ config RALINK + select SYS_HAS_EARLY_PRINTK + select HAVE_MACH_CLKDEV + select CLKDEV_LOOKUP ++ select ARCH_REQUIRE_GPIOLIB + + config SGI_IP22 + bool "SGI IP22 (Indy/Indigo2)" +--- /dev/null ++++ b/arch/mips/include/asm/mach-ralink/gpio.h +@@ -0,0 +1,24 @@ ++/* ++ * Ralink SoC GPIO API support ++ * ++ * Copyright (C) 2008-2009 Gabor Juhos ++ * Copyright (C) 2008 Imre Kaloz ++ * ++ * This program is free software; you can redistribute it and/or modify it ++ * under the terms of the GNU General Public License version 2 as published ++ * by the Free Software Foundation. ++ * ++ */ ++ ++#ifndef __ASM_MACH_RALINK_GPIO_H ++#define __ASM_MACH_RALINK_GPIO_H ++ ++#define ARCH_NR_GPIOS 128 ++#include ++ ++#define gpio_get_value __gpio_get_value ++#define gpio_set_value __gpio_set_value ++#define gpio_cansleep __gpio_cansleep ++#define gpio_to_irq __gpio_to_irq ++ ++#endif /* __ASM_MACH_RALINK_GPIO_H */ +--- a/drivers/gpio/Kconfig ++++ b/drivers/gpio/Kconfig +@@ -201,6 +201,12 @@ config GPIO_PXA + help + Say yes here to support the PXA GPIO device + ++config GPIO_RALINK ++ bool "Ralink GPIO Support" ++ depends on RALINK ++ help ++ Say yes here to support the Ralink SoC GPIO device ++ + config GPIO_SPEAR_SPICS + bool "ST SPEAr13xx SPI Chip Select as GPIO support" + depends on PLAT_SPEAR +--- a/drivers/gpio/Makefile ++++ b/drivers/gpio/Makefile +@@ -54,6 +54,7 @@ obj-$(CONFIG_GPIO_PCF857X) += gpio-pcf85 + obj-$(CONFIG_GPIO_PCH) += gpio-pch.o + obj-$(CONFIG_GPIO_PL061) += gpio-pl061.o + obj-$(CONFIG_GPIO_PXA) += gpio-pxa.o ++obj-$(CONFIG_GPIO_RALINK) += gpio-ralink.o + obj-$(CONFIG_GPIO_RC5T583) += gpio-rc5t583.o + obj-$(CONFIG_GPIO_RDC321X) += gpio-rdc321x.o + obj-$(CONFIG_PLAT_SAMSUNG) += gpio-samsung.o +--- /dev/null ++++ b/drivers/gpio/gpio-ralink.c +@@ -0,0 +1,176 @@ ++/* ++ * 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 ++ * Copyright (C) 2013 John Crispin ++ */ ++ ++#include ++#include ++#include ++#include ++#include ++ ++enum ralink_gpio_reg { ++ GPIO_REG_INT = 0, ++ GPIO_REG_EDGE, ++ GPIO_REG_RENA, ++ GPIO_REG_FENA, ++ GPIO_REG_DATA, ++ GPIO_REG_DIR, ++ GPIO_REG_POL, ++ GPIO_REG_SET, ++ GPIO_REG_RESET, ++ GPIO_REG_TOGGLE, ++ GPIO_REG_MAX ++}; ++ ++struct ralink_gpio_chip { ++ struct gpio_chip chip; ++ u8 regs[GPIO_REG_MAX]; ++ ++ spinlock_t lock; ++ void __iomem *membase; ++}; ++ ++static inline struct ralink_gpio_chip *to_ralink_gpio(struct gpio_chip *chip) ++{ ++ struct ralink_gpio_chip *rg; ++ ++ rg = container_of(chip, struct ralink_gpio_chip, chip); ++ return rg; ++} ++ ++static inline void rt_gpio_w32(struct ralink_gpio_chip *rg, u8 reg, u32 val) ++{ ++ iowrite32(val, rg->membase + rg->regs[reg]); ++} ++ ++static inline u32 rt_gpio_r32(struct ralink_gpio_chip *rg, u8 reg) ++{ ++ return ioread32(rg->membase + rg->regs[reg]); ++} ++ ++static void ralink_gpio_set(struct gpio_chip *chip, unsigned offset, int value) ++{ ++ struct ralink_gpio_chip *rg = to_ralink_gpio(chip); ++ ++ rt_gpio_w32(rg, (value) ? GPIO_REG_SET : GPIO_REG_RESET, BIT(offset)); ++} ++ ++static int ralink_gpio_get(struct gpio_chip *chip, unsigned offset) ++{ ++ struct ralink_gpio_chip *rg = to_ralink_gpio(chip); ++ ++ return !!(rt_gpio_r32(rg, GPIO_REG_DATA) & BIT(offset)); ++} ++ ++static int ralink_gpio_direction_input(struct gpio_chip *chip, unsigned offset) ++{ ++ struct ralink_gpio_chip *rg = to_ralink_gpio(chip); ++ unsigned long flags; ++ u32 t; ++ ++ spin_lock_irqsave(&rg->lock, flags); ++ t = rt_gpio_r32(rg, GPIO_REG_DIR); ++ t &= ~BIT(offset); ++ rt_gpio_w32(rg, GPIO_REG_DIR, t); ++ spin_unlock_irqrestore(&rg->lock, flags); ++ ++ return 0; ++} ++ ++static int ralink_gpio_direction_output(struct gpio_chip *chip, ++ unsigned offset, int value) ++{ ++ struct ralink_gpio_chip *rg = to_ralink_gpio(chip); ++ unsigned long flags; ++ u32 t; ++ ++ spin_lock_irqsave(&rg->lock, flags); ++ ralink_gpio_set(chip, offset, value); ++ t = rt_gpio_r32(rg, GPIO_REG_DIR); ++ t |= BIT(offset); ++ rt_gpio_w32(rg, GPIO_REG_DIR, t); ++ spin_unlock_irqrestore(&rg->lock, flags); ++ ++ return 0; ++} ++ ++static int ralink_gpio_probe(struct platform_device *pdev) ++{ ++ struct device_node *np = pdev->dev.of_node; ++ struct resource *res = platform_get_resource(pdev, IORESOURCE_MEM, 0); ++ struct ralink_gpio_chip *gc; ++ const __be32 *ngpio; ++ ++ if (!res) { ++ dev_err(&pdev->dev, "failed to find resource\n"); ++ return -ENOMEM; ++ } ++ ++ gc = devm_kzalloc(&pdev->dev, ++ sizeof(struct ralink_gpio_chip), GFP_KERNEL); ++ if (!gc) ++ return -ENOMEM; ++ ++ gc->membase = devm_request_and_ioremap(&pdev->dev, res); ++ if (!gc->membase) { ++ dev_err(&pdev->dev, "cannot remap I/O memory region\n"); ++ return -ENOMEM; ++ } ++ ++ if (of_property_read_u8_array(np, "ralink,register-map", ++ gc->regs, GPIO_REG_MAX)) { ++ dev_err(&pdev->dev, "failed to read register definition\n"); ++ return -EINVAL; ++ } ++ ++ ngpio = of_get_property(np, "ralink,num-gpios", NULL); ++ if (!ngpio) { ++ dev_err(&pdev->dev, "failed to read number of pins\n"); ++ return -EINVAL; ++ } ++ ++ spin_lock_init(&gc->lock); ++ ++ gc->chip.label = dev_name(&pdev->dev); ++ gc->chip.of_node = np; ++ gc->chip.base = -1; ++ gc->chip.ngpio = be32_to_cpu(*ngpio); ++ gc->chip.direction_input = ralink_gpio_direction_input; ++ gc->chip.direction_output = ralink_gpio_direction_output; ++ gc->chip.get = ralink_gpio_get; ++ gc->chip.set = ralink_gpio_set; ++ ++ /* set polarity to low for all lines */ ++ rt_gpio_w32(gc, GPIO_REG_POL, 0); ++ ++ dev_info(&pdev->dev, "registering %d gpios\n", gc->chip.ngpio); ++ ++ return gpiochip_add(&gc->chip); ++} ++ ++static const struct of_device_id ralink_gpio_match[] = { ++ { .compatible = "ralink,rt2880-gpio" }, ++ {}, ++}; ++MODULE_DEVICE_TABLE(of, ralink_gpio_match); ++ ++static struct platform_driver ralink_gpio_driver = { ++ .probe = ralink_gpio_probe, ++ .driver = { ++ .name = "rt2880_gpio", ++ .owner = THIS_MODULE, ++ .of_match_table = ralink_gpio_match, ++ }, ++}; ++ ++static int __init ralink_gpio_init(void) ++{ ++ return platform_driver_register(&ralink_gpio_driver); ++} ++ ++subsys_initcall(ralink_gpio_init); diff --git a/target/linux/ramips/patches-3.8/0130-MIPS-ralink-add-cpu-feature-overrides.h-for-RT3662-3.patch b/target/linux/ramips/patches-3.8/0130-MIPS-ralink-add-cpu-feature-overrides.h-for-RT3662-3.patch deleted file mode 100644 index 5d92e36db8..0000000000 --- a/target/linux/ramips/patches-3.8/0130-MIPS-ralink-add-cpu-feature-overrides.h-for-RT3662-3.patch +++ /dev/null @@ -1,81 +0,0 @@ -From 4cca623b74420aacf656b968fde29aace96ae3db Mon Sep 17 00:00:00 2001 -From: Gabor Juhos -Date: Sun, 7 Apr 2013 16:57:30 +0200 -Subject: [PATCH 3/3] MIPS: ralink: add cpu-feature-overrides.h for - RT3662/3883 SoCs - -Signed-off-by: Gabor Juhos ---- - .../asm/mach-ralink/rt3883/cpu-feature-overrides.h | 55 ++++++++++++++++++++ - arch/mips/ralink/Platform | 1 + - 2 files changed, 56 insertions(+) - create mode 100644 arch/mips/include/asm/mach-ralink/rt3883/cpu-feature-overrides.h - ---- /dev/null -+++ b/arch/mips/include/asm/mach-ralink/rt3883/cpu-feature-overrides.h -@@ -0,0 +1,55 @@ -+/* -+ * Ralink RT3662/RT3883 specific CPU feature overrides -+ * -+ * Copyright (C) 2011-2013 Gabor Juhos -+ * -+ * This file was derived from: include/asm-mips/cpu-features.h -+ * Copyright (C) 2003, 2004 Ralf Baechle -+ * Copyright (C) 2004 Maciej W. Rozycki -+ * -+ * This program is free software; you can redistribute it and/or modify it -+ * under the terms of the GNU General Public License version 2 as published -+ * by the Free Software Foundation. -+ * -+ */ -+#ifndef _RT3883_CPU_FEATURE_OVERRIDES_H -+#define _RT3883_CPU_FEATURE_OVERRIDES_H -+ -+#define cpu_has_tlb 1 -+#define cpu_has_4kex 1 -+#define cpu_has_3k_cache 0 -+#define cpu_has_4k_cache 1 -+#define cpu_has_tx39_cache 0 -+#define cpu_has_sb1_cache 0 -+#define cpu_has_fpu 0 -+#define cpu_has_32fpr 0 -+#define cpu_has_counter 1 -+#define cpu_has_watch 1 -+#define cpu_has_divec 1 -+ -+#define cpu_has_prefetch 1 -+#define cpu_has_ejtag 1 -+#define cpu_has_llsc 1 -+ -+#define cpu_has_mips16 1 -+#define cpu_has_mdmx 0 -+#define cpu_has_mips3d 0 -+#define cpu_has_smartmips 0 -+ -+#define cpu_has_mips32r1 1 -+#define cpu_has_mips32r2 1 -+#define cpu_has_mips64r1 0 -+#define cpu_has_mips64r2 0 -+ -+#define cpu_has_dsp 1 -+#define cpu_has_mipsmt 0 -+ -+#define cpu_has_64bits 0 -+#define cpu_has_64bit_zero_reg 0 -+#define cpu_has_64bit_gp_regs 0 -+#define cpu_has_64bit_addresses 0 -+ -+#define cpu_dcache_line_size() 32 -+#define cpu_icache_line_size() 32 -+ -+#endif /* _RT3883_CPU_FEATURE_OVERRIDES_H */ ---- a/arch/mips/ralink/Platform -+++ b/arch/mips/ralink/Platform -@@ -20,6 +20,7 @@ cflags-$(CONFIG_SOC_RT305X) += -I$(srctr - # Ralink RT3883 - # - load-$(CONFIG_SOC_RT3883) += 0xffffffff80000000 -+cflags-$(CONFIG_SOC_RT3883) += -I$(srctree)/arch/mips/include/asm/mach-ralink/rt3883 - - # - # Ralink MT7620 diff --git a/target/linux/ramips/patches-3.8/0131-MIPS-pci-rt3883-rewrite.patch b/target/linux/ramips/patches-3.8/0131-MIPS-pci-rt3883-rewrite.patch deleted file mode 100644 index c493049305..0000000000 --- a/target/linux/ramips/patches-3.8/0131-MIPS-pci-rt3883-rewrite.patch +++ /dev/null @@ -1,856 +0,0 @@ ---- a/arch/mips/pci/pci-rt3883.c -+++ b/arch/mips/pci/pci-rt3883.c -@@ -1,7 +1,7 @@ - /* -- * Ralink RT3883 SoC PCI support -+ * Ralink RT3662/RT3883 SoC PCI support - * -- * Copyright (C) 2011-2012 Gabor Juhos -+ * Copyright (C) 2011-2013 Gabor Juhos - * - * Parts of this file are based on Ralink's 2.6.21 BSP - * -@@ -16,52 +16,82 @@ - #include - #include - #include -+#include -+#include -+#include -+#include -+#include - - #include --#include -+#include - - #define RT3883_MEMORY_BASE 0x00000000 - #define RT3883_MEMORY_SIZE 0x02000000 - --#define RT3883_PCI_MEM_BASE 0x20000000 --#define RT3883_PCI_MEM_SIZE 0x10000000 --#define RT3883_PCI_IO_BASE 0x10160000 --#define RT3883_PCI_IO_SIZE 0x00010000 -- --#define RT3883_PCI_REG_PCICFG_ADDR 0x00 --#define RT3883_PCI_REG_PCIRAW_ADDR 0x04 --#define RT3883_PCI_REG_PCIINT_ADDR 0x08 --#define RT3883_PCI_REG_PCIMSK_ADDR 0x0c --#define RT3833_PCI_PCIINT_PCIE BIT(20) --#define RT3833_PCI_PCIINT_PCI1 BIT(19) --#define RT3833_PCI_PCIINT_PCI0 BIT(18) -+#define RT3883_PCI_REG_PCICFG 0x00 -+#define RT3883_PCICFG_P2P_BR_DEVNUM_M 0xf -+#define RT3883_PCICFG_P2P_BR_DEVNUM_S 16 -+#define RT3883_PCICFG_PCIRST BIT(1) -+#define RT3883_PCI_REG_PCIRAW 0x04 -+#define RT3883_PCI_REG_PCIINT 0x08 -+#define RT3883_PCI_REG_PCIENA 0x0c - --#define RT3883_PCI_REG_CONFIG_ADDR 0x20 --#define RT3883_PCI_REG_CONFIG_DATA 0x24 -+#define RT3883_PCI_REG_CFGADDR 0x20 -+#define RT3883_PCI_REG_CFGDATA 0x24 - #define RT3883_PCI_REG_MEMBASE 0x28 - #define RT3883_PCI_REG_IOBASE 0x2c - #define RT3883_PCI_REG_ARBCTL 0x80 - - #define RT3883_PCI_REG_BASE(_x) (0x1000 + (_x) * 0x1000) --#define RT3883_PCI_REG_BAR0SETUP_ADDR(_x) (RT3883_PCI_REG_BASE((_x)) + 0x10) --#define RT3883_PCI_REG_IMBASEBAR0_ADDR(_x) (RT3883_PCI_REG_BASE((_x)) + 0x18) -+#define RT3883_PCI_REG_BAR0SETUP(_x) (RT3883_PCI_REG_BASE((_x)) + 0x10) -+#define RT3883_PCI_REG_IMBASEBAR0(_x) (RT3883_PCI_REG_BASE((_x)) + 0x18) - #define RT3883_PCI_REG_ID(_x) (RT3883_PCI_REG_BASE((_x)) + 0x30) - #define RT3883_PCI_REG_CLASS(_x) (RT3883_PCI_REG_BASE((_x)) + 0x34) - #define RT3883_PCI_REG_SUBID(_x) (RT3883_PCI_REG_BASE((_x)) + 0x38) - #define RT3883_PCI_REG_STATUS(_x) (RT3883_PCI_REG_BASE((_x)) + 0x50) - --static int (*rt3883_pci_plat_dev_init)(struct pci_dev *dev); --static void __iomem *rt3883_pci_base; --static DEFINE_SPINLOCK(rt3883_pci_lock); -+#define RT3883_PCI_MODE_NONE 0 -+#define RT3883_PCI_MODE_PCI BIT(0) -+#define RT3883_PCI_MODE_PCIE BIT(1) -+#define RT3883_PCI_MODE_BOTH (RT3883_PCI_MODE_PCI | RT3883_PCI_MODE_PCIE) - --static inline u32 rt3883_pci_rr(unsigned reg) -+#define RT3883_PCI_IRQ_COUNT 32 -+ -+#define RT3883_P2P_BR_DEVNUM 1 -+ -+struct rt3883_pci_controller { -+ void __iomem *base; -+ spinlock_t lock; -+ -+ struct irq_domain *irq_domain; -+ -+ struct pci_controller pci_controller; -+ struct resource io_res; -+ struct resource mem_res; -+ -+ bool pcie_ready; -+ unsigned char p2p_devnum; -+}; -+ -+static inline struct rt3883_pci_controller * -+pci_bus_to_rt3883_controller(struct pci_bus *bus) - { -- return readl(rt3883_pci_base + reg); -+ struct pci_controller *hose; -+ -+ hose = (struct pci_controller *) bus->sysdata; -+ return container_of(hose, struct rt3883_pci_controller, pci_controller); -+} -+ -+static inline u32 rt3883_pci_r32(struct rt3883_pci_controller *rpc, -+ unsigned reg) -+{ -+ return ioread32(rpc->base + reg); - } - --static inline void rt3883_pci_wr(u32 val, unsigned reg) -+static inline void rt3883_pci_w32(struct rt3883_pci_controller *rpc, -+ u32 val, unsigned reg) - { -- writel(val, rt3883_pci_base + reg); -+ iowrite32(val, rpc->base + reg); - } - - static inline u32 rt3883_pci_get_cfgaddr(unsigned int bus, unsigned int slot, -@@ -71,7 +101,8 @@ static inline u32 rt3883_pci_get_cfgaddr - 0x80000000); - } - --static u32 rt3883_pci_read_u32(unsigned bus, unsigned slot, -+static u32 rt3883_pci_read_cfg32(struct rt3883_pci_controller *rpc, -+ unsigned bus, unsigned slot, - unsigned func, unsigned reg) - { - unsigned long flags; -@@ -80,15 +111,16 @@ static u32 rt3883_pci_read_u32(unsigned - - address = rt3883_pci_get_cfgaddr(bus, slot, func, reg); - -- spin_lock_irqsave(&rt3883_pci_lock, flags); -- rt3883_pci_wr(address, RT3883_PCI_REG_CONFIG_ADDR); -- ret = rt3883_pci_rr(RT3883_PCI_REG_CONFIG_DATA); -- spin_unlock_irqrestore(&rt3883_pci_lock, flags); -+ spin_lock_irqsave(&rpc->lock, flags); -+ rt3883_pci_w32(rpc, address, RT3883_PCI_REG_CFGADDR); -+ ret = rt3883_pci_r32(rpc, RT3883_PCI_REG_CFGDATA); -+ spin_unlock_irqrestore(&rpc->lock, flags); - - return ret; - } - --static void rt3883_pci_write_u32(unsigned bus, unsigned slot, -+static void rt3883_pci_write_cfg32(struct rt3883_pci_controller *rpc, -+ unsigned bus, unsigned slot, - unsigned func, unsigned reg, u32 val) - { - unsigned long flags; -@@ -96,84 +128,61 @@ static void rt3883_pci_write_u32(unsigne - - address = rt3883_pci_get_cfgaddr(bus, slot, func, reg); - -- spin_lock_irqsave(&rt3883_pci_lock, flags); -- rt3883_pci_wr(address, RT3883_PCI_REG_CONFIG_ADDR); -- rt3883_pci_wr(val, RT3883_PCI_REG_CONFIG_DATA); -- spin_unlock_irqrestore(&rt3883_pci_lock, flags); -+ spin_lock_irqsave(&rpc->lock, flags); -+ rt3883_pci_w32(rpc, address, RT3883_PCI_REG_CFGADDR); -+ rt3883_pci_w32(rpc, val, RT3883_PCI_REG_CFGDATA); -+ spin_unlock_irqrestore(&rpc->lock, flags); - } - - static void rt3883_pci_irq_handler(unsigned int irq, struct irq_desc *desc) - { -+ struct rt3883_pci_controller *rpc; - u32 pending; - -- pending = rt3883_pci_rr(RT3883_PCI_REG_PCIINT_ADDR) & -- rt3883_pci_rr(RT3883_PCI_REG_PCIMSK_ADDR); -+ rpc = irq_get_handler_data(irq); -+ -+ pending = rt3883_pci_r32(rpc, RT3883_PCI_REG_PCIINT) & -+ rt3883_pci_r32(rpc, RT3883_PCI_REG_PCIENA); - - if (!pending) { - spurious_interrupt(); - return; - } - -- if (pending & RT3833_PCI_PCIINT_PCI0) -- generic_handle_irq(RT3883_PCI_IRQ_PCI0); -+ while (pending) { -+ unsigned bit = __ffs(pending); - -- if (pending & RT3833_PCI_PCIINT_PCI1) -- generic_handle_irq(RT3883_PCI_IRQ_PCI1); -+ irq = irq_find_mapping(rpc->irq_domain, bit); -+ generic_handle_irq(irq); - -- if (pending & RT3833_PCI_PCIINT_PCIE) -- generic_handle_irq(RT3883_PCI_IRQ_PCIE); -+ pending &= ~BIT(bit); -+ } - } - - static void rt3883_pci_irq_unmask(struct irq_data *d) - { -- int irq = d->irq; -- u32 mask; -+ struct rt3883_pci_controller *rpc; - u32 t; - -- switch (irq) { -- case RT3883_PCI_IRQ_PCI0: -- mask = RT3833_PCI_PCIINT_PCI0; -- break; -- case RT3883_PCI_IRQ_PCI1: -- mask = RT3833_PCI_PCIINT_PCI1; -- break; -- case RT3883_PCI_IRQ_PCIE: -- mask = RT3833_PCI_PCIINT_PCIE; -- break; -- default: -- BUG(); -- } -+ rpc = irq_data_get_irq_chip_data(d); - -- t = rt3883_pci_rr(RT3883_PCI_REG_PCIMSK_ADDR); -- rt3883_pci_wr(t | mask, RT3883_PCI_REG_PCIMSK_ADDR); -+ t = rt3883_pci_r32(rpc, RT3883_PCI_REG_PCIENA); -+ rt3883_pci_w32(rpc, t | BIT(d->hwirq), RT3883_PCI_REG_PCIENA); - /* flush write */ -- rt3883_pci_rr(RT3883_PCI_REG_PCIMSK_ADDR); -+ rt3883_pci_r32(rpc, RT3883_PCI_REG_PCIENA); - } - - static void rt3883_pci_irq_mask(struct irq_data *d) - { -- int irq = d->irq; -- u32 mask; -+ struct rt3883_pci_controller *rpc; - u32 t; - -- switch (irq) { -- case RT3883_PCI_IRQ_PCI0: -- mask = RT3833_PCI_PCIINT_PCI0; -- break; -- case RT3883_PCI_IRQ_PCI1: -- mask = RT3833_PCI_PCIINT_PCI1; -- break; -- case RT3883_PCI_IRQ_PCIE: -- mask = RT3833_PCI_PCIINT_PCIE; -- break; -- default: -- BUG(); -- } -+ rpc = irq_data_get_irq_chip_data(d); - -- t = rt3883_pci_rr(RT3883_PCI_REG_PCIMSK_ADDR); -- rt3883_pci_wr(t & ~mask, RT3883_PCI_REG_PCIMSK_ADDR); -+ t = rt3883_pci_r32(rpc, RT3883_PCI_REG_PCIENA); -+ rt3883_pci_w32(rpc, t & ~BIT(d->hwirq), RT3883_PCI_REG_PCIENA); - /* flush write */ -- rt3883_pci_rr(RT3883_PCI_REG_PCIMSK_ADDR); -+ rt3883_pci_r32(rpc, RT3883_PCI_REG_PCIENA); - } - - static struct irq_chip rt3883_pci_irq_chip = { -@@ -183,36 +192,84 @@ static struct irq_chip rt3883_pci_irq_ch - .irq_mask_ack = rt3883_pci_irq_mask, - }; - --static void __init rt3883_pci_irq_init(void) -+static int rt3883_pci_irq_map(struct irq_domain *d, unsigned int irq, -+ irq_hw_number_t hw) - { -- int i; -+ irq_set_chip_and_handler(irq, &rt3883_pci_irq_chip, handle_level_irq); -+ irq_set_chip_data(irq, d->host_data); -+ -+ return 0; -+} -+ -+static const struct irq_domain_ops rt3883_pci_irq_domain_ops = { -+ .map = rt3883_pci_irq_map, -+ .xlate = irq_domain_xlate_onecell, -+}; -+ -+static int rt3883_pci_irq_init(struct device *dev, -+ struct rt3883_pci_controller *rpc) -+{ -+ struct device_node *np = dev->of_node; -+ struct device_node *intc_np; -+ int irq; -+ int err; -+ -+ intc_np = of_get_child_by_name(np, "interrupt-controller"); -+ if (!intc_np) { -+ dev_err(dev, "no %s child node found", "interrupt-controller"); -+ return -ENODEV; -+ } -+ -+ irq = irq_of_parse_and_map(intc_np, 0); -+ if (irq == 0) { -+ dev_err(dev, "%s has no IRQ", of_node_full_name(intc_np)); -+ err = -EINVAL; -+ goto err_put_intc; -+ } - - /* disable all interrupts */ -- rt3883_pci_wr(0, RT3883_PCI_REG_PCIMSK_ADDR); -+ rt3883_pci_w32(rpc, 0, RT3883_PCI_REG_PCIENA); - -- for (i = RT3883_PCI_IRQ_BASE; -- i < RT3883_PCI_IRQ_BASE + RT3883_PCI_IRQ_COUNT; i++) { -- irq_set_chip_and_handler(i, &rt3883_pci_irq_chip, -- handle_level_irq); -+ rpc->irq_domain = -+ irq_domain_add_linear(intc_np, RT3883_PCI_IRQ_COUNT, -+ &rt3883_pci_irq_domain_ops, -+ rpc); -+ if (!rpc->irq_domain) { -+ dev_err(dev, "unable to add IRQ domain\n"); -+ err = -ENODEV; -+ goto err_put_intc; - } - -- irq_set_chained_handler(RT3883_CPU_IRQ_PCI, rt3883_pci_irq_handler); -+ irq_set_handler_data(irq, rpc); -+ irq_set_chained_handler(irq, rt3883_pci_irq_handler); -+ -+ return 0; -+ -+err_put_intc: -+ of_node_put(intc_np); -+ return err; - } - - static int rt3883_pci_config_read(struct pci_bus *bus, unsigned int devfn, - int where, int size, u32 *val) - { -+ struct rt3883_pci_controller *rpc; - unsigned long flags; - u32 address; - u32 data; - -+ rpc = pci_bus_to_rt3883_controller(bus); -+ -+ if (!rpc->pcie_ready && bus->number == 1) -+ return PCIBIOS_DEVICE_NOT_FOUND; -+ - address = rt3883_pci_get_cfgaddr(bus->number, PCI_SLOT(devfn), - PCI_FUNC(devfn), where); - -- spin_lock_irqsave(&rt3883_pci_lock, flags); -- rt3883_pci_wr(address, RT3883_PCI_REG_CONFIG_ADDR); -- data = rt3883_pci_rr(RT3883_PCI_REG_CONFIG_DATA); -- spin_unlock_irqrestore(&rt3883_pci_lock, flags); -+ spin_lock_irqsave(&rpc->lock, flags); -+ rt3883_pci_w32(rpc, address, RT3883_PCI_REG_CFGADDR); -+ data = rt3883_pci_r32(rpc, RT3883_PCI_REG_CFGDATA); -+ spin_unlock_irqrestore(&rpc->lock, flags); - - switch (size) { - case 1: -@@ -232,16 +289,22 @@ static int rt3883_pci_config_read(struct - static int rt3883_pci_config_write(struct pci_bus *bus, unsigned int devfn, - int where, int size, u32 val) - { -+ struct rt3883_pci_controller *rpc; - unsigned long flags; - u32 address; - u32 data; - -+ rpc = pci_bus_to_rt3883_controller(bus); -+ -+ if (!rpc->pcie_ready && bus->number == 1) -+ return PCIBIOS_DEVICE_NOT_FOUND; -+ - address = rt3883_pci_get_cfgaddr(bus->number, PCI_SLOT(devfn), - PCI_FUNC(devfn), where); - -- spin_lock_irqsave(&rt3883_pci_lock, flags); -- rt3883_pci_wr(address, RT3883_PCI_REG_CONFIG_ADDR); -- data = rt3883_pci_rr(RT3883_PCI_REG_CONFIG_DATA); -+ spin_lock_irqsave(&rpc->lock, flags); -+ rt3883_pci_w32(rpc, address, RT3883_PCI_REG_CFGADDR); -+ data = rt3883_pci_r32(rpc, RT3883_PCI_REG_CFGDATA); - - switch (size) { - case 1: -@@ -257,8 +320,8 @@ static int rt3883_pci_config_write(struc - break; - } - -- rt3883_pci_wr(data, RT3883_PCI_REG_CONFIG_DATA); -- spin_unlock_irqrestore(&rt3883_pci_lock, flags); -+ rt3883_pci_w32(rpc, data, RT3883_PCI_REG_CFGDATA); -+ spin_unlock_irqrestore(&rpc->lock, flags); - - return PCIBIOS_SUCCESSFUL; - } -@@ -268,220 +331,310 @@ static struct pci_ops rt3883_pci_ops = { - .write = rt3883_pci_config_write, - }; - --static struct resource rt3883_pci_mem_resource = { -- .name = "PCI MEM space", -- .start = RT3883_PCI_MEM_BASE, -- .end = RT3883_PCI_MEM_BASE + RT3883_PCI_MEM_SIZE - 1, -- .flags = IORESOURCE_MEM, --}; -- --static struct resource rt3883_pci_io_resource = { -- .name = "PCI IO space", -- .start = RT3883_PCI_IO_BASE, -- .end = RT3883_PCI_IO_BASE + RT3883_PCI_IO_SIZE - 1, -- .flags = IORESOURCE_IO, --}; -- --static struct pci_controller rt3883_pci_controller = { -- .pci_ops = &rt3883_pci_ops, -- .mem_resource = &rt3883_pci_mem_resource, -- .io_resource = &rt3883_pci_io_resource, --}; -- --static void rt3883_pci_preinit(unsigned mode) -+static void rt3883_pci_preinit(struct rt3883_pci_controller *rpc, unsigned mode) - { - u32 syscfg1; - u32 rstctrl; - u32 clkcfg1; -+ u32 t; -+ -+ rstctrl = rt_sysc_r32(RT3883_SYSC_REG_RSTCTRL); -+ syscfg1 = rt_sysc_r32(RT3883_SYSC_REG_SYSCFG1); -+ clkcfg1 = rt_sysc_r32(RT3883_SYSC_REG_CLKCFG1); - - if (mode & RT3883_PCI_MODE_PCIE) { -- u32 val; -+ rstctrl |= RT3883_RSTCTRL_PCIE; -+ rt_sysc_w32(rstctrl, RT3883_SYSC_REG_RSTCTRL); - -- val = rt3883_sysc_rr(RT3883_SYSC_REG_SYSCFG1); -- val &= ~(0x30); -- val |= (2 << 4); -- rt3883_sysc_wr(val, RT3883_SYSC_REG_SYSCFG1); -- -- val = rt3883_sysc_rr(RT3883_SYSC_REG_PCIE_CLK_GEN0); -- val &= ~BIT(31); -- rt3883_sysc_wr(val, RT3883_SYSC_REG_PCIE_CLK_GEN0); -- -- val = rt3883_sysc_rr(RT3883_SYSC_REG_PCIE_CLK_GEN1); -- val &= 0x80ffffff; -- rt3883_sysc_wr(val, RT3883_SYSC_REG_PCIE_CLK_GEN1); -- -- val = rt3883_sysc_rr(RT3883_SYSC_REG_PCIE_CLK_GEN1); -- val |= 0xa << 24; -- rt3883_sysc_wr(val, RT3883_SYSC_REG_PCIE_CLK_GEN1); -- -- val = rt3883_sysc_rr(RT3883_SYSC_REG_PCIE_CLK_GEN0); -- val |= BIT(31); -- rt3883_sysc_wr(val, RT3883_SYSC_REG_PCIE_CLK_GEN0); -+ /* setup PCI PAD drive mode */ -+ syscfg1 &= ~(0x30); -+ syscfg1 |= (2 << 4); -+ rt_sysc_w32(syscfg1, RT3883_SYSC_REG_SYSCFG1); -+ -+ t = rt_sysc_r32(RT3883_SYSC_REG_PCIE_CLK_GEN0); -+ t &= ~BIT(31); -+ rt_sysc_w32(t, RT3883_SYSC_REG_PCIE_CLK_GEN0); -+ -+ t = rt_sysc_r32(RT3883_SYSC_REG_PCIE_CLK_GEN1); -+ t &= 0x80ffffff; -+ rt_sysc_w32(t, RT3883_SYSC_REG_PCIE_CLK_GEN1); -+ -+ t = rt_sysc_r32(RT3883_SYSC_REG_PCIE_CLK_GEN1); -+ t |= 0xa << 24; -+ rt_sysc_w32(t, RT3883_SYSC_REG_PCIE_CLK_GEN1); -+ -+ t = rt_sysc_r32(RT3883_SYSC_REG_PCIE_CLK_GEN0); -+ t |= BIT(31); -+ rt_sysc_w32(t, RT3883_SYSC_REG_PCIE_CLK_GEN0); - - msleep(50); -+ -+ rstctrl &= ~RT3883_RSTCTRL_PCIE; -+ rt_sysc_w32(rstctrl, RT3883_SYSC_REG_RSTCTRL); - } - -- syscfg1 = rt3883_sysc_rr(RT3883_SYSC_REG_SYSCFG1); -- syscfg1 &= ~(RT3883_SYSCFG1_PCIE_RC_MODE | -- RT3883_SYSCFG1_PCI_HOST_MODE); -- -- rstctrl = rt3883_sysc_rr(RT3883_SYSC_REG_RSTCTRL); -- rstctrl |= (RT3883_RSTCTRL_PCI | RT3883_RSTCTRL_PCIE); -- -- clkcfg1 = rt3883_sysc_rr(RT3883_SYSC_REG_CLKCFG1); -- clkcfg1 &= ~(RT3883_CLKCFG1_PCI_CLK_EN | -- RT3883_CLKCFG1_PCIE_CLK_EN); -+ syscfg1 |= (RT3883_SYSCFG1_PCIE_RC_MODE | RT3883_SYSCFG1_PCI_HOST_MODE); -+ -+ clkcfg1 &= ~(RT3883_CLKCFG1_PCI_CLK_EN | RT3883_CLKCFG1_PCIE_CLK_EN); - - if (mode & RT3883_PCI_MODE_PCI) { -- syscfg1 |= RT3883_SYSCFG1_PCI_HOST_MODE; - clkcfg1 |= RT3883_CLKCFG1_PCI_CLK_EN; - rstctrl &= ~RT3883_RSTCTRL_PCI; - } -+ - if (mode & RT3883_PCI_MODE_PCIE) { -- syscfg1 |= RT3883_SYSCFG1_PCI_HOST_MODE | -- RT3883_SYSCFG1_PCIE_RC_MODE; - clkcfg1 |= RT3883_CLKCFG1_PCIE_CLK_EN; - rstctrl &= ~RT3883_RSTCTRL_PCIE; - } - -- rt3883_sysc_wr(syscfg1, RT3883_SYSC_REG_SYSCFG1); -- rt3883_sysc_wr(rstctrl, RT3883_SYSC_REG_RSTCTRL); -- rt3883_sysc_wr(clkcfg1, RT3883_SYSC_REG_CLKCFG1); -+ rt_sysc_w32(syscfg1, RT3883_SYSC_REG_SYSCFG1); -+ rt_sysc_w32(rstctrl, RT3883_SYSC_REG_RSTCTRL); -+ rt_sysc_w32(clkcfg1, RT3883_SYSC_REG_CLKCFG1); - - msleep(500); --} - --static int rt3883_pcie_ready(void) --{ -- u32 status; -+ /* -+ * setup the device number of the P2P bridge -+ * and de-assert the reset line -+ */ -+ t = (RT3883_P2P_BR_DEVNUM << RT3883_PCICFG_P2P_BR_DEVNUM_S); -+ rt3883_pci_w32(rpc, t, RT3883_PCI_REG_PCICFG); - -+ /* flush write */ -+ rt3883_pci_r32(rpc, RT3883_PCI_REG_PCICFG); - msleep(500); - -- status = rt3883_pci_rr(RT3883_PCI_REG_STATUS(1)); -- if (status & BIT(0)) -- return 0; -+ if (mode & RT3883_PCI_MODE_PCIE) { -+ msleep(500); -+ -+ t = rt3883_pci_r32(rpc, RT3883_PCI_REG_STATUS(1)); -+ -+ rpc->pcie_ready = t & BIT(0); -+ -+ if (!rpc->pcie_ready) { -+ /* reset the PCIe block */ -+ t = rt_sysc_r32(RT3883_SYSC_REG_RSTCTRL); -+ t |= RT3883_RSTCTRL_PCIE; -+ rt_sysc_w32(t, RT3883_SYSC_REG_RSTCTRL); -+ t &= ~RT3883_RSTCTRL_PCIE; -+ rt_sysc_w32(t, RT3883_SYSC_REG_RSTCTRL); -+ -+ /* turn off PCIe clock */ -+ t = rt_sysc_r32(RT3883_SYSC_REG_CLKCFG1); -+ t &= ~RT3883_CLKCFG1_PCIE_CLK_EN; -+ rt_sysc_w32(t, RT3883_SYSC_REG_CLKCFG1); -+ -+ t = rt_sysc_r32(RT3883_SYSC_REG_PCIE_CLK_GEN0); -+ t &= ~0xf000c080; -+ rt_sysc_w32(t, RT3883_SYSC_REG_PCIE_CLK_GEN0); -+ } -+ } -+ -+ /* enable PCI arbiter */ -+ rt3883_pci_w32(rpc, 0x79, RT3883_PCI_REG_ARBCTL); -+} - -- /* TODO: reset PCIe and turn off PCIe clock */ -+static inline void -+rt3883_dump_pci_config(struct rt3883_pci_controller *rpc, -+ int bus, int slot) -+{ -+ int i; -+ -+ for (i = 0; i < 16; i++) { -+ u32 val; - -- return -ENODEV; -+ val = rt3883_pci_read_cfg32(rpc, bus, slot, 0, i << 2); -+ pr_info("pci %02x:%02x.0 0x%02x = %08x\n", -+ bus, slot, i << 2, val); -+ } - } - --void __init rt3883_pci_init(unsigned mode) -+static int rt3883_pci_probe(struct platform_device *pdev) - { -+ struct rt3883_pci_controller *rpc; -+ struct device *dev = &pdev->dev; -+ struct device_node *np = dev->of_node; -+ struct resource *res; -+ struct device_node *child; - u32 val; - int err; -+ int mode; - -- rt3883_pci_preinit(mode); -+ rpc = devm_kzalloc(dev, sizeof(*rpc), GFP_KERNEL); -+ if (!rpc) -+ return -ENOMEM; -+ -+ res = platform_get_resource(pdev, IORESOURCE_MEM, 0); -+ if (!res) -+ return -EINVAL; -+ -+ rpc->base = devm_ioremap_resource(dev, res); -+ if (IS_ERR(rpc->base)) -+ return PTR_ERR(rpc->base); -+ -+ rpc->pci_controller.of_node = of_get_child_by_name(np, "host-bridge"); -+ if (!rpc->pci_controller.of_node) { -+ dev_err(dev, "no %s child node found", "host-bridge"); -+ return -ENODEV; -+ } -+ -+ mode = RT3883_PCI_MODE_NONE; -+ for_each_child_of_node(rpc->pci_controller.of_node, child) { -+ u32 slot; -+ -+ if (!of_device_is_available(child)) -+ continue; -+ -+ if (of_property_read_u32(child, "ralink,pci-slot", -+ &slot)) { -+ dev_err(dev, "no '%s' property found for %s\n", -+ "ralink,pci-slot", -+ of_node_full_name(child)); -+ continue; -+ } - -- rt3883_pci_base = ioremap(RT3883_PCI_BASE, PAGE_SIZE); -- if (rt3883_pci_base == NULL) { -- pr_err("failed to ioremap PCI registers\n"); -- return; -+ switch (slot) { -+ case 1: -+ mode |= RT3883_PCI_MODE_PCIE; -+ break; -+ -+ case 17: -+ case 18: -+ mode |= RT3883_PCI_MODE_PCI; -+ break; -+ } - } - -- rt3883_pci_wr(0, RT3883_PCI_REG_PCICFG_ADDR); -- if (mode & RT3883_PCI_MODE_PCI) -- rt3883_pci_wr(BIT(16), RT3883_PCI_REG_PCICFG_ADDR); -+ if (mode == RT3883_PCI_MODE_NONE) { -+ dev_err(dev, "unable to determine PCI mode\n"); -+ err = -EINVAL; -+ goto err_put_hb_node; -+ } - -- msleep(500); -+ dev_info(dev, "mode:%s%s\n", -+ (mode & RT3883_PCI_MODE_PCI) ? " PCI" : "", -+ (mode & RT3883_PCI_MODE_PCIE) ? " PCIe" : ""); - -- if (mode & RT3883_PCI_MODE_PCIE) { -- err = rt3883_pcie_ready(); -- if (err) -- return; -- } -+ rt3883_pci_preinit(rpc, mode); - -- if (mode & RT3883_PCI_MODE_PCI) -- rt3883_pci_wr(0x79, RT3883_PCI_REG_ARBCTL); -+ rpc->pci_controller.pci_ops = &rt3883_pci_ops; -+ rpc->pci_controller.io_resource = &rpc->io_res; -+ rpc->pci_controller.mem_resource = &rpc->mem_res; - -- rt3883_pci_wr(RT3883_PCI_MEM_BASE, RT3883_PCI_REG_MEMBASE); -- rt3883_pci_wr(RT3883_PCI_IO_BASE, RT3883_PCI_REG_IOBASE); -+ /* Load PCI I/O and memory resources from DT */ -+ pci_load_of_ranges(&rpc->pci_controller, -+ rpc->pci_controller.of_node); -+ -+ rt3883_pci_w32(rpc, rpc->mem_res.start, RT3883_PCI_REG_MEMBASE); -+ rt3883_pci_w32(rpc, rpc->io_res.start, RT3883_PCI_REG_IOBASE); -+ -+ ioport_resource.start = rpc->io_res.start; -+ ioport_resource.end = rpc->io_res.end; - - /* PCI */ -- rt3883_pci_wr(0x03ff0000, RT3883_PCI_REG_BAR0SETUP_ADDR(0)); -- rt3883_pci_wr(RT3883_MEMORY_BASE, RT3883_PCI_REG_IMBASEBAR0_ADDR(0)); -- rt3883_pci_wr(0x08021814, RT3883_PCI_REG_ID(0)); -- rt3883_pci_wr(0x00800001, RT3883_PCI_REG_CLASS(0)); -- rt3883_pci_wr(0x28801814, RT3883_PCI_REG_SUBID(0)); -+ rt3883_pci_w32(rpc, 0x03ff0000, RT3883_PCI_REG_BAR0SETUP(0)); -+ rt3883_pci_w32(rpc, RT3883_MEMORY_BASE, RT3883_PCI_REG_IMBASEBAR0(0)); -+ rt3883_pci_w32(rpc, 0x08021814, RT3883_PCI_REG_ID(0)); -+ rt3883_pci_w32(rpc, 0x00800001, RT3883_PCI_REG_CLASS(0)); -+ rt3883_pci_w32(rpc, 0x28801814, RT3883_PCI_REG_SUBID(0)); - - /* PCIe */ -- rt3883_pci_wr(0x01ff0000, RT3883_PCI_REG_BAR0SETUP_ADDR(1)); -- rt3883_pci_wr(RT3883_MEMORY_BASE, RT3883_PCI_REG_IMBASEBAR0_ADDR(1)); -- rt3883_pci_wr(0x08021814, RT3883_PCI_REG_ID(1)); -- rt3883_pci_wr(0x06040001, RT3883_PCI_REG_CLASS(1)); -- rt3883_pci_wr(0x28801814, RT3883_PCI_REG_SUBID(1)); -- -- rt3883_pci_irq_init(); -+ rt3883_pci_w32(rpc, 0x03ff0000, RT3883_PCI_REG_BAR0SETUP(1)); -+ rt3883_pci_w32(rpc, RT3883_MEMORY_BASE, RT3883_PCI_REG_IMBASEBAR0(1)); -+ rt3883_pci_w32(rpc, 0x08021814, RT3883_PCI_REG_ID(1)); -+ rt3883_pci_w32(rpc, 0x06040001, RT3883_PCI_REG_CLASS(1)); -+ rt3883_pci_w32(rpc, 0x28801814, RT3883_PCI_REG_SUBID(1)); -+ -+ err = rt3883_pci_irq_init(dev, rpc); -+ if (err) -+ goto err_put_hb_node; - - /* PCIe */ -- val = rt3883_pci_read_u32(0, 0x01, 0, PCI_COMMAND); -- val |= 0x7; -- rt3883_pci_write_u32(0, 0x01, 0, PCI_COMMAND, val); -+ val = rt3883_pci_read_cfg32(rpc, 0, 0x01, 0, PCI_COMMAND); -+ val |= PCI_COMMAND_IO | PCI_COMMAND_MEMORY | PCI_COMMAND_MASTER; -+ rt3883_pci_write_cfg32(rpc, 0, 0x01, 0, PCI_COMMAND, val); - - /* PCI */ -- val = rt3883_pci_read_u32(0, 0x00, 0, PCI_COMMAND); -- val |= 0x7; -- rt3883_pci_write_u32(0, 0x00, 0, PCI_COMMAND, val); -+ val = rt3883_pci_read_cfg32(rpc, 0, 0x00, 0, PCI_COMMAND); -+ val |= PCI_COMMAND_IO | PCI_COMMAND_MEMORY | PCI_COMMAND_MASTER; -+ rt3883_pci_write_cfg32(rpc, 0, 0x00, 0, PCI_COMMAND, val); -+ -+ if (mode == RT3883_PCI_MODE_PCIE) { -+ rt3883_pci_w32(rpc, 0x03ff0001, RT3883_PCI_REG_BAR0SETUP(0)); -+ rt3883_pci_w32(rpc, 0x03ff0001, RT3883_PCI_REG_BAR0SETUP(1)); -+ -+ rt3883_pci_write_cfg32(rpc, 0, RT3883_P2P_BR_DEVNUM, 0, -+ PCI_BASE_ADDRESS_0, -+ RT3883_MEMORY_BASE); -+ /* flush write */ -+ rt3883_pci_read_cfg32(rpc, 0, RT3883_P2P_BR_DEVNUM, 0, -+ PCI_BASE_ADDRESS_0); -+ } else { -+ rt3883_pci_write_cfg32(rpc, 0, RT3883_P2P_BR_DEVNUM, 0, -+ PCI_IO_BASE, 0x00000101); -+ } -+ -+ register_pci_controller(&rpc->pci_controller); - -- ioport_resource.start = rt3883_pci_io_resource.start; -- ioport_resource.end = rt3883_pci_io_resource.end; -+ return 0; - -- register_pci_controller(&rt3883_pci_controller); -+err_put_hb_node: -+ of_node_put(rpc->pci_controller.of_node); -+ return err; - } - - int __init pcibios_map_irq(const struct pci_dev *dev, u8 slot, u8 pin) - { -- int irq = -1; -- -- switch (dev->bus->number) { -- case 0: -- switch (PCI_SLOT(dev->devfn)) { -- case 0x00: -- rt3883_pci_wr(0x03ff0001, -- RT3883_PCI_REG_BAR0SETUP_ADDR(0)); -- rt3883_pci_wr(0x03ff0001, -- RT3883_PCI_REG_BAR0SETUP_ADDR(1)); -- -- rt3883_pci_write_u32(0, 0x00, 0, PCI_BASE_ADDRESS_0, -- RT3883_MEMORY_BASE); -- rt3883_pci_read_u32(0, 0x00, 0, PCI_BASE_ADDRESS_0); -- -- irq = RT3883_CPU_IRQ_PCI; -- break; -- case 0x01: -- rt3883_pci_write_u32(0, 0x01, 0, PCI_IO_BASE, -- 0x00000101); -- break; -- case 0x11: -- irq = RT3883_PCI_IRQ_PCI0; -- break; -- case 0x12: -- irq = RT3883_PCI_IRQ_PCI1; -- break; -- } -- break; -- -- case 1: -- irq = RT3883_PCI_IRQ_PCIE; -- break; -+ struct rt3883_pci_controller *rpc; -+ struct of_irq dev_irq; -+ int err; -+ int irq; - -- default: -- dev_err(&dev->dev, "no IRQ specified\n"); -- return irq; -+ rpc = pci_bus_to_rt3883_controller(dev->bus); -+ err = of_irq_map_pci(dev, &dev_irq); -+ if (err) { -+ pr_err("pci %s: unable to get irq map, err=%d\n", -+ pci_name((struct pci_dev *) dev), err); -+ return 0; - } - -+ irq = irq_create_of_mapping(dev_irq.controller, -+ dev_irq.specifier, -+ dev_irq.size); -+ -+ if (irq == 0) -+ pr_crit("pci %s: no irq found for pin %u\n", -+ pci_name((struct pci_dev *) dev), pin); -+ else -+ pr_info("pci %s: using irq %d for pin %u\n", -+ pci_name((struct pci_dev *) dev), irq, pin); -+ - return irq; - } - --void __init rt3883_pci_set_plat_dev_init(int (*f)(struct pci_dev *dev)) -+int pcibios_plat_dev_init(struct pci_dev *dev) - { -- rt3883_pci_plat_dev_init = f; -+ return 0; - } - --int pcibios_plat_dev_init(struct pci_dev *dev) --{ -- if (rt3883_pci_plat_dev_init) -- return rt3883_pci_plat_dev_init(dev); -+static const struct of_device_id rt3883_pci_ids[] = { -+ { .compatible = "ralink,rt3883-pci" }, -+ {}, -+}; -+MODULE_DEVICE_TABLE(of, rt3883_pci_ids); - -- return 0; -+static struct platform_driver rt3883_pci_driver = { -+ .probe = rt3883_pci_probe, -+ .driver = { -+ .name = "rt3883-pci", -+ .owner = THIS_MODULE, -+ .of_match_table = of_match_ptr(rt3883_pci_ids), -+ }, -+}; -+ -+static int __init rt3883_pci_init(void) -+{ -+ return platform_driver_register(&rt3883_pci_driver); - } -+ -+postcore_initcall(rt3883_pci_init); diff --git a/target/linux/ramips/patches-3.8/0131-SPI-ralink-add-Ralink-SoC-spi-driver.patch b/target/linux/ramips/patches-3.8/0131-SPI-ralink-add-Ralink-SoC-spi-driver.patch new file mode 100644 index 0000000000..8217b48318 --- /dev/null +++ b/target/linux/ramips/patches-3.8/0131-SPI-ralink-add-Ralink-SoC-spi-driver.patch @@ -0,0 +1,515 @@ +From 32c1cff4c75925a0bbd305e85ed4adb30140cd42 Mon Sep 17 00:00:00 2001 +From: John Crispin +Date: Mon, 22 Apr 2013 23:16:18 +0200 +Subject: [PATCH 131/137] SPI: ralink: add Ralink SoC spi driver + +Add the driver needed to make SPI work on Ralink SoC. + +Signed-off-by: John Crispin +--- + drivers/spi/Kconfig | 6 + + drivers/spi/Makefile | 1 + + drivers/spi/spi-ralink.c | 472 ++++++++++++++++++++++++++++++++++++++++++++++ + 3 files changed, 479 insertions(+) + create mode 100644 drivers/spi/spi-ralink.c + +--- a/drivers/spi/Kconfig ++++ b/drivers/spi/Kconfig +@@ -324,6 +324,12 @@ config SPI_RSPI + help + SPI driver for Renesas RSPI blocks. + ++config SPI_RALINK ++ tristate "Ralink RT288x/RT305x/RT3662 SPI Controller" ++ depends on (SOC_RT288X || SOC_RT305X || SOC_RT3883) ++ help ++ This selects a driver for the Ralink RT288x/RT305x SPI Controller. ++ + config SPI_S3C24XX + tristate "Samsung S3C24XX series SPI" + depends on ARCH_S3C24XX && EXPERIMENTAL +--- a/drivers/spi/Makefile ++++ b/drivers/spi/Makefile +@@ -51,6 +51,7 @@ obj-$(CONFIG_SPI_PPC4xx) += spi-ppc4xx. + obj-$(CONFIG_SPI_PXA2XX) += spi-pxa2xx.o + obj-$(CONFIG_SPI_PXA2XX_PCI) += spi-pxa2xx-pci.o + obj-$(CONFIG_SPI_RSPI) += spi-rspi.o ++obj-$(CONFIG_SPI_RALINK) += spi-ralink.o + obj-$(CONFIG_SPI_S3C24XX) += spi-s3c24xx-hw.o + spi-s3c24xx-hw-y := spi-s3c24xx.o + spi-s3c24xx-hw-$(CONFIG_SPI_S3C24XX_FIQ) += spi-s3c24xx-fiq.o +--- /dev/null ++++ b/drivers/spi/spi-ralink.c +@@ -0,0 +1,472 @@ ++/* ++ * spi-ralink.c -- Ralink RT288x/RT305x SPI controller driver ++ * ++ * Copyright (C) 2011 Sergiy ++ * Copyright (C) 2011-2013 Gabor Juhos ++ * ++ * Some parts are based on spi-orion.c: ++ * Author: Shadi Ammouri ++ * Copyright (C) 2007-2008 Marvell Ltd. ++ * ++ * This program is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License version 2 as ++ * published by the Free Software Foundation. ++ */ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#define DRIVER_NAME "spi-ralink" ++#define RALINK_NUM_CHIPSELECTS 1 /* only one slave is supported*/ ++#define RALINK_SPI_WAIT_RDY_MAX_LOOP 2000 /* in usec */ ++ ++#define RAMIPS_SPI_STAT 0x00 ++#define RAMIPS_SPI_CFG 0x10 ++#define RAMIPS_SPI_CTL 0x14 ++#define RAMIPS_SPI_DATA 0x20 ++ ++/* SPISTAT register bit field */ ++#define SPISTAT_BUSY BIT(0) ++ ++/* SPICFG register bit field */ ++#define SPICFG_LSBFIRST 0 ++#define SPICFG_MSBFIRST BIT(8) ++#define SPICFG_SPICLKPOL BIT(6) ++#define SPICFG_RXCLKEDGE_FALLING BIT(5) ++#define SPICFG_TXCLKEDGE_FALLING BIT(4) ++#define SPICFG_SPICLK_PRESCALE_MASK 0x7 ++#define SPICFG_SPICLK_DIV2 0 ++#define SPICFG_SPICLK_DIV4 1 ++#define SPICFG_SPICLK_DIV8 2 ++#define SPICFG_SPICLK_DIV16 3 ++#define SPICFG_SPICLK_DIV32 4 ++#define SPICFG_SPICLK_DIV64 5 ++#define SPICFG_SPICLK_DIV128 6 ++#define SPICFG_SPICLK_DISABLE 7 ++ ++/* SPICTL register bit field */ ++#define SPICTL_HIZSDO BIT(3) ++#define SPICTL_STARTWR BIT(2) ++#define SPICTL_STARTRD BIT(1) ++#define SPICTL_SPIENA BIT(0) ++ ++#ifdef DEBUG ++#define spi_debug(args...) printk(args) ++#else ++#define spi_debug(args...) ++#endif ++ ++struct ralink_spi { ++ struct spi_master *master; ++ void __iomem *base; ++ unsigned int sys_freq; ++ unsigned int speed; ++ struct clk *clk; ++}; ++ ++static inline struct ralink_spi *spidev_to_ralink_spi(struct spi_device *spi) ++{ ++ return spi_master_get_devdata(spi->master); ++} ++ ++static inline u32 ralink_spi_read(struct ralink_spi *rs, u32 reg) ++{ ++ return ioread32(rs->base + reg); ++} ++ ++static inline void ralink_spi_write(struct ralink_spi *rs, u32 reg, u32 val) ++{ ++ iowrite32(val, rs->base + reg); ++} ++ ++static inline void ralink_spi_setbits(struct ralink_spi *rs, u32 reg, u32 mask) ++{ ++ void __iomem *addr = rs->base + reg; ++ u32 val; ++ ++ val = ioread32(addr); ++ val |= mask; ++ iowrite32(val, addr); ++} ++ ++static inline void ralink_spi_clrbits(struct ralink_spi *rs, u32 reg, u32 mask) ++{ ++ void __iomem *addr = rs->base + reg; ++ u32 val; ++ ++ val = ioread32(addr); ++ val &= ~mask; ++ iowrite32(val, addr); ++} ++ ++static int ralink_spi_baudrate_set(struct spi_device *spi, unsigned int speed) ++{ ++ struct ralink_spi *rs = spidev_to_ralink_spi(spi); ++ u32 rate; ++ u32 prescale; ++ u32 reg; ++ ++ spi_debug("%s: speed:%u\n", __func__, speed); ++ ++ /* ++ * the supported rates are: 2, 4, 8, ... 128 ++ * round up as we look for equal or less speed ++ */ ++ rate = DIV_ROUND_UP(rs->sys_freq, speed); ++ spi_debug("%s: rate-1:%u\n", __func__, rate); ++ rate = roundup_pow_of_two(rate); ++ spi_debug("%s: rate-2:%u\n", __func__, rate); ++ ++ /* check if requested speed is too small */ ++ if (rate > 128) ++ return -EINVAL; ++ ++ if (rate < 2) ++ rate = 2; ++ ++ /* Convert the rate to SPI clock divisor value. */ ++ prescale = ilog2(rate/2); ++ spi_debug("%s: prescale:%u\n", __func__, prescale); ++ ++ reg = ralink_spi_read(rs, RAMIPS_SPI_CFG); ++ reg = ((reg & ~SPICFG_SPICLK_PRESCALE_MASK) | prescale); ++ ralink_spi_write(rs, RAMIPS_SPI_CFG, reg); ++ rs->speed = speed; ++ return 0; ++} ++ ++/* ++ * called only when no transfer is active on the bus ++ */ ++static int ++ralink_spi_setup_transfer(struct spi_device *spi, struct spi_transfer *t) ++{ ++ struct ralink_spi *rs = spidev_to_ralink_spi(spi); ++ unsigned int speed = spi->max_speed_hz; ++ int rc; ++ unsigned int bits_per_word = 8; ++ ++ if ((t != NULL) && t->speed_hz) ++ speed = t->speed_hz; ++ ++ if ((t != NULL) && t->bits_per_word) ++ bits_per_word = t->bits_per_word; ++ ++ if (rs->speed != speed) { ++ spi_debug("%s: speed_hz:%u\n", __func__, speed); ++ rc = ralink_spi_baudrate_set(spi, speed); ++ if (rc) ++ return rc; ++ } ++ ++ if (bits_per_word != 8) { ++ spi_debug("%s: bad bits_per_word: %u\n", __func__, ++ bits_per_word); ++ return -EINVAL; ++ } ++ ++ return 0; ++} ++ ++static void ralink_spi_set_cs(struct ralink_spi *rs, int enable) ++{ ++ if (enable) ++ ralink_spi_clrbits(rs, RAMIPS_SPI_CTL, SPICTL_SPIENA); ++ else ++ ralink_spi_setbits(rs, RAMIPS_SPI_CTL, SPICTL_SPIENA); ++} ++ ++static inline int ralink_spi_wait_till_ready(struct ralink_spi *rs) ++{ ++ int i; ++ ++ for (i = 0; i < RALINK_SPI_WAIT_RDY_MAX_LOOP; i++) { ++ u32 status; ++ ++ status = ralink_spi_read(rs, RAMIPS_SPI_STAT); ++ if ((status & SPISTAT_BUSY) == 0) ++ return 0; ++ ++ udelay(1); ++ } ++ ++ return -ETIMEDOUT; ++} ++ ++static unsigned int ++ralink_spi_write_read(struct spi_device *spi, struct spi_transfer *xfer) ++{ ++ struct ralink_spi *rs = spidev_to_ralink_spi(spi); ++ unsigned count = 0; ++ u8 *rx = xfer->rx_buf; ++ const u8 *tx = xfer->tx_buf; ++ int err; ++ ++ spi_debug("%s(%d): %s %s\n", __func__, xfer->len, ++ (tx != NULL) ? "tx" : " ", ++ (rx != NULL) ? "rx" : " "); ++ ++ if (tx) { ++ for (count = 0; count < xfer->len; count++) { ++ ralink_spi_write(rs, RAMIPS_SPI_DATA, tx[count]); ++ ralink_spi_setbits(rs, RAMIPS_SPI_CTL, SPICTL_STARTWR); ++ err = ralink_spi_wait_till_ready(rs); ++ if (err) { ++ dev_err(&spi->dev, "TX failed, err=%d\n", err); ++ goto out; ++ } ++ } ++ } ++ ++ if (rx) { ++ for (count = 0; count < xfer->len; count++) { ++ ralink_spi_setbits(rs, RAMIPS_SPI_CTL, SPICTL_STARTRD); ++ err = ralink_spi_wait_till_ready(rs); ++ if (err) { ++ dev_err(&spi->dev, "RX failed, err=%d\n", err); ++ goto out; ++ } ++ rx[count] = (u8) ralink_spi_read(rs, RAMIPS_SPI_DATA); ++ } ++ } ++ ++out: ++ return count; ++} ++ ++static int ralink_spi_transfer_one_message(struct spi_master *master, ++ struct spi_message *m) ++{ ++ struct ralink_spi *rs = spi_master_get_devdata(master); ++ struct spi_device *spi = m->spi; ++ struct spi_transfer *t = NULL; ++ int par_override = 0; ++ int status = 0; ++ int cs_active = 0; ++ ++ /* Load defaults */ ++ status = ralink_spi_setup_transfer(spi, NULL); ++ if (status < 0) ++ goto msg_done; ++ ++ list_for_each_entry(t, &m->transfers, transfer_list) { ++ unsigned int bits_per_word = spi->bits_per_word; ++ ++ if (t->tx_buf == NULL && t->rx_buf == NULL && t->len) { ++ dev_err(&spi->dev, ++ "message rejected: invalid transfer data buffers\n"); ++ status = -EIO; ++ goto msg_done; ++ } ++ ++ if (t->bits_per_word) ++ bits_per_word = t->bits_per_word; ++ ++ if (bits_per_word != 8) { ++ dev_err(&spi->dev, ++ "message rejected: invalid transfer bits_per_word (%d bits)\n", ++ bits_per_word); ++ status = -EIO; ++ goto msg_done; ++ } ++ ++ if (t->speed_hz && t->speed_hz < (rs->sys_freq / 128)) { ++ dev_err(&spi->dev, ++ "message rejected: device min speed (%d Hz) exceeds required transfer speed (%d Hz)\n", ++ (rs->sys_freq / 128), t->speed_hz); ++ status = -EIO; ++ goto msg_done; ++ } ++ ++ if (par_override || t->speed_hz || t->bits_per_word) { ++ par_override = 1; ++ status = ralink_spi_setup_transfer(spi, t); ++ if (status < 0) ++ goto msg_done; ++ if (!t->speed_hz && !t->bits_per_word) ++ par_override = 0; ++ } ++ ++ if (!cs_active) { ++ ralink_spi_set_cs(rs, 1); ++ cs_active = 1; ++ } ++ ++ if (t->len) ++ m->actual_length += ralink_spi_write_read(spi, t); ++ ++ if (t->delay_usecs) ++ udelay(t->delay_usecs); ++ ++ if (t->cs_change) { ++ ralink_spi_set_cs(rs, 0); ++ cs_active = 0; ++ } ++ } ++ ++msg_done: ++ if (cs_active) ++ ralink_spi_set_cs(rs, 0); ++ ++ m->status = status; ++ spi_finalize_current_message(master); ++ ++ return 0; ++} ++ ++static int ralink_spi_setup(struct spi_device *spi) ++{ ++ struct ralink_spi *rs = spidev_to_ralink_spi(spi); ++ ++ if ((spi->max_speed_hz == 0) || ++ (spi->max_speed_hz > (rs->sys_freq / 2))) ++ spi->max_speed_hz = (rs->sys_freq / 2); ++ ++ if (spi->max_speed_hz < (rs->sys_freq / 128)) { ++ dev_err(&spi->dev, "setup: requested speed is too low %d Hz\n", ++ spi->max_speed_hz); ++ return -EINVAL; ++ } ++ ++ if (spi->bits_per_word != 0 && spi->bits_per_word != 8) { ++ dev_err(&spi->dev, ++ "setup: requested bits per words - os wrong %d bpw\n", ++ spi->bits_per_word); ++ return -EINVAL; ++ } ++ ++ if (spi->bits_per_word == 0) ++ spi->bits_per_word = 8; ++ ++ /* ++ * baudrate & width will be set ralink_spi_setup_transfer ++ */ ++ return 0; ++} ++ ++static void ralink_spi_reset(struct ralink_spi *rs) ++{ ++ ralink_spi_write(rs, RAMIPS_SPI_CFG, ++ SPICFG_MSBFIRST | SPICFG_TXCLKEDGE_FALLING | ++ SPICFG_SPICLK_DIV16 | SPICFG_SPICLKPOL); ++ ralink_spi_write(rs, RAMIPS_SPI_CTL, SPICTL_HIZSDO | SPICTL_SPIENA); ++} ++ ++static int ralink_spi_probe(struct platform_device *pdev) ++{ ++ struct spi_master *master; ++ struct ralink_spi *rs; ++ struct resource *r; ++ int status = 0; ++ ++ master = spi_alloc_master(&pdev->dev, sizeof(*rs)); ++ if (master == NULL) { ++ dev_dbg(&pdev->dev, "master allocation failed\n"); ++ return -ENOMEM; ++ } ++ ++ //if (pdev->id != -1) ++ master->bus_num = 0; ++ ++ /* we support only mode 0, and no options */ ++ master->mode_bits = 0; ++ ++ master->setup = ralink_spi_setup; ++ master->transfer_one_message = ralink_spi_transfer_one_message; ++ master->num_chipselect = RALINK_NUM_CHIPSELECTS; ++ master->dev.of_node = pdev->dev.of_node; ++ ++ dev_set_drvdata(&pdev->dev, master); ++ ++ rs = spi_master_get_devdata(master); ++ rs->master = master; ++ ++ rs->clk = clk_get(&pdev->dev, NULL); ++ if (IS_ERR(rs->clk)) { ++ status = PTR_ERR(rs->clk); ++ dev_err(&pdev->dev, "unable to get SYS clock, err=%d\n", ++ status); ++ goto out_put_master; ++ } ++ ++ status = clk_enable(rs->clk); ++ if (status) ++ goto out_put_clk; ++ ++ rs->sys_freq = clk_get_rate(rs->clk); ++ spi_debug("%s: sys_freq: %u\n", __func__, rs->sys_freq); ++ ++ r = platform_get_resource(pdev, IORESOURCE_MEM, 0); ++ if (r == NULL) { ++ status = -ENODEV; ++ goto out_disable_clk; ++ } ++ ++ rs->base = devm_request_and_ioremap(&pdev->dev, r); ++ if (!rs->base) { ++ status = -EADDRNOTAVAIL; ++ goto out_disable_clk; ++ } ++ ++ ralink_spi_reset(rs); ++ ++ status = spi_register_master(master); ++ if (status) ++ goto out_disable_clk; ++ ++ return 0; ++ ++out_disable_clk: ++ clk_disable(rs->clk); ++out_put_clk: ++ clk_put(rs->clk); ++out_put_master: ++ spi_master_put(master); ++ return status; ++} ++ ++static int ralink_spi_remove(struct platform_device *pdev) ++{ ++ struct spi_master *master; ++ struct ralink_spi *rs; ++ ++ master = dev_get_drvdata(&pdev->dev); ++ rs = spi_master_get_devdata(master); ++ ++ clk_disable(rs->clk); ++ clk_put(rs->clk); ++ spi_unregister_master(master); ++ ++ return 0; ++} ++ ++MODULE_ALIAS("platform:" DRIVER_NAME); ++ ++static const struct of_device_id ralink_spi_match[] = { ++ { .compatible = "ralink,rt2880-spi" }, ++ {}, ++}; ++MODULE_DEVICE_TABLE(of, ralink_spi_match); ++ ++static struct platform_driver ralink_spi_driver = { ++ .driver = { ++ .name = DRIVER_NAME, ++ .owner = THIS_MODULE, ++ .of_match_table = ralink_spi_match, ++ }, ++ .probe = ralink_spi_probe, ++ .remove = ralink_spi_remove, ++}; ++ ++module_platform_driver(ralink_spi_driver); ++ ++MODULE_DESCRIPTION("Ralink SPI driver"); ++MODULE_AUTHOR("Sergiy "); ++MODULE_AUTHOR("Gabor Juhos "); ++MODULE_LICENSE("GPL"); diff --git a/target/linux/ramips/patches-3.8/0132-NET-ramips-fix-mdio-bus-support.patch b/target/linux/ramips/patches-3.8/0132-NET-ramips-fix-mdio-bus-support.patch deleted file mode 100644 index eb7badfd52..0000000000 --- a/target/linux/ramips/patches-3.8/0132-NET-ramips-fix-mdio-bus-support.patch +++ /dev/null @@ -1,222 +0,0 @@ ---- a/drivers/net/ethernet/ramips/ramips_main.c -+++ b/drivers/net/ethernet/ramips/ramips_main.c -@@ -28,6 +28,7 @@ - #include - #include - #include -+#include - - #include "ramips_eth.h" - -@@ -406,12 +407,25 @@ ramips_mdio_reset(struct mii_bus *bus) - static int - ramips_mdio_init(struct raeth_priv *re) - { -+ struct device_node *mii_np; - int err; -- int i; -+ -+ mii_np = of_get_child_by_name(re->of_node, "mdio-bus"); -+ if (!mii_np) { -+ dev_err(re->parent, "no %s child node found", "mdio-bus"); -+ return -ENODEV; -+ } -+ -+ if (!of_device_is_available(mii_np)) { -+ err = 0; -+ goto err_put_node; -+ } - - re->mii_bus = mdiobus_alloc(); -- if (re->mii_bus == NULL) -- return -ENOMEM; -+ if (re->mii_bus == NULL) { -+ err = -ENOMEM; -+ goto err_put_node; -+ } - - re->mii_bus->name = "ramips_mdio"; - re->mii_bus->read = ramips_mdio_read; -@@ -422,12 +436,7 @@ ramips_mdio_init(struct raeth_priv *re) - re->mii_bus->parent = re->parent; - - snprintf(re->mii_bus->id, MII_BUS_ID_SIZE, "%s", "ramips_mdio"); -- re->mii_bus->phy_mask = 0; -- -- for (i = 0; i < PHY_MAX_ADDR; i++) -- re->mii_irq[i] = PHY_POLL; -- -- err = mdiobus_register(re->mii_bus); -+ err = of_mdiobus_register(re->mii_bus, mii_np); - if (err) - goto err_free_bus; - -@@ -435,13 +444,20 @@ ramips_mdio_init(struct raeth_priv *re) - - err_free_bus: - kfree(re->mii_bus); -+err_put_node: -+ of_node_put(mii_np); -+ re->mii_bus = NULL; - return err; - } - - static void - ramips_mdio_cleanup(struct raeth_priv *re) - { -+ if (!re->mii_bus) -+ return; -+ - mdiobus_unregister(re->mii_bus); -+ of_node_put(re->mii_bus->dev.of_node); - kfree(re->mii_bus); - } - -@@ -474,106 +490,86 @@ ramips_phy_link_adjust(struct net_device - } - - static int --ramips_phy_connect_multi(struct raeth_priv *re) -+ramips_phy_connect_by_node(struct raeth_priv *re, struct device_node *phy_node) - { -- struct net_device *netdev = re->netdev; -- struct phy_device *phydev = NULL; -- int phy_addr; -- int ret = 0; -- -- for (phy_addr = 0; phy_addr < PHY_MAX_ADDR; phy_addr++) { -- if (!(re->phy_mask & (1 << phy_addr))) -- continue; -- -- if (re->mii_bus->phy_map[phy_addr] == NULL) -- continue; -+ struct phy_device *phydev; -+ int phy_mode; - -- RADEBUG("%s: PHY found at %s, uid=%08x\n", -- netdev->name, -- dev_name(&re->mii_bus->phy_map[phy_addr]->dev), -- re->mii_bus->phy_map[phy_addr]->phy_id); -- -- if (phydev == NULL) -- phydev = re->mii_bus->phy_map[phy_addr]; -- } -- -- if (!phydev) { -- netdev_err(netdev, "no PHY found with phy_mask=%08x\n", -- re->phy_mask); -- return -ENODEV; -+ phy_mode = of_get_phy_mode(re->of_node); -+ if (phy_mode < 0) { -+ dev_err(re->parent, "incorrect phy-mode\n"); -+ return -EINVAL; - } - -- re->phy_dev = phy_connect(netdev, dev_name(&phydev->dev), -- ramips_phy_link_adjust, 0, re->phy_if_mode); -- -- if (IS_ERR(re->phy_dev)) { -- netdev_err(netdev, "could not connect to PHY at %s\n", -- dev_name(&phydev->dev)); -+ phydev = of_phy_connect(re->netdev, phy_node, ramips_phy_link_adjust, -+ 0, phy_mode); -+ if (IS_ERR(phydev)) { -+ dev_err(re->parent, "could not connect to PHY\n"); - return PTR_ERR(re->phy_dev); - } - - phydev->supported &= PHY_GBIT_FEATURES; - phydev->advertising = phydev->supported; - -- RADEBUG("%s: connected to PHY at %s [uid=%08x, driver=%s]\n", -- netdev->name, dev_name(&phydev->dev), -- phydev->phy_id, phydev->drv->name); -+ dev_info(re->parent, -+ "connected to PHY at %s [uid=%08x, driver=%s]\n", -+ dev_name(&phydev->dev), phydev->phy_id, -+ phydev->drv->name); - -+ re->phy_dev = phydev; - re->link = 0; - re->speed = 0; - re->duplex = -1; - re->rx_fc = 0; - re->tx_fc = 0; - -- return ret; -+ return 0; - } - - static int --ramips_phy_connect_fixed(struct raeth_priv *re) -+ramips_phy_connect_fixed(struct raeth_priv *re, const __be32 *link, int size) - { -- if (!re->speed) { -- const __be32 *link; -- int size; -- -- link = of_get_property(re->of_node, -- "ralink,fixed-link", &size); -- if (!link || size != (4 * sizeof(*link))) -- return -ENOENT; -- -- re->speed = be32_to_cpup(link++); -- re->duplex = be32_to_cpup(link++); -- re->tx_fc = be32_to_cpup(link++); -- re->rx_fc = be32_to_cpup(link++); -+ if (size != (4 * sizeof(*link))) { -+ dev_err(re->parent, "invalid fixed-link property\n"); -+ return -EINVAL; - } - -+ re->speed = be32_to_cpup(link++); -+ re->duplex = be32_to_cpup(link++); -+ re->tx_fc = be32_to_cpup(link++); -+ re->rx_fc = be32_to_cpup(link++); -+ - switch (re->speed) { - case SPEED_10: - case SPEED_100: - case SPEED_1000: - break; - default: -- netdev_err(re->netdev, "invalid speed specified\n"); -+ dev_err(re->parent, "invalid link speed: %d\n", re->speed); - return -EINVAL; - } - -- pr_info("%s: using fixed link parameters\n", re->netdev->name); -+ dev_info(re->parent, "using fixed link parameters\n"); - return 0; - } - - static int - ramips_phy_connect(struct raeth_priv *re) - { -- const __be32 *mask; -- -- mask = of_get_property(re->of_node, "ralink,phy-mask", NULL); -- re->phy_if_mode = of_get_phy_mode(re->of_node); -- -- if (!re->phy_if_mode || !mask) -- return ramips_phy_connect_fixed(re); -- -- re->phy_mask = be32_to_cpup(mask); -- return ramips_phy_connect_multi(re); -+ struct device_node *phy_node; -+ const __be32 *p32; -+ int size; -+ -+ phy_node = of_parse_phandle(re->of_node, "phy-handle", 0); -+ if (phy_node) -+ return ramips_phy_connect_by_node(re, phy_node); -+ -+ p32 = of_get_property(re->of_node, "ralink,fixed-link", &size); -+ if (p32) -+ return ramips_phy_connect_fixed(re, p32, size); - -+ dev_err(re->parent, "unable to get connection type\n"); -+ return -EINVAL; - } - - static void diff --git a/target/linux/ramips/patches-3.8/0132-serial-of-allow-au1x00-and-rt288x-to-load-from-OF.patch b/target/linux/ramips/patches-3.8/0132-serial-of-allow-au1x00-and-rt288x-to-load-from-OF.patch new file mode 100644 index 0000000000..bff0799ed2 --- /dev/null +++ b/target/linux/ramips/patches-3.8/0132-serial-of-allow-au1x00-and-rt288x-to-load-from-OF.patch @@ -0,0 +1,27 @@ +From 15bcdbd78abacbe0986a1904d2e2b5dcfe780b5b Mon Sep 17 00:00:00 2001 +From: John Crispin +Date: Tue, 22 Jan 2013 16:01:07 +0100 +Subject: [PATCH 132/137] serial: of: allow au1x00 and rt288x to load from OF + +In order to make serial_8250 loadable via OF on Au1x00 and Ralink WiSoC we need +to default the iotype to UPIO_AU. + +Signed-off-by: John Crispin +--- + drivers/tty/serial/of_serial.c | 5 ++++- + 1 file changed, 4 insertions(+), 1 deletion(-) + +--- a/drivers/tty/serial/of_serial.c ++++ b/drivers/tty/serial/of_serial.c +@@ -97,7 +97,10 @@ static int of_platform_serial_setup(stru + port->regshift = prop; + + port->irq = irq_of_parse_and_map(np, 0); +- port->iotype = UPIO_MEM; ++ if (of_device_is_compatible(np, "ralink,rt2880-uart")) ++ port->iotype = UPIO_AU; ++ else ++ port->iotype = UPIO_MEM; + if (of_property_read_u32(np, "reg-io-width", &prop) == 0) { + switch (prop) { + case 1: diff --git a/target/linux/ramips/patches-3.8/0133-MIPS-ralink-make-early_printk-work-on-RT2880.patch b/target/linux/ramips/patches-3.8/0133-MIPS-ralink-make-early_printk-work-on-RT2880.patch deleted file mode 100644 index 71dad9e0c6..0000000000 --- a/target/linux/ramips/patches-3.8/0133-MIPS-ralink-make-early_printk-work-on-RT2880.patch +++ /dev/null @@ -1,26 +0,0 @@ -From 3f32be8f012fb5476ea916e583e584cccc632a84 Mon Sep 17 00:00:00 2001 -From: John Crispin -Date: Tue, 9 Apr 2013 18:31:15 +0200 -Subject: [PATCH V2 08/16] MIPS: ralink: make early_printk work on RT2880 - -RT2880 has a different location for the early serial port. - -Signed-off-by: John Crispin ---- - arch/mips/ralink/early_printk.c | 4 ++++ - 1 file changed, 4 insertions(+) - ---- a/arch/mips/ralink/early_printk.c -+++ b/arch/mips/ralink/early_printk.c -@@ -11,7 +11,11 @@ - - #include - -+#ifdef CONFIG_SOC_RT288X -+#define EARLY_UART_BASE 0x300c00 -+#else - #define EARLY_UART_BASE 0x10000c00 -+#endif - - #define UART_REG_RX 0x00 - #define UART_REG_TX 0x04 diff --git a/target/linux/ramips/patches-3.8/0133-serial-ralink-adds-mt7620-serial.patch b/target/linux/ramips/patches-3.8/0133-serial-ralink-adds-mt7620-serial.patch new file mode 100644 index 0000000000..1fce223ddb --- /dev/null +++ b/target/linux/ramips/patches-3.8/0133-serial-ralink-adds-mt7620-serial.patch @@ -0,0 +1,23 @@ +From 6471ee7bbf3f8b70267ba1dc93f067e18803c246 Mon Sep 17 00:00:00 2001 +From: John Crispin +Date: Fri, 15 Mar 2013 18:16:01 +0100 +Subject: [PATCH 133/137] serial: ralink: adds mt7620 serial + +Add the config symbol for Mediatek7620 SoC to SERIAL_8250_RT288X + +Signed-off-by: John Crispin +--- + drivers/tty/serial/8250/Kconfig | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/drivers/tty/serial/8250/Kconfig ++++ b/drivers/tty/serial/8250/Kconfig +@@ -280,7 +280,7 @@ config SERIAL_8250_EM + + config SERIAL_8250_RT288X + bool "Ralink RT288x/RT305x/RT3662/RT3883 serial port support" +- depends on SERIAL_8250 && (SOC_RT288X || SOC_RT305X || SOC_RT3883) ++ depends on SERIAL_8250 && (SOC_RT288X || SOC_RT305X || SOC_RT3883 || SOC_MT7620) + help + If you have a Ralink RT288x/RT305x SoC based board and want to use the + serial port, say Y to this option. The driver can handle up to 2 serial diff --git a/target/linux/ramips/patches-3.8/0134-PCI-MIPS-adds-rt2880-pci-support.patch b/target/linux/ramips/patches-3.8/0134-PCI-MIPS-adds-rt2880-pci-support.patch new file mode 100644 index 0000000000..70758f1422 --- /dev/null +++ b/target/linux/ramips/patches-3.8/0134-PCI-MIPS-adds-rt2880-pci-support.patch @@ -0,0 +1,319 @@ +From 55e9ae6a23cb799b7c1d402e1cfda11a6bd1e86e Mon Sep 17 00:00:00 2001 +From: John Crispin +Date: Thu, 21 Mar 2013 18:27:29 +0100 +Subject: [PATCH 134/137] PCI: MIPS: adds rt2880 pci support + +Add support for the pci found on the rt2880 SoC. + +Signed-off-by: John Crispin +--- + arch/mips/pci/Makefile | 1 + + arch/mips/pci/pci-rt2880.c | 281 ++++++++++++++++++++++++++++++++++++++++++++ + arch/mips/ralink/Kconfig | 1 + + 3 files changed, 283 insertions(+) + create mode 100644 arch/mips/pci/pci-rt2880.c + +--- a/arch/mips/pci/Makefile ++++ b/arch/mips/pci/Makefile +@@ -42,6 +42,7 @@ obj-$(CONFIG_SIBYTE_BCM1x80) += pci-bcm1 + 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_RT2880) += pci-rt2880.o + obj-$(CONFIG_TANBAC_TB0219) += fixup-tb0219.o + obj-$(CONFIG_TANBAC_TB0226) += fixup-tb0226.o + obj-$(CONFIG_TANBAC_TB0287) += fixup-tb0287.o +--- /dev/null ++++ b/arch/mips/pci/pci-rt2880.c +@@ -0,0 +1,281 @@ ++/* ++ * Ralink RT288x SoC PCI register definitions ++ * ++ * Copyright (C) 2009 John Crispin ++ * Copyright (C) 2009 Gabor Juhos ++ * ++ * Parts of this file are based on Ralink's 2.6.21 BSP ++ * ++ * This program is free software; you can redistribute it and/or modify it ++ * under the terms of the GNU General Public License version 2 as published ++ * by the Free Software Foundation. ++ */ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#include ++ ++#define RT2880_PCI_BASE 0x00440000 ++#define RT288X_CPU_IRQ_PCI 4 ++ ++#define RT2880_PCI_MEM_BASE 0x20000000 ++#define RT2880_PCI_MEM_SIZE 0x10000000 ++#define RT2880_PCI_IO_BASE 0x00460000 ++#define RT2880_PCI_IO_SIZE 0x00010000 ++ ++#define RT2880_PCI_REG_PCICFG_ADDR 0x00 ++#define RT2880_PCI_REG_PCIMSK_ADDR 0x0c ++#define RT2880_PCI_REG_BAR0SETUP_ADDR 0x10 ++#define RT2880_PCI_REG_IMBASEBAR0_ADDR 0x18 ++#define RT2880_PCI_REG_CONFIG_ADDR 0x20 ++#define RT2880_PCI_REG_CONFIG_DATA 0x24 ++#define RT2880_PCI_REG_MEMBASE 0x28 ++#define RT2880_PCI_REG_IOBASE 0x2c ++#define RT2880_PCI_REG_ID 0x30 ++#define RT2880_PCI_REG_CLASS 0x34 ++#define RT2880_PCI_REG_SUBID 0x38 ++#define RT2880_PCI_REG_ARBCTL 0x80 ++ ++static void __iomem *rt2880_pci_base; ++static DEFINE_SPINLOCK(rt2880_pci_lock); ++ ++static u32 rt2880_pci_reg_read(u32 reg) ++{ ++ return readl(rt2880_pci_base + reg); ++} ++ ++static void rt2880_pci_reg_write(u32 val, u32 reg) ++{ ++ writel(val, rt2880_pci_base + reg); ++} ++ ++static inline u32 rt2880_pci_get_cfgaddr(unsigned int bus, unsigned int slot, ++ unsigned int func, unsigned int where) ++{ ++ return ((bus << 16) | (slot << 11) | (func << 8) | (where & 0xfc) | ++ 0x80000000); ++} ++ ++static int rt2880_pci_config_read(struct pci_bus *bus, unsigned int devfn, ++ int where, int size, u32 *val) ++{ ++ unsigned long flags; ++ u32 address; ++ u32 data; ++ ++ address = rt2880_pci_get_cfgaddr(bus->number, PCI_SLOT(devfn), ++ PCI_FUNC(devfn), where); ++ ++ spin_lock_irqsave(&rt2880_pci_lock, flags); ++ rt2880_pci_reg_write(address, RT2880_PCI_REG_CONFIG_ADDR); ++ data = rt2880_pci_reg_read(RT2880_PCI_REG_CONFIG_DATA); ++ spin_unlock_irqrestore(&rt2880_pci_lock, flags); ++ ++ switch (size) { ++ case 1: ++ *val = (data >> ((where & 3) << 3)) & 0xff; ++ break; ++ case 2: ++ *val = (data >> ((where & 3) << 3)) & 0xffff; ++ break; ++ case 4: ++ *val = data; ++ break; ++ } ++ ++ return PCIBIOS_SUCCESSFUL; ++} ++ ++static int rt2880_pci_config_write(struct pci_bus *bus, unsigned int devfn, ++ int where, int size, u32 val) ++{ ++ unsigned long flags; ++ u32 address; ++ u32 data; ++ ++ address = rt2880_pci_get_cfgaddr(bus->number, PCI_SLOT(devfn), ++ PCI_FUNC(devfn), where); ++ ++ spin_lock_irqsave(&rt2880_pci_lock, flags); ++ rt2880_pci_reg_write(address, RT2880_PCI_REG_CONFIG_ADDR); ++ data = rt2880_pci_reg_read(RT2880_PCI_REG_CONFIG_DATA); ++ ++ switch (size) { ++ case 1: ++ data = (data & ~(0xff << ((where & 3) << 3))) | ++ (val << ((where & 3) << 3)); ++ break; ++ case 2: ++ data = (data & ~(0xffff << ((where & 3) << 3))) | ++ (val << ((where & 3) << 3)); ++ break; ++ case 4: ++ data = val; ++ break; ++ } ++ ++ rt2880_pci_reg_write(data, RT2880_PCI_REG_CONFIG_DATA); ++ spin_unlock_irqrestore(&rt2880_pci_lock, flags); ++ ++ return PCIBIOS_SUCCESSFUL; ++} ++ ++static struct pci_ops rt2880_pci_ops = { ++ .read = rt2880_pci_config_read, ++ .write = rt2880_pci_config_write, ++}; ++ ++static struct resource rt2880_pci_mem_resource = { ++ .name = "PCI MEM space", ++ .start = RT2880_PCI_MEM_BASE, ++ .end = RT2880_PCI_MEM_BASE + RT2880_PCI_MEM_SIZE - 1, ++ .flags = IORESOURCE_MEM, ++}; ++ ++static struct resource rt2880_pci_io_resource = { ++ .name = "PCI IO space", ++ .start = RT2880_PCI_IO_BASE, ++ .end = RT2880_PCI_IO_BASE + RT2880_PCI_IO_SIZE - 1, ++ .flags = IORESOURCE_IO, ++}; ++ ++static struct pci_controller rt2880_pci_controller = { ++ .pci_ops = &rt2880_pci_ops, ++ .mem_resource = &rt2880_pci_mem_resource, ++ .io_resource = &rt2880_pci_io_resource, ++}; ++ ++static inline u32 rt2880_pci_read_u32(unsigned long reg) ++{ ++ unsigned long flags; ++ u32 address; ++ u32 ret; ++ ++ address = rt2880_pci_get_cfgaddr(0, 0, 0, reg); ++ ++ spin_lock_irqsave(&rt2880_pci_lock, flags); ++ rt2880_pci_reg_write(address, RT2880_PCI_REG_CONFIG_ADDR); ++ ret = rt2880_pci_reg_read(RT2880_PCI_REG_CONFIG_DATA); ++ spin_unlock_irqrestore(&rt2880_pci_lock, flags); ++ ++ return ret; ++} ++ ++static inline void rt2880_pci_write_u32(unsigned long reg, u32 val) ++{ ++ unsigned long flags; ++ u32 address; ++ ++ address = rt2880_pci_get_cfgaddr(0, 0, 0, reg); ++ ++ spin_lock_irqsave(&rt2880_pci_lock, flags); ++ rt2880_pci_reg_write(address, RT2880_PCI_REG_CONFIG_ADDR); ++ rt2880_pci_reg_write(val, RT2880_PCI_REG_CONFIG_DATA); ++ spin_unlock_irqrestore(&rt2880_pci_lock, flags); ++} ++ ++int __init pcibios_map_irq(const struct pci_dev *dev, u8 slot, u8 pin) ++{ ++ u16 cmd; ++ int irq = -1; ++ ++ if (dev->bus->number != 0) ++ return irq; ++ ++ switch (PCI_SLOT(dev->devfn)) { ++ case 0x00: ++ rt2880_pci_write_u32(PCI_BASE_ADDRESS_0, 0x08000000); ++ (void) rt2880_pci_read_u32(PCI_BASE_ADDRESS_0); ++ break; ++ case 0x11: ++ irq = RT288X_CPU_IRQ_PCI; ++ break; ++ default: ++ printk("%s:%s[%d] trying to alloc unknown pci irq\n", ++ __FILE__, __func__, __LINE__); ++ BUG(); ++ break; ++ } ++ ++ pci_write_config_byte((struct pci_dev*)dev, PCI_CACHE_LINE_SIZE, 0x14); ++ pci_write_config_byte((struct pci_dev*)dev, PCI_LATENCY_TIMER, 0xFF); ++ pci_read_config_word((struct pci_dev*)dev, PCI_COMMAND, &cmd); ++ cmd |= PCI_COMMAND_MASTER | PCI_COMMAND_IO | PCI_COMMAND_MEMORY | ++ PCI_COMMAND_INVALIDATE | PCI_COMMAND_FAST_BACK | ++ PCI_COMMAND_SERR | PCI_COMMAND_WAIT | PCI_COMMAND_PARITY; ++ pci_write_config_word((struct pci_dev*)dev, PCI_COMMAND, cmd); ++ pci_write_config_byte((struct pci_dev*)dev, PCI_INTERRUPT_LINE, ++ dev->irq); ++ return irq; ++} ++ ++static int rt288x_pci_probe(struct platform_device *pdev) ++{ ++ void __iomem *io_map_base; ++ int i; ++ ++ rt2880_pci_base = ioremap_nocache(RT2880_PCI_BASE, PAGE_SIZE); ++ ++ io_map_base = ioremap(RT2880_PCI_IO_BASE, RT2880_PCI_IO_SIZE); ++ rt2880_pci_controller.io_map_base = (unsigned long) io_map_base; ++ set_io_port_base((unsigned long) io_map_base); ++ ++ ioport_resource.start = RT2880_PCI_IO_BASE; ++ ioport_resource.end = RT2880_PCI_IO_BASE + RT2880_PCI_IO_SIZE - 1; ++ ++ rt2880_pci_reg_write(0, RT2880_PCI_REG_PCICFG_ADDR); ++ for(i = 0; i < 0xfffff; i++) {} ++ ++ rt2880_pci_reg_write(0x79, RT2880_PCI_REG_ARBCTL); ++ rt2880_pci_reg_write(0x07FF0001, RT2880_PCI_REG_BAR0SETUP_ADDR); ++ rt2880_pci_reg_write(RT2880_PCI_MEM_BASE, RT2880_PCI_REG_MEMBASE); ++ rt2880_pci_reg_write(RT2880_PCI_IO_BASE, RT2880_PCI_REG_IOBASE); ++ rt2880_pci_reg_write(0x08000000, RT2880_PCI_REG_IMBASEBAR0_ADDR); ++ rt2880_pci_reg_write(0x08021814, RT2880_PCI_REG_ID); ++ rt2880_pci_reg_write(0x00800001, RT2880_PCI_REG_CLASS); ++ rt2880_pci_reg_write(0x28801814, RT2880_PCI_REG_SUBID); ++ rt2880_pci_reg_write(0x000c0000, RT2880_PCI_REG_PCIMSK_ADDR); ++ ++ rt2880_pci_write_u32(PCI_BASE_ADDRESS_0, 0x08000000); ++ (void) rt2880_pci_read_u32(PCI_BASE_ADDRESS_0); ++ ++ register_pci_controller(&rt2880_pci_controller); ++ return 0; ++} ++ ++int pcibios_plat_dev_init(struct pci_dev *dev) ++{ ++ return 0; ++} ++ ++static const struct of_device_id rt288x_pci_match[] = { ++ { .compatible = "ralink,rt288x-pci" }, ++ {}, ++}; ++MODULE_DEVICE_TABLE(of, rt288x_pci_match); ++ ++static struct platform_driver rt288x_pci_driver = { ++ .probe = rt288x_pci_probe, ++ .driver = { ++ .name = "rt288x-pci", ++ .owner = THIS_MODULE, ++ .of_match_table = rt288x_pci_match, ++ }, ++}; ++ ++int __init pcibios_init(void) ++{ ++ int ret = platform_driver_register(&rt288x_pci_driver); ++ if (ret) ++ pr_info("rt288x-pci: Error registering platform driver!"); ++ return ret; ++} ++ ++arch_initcall(pcibios_init); +--- a/arch/mips/ralink/Kconfig ++++ b/arch/mips/ralink/Kconfig +@@ -8,6 +8,7 @@ choice + + config SOC_RT288X + bool "RT288x" ++ select HW_HAS_PCI + + config SOC_RT305X + bool "RT305x" diff --git a/target/linux/ramips/patches-3.8/0135-PCI-MIPS-adds-rt3883-pci-support.patch b/target/linux/ramips/patches-3.8/0135-PCI-MIPS-adds-rt3883-pci-support.patch new file mode 100644 index 0000000000..9c4ca82404 --- /dev/null +++ b/target/linux/ramips/patches-3.8/0135-PCI-MIPS-adds-rt3883-pci-support.patch @@ -0,0 +1,678 @@ +From 2a5dccdb00d85a6ad6111d7a2b13f9f4fae35838 Mon Sep 17 00:00:00 2001 +From: John Crispin +Date: Thu, 21 Mar 2013 17:34:08 +0100 +Subject: [PATCH 135/137] PCI: MIPS: adds rt3883 pci support + +Add support for the pcie found on the rt3883 SoC. + +Signed-off-by: John Crispin +--- + arch/mips/pci/Makefile | 1 + + arch/mips/pci/pci-rt3883.c | 640 ++++++++++++++++++++++++++++++++++++++++++++ + arch/mips/ralink/Kconfig | 1 + + 3 files changed, 642 insertions(+) + create mode 100644 arch/mips/pci/pci-rt3883.c + +--- a/arch/mips/pci/Makefile ++++ b/arch/mips/pci/Makefile +@@ -43,6 +43,7 @@ obj-$(CONFIG_SNI_RM) += fixup-sni.o ops + obj-$(CONFIG_LANTIQ) += fixup-lantiq.o + obj-$(CONFIG_PCI_LANTIQ) += pci-lantiq.o ops-lantiq.o + obj-$(CONFIG_SOC_RT2880) += pci-rt2880.o ++obj-$(CONFIG_SOC_RT3883) += pci-rt3883.o + obj-$(CONFIG_TANBAC_TB0219) += fixup-tb0219.o + obj-$(CONFIG_TANBAC_TB0226) += fixup-tb0226.o + obj-$(CONFIG_TANBAC_TB0287) += fixup-tb0287.o +--- /dev/null ++++ b/arch/mips/pci/pci-rt3883.c +@@ -0,0 +1,640 @@ ++/* ++ * Ralink RT3662/RT3883 SoC PCI support ++ * ++ * Copyright (C) 2011-2013 Gabor Juhos ++ * ++ * Parts of this file are based on Ralink's 2.6.21 BSP ++ * ++ * This program is free software; you can redistribute it and/or modify it ++ * under the terms of the GNU General Public License version 2 as published ++ * by the Free Software Foundation. ++ */ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#include ++#include ++ ++#define RT3883_MEMORY_BASE 0x00000000 ++#define RT3883_MEMORY_SIZE 0x02000000 ++ ++#define RT3883_PCI_REG_PCICFG 0x00 ++#define RT3883_PCICFG_P2P_BR_DEVNUM_M 0xf ++#define RT3883_PCICFG_P2P_BR_DEVNUM_S 16 ++#define RT3883_PCICFG_PCIRST BIT(1) ++#define RT3883_PCI_REG_PCIRAW 0x04 ++#define RT3883_PCI_REG_PCIINT 0x08 ++#define RT3883_PCI_REG_PCIENA 0x0c ++ ++#define RT3883_PCI_REG_CFGADDR 0x20 ++#define RT3883_PCI_REG_CFGDATA 0x24 ++#define RT3883_PCI_REG_MEMBASE 0x28 ++#define RT3883_PCI_REG_IOBASE 0x2c ++#define RT3883_PCI_REG_ARBCTL 0x80 ++ ++#define RT3883_PCI_REG_BASE(_x) (0x1000 + (_x) * 0x1000) ++#define RT3883_PCI_REG_BAR0SETUP(_x) (RT3883_PCI_REG_BASE((_x)) + 0x10) ++#define RT3883_PCI_REG_IMBASEBAR0(_x) (RT3883_PCI_REG_BASE((_x)) + 0x18) ++#define RT3883_PCI_REG_ID(_x) (RT3883_PCI_REG_BASE((_x)) + 0x30) ++#define RT3883_PCI_REG_CLASS(_x) (RT3883_PCI_REG_BASE((_x)) + 0x34) ++#define RT3883_PCI_REG_SUBID(_x) (RT3883_PCI_REG_BASE((_x)) + 0x38) ++#define RT3883_PCI_REG_STATUS(_x) (RT3883_PCI_REG_BASE((_x)) + 0x50) ++ ++#define RT3883_PCI_MODE_NONE 0 ++#define RT3883_PCI_MODE_PCI BIT(0) ++#define RT3883_PCI_MODE_PCIE BIT(1) ++#define RT3883_PCI_MODE_BOTH (RT3883_PCI_MODE_PCI | RT3883_PCI_MODE_PCIE) ++ ++#define RT3883_PCI_IRQ_COUNT 32 ++ ++#define RT3883_P2P_BR_DEVNUM 1 ++ ++struct rt3883_pci_controller { ++ void __iomem *base; ++ spinlock_t lock; ++ ++ struct irq_domain *irq_domain; ++ ++ struct pci_controller pci_controller; ++ struct resource io_res; ++ struct resource mem_res; ++ ++ bool pcie_ready; ++ unsigned char p2p_devnum; ++}; ++ ++static inline struct rt3883_pci_controller * ++pci_bus_to_rt3883_controller(struct pci_bus *bus) ++{ ++ struct pci_controller *hose; ++ ++ hose = (struct pci_controller *) bus->sysdata; ++ return container_of(hose, struct rt3883_pci_controller, pci_controller); ++} ++ ++static inline u32 rt3883_pci_r32(struct rt3883_pci_controller *rpc, ++ unsigned reg) ++{ ++ return ioread32(rpc->base + reg); ++} ++ ++static inline void rt3883_pci_w32(struct rt3883_pci_controller *rpc, ++ u32 val, unsigned reg) ++{ ++ iowrite32(val, rpc->base + reg); ++} ++ ++static inline u32 rt3883_pci_get_cfgaddr(unsigned int bus, unsigned int slot, ++ unsigned int func, unsigned int where) ++{ ++ return ((bus << 16) | (slot << 11) | (func << 8) | (where & 0xfc) | ++ 0x80000000); ++} ++ ++static u32 rt3883_pci_read_cfg32(struct rt3883_pci_controller *rpc, ++ unsigned bus, unsigned slot, ++ unsigned func, unsigned reg) ++{ ++ unsigned long flags; ++ u32 address; ++ u32 ret; ++ ++ address = rt3883_pci_get_cfgaddr(bus, slot, func, reg); ++ ++ spin_lock_irqsave(&rpc->lock, flags); ++ rt3883_pci_w32(rpc, address, RT3883_PCI_REG_CFGADDR); ++ ret = rt3883_pci_r32(rpc, RT3883_PCI_REG_CFGDATA); ++ spin_unlock_irqrestore(&rpc->lock, flags); ++ ++ return ret; ++} ++ ++static void rt3883_pci_write_cfg32(struct rt3883_pci_controller *rpc, ++ unsigned bus, unsigned slot, ++ unsigned func, unsigned reg, u32 val) ++{ ++ unsigned long flags; ++ u32 address; ++ ++ address = rt3883_pci_get_cfgaddr(bus, slot, func, reg); ++ ++ spin_lock_irqsave(&rpc->lock, flags); ++ rt3883_pci_w32(rpc, address, RT3883_PCI_REG_CFGADDR); ++ rt3883_pci_w32(rpc, val, RT3883_PCI_REG_CFGDATA); ++ spin_unlock_irqrestore(&rpc->lock, flags); ++} ++ ++static void rt3883_pci_irq_handler(unsigned int irq, struct irq_desc *desc) ++{ ++ struct rt3883_pci_controller *rpc; ++ u32 pending; ++ ++ rpc = irq_get_handler_data(irq); ++ ++ pending = rt3883_pci_r32(rpc, RT3883_PCI_REG_PCIINT) & ++ rt3883_pci_r32(rpc, RT3883_PCI_REG_PCIENA); ++ ++ if (!pending) { ++ spurious_interrupt(); ++ return; ++ } ++ ++ while (pending) { ++ unsigned bit = __ffs(pending); ++ ++ irq = irq_find_mapping(rpc->irq_domain, bit); ++ generic_handle_irq(irq); ++ ++ pending &= ~BIT(bit); ++ } ++} ++ ++static void rt3883_pci_irq_unmask(struct irq_data *d) ++{ ++ struct rt3883_pci_controller *rpc; ++ u32 t; ++ ++ rpc = irq_data_get_irq_chip_data(d); ++ ++ t = rt3883_pci_r32(rpc, RT3883_PCI_REG_PCIENA); ++ rt3883_pci_w32(rpc, t | BIT(d->hwirq), RT3883_PCI_REG_PCIENA); ++ /* flush write */ ++ rt3883_pci_r32(rpc, RT3883_PCI_REG_PCIENA); ++} ++ ++static void rt3883_pci_irq_mask(struct irq_data *d) ++{ ++ struct rt3883_pci_controller *rpc; ++ u32 t; ++ ++ rpc = irq_data_get_irq_chip_data(d); ++ ++ t = rt3883_pci_r32(rpc, RT3883_PCI_REG_PCIENA); ++ rt3883_pci_w32(rpc, t & ~BIT(d->hwirq), RT3883_PCI_REG_PCIENA); ++ /* flush write */ ++ rt3883_pci_r32(rpc, RT3883_PCI_REG_PCIENA); ++} ++ ++static struct irq_chip rt3883_pci_irq_chip = { ++ .name = "RT3883 PCI", ++ .irq_mask = rt3883_pci_irq_mask, ++ .irq_unmask = rt3883_pci_irq_unmask, ++ .irq_mask_ack = rt3883_pci_irq_mask, ++}; ++ ++static int rt3883_pci_irq_map(struct irq_domain *d, unsigned int irq, ++ irq_hw_number_t hw) ++{ ++ irq_set_chip_and_handler(irq, &rt3883_pci_irq_chip, handle_level_irq); ++ irq_set_chip_data(irq, d->host_data); ++ ++ return 0; ++} ++ ++static const struct irq_domain_ops rt3883_pci_irq_domain_ops = { ++ .map = rt3883_pci_irq_map, ++ .xlate = irq_domain_xlate_onecell, ++}; ++ ++static int rt3883_pci_irq_init(struct device *dev, ++ struct rt3883_pci_controller *rpc) ++{ ++ struct device_node *np = dev->of_node; ++ struct device_node *intc_np; ++ int irq; ++ int err; ++ ++ intc_np = of_get_child_by_name(np, "interrupt-controller"); ++ if (!intc_np) { ++ dev_err(dev, "no %s child node found", "interrupt-controller"); ++ return -ENODEV; ++ } ++ ++ irq = irq_of_parse_and_map(intc_np, 0); ++ if (irq == 0) { ++ dev_err(dev, "%s has no IRQ", of_node_full_name(intc_np)); ++ err = -EINVAL; ++ goto err_put_intc; ++ } ++ ++ /* disable all interrupts */ ++ rt3883_pci_w32(rpc, 0, RT3883_PCI_REG_PCIENA); ++ ++ rpc->irq_domain = ++ irq_domain_add_linear(intc_np, RT3883_PCI_IRQ_COUNT, ++ &rt3883_pci_irq_domain_ops, ++ rpc); ++ if (!rpc->irq_domain) { ++ dev_err(dev, "unable to add IRQ domain\n"); ++ err = -ENODEV; ++ goto err_put_intc; ++ } ++ ++ irq_set_handler_data(irq, rpc); ++ irq_set_chained_handler(irq, rt3883_pci_irq_handler); ++ ++ return 0; ++ ++err_put_intc: ++ of_node_put(intc_np); ++ return err; ++} ++ ++static int rt3883_pci_config_read(struct pci_bus *bus, unsigned int devfn, ++ int where, int size, u32 *val) ++{ ++ struct rt3883_pci_controller *rpc; ++ unsigned long flags; ++ u32 address; ++ u32 data; ++ ++ rpc = pci_bus_to_rt3883_controller(bus); ++ ++ if (!rpc->pcie_ready && bus->number == 1) ++ return PCIBIOS_DEVICE_NOT_FOUND; ++ ++ address = rt3883_pci_get_cfgaddr(bus->number, PCI_SLOT(devfn), ++ PCI_FUNC(devfn), where); ++ ++ spin_lock_irqsave(&rpc->lock, flags); ++ rt3883_pci_w32(rpc, address, RT3883_PCI_REG_CFGADDR); ++ data = rt3883_pci_r32(rpc, RT3883_PCI_REG_CFGDATA); ++ spin_unlock_irqrestore(&rpc->lock, flags); ++ ++ switch (size) { ++ case 1: ++ *val = (data >> ((where & 3) << 3)) & 0xff; ++ break; ++ case 2: ++ *val = (data >> ((where & 3) << 3)) & 0xffff; ++ break; ++ case 4: ++ *val = data; ++ break; ++ } ++ ++ return PCIBIOS_SUCCESSFUL; ++} ++ ++static int rt3883_pci_config_write(struct pci_bus *bus, unsigned int devfn, ++ int where, int size, u32 val) ++{ ++ struct rt3883_pci_controller *rpc; ++ unsigned long flags; ++ u32 address; ++ u32 data; ++ ++ rpc = pci_bus_to_rt3883_controller(bus); ++ ++ if (!rpc->pcie_ready && bus->number == 1) ++ return PCIBIOS_DEVICE_NOT_FOUND; ++ ++ address = rt3883_pci_get_cfgaddr(bus->number, PCI_SLOT(devfn), ++ PCI_FUNC(devfn), where); ++ ++ spin_lock_irqsave(&rpc->lock, flags); ++ rt3883_pci_w32(rpc, address, RT3883_PCI_REG_CFGADDR); ++ data = rt3883_pci_r32(rpc, RT3883_PCI_REG_CFGDATA); ++ ++ switch (size) { ++ case 1: ++ data = (data & ~(0xff << ((where & 3) << 3))) | ++ (val << ((where & 3) << 3)); ++ break; ++ case 2: ++ data = (data & ~(0xffff << ((where & 3) << 3))) | ++ (val << ((where & 3) << 3)); ++ break; ++ case 4: ++ data = val; ++ break; ++ } ++ ++ rt3883_pci_w32(rpc, data, RT3883_PCI_REG_CFGDATA); ++ spin_unlock_irqrestore(&rpc->lock, flags); ++ ++ return PCIBIOS_SUCCESSFUL; ++} ++ ++static struct pci_ops rt3883_pci_ops = { ++ .read = rt3883_pci_config_read, ++ .write = rt3883_pci_config_write, ++}; ++ ++static void rt3883_pci_preinit(struct rt3883_pci_controller *rpc, unsigned mode) ++{ ++ u32 syscfg1; ++ u32 rstctrl; ++ u32 clkcfg1; ++ u32 t; ++ ++ rstctrl = rt_sysc_r32(RT3883_SYSC_REG_RSTCTRL); ++ syscfg1 = rt_sysc_r32(RT3883_SYSC_REG_SYSCFG1); ++ clkcfg1 = rt_sysc_r32(RT3883_SYSC_REG_CLKCFG1); ++ ++ if (mode & RT3883_PCI_MODE_PCIE) { ++ rstctrl |= RT3883_RSTCTRL_PCIE; ++ rt_sysc_w32(rstctrl, RT3883_SYSC_REG_RSTCTRL); ++ ++ /* setup PCI PAD drive mode */ ++ syscfg1 &= ~(0x30); ++ syscfg1 |= (2 << 4); ++ rt_sysc_w32(syscfg1, RT3883_SYSC_REG_SYSCFG1); ++ ++ t = rt_sysc_r32(RT3883_SYSC_REG_PCIE_CLK_GEN0); ++ t &= ~BIT(31); ++ rt_sysc_w32(t, RT3883_SYSC_REG_PCIE_CLK_GEN0); ++ ++ t = rt_sysc_r32(RT3883_SYSC_REG_PCIE_CLK_GEN1); ++ t &= 0x80ffffff; ++ rt_sysc_w32(t, RT3883_SYSC_REG_PCIE_CLK_GEN1); ++ ++ t = rt_sysc_r32(RT3883_SYSC_REG_PCIE_CLK_GEN1); ++ t |= 0xa << 24; ++ rt_sysc_w32(t, RT3883_SYSC_REG_PCIE_CLK_GEN1); ++ ++ t = rt_sysc_r32(RT3883_SYSC_REG_PCIE_CLK_GEN0); ++ t |= BIT(31); ++ rt_sysc_w32(t, RT3883_SYSC_REG_PCIE_CLK_GEN0); ++ ++ msleep(50); ++ ++ rstctrl &= ~RT3883_RSTCTRL_PCIE; ++ rt_sysc_w32(rstctrl, RT3883_SYSC_REG_RSTCTRL); ++ } ++ ++ syscfg1 |= (RT3883_SYSCFG1_PCIE_RC_MODE | RT3883_SYSCFG1_PCI_HOST_MODE); ++ ++ clkcfg1 &= ~(RT3883_CLKCFG1_PCI_CLK_EN | RT3883_CLKCFG1_PCIE_CLK_EN); ++ ++ if (mode & RT3883_PCI_MODE_PCI) { ++ clkcfg1 |= RT3883_CLKCFG1_PCI_CLK_EN; ++ rstctrl &= ~RT3883_RSTCTRL_PCI; ++ } ++ ++ if (mode & RT3883_PCI_MODE_PCIE) { ++ clkcfg1 |= RT3883_CLKCFG1_PCIE_CLK_EN; ++ rstctrl &= ~RT3883_RSTCTRL_PCIE; ++ } ++ ++ rt_sysc_w32(syscfg1, RT3883_SYSC_REG_SYSCFG1); ++ rt_sysc_w32(rstctrl, RT3883_SYSC_REG_RSTCTRL); ++ rt_sysc_w32(clkcfg1, RT3883_SYSC_REG_CLKCFG1); ++ ++ msleep(500); ++ ++ /* ++ * setup the device number of the P2P bridge ++ * and de-assert the reset line ++ */ ++ t = (RT3883_P2P_BR_DEVNUM << RT3883_PCICFG_P2P_BR_DEVNUM_S); ++ rt3883_pci_w32(rpc, t, RT3883_PCI_REG_PCICFG); ++ ++ /* flush write */ ++ rt3883_pci_r32(rpc, RT3883_PCI_REG_PCICFG); ++ msleep(500); ++ ++ if (mode & RT3883_PCI_MODE_PCIE) { ++ msleep(500); ++ ++ t = rt3883_pci_r32(rpc, RT3883_PCI_REG_STATUS(1)); ++ ++ rpc->pcie_ready = t & BIT(0); ++ ++ if (!rpc->pcie_ready) { ++ /* reset the PCIe block */ ++ t = rt_sysc_r32(RT3883_SYSC_REG_RSTCTRL); ++ t |= RT3883_RSTCTRL_PCIE; ++ rt_sysc_w32(t, RT3883_SYSC_REG_RSTCTRL); ++ t &= ~RT3883_RSTCTRL_PCIE; ++ rt_sysc_w32(t, RT3883_SYSC_REG_RSTCTRL); ++ ++ /* turn off PCIe clock */ ++ t = rt_sysc_r32(RT3883_SYSC_REG_CLKCFG1); ++ t &= ~RT3883_CLKCFG1_PCIE_CLK_EN; ++ rt_sysc_w32(t, RT3883_SYSC_REG_CLKCFG1); ++ ++ t = rt_sysc_r32(RT3883_SYSC_REG_PCIE_CLK_GEN0); ++ t &= ~0xf000c080; ++ rt_sysc_w32(t, RT3883_SYSC_REG_PCIE_CLK_GEN0); ++ } ++ } ++ ++ /* enable PCI arbiter */ ++ rt3883_pci_w32(rpc, 0x79, RT3883_PCI_REG_ARBCTL); ++} ++ ++static inline void ++rt3883_dump_pci_config(struct rt3883_pci_controller *rpc, ++ int bus, int slot) ++{ ++ int i; ++ ++ for (i = 0; i < 16; i++) { ++ u32 val; ++ ++ val = rt3883_pci_read_cfg32(rpc, bus, slot, 0, i << 2); ++ pr_info("pci %02x:%02x.0 0x%02x = %08x\n", ++ bus, slot, i << 2, val); ++ } ++} ++ ++static int rt3883_pci_probe(struct platform_device *pdev) ++{ ++ struct rt3883_pci_controller *rpc; ++ struct device *dev = &pdev->dev; ++ struct device_node *np = dev->of_node; ++ struct resource *res; ++ struct device_node *child; ++ u32 val; ++ int err; ++ int mode; ++ ++ rpc = devm_kzalloc(dev, sizeof(*rpc), GFP_KERNEL); ++ if (!rpc) ++ return -ENOMEM; ++ ++ res = platform_get_resource(pdev, IORESOURCE_MEM, 0); ++ if (!res) ++ return -EINVAL; ++ ++ rpc->base = devm_ioremap_resource(dev, res); ++ if (IS_ERR(rpc->base)) ++ return PTR_ERR(rpc->base); ++ ++ rpc->pci_controller.of_node = of_get_child_by_name(np, "host-bridge"); ++ if (!rpc->pci_controller.of_node) { ++ dev_err(dev, "no %s child node found", "host-bridge"); ++ return -ENODEV; ++ } ++ ++ mode = RT3883_PCI_MODE_NONE; ++ for_each_child_of_node(rpc->pci_controller.of_node, child) { ++ u32 slot; ++ ++ if (!of_device_is_available(child)) ++ continue; ++ ++ if (of_property_read_u32(child, "ralink,pci-slot", ++ &slot)) { ++ dev_err(dev, "no '%s' property found for %s\n", ++ "ralink,pci-slot", ++ of_node_full_name(child)); ++ continue; ++ } ++ ++ switch (slot) { ++ case 1: ++ mode |= RT3883_PCI_MODE_PCIE; ++ break; ++ ++ case 17: ++ case 18: ++ mode |= RT3883_PCI_MODE_PCI; ++ break; ++ } ++ } ++ ++ if (mode == RT3883_PCI_MODE_NONE) { ++ dev_err(dev, "unable to determine PCI mode\n"); ++ err = -EINVAL; ++ goto err_put_hb_node; ++ } ++ ++ dev_info(dev, "mode:%s%s\n", ++ (mode & RT3883_PCI_MODE_PCI) ? " PCI" : "", ++ (mode & RT3883_PCI_MODE_PCIE) ? " PCIe" : ""); ++ ++ rt3883_pci_preinit(rpc, mode); ++ ++ rpc->pci_controller.pci_ops = &rt3883_pci_ops; ++ rpc->pci_controller.io_resource = &rpc->io_res; ++ rpc->pci_controller.mem_resource = &rpc->mem_res; ++ ++ /* Load PCI I/O and memory resources from DT */ ++ pci_load_of_ranges(&rpc->pci_controller, ++ rpc->pci_controller.of_node); ++ ++ rt3883_pci_w32(rpc, rpc->mem_res.start, RT3883_PCI_REG_MEMBASE); ++ rt3883_pci_w32(rpc, rpc->io_res.start, RT3883_PCI_REG_IOBASE); ++ ++ ioport_resource.start = rpc->io_res.start; ++ ioport_resource.end = rpc->io_res.end; ++ ++ /* PCI */ ++ rt3883_pci_w32(rpc, 0x03ff0000, RT3883_PCI_REG_BAR0SETUP(0)); ++ rt3883_pci_w32(rpc, RT3883_MEMORY_BASE, RT3883_PCI_REG_IMBASEBAR0(0)); ++ rt3883_pci_w32(rpc, 0x08021814, RT3883_PCI_REG_ID(0)); ++ rt3883_pci_w32(rpc, 0x00800001, RT3883_PCI_REG_CLASS(0)); ++ rt3883_pci_w32(rpc, 0x28801814, RT3883_PCI_REG_SUBID(0)); ++ ++ /* PCIe */ ++ rt3883_pci_w32(rpc, 0x03ff0000, RT3883_PCI_REG_BAR0SETUP(1)); ++ rt3883_pci_w32(rpc, RT3883_MEMORY_BASE, RT3883_PCI_REG_IMBASEBAR0(1)); ++ rt3883_pci_w32(rpc, 0x08021814, RT3883_PCI_REG_ID(1)); ++ rt3883_pci_w32(rpc, 0x06040001, RT3883_PCI_REG_CLASS(1)); ++ rt3883_pci_w32(rpc, 0x28801814, RT3883_PCI_REG_SUBID(1)); ++ ++ err = rt3883_pci_irq_init(dev, rpc); ++ if (err) ++ goto err_put_hb_node; ++ ++ /* PCIe */ ++ val = rt3883_pci_read_cfg32(rpc, 0, 0x01, 0, PCI_COMMAND); ++ val |= PCI_COMMAND_IO | PCI_COMMAND_MEMORY | PCI_COMMAND_MASTER; ++ rt3883_pci_write_cfg32(rpc, 0, 0x01, 0, PCI_COMMAND, val); ++ ++ /* PCI */ ++ val = rt3883_pci_read_cfg32(rpc, 0, 0x00, 0, PCI_COMMAND); ++ val |= PCI_COMMAND_IO | PCI_COMMAND_MEMORY | PCI_COMMAND_MASTER; ++ rt3883_pci_write_cfg32(rpc, 0, 0x00, 0, PCI_COMMAND, val); ++ ++ if (mode == RT3883_PCI_MODE_PCIE) { ++ rt3883_pci_w32(rpc, 0x03ff0001, RT3883_PCI_REG_BAR0SETUP(0)); ++ rt3883_pci_w32(rpc, 0x03ff0001, RT3883_PCI_REG_BAR0SETUP(1)); ++ ++ rt3883_pci_write_cfg32(rpc, 0, RT3883_P2P_BR_DEVNUM, 0, ++ PCI_BASE_ADDRESS_0, ++ RT3883_MEMORY_BASE); ++ /* flush write */ ++ rt3883_pci_read_cfg32(rpc, 0, RT3883_P2P_BR_DEVNUM, 0, ++ PCI_BASE_ADDRESS_0); ++ } else { ++ rt3883_pci_write_cfg32(rpc, 0, RT3883_P2P_BR_DEVNUM, 0, ++ PCI_IO_BASE, 0x00000101); ++ } ++ ++ register_pci_controller(&rpc->pci_controller); ++ ++ return 0; ++ ++err_put_hb_node: ++ of_node_put(rpc->pci_controller.of_node); ++ return err; ++} ++ ++int __init pcibios_map_irq(const struct pci_dev *dev, u8 slot, u8 pin) ++{ ++ struct rt3883_pci_controller *rpc; ++ struct of_irq dev_irq; ++ int err; ++ int irq; ++ ++ rpc = pci_bus_to_rt3883_controller(dev->bus); ++ err = of_irq_map_pci(dev, &dev_irq); ++ if (err) { ++ pr_err("pci %s: unable to get irq map, err=%d\n", ++ pci_name((struct pci_dev *) dev), err); ++ return 0; ++ } ++ ++ irq = irq_create_of_mapping(dev_irq.controller, ++ dev_irq.specifier, ++ dev_irq.size); ++ ++ if (irq == 0) ++ pr_crit("pci %s: no irq found for pin %u\n", ++ pci_name((struct pci_dev *) dev), pin); ++ else ++ pr_info("pci %s: using irq %d for pin %u\n", ++ pci_name((struct pci_dev *) dev), irq, pin); ++ ++ return irq; ++} ++ ++int pcibios_plat_dev_init(struct pci_dev *dev) ++{ ++ return 0; ++} ++ ++static const struct of_device_id rt3883_pci_ids[] = { ++ { .compatible = "ralink,rt3883-pci" }, ++ {}, ++}; ++MODULE_DEVICE_TABLE(of, rt3883_pci_ids); ++ ++static struct platform_driver rt3883_pci_driver = { ++ .probe = rt3883_pci_probe, ++ .driver = { ++ .name = "rt3883-pci", ++ .owner = THIS_MODULE, ++ .of_match_table = of_match_ptr(rt3883_pci_ids), ++ }, ++}; ++ ++static int __init rt3883_pci_init(void) ++{ ++ return platform_driver_register(&rt3883_pci_driver); ++} ++ ++postcore_initcall(rt3883_pci_init); +--- a/arch/mips/ralink/Kconfig ++++ b/arch/mips/ralink/Kconfig +@@ -20,6 +20,7 @@ choice + bool "RT3883" + select USB_ARCH_HAS_OHCI + select USB_ARCH_HAS_EHCI ++ select HW_HAS_PCI + + config SOC_MT7620 + bool "MT7620" diff --git a/target/linux/ramips/patches-3.8/0136-NET-MIPS-add-ralink-SoC-ethernet-driver.patch b/target/linux/ramips/patches-3.8/0136-NET-MIPS-add-ralink-SoC-ethernet-driver.patch new file mode 100644 index 0000000000..608f1fb87b --- /dev/null +++ b/target/linux/ramips/patches-3.8/0136-NET-MIPS-add-ralink-SoC-ethernet-driver.patch @@ -0,0 +1,3137 @@ +From 34fc7d26c01ba594be347aefcc31f55b36c06a72 Mon Sep 17 00:00:00 2001 +From: John Crispin +Date: Mon, 22 Apr 2013 23:20:03 +0200 +Subject: [PATCH 136/137] NET: MIPS: add ralink SoC ethernet driver + +Add support for Ralink FE and ESW. + +Signed-off-by: John Crispin +--- + .../include/asm/mach-ralink/rt305x_esw_platform.h | 27 + + arch/mips/ralink/rt305x.c | 1 + + drivers/net/ethernet/Kconfig | 1 + + drivers/net/ethernet/Makefile | 1 + + drivers/net/ethernet/ramips/Kconfig | 18 + + drivers/net/ethernet/ramips/Makefile | 9 + + drivers/net/ethernet/ramips/ramips_debugfs.c | 127 ++ + drivers/net/ethernet/ramips/ramips_esw.c | 1221 +++++++++++++++++++ + drivers/net/ethernet/ramips/ramips_eth.h | 375 ++++++ + drivers/net/ethernet/ramips/ramips_main.c | 1281 ++++++++++++++++++++ + 10 files changed, 3061 insertions(+) + create mode 100644 arch/mips/include/asm/mach-ralink/rt305x_esw_platform.h + create mode 100644 drivers/net/ethernet/ramips/Kconfig + create mode 100644 drivers/net/ethernet/ramips/Makefile + create mode 100644 drivers/net/ethernet/ramips/ramips_debugfs.c + create mode 100644 drivers/net/ethernet/ramips/ramips_esw.c + create mode 100644 drivers/net/ethernet/ramips/ramips_eth.h + create mode 100644 drivers/net/ethernet/ramips/ramips_main.c + +--- /dev/null ++++ b/arch/mips/include/asm/mach-ralink/rt305x_esw_platform.h +@@ -0,0 +1,27 @@ ++/* ++ * Ralink RT305x SoC platform device registration ++ * ++ * Copyright (C) 2010 Gabor Juhos ++ * ++ * This program is free software; you can redistribute it and/or modify it ++ * under the terms of the GNU General Public License version 2 as published ++ * by the Free Software Foundation. ++ */ ++ ++#ifndef _RT305X_ESW_PLATFORM_H ++#define _RT305X_ESW_PLATFORM_H ++ ++enum { ++ RT305X_ESW_VLAN_CONFIG_NONE = 0, ++ RT305X_ESW_VLAN_CONFIG_LLLLW, ++ RT305X_ESW_VLAN_CONFIG_WLLLL, ++}; ++ ++struct rt305x_esw_platform_data ++{ ++ u8 vlan_config; ++ u32 reg_initval_fct2; ++ u32 reg_initval_fpa2; ++}; ++ ++#endif /* _RT305X_ESW_PLATFORM_H */ +--- a/arch/mips/ralink/rt305x.c ++++ b/arch/mips/ralink/rt305x.c +@@ -221,6 +221,7 @@ void __init ralink_clk_init(void) + } + + ralink_clk_add("cpu", cpu_rate); ++ ralink_clk_add("sys", sys_rate); + ralink_clk_add("10000b00.spi", sys_rate); + ralink_clk_add("10000100.timer", wdt_rate); + ralink_clk_add("10000120.watchdog", wdt_rate); +--- a/drivers/net/ethernet/Kconfig ++++ b/drivers/net/ethernet/Kconfig +@@ -136,6 +136,7 @@ source "drivers/net/ethernet/packetengin + source "drivers/net/ethernet/pasemi/Kconfig" + source "drivers/net/ethernet/qlogic/Kconfig" + source "drivers/net/ethernet/racal/Kconfig" ++source "drivers/net/ethernet/ramips/Kconfig" + source "drivers/net/ethernet/realtek/Kconfig" + source "drivers/net/ethernet/renesas/Kconfig" + source "drivers/net/ethernet/rdc/Kconfig" +--- a/drivers/net/ethernet/Makefile ++++ b/drivers/net/ethernet/Makefile +@@ -54,6 +54,7 @@ obj-$(CONFIG_NET_PACKET_ENGINE) += packe + obj-$(CONFIG_NET_VENDOR_PASEMI) += pasemi/ + obj-$(CONFIG_NET_VENDOR_QLOGIC) += qlogic/ + obj-$(CONFIG_NET_VENDOR_RACAL) += racal/ ++obj-$(CONFIG_NET_RAMIPS) += ramips/ + obj-$(CONFIG_NET_VENDOR_REALTEK) += realtek/ + obj-$(CONFIG_SH_ETH) += renesas/ + obj-$(CONFIG_NET_VENDOR_RDC) += rdc/ +--- /dev/null ++++ b/drivers/net/ethernet/ramips/Kconfig +@@ -0,0 +1,18 @@ ++config NET_RAMIPS ++ tristate "Ralink RT288X/RT3X5X/RT3662/RT3883 ethernet driver" ++ depends on RALINK ++ select PHYLIB if (SOC_RT288X || SOC_RT3883) ++ select SWCONFIG if SOC_RT305X ++ help ++ This driver supports the etehrnet mac inside the ralink wisocs ++ ++if NET_RAMIPS ++ ++config NET_RAMIPS_DEBUG ++ bool "Enable debug messages in the Ralink ethernet driver" ++ ++config NET_RAMIPS_DEBUG_FS ++ bool "Enable debugfs support for the Ralink ethernet driver" ++ depends on DEBUG_FS ++ ++endif +--- /dev/null ++++ b/drivers/net/ethernet/ramips/Makefile +@@ -0,0 +1,9 @@ ++# ++# Makefile for the Ramips SoCs built-in ethernet macs ++# ++ ++ramips-y += ramips_main.o ++ ++ramips-$(CONFIG_NET_RAMIPS_DEBUG_FS) += ramips_debugfs.o ++ ++obj-$(CONFIG_NET_RAMIPS) += ramips.o +--- /dev/null ++++ b/drivers/net/ethernet/ramips/ramips_debugfs.c +@@ -0,0 +1,127 @@ ++/* ++ * Ralink SoC ethernet driver debugfs code ++ * ++ * Copyright (C) 2011-2012 Gabor Juhos ++ * ++ * 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 ++#include ++#include ++ ++#include "ramips_eth.h" ++ ++static struct dentry *raeth_debugfs_root; ++ ++static int raeth_debugfs_generic_open(struct inode *inode, struct file *file) ++{ ++ file->private_data = inode->i_private; ++ return 0; ++} ++ ++void raeth_debugfs_update_int_stats(struct raeth_priv *re, u32 status) ++{ ++ re->debug.int_stats.total += !!status; ++ ++ re->debug.int_stats.rx_delayed += !!(status & RAMIPS_RX_DLY_INT); ++ re->debug.int_stats.rx_done0 += !!(status & RAMIPS_RX_DONE_INT0); ++ re->debug.int_stats.rx_coherent += !!(status & RAMIPS_RX_COHERENT); ++ ++ re->debug.int_stats.tx_delayed += !!(status & RAMIPS_TX_DLY_INT); ++ re->debug.int_stats.tx_done0 += !!(status & RAMIPS_TX_DONE_INT0); ++ re->debug.int_stats.tx_done1 += !!(status & RAMIPS_TX_DONE_INT1); ++ re->debug.int_stats.tx_done2 += !!(status & RAMIPS_TX_DONE_INT2); ++ re->debug.int_stats.tx_done3 += !!(status & RAMIPS_TX_DONE_INT3); ++ re->debug.int_stats.tx_coherent += !!(status & RAMIPS_TX_COHERENT); ++ ++ re->debug.int_stats.pse_fq_empty += !!(status & RAMIPS_PSE_FQ_EMPTY); ++ re->debug.int_stats.pse_p0_fc += !!(status & RAMIPS_PSE_P0_FC); ++ re->debug.int_stats.pse_p1_fc += !!(status & RAMIPS_PSE_P1_FC); ++ re->debug.int_stats.pse_p2_fc += !!(status & RAMIPS_PSE_P2_FC); ++ re->debug.int_stats.pse_buf_drop += !!(status & RAMIPS_PSE_BUF_DROP); ++} ++ ++static ssize_t read_file_int_stats(struct file *file, char __user *user_buf, ++ size_t count, loff_t *ppos) ++{ ++#define PR_INT_STAT(_label, _field) \ ++ len += snprintf(buf + len, sizeof(buf) - len, \ ++ "%-18s: %10lu\n", _label, re->debug.int_stats._field); ++ ++ struct raeth_priv *re = file->private_data; ++ char buf[512]; ++ unsigned int len = 0; ++ unsigned long flags; ++ ++ spin_lock_irqsave(&re->page_lock, flags); ++ ++ PR_INT_STAT("RX Delayed", rx_delayed); ++ PR_INT_STAT("RX Done 0", rx_done0); ++ PR_INT_STAT("RX Coherent", rx_coherent); ++ ++ PR_INT_STAT("TX Delayed", tx_delayed); ++ PR_INT_STAT("TX Done 0", tx_done0); ++ PR_INT_STAT("TX Done 1", tx_done1); ++ PR_INT_STAT("TX Done 2", tx_done2); ++ PR_INT_STAT("TX Done 3", tx_done3); ++ PR_INT_STAT("TX Coherent", tx_coherent); ++ ++ PR_INT_STAT("PSE FQ empty", pse_fq_empty); ++ PR_INT_STAT("CDMA Flow control", pse_p0_fc); ++ PR_INT_STAT("GDMA1 Flow control", pse_p1_fc); ++ PR_INT_STAT("GDMA2 Flow control", pse_p2_fc); ++ PR_INT_STAT("PSE discard", pse_buf_drop); ++ ++ len += snprintf(buf + len, sizeof(buf) - len, "\n"); ++ PR_INT_STAT("Total", total); ++ ++ spin_unlock_irqrestore(&re->page_lock, flags); ++ ++ return simple_read_from_buffer(user_buf, count, ppos, buf, len); ++#undef PR_INT_STAT ++} ++ ++static const struct file_operations raeth_fops_int_stats = { ++ .open = raeth_debugfs_generic_open, ++ .read = read_file_int_stats, ++ .owner = THIS_MODULE ++}; ++ ++void raeth_debugfs_exit(struct raeth_priv *re) ++{ ++ debugfs_remove_recursive(re->debug.debugfs_dir); ++} ++ ++int raeth_debugfs_init(struct raeth_priv *re) ++{ ++ re->debug.debugfs_dir = debugfs_create_dir(re->netdev->name, ++ raeth_debugfs_root); ++ if (!re->debug.debugfs_dir) ++ return -ENOMEM; ++ ++ debugfs_create_file("int_stats", S_IRUGO, re->debug.debugfs_dir, ++ re, &raeth_fops_int_stats); ++ ++ return 0; ++} ++ ++int raeth_debugfs_root_init(void) ++{ ++ if (raeth_debugfs_root) ++ return -EBUSY; ++ ++ raeth_debugfs_root = debugfs_create_dir("raeth", NULL); ++ if (!raeth_debugfs_root) ++ return -ENOENT; ++ ++ return 0; ++} ++ ++void raeth_debugfs_root_exit(void) ++{ ++ debugfs_remove(raeth_debugfs_root); ++ raeth_debugfs_root = NULL; ++} +--- /dev/null ++++ b/drivers/net/ethernet/ramips/ramips_esw.c +@@ -0,0 +1,1221 @@ ++#include ++#include ++#include ++ ++#include ++#include ++#include ++ ++/* ++ * HW limitations for this switch: ++ * - No large frame support (PKT_MAX_LEN at most 1536) ++ * - Can't have untagged vlan and tagged vlan on one port at the same time, ++ * though this might be possible using the undocumented PPE. ++ */ ++ ++#define RT305X_ESW_REG_ISR 0x00 ++#define RT305X_ESW_REG_IMR 0x04 ++#define RT305X_ESW_REG_FCT0 0x08 ++#define RT305X_ESW_REG_PFC1 0x14 ++#define RT305X_ESW_REG_ATS 0x24 ++#define RT305X_ESW_REG_ATS0 0x28 ++#define RT305X_ESW_REG_ATS1 0x2c ++#define RT305X_ESW_REG_ATS2 0x30 ++#define RT305X_ESW_REG_PVIDC(_n) (0x40 + 4 * (_n)) ++#define RT305X_ESW_REG_VLANI(_n) (0x50 + 4 * (_n)) ++#define RT305X_ESW_REG_VMSC(_n) (0x70 + 4 * (_n)) ++#define RT305X_ESW_REG_POA 0x80 ++#define RT305X_ESW_REG_FPA 0x84 ++#define RT305X_ESW_REG_SOCPC 0x8c ++#define RT305X_ESW_REG_POC0 0x90 ++#define RT305X_ESW_REG_POC1 0x94 ++#define RT305X_ESW_REG_POC2 0x98 ++#define RT305X_ESW_REG_SGC 0x9c ++#define RT305X_ESW_REG_STRT 0xa0 ++#define RT305X_ESW_REG_PCR0 0xc0 ++#define RT305X_ESW_REG_PCR1 0xc4 ++#define RT305X_ESW_REG_FPA2 0xc8 ++#define RT305X_ESW_REG_FCT2 0xcc ++#define RT305X_ESW_REG_SGC2 0xe4 ++#define RT305X_ESW_REG_P0LED 0xa4 ++#define RT305X_ESW_REG_P1LED 0xa8 ++#define RT305X_ESW_REG_P2LED 0xac ++#define RT305X_ESW_REG_P3LED 0xb0 ++#define RT305X_ESW_REG_P4LED 0xb4 ++#define RT305X_ESW_REG_P0PC 0xe8 ++#define RT305X_ESW_REG_P1PC 0xec ++#define RT305X_ESW_REG_P2PC 0xf0 ++#define RT305X_ESW_REG_P3PC 0xf4 ++#define RT305X_ESW_REG_P4PC 0xf8 ++#define RT305X_ESW_REG_P5PC 0xfc ++ ++#define RT305X_ESW_LED_LINK 0 ++#define RT305X_ESW_LED_100M 1 ++#define RT305X_ESW_LED_DUPLEX 2 ++#define RT305X_ESW_LED_ACTIVITY 3 ++#define RT305X_ESW_LED_COLLISION 4 ++#define RT305X_ESW_LED_LINKACT 5 ++#define RT305X_ESW_LED_DUPLCOLL 6 ++#define RT305X_ESW_LED_10MACT 7 ++#define RT305X_ESW_LED_100MACT 8 ++/* Additional led states not in datasheet: */ ++#define RT305X_ESW_LED_BLINK 10 ++#define RT305X_ESW_LED_ON 12 ++ ++#define RT305X_ESW_LINK_S 25 ++#define RT305X_ESW_DUPLEX_S 9 ++#define RT305X_ESW_SPD_S 0 ++ ++#define RT305X_ESW_PCR0_WT_NWAY_DATA_S 16 ++#define RT305X_ESW_PCR0_WT_PHY_CMD BIT(13) ++#define RT305X_ESW_PCR0_CPU_PHY_REG_S 8 ++ ++#define RT305X_ESW_PCR1_WT_DONE BIT(0) ++ ++#define RT305X_ESW_ATS_TIMEOUT (5 * HZ) ++#define RT305X_ESW_PHY_TIMEOUT (5 * HZ) ++ ++#define RT305X_ESW_PVIDC_PVID_M 0xfff ++#define RT305X_ESW_PVIDC_PVID_S 12 ++ ++#define RT305X_ESW_VLANI_VID_M 0xfff ++#define RT305X_ESW_VLANI_VID_S 12 ++ ++#define RT305X_ESW_VMSC_MSC_M 0xff ++#define RT305X_ESW_VMSC_MSC_S 8 ++ ++#define RT305X_ESW_SOCPC_DISUN2CPU_S 0 ++#define RT305X_ESW_SOCPC_DISMC2CPU_S 8 ++#define RT305X_ESW_SOCPC_DISBC2CPU_S 16 ++#define RT305X_ESW_SOCPC_CRC_PADDING BIT(25) ++ ++#define RT305X_ESW_POC0_EN_BP_S 0 ++#define RT305X_ESW_POC0_EN_FC_S 8 ++#define RT305X_ESW_POC0_DIS_RMC2CPU_S 16 ++#define RT305X_ESW_POC0_DIS_PORT_M 0x7f ++#define RT305X_ESW_POC0_DIS_PORT_S 23 ++ ++#define RT305X_ESW_POC2_UNTAG_EN_M 0xff ++#define RT305X_ESW_POC2_UNTAG_EN_S 0 ++#define RT305X_ESW_POC2_ENAGING_S 8 ++#define RT305X_ESW_POC2_DIS_UC_PAUSE_S 16 ++ ++#define RT305X_ESW_SGC2_DOUBLE_TAG_M 0x7f ++#define RT305X_ESW_SGC2_DOUBLE_TAG_S 0 ++#define RT305X_ESW_SGC2_LAN_PMAP_M 0x3f ++#define RT305X_ESW_SGC2_LAN_PMAP_S 24 ++ ++#define RT305X_ESW_PFC1_EN_VLAN_M 0xff ++#define RT305X_ESW_PFC1_EN_VLAN_S 16 ++#define RT305X_ESW_PFC1_EN_TOS_S 24 ++ ++#define RT305X_ESW_VLAN_NONE 0xfff ++ ++#define RT305X_ESW_POA_LINK_MASK 0x1f ++#define RT305X_ESW_POA_LINK_SHIFT 25 ++ ++#define RT305X_ESW_PORT_ST_CHG BIT(26) ++#define RT305X_ESW_PORT0 0 ++#define RT305X_ESW_PORT1 1 ++#define RT305X_ESW_PORT2 2 ++#define RT305X_ESW_PORT3 3 ++#define RT305X_ESW_PORT4 4 ++#define RT305X_ESW_PORT5 5 ++#define RT305X_ESW_PORT6 6 ++ ++#define RT305X_ESW_PORTS_NONE 0 ++ ++#define RT305X_ESW_PMAP_LLLLLL 0x3f ++#define RT305X_ESW_PMAP_LLLLWL 0x2f ++#define RT305X_ESW_PMAP_WLLLLL 0x3e ++ ++#define RT305X_ESW_PORTS_INTERNAL \ ++ (BIT(RT305X_ESW_PORT0) | BIT(RT305X_ESW_PORT1) | \ ++ BIT(RT305X_ESW_PORT2) | BIT(RT305X_ESW_PORT3) | \ ++ BIT(RT305X_ESW_PORT4)) ++ ++#define RT305X_ESW_PORTS_NOCPU \ ++ (RT305X_ESW_PORTS_INTERNAL | BIT(RT305X_ESW_PORT5)) ++ ++#define RT305X_ESW_PORTS_CPU BIT(RT305X_ESW_PORT6) ++ ++#define RT305X_ESW_PORTS_ALL \ ++ (RT305X_ESW_PORTS_NOCPU | RT305X_ESW_PORTS_CPU) ++ ++#define RT305X_ESW_NUM_VLANS 16 ++#define RT305X_ESW_NUM_VIDS 4096 ++#define RT305X_ESW_NUM_PORTS 7 ++#define RT305X_ESW_NUM_LANWAN 6 ++#define RT305X_ESW_NUM_LEDS 5 ++ ++enum { ++ /* Global attributes. */ ++ RT305X_ESW_ATTR_ENABLE_VLAN, ++ RT305X_ESW_ATTR_ALT_VLAN_DISABLE, ++ /* Port attributes. */ ++ RT305X_ESW_ATTR_PORT_DISABLE, ++ RT305X_ESW_ATTR_PORT_DOUBLETAG, ++ RT305X_ESW_ATTR_PORT_UNTAG, ++ RT305X_ESW_ATTR_PORT_LED, ++ RT305X_ESW_ATTR_PORT_LAN, ++ RT305X_ESW_ATTR_PORT_RECV_BAD, ++ RT305X_ESW_ATTR_PORT_RECV_GOOD, ++}; ++ ++struct rt305x_esw_port { ++ bool disable; ++ bool doubletag; ++ bool untag; ++ u8 led; ++ u16 pvid; ++}; ++ ++struct rt305x_esw_vlan { ++ u8 ports; ++ u16 vid; ++}; ++ ++struct rt305x_esw { ++ struct device *dev; ++ void __iomem *base; ++ int irq; ++ const struct rt305x_esw_platform_data *pdata; ++ /* Protects against concurrent register rmw operations. */ ++ spinlock_t reg_rw_lock; ++ ++ unsigned char port_map; ++ unsigned int reg_initval_fct2; ++ unsigned int reg_initval_fpa2; ++ ++ ++ struct switch_dev swdev; ++ bool global_vlan_enable; ++ bool alt_vlan_disable; ++ struct rt305x_esw_vlan vlans[RT305X_ESW_NUM_VLANS]; ++ struct rt305x_esw_port ports[RT305X_ESW_NUM_PORTS]; ++ ++}; ++ ++static inline void ++rt305x_esw_wr(struct rt305x_esw *esw, u32 val, unsigned reg) ++{ ++ __raw_writel(val, esw->base + reg); ++} ++ ++static inline u32 ++rt305x_esw_rr(struct rt305x_esw *esw, unsigned reg) ++{ ++ return __raw_readl(esw->base + reg); ++} ++ ++static inline void ++rt305x_esw_rmw_raw(struct rt305x_esw *esw, unsigned reg, unsigned long mask, ++ unsigned long val) ++{ ++ unsigned long t; ++ ++ t = __raw_readl(esw->base + reg) & ~mask; ++ __raw_writel(t | val, esw->base + reg); ++} ++ ++static void ++rt305x_esw_rmw(struct rt305x_esw *esw, unsigned reg, unsigned long mask, ++ unsigned long val) ++{ ++ unsigned long flags; ++ ++ spin_lock_irqsave(&esw->reg_rw_lock, flags); ++ rt305x_esw_rmw_raw(esw, reg, mask, val); ++ spin_unlock_irqrestore(&esw->reg_rw_lock, flags); ++} ++ ++static u32 ++rt305x_mii_write(struct rt305x_esw *esw, u32 phy_addr, u32 phy_register, ++ u32 write_data) ++{ ++ unsigned long t_start = jiffies; ++ int ret = 0; ++ ++ while (1) { ++ if (!(rt305x_esw_rr(esw, RT305X_ESW_REG_PCR1) & ++ RT305X_ESW_PCR1_WT_DONE)) ++ break; ++ if (time_after(jiffies, t_start + RT305X_ESW_PHY_TIMEOUT)) { ++ ret = 1; ++ goto out; ++ } ++ } ++ ++ write_data &= 0xffff; ++ rt305x_esw_wr(esw, ++ (write_data << RT305X_ESW_PCR0_WT_NWAY_DATA_S) | ++ (phy_register << RT305X_ESW_PCR0_CPU_PHY_REG_S) | ++ (phy_addr) | RT305X_ESW_PCR0_WT_PHY_CMD, ++ RT305X_ESW_REG_PCR0); ++ ++ t_start = jiffies; ++ while (1) { ++ if (rt305x_esw_rr(esw, RT305X_ESW_REG_PCR1) & ++ RT305X_ESW_PCR1_WT_DONE) ++ break; ++ ++ if (time_after(jiffies, t_start + RT305X_ESW_PHY_TIMEOUT)) { ++ ret = 1; ++ break; ++ } ++ } ++out: ++ if (ret) ++ printk(KERN_ERR "ramips_eth: MDIO timeout\n"); ++ return ret; ++} ++ ++static unsigned ++rt305x_esw_get_vlan_id(struct rt305x_esw *esw, unsigned vlan) ++{ ++ unsigned s; ++ unsigned val; ++ ++ s = RT305X_ESW_VLANI_VID_S * (vlan % 2); ++ val = rt305x_esw_rr(esw, RT305X_ESW_REG_VLANI(vlan / 2)); ++ val = (val >> s) & RT305X_ESW_VLANI_VID_M; ++ ++ return val; ++} ++ ++static void ++rt305x_esw_set_vlan_id(struct rt305x_esw *esw, unsigned vlan, unsigned vid) ++{ ++ unsigned s; ++ ++ s = RT305X_ESW_VLANI_VID_S * (vlan % 2); ++ rt305x_esw_rmw(esw, ++ RT305X_ESW_REG_VLANI(vlan / 2), ++ RT305X_ESW_VLANI_VID_M << s, ++ (vid & RT305X_ESW_VLANI_VID_M) << s); ++} ++ ++static unsigned ++rt305x_esw_get_pvid(struct rt305x_esw *esw, unsigned port) ++{ ++ unsigned s, val; ++ ++ s = RT305X_ESW_PVIDC_PVID_S * (port % 2); ++ val = rt305x_esw_rr(esw, RT305X_ESW_REG_PVIDC(port / 2)); ++ return (val >> s) & RT305X_ESW_PVIDC_PVID_M; ++} ++ ++static void ++rt305x_esw_set_pvid(struct rt305x_esw *esw, unsigned port, unsigned pvid) ++{ ++ unsigned s; ++ ++ s = RT305X_ESW_PVIDC_PVID_S * (port % 2); ++ rt305x_esw_rmw(esw, ++ RT305X_ESW_REG_PVIDC(port / 2), ++ RT305X_ESW_PVIDC_PVID_M << s, ++ (pvid & RT305X_ESW_PVIDC_PVID_M) << s); ++} ++ ++static unsigned ++rt305x_esw_get_vmsc(struct rt305x_esw *esw, unsigned vlan) ++{ ++ unsigned s, val; ++ ++ s = RT305X_ESW_VMSC_MSC_S * (vlan % 4); ++ val = rt305x_esw_rr(esw, RT305X_ESW_REG_VMSC(vlan / 4)); ++ val = (val >> s) & RT305X_ESW_VMSC_MSC_M; ++ ++ return val; ++} ++ ++static void ++rt305x_esw_set_vmsc(struct rt305x_esw *esw, unsigned vlan, unsigned msc) ++{ ++ unsigned s; ++ ++ s = RT305X_ESW_VMSC_MSC_S * (vlan % 4); ++ rt305x_esw_rmw(esw, ++ RT305X_ESW_REG_VMSC(vlan / 4), ++ RT305X_ESW_VMSC_MSC_M << s, ++ (msc & RT305X_ESW_VMSC_MSC_M) << s); ++} ++ ++static unsigned ++rt305x_esw_get_port_disable(struct rt305x_esw *esw) ++{ ++ unsigned reg; ++ reg = rt305x_esw_rr(esw, RT305X_ESW_REG_POC0); ++ return (reg >> RT305X_ESW_POC0_DIS_PORT_S) & ++ RT305X_ESW_POC0_DIS_PORT_M; ++} ++ ++static void ++rt305x_esw_set_port_disable(struct rt305x_esw *esw, unsigned disable_mask) ++{ ++ unsigned old_mask; ++ unsigned enable_mask; ++ unsigned changed; ++ int i; ++ ++ old_mask = rt305x_esw_get_port_disable(esw); ++ changed = old_mask ^ disable_mask; ++ enable_mask = old_mask & disable_mask; ++ ++ /* enable before writing to MII */ ++ rt305x_esw_rmw(esw, RT305X_ESW_REG_POC0, ++ (RT305X_ESW_POC0_DIS_PORT_M << ++ RT305X_ESW_POC0_DIS_PORT_S), ++ enable_mask << RT305X_ESW_POC0_DIS_PORT_S); ++ ++ for (i = 0; i < RT305X_ESW_NUM_LEDS; i++) { ++ if (!(changed & (1 << i))) ++ continue; ++ if (disable_mask & (1 << i)) { ++ /* disable */ ++ rt305x_mii_write(esw, i, MII_BMCR, ++ BMCR_PDOWN); ++ } else { ++ /* enable */ ++ rt305x_mii_write(esw, i, MII_BMCR, ++ BMCR_FULLDPLX | ++ BMCR_ANENABLE | ++ BMCR_ANRESTART | ++ BMCR_SPEED100); ++ } ++ } ++ ++ /* disable after writing to MII */ ++ rt305x_esw_rmw(esw, RT305X_ESW_REG_POC0, ++ (RT305X_ESW_POC0_DIS_PORT_M << ++ RT305X_ESW_POC0_DIS_PORT_S), ++ disable_mask << RT305X_ESW_POC0_DIS_PORT_S); ++} ++ ++static int ++rt305x_esw_apply_config(struct switch_dev *dev); ++ ++static void ++rt305x_esw_hw_init(struct rt305x_esw *esw) ++{ ++ int i; ++ u8 port_disable = 0; ++ u8 port_map = RT305X_ESW_PMAP_LLLLLL; ++ ++ /* vodoo from original driver */ ++ rt305x_esw_wr(esw, 0xC8A07850, RT305X_ESW_REG_FCT0); ++ rt305x_esw_wr(esw, 0x00000000, RT305X_ESW_REG_SGC2); ++ /* Port priority 1 for all ports, vlan enabled. */ ++ rt305x_esw_wr(esw, 0x00005555 | ++ (RT305X_ESW_PORTS_ALL << RT305X_ESW_PFC1_EN_VLAN_S), ++ RT305X_ESW_REG_PFC1); ++ ++ /* Enable Back Pressure, and Flow Control */ ++ rt305x_esw_wr(esw, ++ ((RT305X_ESW_PORTS_ALL << RT305X_ESW_POC0_EN_BP_S) | ++ (RT305X_ESW_PORTS_ALL << RT305X_ESW_POC0_EN_FC_S)), ++ RT305X_ESW_REG_POC0); ++ ++ /* Enable Aging, and VLAN TAG removal */ ++ rt305x_esw_wr(esw, ++ ((RT305X_ESW_PORTS_ALL << RT305X_ESW_POC2_ENAGING_S) | ++ (RT305X_ESW_PORTS_NOCPU << RT305X_ESW_POC2_UNTAG_EN_S)), ++ RT305X_ESW_REG_POC2); ++ ++ if (esw->reg_initval_fct2) ++ rt305x_esw_wr(esw, esw->reg_initval_fct2, RT305X_ESW_REG_FCT2); ++ else ++ rt305x_esw_wr(esw, esw->pdata->reg_initval_fct2, RT305X_ESW_REG_FCT2); ++ ++ /* ++ * 300s aging timer, max packet len 1536, broadcast storm prevention ++ * disabled, disable collision abort, mac xor48 hash, 10 packet back ++ * pressure jam, GMII disable was_transmit, back pressure disabled, ++ * 30ms led flash, unmatched IGMP as broadcast, rmc tb fault to all ++ * ports. ++ */ ++ rt305x_esw_wr(esw, 0x0008a301, RT305X_ESW_REG_SGC); ++ ++ /* Setup SoC Port control register */ ++ rt305x_esw_wr(esw, ++ (RT305X_ESW_SOCPC_CRC_PADDING | ++ (RT305X_ESW_PORTS_CPU << RT305X_ESW_SOCPC_DISUN2CPU_S) | ++ (RT305X_ESW_PORTS_CPU << RT305X_ESW_SOCPC_DISMC2CPU_S) | ++ (RT305X_ESW_PORTS_CPU << RT305X_ESW_SOCPC_DISBC2CPU_S)), ++ RT305X_ESW_REG_SOCPC); ++ ++ if (esw->reg_initval_fpa2) ++ rt305x_esw_wr(esw, esw->reg_initval_fpa2, RT305X_ESW_REG_FPA2); ++ else ++ rt305x_esw_wr(esw, esw->pdata->reg_initval_fpa2, RT305X_ESW_REG_FPA2); ++ rt305x_esw_wr(esw, 0x00000000, RT305X_ESW_REG_FPA); ++ ++ /* Force Link/Activity on ports */ ++ rt305x_esw_wr(esw, 0x00000005, RT305X_ESW_REG_P0LED); ++ rt305x_esw_wr(esw, 0x00000005, RT305X_ESW_REG_P1LED); ++ rt305x_esw_wr(esw, 0x00000005, RT305X_ESW_REG_P2LED); ++ rt305x_esw_wr(esw, 0x00000005, RT305X_ESW_REG_P3LED); ++ rt305x_esw_wr(esw, 0x00000005, RT305X_ESW_REG_P4LED); ++ ++ /* Copy disabled port configuration from bootloader setup */ ++ port_disable = rt305x_esw_get_port_disable(esw); ++ for (i = 0; i < 6; i++) ++ esw->ports[i].disable = (port_disable & (1 << i)) != 0; ++ ++ rt305x_mii_write(esw, 0, 31, 0x8000); ++ for (i = 0; i < 5; i++) { ++ if (esw->ports[i].disable) { ++ rt305x_mii_write(esw, i, MII_BMCR, BMCR_PDOWN); ++ } else { ++ rt305x_mii_write(esw, i, MII_BMCR, ++ BMCR_FULLDPLX | ++ BMCR_ANENABLE | ++ BMCR_SPEED100); ++ } ++ /* TX10 waveform coefficient */ ++ rt305x_mii_write(esw, i, 26, 0x1601); ++ /* TX100/TX10 AD/DA current bias */ ++ rt305x_mii_write(esw, i, 29, 0x7058); ++ /* TX100 slew rate control */ ++ rt305x_mii_write(esw, i, 30, 0x0018); ++ } ++ ++ /* PHY IOT */ ++ /* select global register */ ++ rt305x_mii_write(esw, 0, 31, 0x0); ++ /* tune TP_IDL tail and head waveform */ ++ rt305x_mii_write(esw, 0, 22, 0x052f); ++ /* set TX10 signal amplitude threshold to minimum */ ++ rt305x_mii_write(esw, 0, 17, 0x0fe0); ++ /* set squelch amplitude to higher threshold */ ++ rt305x_mii_write(esw, 0, 18, 0x40ba); ++ /* longer TP_IDL tail length */ ++ rt305x_mii_write(esw, 0, 14, 0x65); ++ /* select local register */ ++ rt305x_mii_write(esw, 0, 31, 0x8000); ++ ++ if (esw->port_map) ++ port_map = esw->port_map; ++ else ++ port_map = RT305X_ESW_PMAP_LLLLLL; ++ ++ /* ++ * Unused HW feature, but still nice to be consistent here... ++ * This is also exported to userspace ('lan' attribute) so it's ++ * conveniently usable to decide which ports go into the wan vlan by ++ * default. ++ */ ++ rt305x_esw_rmw(esw, RT305X_ESW_REG_SGC2, ++ RT305X_ESW_SGC2_LAN_PMAP_M << RT305X_ESW_SGC2_LAN_PMAP_S, ++ port_map << RT305X_ESW_SGC2_LAN_PMAP_S); ++ ++ /* make the switch leds blink */ ++ for (i = 0; i < RT305X_ESW_NUM_LEDS; i++) ++ esw->ports[i].led = 0x05; ++ ++ /* Apply the empty config. */ ++ rt305x_esw_apply_config(&esw->swdev); ++} ++ ++static irqreturn_t ++rt305x_esw_interrupt(int irq, void *_esw) ++{ ++ struct rt305x_esw *esw = (struct rt305x_esw *) _esw; ++ u32 status; ++ ++ status = rt305x_esw_rr(esw, RT305X_ESW_REG_ISR); ++ if (status & RT305X_ESW_PORT_ST_CHG) { ++ u32 link = rt305x_esw_rr(esw, RT305X_ESW_REG_POA); ++ link >>= RT305X_ESW_POA_LINK_SHIFT; ++ link &= RT305X_ESW_POA_LINK_MASK; ++ dev_info(esw->dev, "link changed 0x%02X\n", link); ++ } ++ rt305x_esw_wr(esw, RT305X_ESW_PORT_ST_CHG, RT305X_ESW_REG_ISR); ++ ++ return IRQ_HANDLED; ++} ++ ++static void ++rt305x_esw_request_irq(struct rt305x_esw *esw) ++{ ++ /* Only unmask the port change interrupt */ ++ rt305x_esw_wr(esw, ~RT305X_ESW_PORT_ST_CHG, RT305X_ESW_REG_IMR); ++ ++ /* request the irq handler */ ++ request_irq(esw->irq, rt305x_esw_interrupt, 0, "esw", esw); ++} ++ ++static int ++rt305x_esw_apply_config(struct switch_dev *dev) ++{ ++ struct rt305x_esw *esw = container_of(dev, struct rt305x_esw, swdev); ++ int i; ++ u8 disable = 0; ++ u8 doubletag = 0; ++ u8 en_vlan = 0; ++ u8 untag = 0; ++ ++ for (i = 0; i < RT305X_ESW_NUM_VLANS; i++) { ++ u32 vid, vmsc; ++ if (esw->global_vlan_enable) { ++ vid = esw->vlans[i].vid; ++ vmsc = esw->vlans[i].ports; ++ } else { ++ vid = RT305X_ESW_VLAN_NONE; ++ vmsc = RT305X_ESW_PORTS_NONE; ++ } ++ rt305x_esw_set_vlan_id(esw, i, vid); ++ rt305x_esw_set_vmsc(esw, i, vmsc); ++ } ++ ++ for (i = 0; i < RT305X_ESW_NUM_PORTS; i++) { ++ u32 pvid; ++ disable |= esw->ports[i].disable << i; ++ if (esw->global_vlan_enable) { ++ doubletag |= esw->ports[i].doubletag << i; ++ en_vlan |= 1 << i; ++ untag |= esw->ports[i].untag << i; ++ pvid = esw->ports[i].pvid; ++ } else { ++ int x = esw->alt_vlan_disable ? 0 : 1; ++ doubletag |= x << i; ++ en_vlan |= x << i; ++ untag |= x << i; ++ pvid = 0; ++ } ++ rt305x_esw_set_pvid(esw, i, pvid); ++ if (i < RT305X_ESW_NUM_LEDS) ++ rt305x_esw_wr(esw, esw->ports[i].led, ++ RT305X_ESW_REG_P0LED + 4*i); ++ } ++ ++ rt305x_esw_set_port_disable(esw, disable); ++ rt305x_esw_rmw(esw, RT305X_ESW_REG_SGC2, ++ (RT305X_ESW_SGC2_DOUBLE_TAG_M << ++ RT305X_ESW_SGC2_DOUBLE_TAG_S), ++ doubletag << RT305X_ESW_SGC2_DOUBLE_TAG_S); ++ rt305x_esw_rmw(esw, RT305X_ESW_REG_PFC1, ++ RT305X_ESW_PFC1_EN_VLAN_M << RT305X_ESW_PFC1_EN_VLAN_S, ++ en_vlan << RT305X_ESW_PFC1_EN_VLAN_S); ++ rt305x_esw_rmw(esw, RT305X_ESW_REG_POC2, ++ RT305X_ESW_POC2_UNTAG_EN_M << RT305X_ESW_POC2_UNTAG_EN_S, ++ untag << RT305X_ESW_POC2_UNTAG_EN_S); ++ ++ if (!esw->global_vlan_enable) { ++ /* ++ * Still need to put all ports into vlan 0 or they'll be ++ * isolated. ++ * NOTE: vlan 0 is special, no vlan tag is prepended ++ */ ++ rt305x_esw_set_vlan_id(esw, 0, 0); ++ rt305x_esw_set_vmsc(esw, 0, RT305X_ESW_PORTS_ALL); ++ } ++ ++ return 0; ++} ++ ++static int ++rt305x_esw_reset_switch(struct switch_dev *dev) ++{ ++ struct rt305x_esw *esw = container_of(dev, struct rt305x_esw, swdev); ++ esw->global_vlan_enable = 0; ++ memset(esw->ports, 0, sizeof(esw->ports)); ++ memset(esw->vlans, 0, sizeof(esw->vlans)); ++ rt305x_esw_hw_init(esw); ++ ++ return 0; ++} ++ ++static int ++rt305x_esw_get_vlan_enable(struct switch_dev *dev, ++ const struct switch_attr *attr, ++ struct switch_val *val) ++{ ++ struct rt305x_esw *esw = container_of(dev, struct rt305x_esw, swdev); ++ ++ val->value.i = esw->global_vlan_enable; ++ ++ return 0; ++} ++ ++static int ++rt305x_esw_set_vlan_enable(struct switch_dev *dev, ++ const struct switch_attr *attr, ++ struct switch_val *val) ++{ ++ struct rt305x_esw *esw = container_of(dev, struct rt305x_esw, swdev); ++ ++ esw->global_vlan_enable = val->value.i != 0; ++ ++ return 0; ++} ++ ++static int ++rt305x_esw_get_alt_vlan_disable(struct switch_dev *dev, ++ const struct switch_attr *attr, ++ struct switch_val *val) ++{ ++ struct rt305x_esw *esw = container_of(dev, struct rt305x_esw, swdev); ++ ++ val->value.i = esw->alt_vlan_disable; ++ ++ return 0; ++} ++ ++static int ++rt305x_esw_set_alt_vlan_disable(struct switch_dev *dev, ++ const struct switch_attr *attr, ++ struct switch_val *val) ++{ ++ struct rt305x_esw *esw = container_of(dev, struct rt305x_esw, swdev); ++ ++ esw->alt_vlan_disable = val->value.i != 0; ++ ++ return 0; ++} ++ ++static int ++rt305x_esw_get_port_link(struct switch_dev *dev, ++ int port, ++ struct switch_port_link *link) ++{ ++ struct rt305x_esw *esw = container_of(dev, struct rt305x_esw, swdev); ++ u32 speed, poa; ++ ++ if (port < 0 || port >= RT305X_ESW_NUM_PORTS) ++ return -EINVAL; ++ ++ poa = rt305x_esw_rr(esw, RT305X_ESW_REG_POA) >> port; ++ ++ link->link = (poa >> RT305X_ESW_LINK_S) & 1; ++ link->duplex = (poa >> RT305X_ESW_DUPLEX_S) & 1; ++ if (port < RT305X_ESW_NUM_LEDS) { ++ speed = (poa >> RT305X_ESW_SPD_S) & 1; ++ } else { ++ if (port == RT305X_ESW_NUM_PORTS - 1) ++ poa >>= 1; ++ speed = (poa >> RT305X_ESW_SPD_S) & 3; ++ } ++ switch (speed) { ++ case 0: ++ link->speed = SWITCH_PORT_SPEED_10; ++ break; ++ case 1: ++ link->speed = SWITCH_PORT_SPEED_100; ++ break; ++ case 2: ++ case 3: /* forced gige speed can be 2 or 3 */ ++ link->speed = SWITCH_PORT_SPEED_1000; ++ break; ++ default: ++ link->speed = SWITCH_PORT_SPEED_UNKNOWN; ++ break; ++ } ++ ++ return 0; ++} ++ ++static int ++rt305x_esw_get_port_bool(struct switch_dev *dev, ++ const struct switch_attr *attr, ++ struct switch_val *val) ++{ ++ struct rt305x_esw *esw = container_of(dev, struct rt305x_esw, swdev); ++ int idx = val->port_vlan; ++ u32 x, reg, shift; ++ ++ if (idx < 0 || idx >= RT305X_ESW_NUM_PORTS) ++ return -EINVAL; ++ ++ switch (attr->id) { ++ case RT305X_ESW_ATTR_PORT_DISABLE: ++ reg = RT305X_ESW_REG_POC0; ++ shift = RT305X_ESW_POC0_DIS_PORT_S; ++ break; ++ case RT305X_ESW_ATTR_PORT_DOUBLETAG: ++ reg = RT305X_ESW_REG_SGC2; ++ shift = RT305X_ESW_SGC2_DOUBLE_TAG_S; ++ break; ++ case RT305X_ESW_ATTR_PORT_UNTAG: ++ reg = RT305X_ESW_REG_POC2; ++ shift = RT305X_ESW_POC2_UNTAG_EN_S; ++ break; ++ case RT305X_ESW_ATTR_PORT_LAN: ++ reg = RT305X_ESW_REG_SGC2; ++ shift = RT305X_ESW_SGC2_LAN_PMAP_S; ++ if (idx >= RT305X_ESW_NUM_LANWAN) ++ return -EINVAL; ++ break; ++ default: ++ return -EINVAL; ++ } ++ ++ x = rt305x_esw_rr(esw, reg); ++ val->value.i = (x >> (idx + shift)) & 1; ++ ++ return 0; ++} ++ ++static int ++rt305x_esw_set_port_bool(struct switch_dev *dev, ++ const struct switch_attr *attr, ++ struct switch_val *val) ++{ ++ struct rt305x_esw *esw = container_of(dev, struct rt305x_esw, swdev); ++ int idx = val->port_vlan; ++ ++ if (idx < 0 || idx >= RT305X_ESW_NUM_PORTS || ++ val->value.i < 0 || val->value.i > 1) ++ return -EINVAL; ++ ++ switch (attr->id) { ++ case RT305X_ESW_ATTR_PORT_DISABLE: ++ esw->ports[idx].disable = val->value.i; ++ break; ++ case RT305X_ESW_ATTR_PORT_DOUBLETAG: ++ esw->ports[idx].doubletag = val->value.i; ++ break; ++ case RT305X_ESW_ATTR_PORT_UNTAG: ++ esw->ports[idx].untag = val->value.i; ++ break; ++ default: ++ return -EINVAL; ++ } ++ ++ return 0; ++} ++ ++static int ++rt305x_esw_get_port_recv_badgood(struct switch_dev *dev, ++ const struct switch_attr *attr, ++ struct switch_val *val) ++{ ++ struct rt305x_esw *esw = container_of(dev, struct rt305x_esw, swdev); ++ int idx = val->port_vlan; ++ int shift = attr->id == RT305X_ESW_ATTR_PORT_RECV_GOOD ? 0 : 16; ++ u32 reg; ++ ++ if (idx < 0 || idx >= RT305X_ESW_NUM_LANWAN) ++ return -EINVAL; ++ ++ reg = rt305x_esw_rr(esw, RT305X_ESW_REG_P0PC + 4*idx); ++ val->value.i = (reg >> shift) & 0xffff; ++ ++ return 0; ++} ++ ++static int ++rt305x_esw_get_port_led(struct switch_dev *dev, ++ const struct switch_attr *attr, ++ struct switch_val *val) ++{ ++ struct rt305x_esw *esw = container_of(dev, struct rt305x_esw, swdev); ++ int idx = val->port_vlan; ++ ++ if (idx < 0 || idx >= RT305X_ESW_NUM_PORTS || ++ idx >= RT305X_ESW_NUM_LEDS) ++ return -EINVAL; ++ ++ val->value.i = rt305x_esw_rr(esw, RT305X_ESW_REG_P0LED + 4*idx); ++ ++ return 0; ++} ++ ++static int ++rt305x_esw_set_port_led(struct switch_dev *dev, ++ const struct switch_attr *attr, ++ struct switch_val *val) ++{ ++ struct rt305x_esw *esw = container_of(dev, struct rt305x_esw, swdev); ++ int idx = val->port_vlan; ++ ++ if (idx < 0 || idx >= RT305X_ESW_NUM_LEDS) ++ return -EINVAL; ++ ++ esw->ports[idx].led = val->value.i; ++ ++ return 0; ++} ++ ++static int ++rt305x_esw_get_port_pvid(struct switch_dev *dev, int port, int *val) ++{ ++ struct rt305x_esw *esw = container_of(dev, struct rt305x_esw, swdev); ++ ++ if (port >= RT305X_ESW_NUM_PORTS) ++ return -EINVAL; ++ ++ *val = rt305x_esw_get_pvid(esw, port); ++ ++ return 0; ++} ++ ++static int ++rt305x_esw_set_port_pvid(struct switch_dev *dev, int port, int val) ++{ ++ struct rt305x_esw *esw = container_of(dev, struct rt305x_esw, swdev); ++ ++ if (port >= RT305X_ESW_NUM_PORTS) ++ return -EINVAL; ++ ++ esw->ports[port].pvid = val; ++ ++ return 0; ++} ++ ++static int ++rt305x_esw_get_vlan_ports(struct switch_dev *dev, struct switch_val *val) ++{ ++ struct rt305x_esw *esw = container_of(dev, struct rt305x_esw, swdev); ++ u32 vmsc, poc2; ++ int vlan_idx = -1; ++ int i; ++ ++ val->len = 0; ++ ++ if (val->port_vlan < 0 || val->port_vlan >= RT305X_ESW_NUM_VIDS) ++ return -EINVAL; ++ ++ /* valid vlan? */ ++ for (i = 0; i < RT305X_ESW_NUM_VLANS; i++) { ++ if (rt305x_esw_get_vlan_id(esw, i) == val->port_vlan && ++ rt305x_esw_get_vmsc(esw, i) != RT305X_ESW_PORTS_NONE) { ++ vlan_idx = i; ++ break; ++ } ++ } ++ ++ if (vlan_idx == -1) ++ return -EINVAL; ++ ++ vmsc = rt305x_esw_get_vmsc(esw, vlan_idx); ++ poc2 = rt305x_esw_rr(esw, RT305X_ESW_REG_POC2); ++ ++ for (i = 0; i < RT305X_ESW_NUM_PORTS; i++) { ++ struct switch_port *p; ++ int port_mask = 1 << i; ++ ++ if (!(vmsc & port_mask)) ++ continue; ++ ++ p = &val->value.ports[val->len++]; ++ p->id = i; ++ if (poc2 & (port_mask << RT305X_ESW_POC2_UNTAG_EN_S)) ++ p->flags = 0; ++ else ++ p->flags = 1 << SWITCH_PORT_FLAG_TAGGED; ++ } ++ ++ return 0; ++} ++ ++static int ++rt305x_esw_set_vlan_ports(struct switch_dev *dev, struct switch_val *val) ++{ ++ struct rt305x_esw *esw = container_of(dev, struct rt305x_esw, swdev); ++ int ports; ++ int vlan_idx = -1; ++ int i; ++ ++ if (val->port_vlan < 0 || val->port_vlan >= RT305X_ESW_NUM_VIDS || ++ val->len > RT305X_ESW_NUM_PORTS) ++ return -EINVAL; ++ ++ /* one of the already defined vlans? */ ++ for (i = 0; i < RT305X_ESW_NUM_VLANS; i++) { ++ if (esw->vlans[i].vid == val->port_vlan && ++ esw->vlans[i].ports != RT305X_ESW_PORTS_NONE) { ++ vlan_idx = i; ++ break; ++ } ++ } ++ ++ /* select a free slot */ ++ for (i = 0; vlan_idx == -1 && i < RT305X_ESW_NUM_VLANS; i++) { ++ if (esw->vlans[i].ports == RT305X_ESW_PORTS_NONE) ++ vlan_idx = i; ++ } ++ ++ /* bail if all slots are in use */ ++ if (vlan_idx == -1) ++ return -EINVAL; ++ ++ ports = RT305X_ESW_PORTS_NONE; ++ for (i = 0; i < val->len; i++) { ++ struct switch_port *p = &val->value.ports[i]; ++ int port_mask = 1 << p->id; ++ bool untagged = !(p->flags & (1 << SWITCH_PORT_FLAG_TAGGED)); ++ ++ if (p->id >= RT305X_ESW_NUM_PORTS) ++ return -EINVAL; ++ ++ ports |= port_mask; ++ esw->ports[p->id].untag = untagged; ++ } ++ esw->vlans[vlan_idx].ports = ports; ++ if (ports == RT305X_ESW_PORTS_NONE) ++ esw->vlans[vlan_idx].vid = RT305X_ESW_VLAN_NONE; ++ else ++ esw->vlans[vlan_idx].vid = val->port_vlan; ++ ++ return 0; ++} ++ ++static const struct switch_attr rt305x_esw_global[] = { ++ { ++ .type = SWITCH_TYPE_INT, ++ .name = "enable_vlan", ++ .description = "VLAN mode (1:enabled)", ++ .max = 1, ++ .id = RT305X_ESW_ATTR_ENABLE_VLAN, ++ .get = rt305x_esw_get_vlan_enable, ++ .set = rt305x_esw_set_vlan_enable, ++ }, ++ { ++ .type = SWITCH_TYPE_INT, ++ .name = "alternate_vlan_disable", ++ .description = "Use en_vlan instead of doubletag to disable" ++ " VLAN mode", ++ .max = 1, ++ .id = RT305X_ESW_ATTR_ALT_VLAN_DISABLE, ++ .get = rt305x_esw_get_alt_vlan_disable, ++ .set = rt305x_esw_set_alt_vlan_disable, ++ }, ++}; ++ ++static const struct switch_attr rt305x_esw_port[] = { ++ { ++ .type = SWITCH_TYPE_INT, ++ .name = "disable", ++ .description = "Port state (1:disabled)", ++ .max = 1, ++ .id = RT305X_ESW_ATTR_PORT_DISABLE, ++ .get = rt305x_esw_get_port_bool, ++ .set = rt305x_esw_set_port_bool, ++ }, ++ { ++ .type = SWITCH_TYPE_INT, ++ .name = "doubletag", ++ .description = "Double tagging for incoming vlan packets " ++ "(1:enabled)", ++ .max = 1, ++ .id = RT305X_ESW_ATTR_PORT_DOUBLETAG, ++ .get = rt305x_esw_get_port_bool, ++ .set = rt305x_esw_set_port_bool, ++ }, ++ { ++ .type = SWITCH_TYPE_INT, ++ .name = "untag", ++ .description = "Untag (1:strip outgoing vlan tag)", ++ .max = 1, ++ .id = RT305X_ESW_ATTR_PORT_UNTAG, ++ .get = rt305x_esw_get_port_bool, ++ .set = rt305x_esw_set_port_bool, ++ }, ++ { ++ .type = SWITCH_TYPE_INT, ++ .name = "led", ++ .description = "LED mode (0:link, 1:100m, 2:duplex, 3:activity," ++ " 4:collision, 5:linkact, 6:duplcoll, 7:10mact," ++ " 8:100mact, 10:blink, 12:on)", ++ .max = 15, ++ .id = RT305X_ESW_ATTR_PORT_LED, ++ .get = rt305x_esw_get_port_led, ++ .set = rt305x_esw_set_port_led, ++ }, ++ { ++ .type = SWITCH_TYPE_INT, ++ .name = "lan", ++ .description = "HW port group (0:wan, 1:lan)", ++ .max = 1, ++ .id = RT305X_ESW_ATTR_PORT_LAN, ++ .get = rt305x_esw_get_port_bool, ++ }, ++ { ++ .type = SWITCH_TYPE_INT, ++ .name = "recv_bad", ++ .description = "Receive bad packet counter", ++ .id = RT305X_ESW_ATTR_PORT_RECV_BAD, ++ .get = rt305x_esw_get_port_recv_badgood, ++ }, ++ { ++ .type = SWITCH_TYPE_INT, ++ .name = "recv_good", ++ .description = "Receive good packet counter", ++ .id = RT305X_ESW_ATTR_PORT_RECV_GOOD, ++ .get = rt305x_esw_get_port_recv_badgood, ++ }, ++}; ++ ++static const struct switch_attr rt305x_esw_vlan[] = { ++}; ++ ++static const struct switch_dev_ops rt305x_esw_ops = { ++ .attr_global = { ++ .attr = rt305x_esw_global, ++ .n_attr = ARRAY_SIZE(rt305x_esw_global), ++ }, ++ .attr_port = { ++ .attr = rt305x_esw_port, ++ .n_attr = ARRAY_SIZE(rt305x_esw_port), ++ }, ++ .attr_vlan = { ++ .attr = rt305x_esw_vlan, ++ .n_attr = ARRAY_SIZE(rt305x_esw_vlan), ++ }, ++ .get_vlan_ports = rt305x_esw_get_vlan_ports, ++ .set_vlan_ports = rt305x_esw_set_vlan_ports, ++ .get_port_pvid = rt305x_esw_get_port_pvid, ++ .set_port_pvid = rt305x_esw_set_port_pvid, ++ .get_port_link = rt305x_esw_get_port_link, ++ .apply_config = rt305x_esw_apply_config, ++ .reset_switch = rt305x_esw_reset_switch, ++}; ++ ++static struct rt305x_esw_platform_data rt3050_esw_data = { ++ /* All ports are LAN ports. */ ++ .vlan_config = RT305X_ESW_VLAN_CONFIG_NONE, ++ .reg_initval_fct2 = 0x00d6500c, ++ /* ++ * ext phy base addr 31, enable port 5 polling, rx/tx clock skew 1, ++ * turbo mii off, rgmi 3.3v off ++ * port5: disabled ++ * port6: enabled, gige, full-duplex, rx/tx-flow-control ++ */ ++ .reg_initval_fpa2 = 0x3f502b28, ++}; ++ ++static const struct of_device_id ralink_esw_match[] = { ++ { .compatible = "ralink,rt3050-esw", .data = &rt3050_esw_data }, ++ {}, ++}; ++MODULE_DEVICE_TABLE(of, ralink_esw_match); ++ ++static int ++rt305x_esw_probe(struct platform_device *pdev) ++{ ++ struct device_node *np = pdev->dev.of_node; ++ const struct rt305x_esw_platform_data *pdata; ++ const __be32 *port_map, *reg_init; ++ struct rt305x_esw *esw; ++ struct switch_dev *swdev; ++ struct resource *res, *irq; ++ int err; ++ ++ pdata = pdev->dev.platform_data; ++ if (!pdata) { ++ const struct of_device_id *match; ++ match = of_match_device(ralink_esw_match, &pdev->dev); ++ if (match) ++ pdata = (struct rt305x_esw_platform_data *) match->data; ++ } ++ if (!pdata) ++ return -EINVAL; ++ ++ res = platform_get_resource(pdev, IORESOURCE_MEM, 0); ++ if (!res) { ++ dev_err(&pdev->dev, "no memory resource found\n"); ++ return -ENOMEM; ++ } ++ ++ irq = platform_get_resource(pdev, IORESOURCE_IRQ, 0); ++ if (!irq) { ++ dev_err(&pdev->dev, "no irq resource found\n"); ++ return -ENOMEM; ++ } ++ ++ esw = kzalloc(sizeof(struct rt305x_esw), GFP_KERNEL); ++ if (!esw) { ++ dev_err(&pdev->dev, "no memory for private data\n"); ++ return -ENOMEM; ++ } ++ ++ esw->dev = &pdev->dev; ++ esw->irq = irq->start; ++ esw->base = ioremap(res->start, resource_size(res)); ++ if (!esw->base) { ++ dev_err(&pdev->dev, "ioremap failed\n"); ++ err = -ENOMEM; ++ goto free_esw; ++ } ++ ++ port_map = of_get_property(np, "ralink,portmap", NULL); ++ if (port_map) ++ esw->port_map = be32_to_cpu(*port_map); ++ ++ reg_init = of_get_property(np, "ralink,fct2", NULL); ++ if (reg_init) ++ esw->reg_initval_fct2 = be32_to_cpu(*reg_init); ++ ++ reg_init = of_get_property(np, "ralink,fpa2", NULL); ++ if (reg_init) ++ esw->reg_initval_fpa2 = be32_to_cpu(*reg_init); ++ ++ swdev = &esw->swdev; ++ swdev->of_node = pdev->dev.of_node; ++ swdev->name = "rt305x-esw"; ++ swdev->alias = "rt305x"; ++ swdev->cpu_port = RT305X_ESW_PORT6; ++ swdev->ports = RT305X_ESW_NUM_PORTS; ++ swdev->vlans = RT305X_ESW_NUM_VIDS; ++ swdev->ops = &rt305x_esw_ops; ++ ++ err = register_switch(swdev, NULL); ++ if (err < 0) { ++ dev_err(&pdev->dev, "register_switch failed\n"); ++ goto unmap_base; ++ } ++ ++ platform_set_drvdata(pdev, esw); ++ ++ esw->pdata = pdata; ++ spin_lock_init(&esw->reg_rw_lock); ++ rt305x_esw_hw_init(esw); ++ rt305x_esw_request_irq(esw); ++ ++ return 0; ++ ++unmap_base: ++ iounmap(esw->base); ++free_esw: ++ kfree(esw); ++ return err; ++} ++ ++static int ++rt305x_esw_remove(struct platform_device *pdev) ++{ ++ struct rt305x_esw *esw; ++ ++ esw = platform_get_drvdata(pdev); ++ if (esw) { ++ unregister_switch(&esw->swdev); ++ platform_set_drvdata(pdev, NULL); ++ iounmap(esw->base); ++ kfree(esw); ++ } ++ ++ return 0; ++} ++ ++static struct platform_driver rt305x_esw_driver = { ++ .probe = rt305x_esw_probe, ++ .remove = rt305x_esw_remove, ++ .driver = { ++ .name = "rt305x-esw", ++ .owner = THIS_MODULE, ++ .of_match_table = ralink_esw_match, ++ }, ++}; ++ ++static int __init ++rt305x_esw_init(void) ++{ ++ return platform_driver_register(&rt305x_esw_driver); ++} ++ ++static void ++rt305x_esw_exit(void) ++{ ++ platform_driver_unregister(&rt305x_esw_driver); ++} +--- /dev/null ++++ b/drivers/net/ethernet/ramips/ramips_eth.h +@@ -0,0 +1,375 @@ ++/* ++ * This program is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License as published by ++ * the Free Software Foundation; version 2 of the License ++ * ++ * This program is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ * GNU General Public License for more details. ++ * ++ * You should have received a copy of the GNU General Public License ++ * along with this program; if not, write to the Free Software ++ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA. ++ * ++ * based on Ralink SDK3.3 ++ * Copyright (C) 2009 John Crispin ++ */ ++ ++#ifndef RAMIPS_ETH_H ++#define RAMIPS_ETH_H ++ ++#include ++#include ++#include ++#include ++ ++#define NUM_RX_DESC 256 ++#define NUM_TX_DESC 256 ++ ++#define RAMIPS_DELAY_EN_INT 0x80 ++#define RAMIPS_DELAY_MAX_INT 0x04 ++#define RAMIPS_DELAY_MAX_TOUT 0x04 ++#define RAMIPS_DELAY_CHAN (((RAMIPS_DELAY_EN_INT | RAMIPS_DELAY_MAX_INT) << 8) | RAMIPS_DELAY_MAX_TOUT) ++#define RAMIPS_DELAY_INIT ((RAMIPS_DELAY_CHAN << 16) | RAMIPS_DELAY_CHAN) ++#define RAMIPS_PSE_FQFC_CFG_INIT 0x80504000 ++ ++/* interrupt bits */ ++#define RAMIPS_CNT_PPE_AF BIT(31) ++#define RAMIPS_CNT_GDM_AF BIT(29) ++#define RAMIPS_PSE_P2_FC BIT(26) ++#define RAMIPS_PSE_BUF_DROP BIT(24) ++#define RAMIPS_GDM_OTHER_DROP BIT(23) ++#define RAMIPS_PSE_P1_FC BIT(22) ++#define RAMIPS_PSE_P0_FC BIT(21) ++#define RAMIPS_PSE_FQ_EMPTY BIT(20) ++#define RAMIPS_GE1_STA_CHG BIT(18) ++#define RAMIPS_TX_COHERENT BIT(17) ++#define RAMIPS_RX_COHERENT BIT(16) ++#define RAMIPS_TX_DONE_INT3 BIT(11) ++#define RAMIPS_TX_DONE_INT2 BIT(10) ++#define RAMIPS_TX_DONE_INT1 BIT(9) ++#define RAMIPS_TX_DONE_INT0 BIT(8) ++#define RAMIPS_RX_DONE_INT0 BIT(2) ++#define RAMIPS_TX_DLY_INT BIT(1) ++#define RAMIPS_RX_DLY_INT BIT(0) ++ ++#define RT5350_RX_DLY_INT BIT(30) ++#define RT5350_TX_DLY_INT BIT(28) ++ ++/* registers */ ++#define RAMIPS_FE_OFFSET 0x0000 ++#define RAMIPS_GDMA_OFFSET 0x0020 ++#define RAMIPS_PSE_OFFSET 0x0040 ++#define RAMIPS_GDMA2_OFFSET 0x0060 ++#define RAMIPS_CDMA_OFFSET 0x0080 ++#define RAMIPS_PDMA_OFFSET 0x0100 ++#define RAMIPS_PPE_OFFSET 0x0200 ++#define RAMIPS_CMTABLE_OFFSET 0x0400 ++#define RAMIPS_POLICYTABLE_OFFSET 0x1000 ++ ++#define RT5350_PDMA_OFFSET 0x0800 ++#define RT5350_SDM_OFFSET 0x0c00 ++ ++#define RAMIPS_MDIO_ACCESS (RAMIPS_FE_OFFSET + 0x00) ++#define RAMIPS_MDIO_CFG (RAMIPS_FE_OFFSET + 0x04) ++#define RAMIPS_FE_GLO_CFG (RAMIPS_FE_OFFSET + 0x08) ++#define RAMIPS_FE_RST_GL (RAMIPS_FE_OFFSET + 0x0C) ++#define RAMIPS_FE_INT_STATUS (RAMIPS_FE_OFFSET + 0x10) ++#define RAMIPS_FE_INT_ENABLE (RAMIPS_FE_OFFSET + 0x14) ++#define RAMIPS_MDIO_CFG2 (RAMIPS_FE_OFFSET + 0x18) ++#define RAMIPS_FOC_TS_T (RAMIPS_FE_OFFSET + 0x1C) ++ ++#define RAMIPS_GDMA1_FWD_CFG (RAMIPS_GDMA_OFFSET + 0x00) ++#define RAMIPS_GDMA1_SCH_CFG (RAMIPS_GDMA_OFFSET + 0x04) ++#define RAMIPS_GDMA1_SHPR_CFG (RAMIPS_GDMA_OFFSET + 0x08) ++#define RAMIPS_GDMA1_MAC_ADRL (RAMIPS_GDMA_OFFSET + 0x0C) ++#define RAMIPS_GDMA1_MAC_ADRH (RAMIPS_GDMA_OFFSET + 0x10) ++ ++#define RAMIPS_GDMA2_FWD_CFG (RAMIPS_GDMA2_OFFSET + 0x00) ++#define RAMIPS_GDMA2_SCH_CFG (RAMIPS_GDMA2_OFFSET + 0x04) ++#define RAMIPS_GDMA2_SHPR_CFG (RAMIPS_GDMA2_OFFSET + 0x08) ++#define RAMIPS_GDMA2_MAC_ADRL (RAMIPS_GDMA2_OFFSET + 0x0C) ++#define RAMIPS_GDMA2_MAC_ADRH (RAMIPS_GDMA2_OFFSET + 0x10) ++ ++#define RAMIPS_PSE_FQ_CFG (RAMIPS_PSE_OFFSET + 0x00) ++#define RAMIPS_CDMA_FC_CFG (RAMIPS_PSE_OFFSET + 0x04) ++#define RAMIPS_GDMA1_FC_CFG (RAMIPS_PSE_OFFSET + 0x08) ++#define RAMIPS_GDMA2_FC_CFG (RAMIPS_PSE_OFFSET + 0x0C) ++ ++#define RAMIPS_CDMA_CSG_CFG (RAMIPS_CDMA_OFFSET + 0x00) ++#define RAMIPS_CDMA_SCH_CFG (RAMIPS_CDMA_OFFSET + 0x04) ++ ++#define RT5350_TX_BASE_PTR0 (RT5350_PDMA_OFFSET + 0x00) ++#define RT5350_TX_MAX_CNT0 (RT5350_PDMA_OFFSET + 0x04) ++#define RT5350_TX_CTX_IDX0 (RT5350_PDMA_OFFSET + 0x08) ++#define RT5350_TX_DTX_IDX0 (RT5350_PDMA_OFFSET + 0x0C) ++#define RT5350_TX_BASE_PTR1 (RT5350_PDMA_OFFSET + 0x10) ++#define RT5350_TX_MAX_CNT1 (RT5350_PDMA_OFFSET + 0x14) ++#define RT5350_TX_CTX_IDX1 (RT5350_PDMA_OFFSET + 0x18) ++#define RT5350_TX_DTX_IDX1 (RT5350_PDMA_OFFSET + 0x1C) ++#define RT5350_TX_BASE_PTR2 (RT5350_PDMA_OFFSET + 0x20) ++#define RT5350_TX_MAX_CNT2 (RT5350_PDMA_OFFSET + 0x24) ++#define RT5350_TX_CTX_IDX2 (RT5350_PDMA_OFFSET + 0x28) ++#define RT5350_TX_DTX_IDX2 (RT5350_PDMA_OFFSET + 0x2C) ++#define RT5350_TX_BASE_PTR3 (RT5350_PDMA_OFFSET + 0x30) ++#define RT5350_TX_MAX_CNT3 (RT5350_PDMA_OFFSET + 0x34) ++#define RT5350_TX_CTX_IDX3 (RT5350_PDMA_OFFSET + 0x38) ++#define RT5350_TX_DTX_IDX3 (RT5350_PDMA_OFFSET + 0x3C) ++#define RT5350_RX_BASE_PTR0 (RT5350_PDMA_OFFSET + 0x100) ++#define RT5350_RX_MAX_CNT0 (RT5350_PDMA_OFFSET + 0x104) ++#define RT5350_RX_CALC_IDX0 (RT5350_PDMA_OFFSET + 0x108) ++#define RT5350_RX_DRX_IDX0 (RT5350_PDMA_OFFSET + 0x10C) ++#define RT5350_RX_BASE_PTR1 (RT5350_PDMA_OFFSET + 0x110) ++#define RT5350_RX_MAX_CNT1 (RT5350_PDMA_OFFSET + 0x114) ++#define RT5350_RX_CALC_IDX1 (RT5350_PDMA_OFFSET + 0x118) ++#define RT5350_RX_DRX_IDX1 (RT5350_PDMA_OFFSET + 0x11C) ++#define RT5350_PDMA_GLO_CFG (RT5350_PDMA_OFFSET + 0x204) ++#define RT5350_PDMA_RST_CFG (RT5350_PDMA_OFFSET + 0x208) ++#define RT5350_DLY_INT_CFG (RT5350_PDMA_OFFSET + 0x20c) ++#define RT5350_FE_INT_STATUS (RT5350_PDMA_OFFSET + 0x220) ++#define RT5350_FE_INT_ENABLE (RT5350_PDMA_OFFSET + 0x228) ++#define RT5350_PDMA_SCH_CFG (RT5350_PDMA_OFFSET + 0x280) ++ ++ ++#define RAMIPS_PDMA_GLO_CFG (RAMIPS_PDMA_OFFSET + 0x00) ++#define RAMIPS_PDMA_RST_CFG (RAMIPS_PDMA_OFFSET + 0x04) ++#define RAMIPS_PDMA_SCH_CFG (RAMIPS_PDMA_OFFSET + 0x08) ++#define RAMIPS_DLY_INT_CFG (RAMIPS_PDMA_OFFSET + 0x0C) ++#define RAMIPS_TX_BASE_PTR0 (RAMIPS_PDMA_OFFSET + 0x10) ++#define RAMIPS_TX_MAX_CNT0 (RAMIPS_PDMA_OFFSET + 0x14) ++#define RAMIPS_TX_CTX_IDX0 (RAMIPS_PDMA_OFFSET + 0x18) ++#define RAMIPS_TX_DTX_IDX0 (RAMIPS_PDMA_OFFSET + 0x1C) ++#define RAMIPS_TX_BASE_PTR1 (RAMIPS_PDMA_OFFSET + 0x20) ++#define RAMIPS_TX_MAX_CNT1 (RAMIPS_PDMA_OFFSET + 0x24) ++#define RAMIPS_TX_CTX_IDX1 (RAMIPS_PDMA_OFFSET + 0x28) ++#define RAMIPS_TX_DTX_IDX1 (RAMIPS_PDMA_OFFSET + 0x2C) ++#define RAMIPS_RX_BASE_PTR0 (RAMIPS_PDMA_OFFSET + 0x30) ++#define RAMIPS_RX_MAX_CNT0 (RAMIPS_PDMA_OFFSET + 0x34) ++#define RAMIPS_RX_CALC_IDX0 (RAMIPS_PDMA_OFFSET + 0x38) ++#define RAMIPS_RX_DRX_IDX0 (RAMIPS_PDMA_OFFSET + 0x3C) ++#define RAMIPS_TX_BASE_PTR2 (RAMIPS_PDMA_OFFSET + 0x40) ++#define RAMIPS_TX_MAX_CNT2 (RAMIPS_PDMA_OFFSET + 0x44) ++#define RAMIPS_TX_CTX_IDX2 (RAMIPS_PDMA_OFFSET + 0x48) ++#define RAMIPS_TX_DTX_IDX2 (RAMIPS_PDMA_OFFSET + 0x4C) ++#define RAMIPS_TX_BASE_PTR3 (RAMIPS_PDMA_OFFSET + 0x50) ++#define RAMIPS_TX_MAX_CNT3 (RAMIPS_PDMA_OFFSET + 0x54) ++#define RAMIPS_TX_CTX_IDX3 (RAMIPS_PDMA_OFFSET + 0x58) ++#define RAMIPS_TX_DTX_IDX3 (RAMIPS_PDMA_OFFSET + 0x5C) ++#define RAMIPS_RX_BASE_PTR1 (RAMIPS_PDMA_OFFSET + 0x60) ++#define RAMIPS_RX_MAX_CNT1 (RAMIPS_PDMA_OFFSET + 0x64) ++#define RAMIPS_RX_CALC_IDX1 (RAMIPS_PDMA_OFFSET + 0x68) ++#define RAMIPS_RX_DRX_IDX1 (RAMIPS_PDMA_OFFSET + 0x6C) ++ ++#define RT5350_SDM_CFG (RT5350_SDM_OFFSET + 0x00) //Switch DMA configuration ++#define RT5350_SDM_RRING (RT5350_SDM_OFFSET + 0x04) //Switch DMA Rx Ring ++#define RT5350_SDM_TRING (RT5350_SDM_OFFSET + 0x08) //Switch DMA Tx Ring ++#define RT5350_SDM_MAC_ADRL (RT5350_SDM_OFFSET + 0x0C) //Switch MAC address LSB ++#define RT5350_SDM_MAC_ADRH (RT5350_SDM_OFFSET + 0x10) //Switch MAC Address MSB ++#define RT5350_SDM_TPCNT (RT5350_SDM_OFFSET + 0x100) //Switch DMA Tx packet count ++#define RT5350_SDM_TBCNT (RT5350_SDM_OFFSET + 0x104) //Switch DMA Tx byte count ++#define RT5350_SDM_RPCNT (RT5350_SDM_OFFSET + 0x108) //Switch DMA rx packet count ++#define RT5350_SDM_RBCNT (RT5350_SDM_OFFSET + 0x10C) //Switch DMA rx byte count ++#define RT5350_SDM_CS_ERR (RT5350_SDM_OFFSET + 0x110) //Switch DMA rx checksum error count ++ ++#define RT5350_SDM_ICS_EN BIT(16) ++#define RT5350_SDM_TCS_EN BIT(17) ++#define RT5350_SDM_UCS_EN BIT(18) ++ ++ ++/* MDIO_CFG register bits */ ++#define RAMIPS_MDIO_CFG_AUTO_POLL_EN BIT(29) ++#define RAMIPS_MDIO_CFG_GP1_BP_EN BIT(16) ++#define RAMIPS_MDIO_CFG_GP1_FRC_EN BIT(15) ++#define RAMIPS_MDIO_CFG_GP1_SPEED_10 (0 << 13) ++#define RAMIPS_MDIO_CFG_GP1_SPEED_100 (1 << 13) ++#define RAMIPS_MDIO_CFG_GP1_SPEED_1000 (2 << 13) ++#define RAMIPS_MDIO_CFG_GP1_DUPLEX BIT(12) ++#define RAMIPS_MDIO_CFG_GP1_FC_TX BIT(11) ++#define RAMIPS_MDIO_CFG_GP1_FC_RX BIT(10) ++#define RAMIPS_MDIO_CFG_GP1_LNK_DWN BIT(9) ++#define RAMIPS_MDIO_CFG_GP1_AN_FAIL BIT(8) ++#define RAMIPS_MDIO_CFG_MDC_CLK_DIV_1 (0 << 6) ++#define RAMIPS_MDIO_CFG_MDC_CLK_DIV_2 (1 << 6) ++#define RAMIPS_MDIO_CFG_MDC_CLK_DIV_4 (2 << 6) ++#define RAMIPS_MDIO_CFG_MDC_CLK_DIV_8 (3 << 6) ++#define RAMIPS_MDIO_CFG_TURBO_MII_FREQ BIT(5) ++#define RAMIPS_MDIO_CFG_TURBO_MII_MODE BIT(4) ++#define RAMIPS_MDIO_CFG_RX_CLK_SKEW_0 (0 << 2) ++#define RAMIPS_MDIO_CFG_RX_CLK_SKEW_200 (1 << 2) ++#define RAMIPS_MDIO_CFG_RX_CLK_SKEW_400 (2 << 2) ++#define RAMIPS_MDIO_CFG_RX_CLK_SKEW_INV (3 << 2) ++#define RAMIPS_MDIO_CFG_TX_CLK_SKEW_0 0 ++#define RAMIPS_MDIO_CFG_TX_CLK_SKEW_200 1 ++#define RAMIPS_MDIO_CFG_TX_CLK_SKEW_400 2 ++#define RAMIPS_MDIO_CFG_TX_CLK_SKEW_INV 3 ++ ++/* uni-cast port */ ++#define RAMIPS_GDM1_ICS_EN BIT(22) ++#define RAMIPS_GDM1_TCS_EN BIT(21) ++#define RAMIPS_GDM1_UCS_EN BIT(20) ++#define RAMIPS_GDM1_JMB_EN BIT(19) ++#define RAMIPS_GDM1_STRPCRC BIT(16) ++#define RAMIPS_GDM1_UFRC_P_CPU (0 << 12) ++#define RAMIPS_GDM1_UFRC_P_GDMA1 (1 << 12) ++#define RAMIPS_GDM1_UFRC_P_PPE (6 << 12) ++ ++/* checksums */ ++#define RAMIPS_ICS_GEN_EN BIT(2) ++#define RAMIPS_UCS_GEN_EN BIT(1) ++#define RAMIPS_TCS_GEN_EN BIT(0) ++ ++/* dma ring */ ++#define RAMIPS_PST_DRX_IDX0 BIT(16) ++#define RAMIPS_PST_DTX_IDX3 BIT(3) ++#define RAMIPS_PST_DTX_IDX2 BIT(2) ++#define RAMIPS_PST_DTX_IDX1 BIT(1) ++#define RAMIPS_PST_DTX_IDX0 BIT(0) ++ ++#define RAMIPS_TX_WB_DDONE BIT(6) ++#define RAMIPS_RX_DMA_BUSY BIT(3) ++#define RAMIPS_TX_DMA_BUSY BIT(1) ++#define RAMIPS_RX_DMA_EN BIT(2) ++#define RAMIPS_TX_DMA_EN BIT(0) ++ ++#define RAMIPS_PDMA_SIZE_4DWORDS (0 << 4) ++#define RAMIPS_PDMA_SIZE_8DWORDS (1 << 4) ++#define RAMIPS_PDMA_SIZE_16DWORDS (2 << 4) ++ ++#define RAMIPS_US_CYC_CNT_MASK 0xff ++#define RAMIPS_US_CYC_CNT_SHIFT 0x8 ++#define RAMIPS_US_CYC_CNT_DIVISOR 1000000 ++ ++#define RX_DMA_PLEN0(_x) (((_x) >> 16) & 0x3fff) ++#define RX_DMA_LSO BIT(30) ++#define RX_DMA_DONE BIT(31) ++ ++struct ramips_rx_dma { ++ unsigned int rxd1; ++ unsigned int rxd2; ++ unsigned int rxd3; ++ unsigned int rxd4; ++} __packed __aligned(4); ++ ++#define TX_DMA_PLEN0_MASK ((0x3fff) << 16) ++#define TX_DMA_PLEN0(_x) (((_x) & 0x3fff) << 16) ++#define TX_DMA_LSO BIT(30) ++#define TX_DMA_DONE BIT(31) ++#define TX_DMA_QN(_x) ((_x) << 16) ++#define TX_DMA_PN(_x) ((_x) << 24) ++#define TX_DMA_QN_MASK TX_DMA_QN(0x7) ++#define TX_DMA_PN_MASK TX_DMA_PN(0x7) ++ ++struct ramips_tx_dma { ++ unsigned int txd1; ++ unsigned int txd2; ++ unsigned int txd3; ++ unsigned int txd4; ++} __packed __aligned(4); ++ ++struct raeth_tx_info { ++ struct ramips_tx_dma *tx_desc; ++ struct sk_buff *tx_skb; ++}; ++ ++struct raeth_rx_info { ++ struct ramips_rx_dma *rx_desc; ++ struct sk_buff *rx_skb; ++ dma_addr_t rx_dma; ++ unsigned int pad; ++}; ++ ++struct raeth_int_stats { ++ unsigned long rx_delayed; ++ unsigned long tx_delayed; ++ unsigned long rx_done0; ++ unsigned long tx_done0; ++ unsigned long tx_done1; ++ unsigned long tx_done2; ++ unsigned long tx_done3; ++ unsigned long rx_coherent; ++ unsigned long tx_coherent; ++ ++ unsigned long pse_fq_empty; ++ unsigned long pse_p0_fc; ++ unsigned long pse_p1_fc; ++ unsigned long pse_p2_fc; ++ unsigned long pse_buf_drop; ++ ++ unsigned long total; ++}; ++ ++struct raeth_debug { ++ struct dentry *debugfs_dir; ++ ++ struct raeth_int_stats int_stats; ++}; ++ ++struct raeth_priv ++{ ++ struct device_node *of_node; ++ ++ struct raeth_rx_info *rx_info; ++ dma_addr_t rx_desc_dma; ++ struct tasklet_struct rx_tasklet; ++ struct ramips_rx_dma *rx; ++ ++ struct raeth_tx_info *tx_info; ++ dma_addr_t tx_desc_dma; ++ struct tasklet_struct tx_housekeeping_tasklet; ++ struct ramips_tx_dma *tx; ++ ++ unsigned int skb_free_idx; ++ ++ spinlock_t page_lock; ++ struct net_device *netdev; ++ struct device *parent; ++ ++ int link; ++ int speed; ++ int duplex; ++ int tx_fc; ++ int rx_fc; ++ ++ struct mii_bus *mii_bus; ++ int mii_irq[PHY_MAX_ADDR]; ++ struct phy_device *phy_dev; ++ spinlock_t phy_lock; ++ unsigned long sys_freq; ++ ++ unsigned char mac[6]; ++ void (*reset_fe)(void); ++ int min_pkt_len; ++ ++ u32 phy_mask; ++ phy_interface_t phy_if_mode; ++ ++#ifdef CONFIG_NET_RAMIPS_DEBUG_FS ++ struct raeth_debug debug; ++#endif ++}; ++ ++struct ramips_soc_data ++{ ++ unsigned char mac[6]; ++ void (*reset_fe)(void); ++ int min_pkt_len; ++}; ++ ++ ++#ifdef CONFIG_NET_RAMIPS_DEBUG_FS ++int raeth_debugfs_root_init(void); ++void raeth_debugfs_root_exit(void); ++int raeth_debugfs_init(struct raeth_priv *re); ++void raeth_debugfs_exit(struct raeth_priv *re); ++void raeth_debugfs_update_int_stats(struct raeth_priv *re, u32 status); ++#else ++static inline int raeth_debugfs_root_init(void) { return 0; } ++static inline void raeth_debugfs_root_exit(void) {} ++static inline int raeth_debugfs_init(struct raeth_priv *re) { return 0; } ++static inline void raeth_debugfs_exit(struct raeth_priv *re) {} ++static inline void raeth_debugfs_update_int_stats(struct raeth_priv *re, ++ u32 status) {} ++#endif /* CONFIG_NET_RAMIPS_DEBUG_FS */ ++ ++#endif /* RAMIPS_ETH_H */ +--- /dev/null ++++ b/drivers/net/ethernet/ramips/ramips_main.c +@@ -0,0 +1,1281 @@ ++/* ++ * This program is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License as published by ++ * the Free Software Foundation; version 2 of the License ++ * ++ * This program is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ * GNU General Public License for more details. ++ * ++ * You should have received a copy of the GNU General Public License ++ * along with this program; if not, write to the Free Software ++ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA. ++ * ++ * Copyright (C) 2009 John Crispin ++ */ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#include "ramips_eth.h" ++ ++#define TX_TIMEOUT (20 * HZ / 100) ++#define MAX_RX_LENGTH 1600 ++ ++#ifdef CONFIG_SOC_RT305X ++#include ++#include "ramips_esw.c" ++#else ++#include ++static inline int rt305x_esw_init(void) { return 0; } ++static inline void rt305x_esw_exit(void) { } ++static inline int soc_is_rt5350(void) { return 0; } ++#endif ++ ++#define phys_to_bus(a) (a & 0x1FFFFFFF) ++ ++#ifdef CONFIG_NET_RAMIPS_DEBUG ++#define RADEBUG(fmt, args...) printk(KERN_DEBUG fmt, ## args) ++#else ++#define RADEBUG(fmt, args...) do {} while (0) ++#endif ++ ++#define RX_DLY_INT ((soc_is_rt5350())?(RT5350_RX_DLY_INT):(RAMIPS_RX_DLY_INT)) ++#define TX_DLY_INT ((soc_is_rt5350())?(RT5350_TX_DLY_INT):(RAMIPS_TX_DLY_INT)) ++ ++enum raeth_reg { ++ RAETH_REG_PDMA_GLO_CFG = 0, ++ RAETH_REG_PDMA_RST_CFG, ++ RAETH_REG_DLY_INT_CFG, ++ RAETH_REG_TX_BASE_PTR0, ++ RAETH_REG_TX_MAX_CNT0, ++ RAETH_REG_TX_CTX_IDX0, ++ RAETH_REG_RX_BASE_PTR0, ++ RAETH_REG_RX_MAX_CNT0, ++ RAETH_REG_RX_CALC_IDX0, ++ RAETH_REG_FE_INT_ENABLE, ++ RAETH_REG_FE_INT_STATUS, ++ RAETH_REG_COUNT ++}; ++ ++static const u32 ramips_reg_table[RAETH_REG_COUNT] = { ++ [RAETH_REG_PDMA_GLO_CFG] = RAMIPS_PDMA_GLO_CFG, ++ [RAETH_REG_PDMA_RST_CFG] = RAMIPS_PDMA_RST_CFG, ++ [RAETH_REG_DLY_INT_CFG] = RAMIPS_DLY_INT_CFG, ++ [RAETH_REG_TX_BASE_PTR0] = RAMIPS_TX_BASE_PTR0, ++ [RAETH_REG_TX_MAX_CNT0] = RAMIPS_TX_MAX_CNT0, ++ [RAETH_REG_TX_CTX_IDX0] = RAMIPS_TX_CTX_IDX0, ++ [RAETH_REG_RX_BASE_PTR0] = RAMIPS_RX_BASE_PTR0, ++ [RAETH_REG_RX_MAX_CNT0] = RAMIPS_RX_MAX_CNT0, ++ [RAETH_REG_RX_CALC_IDX0] = RAMIPS_RX_CALC_IDX0, ++ [RAETH_REG_FE_INT_ENABLE] = RAMIPS_FE_INT_ENABLE, ++ [RAETH_REG_FE_INT_STATUS] = RAMIPS_FE_INT_STATUS, ++}; ++ ++static const u32 rt5350_reg_table[RAETH_REG_COUNT] = { ++ [RAETH_REG_PDMA_GLO_CFG] = RT5350_PDMA_GLO_CFG, ++ [RAETH_REG_PDMA_RST_CFG] = RT5350_PDMA_RST_CFG, ++ [RAETH_REG_DLY_INT_CFG] = RT5350_DLY_INT_CFG, ++ [RAETH_REG_TX_BASE_PTR0] = RT5350_TX_BASE_PTR0, ++ [RAETH_REG_TX_MAX_CNT0] = RT5350_TX_MAX_CNT0, ++ [RAETH_REG_TX_CTX_IDX0] = RT5350_TX_CTX_IDX0, ++ [RAETH_REG_RX_BASE_PTR0] = RT5350_RX_BASE_PTR0, ++ [RAETH_REG_RX_MAX_CNT0] = RT5350_RX_MAX_CNT0, ++ [RAETH_REG_RX_CALC_IDX0] = RT5350_RX_CALC_IDX0, ++ [RAETH_REG_FE_INT_ENABLE] = RT5350_FE_INT_ENABLE, ++ [RAETH_REG_FE_INT_STATUS] = RT5350_FE_INT_STATUS, ++}; ++ ++static struct net_device * ramips_dev; ++static void __iomem *ramips_fe_base = 0; ++ ++static inline u32 get_reg_offset(enum raeth_reg reg) ++{ ++ const u32 *table; ++ ++ if (soc_is_rt5350()) ++ table = rt5350_reg_table; ++ else ++ table = ramips_reg_table; ++ ++ return table[reg]; ++} ++ ++static inline void ++ramips_fe_wr(u32 val, unsigned reg) ++{ ++ __raw_writel(val, ramips_fe_base + reg); ++} ++ ++static inline u32 ++ramips_fe_rr(unsigned reg) ++{ ++ return __raw_readl(ramips_fe_base + reg); ++} ++ ++static inline void ++ramips_fe_twr(u32 val, enum raeth_reg reg) ++{ ++ ramips_fe_wr(val, get_reg_offset(reg)); ++} ++ ++static inline u32 ++ramips_fe_trr(enum raeth_reg reg) ++{ ++ return ramips_fe_rr(get_reg_offset(reg)); ++} ++ ++static inline void ++ramips_fe_int_disable(u32 mask) ++{ ++ ramips_fe_twr(ramips_fe_trr(RAETH_REG_FE_INT_ENABLE) & ~mask, ++ RAETH_REG_FE_INT_ENABLE); ++ /* flush write */ ++ ramips_fe_trr(RAETH_REG_FE_INT_ENABLE); ++} ++ ++static inline void ++ramips_fe_int_enable(u32 mask) ++{ ++ ramips_fe_twr(ramips_fe_trr(RAETH_REG_FE_INT_ENABLE) | mask, ++ RAETH_REG_FE_INT_ENABLE); ++ /* flush write */ ++ ramips_fe_trr(RAETH_REG_FE_INT_ENABLE); ++} ++ ++static inline void ++ramips_hw_set_macaddr(unsigned char *mac) ++{ ++ if (soc_is_rt5350()) { ++ ramips_fe_wr((mac[0] << 8) | mac[1], RT5350_SDM_MAC_ADRH); ++ ramips_fe_wr((mac[2] << 24) | (mac[3] << 16) | (mac[4] << 8) | mac[5], ++ RT5350_SDM_MAC_ADRL); ++ } else { ++ ramips_fe_wr((mac[0] << 8) | mac[1], RAMIPS_GDMA1_MAC_ADRH); ++ ramips_fe_wr((mac[2] << 24) | (mac[3] << 16) | (mac[4] << 8) | mac[5], ++ RAMIPS_GDMA1_MAC_ADRL); ++ } ++} ++ ++static struct sk_buff * ++ramips_alloc_skb(struct raeth_priv *re) ++{ ++ struct sk_buff *skb; ++ ++ skb = netdev_alloc_skb(re->netdev, MAX_RX_LENGTH + NET_IP_ALIGN); ++ if (!skb) ++ return NULL; ++ ++ skb_reserve(skb, NET_IP_ALIGN); ++ ++ return skb; ++} ++ ++static void ++ramips_ring_setup(struct raeth_priv *re) ++{ ++ int len; ++ int i; ++ ++ memset(re->tx_info, 0, NUM_TX_DESC * sizeof(struct raeth_tx_info)); ++ ++ len = NUM_TX_DESC * sizeof(struct ramips_tx_dma); ++ memset(re->tx, 0, len); ++ ++ for (i = 0; i < NUM_TX_DESC; i++) { ++ struct raeth_tx_info *txi; ++ struct ramips_tx_dma *txd; ++ ++ txd = &re->tx[i]; ++ txd->txd4 = TX_DMA_QN(3) | TX_DMA_PN(1); ++ txd->txd2 = TX_DMA_LSO | TX_DMA_DONE; ++ ++ txi = &re->tx_info[i]; ++ txi->tx_desc = txd; ++ if (txi->tx_skb != NULL) { ++ netdev_warn(re->netdev, ++ "dirty skb for TX desc %d\n", i); ++ txi->tx_skb = NULL; ++ } ++ } ++ ++ len = NUM_RX_DESC * sizeof(struct ramips_rx_dma); ++ memset(re->rx, 0, len); ++ ++ for (i = 0; i < NUM_RX_DESC; i++) { ++ struct raeth_rx_info *rxi; ++ struct ramips_rx_dma *rxd; ++ dma_addr_t dma_addr; ++ ++ rxd = &re->rx[i]; ++ rxi = &re->rx_info[i]; ++ BUG_ON(rxi->rx_skb == NULL); ++ dma_addr = dma_map_single(&re->netdev->dev, rxi->rx_skb->data, ++ MAX_RX_LENGTH, DMA_FROM_DEVICE); ++ rxi->rx_dma = dma_addr; ++ rxi->rx_desc = rxd; ++ ++ rxd->rxd1 = (unsigned int) dma_addr; ++ rxd->rxd2 = RX_DMA_LSO; ++ } ++ ++ /* flush descriptors */ ++ wmb(); ++} ++ ++static void ++ramips_ring_cleanup(struct raeth_priv *re) ++{ ++ int i; ++ ++ for (i = 0; i < NUM_RX_DESC; i++) { ++ struct raeth_rx_info *rxi; ++ ++ rxi = &re->rx_info[i]; ++ if (rxi->rx_skb) ++ dma_unmap_single(&re->netdev->dev, rxi->rx_dma, ++ MAX_RX_LENGTH, DMA_FROM_DEVICE); ++ } ++ ++ for (i = 0; i < NUM_TX_DESC; i++) { ++ struct raeth_tx_info *txi; ++ ++ txi = &re->tx_info[i]; ++ if (txi->tx_skb) { ++ dev_kfree_skb_any(txi->tx_skb); ++ txi->tx_skb = NULL; ++ } ++ } ++ ++ netdev_reset_queue(re->netdev); ++} ++ ++#if defined(CONFIG_SOC_RT288X) || defined(CONFIG_SOC_RT3883) ++ ++#define RAMIPS_MDIO_RETRY 1000 ++ ++static unsigned char *ramips_speed_str(struct raeth_priv *re) ++{ ++ switch (re->speed) { ++ case SPEED_1000: ++ return "1000"; ++ case SPEED_100: ++ return "100"; ++ case SPEED_10: ++ return "10"; ++ } ++ ++ return "?"; ++} ++ ++static void ramips_link_adjust(struct raeth_priv *re) ++{ ++ u32 mdio_cfg; ++ ++ if (!re->link) { ++ netif_carrier_off(re->netdev); ++ netdev_info(re->netdev, "link down\n"); ++ return; ++ } ++ ++ mdio_cfg = RAMIPS_MDIO_CFG_TX_CLK_SKEW_200 | ++ RAMIPS_MDIO_CFG_TX_CLK_SKEW_200 | ++ RAMIPS_MDIO_CFG_GP1_FRC_EN; ++ ++ if (re->duplex == DUPLEX_FULL) ++ mdio_cfg |= RAMIPS_MDIO_CFG_GP1_DUPLEX; ++ ++ if (re->tx_fc) ++ mdio_cfg |= RAMIPS_MDIO_CFG_GP1_FC_TX; ++ ++ if (re->rx_fc) ++ mdio_cfg |= RAMIPS_MDIO_CFG_GP1_FC_RX; ++ ++ switch (re->speed) { ++ case SPEED_10: ++ mdio_cfg |= RAMIPS_MDIO_CFG_GP1_SPEED_10; ++ break; ++ case SPEED_100: ++ mdio_cfg |= RAMIPS_MDIO_CFG_GP1_SPEED_100; ++ break; ++ case SPEED_1000: ++ mdio_cfg |= RAMIPS_MDIO_CFG_GP1_SPEED_1000; ++ break; ++ default: ++ BUG(); ++ } ++ ++ ramips_fe_wr(mdio_cfg, RAMIPS_MDIO_CFG); ++ ++ netif_carrier_on(re->netdev); ++ netdev_info(re->netdev, "link up (%sMbps/%s duplex)\n", ++ ramips_speed_str(re), ++ (DUPLEX_FULL == re->duplex) ? "Full" : "Half"); ++} ++ ++static int ++ramips_mdio_wait_ready(struct raeth_priv *re) ++{ ++ int retries; ++ ++ retries = RAMIPS_MDIO_RETRY; ++ while (1) { ++ u32 t; ++ ++ t = ramips_fe_rr(RAMIPS_MDIO_ACCESS); ++ if ((t & (0x1 << 31)) == 0) ++ return 0; ++ ++ if (retries-- == 0) ++ break; ++ ++ udelay(1); ++ } ++ ++ dev_err(re->parent, "MDIO operation timed out\n"); ++ return -ETIMEDOUT; ++} ++ ++static int ++ramips_mdio_read(struct mii_bus *bus, int phy_addr, int phy_reg) ++{ ++ struct raeth_priv *re = bus->priv; ++ int err; ++ u32 t; ++ ++ err = ramips_mdio_wait_ready(re); ++ if (err) ++ return 0xffff; ++ ++ t = (phy_addr << 24) | (phy_reg << 16); ++ ramips_fe_wr(t, RAMIPS_MDIO_ACCESS); ++ t |= (1 << 31); ++ ramips_fe_wr(t, RAMIPS_MDIO_ACCESS); ++ ++ err = ramips_mdio_wait_ready(re); ++ if (err) ++ return 0xffff; ++ ++ RADEBUG("%s: addr=%04x, reg=%04x, value=%04x\n", __func__, ++ phy_addr, phy_reg, ramips_fe_rr(RAMIPS_MDIO_ACCESS) & 0xffff); ++ ++ return ramips_fe_rr(RAMIPS_MDIO_ACCESS) & 0xffff; ++} ++ ++static int ++ramips_mdio_write(struct mii_bus *bus, int phy_addr, int phy_reg, u16 val) ++{ ++ struct raeth_priv *re = bus->priv; ++ int err; ++ u32 t; ++ ++ RADEBUG("%s: addr=%04x, reg=%04x, value=%04x\n", __func__, ++ phy_addr, phy_reg, ramips_fe_rr(RAMIPS_MDIO_ACCESS) & 0xffff); ++ ++ err = ramips_mdio_wait_ready(re); ++ if (err) ++ return err; ++ ++ t = (1 << 30) | (phy_addr << 24) | (phy_reg << 16) | val; ++ ramips_fe_wr(t, RAMIPS_MDIO_ACCESS); ++ t |= (1 << 31); ++ ramips_fe_wr(t, RAMIPS_MDIO_ACCESS); ++ ++ return ramips_mdio_wait_ready(re); ++} ++ ++static int ++ramips_mdio_reset(struct mii_bus *bus) ++{ ++ /* TODO */ ++ return 0; ++} ++ ++static int ++ramips_mdio_init(struct raeth_priv *re) ++{ ++ struct device_node *mii_np; ++ int err; ++ ++ mii_np = of_get_child_by_name(re->of_node, "mdio-bus"); ++ if (!mii_np) { ++ dev_err(re->parent, "no %s child node found", "mdio-bus"); ++ return -ENODEV; ++ } ++ ++ if (!of_device_is_available(mii_np)) { ++ err = 0; ++ goto err_put_node; ++ } ++ ++ re->mii_bus = mdiobus_alloc(); ++ if (re->mii_bus == NULL) { ++ err = -ENOMEM; ++ goto err_put_node; ++ } ++ ++ re->mii_bus->name = "ramips_mdio"; ++ re->mii_bus->read = ramips_mdio_read; ++ re->mii_bus->write = ramips_mdio_write; ++ re->mii_bus->reset = ramips_mdio_reset; ++ re->mii_bus->irq = re->mii_irq; ++ re->mii_bus->priv = re; ++ re->mii_bus->parent = re->parent; ++ ++ snprintf(re->mii_bus->id, MII_BUS_ID_SIZE, "%s", "ramips_mdio"); ++ err = of_mdiobus_register(re->mii_bus, mii_np); ++ if (err) ++ goto err_free_bus; ++ ++ return 0; ++ ++err_free_bus: ++ kfree(re->mii_bus); ++err_put_node: ++ of_node_put(mii_np); ++ re->mii_bus = NULL; ++ return err; ++} ++ ++static void ++ramips_mdio_cleanup(struct raeth_priv *re) ++{ ++ if (!re->mii_bus) ++ return; ++ ++ mdiobus_unregister(re->mii_bus); ++ of_node_put(re->mii_bus->dev.of_node); ++ kfree(re->mii_bus); ++} ++ ++static void ++ramips_phy_link_adjust(struct net_device *dev) ++{ ++ struct raeth_priv *re = netdev_priv(dev); ++ struct phy_device *phydev = re->phy_dev; ++ unsigned long flags; ++ int status_change = 0; ++ ++ spin_lock_irqsave(&re->phy_lock, flags); ++ ++ if (phydev->link) ++ if (re->duplex != phydev->duplex || ++ re->speed != phydev->speed) ++ status_change = 1; ++ ++ if (phydev->link != re->link) ++ status_change = 1; ++ ++ re->link = phydev->link; ++ re->duplex = phydev->duplex; ++ re->speed = phydev->speed; ++ ++ if (status_change) ++ ramips_link_adjust(re); ++ ++ spin_unlock_irqrestore(&re->phy_lock, flags); ++} ++ ++static int ++ramips_phy_connect_by_node(struct raeth_priv *re, struct device_node *phy_node) ++{ ++ struct phy_device *phydev; ++ int phy_mode; ++ ++ phy_mode = of_get_phy_mode(re->of_node); ++ if (phy_mode < 0) { ++ dev_err(re->parent, "incorrect phy-mode\n"); ++ return -EINVAL; ++ } ++ ++ phydev = of_phy_connect(re->netdev, phy_node, ramips_phy_link_adjust, ++ 0, phy_mode); ++ if (IS_ERR(phydev)) { ++ dev_err(re->parent, "could not connect to PHY\n"); ++ return PTR_ERR(re->phy_dev); ++ } ++ ++ phydev->supported &= PHY_GBIT_FEATURES; ++ phydev->advertising = phydev->supported; ++ ++ dev_info(re->parent, ++ "connected to PHY at %s [uid=%08x, driver=%s]\n", ++ dev_name(&phydev->dev), phydev->phy_id, ++ phydev->drv->name); ++ ++ re->phy_dev = phydev; ++ re->link = 0; ++ re->speed = 0; ++ re->duplex = -1; ++ re->rx_fc = 0; ++ re->tx_fc = 0; ++ ++ return 0; ++} ++ ++static int ++ramips_phy_connect_fixed(struct raeth_priv *re, const __be32 *link, int size) ++{ ++ if (size != (4 * sizeof(*link))) { ++ dev_err(re->parent, "invalid fixed-link property\n"); ++ return -EINVAL; ++ } ++ ++ re->speed = be32_to_cpup(link++); ++ re->duplex = be32_to_cpup(link++); ++ re->tx_fc = be32_to_cpup(link++); ++ re->rx_fc = be32_to_cpup(link++); ++ ++ switch (re->speed) { ++ case SPEED_10: ++ case SPEED_100: ++ case SPEED_1000: ++ break; ++ default: ++ dev_err(re->parent, "invalid link speed: %d\n", re->speed); ++ return -EINVAL; ++ } ++ ++ dev_info(re->parent, "using fixed link parameters\n"); ++ return 0; ++} ++ ++static int ++ramips_phy_connect(struct raeth_priv *re) ++{ ++ struct device_node *phy_node; ++ const __be32 *p32; ++ int size; ++ ++ phy_node = of_parse_phandle(re->of_node, "phy-handle", 0); ++ if (phy_node) ++ return ramips_phy_connect_by_node(re, phy_node); ++ ++ p32 = of_get_property(re->of_node, "ralink,fixed-link", &size); ++ if (p32) ++ return ramips_phy_connect_fixed(re, p32, size); ++ ++ dev_err(re->parent, "unable to get connection type\n"); ++ return -EINVAL; ++} ++ ++static void ++ramips_phy_disconnect(struct raeth_priv *re) ++{ ++ if (re->phy_dev) ++ phy_disconnect(re->phy_dev); ++} ++ ++static void ++ramips_phy_start(struct raeth_priv *re) ++{ ++ unsigned long flags; ++ ++ if (re->phy_dev) { ++ phy_start(re->phy_dev); ++ } else { ++ spin_lock_irqsave(&re->phy_lock, flags); ++ re->link = 1; ++ ramips_link_adjust(re); ++ spin_unlock_irqrestore(&re->phy_lock, flags); ++ } ++} ++ ++static void ++ramips_phy_stop(struct raeth_priv *re) ++{ ++ unsigned long flags; ++ ++ if (re->phy_dev) ++ phy_stop(re->phy_dev); ++ ++ spin_lock_irqsave(&re->phy_lock, flags); ++ re->link = 0; ++ ramips_link_adjust(re); ++ spin_unlock_irqrestore(&re->phy_lock, flags); ++} ++#else ++static inline int ++ramips_mdio_init(struct raeth_priv *re) ++{ ++ return 0; ++} ++ ++static inline void ++ramips_mdio_cleanup(struct raeth_priv *re) ++{ ++} ++ ++static inline int ++ramips_phy_connect(struct raeth_priv *re) ++{ ++ return 0; ++} ++ ++static inline void ++ramips_phy_disconnect(struct raeth_priv *re) ++{ ++} ++ ++static inline void ++ramips_phy_start(struct raeth_priv *re) ++{ ++} ++ ++static inline void ++ramips_phy_stop(struct raeth_priv *re) ++{ ++} ++#endif /* CONFIG_SOC_RT288X || CONFIG_SOC_RT3883 */ ++ ++static void ++ramips_ring_free(struct raeth_priv *re) ++{ ++ int len; ++ int i; ++ ++ if (re->rx_info) { ++ for (i = 0; i < NUM_RX_DESC; i++) { ++ struct raeth_rx_info *rxi; ++ ++ rxi = &re->rx_info[i]; ++ if (rxi->rx_skb) ++ dev_kfree_skb_any(rxi->rx_skb); ++ } ++ kfree(re->rx_info); ++ } ++ ++ if (re->rx) { ++ len = NUM_RX_DESC * sizeof(struct ramips_rx_dma); ++ dma_free_coherent(&re->netdev->dev, len, re->rx, ++ re->rx_desc_dma); ++ } ++ ++ if (re->tx) { ++ len = NUM_TX_DESC * sizeof(struct ramips_tx_dma); ++ dma_free_coherent(&re->netdev->dev, len, re->tx, ++ re->tx_desc_dma); ++ } ++ ++ kfree(re->tx_info); ++} ++ ++static int ++ramips_ring_alloc(struct raeth_priv *re) ++{ ++ int len; ++ int err = -ENOMEM; ++ int i; ++ ++ re->tx_info = kzalloc(NUM_TX_DESC * sizeof(struct raeth_tx_info), ++ GFP_ATOMIC); ++ if (!re->tx_info) ++ goto err_cleanup; ++ ++ re->rx_info = kzalloc(NUM_RX_DESC * sizeof(struct raeth_rx_info), ++ GFP_ATOMIC); ++ if (!re->rx_info) ++ goto err_cleanup; ++ ++ /* allocate tx ring */ ++ len = NUM_TX_DESC * sizeof(struct ramips_tx_dma); ++ re->tx = dma_alloc_coherent(&re->netdev->dev, len, ++ &re->tx_desc_dma, GFP_ATOMIC); ++ if (!re->tx) ++ goto err_cleanup; ++ ++ /* allocate rx ring */ ++ len = NUM_RX_DESC * sizeof(struct ramips_rx_dma); ++ re->rx = dma_alloc_coherent(&re->netdev->dev, len, ++ &re->rx_desc_dma, GFP_ATOMIC); ++ if (!re->rx) ++ goto err_cleanup; ++ ++ for (i = 0; i < NUM_RX_DESC; i++) { ++ struct sk_buff *skb; ++ ++ skb = ramips_alloc_skb(re); ++ if (!skb) ++ goto err_cleanup; ++ ++ re->rx_info[i].rx_skb = skb; ++ } ++ ++ return 0; ++ ++err_cleanup: ++ ramips_ring_free(re); ++ return err; ++} ++ ++static void ++ramips_setup_dma(struct raeth_priv *re) ++{ ++ ramips_fe_twr(re->tx_desc_dma, RAETH_REG_TX_BASE_PTR0); ++ ramips_fe_twr(NUM_TX_DESC, RAETH_REG_TX_MAX_CNT0); ++ ramips_fe_twr(0, RAETH_REG_TX_CTX_IDX0); ++ ramips_fe_twr(RAMIPS_PST_DTX_IDX0, RAETH_REG_PDMA_RST_CFG); ++ ++ ramips_fe_twr(re->rx_desc_dma, RAETH_REG_RX_BASE_PTR0); ++ ramips_fe_twr(NUM_RX_DESC, RAETH_REG_RX_MAX_CNT0); ++ ramips_fe_twr((NUM_RX_DESC - 1), RAETH_REG_RX_CALC_IDX0); ++ ramips_fe_twr(RAMIPS_PST_DRX_IDX0, RAETH_REG_PDMA_RST_CFG); ++} ++ ++static int ++ramips_eth_hard_start_xmit(struct sk_buff *skb, struct net_device *dev) ++{ ++ struct raeth_priv *re = netdev_priv(dev); ++ struct raeth_tx_info *txi, *txi_next; ++ struct ramips_tx_dma *txd, *txd_next; ++ unsigned long tx; ++ unsigned int tx_next; ++ dma_addr_t mapped_addr; ++ ++ if (re->min_pkt_len) { ++ if (skb->len < re->min_pkt_len) { ++ if (skb_padto(skb, re->min_pkt_len)) { ++ printk(KERN_ERR ++ "ramips_eth: skb_padto failed\n"); ++ kfree_skb(skb); ++ return 0; ++ } ++ skb_put(skb, re->min_pkt_len - skb->len); ++ } ++ } ++ ++ dev->trans_start = jiffies; ++ mapped_addr = dma_map_single(&re->netdev->dev, skb->data, skb->len, ++ DMA_TO_DEVICE); ++ ++ spin_lock(&re->page_lock); ++ tx = ramips_fe_trr(RAETH_REG_TX_CTX_IDX0); ++ tx_next = (tx + 1) % NUM_TX_DESC; ++ ++ txi = &re->tx_info[tx]; ++ txd = txi->tx_desc; ++ txi_next = &re->tx_info[tx_next]; ++ txd_next = txi_next->tx_desc; ++ ++ if ((txi->tx_skb) || (txi_next->tx_skb) || ++ !(txd->txd2 & TX_DMA_DONE) || ++ !(txd_next->txd2 & TX_DMA_DONE)) ++ goto out; ++ ++ txi->tx_skb = skb; ++ ++ txd->txd1 = (unsigned int) mapped_addr; ++ wmb(); ++ txd->txd2 = TX_DMA_LSO | TX_DMA_PLEN0(skb->len); ++ dev->stats.tx_packets++; ++ dev->stats.tx_bytes += skb->len; ++ ramips_fe_twr(tx_next, RAETH_REG_TX_CTX_IDX0); ++ netdev_sent_queue(dev, skb->len); ++ spin_unlock(&re->page_lock); ++ return NETDEV_TX_OK; ++ ++ out: ++ spin_unlock(&re->page_lock); ++ dev->stats.tx_dropped++; ++ kfree_skb(skb); ++ return NETDEV_TX_OK; ++} ++ ++static void ++ramips_eth_rx_hw(unsigned long ptr) ++{ ++ struct net_device *dev = (struct net_device *) ptr; ++ struct raeth_priv *re = netdev_priv(dev); ++ int rx; ++ int max_rx = 16; ++ ++ rx = ramips_fe_trr(RAETH_REG_RX_CALC_IDX0); ++ ++ while (max_rx) { ++ struct raeth_rx_info *rxi; ++ struct ramips_rx_dma *rxd; ++ struct sk_buff *rx_skb, *new_skb; ++ int pktlen; ++ ++ rx = (rx + 1) % NUM_RX_DESC; ++ ++ rxi = &re->rx_info[rx]; ++ rxd = rxi->rx_desc; ++ if (!(rxd->rxd2 & RX_DMA_DONE)) ++ break; ++ ++ rx_skb = rxi->rx_skb; ++ pktlen = RX_DMA_PLEN0(rxd->rxd2); ++ ++ new_skb = ramips_alloc_skb(re); ++ /* Reuse the buffer on allocation failures */ ++ if (new_skb) { ++ dma_addr_t dma_addr; ++ ++ dma_unmap_single(&re->netdev->dev, rxi->rx_dma, ++ MAX_RX_LENGTH, DMA_FROM_DEVICE); ++ ++ skb_put(rx_skb, pktlen); ++ rx_skb->dev = dev; ++ rx_skb->protocol = eth_type_trans(rx_skb, dev); ++ rx_skb->ip_summed = CHECKSUM_NONE; ++ dev->stats.rx_packets++; ++ dev->stats.rx_bytes += pktlen; ++ netif_rx(rx_skb); ++ ++ rxi->rx_skb = new_skb; ++ ++ dma_addr = dma_map_single(&re->netdev->dev, ++ new_skb->data, ++ MAX_RX_LENGTH, ++ DMA_FROM_DEVICE); ++ rxi->rx_dma = dma_addr; ++ rxd->rxd1 = (unsigned int) dma_addr; ++ wmb(); ++ } else { ++ dev->stats.rx_dropped++; ++ } ++ ++ rxd->rxd2 = RX_DMA_LSO; ++ ramips_fe_twr(rx, RAETH_REG_RX_CALC_IDX0); ++ max_rx--; ++ } ++ ++ if (max_rx == 0) ++ tasklet_schedule(&re->rx_tasklet); ++ else ++ ramips_fe_int_enable(RX_DLY_INT); ++} ++ ++static void ++ramips_eth_tx_housekeeping(unsigned long ptr) ++{ ++ struct net_device *dev = (struct net_device*)ptr; ++ struct raeth_priv *re = netdev_priv(dev); ++ unsigned int bytes_compl = 0, pkts_compl = 0; ++ ++ spin_lock(&re->page_lock); ++ while (1) { ++ struct raeth_tx_info *txi; ++ struct ramips_tx_dma *txd; ++ ++ txi = &re->tx_info[re->skb_free_idx]; ++ txd = txi->tx_desc; ++ ++ if (!(txd->txd2 & TX_DMA_DONE) || !(txi->tx_skb)) ++ break; ++ ++ pkts_compl++; ++ bytes_compl += txi->tx_skb->len; ++ ++ dev_kfree_skb_irq(txi->tx_skb); ++ txi->tx_skb = NULL; ++ re->skb_free_idx++; ++ if (re->skb_free_idx >= NUM_TX_DESC) ++ re->skb_free_idx = 0; ++ } ++ netdev_completed_queue(dev, pkts_compl, bytes_compl); ++ spin_unlock(&re->page_lock); ++ ++ ramips_fe_int_enable(TX_DLY_INT); ++} ++ ++static void ++ramips_eth_timeout(struct net_device *dev) ++{ ++ struct raeth_priv *re = netdev_priv(dev); ++ ++ tasklet_schedule(&re->tx_housekeeping_tasklet); ++} ++ ++static irqreturn_t ++ramips_eth_irq(int irq, void *dev) ++{ ++ struct raeth_priv *re = netdev_priv(dev); ++ unsigned int status; ++ ++ status = ramips_fe_trr(RAETH_REG_FE_INT_STATUS); ++ status &= ramips_fe_trr(RAETH_REG_FE_INT_ENABLE); ++ ++ if (!status) ++ return IRQ_NONE; ++ ++ ramips_fe_twr(status, RAETH_REG_FE_INT_STATUS); ++ ++ if (status & RX_DLY_INT) { ++ ramips_fe_int_disable(RX_DLY_INT); ++ tasklet_schedule(&re->rx_tasklet); ++ } ++ ++ if (status & TX_DLY_INT) { ++ ramips_fe_int_disable(TX_DLY_INT); ++ tasklet_schedule(&re->tx_housekeeping_tasklet); ++ } ++ ++ raeth_debugfs_update_int_stats(re, status); ++ ++ return IRQ_HANDLED; ++} ++ ++static int ++ramips_eth_hw_init(struct net_device *dev) ++{ ++ struct raeth_priv *re = netdev_priv(dev); ++ int err; ++ ++ err = request_irq(dev->irq, ramips_eth_irq, IRQF_DISABLED, ++ dev_name(re->parent), dev); ++ if (err) ++ return err; ++ ++ err = ramips_ring_alloc(re); ++ if (err) ++ goto err_free_irq; ++ ++ ramips_ring_setup(re); ++ ramips_hw_set_macaddr(dev->dev_addr); ++ ++ ramips_setup_dma(re); ++ ramips_fe_wr((ramips_fe_rr(RAMIPS_FE_GLO_CFG) & ++ ~(RAMIPS_US_CYC_CNT_MASK << RAMIPS_US_CYC_CNT_SHIFT)) | ++ ((re->sys_freq / RAMIPS_US_CYC_CNT_DIVISOR) << RAMIPS_US_CYC_CNT_SHIFT), ++ RAMIPS_FE_GLO_CFG); ++ ++ tasklet_init(&re->tx_housekeeping_tasklet, ramips_eth_tx_housekeeping, ++ (unsigned long)dev); ++ tasklet_init(&re->rx_tasklet, ramips_eth_rx_hw, (unsigned long)dev); ++ ++ ++ ramips_fe_twr(RAMIPS_DELAY_INIT, RAETH_REG_DLY_INT_CFG); ++ ramips_fe_twr(TX_DLY_INT | RX_DLY_INT, RAETH_REG_FE_INT_ENABLE); ++ if (soc_is_rt5350()) { ++ ramips_fe_wr(ramips_fe_rr(RT5350_SDM_CFG) & ++ ~(RT5350_SDM_ICS_EN | RT5350_SDM_TCS_EN | RT5350_SDM_UCS_EN | 0xffff), ++ RT5350_SDM_CFG); ++ } else { ++ ramips_fe_wr(ramips_fe_rr(RAMIPS_GDMA1_FWD_CFG) & ++ ~(RAMIPS_GDM1_ICS_EN | RAMIPS_GDM1_TCS_EN | RAMIPS_GDM1_UCS_EN | 0xffff), ++ RAMIPS_GDMA1_FWD_CFG); ++ ramips_fe_wr(ramips_fe_rr(RAMIPS_CDMA_CSG_CFG) & ++ ~(RAMIPS_ICS_GEN_EN | RAMIPS_TCS_GEN_EN | RAMIPS_UCS_GEN_EN), ++ RAMIPS_CDMA_CSG_CFG); ++ ramips_fe_wr(RAMIPS_PSE_FQFC_CFG_INIT, RAMIPS_PSE_FQ_CFG); ++ } ++ ramips_fe_wr(1, RAMIPS_FE_RST_GL); ++ ramips_fe_wr(0, RAMIPS_FE_RST_GL); ++ ++ return 0; ++ ++err_free_irq: ++ free_irq(dev->irq, dev); ++ return err; ++} ++ ++static int ++ramips_eth_open(struct net_device *dev) ++{ ++ struct raeth_priv *re = netdev_priv(dev); ++ ++ ramips_fe_twr((ramips_fe_trr(RAETH_REG_PDMA_GLO_CFG) & 0xff) | ++ (RAMIPS_TX_WB_DDONE | RAMIPS_RX_DMA_EN | ++ RAMIPS_TX_DMA_EN | RAMIPS_PDMA_SIZE_4DWORDS), ++ RAETH_REG_PDMA_GLO_CFG); ++ ramips_phy_start(re); ++ netif_start_queue(dev); ++ return 0; ++} ++ ++static int ++ramips_eth_stop(struct net_device *dev) ++{ ++ struct raeth_priv *re = netdev_priv(dev); ++ ++ ramips_fe_twr(ramips_fe_trr(RAETH_REG_PDMA_GLO_CFG) & ++ ~(RAMIPS_TX_WB_DDONE | RAMIPS_RX_DMA_EN | RAMIPS_TX_DMA_EN), ++ RAETH_REG_PDMA_GLO_CFG); ++ ++ netif_stop_queue(dev); ++ ramips_phy_stop(re); ++ RADEBUG("ramips_eth: stopped\n"); ++ return 0; ++} ++ ++static int __init ++ramips_eth_probe(struct net_device *dev) ++{ ++ struct raeth_priv *re = netdev_priv(dev); ++ int err; ++ ++ BUG_ON(!re->reset_fe); ++ re->reset_fe(); ++ net_srandom(jiffies); ++ memcpy(dev->dev_addr, re->mac, ETH_ALEN); ++ of_get_mac_address_mtd(re->of_node, dev->dev_addr); ++ ether_setup(dev); ++ dev->mtu = 1500; ++ dev->watchdog_timeo = TX_TIMEOUT; ++ spin_lock_init(&re->page_lock); ++ spin_lock_init(&re->phy_lock); ++ ++ err = ramips_mdio_init(re); ++ if (err) ++ return err; ++ ++ err = ramips_phy_connect(re); ++ if (err) ++ goto err_mdio_cleanup; ++ ++ err = raeth_debugfs_init(re); ++ if (err) ++ goto err_phy_disconnect; ++ ++ err = ramips_eth_hw_init(dev); ++ if (err) ++ goto err_debugfs; ++ ++ return 0; ++ ++err_debugfs: ++ raeth_debugfs_exit(re); ++err_phy_disconnect: ++ ramips_phy_disconnect(re); ++err_mdio_cleanup: ++ ramips_mdio_cleanup(re); ++ return err; ++} ++ ++static void ++ramips_eth_uninit(struct net_device *dev) ++{ ++ struct raeth_priv *re = netdev_priv(dev); ++ ++ raeth_debugfs_exit(re); ++ ramips_phy_disconnect(re); ++ ramips_mdio_cleanup(re); ++ ramips_fe_twr(0, RAETH_REG_FE_INT_ENABLE); ++ free_irq(dev->irq, dev); ++ tasklet_kill(&re->tx_housekeeping_tasklet); ++ tasklet_kill(&re->rx_tasklet); ++ ramips_ring_cleanup(re); ++ ramips_ring_free(re); ++} ++ ++static const struct net_device_ops ramips_eth_netdev_ops = { ++ .ndo_init = ramips_eth_probe, ++ .ndo_uninit = ramips_eth_uninit, ++ .ndo_open = ramips_eth_open, ++ .ndo_stop = ramips_eth_stop, ++ .ndo_start_xmit = ramips_eth_hard_start_xmit, ++ .ndo_tx_timeout = ramips_eth_timeout, ++ .ndo_change_mtu = eth_change_mtu, ++ .ndo_set_mac_address = eth_mac_addr, ++ .ndo_validate_addr = eth_validate_addr, ++}; ++ ++#ifdef CONFIG_SOC_RT305X ++static void rt305x_fe_reset(void) ++{ ++#define RT305X_RESET_FE BIT(21) ++#define RT305X_RESET_ESW BIT(23) ++#define SYSC_REG_RESET_CTRL 0x034 ++ u32 reset_bits = RT305X_RESET_FE; ++ ++ if (soc_is_rt5350()) ++ reset_bits |= RT305X_RESET_ESW; ++ rt_sysc_w32(reset_bits, SYSC_REG_RESET_CTRL); ++ rt_sysc_w32(0, SYSC_REG_RESET_CTRL); ++} ++ ++struct ramips_soc_data rt3050_data = { ++ .mac = { 0x00, 0x11, 0x22, 0x33, 0x44, 0x55 }, ++ .reset_fe = rt305x_fe_reset, ++ .min_pkt_len = 64, ++}; ++ ++static const struct of_device_id ralink_eth_match[] = { ++ { .compatible = "ralink,rt3050-eth", .data = &rt3050_data }, ++ {}, ++}; ++#else ++static void rt3883_fe_reset(void) ++{ ++#define RT3883_SYSC_REG_RSTCTRL 0x34 ++#define RT3883_RSTCTRL_FE BIT(21) ++ u32 t; ++ ++ t = rt_sysc_r32(RT3883_SYSC_REG_RSTCTRL); ++ t |= RT3883_RSTCTRL_FE; ++ rt_sysc_w32(t , RT3883_SYSC_REG_RSTCTRL); ++ ++ t &= ~RT3883_RSTCTRL_FE; ++ rt_sysc_w32(t, RT3883_SYSC_REG_RSTCTRL); ++} ++ ++struct ramips_soc_data rt3883_data = { ++ .mac = { 0x00, 0x11, 0x22, 0x33, 0x44, 0x55 }, ++ .reset_fe = rt3883_fe_reset, ++ .min_pkt_len = 64, ++}; ++ ++static const struct of_device_id ralink_eth_match[] = { ++ { .compatible = "ralink,rt3883-eth", .data = &rt3883_data }, ++ {}, ++}; ++#endif ++MODULE_DEVICE_TABLE(of, ralink_eth_match); ++ ++static int ++ramips_eth_plat_probe(struct platform_device *plat) ++{ ++ struct raeth_priv *re; ++ struct resource *res; ++ struct clk *clk; ++ int err; ++ const struct of_device_id *match; ++ const struct ramips_soc_data *soc = NULL; ++ ++ match = of_match_device(ralink_eth_match, &plat->dev); ++ if (match) ++ soc = (const struct ramips_soc_data *) match->data; ++ ++ if (!soc) { ++ dev_err(&plat->dev, "no platform data specified\n"); ++ return -EINVAL; ++ } ++ ++ res = platform_get_resource(plat, IORESOURCE_MEM, 0); ++ if (!res) { ++ dev_err(&plat->dev, "no memory resource found\n"); ++ return -ENXIO; ++ } ++ ++ ramips_fe_base = ioremap_nocache(res->start, res->end - res->start + 1); ++ if (!ramips_fe_base) ++ return -ENOMEM; ++ ++ ramips_dev = alloc_etherdev(sizeof(struct raeth_priv)); ++ if (!ramips_dev) { ++ dev_err(&plat->dev, "alloc_etherdev failed\n"); ++ err = -ENOMEM; ++ goto err_unmap; ++ } ++ ++ strcpy(ramips_dev->name, "eth%d"); ++ ramips_dev->irq = platform_get_irq(plat, 0); ++ if (ramips_dev->irq < 0) { ++ dev_err(&plat->dev, "no IRQ resource found\n"); ++ err = -ENXIO; ++ goto err_free_dev; ++ } ++ ramips_dev->addr_len = ETH_ALEN; ++ ramips_dev->base_addr = (unsigned long)ramips_fe_base; ++ ramips_dev->netdev_ops = &ramips_eth_netdev_ops; ++ ++ re = netdev_priv(ramips_dev); ++ ++ clk = clk_get(&plat->dev, NULL); ++ if (IS_ERR(clk)) ++ panic("unable to get SYS clock, err=%ld", PTR_ERR(clk)); ++ re->sys_freq = clk_get_rate(clk); ++ ++ re->netdev = ramips_dev; ++ re->of_node = plat->dev.of_node; ++ re->parent = &plat->dev; ++ memcpy(re->mac, soc->mac, 6); ++ re->reset_fe = soc->reset_fe; ++ re->min_pkt_len = soc->min_pkt_len; ++ ++ err = register_netdev(ramips_dev); ++ if (err) { ++ dev_err(&plat->dev, "error bringing up device\n"); ++ goto err_free_dev; ++ } ++ ++ netdev_info(ramips_dev, "done loading\n"); ++ return 0; ++ ++ err_free_dev: ++ kfree(ramips_dev); ++ err_unmap: ++ iounmap(ramips_fe_base); ++ return err; ++} ++ ++static int ++ramips_eth_plat_remove(struct platform_device *plat) ++{ ++ unregister_netdev(ramips_dev); ++ free_netdev(ramips_dev); ++ RADEBUG("ramips_eth: unloaded\n"); ++ return 0; ++} ++ ++ ++ ++static struct platform_driver ramips_eth_driver = { ++ .probe = ramips_eth_plat_probe, ++ .remove = ramips_eth_plat_remove, ++ .driver = { ++ .name = "ramips_eth", ++ .owner = THIS_MODULE, ++ .of_match_table = ralink_eth_match ++ }, ++}; ++ ++static int __init ++ramips_eth_init(void) ++{ ++ int ret; ++ ++ ret = raeth_debugfs_root_init(); ++ if (ret) ++ goto err_out; ++ ++ ret = rt305x_esw_init(); ++ if (ret) ++ goto err_debugfs_exit; ++ ++ ret = platform_driver_register(&ramips_eth_driver); ++ if (ret) { ++ printk(KERN_ERR ++ "ramips_eth: Error registering platfom driver!\n"); ++ goto esw_cleanup; ++ } ++ ++ return 0; ++ ++esw_cleanup: ++ rt305x_esw_exit(); ++err_debugfs_exit: ++ raeth_debugfs_root_exit(); ++err_out: ++ return ret; ++} ++ ++static void __exit ++ramips_eth_cleanup(void) ++{ ++ platform_driver_unregister(&ramips_eth_driver); ++ rt305x_esw_exit(); ++ raeth_debugfs_root_exit(); ++} ++ ++module_init(ramips_eth_init); ++module_exit(ramips_eth_cleanup); ++ ++MODULE_LICENSE("GPL"); ++MODULE_AUTHOR("John Crispin "); ++MODULE_DESCRIPTION("ethernet driver for ramips boards"); diff --git a/target/linux/ramips/patches-3.8/0137-watchdog-adds-ralink-wdt.patch b/target/linux/ramips/patches-3.8/0137-watchdog-adds-ralink-wdt.patch new file mode 100644 index 0000000000..3b7246ffdb --- /dev/null +++ b/target/linux/ramips/patches-3.8/0137-watchdog-adds-ralink-wdt.patch @@ -0,0 +1,395 @@ +From 14c1b064274d28cf88113a685c58374a515f3018 Mon Sep 17 00:00:00 2001 +From: John Crispin +Date: Mon, 22 Apr 2013 23:23:07 +0200 +Subject: [PATCH 137/137] watchdog: adds ralink wdt + +Adds the watchdog driver for ralink SoC. + +Signed-off-by: John Crispin +--- + drivers/watchdog/Kconfig | 6 + + drivers/watchdog/Makefile | 1 + + drivers/watchdog/ralink_wdt.c | 352 +++++++++++++++++++++++++++++++++++++++++ + 3 files changed, 359 insertions(+) + create mode 100644 drivers/watchdog/ralink_wdt.c + +--- a/drivers/watchdog/Kconfig ++++ b/drivers/watchdog/Kconfig +@@ -1077,6 +1077,12 @@ config LANTIQ_WDT + help + Hardware driver for the Lantiq SoC Watchdog Timer. + ++config RALINK_WDT ++ tristate "Ralink SoC watchdog" ++ depends on RALINK ++ help ++ Hardware driver for the Ralink SoC Watchdog Timer. ++ + # PARISC Architecture + + # POWERPC Architecture +--- a/drivers/watchdog/Makefile ++++ b/drivers/watchdog/Makefile +@@ -132,6 +132,7 @@ obj-$(CONFIG_TXX9_WDT) += txx9wdt.o + obj-$(CONFIG_OCTEON_WDT) += octeon-wdt.o + octeon-wdt-y := octeon-wdt-main.o octeon-wdt-nmi.o + obj-$(CONFIG_LANTIQ_WDT) += lantiq_wdt.o ++obj-$(CONFIG_RALINK_WDT) += ralink_wdt.o + + # PARISC Architecture + +--- /dev/null ++++ b/drivers/watchdog/ralink_wdt.c +@@ -0,0 +1,352 @@ ++/* ++ * Ralink RT288X/RT305X built-in hardware watchdog timer ++ * ++ * Copyright (C) 2011 Gabor Juhos ++ * ++ * This driver was based on: drivers/watchdog/ixp4xx_wdt.c ++ * Author: Deepak Saxena ++ * Copyright 2004 (c) MontaVista, Software, Inc. ++ * ++ * which again was based on sa1100 driver, ++ * Copyright (C) 2000 Oleg Drokin ++ * ++ * parts of the driver are based on Ralink's 2.6.21 BSP ++ * ++ * This program is free software; you can redistribute it and/or modify it ++ * under the terms of the GNU General Public License version 2 as published ++ * by the Free Software Foundation. ++ */ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#define DRIVER_NAME "ralink-wdt" ++ ++#define RALINK_WDT_TIMEOUT 30 /* seconds */ ++#define RALINK_WDT_PRESCALE 65536 ++ ++#define TIMER_REG_TMR1LOAD 0x00 ++#define TIMER_REG_TMR1CTL 0x08 ++ ++#define TMRSTAT_TMR1RST BIT(5) ++ ++#define TMR1CTL_ENABLE BIT(7) ++#define TMR1CTL_MODE_SHIFT 4 ++#define TMR1CTL_MODE_MASK 0x3 ++#define TMR1CTL_MODE_FREE_RUNNING 0x0 ++#define TMR1CTL_MODE_PERIODIC 0x1 ++#define TMR1CTL_MODE_TIMEOUT 0x2 ++#define TMR1CTL_MODE_WDT 0x3 ++#define TMR1CTL_PRESCALE_MASK 0xf ++#define TMR1CTL_PRESCALE_65536 0xf ++ ++static int nowayout = WATCHDOG_NOWAYOUT; ++module_param(nowayout, int, 0); ++MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started " ++ "(default=" __MODULE_STRING(WATCHDOG_NOWAYOUT) ")"); ++ ++static int ralink_wdt_timeout = RALINK_WDT_TIMEOUT; ++module_param_named(timeout, ralink_wdt_timeout, int, 0); ++MODULE_PARM_DESC(timeout, "Watchdog timeout in seconds, 0 means use maximum " ++ "(default=" __MODULE_STRING(RALINK_WDT_TIMEOUT) "s)"); ++ ++static unsigned long ralink_wdt_flags; ++ ++#define WDT_FLAGS_BUSY 0 ++#define WDT_FLAGS_EXPECT_CLOSE 1 ++ ++static struct clk *ralink_wdt_clk; ++static unsigned long ralink_wdt_freq; ++static int ralink_wdt_max_timeout; ++static void __iomem *ralink_wdt_base; ++ ++static inline void rt_wdt_w32(unsigned reg, u32 val) ++{ ++ __raw_writel(val, ralink_wdt_base + reg); ++} ++ ++static inline u32 rt_wdt_r32(unsigned reg) ++{ ++ return __raw_readl(ralink_wdt_base + reg); ++} ++ ++static inline void ralink_wdt_keepalive(void) ++{ ++ rt_wdt_w32(TIMER_REG_TMR1LOAD, ralink_wdt_timeout * ralink_wdt_freq); ++} ++ ++static inline void ralink_wdt_enable(void) ++{ ++ u32 t; ++ ++ ralink_wdt_keepalive(); ++ ++ t = rt_wdt_r32(TIMER_REG_TMR1CTL); ++ t |= TMR1CTL_ENABLE; ++ rt_wdt_w32(TIMER_REG_TMR1CTL, t); ++} ++ ++static inline void ralink_wdt_disable(void) ++{ ++ u32 t; ++ ++ ralink_wdt_keepalive(); ++ ++ t = rt_wdt_r32(TIMER_REG_TMR1CTL); ++ t &= ~TMR1CTL_ENABLE; ++ rt_wdt_w32(TIMER_REG_TMR1CTL, t); ++} ++ ++static int ralink_wdt_set_timeout(int val) ++{ ++ if (val < 1 || val > ralink_wdt_max_timeout) { ++ pr_warn(DRIVER_NAME ++ ": timeout value %d must be 0 < timeout <= %d, using %d\n", ++ val, ralink_wdt_max_timeout, ralink_wdt_timeout); ++ return -EINVAL; ++ } ++ ++ ralink_wdt_timeout = val; ++ ralink_wdt_keepalive(); ++ ++ return 0; ++} ++ ++static int ralink_wdt_open(struct inode *inode, struct file *file) ++{ ++ u32 t; ++ ++ if (test_and_set_bit(WDT_FLAGS_BUSY, &ralink_wdt_flags)) ++ return -EBUSY; ++ ++ clear_bit(WDT_FLAGS_EXPECT_CLOSE, &ralink_wdt_flags); ++ ++ t = rt_wdt_r32(TIMER_REG_TMR1CTL); ++ t &= ~(TMR1CTL_MODE_MASK << TMR1CTL_MODE_SHIFT | ++ TMR1CTL_PRESCALE_MASK); ++ t |= (TMR1CTL_MODE_WDT << TMR1CTL_MODE_SHIFT | ++ TMR1CTL_PRESCALE_65536); ++ rt_wdt_w32(TIMER_REG_TMR1CTL, t); ++ ++ ralink_wdt_enable(); ++ ++ return nonseekable_open(inode, file); ++} ++ ++static int ralink_wdt_release(struct inode *inode, struct file *file) ++{ ++ if (test_bit(WDT_FLAGS_EXPECT_CLOSE, &ralink_wdt_flags)) ++ ralink_wdt_disable(); ++ else { ++ pr_crit(DRIVER_NAME ": device closed unexpectedly, " ++ "watchdog timer will not stop!\n"); ++ ralink_wdt_keepalive(); ++ } ++ ++ clear_bit(WDT_FLAGS_BUSY, &ralink_wdt_flags); ++ clear_bit(WDT_FLAGS_EXPECT_CLOSE, &ralink_wdt_flags); ++ ++ return 0; ++} ++ ++static ssize_t rt_wdt_w32ite(struct file *file, const char *data, ++ size_t len, loff_t *ppos) ++{ ++ if (len) { ++ if (!nowayout) { ++ size_t i; ++ ++ clear_bit(WDT_FLAGS_EXPECT_CLOSE, &ralink_wdt_flags); ++ ++ for (i = 0; i != len; i++) { ++ char c; ++ ++ if (get_user(c, data + i)) ++ return -EFAULT; ++ ++ if (c == 'V') ++ set_bit(WDT_FLAGS_EXPECT_CLOSE, ++ &ralink_wdt_flags); ++ } ++ } ++ ++ ralink_wdt_keepalive(); ++ } ++ ++ return len; ++} ++ ++static const struct watchdog_info ralink_wdt_info = { ++ .options = WDIOF_SETTIMEOUT | WDIOF_KEEPALIVEPING | ++ WDIOF_MAGICCLOSE, ++ .firmware_version = 0, ++ .identity = "RALINK watchdog", ++}; ++ ++static long ralink_wdt_ioctl(struct file *file, unsigned int cmd, ++ unsigned long arg) ++{ ++ void __user *argp = (void __user *)arg; ++ int __user *p = argp; ++ int err; ++ int t; ++ ++ switch (cmd) { ++ case WDIOC_GETSUPPORT: ++ err = copy_to_user(argp, &ralink_wdt_info, ++ sizeof(ralink_wdt_info)) ? -EFAULT : 0; ++ break; ++ ++ case WDIOC_GETSTATUS: ++ err = put_user(0, p); ++ break; ++ ++ case WDIOC_KEEPALIVE: ++ ralink_wdt_keepalive(); ++ err = 0; ++ break; ++ ++ case WDIOC_SETTIMEOUT: ++ err = get_user(t, p); ++ if (err) ++ break; ++ ++ err = ralink_wdt_set_timeout(t); ++ if (err) ++ break; ++ ++ /* fallthrough */ ++ case WDIOC_GETTIMEOUT: ++ err = put_user(ralink_wdt_timeout, p); ++ break; ++ ++ default: ++ err = -ENOTTY; ++ break; ++ } ++ ++ return err; ++} ++ ++static const struct file_operations ralink_wdt_fops = { ++ .owner = THIS_MODULE, ++ .llseek = no_llseek, ++ .write = rt_wdt_w32ite, ++ .unlocked_ioctl = ralink_wdt_ioctl, ++ .open = ralink_wdt_open, ++ .release = ralink_wdt_release, ++}; ++ ++static struct miscdevice ralink_wdt_miscdev = { ++ .minor = WATCHDOG_MINOR, ++ .name = "watchdog", ++ .fops = &ralink_wdt_fops, ++}; ++ ++static int ralink_wdt_probe(struct platform_device *pdev) ++{ ++ struct resource *res; ++ int err; ++ ++ res = platform_get_resource(pdev, IORESOURCE_MEM, 0); ++ if (!res) { ++ dev_err(&pdev->dev, "no memory resource found\n"); ++ return -EINVAL; ++ } ++ ++ ralink_wdt_base = ioremap(res->start, resource_size(res)); ++ if (!ralink_wdt_base) ++ return -ENOMEM; ++ ++ ralink_wdt_clk = clk_get(&pdev->dev, NULL); ++ if (IS_ERR(ralink_wdt_clk)) { ++ err = PTR_ERR(ralink_wdt_clk); ++ goto err_unmap; ++ } ++ ++ err = clk_enable(ralink_wdt_clk); ++ if (err) ++ goto err_clk_put; ++ ++ ralink_wdt_freq = clk_get_rate(ralink_wdt_clk) / RALINK_WDT_PRESCALE; ++ if (!ralink_wdt_freq) { ++ err = -EINVAL; ++ goto err_clk_disable; ++ } ++ ++ ralink_wdt_max_timeout = (0xfffful / ralink_wdt_freq); ++ if (ralink_wdt_timeout < 1 || ++ ralink_wdt_timeout > ralink_wdt_max_timeout) { ++ ralink_wdt_timeout = ralink_wdt_max_timeout; ++ dev_info(&pdev->dev, ++ "timeout value must be 0 < timeout <= %d, using %d\n", ++ ralink_wdt_max_timeout, ralink_wdt_timeout); ++ } ++ ++ err = misc_register(&ralink_wdt_miscdev); ++ if (err) { ++ dev_err(&pdev->dev, ++ "unable to register misc device, err=%d\n", err); ++ goto err_clk_disable; ++ } ++ ++ return 0; ++ ++err_clk_disable: ++ clk_disable(ralink_wdt_clk); ++err_clk_put: ++ clk_put(ralink_wdt_clk); ++err_unmap: ++ iounmap(ralink_wdt_base); ++ return err; ++} ++ ++static int ralink_wdt_remove(struct platform_device *pdev) ++{ ++ misc_deregister(&ralink_wdt_miscdev); ++ clk_disable(ralink_wdt_clk); ++ clk_put(ralink_wdt_clk); ++ iounmap(ralink_wdt_base); ++ return 0; ++} ++ ++static void ralink_wdt_shutdown(struct platform_device *pdev) ++{ ++ ralink_wdt_disable(); ++} ++ ++static const struct of_device_id ralink_wdt_match[] = { ++ { .compatible = "ralink,rt2880-wdt" }, ++ {}, ++}; ++MODULE_DEVICE_TABLE(of, ralink_wdt_match); ++ ++static struct platform_driver ralink_wdt_driver = { ++ .probe = ralink_wdt_probe, ++ .remove = ralink_wdt_remove, ++ .shutdown = ralink_wdt_shutdown, ++ .driver = { ++ .name = DRIVER_NAME, ++ .owner = THIS_MODULE, ++ .of_match_table = ralink_wdt_match, ++ }, ++}; ++ ++module_platform_driver(ralink_wdt_driver); ++ ++MODULE_DESCRIPTION("MediaTek/Ralink RT288X/RT305X hardware watchdog driver"); ++MODULE_AUTHOR("Gabor Juhos -Date: Sun, 17 Mar 2013 10:30:48 +0100 -Subject: [PATCH 200/208] MIPS: read the mips_machine name from OF and output - it in /proc/cpuinfo - -This allows the userland to be compatible to the devive probing of mips_machine. - -Signed-off-by: John Crispin ---- - arch/mips/include/asm/prom.h | 3 +++ - arch/mips/kernel/proc.c | 6 +++++- - arch/mips/kernel/prom.c | 24 ++++++++++++++++++++++++ - 3 files changed, 32 insertions(+), 1 deletion(-) - ---- a/arch/mips/include/asm/prom.h -+++ b/arch/mips/include/asm/prom.h -@@ -44,8 +44,11 @@ extern void __dt_setup_arch(struct boot_ - __dt_setup_arch(&__dtb_##sym##_begin); \ - }) - -+extern char *of_mips_get_machine_name(void); -+ - #else /* CONFIG_OF */ - static inline void device_tree_init(void) { } -+static char *of_mips_get_machine_name(void) { return NULL; } - #endif /* CONFIG_OF */ - - #endif /* __ASM_PROM_H */ ---- a/arch/mips/kernel/proc.c -+++ b/arch/mips/kernel/proc.c -@@ -12,6 +12,7 @@ - #include - #include - #include -+#include - #include - - unsigned int vced_count, vcei_count; -@@ -34,7 +35,10 @@ static int show_cpuinfo(struct seq_file - */ - if (n == 0) { - seq_printf(m, "system type\t\t: %s\n", get_system_type()); -- if (mips_get_machine_name()) -+ if (of_mips_get_machine_name()) -+ seq_printf(m, "machine\t\t\t: %s\n", -+ of_mips_get_machine_name()); -+ else if (mips_get_machine_name()) - seq_printf(m, "machine\t\t\t: %s\n", - mips_get_machine_name()); - } ---- a/arch/mips/kernel/prom.c -+++ b/arch/mips/kernel/prom.c -@@ -23,6 +23,13 @@ - #include - #include - -+static char of_mips_machine_name[64] = "Unknown"; -+ -+char *of_mips_get_machine_name(void) -+{ -+ return of_mips_machine_name; -+} -+ - int __init early_init_dt_scan_memory_arch(unsigned long node, - const char *uname, int depth, - void *data) -@@ -50,6 +57,20 @@ void __init early_init_dt_setup_initrd_a - } - #endif - -+int __init early_init_dt_scan_model(unsigned long node, -+ const char *uname, int depth, -+ void *data) -+{ -+ if (!depth) { -+ char *model = of_get_flat_dt_prop(node, "model", NULL); -+ if (model) { -+ snprintf(of_mips_machine_name, sizeof(of_mips_machine_name), model); -+ pr_info("MIPS: machine is %s\n", of_mips_machine_name); -+ } -+ } -+ return 0; -+} -+ - void __init early_init_devtree(void *params) - { - /* Setup flat device-tree pointer */ -@@ -65,6 +86,9 @@ void __init early_init_devtree(void *par - /* Scan memory nodes */ - of_scan_flat_dt(early_init_dt_scan_root, NULL); - of_scan_flat_dt(early_init_dt_scan_memory_arch, NULL); -+ -+ /* try to load the mips machine name */ -+ of_scan_flat_dt(early_init_dt_scan_model, NULL); - } - - void __init __dt_setup_arch(struct boot_param_header *bph) diff --git a/target/linux/ramips/patches-3.8/0204-owrt-MIPS-ralink-add-usb-platform-support.patch b/target/linux/ramips/patches-3.8/0204-owrt-MIPS-ralink-add-usb-platform-support.patch index 0b5b443600..88514008a7 100644 --- a/target/linux/ramips/patches-3.8/0204-owrt-MIPS-ralink-add-usb-platform-support.patch +++ b/target/linux/ramips/patches-3.8/0204-owrt-MIPS-ralink-add-usb-platform-support.patch @@ -34,7 +34,7 @@ Signed-off-by: John Crispin obj-$(CONFIG_EARLY_PRINTK) += early_printk.o --- a/arch/mips/ralink/common.h +++ b/arch/mips/ralink/common.h -@@ -46,5 +46,6 @@ extern void prom_soc_init(struct ralink_ +@@ -51,5 +51,6 @@ extern void prom_soc_init(struct ralink_ __iomem void *plat_of_remap_node(const char *node); void ralink_pinmux(void); @@ -43,8 +43,8 @@ Signed-off-by: John Crispin #endif /* _RALINK_COMMON_H__ */ --- a/arch/mips/ralink/mt7620.c +++ b/arch/mips/ralink/mt7620.c -@@ -146,6 +146,11 @@ struct ralink_pinmux rt_pinmux = { - // .wdt_reset = rt305x_wdt_reset, +@@ -140,6 +140,11 @@ struct ralink_pinmux rt_gpio_pinmux = { + .uart_mask = MT7620_GPIO_MODE_GPIO, }; +void ralink_usb_platform(void) @@ -57,7 +57,7 @@ Signed-off-by: John Crispin unsigned long cpu_rate, sys_rate; --- a/arch/mips/ralink/of.c +++ b/arch/mips/ralink/of.c -@@ -102,6 +102,7 @@ static int __init plat_of_setup(void) +@@ -111,6 +111,7 @@ static int __init plat_of_setup(void) panic("failed to populate DT\n"); ralink_pinmux(); diff --git a/target/linux/ramips/patches-3.8/0205-owrt-MIPS-add-OWRTDTB-secion.patch b/target/linux/ramips/patches-3.8/0205-owrt-MIPS-add-OWRTDTB-secion.patch index f443468e3f..b1e8058c7b 100644 --- a/target/linux/ramips/patches-3.8/0205-owrt-MIPS-add-OWRTDTB-secion.patch +++ b/target/linux/ramips/patches-3.8/0205-owrt-MIPS-add-OWRTDTB-secion.patch @@ -32,7 +32,7 @@ Signed-off-by: John Crispin +#obj-y += dts/ --- a/arch/mips/ralink/of.c +++ b/arch/mips/ralink/of.c -@@ -76,6 +76,8 @@ void __init device_tree_init(void) +@@ -77,6 +77,8 @@ void __init device_tree_init(void) free_bootmem(base, size); } @@ -41,12 +41,12 @@ Signed-off-by: John Crispin void __init plat_mem_setup(void) { set_io_port_base(KSEG1); -@@ -84,7 +86,7 @@ void __init plat_mem_setup(void) +@@ -85,7 +87,7 @@ void __init plat_mem_setup(void) * Load the builtin devicetree. This causes the chosen node to be * parsed resulting in our memory appearing */ - __dt_setup_arch(&__dtb_start); + __dt_setup_arch(&__image_dtb); - } - static int __init plat_of_setup(void) + if (soc_info.mem_size) + add_memory_region(soc_info.mem_base, soc_info.mem_size, diff --git a/target/linux/ramips/patches-3.8/0207-owrt-MIPS-ralink-add-support-for-runtime-memory-dete.patch b/target/linux/ramips/patches-3.8/0207-owrt-MIPS-ralink-add-support-for-runtime-memory-dete.patch deleted file mode 100644 index 51e233a12c..0000000000 --- a/target/linux/ramips/patches-3.8/0207-owrt-MIPS-ralink-add-support-for-runtime-memory-dete.patch +++ /dev/null @@ -1,176 +0,0 @@ -From bcd97dbdcb7bc0300397db481872252e8849307b Mon Sep 17 00:00:00 2001 -From: John Crispin -Date: Mon, 25 Mar 2013 10:50:53 +0100 -Subject: [PATCH 207/208] owrt: MIPS: ralink: add support for runtime memory - detection - -This allows us to add a device_node called "memorydetect" to the DT with -information about the memory windoe of the SoC. Based on this the memory is -detected ar runtime. - -Signed-off-by: John Crispin ---- - arch/mips/include/asm/prom.h | 3 ++ - arch/mips/kernel/prom.c | 3 ++ - arch/mips/ralink/Makefile | 2 +- - arch/mips/ralink/memory.c | 119 ++++++++++++++++++++++++++++++++++++++++++ - 4 files changed, 126 insertions(+), 1 deletion(-) - create mode 100644 arch/mips/ralink/memory.c - ---- a/arch/mips/include/asm/prom.h -+++ b/arch/mips/include/asm/prom.h -@@ -20,6 +20,9 @@ - extern int early_init_dt_scan_memory_arch(unsigned long node, - const char *uname, int depth, void *data); - -+extern int early_init_dt_detect_memory(unsigned long node, -+ const char *uname, int depth, void *data); -+ - extern void device_tree_init(void); - - static inline unsigned long pci_address_to_pio(phys_addr_t address) ---- a/arch/mips/kernel/prom.c -+++ b/arch/mips/kernel/prom.c -@@ -88,6 +88,9 @@ void __init early_init_devtree(void *par - of_scan_flat_dt(early_init_dt_scan_memory_arch, NULL); - - /* try to load the mips machine name */ -+ of_scan_flat_dt(early_init_dt_detect_memory, NULL); -+ -+ /* try to load the mips machine name */ - of_scan_flat_dt(early_init_dt_scan_model, NULL); - } - ---- a/arch/mips/ralink/Makefile -+++ b/arch/mips/ralink/Makefile -@@ -6,7 +6,7 @@ - # Copyright (C) 2009-2011 Gabor Juhos - # Copyright (C) 2013 John Crispin - --obj-y := prom.o of.o reset.o clk.o irq.o pinmux.o timer.o -+obj-y := prom.o of.o reset.o clk.o irq.o pinmux.o timer.o memory.o - - obj-$(CONFIG_SOC_RT288X) += rt288x.o - obj-$(CONFIG_SOC_RT305X) += rt305x.o rt305x-usb.o ---- /dev/null -+++ b/arch/mips/ralink/memory.c -@@ -0,0 +1,119 @@ -+/* -+ * 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 Gabor Juhos -+ * Copyright (C) 2013 John Crispin -+ */ -+ -+#include -+#include -+#include -+ -+#include -+#include -+ -+#include "common.h" -+ -+#define MB (1024 * 1024) -+ -+unsigned long ramips_mem_base; -+unsigned long ramips_mem_size_min; -+unsigned long ramips_mem_size_max; -+ -+#ifdef CONFIG_SOC_RT305X -+ -+#include -+ -+static unsigned long rt5350_get_mem_size(void) -+{ -+ void __iomem *sysc = (void __iomem *) KSEG1ADDR(RT305X_SYSC_BASE); -+ unsigned long ret; -+ u32 t; -+ -+ t = __raw_readl(sysc + SYSC_REG_SYSTEM_CONFIG); -+ t = (t >> RT5350_SYSCFG0_DRAM_SIZE_SHIFT) & -+ RT5350_SYSCFG0_DRAM_SIZE_MASK; -+ -+ switch (t) { -+ case RT5350_SYSCFG0_DRAM_SIZE_2M: -+ ret = 2 * 1024 * 1024; -+ break; -+ case RT5350_SYSCFG0_DRAM_SIZE_8M: -+ ret = 8 * 1024 * 1024; -+ break; -+ case RT5350_SYSCFG0_DRAM_SIZE_16M: -+ ret = 16 * 1024 * 1024; -+ break; -+ case RT5350_SYSCFG0_DRAM_SIZE_32M: -+ ret = 32 * 1024 * 1024; -+ break; -+ case RT5350_SYSCFG0_DRAM_SIZE_64M: -+ ret = 64 * 1024 * 1024; -+ break; -+ default: -+ panic("rt5350: invalid DRAM size: %u", t); -+ break; -+ } -+ -+ return ret; -+} -+ -+#endif -+ -+static void __init detect_mem_size(void) -+{ -+ unsigned long size; -+ -+#ifdef CONFIG_SOC_RT305X -+ if (soc_is_rt5350()) { -+ size = rt5350_get_mem_size(); -+ } else -+#endif -+ { -+ void *base; -+ -+ base = (void *) KSEG1ADDR(detect_mem_size); -+ for (size = ramips_mem_size_min; size < ramips_mem_size_max; -+ size <<= 1 ) { -+ if (!memcmp(base, base + size, 1024)) -+ break; -+ } -+ } -+ -+ pr_info("memory detected: %uMB\n", (unsigned int) size / MB); -+ -+ add_memory_region(ramips_mem_base, size, BOOT_MEM_RAM); -+} -+ -+int __init early_init_dt_detect_memory(unsigned long node, const char *uname, -+ int depth, void *data) -+{ -+ unsigned long l; -+ __be32 *mem; -+ -+ /* We are scanning "memorydetect" nodes only */ -+ if (depth != 1 || strcmp(uname, "memorydetect") != 0) -+ return 0; -+ -+ mem = of_get_flat_dt_prop(node, "ralink,memory", &l); -+ if (mem == NULL) -+ return 0; -+ -+ if ((l / sizeof(__be32)) != 3) -+ panic("invalid memorydetect node\n"); -+ -+ ramips_mem_base = dt_mem_next_cell(dt_root_addr_cells, &mem); -+ ramips_mem_size_min = dt_mem_next_cell(dt_root_size_cells, &mem); -+ ramips_mem_size_max = dt_mem_next_cell(dt_root_size_cells, &mem); -+ -+ pr_info("memory window: 0x%llx, min: %uMB, max: %uMB\n", -+ (unsigned long long) ramips_mem_base, -+ (unsigned int) ramips_mem_size_min / MB, -+ (unsigned int) ramips_mem_size_max / MB); -+ -+ detect_mem_size(); -+ -+ return 0; -+} diff --git a/target/linux/ramips/patches-3.8/0212-MIPS-ralink-add-GPIO-mode-to-RT305x-UART-pinmux-grou.patch b/target/linux/ramips/patches-3.8/0212-MIPS-ralink-add-GPIO-mode-to-RT305x-UART-pinmux-grou.patch deleted file mode 100644 index 81c655d110..0000000000 --- a/target/linux/ramips/patches-3.8/0212-MIPS-ralink-add-GPIO-mode-to-RT305x-UART-pinmux-grou.patch +++ /dev/null @@ -1,14 +0,0 @@ ---- a/arch/mips/ralink/rt305x.c -+++ b/arch/mips/ralink/rt305x.c -@@ -97,6 +97,11 @@ struct ralink_pinmux_grp uart_mux[] = { - .mask = RT305X_GPIO_MODE_GPIO_I2S, - .gpio_first = RT305X_GPIO_7, - .gpio_last = RT305X_GPIO_14, -+ }, { -+ .name = "gpio", -+ .mask = RT305X_GPIO_MODE_GPIO, -+ .gpio_first = RT305X_GPIO_7, -+ .gpio_last = RT305X_GPIO_14, - }, {0} - }; - -- cgit v1.2.3