From 7206a10548e457fc7ef77437b1502267262a493c Mon Sep 17 00:00:00 2001 From: Waldemar Brodkorb Date: Sun, 6 Dec 2015 17:00:48 +0100 Subject: ath79 board support Use full OpenWrt patch for it, as it works better on 4.1.13 kernel. Deduplicate the patches for atheros devices. --- .../ath79/patches/4.1.13/0001-openwrt-ath79.patch | 47200 +++++++++++++++++++ .../3.14.54/0001-mtd-add-rb4xx-nand-driver.patch | 351 - ...htool-ioctl-support-used-by-ag71xx-driver.patch | 80 - .../3.14.54/0003-net-add-ag71xx-mac-driver.patch | 4245 -- ...ivers-link-SPI-drivers-before-MTD-drivers.patch | 27 - ...ious-flags-to-spi_transfer-and-spi_messag.patch | 34 - .../3.14.54/0006-spi-add-rb4xx-SPI-driver.patch | 557 - .../3.14.54/0007-spi-add-rb4xx-cpld-driver.patch | 548 - .../3.14.54/0008-gpio-add-GPIO-latch-driver.patch | 290 - ...0009-spi-export-spi_bitbang_bufs-function.patch | 45 - ...spi-add-type-field-to-spi_transfer-struct.patch | 37 - .../0011-mtd-m25p80-set-SPI-transfer-type.patch | 29 - ...mips-ath79-swizzle-PCI-address-for-ar71xx.patch | 130 - .../3.14.54/0013-net-add-swconfig-support.patch | 1859 - ...-add-detach-callback-to-struct-phy_driver.patch | 46 - .../3.14.54/0015-phy-add-ar8216-PHY-support.patch | 3671 -- .../0016-phy-mdio-bitbang-ignore-TA-value.patch | 44 - .../0017-MIPS-ath79-fix-maximum-timeout.patch | 37 - ...PHY-drivers-to-insert-packet-mangle-hooks.patch | 211 - ...9-MIPS-ath79-process-board-cmdline-option.patch | 26 - ...020-spi-ath79-add-fast-flash-read-support.patch | 202 - .../3.14.54/0021-phy-add-mdio-boardinfo.patch | 227 - ...0022-mips-ath79-add-ath79-ethernet-driver.patch | 1429 - ...S-ath79-add-Mikrotik-rb4xx-device-support.patch | 536 - .../3.14.54/0024-various-fixups-for-Werror.patch | 105 - .../0025-rb4xx_nand-add-partition-for-cfgfs.patch | 28 - ...us-fixups-for-ath5k-fixing-system-freezes.patch | 108 - .../3.14.54/0001-mtd-add-rb4xx-nand-driver.patch | 351 - ...htool-ioctl-support-used-by-ag71xx-driver.patch | 80 - .../3.14.54/0003-net-add-ag71xx-mac-driver.patch | 4245 -- ...ivers-link-SPI-drivers-before-MTD-drivers.patch | 27 - ...ious-flags-to-spi_transfer-and-spi_messag.patch | 34 - .../3.14.54/0006-spi-add-rb4xx-SPI-driver.patch | 557 - .../3.14.54/0007-spi-add-rb4xx-cpld-driver.patch | 548 - .../3.14.54/0008-gpio-add-GPIO-latch-driver.patch | 290 - ...0009-spi-export-spi_bitbang_bufs-function.patch | 45 - ...spi-add-type-field-to-spi_transfer-struct.patch | 37 - .../0011-mtd-m25p80-set-SPI-transfer-type.patch | 29 - ...mips-ath79-swizzle-PCI-address-for-ar71xx.patch | 130 - .../3.14.54/0013-net-add-swconfig-support.patch | 1859 - ...-add-detach-callback-to-struct-phy_driver.patch | 46 - .../3.14.54/0015-phy-add-ar8216-PHY-support.patch | 3671 -- .../0016-phy-mdio-bitbang-ignore-TA-value.patch | 44 - .../0017-MIPS-ath79-fix-maximum-timeout.patch | 37 - ...PHY-drivers-to-insert-packet-mangle-hooks.patch | 211 - ...9-MIPS-ath79-process-board-cmdline-option.patch | 26 - ...020-spi-ath79-add-fast-flash-read-support.patch | 202 - .../3.14.54/0021-phy-add-mdio-boardinfo.patch | 227 - ...0022-mips-ath79-add-ath79-ethernet-driver.patch | 1429 - ...S-ath79-add-Mikrotik-rb4xx-device-support.patch | 536 - .../3.14.54/0024-various-fixups-for-Werror.patch | 105 - .../0025-rb4xx_nand-add-partition-for-cfgfs.patch | 28 - ...us-fixups-for-ath5k-fixing-system-freezes.patch | 108 - .../3.14.54/0027-ar71xx-add-zboot-support.patch | 64 - ...028-ag71xx-workaround-some-link-state-bug.patch | 39 - ...0029-MIPS-Fix-build-with-binutils-2.24.51.patch | 474 - .../4.1.10/0001-mtd-add-rb4xx-nand-driver.patch | 351 - ...htool-ioctl-support-used-by-ag71xx-driver.patch | 80 - .../4.1.10/0003-net-add-ag71xx-mac-driver.patch | 4185 -- ...ious-flags-to-spi_transfer-and-spi_messag.patch | 34 - .../4.1.10/0006-spi-add-rb4xx-SPI-driver.patch | 538 - .../4.1.10/0007-spi-add-rb4xx-cpld-driver.patch | 525 - .../4.1.10/0008-gpio-add-GPIO-latch-driver.patch | 290 - ...0009-spi-export-spi_bitbang_bufs-function.patch | 45 - ...spi-add-type-field-to-spi_transfer-struct.patch | 37 - ...mips-ath79-swizzle-PCI-address-for-ar71xx.patch | 130 - .../4.1.10/0013-net-add-swconfig-support.patch | 1837 - .../4.1.10/0015-phy-add-ar8216-PHY-support.patch | 4513 -- .../0016-phy-mdio-bitbang-ignore-TA-value.patch | 44 - .../0017-MIPS-ath79-fix-maximum-timeout.patch | 37 - ...PHY-drivers-to-insert-packet-mangle-hooks.patch | 167 - ...9-MIPS-ath79-process-board-cmdline-option.patch | 26 - ...020-spi-ath79-add-fast-flash-read-support.patch | 202 - .../4.1.10/0021-phy-add-mdio-boardinfo.patch | 199 - ...0022-mips-ath79-add-ath79-ethernet-driver.patch | 1429 - ...S-ath79-add-Mikrotik-rb4xx-device-support.patch | 536 - .../4.1.10/0024-various-fixups-for-Werror.patch | 66 - .../0025-rb4xx_nand-add-partition-for-cfgfs.patch | 28 - .../4.1.10/0027-ar71xx-add-zboot-support.patch | 64 - ...028-ag71xx-workaround-some-link-state-bug.patch | 39 - .../4.1.10/0029-gpio-add-gpio-latch-driver.patch | 1261 - target/mips/systems/dragino-ms14s | 1 + target/mips/systems/mikrotik-rb4xx | 1 + 83 files changed, 47202 insertions(+), 47044 deletions(-) create mode 100644 target/mips/ath79/patches/4.1.13/0001-openwrt-ath79.patch delete mode 100644 target/mips/dragino-ms14s/patches/3.14.54/0001-mtd-add-rb4xx-nand-driver.patch delete mode 100644 target/mips/dragino-ms14s/patches/3.14.54/0002-phy-add-ethtool-ioctl-support-used-by-ag71xx-driver.patch delete mode 100644 target/mips/dragino-ms14s/patches/3.14.54/0003-net-add-ag71xx-mac-driver.patch delete mode 100644 target/mips/dragino-ms14s/patches/3.14.54/0004-drivers-link-SPI-drivers-before-MTD-drivers.patch delete mode 100644 target/mips/dragino-ms14s/patches/3.14.54/0005-spi-add-various-flags-to-spi_transfer-and-spi_messag.patch delete mode 100644 target/mips/dragino-ms14s/patches/3.14.54/0006-spi-add-rb4xx-SPI-driver.patch delete mode 100644 target/mips/dragino-ms14s/patches/3.14.54/0007-spi-add-rb4xx-cpld-driver.patch delete mode 100644 target/mips/dragino-ms14s/patches/3.14.54/0008-gpio-add-GPIO-latch-driver.patch delete mode 100644 target/mips/dragino-ms14s/patches/3.14.54/0009-spi-export-spi_bitbang_bufs-function.patch delete mode 100644 target/mips/dragino-ms14s/patches/3.14.54/0010-spi-add-type-field-to-spi_transfer-struct.patch delete mode 100644 target/mips/dragino-ms14s/patches/3.14.54/0011-mtd-m25p80-set-SPI-transfer-type.patch delete mode 100644 target/mips/dragino-ms14s/patches/3.14.54/0012-mips-ath79-swizzle-PCI-address-for-ar71xx.patch delete mode 100644 target/mips/dragino-ms14s/patches/3.14.54/0013-net-add-swconfig-support.patch delete mode 100644 target/mips/dragino-ms14s/patches/3.14.54/0014-phy-add-detach-callback-to-struct-phy_driver.patch delete mode 100644 target/mips/dragino-ms14s/patches/3.14.54/0015-phy-add-ar8216-PHY-support.patch delete mode 100644 target/mips/dragino-ms14s/patches/3.14.54/0016-phy-mdio-bitbang-ignore-TA-value.patch delete mode 100644 target/mips/dragino-ms14s/patches/3.14.54/0017-MIPS-ath79-fix-maximum-timeout.patch delete mode 100644 target/mips/dragino-ms14s/patches/3.14.54/0018-net-allow-PHY-drivers-to-insert-packet-mangle-hooks.patch delete mode 100644 target/mips/dragino-ms14s/patches/3.14.54/0019-MIPS-ath79-process-board-cmdline-option.patch delete mode 100644 target/mips/dragino-ms14s/patches/3.14.54/0020-spi-ath79-add-fast-flash-read-support.patch delete mode 100644 target/mips/dragino-ms14s/patches/3.14.54/0021-phy-add-mdio-boardinfo.patch delete mode 100644 target/mips/dragino-ms14s/patches/3.14.54/0022-mips-ath79-add-ath79-ethernet-driver.patch delete mode 100644 target/mips/dragino-ms14s/patches/3.14.54/0023-MIPS-ath79-add-Mikrotik-rb4xx-device-support.patch delete mode 100644 target/mips/dragino-ms14s/patches/3.14.54/0024-various-fixups-for-Werror.patch delete mode 100644 target/mips/dragino-ms14s/patches/3.14.54/0025-rb4xx_nand-add-partition-for-cfgfs.patch delete mode 100644 target/mips/dragino-ms14s/patches/3.14.54/0026-various-fixups-for-ath5k-fixing-system-freezes.patch delete mode 100644 target/mips/mikrotik-rb4xx/patches/3.14.54/0001-mtd-add-rb4xx-nand-driver.patch delete mode 100644 target/mips/mikrotik-rb4xx/patches/3.14.54/0002-phy-add-ethtool-ioctl-support-used-by-ag71xx-driver.patch delete mode 100644 target/mips/mikrotik-rb4xx/patches/3.14.54/0003-net-add-ag71xx-mac-driver.patch delete mode 100644 target/mips/mikrotik-rb4xx/patches/3.14.54/0004-drivers-link-SPI-drivers-before-MTD-drivers.patch delete mode 100644 target/mips/mikrotik-rb4xx/patches/3.14.54/0005-spi-add-various-flags-to-spi_transfer-and-spi_messag.patch delete mode 100644 target/mips/mikrotik-rb4xx/patches/3.14.54/0006-spi-add-rb4xx-SPI-driver.patch delete mode 100644 target/mips/mikrotik-rb4xx/patches/3.14.54/0007-spi-add-rb4xx-cpld-driver.patch delete mode 100644 target/mips/mikrotik-rb4xx/patches/3.14.54/0008-gpio-add-GPIO-latch-driver.patch delete mode 100644 target/mips/mikrotik-rb4xx/patches/3.14.54/0009-spi-export-spi_bitbang_bufs-function.patch delete mode 100644 target/mips/mikrotik-rb4xx/patches/3.14.54/0010-spi-add-type-field-to-spi_transfer-struct.patch delete mode 100644 target/mips/mikrotik-rb4xx/patches/3.14.54/0011-mtd-m25p80-set-SPI-transfer-type.patch delete mode 100644 target/mips/mikrotik-rb4xx/patches/3.14.54/0012-mips-ath79-swizzle-PCI-address-for-ar71xx.patch delete mode 100644 target/mips/mikrotik-rb4xx/patches/3.14.54/0013-net-add-swconfig-support.patch delete mode 100644 target/mips/mikrotik-rb4xx/patches/3.14.54/0014-phy-add-detach-callback-to-struct-phy_driver.patch delete mode 100644 target/mips/mikrotik-rb4xx/patches/3.14.54/0015-phy-add-ar8216-PHY-support.patch delete mode 100644 target/mips/mikrotik-rb4xx/patches/3.14.54/0016-phy-mdio-bitbang-ignore-TA-value.patch delete mode 100644 target/mips/mikrotik-rb4xx/patches/3.14.54/0017-MIPS-ath79-fix-maximum-timeout.patch delete mode 100644 target/mips/mikrotik-rb4xx/patches/3.14.54/0018-net-allow-PHY-drivers-to-insert-packet-mangle-hooks.patch delete mode 100644 target/mips/mikrotik-rb4xx/patches/3.14.54/0019-MIPS-ath79-process-board-cmdline-option.patch delete mode 100644 target/mips/mikrotik-rb4xx/patches/3.14.54/0020-spi-ath79-add-fast-flash-read-support.patch delete mode 100644 target/mips/mikrotik-rb4xx/patches/3.14.54/0021-phy-add-mdio-boardinfo.patch delete mode 100644 target/mips/mikrotik-rb4xx/patches/3.14.54/0022-mips-ath79-add-ath79-ethernet-driver.patch delete mode 100644 target/mips/mikrotik-rb4xx/patches/3.14.54/0023-MIPS-ath79-add-Mikrotik-rb4xx-device-support.patch delete mode 100644 target/mips/mikrotik-rb4xx/patches/3.14.54/0024-various-fixups-for-Werror.patch delete mode 100644 target/mips/mikrotik-rb4xx/patches/3.14.54/0025-rb4xx_nand-add-partition-for-cfgfs.patch delete mode 100644 target/mips/mikrotik-rb4xx/patches/3.14.54/0026-various-fixups-for-ath5k-fixing-system-freezes.patch delete mode 100644 target/mips/mikrotik-rb4xx/patches/3.14.54/0027-ar71xx-add-zboot-support.patch delete mode 100644 target/mips/mikrotik-rb4xx/patches/3.14.54/0028-ag71xx-workaround-some-link-state-bug.patch delete mode 100644 target/mips/mikrotik-rb4xx/patches/3.14.54/0029-MIPS-Fix-build-with-binutils-2.24.51.patch delete mode 100644 target/mips/mikrotik-rb4xx/patches/4.1.10/0001-mtd-add-rb4xx-nand-driver.patch delete mode 100644 target/mips/mikrotik-rb4xx/patches/4.1.10/0002-phy-add-ethtool-ioctl-support-used-by-ag71xx-driver.patch delete mode 100644 target/mips/mikrotik-rb4xx/patches/4.1.10/0003-net-add-ag71xx-mac-driver.patch delete mode 100644 target/mips/mikrotik-rb4xx/patches/4.1.10/0005-spi-add-various-flags-to-spi_transfer-and-spi_messag.patch delete mode 100644 target/mips/mikrotik-rb4xx/patches/4.1.10/0006-spi-add-rb4xx-SPI-driver.patch delete mode 100644 target/mips/mikrotik-rb4xx/patches/4.1.10/0007-spi-add-rb4xx-cpld-driver.patch delete mode 100644 target/mips/mikrotik-rb4xx/patches/4.1.10/0008-gpio-add-GPIO-latch-driver.patch delete mode 100644 target/mips/mikrotik-rb4xx/patches/4.1.10/0009-spi-export-spi_bitbang_bufs-function.patch delete mode 100644 target/mips/mikrotik-rb4xx/patches/4.1.10/0010-spi-add-type-field-to-spi_transfer-struct.patch delete mode 100644 target/mips/mikrotik-rb4xx/patches/4.1.10/0012-mips-ath79-swizzle-PCI-address-for-ar71xx.patch delete mode 100644 target/mips/mikrotik-rb4xx/patches/4.1.10/0013-net-add-swconfig-support.patch delete mode 100644 target/mips/mikrotik-rb4xx/patches/4.1.10/0015-phy-add-ar8216-PHY-support.patch delete mode 100644 target/mips/mikrotik-rb4xx/patches/4.1.10/0016-phy-mdio-bitbang-ignore-TA-value.patch delete mode 100644 target/mips/mikrotik-rb4xx/patches/4.1.10/0017-MIPS-ath79-fix-maximum-timeout.patch delete mode 100644 target/mips/mikrotik-rb4xx/patches/4.1.10/0018-net-allow-PHY-drivers-to-insert-packet-mangle-hooks.patch delete mode 100644 target/mips/mikrotik-rb4xx/patches/4.1.10/0019-MIPS-ath79-process-board-cmdline-option.patch delete mode 100644 target/mips/mikrotik-rb4xx/patches/4.1.10/0020-spi-ath79-add-fast-flash-read-support.patch delete mode 100644 target/mips/mikrotik-rb4xx/patches/4.1.10/0021-phy-add-mdio-boardinfo.patch delete mode 100644 target/mips/mikrotik-rb4xx/patches/4.1.10/0022-mips-ath79-add-ath79-ethernet-driver.patch delete mode 100644 target/mips/mikrotik-rb4xx/patches/4.1.10/0023-MIPS-ath79-add-Mikrotik-rb4xx-device-support.patch delete mode 100644 target/mips/mikrotik-rb4xx/patches/4.1.10/0024-various-fixups-for-Werror.patch delete mode 100644 target/mips/mikrotik-rb4xx/patches/4.1.10/0025-rb4xx_nand-add-partition-for-cfgfs.patch delete mode 100644 target/mips/mikrotik-rb4xx/patches/4.1.10/0027-ar71xx-add-zboot-support.patch delete mode 100644 target/mips/mikrotik-rb4xx/patches/4.1.10/0028-ag71xx-workaround-some-link-state-bug.patch delete mode 100644 target/mips/mikrotik-rb4xx/patches/4.1.10/0029-gpio-add-gpio-latch-driver.patch diff --git a/target/mips/ath79/patches/4.1.13/0001-openwrt-ath79.patch b/target/mips/ath79/patches/4.1.13/0001-openwrt-ath79.patch new file mode 100644 index 000000000..4178f20cb --- /dev/null +++ b/target/mips/ath79/patches/4.1.13/0001-openwrt-ath79.patch @@ -0,0 +1,47200 @@ +diff -Nur linux-4.1.13.orig/arch/mips/ath79/clock.c linux-4.1.13/arch/mips/ath79/clock.c +--- linux-4.1.13.orig/arch/mips/ath79/clock.c 2015-11-09 23:34:10.000000000 +0100 ++++ linux-4.1.13/arch/mips/ath79/clock.c 2015-12-04 19:57:05.422010155 +0100 +@@ -25,7 +25,7 @@ + #include "common.h" + + #define AR71XX_BASE_FREQ 40000000 +-#define AR724X_BASE_FREQ 5000000 ++#define AR724X_BASE_FREQ 40000000 + #define AR913X_BASE_FREQ 5000000 + + struct clk { +@@ -99,8 +99,8 @@ + div = ((pll >> AR724X_PLL_DIV_SHIFT) & AR724X_PLL_DIV_MASK); + freq = div * ref_rate; + +- div = ((pll >> AR724X_PLL_REF_DIV_SHIFT) & AR724X_PLL_REF_DIV_MASK); +- freq *= div; ++ div = ((pll >> AR724X_PLL_REF_DIV_SHIFT) & AR724X_PLL_REF_DIV_MASK) * 2; ++ freq /= div; + + cpu_rate = freq; + +@@ -350,6 +350,91 @@ + iounmap(dpll_base); + } + ++static void __init qca953x_clocks_init(void) ++{ ++ unsigned long ref_rate; ++ unsigned long cpu_rate; ++ unsigned long ddr_rate; ++ unsigned long ahb_rate; ++ u32 pll, out_div, ref_div, nint, frac, clk_ctrl, postdiv; ++ u32 cpu_pll, ddr_pll; ++ u32 bootstrap; ++ ++ bootstrap = ath79_reset_rr(QCA953X_RESET_REG_BOOTSTRAP); ++ if (bootstrap & QCA953X_BOOTSTRAP_REF_CLK_40) ++ ref_rate = 40 * 1000 * 1000; ++ else ++ ref_rate = 25 * 1000 * 1000; ++ ++ pll = ath79_pll_rr(QCA953X_PLL_CPU_CONFIG_REG); ++ out_div = (pll >> QCA953X_PLL_CPU_CONFIG_OUTDIV_SHIFT) & ++ QCA953X_PLL_CPU_CONFIG_OUTDIV_MASK; ++ ref_div = (pll >> QCA953X_PLL_CPU_CONFIG_REFDIV_SHIFT) & ++ QCA953X_PLL_CPU_CONFIG_REFDIV_MASK; ++ nint = (pll >> QCA953X_PLL_CPU_CONFIG_NINT_SHIFT) & ++ QCA953X_PLL_CPU_CONFIG_NINT_MASK; ++ frac = (pll >> QCA953X_PLL_CPU_CONFIG_NFRAC_SHIFT) & ++ QCA953X_PLL_CPU_CONFIG_NFRAC_MASK; ++ ++ cpu_pll = nint * ref_rate / ref_div; ++ cpu_pll += frac * (ref_rate >> 6) / ref_div; ++ cpu_pll /= (1 << out_div); ++ ++ pll = ath79_pll_rr(QCA953X_PLL_DDR_CONFIG_REG); ++ out_div = (pll >> QCA953X_PLL_DDR_CONFIG_OUTDIV_SHIFT) & ++ QCA953X_PLL_DDR_CONFIG_OUTDIV_MASK; ++ ref_div = (pll >> QCA953X_PLL_DDR_CONFIG_REFDIV_SHIFT) & ++ QCA953X_PLL_DDR_CONFIG_REFDIV_MASK; ++ nint = (pll >> QCA953X_PLL_DDR_CONFIG_NINT_SHIFT) & ++ QCA953X_PLL_DDR_CONFIG_NINT_MASK; ++ frac = (pll >> QCA953X_PLL_DDR_CONFIG_NFRAC_SHIFT) & ++ QCA953X_PLL_DDR_CONFIG_NFRAC_MASK; ++ ++ ddr_pll = nint * ref_rate / ref_div; ++ ddr_pll += frac * (ref_rate >> 6) / (ref_div << 4); ++ ddr_pll /= (1 << out_div); ++ ++ clk_ctrl = ath79_pll_rr(QCA953X_PLL_CLK_CTRL_REG); ++ ++ postdiv = (clk_ctrl >> QCA953X_PLL_CLK_CTRL_CPU_POST_DIV_SHIFT) & ++ QCA953X_PLL_CLK_CTRL_CPU_POST_DIV_MASK; ++ ++ if (clk_ctrl & QCA953X_PLL_CLK_CTRL_CPU_PLL_BYPASS) ++ cpu_rate = ref_rate; ++ else if (clk_ctrl & QCA953X_PLL_CLK_CTRL_CPUCLK_FROM_CPUPLL) ++ cpu_rate = cpu_pll / (postdiv + 1); ++ else ++ cpu_rate = ddr_pll / (postdiv + 1); ++ ++ postdiv = (clk_ctrl >> QCA953X_PLL_CLK_CTRL_DDR_POST_DIV_SHIFT) & ++ QCA953X_PLL_CLK_CTRL_DDR_POST_DIV_MASK; ++ ++ if (clk_ctrl & QCA953X_PLL_CLK_CTRL_DDR_PLL_BYPASS) ++ ddr_rate = ref_rate; ++ else if (clk_ctrl & QCA953X_PLL_CLK_CTRL_DDRCLK_FROM_DDRPLL) ++ ddr_rate = ddr_pll / (postdiv + 1); ++ else ++ ddr_rate = cpu_pll / (postdiv + 1); ++ ++ postdiv = (clk_ctrl >> QCA953X_PLL_CLK_CTRL_AHB_POST_DIV_SHIFT) & ++ QCA953X_PLL_CLK_CTRL_AHB_POST_DIV_MASK; ++ ++ if (clk_ctrl & QCA953X_PLL_CLK_CTRL_AHB_PLL_BYPASS) ++ ahb_rate = ref_rate; ++ else if (clk_ctrl & QCA953X_PLL_CLK_CTRL_AHBCLK_FROM_DDRPLL) ++ ahb_rate = ddr_pll / (postdiv + 1); ++ else ++ ahb_rate = cpu_pll / (postdiv + 1); ++ ++ ath79_add_sys_clkdev("ref", ref_rate); ++ ath79_add_sys_clkdev("cpu", cpu_rate); ++ ath79_add_sys_clkdev("ddr", ddr_rate); ++ ath79_add_sys_clkdev("ahb", ahb_rate); ++ ++ clk_add_alias("wdt", NULL, "ref", NULL); ++ clk_add_alias("uart", NULL, "ref", NULL); ++} ++ + static void __init qca955x_clocks_init(void) + { + unsigned long ref_rate; +@@ -435,6 +520,100 @@ + clk_add_alias("uart", NULL, "ref", NULL); + } + ++static void __init qca956x_clocks_init(void) ++{ ++ unsigned long ref_rate; ++ unsigned long cpu_rate; ++ unsigned long ddr_rate; ++ unsigned long ahb_rate; ++ u32 pll, out_div, ref_div, nint, hfrac, lfrac, clk_ctrl, postdiv; ++ u32 cpu_pll, ddr_pll; ++ u32 bootstrap; ++ ++ bootstrap = ath79_reset_rr(QCA956X_RESET_REG_BOOTSTRAP); ++ if (bootstrap & QCA956X_BOOTSTRAP_REF_CLK_40) ++ ref_rate = 40 * 1000 * 1000; ++ else ++ ref_rate = 25 * 1000 * 1000; ++ ++ pll = ath79_pll_rr(QCA956X_PLL_CPU_CONFIG_REG); ++ out_div = (pll >> QCA956X_PLL_CPU_CONFIG_OUTDIV_SHIFT) & ++ QCA956X_PLL_CPU_CONFIG_OUTDIV_MASK; ++ ref_div = (pll >> QCA956X_PLL_CPU_CONFIG_REFDIV_SHIFT) & ++ QCA956X_PLL_CPU_CONFIG_REFDIV_MASK; ++ ++ pll = ath79_pll_rr(QCA956X_PLL_CPU_CONFIG1_REG); ++ nint = (pll >> QCA956X_PLL_CPU_CONFIG1_NINT_SHIFT) & ++ QCA956X_PLL_CPU_CONFIG1_NINT_MASK; ++ hfrac = (pll >> QCA956X_PLL_CPU_CONFIG1_NFRAC_H_SHIFT) & ++ QCA956X_PLL_CPU_CONFIG1_NFRAC_H_MASK; ++ lfrac = (pll >> QCA956X_PLL_CPU_CONFIG1_NFRAC_L_SHIFT) & ++ QCA956X_PLL_CPU_CONFIG1_NFRAC_L_MASK; ++ ++ cpu_pll = nint * ref_rate / ref_div; ++ cpu_pll += (lfrac * ref_rate) / ((ref_div * 25) << 13); ++ cpu_pll += (hfrac >> 13) * ref_rate / ref_div; ++ cpu_pll /= (1 << out_div); ++ ++ pll = ath79_pll_rr(QCA956X_PLL_DDR_CONFIG_REG); ++ out_div = (pll >> QCA956X_PLL_DDR_CONFIG_OUTDIV_SHIFT) & ++ QCA956X_PLL_DDR_CONFIG_OUTDIV_MASK; ++ ref_div = (pll >> QCA956X_PLL_DDR_CONFIG_REFDIV_SHIFT) & ++ QCA956X_PLL_DDR_CONFIG_REFDIV_MASK; ++ pll = ath79_pll_rr(QCA956X_PLL_DDR_CONFIG1_REG); ++ nint = (pll >> QCA956X_PLL_DDR_CONFIG1_NINT_SHIFT) & ++ QCA956X_PLL_DDR_CONFIG1_NINT_MASK; ++ hfrac = (pll >> QCA956X_PLL_DDR_CONFIG1_NFRAC_H_SHIFT) & ++ QCA956X_PLL_DDR_CONFIG1_NFRAC_H_MASK; ++ lfrac = (pll >> QCA956X_PLL_DDR_CONFIG1_NFRAC_L_SHIFT) & ++ QCA956X_PLL_DDR_CONFIG1_NFRAC_L_MASK; ++ ++ ddr_pll = nint * ref_rate / ref_div; ++ ddr_pll += (lfrac * ref_rate) / ((ref_div * 25) << 13); ++ ddr_pll += (hfrac >> 13) * ref_rate / ref_div; ++ ddr_pll /= (1 << out_div); ++ ++ clk_ctrl = ath79_pll_rr(QCA956X_PLL_CLK_CTRL_REG); ++ ++ postdiv = (clk_ctrl >> QCA956X_PLL_CLK_CTRL_CPU_POST_DIV_SHIFT) & ++ QCA956X_PLL_CLK_CTRL_CPU_POST_DIV_MASK; ++ ++ if (clk_ctrl & QCA956X_PLL_CLK_CTRL_CPU_PLL_BYPASS) ++ cpu_rate = ref_rate; ++ else if (clk_ctrl & QCA956X_PLL_CLK_CTRL_CPU_DDRCLK_FROM_CPUPLL) ++ cpu_rate = ddr_pll / (postdiv + 1); ++ else ++ cpu_rate = cpu_pll / (postdiv + 1); ++ ++ postdiv = (clk_ctrl >> QCA956X_PLL_CLK_CTRL_DDR_POST_DIV_SHIFT) & ++ QCA956X_PLL_CLK_CTRL_DDR_POST_DIV_MASK; ++ ++ if (clk_ctrl & QCA956X_PLL_CLK_CTRL_DDR_PLL_BYPASS) ++ ddr_rate = ref_rate; ++ else if (clk_ctrl & QCA956X_PLL_CLK_CTRL_CPU_DDRCLK_FROM_DDRPLL) ++ ddr_rate = cpu_pll / (postdiv + 1); ++ else ++ ddr_rate = ddr_pll / (postdiv + 1); ++ ++ postdiv = (clk_ctrl >> QCA956X_PLL_CLK_CTRL_AHB_POST_DIV_SHIFT) & ++ QCA956X_PLL_CLK_CTRL_AHB_POST_DIV_MASK; ++ ++ if (clk_ctrl & QCA956X_PLL_CLK_CTRL_AHB_PLL_BYPASS) ++ ahb_rate = ref_rate; ++ else if (clk_ctrl & QCA956X_PLL_CLK_CTRL_AHBCLK_FROM_DDRPLL) ++ ahb_rate = ddr_pll / (postdiv + 1); ++ else ++ ahb_rate = cpu_pll / (postdiv + 1); ++ ++ ath79_add_sys_clkdev("ref", ref_rate); ++ ath79_add_sys_clkdev("cpu", cpu_rate); ++ ath79_add_sys_clkdev("ddr", ddr_rate); ++ ath79_add_sys_clkdev("ahb", ahb_rate); ++ ++ clk_add_alias("wdt", NULL, "ref", NULL); ++ clk_add_alias("uart", NULL, "ref", NULL); ++} ++ + void __init ath79_clocks_init(void) + { + if (soc_is_ar71xx()) +@@ -447,8 +626,12 @@ + ar933x_clocks_init(); + else if (soc_is_ar934x()) + ar934x_clocks_init(); ++ else if (soc_is_qca953x()) ++ qca953x_clocks_init(); + else if (soc_is_qca955x()) + qca955x_clocks_init(); ++ else if (soc_is_qca956x()) ++ qca956x_clocks_init(); + else + BUG(); + } +@@ -488,3 +671,15 @@ + return clk->rate; + } + EXPORT_SYMBOL(clk_get_rate); ++ ++int clk_set_rate(struct clk *clk, unsigned long rate) ++{ ++ return 0; ++} ++EXPORT_SYMBOL_GPL(clk_set_rate); ++ ++long clk_round_rate(struct clk *clk, unsigned long rate) ++{ ++ return 0; ++} ++EXPORT_SYMBOL_GPL(clk_round_rate); +diff -Nur linux-4.1.13.orig/arch/mips/ath79/common.c linux-4.1.13/arch/mips/ath79/common.c +--- linux-4.1.13.orig/arch/mips/ath79/common.c 2015-11-09 23:34:10.000000000 +0100 ++++ linux-4.1.13/arch/mips/ath79/common.c 2015-12-04 19:57:04.474072175 +0100 +@@ -22,6 +22,7 @@ + #include "common.h" + + static DEFINE_SPINLOCK(ath79_device_reset_lock); ++static DEFINE_MUTEX(ath79_flash_mutex); + + u32 ath79_cpu_freq; + EXPORT_SYMBOL_GPL(ath79_cpu_freq); +@@ -72,10 +73,14 @@ + reg = AR933X_RESET_REG_RESET_MODULE; + else if (soc_is_ar934x()) + reg = AR934X_RESET_REG_RESET_MODULE; ++ else if (soc_is_qca953x()) ++ reg = QCA953X_RESET_REG_RESET_MODULE; + else if (soc_is_qca955x()) + reg = QCA955X_RESET_REG_RESET_MODULE; ++ else if (soc_is_qca956x()) ++ reg = QCA956X_RESET_REG_RESET_MODULE; + else +- BUG(); ++ panic("Reset register not defined for this SOC"); + + spin_lock_irqsave(&ath79_device_reset_lock, flags); + t = ath79_reset_rr(reg); +@@ -100,10 +105,14 @@ + reg = AR933X_RESET_REG_RESET_MODULE; + else if (soc_is_ar934x()) + reg = AR934X_RESET_REG_RESET_MODULE; ++ else if (soc_is_qca953x()) ++ reg = QCA953X_RESET_REG_RESET_MODULE; + else if (soc_is_qca955x()) + reg = QCA955X_RESET_REG_RESET_MODULE; ++ else if (soc_is_qca956x()) ++ reg = QCA956X_RESET_REG_RESET_MODULE; + else +- BUG(); ++ panic("Reset register not defined for this SOC"); + + spin_lock_irqsave(&ath79_device_reset_lock, flags); + t = ath79_reset_rr(reg); +@@ -111,3 +120,42 @@ + spin_unlock_irqrestore(&ath79_device_reset_lock, flags); + } + EXPORT_SYMBOL_GPL(ath79_device_reset_clear); ++ ++u32 ath79_device_reset_get(u32 mask) ++{ ++ unsigned long flags; ++ u32 reg; ++ u32 ret; ++ ++ if (soc_is_ar71xx()) ++ reg = AR71XX_RESET_REG_RESET_MODULE; ++ else if (soc_is_ar724x()) ++ reg = AR724X_RESET_REG_RESET_MODULE; ++ else if (soc_is_ar913x()) ++ reg = AR913X_RESET_REG_RESET_MODULE; ++ else if (soc_is_ar933x()) ++ reg = AR933X_RESET_REG_RESET_MODULE; ++ else if (soc_is_ar934x()) ++ reg = AR934X_RESET_REG_RESET_MODULE; ++ else ++ BUG(); ++ ++ spin_lock_irqsave(&ath79_device_reset_lock, flags); ++ ret = ath79_reset_rr(reg); ++ spin_unlock_irqrestore(&ath79_device_reset_lock, flags); ++ return ret; ++} ++EXPORT_SYMBOL_GPL(ath79_device_reset_get); ++ ++void ath79_flash_acquire(void) ++{ ++ mutex_lock(&ath79_flash_mutex); ++} ++EXPORT_SYMBOL_GPL(ath79_flash_acquire); ++ ++void ath79_flash_release(void) ++{ ++ mutex_unlock(&ath79_flash_mutex); ++} ++EXPORT_SYMBOL_GPL(ath79_flash_release); ++ +diff -Nur linux-4.1.13.orig/arch/mips/ath79/common.h linux-4.1.13/arch/mips/ath79/common.h +--- linux-4.1.13.orig/arch/mips/ath79/common.h 2015-11-09 23:34:10.000000000 +0100 ++++ linux-4.1.13/arch/mips/ath79/common.h 2015-12-04 19:57:05.893979276 +0100 +@@ -27,6 +27,9 @@ + void ath79_gpio_function_enable(u32 mask); + void ath79_gpio_function_disable(u32 mask); + void ath79_gpio_function_setup(u32 set, u32 clear); ++void ath79_gpio_function2_setup(u32 set, u32 clear); ++void ath79_gpio_output_select(unsigned gpio, u8 val); ++int ath79_gpio_direction_select(unsigned gpio, bool oe); + void ath79_gpio_init(void); + + #endif /* __ATH79_COMMON_H */ +diff -Nur linux-4.1.13.orig/arch/mips/ath79/dev-ap9x-pci.c linux-4.1.13/arch/mips/ath79/dev-ap9x-pci.c +--- linux-4.1.13.orig/arch/mips/ath79/dev-ap9x-pci.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux-4.1.13/arch/mips/ath79/dev-ap9x-pci.c 2015-09-13 20:04:35.064524285 +0200 +@@ -0,0 +1,159 @@ ++/* ++ * Atheros AP9X reference board PCI initialization ++ * ++ * Copyright (C) 2009-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 ++ ++#include "dev-ap9x-pci.h" ++#include "pci-ath9k-fixup.h" ++#include "pci.h" ++ ++static struct ath9k_platform_data ap9x_wmac0_data = { ++ .led_pin = -1, ++}; ++static struct ath9k_platform_data ap9x_wmac1_data = { ++ .led_pin = -1, ++}; ++static char ap9x_wmac0_mac[6]; ++static char ap9x_wmac1_mac[6]; ++ ++__init void ap9x_pci_setup_wmac_led_pin(unsigned wmac, int pin) ++{ ++ switch (wmac) { ++ case 0: ++ ap9x_wmac0_data.led_pin = pin; ++ break; ++ case 1: ++ ap9x_wmac1_data.led_pin = pin; ++ break; ++ } ++} ++ ++__init struct ath9k_platform_data *ap9x_pci_get_wmac_data(unsigned wmac) ++{ ++ switch (wmac) { ++ case 0: ++ return &ap9x_wmac0_data; ++ ++ case 1: ++ return &ap9x_wmac1_data; ++ } ++ ++ return NULL; ++} ++ ++__init void ap9x_pci_setup_wmac_gpio(unsigned wmac, u32 mask, u32 val) ++{ ++ switch (wmac) { ++ case 0: ++ ap9x_wmac0_data.gpio_mask = mask; ++ ap9x_wmac0_data.gpio_val = val; ++ break; ++ case 1: ++ ap9x_wmac1_data.gpio_mask = mask; ++ ap9x_wmac1_data.gpio_val = val; ++ break; ++ } ++} ++ ++__init void ap9x_pci_setup_wmac_leds(unsigned wmac, struct gpio_led *leds, ++ int num_leds) ++{ ++ switch (wmac) { ++ case 0: ++ ap9x_wmac0_data.leds = leds; ++ ap9x_wmac0_data.num_leds = num_leds; ++ break; ++ case 1: ++ ap9x_wmac1_data.leds = leds; ++ ap9x_wmac1_data.num_leds = num_leds; ++ break; ++ } ++} ++ ++static int ap91_pci_plat_dev_init(struct pci_dev *dev) ++{ ++ switch (PCI_SLOT(dev->devfn)) { ++ case 0: ++ dev->dev.platform_data = &ap9x_wmac0_data; ++ break; ++ } ++ ++ return 0; ++} ++ ++__init void ap91_pci_init(u8 *cal_data, u8 *mac_addr) ++{ ++ if (cal_data) ++ memcpy(ap9x_wmac0_data.eeprom_data, cal_data, ++ sizeof(ap9x_wmac0_data.eeprom_data)); ++ ++ if (mac_addr) { ++ memcpy(ap9x_wmac0_mac, mac_addr, sizeof(ap9x_wmac0_mac)); ++ ap9x_wmac0_data.macaddr = ap9x_wmac0_mac; ++ } ++ ++ ath79_pci_set_plat_dev_init(ap91_pci_plat_dev_init); ++ ath79_register_pci(); ++ ++ pci_enable_ath9k_fixup(0, ap9x_wmac0_data.eeprom_data); ++} ++ ++__init void ap91_pci_init_simple(void) ++{ ++ ap91_pci_init(NULL, NULL); ++ ap9x_wmac0_data.eeprom_name = "pci_wmac0.eeprom"; ++} ++ ++static int ap94_pci_plat_dev_init(struct pci_dev *dev) ++{ ++ switch (PCI_SLOT(dev->devfn)) { ++ case 17: ++ dev->dev.platform_data = &ap9x_wmac0_data; ++ break; ++ ++ case 18: ++ dev->dev.platform_data = &ap9x_wmac1_data; ++ break; ++ } ++ ++ return 0; ++} ++ ++__init void ap94_pci_init(u8 *cal_data0, u8 *mac_addr0, ++ u8 *cal_data1, u8 *mac_addr1) ++{ ++ if (cal_data0) ++ memcpy(ap9x_wmac0_data.eeprom_data, cal_data0, ++ sizeof(ap9x_wmac0_data.eeprom_data)); ++ ++ if (cal_data1) ++ memcpy(ap9x_wmac1_data.eeprom_data, cal_data1, ++ sizeof(ap9x_wmac1_data.eeprom_data)); ++ ++ if (mac_addr0) { ++ memcpy(ap9x_wmac0_mac, mac_addr0, sizeof(ap9x_wmac0_mac)); ++ ap9x_wmac0_data.macaddr = ap9x_wmac0_mac; ++ } ++ ++ if (mac_addr1) { ++ memcpy(ap9x_wmac1_mac, mac_addr1, sizeof(ap9x_wmac1_mac)); ++ ap9x_wmac1_data.macaddr = ap9x_wmac1_mac; ++ } ++ ++ ath79_pci_set_plat_dev_init(ap94_pci_plat_dev_init); ++ ath79_register_pci(); ++ ++ pci_enable_ath9k_fixup(17, ap9x_wmac0_data.eeprom_data); ++ pci_enable_ath9k_fixup(18, ap9x_wmac1_data.eeprom_data); ++} +diff -Nur linux-4.1.13.orig/arch/mips/ath79/dev-ap9x-pci.h linux-4.1.13/arch/mips/ath79/dev-ap9x-pci.h +--- linux-4.1.13.orig/arch/mips/ath79/dev-ap9x-pci.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux-4.1.13/arch/mips/ath79/dev-ap9x-pci.h 2015-09-13 20:04:35.064524285 +0200 +@@ -0,0 +1,48 @@ ++/* ++ * Atheros AP9X reference board PCI initialization ++ * ++ * Copyright (C) 2009-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 _ATH79_DEV_AP9X_PCI_H ++#define _ATH79_DEV_AP9X_PCI_H ++ ++struct gpio_led; ++struct ath9k_platform_data; ++ ++#if defined(CONFIG_ATH79_DEV_AP9X_PCI) ++void ap9x_pci_setup_wmac_led_pin(unsigned wmac, int pin); ++void ap9x_pci_setup_wmac_gpio(unsigned wmac, u32 mask, u32 val); ++void ap9x_pci_setup_wmac_leds(unsigned wmac, struct gpio_led *leds, ++ int num_leds); ++struct ath9k_platform_data *ap9x_pci_get_wmac_data(unsigned wmac); ++ ++void ap91_pci_init(u8 *cal_data, u8 *mac_addr); ++void ap91_pci_init_simple(void); ++void ap94_pci_init(u8 *cal_data0, u8 *mac_addr0, ++ u8 *cal_data1, u8 *mac_addr1); ++ ++#else ++static inline void ap9x_pci_setup_wmac_led_pin(unsigned wmac, int pin) {} ++static inline void ap9x_pci_setup_wmac_gpio(unsigned wmac, ++ u32 mask, u32 val) {} ++static inline void ap9x_pci_setup_wmac_leds(unsigned wmac, ++ struct gpio_led *leds, ++ int num_leds) {} ++static inline struct ath9k_platform_data *ap9x_pci_get_wmac_data(unsigned wmac) ++{ ++ return NULL; ++} ++ ++static inline void ap91_pci_init(u8 *cal_data, u8 *mac_addr) {} ++static inline void ap91_pci_init_simple(void) {} ++static inline void ap94_pci_init(u8 *cal_data0, u8 *mac_addr0, ++ u8 *cal_data1, u8 *mac_addr1) {} ++#endif ++ ++#endif /* _ATH79_DEV_AP9X_PCI_H */ ++ +diff -Nur linux-4.1.13.orig/arch/mips/ath79/dev-common.c linux-4.1.13/arch/mips/ath79/dev-common.c +--- linux-4.1.13.orig/arch/mips/ath79/dev-common.c 2015-11-09 23:34:10.000000000 +0100 ++++ linux-4.1.13/arch/mips/ath79/dev-common.c 2015-12-04 19:57:04.474072175 +0100 +@@ -80,11 +80,22 @@ + + uart_clk_rate = ath79_get_sys_clk_rate("uart"); + ++ if (soc_is_ar71xx()) ++ ath79_gpio_function_enable(AR71XX_GPIO_FUNC_UART_EN); ++ else if (soc_is_ar724x()) ++ ath79_gpio_function_enable(AR724X_GPIO_FUNC_UART_EN); ++ else if (soc_is_ar913x()) ++ ath79_gpio_function_enable(AR913X_GPIO_FUNC_UART_EN); ++ else if (soc_is_ar933x()) ++ ath79_gpio_function_enable(AR933X_GPIO_FUNC_UART_EN); ++ + if (soc_is_ar71xx() || + soc_is_ar724x() || + soc_is_ar913x() || + soc_is_ar934x() || +- soc_is_qca955x()) { ++ soc_is_qca953x() || ++ soc_is_qca955x() || ++ soc_is_qca956x()) { + ath79_uart_data[0].uartclk = uart_clk_rate; + platform_device_register(&ath79_uart_device); + } else if (soc_is_ar933x()) { +diff -Nur linux-4.1.13.orig/arch/mips/ath79/dev-dsa.c linux-4.1.13/arch/mips/ath79/dev-dsa.c +--- linux-4.1.13.orig/arch/mips/ath79/dev-dsa.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux-4.1.13/arch/mips/ath79/dev-dsa.c 2015-09-13 20:04:35.064524285 +0200 +@@ -0,0 +1,41 @@ ++/* ++ * Atheros AR71xx DSA switch device support ++ * ++ * Copyright (C) 2008-2012 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. ++ */ ++ ++#include ++#include ++#include ++ ++#include ++ ++#include "dev-dsa.h" ++ ++static struct platform_device ar71xx_dsa_switch_device = { ++ .name = "dsa", ++ .id = 0, ++}; ++ ++void __init ath79_register_dsa(struct device *netdev, ++ struct device *miidev, ++ struct dsa_platform_data *d) ++{ ++ int i; ++ ++ d->netdev = netdev; ++ for (i = 0; i < d->nr_chips; i++) ++#if LINUX_VERSION_CODE < KERNEL_VERSION(3,15,0) ++ d->chip[i].mii_bus = miidev; ++#else ++ d->chip[i].host_dev = miidev; ++#endif ++ ++ ar71xx_dsa_switch_device.dev.platform_data = d; ++ platform_device_register(&ar71xx_dsa_switch_device); ++} +diff -Nur linux-4.1.13.orig/arch/mips/ath79/dev-dsa.h linux-4.1.13/arch/mips/ath79/dev-dsa.h +--- linux-4.1.13.orig/arch/mips/ath79/dev-dsa.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux-4.1.13/arch/mips/ath79/dev-dsa.h 2015-09-13 20:04:35.064524285 +0200 +@@ -0,0 +1,21 @@ ++/* ++ * Atheros AR71xx DSA switch device 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 _ATH79_DEV_DSA_H ++#define _ATH79_DEV_DSA_H ++ ++#include ++ ++void ath79_register_dsa(struct device *netdev, ++ struct device *miidev, ++ struct dsa_platform_data *d); ++ ++#endif /* _ATH79_DEV_DSA_H */ +diff -Nur linux-4.1.13.orig/arch/mips/ath79/dev-eth.c linux-4.1.13/arch/mips/ath79/dev-eth.c +--- linux-4.1.13.orig/arch/mips/ath79/dev-eth.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux-4.1.13/arch/mips/ath79/dev-eth.c 2015-11-21 17:22:11.759223549 +0100 +@@ -0,0 +1,1254 @@ ++/* ++ * Atheros AR71xx SoC platform devices ++ * ++ * Copyright (C) 2010-2011 Jaiganesh Narayanan ++ * Copyright (C) 2008-2012 Gabor Juhos ++ * Copyright (C) 2008 Imre Kaloz ++ * ++ * Parts of this file are based on Atheros 2.6.15 BSP ++ * Parts of this file are based on Atheros 2.6.31 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 "common.h" ++#include "dev-eth.h" ++ ++unsigned char ath79_mac_base[ETH_ALEN] __initdata; ++ ++static struct resource ath79_mdio0_resources[] = { ++ { ++ .name = "mdio_base", ++ .flags = IORESOURCE_MEM, ++ .start = AR71XX_GE0_BASE, ++ .end = AR71XX_GE0_BASE + 0x200 - 1, ++ } ++}; ++ ++struct ag71xx_mdio_platform_data ath79_mdio0_data; ++ ++struct platform_device ath79_mdio0_device = { ++ .name = "ag71xx-mdio", ++ .id = 0, ++ .resource = ath79_mdio0_resources, ++ .num_resources = ARRAY_SIZE(ath79_mdio0_resources), ++ .dev = { ++ .platform_data = &ath79_mdio0_data, ++ }, ++}; ++ ++static struct resource ath79_mdio1_resources[] = { ++ { ++ .name = "mdio_base", ++ .flags = IORESOURCE_MEM, ++ .start = AR71XX_GE1_BASE, ++ .end = AR71XX_GE1_BASE + 0x200 - 1, ++ } ++}; ++ ++struct ag71xx_mdio_platform_data ath79_mdio1_data; ++ ++struct platform_device ath79_mdio1_device = { ++ .name = "ag71xx-mdio", ++ .id = 1, ++ .resource = ath79_mdio1_resources, ++ .num_resources = ARRAY_SIZE(ath79_mdio1_resources), ++ .dev = { ++ .platform_data = &ath79_mdio1_data, ++ }, ++}; ++ ++static void ath79_set_pll(u32 cfg_reg, u32 pll_reg, u32 pll_val, u32 shift) ++{ ++ void __iomem *base; ++ u32 t; ++ ++ base = ioremap_nocache(AR71XX_PLL_BASE, AR71XX_PLL_SIZE); ++ ++ t = __raw_readl(base + cfg_reg); ++ t &= ~(3 << shift); ++ t |= (2 << shift); ++ __raw_writel(t, base + cfg_reg); ++ udelay(100); ++ ++ __raw_writel(pll_val, base + pll_reg); ++ ++ t |= (3 << shift); ++ __raw_writel(t, base + cfg_reg); ++ udelay(100); ++ ++ t &= ~(3 << shift); ++ __raw_writel(t, base + cfg_reg); ++ udelay(100); ++ ++ printk(KERN_DEBUG "ar71xx: pll_reg %#x: %#x\n", ++ (unsigned int)(base + pll_reg), __raw_readl(base + pll_reg)); ++ ++ iounmap(base); ++} ++ ++static void __init ath79_mii_ctrl_set_if(unsigned int reg, ++ unsigned int mii_if) ++{ ++ void __iomem *base; ++ u32 t; ++ ++ base = ioremap(AR71XX_MII_BASE, AR71XX_MII_SIZE); ++ ++ t = __raw_readl(base + reg); ++ t &= ~(AR71XX_MII_CTRL_IF_MASK); ++ t |= (mii_if & AR71XX_MII_CTRL_IF_MASK); ++ __raw_writel(t, base + reg); ++ ++ iounmap(base); ++} ++ ++static void ath79_mii_ctrl_set_speed(unsigned int reg, unsigned int speed) ++{ ++ void __iomem *base; ++ unsigned int mii_speed; ++ u32 t; ++ ++ switch (speed) { ++ case SPEED_10: ++ mii_speed = AR71XX_MII_CTRL_SPEED_10; ++ break; ++ case SPEED_100: ++ mii_speed = AR71XX_MII_CTRL_SPEED_100; ++ break; ++ case SPEED_1000: ++ mii_speed = AR71XX_MII_CTRL_SPEED_1000; ++ break; ++ default: ++ BUG(); ++ } ++ ++ base = ioremap(AR71XX_MII_BASE, AR71XX_MII_SIZE); ++ ++ t = __raw_readl(base + reg); ++ t &= ~(AR71XX_MII_CTRL_SPEED_MASK << AR71XX_MII_CTRL_SPEED_SHIFT); ++ t |= mii_speed << AR71XX_MII_CTRL_SPEED_SHIFT; ++ __raw_writel(t, base + reg); ++ ++ iounmap(base); ++} ++ ++static unsigned long ar934x_get_mdio_ref_clock(void) ++{ ++ void __iomem *base; ++ unsigned long ret; ++ u32 t; ++ ++ base = ioremap(AR71XX_PLL_BASE, AR71XX_PLL_SIZE); ++ ++ ret = 0; ++ t = __raw_readl(base + AR934X_PLL_SWITCH_CLOCK_CONTROL_REG); ++ if (t & AR934X_PLL_SWITCH_CLOCK_CONTROL_MDIO_CLK_SEL) { ++ ret = 100 * 1000 * 1000; ++ } else { ++ struct clk *clk; ++ ++ clk = clk_get(NULL, "ref"); ++ if (!IS_ERR(clk)) ++ ret = clk_get_rate(clk); ++ } ++ ++ iounmap(base); ++ ++ return ret; ++} ++ ++void __init ath79_register_mdio(unsigned int id, u32 phy_mask) ++{ ++ struct platform_device *mdio_dev; ++ struct ag71xx_mdio_platform_data *mdio_data; ++ unsigned int max_id; ++ ++ if (ath79_soc == ATH79_SOC_AR9341 || ++ ath79_soc == ATH79_SOC_AR9342 || ++ ath79_soc == ATH79_SOC_AR9344 || ++ ath79_soc == ATH79_SOC_QCA9556 || ++ ath79_soc == ATH79_SOC_QCA9558) ++ max_id = 1; ++ else ++ max_id = 0; ++ ++ if (id > max_id) { ++ printk(KERN_ERR "ar71xx: invalid MDIO id %u\n", id); ++ return; ++ } ++ ++ switch (ath79_soc) { ++ case ATH79_SOC_AR7241: ++ case ATH79_SOC_AR9330: ++ case ATH79_SOC_AR9331: ++ case ATH79_SOC_QCA9533: ++ case ATH79_SOC_QCA9561: ++ case ATH79_SOC_TP9343: ++ mdio_dev = &ath79_mdio1_device; ++ mdio_data = &ath79_mdio1_data; ++ break; ++ ++ case ATH79_SOC_AR9341: ++ case ATH79_SOC_AR9342: ++ case ATH79_SOC_AR9344: ++ case ATH79_SOC_QCA9556: ++ case ATH79_SOC_QCA9558: ++ if (id == 0) { ++ mdio_dev = &ath79_mdio0_device; ++ mdio_data = &ath79_mdio0_data; ++ } else { ++ mdio_dev = &ath79_mdio1_device; ++ mdio_data = &ath79_mdio1_data; ++ } ++ break; ++ ++ case ATH79_SOC_AR7242: ++ ath79_set_pll(AR71XX_PLL_REG_SEC_CONFIG, ++ AR7242_PLL_REG_ETH0_INT_CLOCK, 0x62000000, ++ AR71XX_ETH0_PLL_SHIFT); ++ /* fall through */ ++ default: ++ mdio_dev = &ath79_mdio0_device; ++ mdio_data = &ath79_mdio0_data; ++ break; ++ } ++ ++ mdio_data->phy_mask = phy_mask; ++ ++ switch (ath79_soc) { ++ case ATH79_SOC_AR7240: ++ mdio_data->is_ar7240 = 1; ++ /* fall through */ ++ case ATH79_SOC_AR7241: ++ mdio_data->builtin_switch = 1; ++ break; ++ ++ case ATH79_SOC_AR9330: ++ mdio_data->is_ar9330 = 1; ++ /* fall through */ ++ case ATH79_SOC_AR9331: ++ mdio_data->builtin_switch = 1; ++ break; ++ ++ case ATH79_SOC_AR9341: ++ case ATH79_SOC_AR9342: ++ case ATH79_SOC_AR9344: ++ if (id == 1) { ++ mdio_data->builtin_switch = 1; ++ mdio_data->ref_clock = ar934x_get_mdio_ref_clock(); ++ mdio_data->mdio_clock = 6250000; ++ } ++ mdio_data->is_ar934x = 1; ++ break; ++ ++ case ATH79_SOC_QCA9533: ++ case ATH79_SOC_QCA9561: ++ case ATH79_SOC_TP9343: ++ mdio_data->builtin_switch = 1; ++ break; ++ ++ case ATH79_SOC_QCA9556: ++ case ATH79_SOC_QCA9558: ++ mdio_data->is_ar934x = 1; ++ break; ++ ++ default: ++ break; ++ } ++ ++ platform_device_register(mdio_dev); ++} ++ ++struct ath79_eth_pll_data ath79_eth0_pll_data; ++struct ath79_eth_pll_data ath79_eth1_pll_data; ++ ++static u32 ath79_get_eth_pll(unsigned int mac, int speed) ++{ ++ struct ath79_eth_pll_data *pll_data; ++ u32 pll_val; ++ ++ switch (mac) { ++ case 0: ++ pll_data = &ath79_eth0_pll_data; ++ break; ++ case 1: ++ pll_data = &ath79_eth1_pll_data; ++ break; ++ default: ++ BUG(); ++ } ++ ++ switch (speed) { ++ case SPEED_10: ++ pll_val = pll_data->pll_10; ++ break; ++ case SPEED_100: ++ pll_val = pll_data->pll_100; ++ break; ++ case SPEED_1000: ++ pll_val = pll_data->pll_1000; ++ break; ++ default: ++ BUG(); ++ } ++ ++ return pll_val; ++} ++ ++static void ath79_set_speed_ge0(int speed) ++{ ++ u32 val = ath79_get_eth_pll(0, speed); ++ ++ ath79_set_pll(AR71XX_PLL_REG_SEC_CONFIG, AR71XX_PLL_REG_ETH0_INT_CLOCK, ++ val, AR71XX_ETH0_PLL_SHIFT); ++ ath79_mii_ctrl_set_speed(AR71XX_MII_REG_MII0_CTRL, speed); ++} ++ ++static void ath79_set_speed_ge1(int speed) ++{ ++ u32 val = ath79_get_eth_pll(1, speed); ++ ++ ath79_set_pll(AR71XX_PLL_REG_SEC_CONFIG, AR71XX_PLL_REG_ETH1_INT_CLOCK, ++ val, AR71XX_ETH1_PLL_SHIFT); ++ ath79_mii_ctrl_set_speed(AR71XX_MII_REG_MII1_CTRL, speed); ++} ++ ++static void ar7242_set_speed_ge0(int speed) ++{ ++ u32 val = ath79_get_eth_pll(0, speed); ++ void __iomem *base; ++ ++ base = ioremap_nocache(AR71XX_PLL_BASE, AR71XX_PLL_SIZE); ++ __raw_writel(val, base + AR7242_PLL_REG_ETH0_INT_CLOCK); ++ iounmap(base); ++} ++ ++static void ar91xx_set_speed_ge0(int speed) ++{ ++ u32 val = ath79_get_eth_pll(0, speed); ++ ++ ath79_set_pll(AR913X_PLL_REG_ETH_CONFIG, AR913X_PLL_REG_ETH0_INT_CLOCK, ++ val, AR913X_ETH0_PLL_SHIFT); ++ ath79_mii_ctrl_set_speed(AR71XX_MII_REG_MII0_CTRL, speed); ++} ++ ++static void ar91xx_set_speed_ge1(int speed) ++{ ++ u32 val = ath79_get_eth_pll(1, speed); ++ ++ ath79_set_pll(AR913X_PLL_REG_ETH_CONFIG, AR913X_PLL_REG_ETH1_INT_CLOCK, ++ val, AR913X_ETH1_PLL_SHIFT); ++ ath79_mii_ctrl_set_speed(AR71XX_MII_REG_MII1_CTRL, speed); ++} ++ ++static void ar934x_set_speed_ge0(int speed) ++{ ++ void __iomem *base; ++ u32 val = ath79_get_eth_pll(0, speed); ++ ++ base = ioremap_nocache(AR71XX_PLL_BASE, AR71XX_PLL_SIZE); ++ __raw_writel(val, base + AR934X_PLL_ETH_XMII_CONTROL_REG); ++ iounmap(base); ++} ++ ++static void qca955x_set_speed_xmii(int speed) ++{ ++ void __iomem *base; ++ u32 val = ath79_get_eth_pll(0, speed); ++ ++ base = ioremap_nocache(AR71XX_PLL_BASE, AR71XX_PLL_SIZE); ++ __raw_writel(val, base + QCA955X_PLL_ETH_XMII_CONTROL_REG); ++ iounmap(base); ++} ++ ++static void qca955x_set_speed_sgmii(int speed) ++{ ++ void __iomem *base; ++ u32 val = ath79_get_eth_pll(1, speed); ++ ++ base = ioremap_nocache(AR71XX_PLL_BASE, AR71XX_PLL_SIZE); ++ __raw_writel(val, base + QCA955X_PLL_ETH_SGMII_CONTROL_REG); ++ iounmap(base); ++} ++ ++static void ath79_set_speed_dummy(int speed) ++{ ++} ++ ++static void ath79_ddr_no_flush(void) ++{ ++} ++ ++static void ath79_ddr_flush_ge0(void) ++{ ++ ath79_ddr_wb_flush(AR71XX_DDR_REG_FLUSH_GE0); ++} ++ ++static void ath79_ddr_flush_ge1(void) ++{ ++ ath79_ddr_wb_flush(AR71XX_DDR_REG_FLUSH_GE1); ++} ++ ++static void ar724x_ddr_flush_ge0(void) ++{ ++ ath79_ddr_wb_flush(AR724X_DDR_REG_FLUSH_GE0); ++} ++ ++static void ar724x_ddr_flush_ge1(void) ++{ ++ ath79_ddr_wb_flush(AR724X_DDR_REG_FLUSH_GE1); ++} ++ ++static void ar91xx_ddr_flush_ge0(void) ++{ ++ ath79_ddr_wb_flush(AR913X_DDR_REG_FLUSH_GE0); ++} ++ ++static void ar91xx_ddr_flush_ge1(void) ++{ ++ ath79_ddr_wb_flush(AR913X_DDR_REG_FLUSH_GE1); ++} ++ ++static void ar933x_ddr_flush_ge0(void) ++{ ++ ath79_ddr_wb_flush(AR933X_DDR_REG_FLUSH_GE0); ++} ++ ++static void ar933x_ddr_flush_ge1(void) ++{ ++ ath79_ddr_wb_flush(AR933X_DDR_REG_FLUSH_GE1); ++} ++ ++static struct resource ath79_eth0_resources[] = { ++ { ++ .name = "mac_base", ++ .flags = IORESOURCE_MEM, ++ .start = AR71XX_GE0_BASE, ++ .end = AR71XX_GE0_BASE + 0x200 - 1, ++ }, { ++ .name = "mac_irq", ++ .flags = IORESOURCE_IRQ, ++ .start = ATH79_CPU_IRQ(4), ++ .end = ATH79_CPU_IRQ(4), ++ }, ++}; ++ ++struct ag71xx_platform_data ath79_eth0_data = { ++ .reset_bit = AR71XX_RESET_GE0_MAC, ++}; ++ ++struct platform_device ath79_eth0_device = { ++ .name = "ag71xx", ++ .id = 0, ++ .resource = ath79_eth0_resources, ++ .num_resources = ARRAY_SIZE(ath79_eth0_resources), ++ .dev = { ++ .platform_data = &ath79_eth0_data, ++ }, ++}; ++ ++static struct resource ath79_eth1_resources[] = { ++ { ++ .name = "mac_base", ++ .flags = IORESOURCE_MEM, ++ .start = AR71XX_GE1_BASE, ++ .end = AR71XX_GE1_BASE + 0x200 - 1, ++ }, { ++ .name = "mac_irq", ++ .flags = IORESOURCE_IRQ, ++ .start = ATH79_CPU_IRQ(5), ++ .end = ATH79_CPU_IRQ(5), ++ }, ++}; ++ ++struct ag71xx_platform_data ath79_eth1_data = { ++ .reset_bit = AR71XX_RESET_GE1_MAC, ++}; ++ ++struct platform_device ath79_eth1_device = { ++ .name = "ag71xx", ++ .id = 1, ++ .resource = ath79_eth1_resources, ++ .num_resources = ARRAY_SIZE(ath79_eth1_resources), ++ .dev = { ++ .platform_data = &ath79_eth1_data, ++ }, ++}; ++ ++struct ag71xx_switch_platform_data ath79_switch_data; ++ ++#define AR71XX_PLL_VAL_1000 0x00110000 ++#define AR71XX_PLL_VAL_100 0x00001099 ++#define AR71XX_PLL_VAL_10 0x00991099 ++ ++#define AR724X_PLL_VAL_1000 0x00110000 ++#define AR724X_PLL_VAL_100 0x00001099 ++#define AR724X_PLL_VAL_10 0x00991099 ++ ++#define AR7242_PLL_VAL_1000 0x16000000 ++#define AR7242_PLL_VAL_100 0x00000101 ++#define AR7242_PLL_VAL_10 0x00001616 ++ ++#define AR913X_PLL_VAL_1000 0x1a000000 ++#define AR913X_PLL_VAL_100 0x13000a44 ++#define AR913X_PLL_VAL_10 0x00441099 ++ ++#define AR933X_PLL_VAL_1000 0x00110000 ++#define AR933X_PLL_VAL_100 0x00001099 ++#define AR933X_PLL_VAL_10 0x00991099 ++ ++#define AR934X_PLL_VAL_1000 0x16000000 ++#define AR934X_PLL_VAL_100 0x00000101 ++#define AR934X_PLL_VAL_10 0x00001616 ++ ++static void __init ath79_init_eth_pll_data(unsigned int id) ++{ ++ struct ath79_eth_pll_data *pll_data; ++ u32 pll_10, pll_100, pll_1000; ++ ++ switch (id) { ++ case 0: ++ pll_data = &ath79_eth0_pll_data; ++ break; ++ case 1: ++ pll_data = &ath79_eth1_pll_data; ++ break; ++ default: ++ BUG(); ++ } ++ ++ switch (ath79_soc) { ++ case ATH79_SOC_AR7130: ++ case ATH79_SOC_AR7141: ++ case ATH79_SOC_AR7161: ++ pll_10 = AR71XX_PLL_VAL_10; ++ pll_100 = AR71XX_PLL_VAL_100; ++ pll_1000 = AR71XX_PLL_VAL_1000; ++ break; ++ ++ case ATH79_SOC_AR7240: ++ case ATH79_SOC_AR7241: ++ pll_10 = AR724X_PLL_VAL_10; ++ pll_100 = AR724X_PLL_VAL_100; ++ pll_1000 = AR724X_PLL_VAL_1000; ++ break; ++ ++ case ATH79_SOC_AR7242: ++ pll_10 = AR7242_PLL_VAL_10; ++ pll_100 = AR7242_PLL_VAL_100; ++ pll_1000 = AR7242_PLL_VAL_1000; ++ break; ++ ++ case ATH79_SOC_AR9130: ++ case ATH79_SOC_AR9132: ++ pll_10 = AR913X_PLL_VAL_10; ++ pll_100 = AR913X_PLL_VAL_100; ++ pll_1000 = AR913X_PLL_VAL_1000; ++ break; ++ ++ case ATH79_SOC_AR9330: ++ case ATH79_SOC_AR9331: ++ pll_10 = AR933X_PLL_VAL_10; ++ pll_100 = AR933X_PLL_VAL_100; ++ pll_1000 = AR933X_PLL_VAL_1000; ++ break; ++ ++ case ATH79_SOC_AR9341: ++ case ATH79_SOC_AR9342: ++ case ATH79_SOC_AR9344: ++ case ATH79_SOC_QCA9533: ++ case ATH79_SOC_QCA9556: ++ case ATH79_SOC_QCA9558: ++ case ATH79_SOC_QCA9561: ++ case ATH79_SOC_TP9343: ++ pll_10 = AR934X_PLL_VAL_10; ++ pll_100 = AR934X_PLL_VAL_100; ++ pll_1000 = AR934X_PLL_VAL_1000; ++ break; ++ ++ default: ++ BUG(); ++ } ++ ++ if (!pll_data->pll_10) ++ pll_data->pll_10 = pll_10; ++ ++ if (!pll_data->pll_100) ++ pll_data->pll_100 = pll_100; ++ ++ if (!pll_data->pll_1000) ++ pll_data->pll_1000 = pll_1000; ++} ++ ++static int __init ath79_setup_phy_if_mode(unsigned int id, ++ struct ag71xx_platform_data *pdata) ++{ ++ unsigned int mii_if; ++ ++ switch (id) { ++ case 0: ++ switch (ath79_soc) { ++ case ATH79_SOC_AR7130: ++ case ATH79_SOC_AR7141: ++ case ATH79_SOC_AR7161: ++ case ATH79_SOC_AR9130: ++ case ATH79_SOC_AR9132: ++ switch (pdata->phy_if_mode) { ++ case PHY_INTERFACE_MODE_MII: ++ mii_if = AR71XX_MII0_CTRL_IF_MII; ++ break; ++ case PHY_INTERFACE_MODE_GMII: ++ mii_if = AR71XX_MII0_CTRL_IF_GMII; ++ break; ++ case PHY_INTERFACE_MODE_RGMII: ++ mii_if = AR71XX_MII0_CTRL_IF_RGMII; ++ break; ++ case PHY_INTERFACE_MODE_RMII: ++ mii_if = AR71XX_MII0_CTRL_IF_RMII; ++ break; ++ default: ++ return -EINVAL; ++ } ++ ath79_mii_ctrl_set_if(AR71XX_MII_REG_MII0_CTRL, mii_if); ++ break; ++ ++ case ATH79_SOC_AR7240: ++ case ATH79_SOC_AR7241: ++ case ATH79_SOC_AR9330: ++ case ATH79_SOC_AR9331: ++ case ATH79_SOC_QCA9533: ++ case ATH79_SOC_TP9343: ++ pdata->phy_if_mode = PHY_INTERFACE_MODE_MII; ++ break; ++ ++ case ATH79_SOC_AR7242: ++ /* FIXME */ ++ ++ case ATH79_SOC_AR9341: ++ case ATH79_SOC_AR9342: ++ case ATH79_SOC_AR9344: ++ switch (pdata->phy_if_mode) { ++ case PHY_INTERFACE_MODE_MII: ++ case PHY_INTERFACE_MODE_GMII: ++ case PHY_INTERFACE_MODE_RGMII: ++ case PHY_INTERFACE_MODE_RMII: ++ break; ++ default: ++ return -EINVAL; ++ } ++ break; ++ ++ case ATH79_SOC_QCA9556: ++ case ATH79_SOC_QCA9558: ++ switch (pdata->phy_if_mode) { ++ case PHY_INTERFACE_MODE_MII: ++ case PHY_INTERFACE_MODE_RGMII: ++ case PHY_INTERFACE_MODE_SGMII: ++ break; ++ default: ++ return -EINVAL; ++ } ++ break; ++ ++ case ATH79_SOC_QCA9561: ++ if (!pdata->phy_if_mode) ++ pdata->phy_if_mode = PHY_INTERFACE_MODE_MII; ++ break; ++ ++ default: ++ BUG(); ++ } ++ break; ++ case 1: ++ switch (ath79_soc) { ++ case ATH79_SOC_AR7130: ++ case ATH79_SOC_AR7141: ++ case ATH79_SOC_AR7161: ++ case ATH79_SOC_AR9130: ++ case ATH79_SOC_AR9132: ++ switch (pdata->phy_if_mode) { ++ case PHY_INTERFACE_MODE_RMII: ++ mii_if = AR71XX_MII1_CTRL_IF_RMII; ++ break; ++ case PHY_INTERFACE_MODE_RGMII: ++ mii_if = AR71XX_MII1_CTRL_IF_RGMII; ++ break; ++ default: ++ return -EINVAL; ++ } ++ ath79_mii_ctrl_set_if(AR71XX_MII_REG_MII1_CTRL, mii_if); ++ break; ++ ++ case ATH79_SOC_AR7240: ++ case ATH79_SOC_AR7241: ++ case ATH79_SOC_AR9330: ++ case ATH79_SOC_AR9331: ++ case ATH79_SOC_QCA9561: ++ case ATH79_SOC_TP9343: ++ pdata->phy_if_mode = PHY_INTERFACE_MODE_GMII; ++ break; ++ ++ case ATH79_SOC_AR7242: ++ /* FIXME */ ++ ++ case ATH79_SOC_AR9341: ++ case ATH79_SOC_AR9342: ++ case ATH79_SOC_AR9344: ++ case ATH79_SOC_QCA9533: ++ switch (pdata->phy_if_mode) { ++ case PHY_INTERFACE_MODE_MII: ++ case PHY_INTERFACE_MODE_GMII: ++ break; ++ default: ++ return -EINVAL; ++ } ++ break; ++ ++ case ATH79_SOC_QCA9556: ++ case ATH79_SOC_QCA9558: ++ switch (pdata->phy_if_mode) { ++ case PHY_INTERFACE_MODE_MII: ++ case PHY_INTERFACE_MODE_RGMII: ++ case PHY_INTERFACE_MODE_SGMII: ++ break; ++ default: ++ return -EINVAL; ++ } ++ break; ++ ++ default: ++ BUG(); ++ } ++ break; ++ } ++ ++ return 0; ++} ++ ++void __init ath79_setup_ar933x_phy4_switch(bool mac, bool mdio) ++{ ++ void __iomem *base; ++ u32 t; ++ ++ base = ioremap(AR933X_GMAC_BASE, AR933X_GMAC_SIZE); ++ ++ t = __raw_readl(base + AR933X_GMAC_REG_ETH_CFG); ++ t &= ~(AR933X_ETH_CFG_SW_PHY_SWAP | AR933X_ETH_CFG_SW_PHY_ADDR_SWAP); ++ if (mac) ++ t |= AR933X_ETH_CFG_SW_PHY_SWAP; ++ if (mdio) ++ t |= AR933X_ETH_CFG_SW_PHY_ADDR_SWAP; ++ __raw_writel(t, base + AR933X_GMAC_REG_ETH_CFG); ++ ++ iounmap(base); ++} ++ ++void __init ath79_setup_ar934x_eth_cfg(u32 mask) ++{ ++ void __iomem *base; ++ u32 t; ++ ++ base = ioremap(AR934X_GMAC_BASE, AR934X_GMAC_SIZE); ++ ++ t = __raw_readl(base + AR934X_GMAC_REG_ETH_CFG); ++ ++ t &= ~(AR934X_ETH_CFG_RGMII_GMAC0 | ++ AR934X_ETH_CFG_MII_GMAC0 | ++ AR934X_ETH_CFG_GMII_GMAC0 | ++ AR934X_ETH_CFG_SW_ONLY_MODE | ++ AR934X_ETH_CFG_SW_PHY_SWAP); ++ ++ t |= mask; ++ ++ __raw_writel(t, base + AR934X_GMAC_REG_ETH_CFG); ++ /* flush write */ ++ __raw_readl(base + AR934X_GMAC_REG_ETH_CFG); ++ ++ iounmap(base); ++} ++ ++void __init ath79_setup_ar934x_eth_rx_delay(unsigned int rxd, ++ unsigned int rxdv) ++{ ++ void __iomem *base; ++ u32 t; ++ ++ rxd &= AR934X_ETH_CFG_RXD_DELAY_MASK; ++ rxdv &= AR934X_ETH_CFG_RDV_DELAY_MASK; ++ ++ base = ioremap(AR934X_GMAC_BASE, AR934X_GMAC_SIZE); ++ ++ t = __raw_readl(base + AR934X_GMAC_REG_ETH_CFG); ++ ++ t &= ~(AR934X_ETH_CFG_RXD_DELAY_MASK << AR934X_ETH_CFG_RXD_DELAY_SHIFT | ++ AR934X_ETH_CFG_RDV_DELAY_MASK << AR934X_ETH_CFG_RDV_DELAY_SHIFT); ++ ++ t |= (rxd << AR934X_ETH_CFG_RXD_DELAY_SHIFT | ++ rxdv << AR934X_ETH_CFG_RDV_DELAY_SHIFT); ++ ++ __raw_writel(t, base + AR934X_GMAC_REG_ETH_CFG); ++ /* flush write */ ++ __raw_readl(base + AR934X_GMAC_REG_ETH_CFG); ++ ++ iounmap(base); ++} ++ ++void __init ath79_setup_qca955x_eth_cfg(u32 mask) ++{ ++ void __iomem *base; ++ u32 t; ++ ++ base = ioremap(QCA955X_GMAC_BASE, QCA955X_GMAC_SIZE); ++ ++ t = __raw_readl(base + QCA955X_GMAC_REG_ETH_CFG); ++ ++ t &= ~(QCA955X_ETH_CFG_RGMII_EN | QCA955X_ETH_CFG_GE0_SGMII); ++ ++ t |= mask; ++ ++ __raw_writel(t, base + QCA955X_GMAC_REG_ETH_CFG); ++ ++ iounmap(base); ++} ++ ++static int ath79_eth_instance __initdata; ++void __init ath79_register_eth(unsigned int id) ++{ ++ struct platform_device *pdev; ++ struct ag71xx_platform_data *pdata; ++ int err; ++ ++ if (id > 1) { ++ printk(KERN_ERR "ar71xx: invalid ethernet id %d\n", id); ++ return; ++ } ++ ++ ath79_init_eth_pll_data(id); ++ ++ if (id == 0) ++ pdev = &ath79_eth0_device; ++ else ++ pdev = &ath79_eth1_device; ++ ++ pdata = pdev->dev.platform_data; ++ ++ pdata->max_frame_len = 1540; ++ pdata->desc_pktlen_mask = 0xfff; ++ ++ err = ath79_setup_phy_if_mode(id, pdata); ++ if (err) { ++ printk(KERN_ERR ++ "ar71xx: invalid PHY interface mode for GE%u\n", id); ++ return; ++ } ++ ++ switch (ath79_soc) { ++ case ATH79_SOC_AR7130: ++ if (id == 0) { ++ pdata->ddr_flush = ath79_ddr_flush_ge0; ++ pdata->set_speed = ath79_set_speed_ge0; ++ } else { ++ pdata->ddr_flush = ath79_ddr_flush_ge1; ++ pdata->set_speed = ath79_set_speed_ge1; ++ } ++ break; ++ ++ case ATH79_SOC_AR7141: ++ case ATH79_SOC_AR7161: ++ if (id == 0) { ++ pdata->ddr_flush = ath79_ddr_flush_ge0; ++ pdata->set_speed = ath79_set_speed_ge0; ++ } else { ++ pdata->ddr_flush = ath79_ddr_flush_ge1; ++ pdata->set_speed = ath79_set_speed_ge1; ++ } ++ pdata->has_gbit = 1; ++ break; ++ ++ case ATH79_SOC_AR7242: ++ if (id == 0) { ++ pdata->reset_bit |= AR724X_RESET_GE0_MDIO | ++ AR71XX_RESET_GE0_PHY; ++ pdata->ddr_flush = ar724x_ddr_flush_ge0; ++ pdata->set_speed = ar7242_set_speed_ge0; ++ } else { ++ pdata->reset_bit |= AR724X_RESET_GE1_MDIO | ++ AR71XX_RESET_GE1_PHY; ++ pdata->ddr_flush = ar724x_ddr_flush_ge1; ++ pdata->set_speed = ath79_set_speed_dummy; ++ } ++ pdata->has_gbit = 1; ++ pdata->is_ar724x = 1; ++ ++ if (!pdata->fifo_cfg1) ++ pdata->fifo_cfg1 = 0x0010ffff; ++ if (!pdata->fifo_cfg2) ++ pdata->fifo_cfg2 = 0x015500aa; ++ if (!pdata->fifo_cfg3) ++ pdata->fifo_cfg3 = 0x01f00140; ++ break; ++ ++ case ATH79_SOC_AR7241: ++ if (id == 0) ++ pdata->reset_bit |= AR724X_RESET_GE0_MDIO; ++ else ++ pdata->reset_bit |= AR724X_RESET_GE1_MDIO; ++ /* fall through */ ++ case ATH79_SOC_AR7240: ++ if (id == 0) { ++ pdata->reset_bit |= AR71XX_RESET_GE0_PHY; ++ pdata->ddr_flush = ar724x_ddr_flush_ge0; ++ pdata->set_speed = ath79_set_speed_dummy; ++ ++ pdata->phy_mask = BIT(4); ++ } else { ++ pdata->reset_bit |= AR71XX_RESET_GE1_PHY; ++ pdata->ddr_flush = ar724x_ddr_flush_ge1; ++ pdata->set_speed = ath79_set_speed_dummy; ++ ++ pdata->speed = SPEED_1000; ++ pdata->duplex = DUPLEX_FULL; ++ pdata->switch_data = &ath79_switch_data; ++ ++ ath79_switch_data.phy_poll_mask |= BIT(4); ++ } ++ pdata->has_gbit = 1; ++ pdata->is_ar724x = 1; ++ if (ath79_soc == ATH79_SOC_AR7240) ++ pdata->is_ar7240 = 1; ++ ++ if (!pdata->fifo_cfg1) ++ pdata->fifo_cfg1 = 0x0010ffff; ++ if (!pdata->fifo_cfg2) ++ pdata->fifo_cfg2 = 0x015500aa; ++ if (!pdata->fifo_cfg3) ++ pdata->fifo_cfg3 = 0x01f00140; ++ break; ++ ++ case ATH79_SOC_AR9130: ++ if (id == 0) { ++ pdata->ddr_flush = ar91xx_ddr_flush_ge0; ++ pdata->set_speed = ar91xx_set_speed_ge0; ++ } else { ++ pdata->ddr_flush = ar91xx_ddr_flush_ge1; ++ pdata->set_speed = ar91xx_set_speed_ge1; ++ } ++ pdata->is_ar91xx = 1; ++ break; ++ ++ case ATH79_SOC_AR9132: ++ if (id == 0) { ++ pdata->ddr_flush = ar91xx_ddr_flush_ge0; ++ pdata->set_speed = ar91xx_set_speed_ge0; ++ } else { ++ pdata->ddr_flush = ar91xx_ddr_flush_ge1; ++ pdata->set_speed = ar91xx_set_speed_ge1; ++ } ++ pdata->is_ar91xx = 1; ++ pdata->has_gbit = 1; ++ break; ++ ++ case ATH79_SOC_AR9330: ++ case ATH79_SOC_AR9331: ++ if (id == 0) { ++ pdata->reset_bit = AR933X_RESET_GE0_MAC | ++ AR933X_RESET_GE0_MDIO; ++ pdata->ddr_flush = ar933x_ddr_flush_ge0; ++ pdata->set_speed = ath79_set_speed_dummy; ++ ++ pdata->phy_mask = BIT(4); ++ } else { ++ pdata->reset_bit = AR933X_RESET_GE1_MAC | ++ AR933X_RESET_GE1_MDIO; ++ pdata->ddr_flush = ar933x_ddr_flush_ge1; ++ pdata->set_speed = ath79_set_speed_dummy; ++ ++ pdata->speed = SPEED_1000; ++ pdata->has_gbit = 1; ++ pdata->duplex = DUPLEX_FULL; ++ pdata->switch_data = &ath79_switch_data; ++ ++ ath79_switch_data.phy_poll_mask |= BIT(4); ++ } ++ ++ pdata->is_ar724x = 1; ++ ++ if (!pdata->fifo_cfg1) ++ pdata->fifo_cfg1 = 0x0010ffff; ++ if (!pdata->fifo_cfg2) ++ pdata->fifo_cfg2 = 0x015500aa; ++ if (!pdata->fifo_cfg3) ++ pdata->fifo_cfg3 = 0x01f00140; ++ break; ++ ++ case ATH79_SOC_AR9341: ++ case ATH79_SOC_AR9342: ++ case ATH79_SOC_AR9344: ++ case ATH79_SOC_QCA9533: ++ if (id == 0) { ++ pdata->reset_bit = AR934X_RESET_GE0_MAC | ++ AR934X_RESET_GE0_MDIO; ++ pdata->set_speed = ar934x_set_speed_ge0; ++ } else { ++ pdata->reset_bit = AR934X_RESET_GE1_MAC | ++ AR934X_RESET_GE1_MDIO; ++ pdata->set_speed = ath79_set_speed_dummy; ++ ++ pdata->switch_data = &ath79_switch_data; ++ ++ /* reset the built-in switch */ ++ ath79_device_reset_set(AR934X_RESET_ETH_SWITCH); ++ ath79_device_reset_clear(AR934X_RESET_ETH_SWITCH); ++ } ++ ++ pdata->ddr_flush = ath79_ddr_no_flush; ++ pdata->has_gbit = 1; ++ pdata->is_ar724x = 1; ++ ++ pdata->max_frame_len = SZ_16K - 1; ++ pdata->desc_pktlen_mask = SZ_16K - 1; ++ ++ if (!pdata->fifo_cfg1) ++ pdata->fifo_cfg1 = 0x0010ffff; ++ if (!pdata->fifo_cfg2) ++ pdata->fifo_cfg2 = 0x015500aa; ++ if (!pdata->fifo_cfg3) ++ pdata->fifo_cfg3 = 0x01f00140; ++ break; ++ ++ case ATH79_SOC_QCA9561: ++ case ATH79_SOC_TP9343: ++ if (id == 0) { ++ pdata->reset_bit = AR933X_RESET_GE0_MAC | ++ AR933X_RESET_GE0_MDIO; ++ pdata->set_speed = ath79_set_speed_dummy; ++ ++ if (!pdata->phy_mask) ++ pdata->phy_mask = BIT(4); ++ } else { ++ pdata->reset_bit = AR933X_RESET_GE1_MAC | ++ AR933X_RESET_GE1_MDIO; ++ pdata->set_speed = ath79_set_speed_dummy; ++ ++ pdata->speed = SPEED_1000; ++ pdata->duplex = DUPLEX_FULL; ++ pdata->switch_data = &ath79_switch_data; ++ ++ ath79_switch_data.phy_poll_mask |= BIT(4); ++ } ++ ++ pdata->ddr_flush = ath79_ddr_no_flush; ++ pdata->has_gbit = 1; ++ pdata->is_ar724x = 1; ++ ++ if (!pdata->fifo_cfg1) ++ pdata->fifo_cfg1 = 0x0010ffff; ++ if (!pdata->fifo_cfg2) ++ pdata->fifo_cfg2 = 0x015500aa; ++ if (!pdata->fifo_cfg3) ++ pdata->fifo_cfg3 = 0x01f00140; ++ break; ++ ++ case ATH79_SOC_QCA9556: ++ case ATH79_SOC_QCA9558: ++ if (id == 0) { ++ pdata->reset_bit = QCA955X_RESET_GE0_MAC | ++ QCA955X_RESET_GE0_MDIO; ++ pdata->set_speed = qca955x_set_speed_xmii; ++ } else { ++ pdata->reset_bit = QCA955X_RESET_GE1_MAC | ++ QCA955X_RESET_GE1_MDIO; ++ pdata->set_speed = qca955x_set_speed_sgmii; ++ } ++ ++ pdata->ddr_flush = ath79_ddr_no_flush; ++ pdata->has_gbit = 1; ++ pdata->is_ar724x = 1; ++ ++ /* ++ * Limit the maximum frame length to 4095 bytes. ++ * Although the documentation says that the hardware ++ * limit is 16383 bytes but that does not work in ++ * practice. It seems that the hardware only updates ++ * the lowest 12 bits of the packet length field ++ * in the RX descriptor. ++ */ ++ pdata->max_frame_len = SZ_4K - 1; ++ pdata->desc_pktlen_mask = SZ_16K - 1; ++ ++ if (!pdata->fifo_cfg1) ++ pdata->fifo_cfg1 = 0x0010ffff; ++ if (!pdata->fifo_cfg2) ++ pdata->fifo_cfg2 = 0x015500aa; ++ if (!pdata->fifo_cfg3) ++ pdata->fifo_cfg3 = 0x01f00140; ++ break; ++ ++ default: ++ BUG(); ++ } ++ ++ switch (pdata->phy_if_mode) { ++ case PHY_INTERFACE_MODE_GMII: ++ case PHY_INTERFACE_MODE_RGMII: ++ case PHY_INTERFACE_MODE_SGMII: ++ if (!pdata->has_gbit) { ++ printk(KERN_ERR "ar71xx: no gbit available on eth%d\n", ++ id); ++ return; ++ } ++ /* fallthrough */ ++ default: ++ break; ++ } ++ ++ if (!is_valid_ether_addr(pdata->mac_addr)) { ++ random_ether_addr(pdata->mac_addr); ++ printk(KERN_DEBUG ++ "ar71xx: using random MAC address for eth%d\n", ++ ath79_eth_instance); ++ } ++ ++ if (pdata->mii_bus_dev == NULL) { ++ switch (ath79_soc) { ++ case ATH79_SOC_AR9341: ++ case ATH79_SOC_AR9342: ++ case ATH79_SOC_AR9344: ++ if (id == 0) ++ pdata->mii_bus_dev = &ath79_mdio0_device.dev; ++ else ++ pdata->mii_bus_dev = &ath79_mdio1_device.dev; ++ break; ++ ++ case ATH79_SOC_AR7241: ++ case ATH79_SOC_AR9330: ++ case ATH79_SOC_AR9331: ++ case ATH79_SOC_QCA9533: ++ case ATH79_SOC_QCA9561: ++ case ATH79_SOC_TP9343: ++ pdata->mii_bus_dev = &ath79_mdio1_device.dev; ++ break; ++ ++ case ATH79_SOC_QCA9556: ++ case ATH79_SOC_QCA9558: ++ /* don't assign any MDIO device by default */ ++ break; ++ ++ default: ++ pdata->mii_bus_dev = &ath79_mdio0_device.dev; ++ break; ++ } ++ } ++ ++ /* Reset the device */ ++ ath79_device_reset_set(pdata->reset_bit); ++ msleep(100); ++ ++ ath79_device_reset_clear(pdata->reset_bit); ++ msleep(100); ++ ++ platform_device_register(pdev); ++ ath79_eth_instance++; ++} ++ ++void __init ath79_set_mac_base(unsigned char *mac) ++{ ++ memcpy(ath79_mac_base, mac, ETH_ALEN); ++} ++ ++void __init ath79_parse_ascii_mac(char *mac_str, u8 *mac) ++{ ++ int t; ++ ++ t = sscanf(mac_str, "%02hhx:%02hhx:%02hhx:%02hhx:%02hhx:%02hhx", ++ &mac[0], &mac[1], &mac[2], &mac[3], &mac[4], &mac[5]); ++ ++ if (t != ETH_ALEN) ++ t = sscanf(mac_str, "%02hhx.%02hhx.%02hhx.%02hhx.%02hhx.%02hhx", ++ &mac[0], &mac[1], &mac[2], &mac[3], &mac[4], &mac[5]); ++ ++ if (t != ETH_ALEN || !is_valid_ether_addr(mac)) { ++ memset(mac, 0, ETH_ALEN); ++ printk(KERN_DEBUG "ar71xx: invalid mac address \"%s\"\n", ++ mac_str); ++ } ++} ++ ++static void __init ath79_set_mac_base_ascii(char *str) ++{ ++ u8 mac[ETH_ALEN]; ++ ++ ath79_parse_ascii_mac(str, mac); ++ ath79_set_mac_base(mac); ++} ++ ++static int __init ath79_ethaddr_setup(char *str) ++{ ++ ath79_set_mac_base_ascii(str); ++ return 1; ++} ++__setup("ethaddr=", ath79_ethaddr_setup); ++ ++static int __init ath79_kmac_setup(char *str) ++{ ++ ath79_set_mac_base_ascii(str); ++ return 1; ++} ++__setup("kmac=", ath79_kmac_setup); ++ ++void __init ath79_init_mac(unsigned char *dst, const unsigned char *src, ++ int offset) ++{ ++ int t; ++ ++ if (!dst) ++ return; ++ ++ if (!src || !is_valid_ether_addr(src)) { ++ memset(dst, '\0', ETH_