summaryrefslogtreecommitdiff
path: root/target/linux/mediatek/patches-4.4
diff options
context:
space:
mode:
Diffstat (limited to 'target/linux/mediatek/patches-4.4')
-rw-r--r--target/linux/mediatek/patches-4.4/0001-NET-multi-phy-support.patch2
-rw-r--r--target/linux/mediatek/patches-4.4/0002-soc-mediatek-Separate-scpsys-driver-common-code.patch2
-rw-r--r--target/linux/mediatek/patches-4.4/0003-soc-mediatek-Init-MT8173-scpsys-driver-earlier.patch2
-rw-r--r--target/linux/mediatek/patches-4.4/0004-soc-mediatek-Add-MT2701-power-dt-bindings.patch2
-rw-r--r--target/linux/mediatek/patches-4.4/0005-soc-mediatek-Add-MT2701-MT7623-scpsys-driver.patch2
-rw-r--r--target/linux/mediatek/patches-4.4/0006-clk-mediatek-Refine-the-makefile-to-support-multiple.patch2
-rw-r--r--target/linux/mediatek/patches-4.4/0007-dt-bindings-ARM-Mediatek-Document-bindings-for-MT270.patch2
-rw-r--r--target/linux/mediatek/patches-4.4/0008-clk-mediatek-Add-dt-bindings-for-MT2701-clocks.patch2
-rw-r--r--target/linux/mediatek/patches-4.4/0009-clk-mediatek-Add-MT2701-clock-support.patch2
-rw-r--r--target/linux/mediatek/patches-4.4/0010-reset-mediatek-mt2701-reset-controller-dt-binding-fi.patch2
-rw-r--r--target/linux/mediatek/patches-4.4/0011-reset-mediatek-mt2701-reset-driver.patch2
-rw-r--r--target/linux/mediatek/patches-4.4/0012-ARM-mediatek-Add-MT2701-config-options-for-mediatek-.patch2
-rw-r--r--target/linux/mediatek/patches-4.4/0013-dt-bindings-mediatek-Modify-pinctrl-bindings-for-mt2.patch2
-rw-r--r--target/linux/mediatek/patches-4.4/0014-pinctrl-dt-bindings-Add-pinfunc-header-file-for-mt27.patch2
-rw-r--r--target/linux/mediatek/patches-4.4/0015-dt-bindings-mediatek-Modify-pinctrl-bindings-for-mt7.patch2
-rw-r--r--target/linux/mediatek/patches-4.4/0016-pinctrl-dt-bindings-Add-pinctrl-file-for-mt7623.patch2
-rw-r--r--target/linux/mediatek/patches-4.4/0017-clk-add-hifsys-reset.patch2
-rw-r--r--target/linux/mediatek/patches-4.4/0018-dt-bindings-Add-a-binding-for-Mediatek-xHCI-host-con.patch2
-rw-r--r--target/linux/mediatek/patches-4.4/0019-xhci-mediatek-support-MTK-xHCI-host-controller.patch2
-rw-r--r--target/linux/mediatek/patches-4.4/0020-arm64-dts-mediatek-add-xHCI-usb-phy-for-mt8173.patch2
-rw-r--r--target/linux/mediatek/patches-4.4/0021-Document-DT-Add-bindings-for-mediatek-MT7623-SoC-Pla.patch2
-rw-r--r--target/linux/mediatek/patches-4.4/0022-soc-mediatek-add-compat-string-for-mt7623-to-scpsys.patch2
-rw-r--r--target/linux/mediatek/patches-4.4/0023-ARM-dts-mediatek-add-MT7623-basic-support.patch26
-rw-r--r--target/linux/mediatek/patches-4.4/0024-dt-bindings-add-MediaTek-PCIe-binding-documentation.patch30
-rw-r--r--target/linux/mediatek/patches-4.4/0025-PCI-mediatek-add-support-for-PCIe-found-on-MT7623-MT.patch4
-rw-r--r--target/linux/mediatek/patches-4.4/0026-scpsys-various-fixes.patch4
-rw-r--r--target/linux/mediatek/patches-4.4/0027-soc-mediatek-PMIC-wrap-Clear-the-vldclr-if-state-mac.patch4
-rw-r--r--target/linux/mediatek/patches-4.4/0028-ARM-mediatek-add-MT7623-smp-bringup-code.patch4
-rw-r--r--target/linux/mediatek/patches-4.4/0029-soc-mediatek-PMIC-wrap-clear-the-STAUPD_TRIG-bit-of-.patch4
-rw-r--r--target/linux/mediatek/patches-4.4/0030-ARM-mediatek-add-mt2701-smp-bringup-code.patch4
-rw-r--r--target/linux/mediatek/patches-4.4/0031-dt-bindings-ARM-Mediatek-add-MT2701-7623-string-to-t.patch4
-rw-r--r--target/linux/mediatek/patches-4.4/0032-soc-mediatek-PMIC-wrap-don-t-duplicate-the-wrapper-d.patch4
-rw-r--r--target/linux/mediatek/patches-4.4/0033-soc-mediatek-PMIC-wrap-add-wrapper-callbacks-for-ini.patch4
-rw-r--r--target/linux/mediatek/patches-4.4/0034-soc-mediatek-PMIC-wrap-split-SoC-specific-init-into-.patch4
-rw-r--r--target/linux/mediatek/patches-4.4/0035-soc-mediatek-PMIC-wrap-WRAP_INT_EN-needs-a-different.patch4
-rw-r--r--target/linux/mediatek/patches-4.4/0036-soc-mediatek-PMIC-wrap-SPI_WRITE-needs-a-different-b.patch4
-rw-r--r--target/linux/mediatek/patches-4.4/0037-soc-mediatek-PMIC-wrap-move-wdt_src-into-the-pmic_wr.patch4
-rw-r--r--target/linux/mediatek/patches-4.4/0038-soc-mediatek-PMIC-wrap-remove-pwrap_is_mt8135-and-pw.patch4
-rw-r--r--target/linux/mediatek/patches-4.4/0039-soc-mediatek-PMIC-wrap-add-a-slave-specific-struct.patch4
-rw-r--r--target/linux/mediatek/patches-4.4/0040-soc-mediatek-PMIC-wrap-add-mt6323-slave-support.patch4
-rw-r--r--target/linux/mediatek/patches-4.4/0041-soc-mediatek-PMIC-wrap-add-MT2701-7623-support.patch4
-rw-r--r--target/linux/mediatek/patches-4.4/0042-dt-bindings-mfd-Add-bindings-for-the-MediaTek-MT6323.patch4
-rw-r--r--target/linux/mediatek/patches-4.4/0043-mfd-mt6397-int_con-and-int_status-may-vary-in-locati.patch4
-rw-r--r--target/linux/mediatek/patches-4.4/0044-mfd-mt6397-add-support-for-different-Slave-types.patch4
-rw-r--r--target/linux/mediatek/patches-4.4/0045-mfd-mt6397-add-MT6323-support-to-MT6397-driver.patch4
-rw-r--r--target/linux/mediatek/patches-4.4/0046-regulator-Add-document-for-MT6323-regulator.patch4
-rw-r--r--target/linux/mediatek/patches-4.4/0047-regulator-mt6323-Add-support-for-MT6323-regulator.patch4
-rw-r--r--target/linux/mediatek/patches-4.4/0048-net-next-mediatek-document-MediaTek-SoC-ethernet-bin.patch4
-rw-r--r--target/linux/mediatek/patches-4.4/0049-net-next-mediatek-add-support-for-MT7623-ethernet.patch4
-rw-r--r--target/linux/mediatek/patches-4.4/0050-net-next-mediatek-add-Kconfig-and-Makefile.patch4
-rw-r--r--target/linux/mediatek/patches-4.4/0051-net-next-mediatek-add-an-entry-to-MAINTAINERS.patch4
-rw-r--r--target/linux/mediatek/patches-4.4/0052-net-mediatek-checking-for-IS_ERR-instead-of-NULL.patch32
-rw-r--r--target/linux/mediatek/patches-4.4/0053-net-mediatek-unlock-on-error-in-mtk_tx_map.patch29
-rw-r--r--target/linux/mediatek/patches-4.4/0054-net-mediatek-use-dma_addr_t-correctly.patch35
-rw-r--r--target/linux/mediatek/patches-4.4/0055-net-mediatek-remove-incorrect-dma_mask-assignment.patch36
-rw-r--r--target/linux/mediatek/patches-4.4/0056-net-mediatek-check-device_reset-return-code.patch38
-rw-r--r--target/linux/mediatek/patches-4.4/0057-net-mediatek-out-of-tree-fixes.patch (renamed from target/linux/mediatek/patches-4.4/0052-net-out-of-tree-fixes.patch)458
-rw-r--r--target/linux/mediatek/patches-4.4/0058-dont-disable-clocks.patch (renamed from target/linux/mediatek/patches-4.4/0053-dont-disable-clocks.patch)4
-rw-r--r--target/linux/mediatek/patches-4.4/0059-mtd-nand-add-an-mtd_to_nand-helper.patch35
-rw-r--r--target/linux/mediatek/patches-4.4/0060-mtd-nand-add-nand_to_mtd-helper.patch32
-rw-r--r--target/linux/mediatek/patches-4.4/0061-mtd-nand-add-helpers-to-access-priv.patch39
-rw-r--r--target/linux/mediatek/patches-4.4/0062-mtd-nand-embed-an-mtd_info-structure-into-nand_chip.patch42
-rw-r--r--target/linux/mediatek/patches-4.4/0063-mtd-add-get-set-of_node-flash_node-helpers.patch87
-rw-r--r--target/linux/mediatek/patches-4.4/0064-mtd-mediatek-device-tree-docs-for-MTK-Smart-Device-G.patch64
-rw-r--r--target/linux/mediatek/patches-4.4/0065-mtd-mediatek-driver-for-MTK-Smart-Device-Gen1-NAND.patch1798
-rw-r--r--target/linux/mediatek/patches-4.4/0066-net-next-mediatek-mtk_cal_txd_req-returns-bad-value.patch31
66 files changed, 2668 insertions, 300 deletions
diff --git a/target/linux/mediatek/patches-4.4/0001-NET-multi-phy-support.patch b/target/linux/mediatek/patches-4.4/0001-NET-multi-phy-support.patch
index 8917ac3..239e434 100644
--- a/target/linux/mediatek/patches-4.4/0001-NET-multi-phy-support.patch
+++ b/target/linux/mediatek/patches-4.4/0001-NET-multi-phy-support.patch
@@ -1,7 +1,7 @@
From c30a296646a42302065ba452abe95b0b4b550883 Mon Sep 17 00:00:00 2001
From: John Crispin <blogic@openwrt.org>
Date: Sun, 27 Jul 2014 09:38:50 +0100
-Subject: [PATCH 01/53] NET: multi phy support
+Subject: [PATCH 01/66] NET: multi phy support
Signed-off-by: John Crispin <blogic@openwrt.org>
---
diff --git a/target/linux/mediatek/patches-4.4/0002-soc-mediatek-Separate-scpsys-driver-common-code.patch b/target/linux/mediatek/patches-4.4/0002-soc-mediatek-Separate-scpsys-driver-common-code.patch
index 53781dc..f99496a 100644
--- a/target/linux/mediatek/patches-4.4/0002-soc-mediatek-Separate-scpsys-driver-common-code.patch
+++ b/target/linux/mediatek/patches-4.4/0002-soc-mediatek-Separate-scpsys-driver-common-code.patch
@@ -1,7 +1,7 @@
From 2c93328ed05061a50e3bd4111379dbcf6946d3ac Mon Sep 17 00:00:00 2001
From: James Liao <jamesjj.liao@mediatek.com>
Date: Wed, 30 Dec 2015 14:41:43 +0800
-Subject: [PATCH 02/53] soc: mediatek: Separate scpsys driver common code
+Subject: [PATCH 02/66] soc: mediatek: Separate scpsys driver common code
Separate scpsys driver common code to mtk-scpsys.c, and move MT8173
platform code to mtk-scpsys-mt8173.c.
diff --git a/target/linux/mediatek/patches-4.4/0003-soc-mediatek-Init-MT8173-scpsys-driver-earlier.patch b/target/linux/mediatek/patches-4.4/0003-soc-mediatek-Init-MT8173-scpsys-driver-earlier.patch
index 43ed31c..0fc766c 100644
--- a/target/linux/mediatek/patches-4.4/0003-soc-mediatek-Init-MT8173-scpsys-driver-earlier.patch
+++ b/target/linux/mediatek/patches-4.4/0003-soc-mediatek-Init-MT8173-scpsys-driver-earlier.patch
@@ -1,7 +1,7 @@
From c359272f86805259c5801385d60fdeea9d629cf9 Mon Sep 17 00:00:00 2001
From: James Liao <jamesjj.liao@mediatek.com>
Date: Wed, 30 Dec 2015 14:41:44 +0800
-Subject: [PATCH 03/53] soc: mediatek: Init MT8173 scpsys driver earlier
+Subject: [PATCH 03/66] soc: mediatek: Init MT8173 scpsys driver earlier
Some power domain comsumers may init before module_init.
So the power domain provider (scpsys) need to be initialized
diff --git a/target/linux/mediatek/patches-4.4/0004-soc-mediatek-Add-MT2701-power-dt-bindings.patch b/target/linux/mediatek/patches-4.4/0004-soc-mediatek-Add-MT2701-power-dt-bindings.patch
index 79f849f..1b45c44 100644
--- a/target/linux/mediatek/patches-4.4/0004-soc-mediatek-Add-MT2701-power-dt-bindings.patch
+++ b/target/linux/mediatek/patches-4.4/0004-soc-mediatek-Add-MT2701-power-dt-bindings.patch
@@ -1,7 +1,7 @@
From f371844374fff273f817d6c43f679606417af59e Mon Sep 17 00:00:00 2001
From: Shunli Wang <shunli.wang@mediatek.com>
Date: Wed, 30 Dec 2015 14:41:45 +0800
-Subject: [PATCH 04/53] soc: mediatek: Add MT2701 power dt-bindings
+Subject: [PATCH 04/66] soc: mediatek: Add MT2701 power dt-bindings
Add power dt-bindings for MT2701.
diff --git a/target/linux/mediatek/patches-4.4/0005-soc-mediatek-Add-MT2701-MT7623-scpsys-driver.patch b/target/linux/mediatek/patches-4.4/0005-soc-mediatek-Add-MT2701-MT7623-scpsys-driver.patch
index 6bbeecb..505292e 100644
--- a/target/linux/mediatek/patches-4.4/0005-soc-mediatek-Add-MT2701-MT7623-scpsys-driver.patch
+++ b/target/linux/mediatek/patches-4.4/0005-soc-mediatek-Add-MT2701-MT7623-scpsys-driver.patch
@@ -1,7 +1,7 @@
From c6711565985f359d7d3c05f01f081e4c216902de Mon Sep 17 00:00:00 2001
From: Shunli Wang <shunli.wang@mediatek.com>
Date: Wed, 30 Dec 2015 14:41:46 +0800
-Subject: [PATCH 05/53] soc: mediatek: Add MT2701/MT7623 scpsys driver
+Subject: [PATCH 05/66] soc: mediatek: Add MT2701/MT7623 scpsys driver
Add scpsys driver for MT2701 and MT7623.
diff --git a/target/linux/mediatek/patches-4.4/0006-clk-mediatek-Refine-the-makefile-to-support-multiple.patch b/target/linux/mediatek/patches-4.4/0006-clk-mediatek-Refine-the-makefile-to-support-multiple.patch
index 6b00dc2..e02b7a5 100644
--- a/target/linux/mediatek/patches-4.4/0006-clk-mediatek-Refine-the-makefile-to-support-multiple.patch
+++ b/target/linux/mediatek/patches-4.4/0006-clk-mediatek-Refine-the-makefile-to-support-multiple.patch
@@ -1,7 +1,7 @@
From 0c39bcd17fa6ce723f56ad3756b4bb36c4690342 Mon Sep 17 00:00:00 2001
From: James Liao <jamesjj.liao@mediatek.com>
Date: Tue, 5 Jan 2016 14:30:17 +0800
-Subject: [PATCH 06/53] clk: mediatek: Refine the makefile to support multiple
+Subject: [PATCH 06/66] clk: mediatek: Refine the makefile to support multiple
clock drivers
Add a Kconfig to define clock configuration for each SoC, and
diff --git a/target/linux/mediatek/patches-4.4/0007-dt-bindings-ARM-Mediatek-Document-bindings-for-MT270.patch b/target/linux/mediatek/patches-4.4/0007-dt-bindings-ARM-Mediatek-Document-bindings-for-MT270.patch
index 3d6bc70..c562647 100644
--- a/target/linux/mediatek/patches-4.4/0007-dt-bindings-ARM-Mediatek-Document-bindings-for-MT270.patch
+++ b/target/linux/mediatek/patches-4.4/0007-dt-bindings-ARM-Mediatek-Document-bindings-for-MT270.patch
@@ -1,7 +1,7 @@
From d7e96f87f66c571e9f4171ecd89c656fbd2de89b Mon Sep 17 00:00:00 2001
From: James Liao <jamesjj.liao@mediatek.com>
Date: Tue, 5 Jan 2016 14:30:18 +0800
-Subject: [PATCH 07/53] dt-bindings: ARM: Mediatek: Document bindings for
+Subject: [PATCH 07/66] dt-bindings: ARM: Mediatek: Document bindings for
MT2701
This patch adds the binding documentation for apmixedsys, bdpsys,
diff --git a/target/linux/mediatek/patches-4.4/0008-clk-mediatek-Add-dt-bindings-for-MT2701-clocks.patch b/target/linux/mediatek/patches-4.4/0008-clk-mediatek-Add-dt-bindings-for-MT2701-clocks.patch
index 0cbe27d..6e80e1a 100644
--- a/target/linux/mediatek/patches-4.4/0008-clk-mediatek-Add-dt-bindings-for-MT2701-clocks.patch
+++ b/target/linux/mediatek/patches-4.4/0008-clk-mediatek-Add-dt-bindings-for-MT2701-clocks.patch
@@ -1,7 +1,7 @@
From 2fcbc15da2f13164e0851b9c7fae290249f0b44d Mon Sep 17 00:00:00 2001
From: Shunli Wang <shunli.wang@mediatek.com>
Date: Tue, 5 Jan 2016 14:30:19 +0800
-Subject: [PATCH 08/53] clk: mediatek: Add dt-bindings for MT2701 clocks
+Subject: [PATCH 08/66] clk: mediatek: Add dt-bindings for MT2701 clocks
Add MT2701 clock dt-bindings, include topckgen, apmixedsys,
infracfg, pericfg and subsystem clocks.
diff --git a/target/linux/mediatek/patches-4.4/0009-clk-mediatek-Add-MT2701-clock-support.patch b/target/linux/mediatek/patches-4.4/0009-clk-mediatek-Add-MT2701-clock-support.patch
index f9670e4..e2bb10d 100644
--- a/target/linux/mediatek/patches-4.4/0009-clk-mediatek-Add-MT2701-clock-support.patch
+++ b/target/linux/mediatek/patches-4.4/0009-clk-mediatek-Add-MT2701-clock-support.patch
@@ -1,7 +1,7 @@
From f2c07eaa2df52f9acac9ffc3457d3d81079dd723 Mon Sep 17 00:00:00 2001
From: Shunli Wang <shunli.wang@mediatek.com>
Date: Tue, 5 Jan 2016 14:30:20 +0800
-Subject: [PATCH 09/53] clk: mediatek: Add MT2701 clock support
+Subject: [PATCH 09/66] clk: mediatek: Add MT2701 clock support
Add MT2701 clock support, include topckgen, apmixedsys,
infracfg, pericfg and subsystem clocks.
diff --git a/target/linux/mediatek/patches-4.4/0010-reset-mediatek-mt2701-reset-controller-dt-binding-fi.patch b/target/linux/mediatek/patches-4.4/0010-reset-mediatek-mt2701-reset-controller-dt-binding-fi.patch
index c78d7f8..bb4eb5b 100644
--- a/target/linux/mediatek/patches-4.4/0010-reset-mediatek-mt2701-reset-controller-dt-binding-fi.patch
+++ b/target/linux/mediatek/patches-4.4/0010-reset-mediatek-mt2701-reset-controller-dt-binding-fi.patch
@@ -1,7 +1,7 @@
From 8d134cbe750b59d15c591622d81e2e9daa09f0c4 Mon Sep 17 00:00:00 2001
From: Shunli Wang <shunli.wang@mediatek.com>
Date: Tue, 5 Jan 2016 14:30:21 +0800
-Subject: [PATCH 10/53] reset: mediatek: mt2701 reset controller dt-binding
+Subject: [PATCH 10/66] reset: mediatek: mt2701 reset controller dt-binding
file
Dt-binding file about reset controller is used to provide
diff --git a/target/linux/mediatek/patches-4.4/0011-reset-mediatek-mt2701-reset-driver.patch b/target/linux/mediatek/patches-4.4/0011-reset-mediatek-mt2701-reset-driver.patch
index 64d3133..fc1a35a 100644
--- a/target/linux/mediatek/patches-4.4/0011-reset-mediatek-mt2701-reset-driver.patch
+++ b/target/linux/mediatek/patches-4.4/0011-reset-mediatek-mt2701-reset-driver.patch
@@ -1,7 +1,7 @@
From b86d3303db25a8296e4c3de46ee1470f60f71b0c Mon Sep 17 00:00:00 2001
From: Shunli Wang <shunli.wang@mediatek.com>
Date: Tue, 5 Jan 2016 14:30:22 +0800
-Subject: [PATCH 11/53] reset: mediatek: mt2701 reset driver
+Subject: [PATCH 11/66] reset: mediatek: mt2701 reset driver
In infrasys and perifsys, there are many reset
control bits for kinds of modules. These bits are
diff --git a/target/linux/mediatek/patches-4.4/0012-ARM-mediatek-Add-MT2701-config-options-for-mediatek-.patch b/target/linux/mediatek/patches-4.4/0012-ARM-mediatek-Add-MT2701-config-options-for-mediatek-.patch
index 81e67ca..6c7632e 100644
--- a/target/linux/mediatek/patches-4.4/0012-ARM-mediatek-Add-MT2701-config-options-for-mediatek-.patch
+++ b/target/linux/mediatek/patches-4.4/0012-ARM-mediatek-Add-MT2701-config-options-for-mediatek-.patch
@@ -1,7 +1,7 @@
From 3b5df542d52b13a1b20d25311fa4c4029a3b83af Mon Sep 17 00:00:00 2001
From: Erin Lo <erin.lo@mediatek.com>
Date: Mon, 28 Dec 2015 15:09:02 +0800
-Subject: [PATCH 12/53] ARM: mediatek: Add MT2701 config options for mediatek
+Subject: [PATCH 12/66] ARM: mediatek: Add MT2701 config options for mediatek
SoCs.
The upcoming MTK pinctrl driver have a big pin table for each SoC
diff --git a/target/linux/mediatek/patches-4.4/0013-dt-bindings-mediatek-Modify-pinctrl-bindings-for-mt2.patch b/target/linux/mediatek/patches-4.4/0013-dt-bindings-mediatek-Modify-pinctrl-bindings-for-mt2.patch
index 35b6137..11f2cf9 100644
--- a/target/linux/mediatek/patches-4.4/0013-dt-bindings-mediatek-Modify-pinctrl-bindings-for-mt2.patch
+++ b/target/linux/mediatek/patches-4.4/0013-dt-bindings-mediatek-Modify-pinctrl-bindings-for-mt2.patch
@@ -1,7 +1,7 @@
From 1a254735cad9db5c8605c972b0f16b3929dc0d6e Mon Sep 17 00:00:00 2001
From: Biao Huang <biao.huang@mediatek.com>
Date: Mon, 28 Dec 2015 15:09:03 +0800
-Subject: [PATCH 13/53] dt-bindings: mediatek: Modify pinctrl bindings for
+Subject: [PATCH 13/66] dt-bindings: mediatek: Modify pinctrl bindings for
mt2701
Signed-off-by: Biao Huang <biao.huang@mediatek.com>
diff --git a/target/linux/mediatek/patches-4.4/0014-pinctrl-dt-bindings-Add-pinfunc-header-file-for-mt27.patch b/target/linux/mediatek/patches-4.4/0014-pinctrl-dt-bindings-Add-pinfunc-header-file-for-mt27.patch
index 77696b3..58de1fe 100644
--- a/target/linux/mediatek/patches-4.4/0014-pinctrl-dt-bindings-Add-pinfunc-header-file-for-mt27.patch
+++ b/target/linux/mediatek/patches-4.4/0014-pinctrl-dt-bindings-Add-pinfunc-header-file-for-mt27.patch
@@ -1,7 +1,7 @@
From 416720ba33d4fd7d3166c17be7c13651cc08d408 Mon Sep 17 00:00:00 2001
From: Biao Huang <biao.huang@mediatek.com>
Date: Mon, 28 Dec 2015 15:09:04 +0800
-Subject: [PATCH 14/53] pinctrl: dt bindings: Add pinfunc header file for
+Subject: [PATCH 14/66] pinctrl: dt bindings: Add pinfunc header file for
mt2701
Add pinfunc header file, mt2701 related dts will include it
diff --git a/target/linux/mediatek/patches-4.4/0015-dt-bindings-mediatek-Modify-pinctrl-bindings-for-mt7.patch b/target/linux/mediatek/patches-4.4/0015-dt-bindings-mediatek-Modify-pinctrl-bindings-for-mt7.patch
index 3f91087..974f39e 100644
--- a/target/linux/mediatek/patches-4.4/0015-dt-bindings-mediatek-Modify-pinctrl-bindings-for-mt7.patch
+++ b/target/linux/mediatek/patches-4.4/0015-dt-bindings-mediatek-Modify-pinctrl-bindings-for-mt7.patch
@@ -1,7 +1,7 @@
From ddc72b659b3642d0496dee4e1ee39416ca008053 Mon Sep 17 00:00:00 2001
From: John Crispin <blogic@openwrt.org>
Date: Thu, 7 Jan 2016 23:42:06 +0100
-Subject: [PATCH 15/53] dt-bindings: mediatek: Modify pinctrl bindings for
+Subject: [PATCH 15/66] dt-bindings: mediatek: Modify pinctrl bindings for
mt7623
Signed-off-by: John Crispin <blogic@openwrt.org>
diff --git a/target/linux/mediatek/patches-4.4/0016-pinctrl-dt-bindings-Add-pinctrl-file-for-mt7623.patch b/target/linux/mediatek/patches-4.4/0016-pinctrl-dt-bindings-Add-pinctrl-file-for-mt7623.patch
index 0ed28c3..fca1fab 100644
--- a/target/linux/mediatek/patches-4.4/0016-pinctrl-dt-bindings-Add-pinctrl-file-for-mt7623.patch
+++ b/target/linux/mediatek/patches-4.4/0016-pinctrl-dt-bindings-Add-pinctrl-file-for-mt7623.patch
@@ -1,7 +1,7 @@
From 1255eaacd6cc9d1fa6bb33185380efed22008baf Mon Sep 17 00:00:00 2001
From: John Crispin <blogic@openwrt.org>
Date: Sat, 27 Jun 2015 13:13:05 +0200
-Subject: [PATCH 16/53] pinctrl: dt bindings: Add pinctrl file for mt7623
+Subject: [PATCH 16/66] pinctrl: dt bindings: Add pinctrl file for mt7623
Add the driver and header files required to make pinctrl work on MediaTek
MT7623.
diff --git a/target/linux/mediatek/patches-4.4/0017-clk-add-hifsys-reset.patch b/target/linux/mediatek/patches-4.4/0017-clk-add-hifsys-reset.patch
index fb6e417..685a496 100644
--- a/target/linux/mediatek/patches-4.4/0017-clk-add-hifsys-reset.patch
+++ b/target/linux/mediatek/patches-4.4/0017-clk-add-hifsys-reset.patch
@@ -1,7 +1,7 @@
From 294cf90337d70ad74edf147180bbeef837298bd0 Mon Sep 17 00:00:00 2001
From: John Crispin <blogic@openwrt.org>
Date: Wed, 6 Jan 2016 20:06:49 +0100
-Subject: [PATCH 17/53] clk: add hifsys reset
+Subject: [PATCH 17/66] clk: add hifsys reset
Hi,
diff --git a/target/linux/mediatek/patches-4.4/0018-dt-bindings-Add-a-binding-for-Mediatek-xHCI-host-con.patch b/target/linux/mediatek/patches-4.4/0018-dt-bindings-Add-a-binding-for-Mediatek-xHCI-host-con.patch
index 981d71f..216d388 100644
--- a/target/linux/mediatek/patches-4.4/0018-dt-bindings-Add-a-binding-for-Mediatek-xHCI-host-con.patch
+++ b/target/linux/mediatek/patches-4.4/0018-dt-bindings-Add-a-binding-for-Mediatek-xHCI-host-con.patch
@@ -1,7 +1,7 @@
From 84d37aeef94deae3ce87e677f6016a5d980429e8 Mon Sep 17 00:00:00 2001
From: "chunfeng.yun@mediatek.com" <chunfeng.yun@mediatek.com>
Date: Tue, 17 Nov 2015 17:18:39 +0800
-Subject: [PATCH 18/53] dt-bindings: Add a binding for Mediatek xHCI host
+Subject: [PATCH 18/66] dt-bindings: Add a binding for Mediatek xHCI host
controller
add a DT binding documentation of xHCI host controller for the
diff --git a/target/linux/mediatek/patches-4.4/0019-xhci-mediatek-support-MTK-xHCI-host-controller.patch b/target/linux/mediatek/patches-4.4/0019-xhci-mediatek-support-MTK-xHCI-host-controller.patch
index 05e000b..188728d 100644
--- a/target/linux/mediatek/patches-4.4/0019-xhci-mediatek-support-MTK-xHCI-host-controller.patch
+++ b/target/linux/mediatek/patches-4.4/0019-xhci-mediatek-support-MTK-xHCI-host-controller.patch
@@ -1,7 +1,7 @@
From 651d8fff94718c7e48b8a40d7774878eb8ed62ee Mon Sep 17 00:00:00 2001
From: "chunfeng.yun@mediatek.com" <chunfeng.yun@mediatek.com>
Date: Tue, 17 Nov 2015 17:18:40 +0800
-Subject: [PATCH 19/53] xhci: mediatek: support MTK xHCI host controller
+Subject: [PATCH 19/66] xhci: mediatek: support MTK xHCI host controller
There some vendor quirks for MTK xhci host controller:
1. It defines some extra SW scheduling parameters for HW
diff --git a/target/linux/mediatek/patches-4.4/0020-arm64-dts-mediatek-add-xHCI-usb-phy-for-mt8173.patch b/target/linux/mediatek/patches-4.4/0020-arm64-dts-mediatek-add-xHCI-usb-phy-for-mt8173.patch
index d52b8eb..e9ce56e 100644
--- a/target/linux/mediatek/patches-4.4/0020-arm64-dts-mediatek-add-xHCI-usb-phy-for-mt8173.patch
+++ b/target/linux/mediatek/patches-4.4/0020-arm64-dts-mediatek-add-xHCI-usb-phy-for-mt8173.patch
@@ -1,7 +1,7 @@
From 31a22fbd0d3b187be61c4c5d22b19c95abb327c3 Mon Sep 17 00:00:00 2001
From: "chunfeng.yun@mediatek.com" <chunfeng.yun@mediatek.com>
Date: Tue, 17 Nov 2015 17:18:41 +0800
-Subject: [PATCH 20/53] arm64: dts: mediatek: add xHCI & usb phy for mt8173
+Subject: [PATCH 20/66] arm64: dts: mediatek: add xHCI & usb phy for mt8173
add xHCI and phy drivers for MT8173-EVB
diff --git a/target/linux/mediatek/patches-4.4/0021-Document-DT-Add-bindings-for-mediatek-MT7623-SoC-Pla.patch b/target/linux/mediatek/patches-4.4/0021-Document-DT-Add-bindings-for-mediatek-MT7623-SoC-Pla.patch
index 053c4fe..b7aae92 100644
--- a/target/linux/mediatek/patches-4.4/0021-Document-DT-Add-bindings-for-mediatek-MT7623-SoC-Pla.patch
+++ b/target/linux/mediatek/patches-4.4/0021-Document-DT-Add-bindings-for-mediatek-MT7623-SoC-Pla.patch
@@ -1,7 +1,7 @@
From 162deec293400cb132161606629654acaec7cb4b Mon Sep 17 00:00:00 2001
From: John Crispin <blogic@openwrt.org>
Date: Tue, 5 Jan 2016 12:13:54 +0100
-Subject: [PATCH 21/53] Document: DT: Add bindings for mediatek MT7623 SoC
+Subject: [PATCH 21/66] Document: DT: Add bindings for mediatek MT7623 SoC
Platform
This adds a DT binding documentation for the MT7623 SoC from Mediatek.
diff --git a/target/linux/mediatek/patches-4.4/0022-soc-mediatek-add-compat-string-for-mt7623-to-scpsys.patch b/target/linux/mediatek/patches-4.4/0022-soc-mediatek-add-compat-string-for-mt7623-to-scpsys.patch
index 6d76ae3..eefbffd 100644
--- a/target/linux/mediatek/patches-4.4/0022-soc-mediatek-add-compat-string-for-mt7623-to-scpsys.patch
+++ b/target/linux/mediatek/patches-4.4/0022-soc-mediatek-add-compat-string-for-mt7623-to-scpsys.patch
@@ -1,7 +1,7 @@
From fa5d94d6b4b314f751b1c32bb5a87a80b866d05e Mon Sep 17 00:00:00 2001
From: John Crispin <blogic@openwrt.org>
Date: Tue, 5 Jan 2016 16:52:31 +0100
-Subject: [PATCH 22/53] soc: mediatek: add compat string for mt7623 to scpsys
+Subject: [PATCH 22/66] soc: mediatek: add compat string for mt7623 to scpsys
Signed-off-by: John Crispin <blogic@openwrt.org>
---
diff --git a/target/linux/mediatek/patches-4.4/0023-ARM-dts-mediatek-add-MT7623-basic-support.patch b/target/linux/mediatek/patches-4.4/0023-ARM-dts-mediatek-add-MT7623-basic-support.patch
index 85ff551..af0a68f 100644
--- a/target/linux/mediatek/patches-4.4/0023-ARM-dts-mediatek-add-MT7623-basic-support.patch
+++ b/target/linux/mediatek/patches-4.4/0023-ARM-dts-mediatek-add-MT7623-basic-support.patch
@@ -1,7 +1,7 @@
From cfe366d7a20f88c7fc92faaf8b25c24e730bd40b Mon Sep 17 00:00:00 2001
From: John Crispin <blogic@openwrt.org>
Date: Tue, 5 Jan 2016 12:16:17 +0100
-Subject: [PATCH 23/53] ARM: dts: mediatek: add MT7623 basic support
+Subject: [PATCH 23/66] ARM: dts: mediatek: add MT7623 basic support
This adds basic chip support for Mediatek MT7623.
@@ -16,11 +16,9 @@ Signed-off-by: John Crispin <blogic@openwrt.org>
create mode 100644 arch/arm/boot/dts/mt7623-evb.dts
create mode 100644 arch/arm/boot/dts/mt7623.dtsi
-diff --git a/arch/arm/boot/dts/Makefile b/arch/arm/boot/dts/Makefile
-index 30bbc37..2bce370 100644
--- a/arch/arm/boot/dts/Makefile
+++ b/arch/arm/boot/dts/Makefile
-@@ -774,6 +774,7 @@ dtb-$(CONFIG_ARCH_MEDIATEK) += \
+@@ -774,6 +774,7 @@
mt6580-evbp1.dtb \
mt6589-aquaris5.dtb \
mt6592-evb.dtb \
@@ -28,9 +26,6 @@ index 30bbc37..2bce370 100644
mt8127-moose.dtb \
mt8135-evbp1.dtb
dtb-$(CONFIG_ARCH_ZX) += zx296702-ad1.dtb
-diff --git a/arch/arm/boot/dts/mt7623-evb.dts b/arch/arm/boot/dts/mt7623-evb.dts
-new file mode 100644
-index 0000000..5e9381d
--- /dev/null
+++ b/arch/arm/boot/dts/mt7623-evb.dts
@@ -0,0 +1,459 @@
@@ -493,12 +488,9 @@ index 0000000..5e9381d
+ mediatek,reset-pin = <&pio 15 0>;
+ status = "okay";
+};
-diff --git a/arch/arm/boot/dts/mt7623.dtsi b/arch/arm/boot/dts/mt7623.dtsi
-new file mode 100644
-index 0000000..1ba7790
--- /dev/null
+++ b/arch/arm/boot/dts/mt7623.dtsi
-@@ -0,0 +1,507 @@
+@@ -0,0 +1,508 @@
+/*
+ * Copyright (c) 2016 MediaTek Inc.
+ * Author: John Crispin <blogic@openwrt.org>
@@ -530,6 +522,7 @@ index 0000000..1ba7790
+ cpus {
+ #address-cells = <1>;
+ #size-cells = <0>;
++ enable-method = "mediatek,mt6589-smp";
+
+ cpu@0 {
+ device_type = "cpu";
@@ -1006,11 +999,9 @@ index 0000000..1ba7790
+ status = "disabled";
+ };
+};
-diff --git a/arch/arm/mach-mediatek/Kconfig b/arch/arm/mach-mediatek/Kconfig
-index 37dd438..7fb605e 100644
--- a/arch/arm/mach-mediatek/Kconfig
+++ b/arch/arm/mach-mediatek/Kconfig
-@@ -21,6 +21,10 @@ config MACH_MT6592
+@@ -21,6 +21,10 @@
bool "MediaTek MT6592 SoCs support"
default ARCH_MEDIATEK
@@ -1021,11 +1012,9 @@ index 37dd438..7fb605e 100644
config MACH_MT8127
bool "MediaTek MT8127 SoCs support"
default ARCH_MEDIATEK
-diff --git a/arch/arm/mach-mediatek/mediatek.c b/arch/arm/mach-mediatek/mediatek.c
-index d019a08..bcfca37 100644
--- a/arch/arm/mach-mediatek/mediatek.c
+++ b/arch/arm/mach-mediatek/mediatek.c
-@@ -46,6 +46,7 @@ static void __init mediatek_timer_init(void)
+@@ -46,6 +46,7 @@
static const char * const mediatek_board_dt_compat[] = {
"mediatek,mt6589",
"mediatek,mt6592",
@@ -1033,6 +1022,3 @@ index d019a08..bcfca37 100644
"mediatek,mt8127",
"mediatek,mt8135",
NULL,
---
-1.7.10.4
-
diff --git a/target/linux/mediatek/patches-4.4/0024-dt-bindings-add-MediaTek-PCIe-binding-documentation.patch b/target/linux/mediatek/patches-4.4/0024-dt-bindings-add-MediaTek-PCIe-binding-documentation.patch
index 2274833..53db649 100644
--- a/target/linux/mediatek/patches-4.4/0024-dt-bindings-add-MediaTek-PCIe-binding-documentation.patch
+++ b/target/linux/mediatek/patches-4.4/0024-dt-bindings-add-MediaTek-PCIe-binding-documentation.patch
@@ -1,12 +1,13 @@
-From 5b51a1e93ccaaec4cd90b73ee20cea219af2f151 Mon Sep 17 00:00:00 2001
+From 2ff725af8a512481d68ebd7f8ad122b1c98f3fad Mon Sep 17 00:00:00 2001
From: John Crispin <blogic@openwrt.org>
Date: Wed, 6 Jan 2016 21:55:10 +0100
-Subject: [PATCH 24/53] dt-bindings: add MediaTek PCIe binding documentation
+Subject: [PATCH 24/66] dt-bindings: add MediaTek PCIe binding documentation
Signed-off-by: John Crispin <blogic@openwrt.org>
---
.../devicetree/bindings/pci/mediatek-pcie.txt | 140 ++++++++++++++++++++
- 1 file changed, 140 insertions(+)
+ arch/arm/boot/dts/mt7623.dtsi | 12 ++
+ 2 files changed, 152 insertions(+)
create mode 100644 Documentation/devicetree/bindings/pci/mediatek-pcie.txt
diff --git a/Documentation/devicetree/bindings/pci/mediatek-pcie.txt b/Documentation/devicetree/bindings/pci/mediatek-pcie.txt
@@ -155,6 +156,29 @@ index 0000000..8fea3ed
+ status = "okay";
+ };
+ };
+diff --git a/arch/arm/boot/dts/mt7623.dtsi b/arch/arm/boot/dts/mt7623.dtsi
+index 1ba7790..ec19283 100644
+--- a/arch/arm/boot/dts/mt7623.dtsi
++++ b/arch/arm/boot/dts/mt7623.dtsi
+@@ -291,6 +291,18 @@
+ status = "disabled";
+ };
+
++ nand: nfi@1100d000 {
++ compatible = "mediatek,mt2701-nfc";
++ reg = <0 0x1100d000 0 0x1000>, <0 0x1100e000 0 0x1000>;
++ interrupts = <GIC_SPI 56 IRQ_TYPE_LEVEL_LOW>,
++ <GIC_SPI 55 IRQ_TYPE_LEVEL_LOW>;
++ clocks = <&pericfg CLK_PERI_NFI>, <&pericfg CLK_PERI_NFI_ECC>,
++ <&pericfg CLK_PERI_NFI_PAD>;
++ clock-names = "nfi_clk", "nfiecc_clk", "pad_clk";
++ nand-on-flash-bbt;
++ status = "disabled";
++ };
++
+ mmc0: mmc@11230000 {
+ compatible = "mediatek,mt7623-mmc",
+ "mediatek,mt8135-mmc";
--
1.7.10.4
diff --git a/target/linux/mediatek/patches-4.4/0025-PCI-mediatek-add-support-for-PCIe-found-on-MT7623-MT.patch b/target/linux/mediatek/patches-4.4/0025-PCI-mediatek-add-support-for-PCIe-found-on-MT7623-MT.patch
index 9e12892..36a7a85 100644
--- a/target/linux/mediatek/patches-4.4/0025-PCI-mediatek-add-support-for-PCIe-found-on-MT7623-MT.patch
+++ b/target/linux/mediatek/patches-4.4/0025-PCI-mediatek-add-support-for-PCIe-found-on-MT7623-MT.patch
@@ -1,7 +1,7 @@
-From fc6d1a9f37cddd79c0c149e3f1394d393ac05772 Mon Sep 17 00:00:00 2001
+From 1ac5a6be891fb934e2a864bb2e424f05315f7385 Mon Sep 17 00:00:00 2001
From: John Crispin <blogic@openwrt.org>
Date: Tue, 5 Jan 2016 20:20:04 +0100
-Subject: [PATCH 25/53] PCI: mediatek: add support for PCIe found on
+Subject: [PATCH 25/66] PCI: mediatek: add support for PCIe found on
MT7623/MT2701
Add PCIe controller support on MediaTek MT2701/MT7623. The driver supports
diff --git a/target/linux/mediatek/patches-4.4/0026-scpsys-various-fixes.patch b/target/linux/mediatek/patches-4.4/0026-scpsys-various-fixes.patch
index 1ff2515..bf26783 100644
--- a/target/linux/mediatek/patches-4.4/0026-scpsys-various-fixes.patch
+++ b/target/linux/mediatek/patches-4.4/0026-scpsys-various-fixes.patch
@@ -1,7 +1,7 @@
-From f027ce51ff728a22428fb0b7107edf9e1bd61712 Mon Sep 17 00:00:00 2001
+From 6c5c23a6c21b1a244db79d6387db915c72f50367 Mon Sep 17 00:00:00 2001
From: John Crispin <blogic@openwrt.org>
Date: Sun, 21 Feb 2016 13:52:12 +0100
-Subject: [PATCH 26/53] scpsys: various fixes
+Subject: [PATCH 26/66] scpsys: various fixes
---
drivers/clk/mediatek/clk-mt2701.c | 2 ++
diff --git a/target/linux/mediatek/patches-4.4/0027-soc-mediatek-PMIC-wrap-Clear-the-vldclr-if-state-mac.patch b/target/linux/mediatek/patches-4.4/0027-soc-mediatek-PMIC-wrap-Clear-the-vldclr-if-state-mac.patch
index 970860c..2607f93 100644
--- a/target/linux/mediatek/patches-4.4/0027-soc-mediatek-PMIC-wrap-Clear-the-vldclr-if-state-mac.patch
+++ b/target/linux/mediatek/patches-4.4/0027-soc-mediatek-PMIC-wrap-Clear-the-vldclr-if-state-mac.patch
@@ -1,7 +1,7 @@
-From af4a99b856b584b2426757e905e9b6f39906ce05 Mon Sep 17 00:00:00 2001
+From dadfca5daee5cb40d34542425392e694eddc5bc1 Mon Sep 17 00:00:00 2001
From: Henry Chen <henryc.chen@mediatek.com>
Date: Mon, 4 Jan 2016 20:02:52 +0800
-Subject: [PATCH 27/53] soc: mediatek: PMIC wrap: Clear the vldclr if state
+Subject: [PATCH 27/66] soc: mediatek: PMIC wrap: Clear the vldclr if state
machine stay on FSM_VLDCLR state.
Sometimes PMIC is too busy to send data in time to cause pmic wrap timeout,
diff --git a/target/linux/mediatek/patches-4.4/0028-ARM-mediatek-add-MT7623-smp-bringup-code.patch b/target/linux/mediatek/patches-4.4/0028-ARM-mediatek-add-MT7623-smp-bringup-code.patch
index 80bb4ff..24521cb 100644
--- a/target/linux/mediatek/patches-4.4/0028-ARM-mediatek-add-MT7623-smp-bringup-code.patch
+++ b/target/linux/mediatek/patches-4.4/0028-ARM-mediatek-add-MT7623-smp-bringup-code.patch
@@ -1,7 +1,7 @@
-From 0742887b1d36913ccd5f6fa85649ad5eb0bfb200 Mon Sep 17 00:00:00 2001
+From 7512d9b4bf8ab222b4d542ada87368229770383f Mon Sep 17 00:00:00 2001
From: John Crispin <blogic@openwrt.org>
Date: Tue, 5 Jan 2016 17:24:28 +0100
-Subject: [PATCH 28/53] ARM: mediatek: add MT7623 smp bringup code
+Subject: [PATCH 28/66] ARM: mediatek: add MT7623 smp bringup code
Add support for booting secondary CPUs on MT7623.
diff --git a/target/linux/mediatek/patches-4.4/0029-soc-mediatek-PMIC-wrap-clear-the-STAUPD_TRIG-bit-of-.patch b/target/linux/mediatek/patches-4.4/0029-soc-mediatek-PMIC-wrap-clear-the-STAUPD_TRIG-bit-of-.patch
index f8a1cd1..eab74bc 100644
--- a/target/linux/mediatek/patches-4.4/0029-soc-mediatek-PMIC-wrap-clear-the-STAUPD_TRIG-bit-of-.patch
+++ b/target/linux/mediatek/patches-4.4/0029-soc-mediatek-PMIC-wrap-clear-the-STAUPD_TRIG-bit-of-.patch
@@ -1,7 +1,7 @@
-From 5d75662fcdfef08d82710f8c4b71c58d618d4171 Mon Sep 17 00:00:00 2001
+From f8296ee9561945b5cebb570e06259b8865ef0b91 Mon Sep 17 00:00:00 2001
From: Henry Chen <henryc.chen@mediatek.com>
Date: Thu, 21 Jan 2016 19:04:00 +0800
-Subject: [PATCH 29/53] soc: mediatek: PMIC wrap: clear the STAUPD_TRIG bit of
+Subject: [PATCH 29/66] soc: mediatek: PMIC wrap: clear the STAUPD_TRIG bit of
WDT_SRC_EN
Since STAUPD interrupts aren't handled on mt8173, disable watchdog timeout
diff --git a/target/linux/mediatek/patches-4.4/0030-ARM-mediatek-add-mt2701-smp-bringup-code.patch b/target/linux/mediatek/patches-4.4/0030-ARM-mediatek-add-mt2701-smp-bringup-code.patch
index 24e59e8..9039cc1 100644
--- a/target/linux/mediatek/patches-4.4/0030-ARM-mediatek-add-mt2701-smp-bringup-code.patch
+++ b/target/linux/mediatek/patches-4.4/0030-ARM-mediatek-add-mt2701-smp-bringup-code.patch
@@ -1,7 +1,7 @@
-From f6e138ee1a8ddba7b512cafc2ecc7cd1b41781dc Mon Sep 17 00:00:00 2001
+From 977ccf394047647354093535f9b07f13a74949df Mon Sep 17 00:00:00 2001
From: Louis Yu <louis.yu@mediatek.com>
Date: Thu, 7 Jan 2016 20:09:43 +0800
-Subject: [PATCH 30/53] ARM: mediatek: add mt2701 smp bringup code
+Subject: [PATCH 30/66] ARM: mediatek: add mt2701 smp bringup code
Add support for booting secondary CPUs on mt2701.
diff --git a/target/linux/mediatek/patches-4.4/0031-dt-bindings-ARM-Mediatek-add-MT2701-7623-string-to-t.patch b/target/linux/mediatek/patches-4.4/0031-dt-bindings-ARM-Mediatek-add-MT2701-7623-string-to-t.patch
index b444136..fd44518 100644
--- a/target/linux/mediatek/patches-4.4/0031-dt-bindings-ARM-Mediatek-add-MT2701-7623-string-to-t.patch
+++ b/target/linux/mediatek/patches-4.4/0031-dt-bindings-ARM-Mediatek-add-MT2701-7623-string-to-t.patch
@@ -1,7 +1,7 @@
-From 2e4a714f60266098a2b3553d1b1f83732da90abd Mon Sep 17 00:00:00 2001
+From add1cc43bd41e6fc755852a5767e710cb3314013 Mon Sep 17 00:00:00 2001
From: John Crispin <blogic@openwrt.org>
Date: Wed, 20 Jan 2016 13:12:19 +0100
-Subject: [PATCH 31/53] dt-bindings: ARM: Mediatek: add MT2701/7623 string to
+Subject: [PATCH 31/66] dt-bindings: ARM: Mediatek: add MT2701/7623 string to
the PMIC wrapper doc
Signed-off-by: John Crispin <blogic@openwrt.org>
diff --git a/target/linux/mediatek/patches-4.4/0032-soc-mediatek-PMIC-wrap-don-t-duplicate-the-wrapper-d.patch b/target/linux/mediatek/patches-4.4/0032-soc-mediatek-PMIC-wrap-don-t-duplicate-the-wrapper-d.patch
index 7f389b3..5ee4ea4 100644
--- a/target/linux/mediatek/patches-4.4/0032-soc-mediatek-PMIC-wrap-don-t-duplicate-the-wrapper-d.patch
+++ b/target/linux/mediatek/patches-4.4/0032-soc-mediatek-PMIC-wrap-don-t-duplicate-the-wrapper-d.patch
@@ -1,7 +1,7 @@
-From b68e33cc67465ad99299947916678f8ea4418b1c Mon Sep 17 00:00:00 2001
+From 6792f25663b6064f21f033241bbeb6b023fa8ce7 Mon Sep 17 00:00:00 2001
From: John Crispin <blogic@openwrt.org>
Date: Wed, 20 Jan 2016 06:42:01 +0100
-Subject: [PATCH 32/53] soc: mediatek: PMIC wrap: don't duplicate the wrapper
+Subject: [PATCH 32/66] soc: mediatek: PMIC wrap: don't duplicate the wrapper
data
As we add support for more devices struct pmic_wrapper_type will grow and
diff --git a/target/linux/mediatek/patches-4.4/0033-soc-mediatek-PMIC-wrap-add-wrapper-callbacks-for-ini.patch b/target/linux/mediatek/patches-4.4/0033-soc-mediatek-PMIC-wrap-add-wrapper-callbacks-for-ini.patch
index 67ef869..55881e0 100644
--- a/target/linux/mediatek/patches-4.4/0033-soc-mediatek-PMIC-wrap-add-wrapper-callbacks-for-ini.patch
+++ b/target/linux/mediatek/patches-4.4/0033-soc-mediatek-PMIC-wrap-add-wrapper-callbacks-for-ini.patch
@@ -1,7 +1,7 @@
-From 45ead148322ba7be9de970a2ab6be4ed3f7ca184 Mon Sep 17 00:00:00 2001
+From b67fd66c46f7cc6ac869aafc7f920846aed6bc12 Mon Sep 17 00:00:00 2001
From: John Crispin <blogic@openwrt.org>
Date: Wed, 20 Jan 2016 05:27:17 +0100
-Subject: [PATCH 33/53] soc: mediatek: PMIC wrap: add wrapper callbacks for
+Subject: [PATCH 33/66] soc: mediatek: PMIC wrap: add wrapper callbacks for
init_reg_clock
Split init_reg_clock up into SoC specific callbacks. The patch also
diff --git a/target/linux/mediatek/patches-4.4/0034-soc-mediatek-PMIC-wrap-split-SoC-specific-init-into-.patch b/target/linux/mediatek/patches-4.4/0034-soc-mediatek-PMIC-wrap-split-SoC-specific-init-into-.patch
index aa34aaf..e73c43a 100644
--- a/target/linux/mediatek/patches-4.4/0034-soc-mediatek-PMIC-wrap-split-SoC-specific-init-into-.patch
+++ b/target/linux/mediatek/patches-4.4/0034-soc-mediatek-PMIC-wrap-split-SoC-specific-init-into-.patch
@@ -1,7 +1,7 @@
-From b3cc9f4c4b1164ac6a0700920eca84dff81d13d7 Mon Sep 17 00:00:00 2001
+From 4dd080818ec30dd101b6248b418751de5ac508f2 Mon Sep 17 00:00:00 2001
From: John Crispin <blogic@openwrt.org>
Date: Wed, 20 Jan 2016 10:12:00 +0100
-Subject: [PATCH 34/53] soc: mediatek: PMIC wrap: split SoC specific init into
+Subject: [PATCH 34/66] soc: mediatek: PMIC wrap: split SoC specific init into
callback
This patch moves the SoC specific wrapper init code into separate callback
diff --git a/target/linux/mediatek/patches-4.4/0035-soc-mediatek-PMIC-wrap-WRAP_INT_EN-needs-a-different.patch b/target/linux/mediatek/patches-4.4/0035-soc-mediatek-PMIC-wrap-WRAP_INT_EN-needs-a-different.patch
index 9bfc90d..8451679 100644
--- a/target/linux/mediatek/patches-4.4/0035-soc-mediatek-PMIC-wrap-WRAP_INT_EN-needs-a-different.patch
+++ b/target/linux/mediatek/patches-4.4/0035-soc-mediatek-PMIC-wrap-WRAP_INT_EN-needs-a-different.patch
@@ -1,7 +1,7 @@
-From 824563fe3d8b915714816255489fcfb2792c3a8a Mon Sep 17 00:00:00 2001
+From 72300493dbf58de75972fce86e64f4728ff9b594 Mon Sep 17 00:00:00 2001
From: John Crispin <blogic@openwrt.org>
Date: Wed, 20 Jan 2016 10:14:39 +0100
-Subject: [PATCH 35/53] soc: mediatek: PMIC wrap: WRAP_INT_EN needs a
+Subject: [PATCH 35/66] soc: mediatek: PMIC wrap: WRAP_INT_EN needs a
different bitmask for MT2701/7623
MT2701 and MT7623 use a different bitmask for PWRAP_INT_EN.
diff --git a/target/linux/mediatek/patches-4.4/0036-soc-mediatek-PMIC-wrap-SPI_WRITE-needs-a-different-b.patch b/target/linux/mediatek/patches-4.4/0036-soc-mediatek-PMIC-wrap-SPI_WRITE-needs-a-different-b.patch
index e18f47d..7f7a905 100644
--- a/target/linux/mediatek/patches-4.4/0036-soc-mediatek-PMIC-wrap-SPI_WRITE-needs-a-different-b.patch
+++ b/target/linux/mediatek/patches-4.4/0036-soc-mediatek-PMIC-wrap-SPI_WRITE-needs-a-different-b.patch
@@ -1,7 +1,7 @@
-From 2028a24d161da25b827b394bdcec4deba5d2efd9 Mon Sep 17 00:00:00 2001
+From 8e28fd218224df9c1a108a0b0d4c3a2ec51ddc62 Mon Sep 17 00:00:00 2001
From: John Crispin <blogic@openwrt.org>
Date: Wed, 20 Jan 2016 10:21:42 +0100
-Subject: [PATCH 36/53] soc: mediatek: PMIC wrap: SPI_WRITE needs a different
+Subject: [PATCH 36/66] soc: mediatek: PMIC wrap: SPI_WRITE needs a different
bitmask for MT2701/7623
Different SoCs will use different bitmask for the SPI_WRITE command. This
diff --git a/target/linux/mediatek/patches-4.4/0037-soc-mediatek-PMIC-wrap-move-wdt_src-into-the-pmic_wr.patch b/target/linux/mediatek/patches-4.4/0037-soc-mediatek-PMIC-wrap-move-wdt_src-into-the-pmic_wr.patch
index e589665..ed225a5 100644
--- a/target/linux/mediatek/patches-4.4/0037-soc-mediatek-PMIC-wrap-move-wdt_src-into-the-pmic_wr.patch
+++ b/target/linux/mediatek/patches-4.4/0037-soc-mediatek-PMIC-wrap-move-wdt_src-into-the-pmic_wr.patch
@@ -1,7 +1,7 @@
-From 50bd0c152a0c33000ae88d0828f320eb603fd535 Mon Sep 17 00:00:00 2001
+From 3a01206ed5749b5469459f82f1152e3699cb8baf Mon Sep 17 00:00:00 2001
From: John Crispin <blogic@openwrt.org>
Date: Wed, 20 Jan 2016 10:48:35 +0100
-Subject: [PATCH 37/53] soc: mediatek: PMIC wrap: move wdt_src into the
+Subject: [PATCH 37/66] soc: mediatek: PMIC wrap: move wdt_src into the
pmic_wrapper_type struct
Different SoCs will use different bitmask for the wdt_src. This patch
diff --git a/target/linux/mediatek/patches-4.4/0038-soc-mediatek-PMIC-wrap-remove-pwrap_is_mt8135-and-pw.patch b/target/linux/mediatek/patches-4.4/0038-soc-mediatek-PMIC-wrap-remove-pwrap_is_mt8135-and-pw.patch
index 0251883..ad8ff5f 100644
--- a/target/linux/mediatek/patches-4.4/0038-soc-mediatek-PMIC-wrap-remove-pwrap_is_mt8135-and-pw.patch
+++ b/target/linux/mediatek/patches-4.4/0038-soc-mediatek-PMIC-wrap-remove-pwrap_is_mt8135-and-pw.patch
@@ -1,7 +1,7 @@
-From f08ce6b84d2759fdff2e8ea2cf2b30b3220521ef Mon Sep 17 00:00:00 2001
+From 20f4eef2f061619762aa87d484b359c3f9a0b228 Mon Sep 17 00:00:00 2001
From: John Crispin <blogic@openwrt.org>
Date: Wed, 20 Jan 2016 10:54:18 +0100
-Subject: [PATCH 38/53] soc: mediatek: PMIC wrap: remove pwrap_is_mt8135() and
+Subject: [PATCH 38/66] soc: mediatek: PMIC wrap: remove pwrap_is_mt8135() and
pwrap_is_mt8173()
With more SoCs being added the list of helper functions like these would
diff --git a/target/linux/mediatek/patches-4.4/0039-soc-mediatek-PMIC-wrap-add-a-slave-specific-struct.patch b/target/linux/mediatek/patches-4.4/0039-soc-mediatek-PMIC-wrap-add-a-slave-specific-struct.patch
index c76e27b..5cde242 100644
--- a/target/linux/mediatek/patches-4.4/0039-soc-mediatek-PMIC-wrap-add-a-slave-specific-struct.patch
+++ b/target/linux/mediatek/patches-4.4/0039-soc-mediatek-PMIC-wrap-add-a-slave-specific-struct.patch
@@ -1,7 +1,7 @@
-From 7c6b5e5e36ccd9079a2425dc80507447784b9bb2 Mon Sep 17 00:00:00 2001
+From 023e530aa86c95352dfc97df960ee0039ef2c030 Mon Sep 17 00:00:00 2001
From: John Crispin <blogic@openwrt.org>
Date: Wed, 20 Jan 2016 09:55:08 +0100
-Subject: [PATCH 39/53] soc: mediatek: PMIC wrap: add a slave specific struct
+Subject: [PATCH 39/66] soc: mediatek: PMIC wrap: add a slave specific struct
This patch adds a new struct pwrap_slv_type that we use to store the slave
specific data. The patch adds 2 new helper functions to access the dew
diff --git a/target/linux/mediatek/patches-4.4/0040-soc-mediatek-PMIC-wrap-add-mt6323-slave-support.patch b/target/linux/mediatek/patches-4.4/0040-soc-mediatek-PMIC-wrap-add-mt6323-slave-support.patch
index 77f46e7..a01f992 100644
--- a/target/linux/mediatek/patches-4.4/0040-soc-mediatek-PMIC-wrap-add-mt6323-slave-support.patch
+++ b/target/linux/mediatek/patches-4.4/0040-soc-mediatek-PMIC-wrap-add-mt6323-slave-support.patch
@@ -1,7 +1,7 @@
-From b82474df3eb9fad739b2b74301b68f71011a9dc7 Mon Sep 17 00:00:00 2001
+From 5db18f42fc5584a516cb7a8b705c97a7f1c4bf1b Mon Sep 17 00:00:00 2001
From: John Crispin <blogic@openwrt.org>
Date: Wed, 20 Jan 2016 11:40:43 +0100
-Subject: [PATCH 40/53] soc: mediatek: PMIC wrap: add mt6323 slave support
+Subject: [PATCH 40/66] soc: mediatek: PMIC wrap: add mt6323 slave support
Add support for MT6323 slaves. This PMIC can be found on MT2701 and MT7623
EVB. The only function that we need to touch is pwrap_init_cipher().
diff --git a/target/linux/mediatek/patches-4.4/0041-soc-mediatek-PMIC-wrap-add-MT2701-7623-support.patch b/target/linux/mediatek/patches-4.4/0041-soc-mediatek-PMIC-wrap-add-MT2701-7623-support.patch
index 15445a7..a7e8775 100644
--- a/target/linux/mediatek/patches-4.4/0041-soc-mediatek-PMIC-wrap-add-MT2701-7623-support.patch
+++ b/target/linux/mediatek/patches-4.4/0041-soc-mediatek-PMIC-wrap-add-MT2701-7623-support.patch
@@ -1,7 +1,7 @@
-From 84e83af30688372723a3b5713e914b0867d9a745 Mon Sep 17 00:00:00 2001
+From 444c4931cc6c2d1d9c94d8bbd4ee89438abca212 Mon Sep 17 00:00:00 2001
From: John Crispin <blogic@openwrt.org>
Date: Wed, 20 Jan 2016 12:09:14 +0100
-Subject: [PATCH 41/53] soc: mediatek: PMIC wrap: add MT2701/7623 support
+Subject: [PATCH 41/66] soc: mediatek: PMIC wrap: add MT2701/7623 support
Add the registers, callbacks and data structures required to make the
wrapper work on MT2701 and MT7623.
diff --git a/target/linux/mediatek/patches-4.4/0042-dt-bindings-mfd-Add-bindings-for-the-MediaTek-MT6323.patch b/target/linux/mediatek/patches-4.4/0042-dt-bindings-mfd-Add-bindings-for-the-MediaTek-MT6323.patch
index e7a23f7..b31f063 100644
--- a/target/linux/mediatek/patches-4.4/0042-dt-bindings-mfd-Add-bindings-for-the-MediaTek-MT6323.patch
+++ b/target/linux/mediatek/patches-4.4/0042-dt-bindings-mfd-Add-bindings-for-the-MediaTek-MT6323.patch
@@ -1,7 +1,7 @@
-From 3af0e56f55d7676fab0ba39ef599c64dd6ab4b35 Mon Sep 17 00:00:00 2001
+From eb574bce59e66295ee288de0df450a6e82bb5b56 Mon Sep 17 00:00:00 2001
From: John Crispin <blogic@openwrt.org>
Date: Sun, 10 Jan 2016 17:12:37 +0100
-Subject: [PATCH 42/53] dt-bindings: mfd: Add bindings for the MediaTek MT6323
+Subject: [PATCH 42/66] dt-bindings: mfd: Add bindings for the MediaTek MT6323
PMIC
Signed-off-by: John Crispin <blogic@openwrt.org>
diff --git a/target/linux/mediatek/patches-4.4/0043-mfd-mt6397-int_con-and-int_status-may-vary-in-locati.patch b/target/linux/mediatek/patches-4.4/0043-mfd-mt6397-int_con-and-int_status-may-vary-in-locati.patch
index 113c8de..9d2379d 100644
--- a/target/linux/mediatek/patches-4.4/0043-mfd-mt6397-int_con-and-int_status-may-vary-in-locati.patch
+++ b/target/linux/mediatek/patches-4.4/0043-mfd-mt6397-int_con-and-int_status-may-vary-in-locati.patch
@@ -1,7 +1,7 @@
-From f3d5ef8f5422de25f1c8a96b313baf60e4ce1081 Mon Sep 17 00:00:00 2001
+From 337807a89aec90a313a77336a9296ccd926c7015 Mon Sep 17 00:00:00 2001
From: John Crispin <blogic@openwrt.org>
Date: Fri, 8 Jan 2016 08:33:17 +0100
-Subject: [PATCH 43/53] mfd: mt6397: int_con and int_status may vary in
+Subject: [PATCH 43/66] mfd: mt6397: int_con and int_status may vary in
location
MT6323 has the INT_CON and INT_STATUS located at a different position.
diff --git a/target/linux/mediatek/patches-4.4/0044-mfd-mt6397-add-support-for-different-Slave-types.patch b/target/linux/mediatek/patches-4.4/0044-mfd-mt6397-add-support-for-different-Slave-types.patch
index 30576b7..0550087 100644
--- a/target/linux/mediatek/patches-4.4/0044-mfd-mt6397-add-support-for-different-Slave-types.patch
+++ b/target/linux/mediatek/patches-4.4/0044-mfd-mt6397-add-support-for-different-Slave-types.patch
@@ -1,7 +1,7 @@
-From d29ee5f0472ea3e964e698e3e9e87a83b4465e9c Mon Sep 17 00:00:00 2001
+From c6fab1574939f968257029dd75da51ab266081c9 Mon Sep 17 00:00:00 2001
From: John Crispin <blogic@openwrt.org>
Date: Fri, 8 Jan 2016 08:41:52 +0100
-Subject: [PATCH 44/53] mfd: mt6397: add support for different Slave types
+Subject: [PATCH 44/66] mfd: mt6397: add support for different Slave types
Signed-off-by: John Crispin <blogic@openwrt.org>
---
diff --git a/target/linux/mediatek/patches-4.4/0045-mfd-mt6397-add-MT6323-support-to-MT6397-driver.patch b/target/linux/mediatek/patches-4.4/0045-mfd-mt6397-add-MT6323-support-to-MT6397-driver.patch
index 7831eb6..3b8a752 100644
--- a/target/linux/mediatek/patches-4.4/0045-mfd-mt6397-add-MT6323-support-to-MT6397-driver.patch
+++ b/target/linux/mediatek/patches-4.4/0045-mfd-mt6397-add-MT6323-support-to-MT6397-driver.patch
@@ -1,7 +1,7 @@
-From 926910e33f5de67f229ac089ab5f3de1bfd117f9 Mon Sep 17 00:00:00 2001
+From d3d044cff01ef835ef36b6f7d22b19fe47b65e46 Mon Sep 17 00:00:00 2001
From: John Crispin <blogic@openwrt.org>
Date: Fri, 8 Jan 2016 04:09:43 +0100
-Subject: [PATCH 45/53] mfd: mt6397: add MT6323 support to MT6397 driver
+Subject: [PATCH 45/66] mfd: mt6397: add MT6323 support to MT6397 driver
Signed-off-by: John Crispin <blogic@openwrt.org>
---
diff --git a/target/linux/mediatek/patches-4.4/0046-regulator-Add-document-for-MT6323-regulator.patch b/target/linux/mediatek/patches-4.4/0046-regulator-Add-document-for-MT6323-regulator.patch
index b6b237d..f5b7f23 100644
--- a/target/linux/mediatek/patches-4.4/0046-regulator-Add-document-for-MT6323-regulator.patch
+++ b/target/linux/mediatek/patches-4.4/0046-regulator-Add-document-for-MT6323-regulator.patch
@@ -1,7 +1,7 @@
-From 3900467f0f0470f889b9e6cdfd7dc4cf460e8d41 Mon Sep 17 00:00:00 2001
+From 9877cc960be38947b6bce371e3dce2be185dc337 Mon Sep 17 00:00:00 2001
From: John Crispin <blogic@openwrt.org>
Date: Sun, 10 Jan 2016 17:31:46 +0100
-Subject: [PATCH 46/53] regulator: Add document for MT6323 regulator
+Subject: [PATCH 46/66] regulator: Add document for MT6323 regulator
Signed-off-by: John Crispin <blogic@openwrt.org>
Cc: devicetree@vger.kernel.org
diff --git a/target/linux/mediatek/patches-4.4/0047-regulator-mt6323-Add-support-for-MT6323-regulator.patch b/target/linux/mediatek/patches-4.4/0047-regulator-mt6323-Add-support-for-MT6323-regulator.patch
index 36702dc..37d7fd1 100644
--- a/target/linux/mediatek/patches-4.4/0047-regulator-mt6323-Add-support-for-MT6323-regulator.patch
+++ b/target/linux/mediatek/patches-4.4/0047-regulator-mt6323-Add-support-for-MT6323-regulator.patch
@@ -1,7 +1,7 @@
-From eb0a8e236431bf233267299ba797e2269b6e19ea Mon Sep 17 00:00:00 2001
+From 34163b123140c2668d52385bb9ab501cb025f943 Mon Sep 17 00:00:00 2001
From: Chen Zhong <chen.zhong@mediatek.com>
Date: Fri, 8 Jan 2016 04:17:37 +0100
-Subject: [PATCH 47/53] regulator: mt6323: Add support for MT6323 regulator
+Subject: [PATCH 47/66] regulator: mt6323: Add support for MT6323 regulator
The MT6323 is a regulator found on boards based on MediaTek MT7623 and
probably other SoCs. It is a so called pmic and connects as a slave to
diff --git a/target/linux/mediatek/patches-4.4/0048-net-next-mediatek-document-MediaTek-SoC-ethernet-bin.patch b/target/linux/mediatek/patches-4.4/0048-net-next-mediatek-document-MediaTek-SoC-ethernet-bin.patch
index 43e8795..34a033e 100644
--- a/target/linux/mediatek/patches-4.4/0048-net-next-mediatek-document-MediaTek-SoC-ethernet-bin.patch
+++ b/target/linux/mediatek/patches-4.4/0048-net-next-mediatek-document-MediaTek-SoC-ethernet-bin.patch
@@ -1,7 +1,7 @@
-From 32f95a0bc03886b38a53569466d5bee4a6d66875 Mon Sep 17 00:00:00 2001
+From 13e64dd7fb55bf3948005863a494646874c22c1b Mon Sep 17 00:00:00 2001
From: John Crispin <blogic@openwrt.org>
Date: Wed, 2 Mar 2016 07:18:52 +0100
-Subject: [PATCH 48/53] net-next: mediatek: document MediaTek SoC ethernet
+Subject: [PATCH 48/66] net-next: mediatek: document MediaTek SoC ethernet
binding
This adds the binding documentation for the MediaTek Ethernet
diff --git a/target/linux/mediatek/patches-4.4/0049-net-next-mediatek-add-support-for-MT7623-ethernet.patch b/target/linux/mediatek/patches-4.4/0049-net-next-mediatek-add-support-for-MT7623-ethernet.patch
index 5bfc00f..a3e3efd 100644
--- a/target/linux/mediatek/patches-4.4/0049-net-next-mediatek-add-support-for-MT7623-ethernet.patch
+++ b/target/linux/mediatek/patches-4.4/0049-net-next-mediatek-add-support-for-MT7623-ethernet.patch
@@ -1,7 +1,7 @@
-From 873a5623ef43181f07b58328131e98fee5bc3d64 Mon Sep 17 00:00:00 2001
+From ce02aa9cebf5805427b874201b4ccb2a5e770597 Mon Sep 17 00:00:00 2001
From: John Crispin <blogic@openwrt.org>
Date: Wed, 2 Mar 2016 04:27:10 +0100
-Subject: [PATCH 49/53] net-next: mediatek: add support for MT7623 ethernet
+Subject: [PATCH 49/66] net-next: mediatek: add support for MT7623 ethernet
Add ethernet support for MediaTek SoCs from the MT7623 family. These have
dual GMAC. Depending on the exact version, there might be a built-in
diff --git a/target/linux/mediatek/patches-4.4/0050-net-next-mediatek-add-Kconfig-and-Makefile.patch b/target/linux/mediatek/patches-4.4/0050-net-next-mediatek-add-Kconfig-and-Makefile.patch
index 2358b6a..d2bd7a8 100644
--- a/target/linux/mediatek/patches-4.4/0050-net-next-mediatek-add-Kconfig-and-Makefile.patch
+++ b/target/linux/mediatek/patches-4.4/0050-net-next-mediatek-add-Kconfig-and-Makefile.patch
@@ -1,7 +1,7 @@
-From 093d38375d35e6fa0f54c2c30b517a73d8448710 Mon Sep 17 00:00:00 2001
+From e39d6547a391e3e32f88b6dde16dee271e905562 Mon Sep 17 00:00:00 2001
From: John Crispin <blogic@openwrt.org>
Date: Wed, 2 Mar 2016 04:32:43 +0100
-Subject: [PATCH 50/53] net-next: mediatek: add Kconfig and Makefile
+Subject: [PATCH 50/66] net-next: mediatek: add Kconfig and Makefile
This patch adds the Makefile and Kconfig required to make the driver build.
diff --git a/target/linux/mediatek/patches-4.4/0051-net-next-mediatek-add-an-entry-to-MAINTAINERS.patch b/target/linux/mediatek/patches-4.4/0051-net-next-mediatek-add-an-entry-to-MAINTAINERS.patch
index deb6eff..fe1f4af 100644
--- a/target/linux/mediatek/patches-4.4/0051-net-next-mediatek-add-an-entry-to-MAINTAINERS.patch
+++ b/target/linux/mediatek/patches-4.4/0051-net-next-mediatek-add-an-entry-to-MAINTAINERS.patch
@@ -1,7 +1,7 @@
-From 3180cf4f325411f796468e12d524fe6354ded274 Mon Sep 17 00:00:00 2001
+From 0ab2afe39e683c82b5c176047e81eeb2d1b9119c Mon Sep 17 00:00:00 2001
From: John Crispin <blogic@openwrt.org>
Date: Wed, 2 Mar 2016 04:34:04 +0100
-Subject: [PATCH 51/53] net-next: mediatek: add an entry to MAINTAINERS
+Subject: [PATCH 51/66] net-next: mediatek: add an entry to MAINTAINERS
Add myself and Felix as the Maintainers for the MediaTek ethernet driver.
diff --git a/target/linux/mediatek/patches-4.4/0052-net-mediatek-checking-for-IS_ERR-instead-of-NULL.patch b/target/linux/mediatek/patches-4.4/0052-net-mediatek-checking-for-IS_ERR-instead-of-NULL.patch
new file mode 100644
index 0000000..5e54291
--- /dev/null
+++ b/target/linux/mediatek/patches-4.4/0052-net-mediatek-checking-for-IS_ERR-instead-of-NULL.patch
@@ -0,0 +1,32 @@
+From 7809955b6f4319773a5ef561a5e98c61dc891a47 Mon Sep 17 00:00:00 2001
+From: Dan Carpenter <dan.carpenter@oracle.com>
+Date: Tue, 15 Mar 2016 10:18:49 +0300
+Subject: [PATCH 52/66] net: mediatek: checking for IS_ERR() instead of NULL
+
+of_phy_connect() returns NULL on error, it never returns error pointers.
+
+Fixes: 656e705243fd ('net-next: mediatek: add support for MT7623 ethernet')
+Signed-off-by: Dan Carpenter <dan.carpenter@oracle.com>
+---
+ drivers/net/ethernet/mediatek/mtk_eth_soc.c | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/net/ethernet/mediatek/mtk_eth_soc.c b/drivers/net/ethernet/mediatek/mtk_eth_soc.c
+index ba3afa5..9759fe5 100644
+--- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c
++++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c
+@@ -186,9 +186,9 @@ static int mtk_phy_connect_node(struct mtk_eth *eth, struct mtk_mac *mac,
+
+ phydev = of_phy_connect(eth->netdev[mac->id], phy_node,
+ mtk_phy_link_adjust, 0, phy_mode);
+- if (IS_ERR(phydev)) {
++ if (!phydev) {
+ dev_err(eth->dev, "could not connect to PHY\n");
+- return PTR_ERR(phydev);
++ return -ENODEV;
+ }
+
+ dev_info(eth->dev,
+--
+1.7.10.4
+
diff --git a/target/linux/mediatek/patches-4.4/0053-net-mediatek-unlock-on-error-in-mtk_tx_map.patch b/target/linux/mediatek/patches-4.4/0053-net-mediatek-unlock-on-error-in-mtk_tx_map.patch
new file mode 100644
index 0000000..89ad003
--- /dev/null
+++ b/target/linux/mediatek/patches-4.4/0053-net-mediatek-unlock-on-error-in-mtk_tx_map.patch
@@ -0,0 +1,29 @@
+From a2559aaca7c4a9b80699147390efda51df20ac96 Mon Sep 17 00:00:00 2001
+From: Dan Carpenter <dan.carpenter@oracle.com>
+Date: Tue, 15 Mar 2016 10:19:04 +0300
+Subject: [PATCH 53/66] net: mediatek: unlock on error in mtk_tx_map()
+
+There was a missing unlock on the error path.
+
+Fixes: 656e705243fd ('net-next: mediatek: add support for MT7623 ethernet')
+Signed-off-by: Dan Carpenter <dan.carpenter@oracle.com>
+---
+ drivers/net/ethernet/mediatek/mtk_eth_soc.c | 2 ++
+ 1 file changed, 2 insertions(+)
+
+diff --git a/drivers/net/ethernet/mediatek/mtk_eth_soc.c b/drivers/net/ethernet/mediatek/mtk_eth_soc.c
+index 9759fe5..c2c2e206 100644
+--- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c
++++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c
+@@ -661,6 +661,8 @@ err_dma:
+ itxd = mtk_qdma_phys_to_virt(ring, itxd->txd2);
+ } while (itxd != txd);
+
++ spin_unlock_irqrestore(&eth->page_lock, flags);
++
+ return -ENOMEM;
+ }
+
+--
+1.7.10.4
+
diff --git a/target/linux/mediatek/patches-4.4/0054-net-mediatek-use-dma_addr_t-correctly.patch b/target/linux/mediatek/patches-4.4/0054-net-mediatek-use-dma_addr_t-correctly.patch
new file mode 100644
index 0000000..d00d9b6
--- /dev/null
+++ b/target/linux/mediatek/patches-4.4/0054-net-mediatek-use-dma_addr_t-correctly.patch
@@ -0,0 +1,35 @@
+From ca4d9b6f3476e18e3136e488debdb35cd402d8d3 Mon Sep 17 00:00:00 2001
+From: Arnd Bergmann <arnd@arndb.de>
+Date: Mon, 14 Mar 2016 15:07:10 +0100
+Subject: [PATCH 54/66] net: mediatek: use dma_addr_t correctly
+
+dma_alloc_coherent() expects a dma_addr_t pointer as its argument,
+not an 'unsigned int', and gcc correctly warns about broken
+code in the mtk_init_fq_dma function:
+
+drivers/net/ethernet/mediatek/mtk_eth_soc.c: In function 'mtk_init_fq_dma':
+drivers/net/ethernet/mediatek/mtk_eth_soc.c:463:13: error: passing argument 3 of 'dma_alloc_coherent' from incompatible pointer type [-Werror=incompatible-pointer-types]
+
+This changes the type of the local variable to dma_addr_t.
+
+Signed-off-by: Arnd Bergmann <arnd@arndb.de>
+---
+ drivers/net/ethernet/mediatek/mtk_eth_soc.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/net/ethernet/mediatek/mtk_eth_soc.c b/drivers/net/ethernet/mediatek/mtk_eth_soc.c
+index c2c2e206..a005bc4 100644
+--- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c
++++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c
+@@ -453,7 +453,7 @@ static inline void mtk_rx_get_desc(struct mtk_rx_dma *rxd,
+ /* the qdma core needs scratch memory to be setup */
+ static int mtk_init_fq_dma(struct mtk_eth *eth)
+ {
+- unsigned int phy_ring_head, phy_ring_tail;
++ dma_addr_t phy_ring_head, phy_ring_tail;
+ int cnt = MTK_DMA_SIZE;
+ dma_addr_t dma_addr;
+ int i;
+--
+1.7.10.4
+
diff --git a/target/linux/mediatek/patches-4.4/0055-net-mediatek-remove-incorrect-dma_mask-assignment.patch b/target/linux/mediatek/patches-4.4/0055-net-mediatek-remove-incorrect-dma_mask-assignment.patch
new file mode 100644
index 0000000..4bf0947
--- /dev/null
+++ b/target/linux/mediatek/patches-4.4/0055-net-mediatek-remove-incorrect-dma_mask-assignment.patch
@@ -0,0 +1,36 @@
+From 9d602a7040c0fe9c81f2beffb3c277442a6d9ea2 Mon Sep 17 00:00:00 2001
+From: Arnd Bergmann <arnd@arndb.de>
+Date: Mon, 14 Mar 2016 15:07:11 +0100
+Subject: [PATCH 55/66] net: mediatek: remove incorrect dma_mask assignment
+
+Device drivers should not mess with the DMA mask directly,
+but instead call dma_set_mask() etc if needed.
+
+In case of the mtk_eth_soc driver, the mask already gets set
+correctly when the device is created, and setting it again
+is against the documented API.
+
+This removes the incorrect setting.
+
+Signed-off-by: Arnd Bergmann <arnd@arndb.de>
+---
+ drivers/net/ethernet/mediatek/mtk_eth_soc.c | 3 ---
+ 1 file changed, 3 deletions(-)
+
+diff --git a/drivers/net/ethernet/mediatek/mtk_eth_soc.c b/drivers/net/ethernet/mediatek/mtk_eth_soc.c
+index a005bc4..fcd4ed7 100644
+--- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c
++++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c
+@@ -1678,9 +1678,6 @@ static int mtk_probe(struct platform_device *pdev)
+ struct mtk_eth *eth;
+ int err;
+
+- pdev->dev.coherent_dma_mask = DMA_BIT_MASK(32);
+- pdev->dev.dma_mask = &pdev->dev.coherent_dma_mask;
+-
+ device_reset(&pdev->dev);
+
+ match = of_match_device(of_mtk_match, &pdev->dev);
+--
+1.7.10.4
+
diff --git a/target/linux/mediatek/patches-4.4/0056-net-mediatek-check-device_reset-return-code.patch b/target/linux/mediatek/patches-4.4/0056-net-mediatek-check-device_reset-return-code.patch
new file mode 100644
index 0000000..00e5c8b
--- /dev/null
+++ b/target/linux/mediatek/patches-4.4/0056-net-mediatek-check-device_reset-return-code.patch
@@ -0,0 +1,38 @@
+From b461f1a8dfcf32f289a559b6eba4e784b37d121c Mon Sep 17 00:00:00 2001
+From: Arnd Bergmann <arnd@arndb.de>
+Date: Mon, 14 Mar 2016 15:07:12 +0100
+Subject: [PATCH 56/66] net: mediatek: check device_reset return code
+
+The device_reset() function may fail, so we have to check
+its return value, e.g. to make deferred probing work correctly.
+gcc warns about it because of the warn_unused_result attribute:
+
+drivers/net/ethernet/mediatek/mtk_eth_soc.c: In function 'mtk_probe':
+drivers/net/ethernet/mediatek/mtk_eth_soc.c:1679:2: error: ignoring return value of 'device_reset', declared with attribute warn_unused_result [-Werror=unused-result]
+
+This adds the trivial error check to propagate the return value
+to the generic platform device probe code.
+
+Signed-off-by: Arnd Bergmann <arnd@arndb.de>
+---
+ drivers/net/ethernet/mediatek/mtk_eth_soc.c | 4 +++-
+ 1 file changed, 3 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/net/ethernet/mediatek/mtk_eth_soc.c b/drivers/net/ethernet/mediatek/mtk_eth_soc.c
+index fcd4ed7..7f2126b 100644
+--- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c
++++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c
+@@ -1678,7 +1678,9 @@ static int mtk_probe(struct platform_device *pdev)
+ struct mtk_eth *eth;
+ int err;
+
+- device_reset(&pdev->dev);
++ err = device_reset(&pdev->dev);
++ if (err)
++ return err;
+
+ match = of_match_device(of_mtk_match, &pdev->dev);
+ soc = (struct mtk_soc_data *)match->data;
+--
+1.7.10.4
+
diff --git a/target/linux/mediatek/patches-4.4/0052-net-out-of-tree-fixes.patch b/target/linux/mediatek/patches-4.4/0057-net-mediatek-out-of-tree-fixes.patch
index 10d9d71..1e78d49 100644
--- a/target/linux/mediatek/patches-4.4/0052-net-out-of-tree-fixes.patch
+++ b/target/linux/mediatek/patches-4.4/0057-net-mediatek-out-of-tree-fixes.patch
@@ -1,7 +1,7 @@
-From 242801fc94db9ceb1e3e2a8b19fb2c57122e53f3 Mon Sep 17 00:00:00 2001
+From cee958b55f35f953481c2ddf9609dbd018ef5979 Mon Sep 17 00:00:00 2001
From: John Crispin <blogic@openwrt.org>
Date: Mon, 21 Mar 2016 16:36:22 +0100
-Subject: [PATCH] net: out of tree fixes
+Subject: [PATCH 57/66] net: mediatek: out of tree fixes
Signed-off-by: John Crispin <blogic@openwrt.org>
---
@@ -9,13 +9,12 @@ Signed-off-by: John Crispin <blogic@openwrt.org>
arch/arm/boot/dts/mt7623.dtsi | 40 +-
drivers/net/ethernet/mediatek/Makefile | 2 +-
drivers/net/ethernet/mediatek/gsw_mt7620.h | 250 +++++++
- drivers/net/ethernet/mediatek/gsw_mt7623.c | 966 +++++++++++++++++++++++++++
- drivers/net/ethernet/mediatek/mt7530.c | 808 ++++++++++++++++++++++
+ drivers/net/ethernet/mediatek/gsw_mt7623.c | 1058 +++++++++++++++++++++++++++
+ drivers/net/ethernet/mediatek/mt7530.c | 808 ++++++++++++++++++++
drivers/net/ethernet/mediatek/mt7530.h | 20 +
- drivers/net/ethernet/mediatek/mtk_eth_soc.c | 59 +-
+ drivers/net/ethernet/mediatek/mtk_eth_soc.c | 41 +-
drivers/net/ethernet/mediatek/mtk_eth_soc.h | 5 +
- lib/dynamic_queue_limits.c | 6 +-
- 10 files changed, 2110 insertions(+), 47 deletions(-)
+ 9 files changed, 2202 insertions(+), 23 deletions(-)
create mode 100644 drivers/net/ethernet/mediatek/gsw_mt7620.h
create mode 100644 drivers/net/ethernet/mediatek/gsw_mt7623.c
create mode 100644 drivers/net/ethernet/mediatek/mt7530.c
@@ -34,10 +33,10 @@ index 5e9381d..bc2b3f1 100644
};
diff --git a/arch/arm/boot/dts/mt7623.dtsi b/arch/arm/boot/dts/mt7623.dtsi
-index 1ba7790..5926e14 100644
+index ec19283..0c65045 100644
--- a/arch/arm/boot/dts/mt7623.dtsi
+++ b/arch/arm/boot/dts/mt7623.dtsi
-@@ -440,23 +440,30 @@
+@@ -452,23 +452,30 @@
};
ethsys: syscon@1b000000 {
@@ -73,7 +72,7 @@ index 1ba7790..5926e14 100644
mediatek,switch = <&gsw>;
#address-cells = <1>;
-@@ -468,6 +475,8 @@
+@@ -480,6 +487,8 @@
compatible = "mediatek,eth-mac";
reg = <0>;
@@ -82,7 +81,7 @@ index 1ba7790..5926e14 100644
status = "disabled";
};
-@@ -475,6 +484,7 @@
+@@ -487,6 +496,7 @@
compatible = "mediatek,eth-mac";
reg = <1>;
@@ -90,7 +89,7 @@ index 1ba7790..5926e14 100644
status = "disabled";
};
-@@ -482,6 +492,16 @@
+@@ -494,6 +504,16 @@
#address-cells = <1>;
#size-cells = <0>;
@@ -107,7 +106,7 @@ index 1ba7790..5926e14 100644
phy1f: ethernet-phy@1f {
reg = <0x1f>;
phy-mode = "rgmii";
-@@ -491,14 +511,12 @@
+@@ -503,14 +523,12 @@
gsw: switch@1b100000 {
compatible = "mediatek,mt7623-gsw";
@@ -394,10 +393,10 @@ index 0000000..7013803
+#endif
diff --git a/drivers/net/ethernet/mediatek/gsw_mt7623.c b/drivers/net/ethernet/mediatek/gsw_mt7623.c
new file mode 100644
-index 0000000..78c36c7
+index 0000000..4e486af
--- /dev/null
+++ b/drivers/net/ethernet/mediatek/gsw_mt7623.c
-@@ -0,0 +1,966 @@
+@@ -0,0 +1,1058 @@
+/* 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
@@ -438,6 +437,9 @@ index 0000000..78c36c7
+#include "gsw_mt7620.h"
+#include "mt7530.h"
+
++#define ETHSYS_CLKCFG0 0x2c
++#define ETHSYS_TRGMII_CLK_SEL362_5 BIT(11)
++
+void mt7530_mdio_w32(struct mt7620_gsw *gsw, u32 reg, u32 val)
+{
+ _mtk_mdio_write(gsw->eth, 0x1f, 0x1f, (reg >> 6) & 0x3ff);
@@ -485,29 +487,39 @@ index 0000000..78c36c7
+ mtk_switch_w32(gsw, val, reg);
+}
+
++int mt7623_gsw_config(struct mtk_eth *eth)
++{
++ if (eth->mii_bus && eth->mii_bus->phy_map[0x1f])
++ mt7530_probe(eth->dev, NULL, eth->mii_bus, 1);
++
++ return 0;
++}
++
+static irqreturn_t gsw_interrupt_mt7623(int irq, void *_eth)
+{
+ struct mtk_eth *eth = (struct mtk_eth *)_eth;
+ struct mt7620_gsw *gsw = (struct mt7620_gsw *)eth->sw_priv;
+ u32 reg, i;
+
-+ reg = mt7530_mdio_r32(gsw, MT7530_SYS_INT_STS);
++ reg = mt7530_mdio_r32(gsw, 0x700c);
+
-+ for (i = 0; i < 5; i++) {
-+ unsigned int link;
-+
-+ if ((reg & BIT(i)) == 0)
-+ continue;
++ for (i = 0; i < 5; i++)
++ if (reg & BIT(i)) {
++ unsigned int link;
+
-+ link = mt7530_mdio_r32(gsw, MT7530_PMSR_P(i)) & 0x1;
++ link = mt7530_mdio_r32(gsw,
++ 0x3008 + (i * 0x100)) & 0x1;
+
-+ if (link)
-+ dev_info(gsw->dev, "port %d link up\n", i);
-+ else
-+ dev_info(gsw->dev, "port %d link down\n", i);
-+ }
++ if (link)
++ dev_info(gsw->dev,
++ "port %d link up\n", i);
++ else
++ dev_info(gsw->dev,
++ "port %d link down\n", i);
++ }
+
-+ mt7530_mdio_w32(gsw, MT7530_SYS_INT_STS, 0x1f);
++// mt7620_handle_carrier(eth);
++ mt7530_mdio_w32(gsw, 0x700c, 0x1f);
+
+ return IRQ_HANDLED;
+}
@@ -521,14 +533,6 @@ index 0000000..78c36c7
+ read_data = mtk_switch_r32(gsw, 0x610);
+}
+
-+int mt7623_gsw_config(struct mtk_eth *eth)
-+{
-+ if (eth->mii_bus && eth->mii_bus->phy_map[0x1f])
-+ mt7530_probe(eth->dev, NULL, eth->mii_bus, 1);
-+
-+ return 0;
-+}
-+
+static void trgmii_calibration_7623(struct mt7620_gsw *gsw)
+{
+
@@ -579,16 +583,18 @@ index 0000000..78c36c7
+ for (i = 0; i < 5; i++)
+ mtk_switch_m32(gsw, 0, 0x80000000, TRGMII_7623_RD_0 + i * 8);
+
-+ /* Enable Training Mode in MT7530 */
-+ mt7530_mdio_m32(gsw, 0, 0xC0000000, 0x7A40);
-+
-+ /* Adjust RXC delay in MT7623 */
-+ read_data = 0x0;
++ pr_err("Enable Training Mode in MT7530\n");
++ read_data = mt7530_mdio_r32(gsw, 0x7A40);
++ read_data |= 0xC0000000;
++ mt7530_mdio_w32(gsw, 0x7A40, read_data); /* Enable Training Mode in MT7530 */
+ err_total_flag = 0;
++ pr_err("Adjust RXC delay in MT7623\n");
++ read_data = 0x0;
+ while (err_total_flag == 0 && read_data != 0x68) {
++ pr_err("2nd Enable EDGE CHK in MT7623\n");
+ /* Enable EDGE CHK in MT7623 */
+ for (i = 0; i < 5; i++)
-+ mtk_switch_m32(gsw, 0x4fffffff, 0x40000000, TRGMII_7623_RD_0 + i * 8);
++ mtk_switch_m32(gsw, 0x4fffffff, 0x40000000, TRGMII_7623_RD_0 + i * 8);
+
+ wait_loop(gsw);
+ err_total_flag = 1;
@@ -749,6 +755,7 @@ index 0000000..78c36c7
+ u32 TRGMII_RCK_CTRL;
+ u32 TRGMII_7530_base;
+ u32 TRGMII_7530_TX_base;
++ u32 val;
+
+ TRGMII_7623_base = 0x300;
+ TRGMII_7530_base = 0x7A00;
@@ -761,81 +768,113 @@ index 0000000..78c36c7
+
+ TRGMII_7530_TX_base = TRGMII_7530_base + 0x50;
+
-+ /* Calibration begin */
-+ mtk_switch_m32(gsw, 0, 0x80000000, TRGMII_7623_base + 0x40);
-+
-+ /* RX clock gating in MT7530 */
-+ mt7530_mdio_m32(gsw, 0x3fffffff, 0, TRGMII_7530_base + 0x04);
-+
-+ /* Set TX OE edge in MT7530 */
-+ mt7530_mdio_m32(gsw, 0, 0x2000, TRGMII_7530_base + 0x78);
++ /* pr_err("Calibration begin ........\n"); */
++ val = mtk_switch_r32(gsw, TRGMII_7623_base + 0x40) | 0x80000000;
++ mtk_switch_w32(gsw, val, TRGMII_7623_base + 0x40);
++ read_data = mt7530_mdio_r32(gsw, 0x7a10);
++ /* pr_err("TRGMII_7530_RD_0 is %x\n", read_data); */
+
-+ /* Assert RX reset in MT7530 */
-+ mt7530_mdio_m32(gsw, 0, 0x80000000, TRGMII_7530_base);
-+
-+ /* Release RX reset in MT7530 */
-+ mt7530_mdio_m32(gsw, 0x7fffffff, 0, TRGMII_7530_base);
-+
-+ /* Disable RX clock gating in MT7530 */
-+ mt7530_mdio_m32(gsw, 0, 0xC0000000, TRGMII_7530_base + 0x04);
-+
-+ /* Enable Training Mode in MT7623 */
-+ mtk_switch_m32(gsw, 0, 0x80000000, TRGMII_7623_base + 0x40);
-+ if (gsw->trgmii_force == 2000)
-+ mtk_switch_m32(gsw, 0, 0xC0000000, TRGMII_7623_base + 0x40);
-+ else
-+ mtk_switch_m32(gsw, 0, 0x80000000, TRGMII_7623_base + 0x40);
-+ mtk_switch_m32(gsw, 0xfffff0ff, 0, TRGMII_7623_base + 0x078);
-+ mtk_switch_m32(gsw, 0xfffff0ff, 0, TRGMII_7623_base + 0x50);
-+ mtk_switch_m32(gsw, 0xfffff0ff, 0, TRGMII_7623_base + 0x58);
-+ mtk_switch_m32(gsw, 0xfffff0ff, 0, TRGMII_7623_base + 0x60);
-+ mtk_switch_m32(gsw, 0xfffff0ff, 0, TRGMII_7623_base + 0x68);
-+ mtk_switch_m32(gsw, 0xfffff0ff, 0, TRGMII_7623_base + 0x70);
-+ mtk_switch_m32(gsw, 0x00000800, 0, TRGMII_7623_base + 0x78);
-+
-+ /* Adjust RXC delay in MT7530 */
++ read_data = mt7530_mdio_r32(gsw, TRGMII_7530_base + 0x04);
++ read_data &= 0x3fffffff;
++ mt7530_mdio_w32(gsw, TRGMII_7530_base + 0x04, read_data); /* RX clock gating in MT7530 */
++
++ read_data = mt7530_mdio_r32(gsw, TRGMII_7530_base + 0x78);
++ read_data |= 0x00002000;
++ mt7530_mdio_w32(gsw, TRGMII_7530_base + 0x78, read_data); /* Set TX OE edge in MT7530 */
++
++ read_data = mt7530_mdio_r32(gsw, TRGMII_7530_base);
++ read_data |= 0x80000000;
++ mt7530_mdio_w32(gsw, TRGMII_7530_base, read_data); /* Assert RX reset in MT7530 */
++
++ read_data = mt7530_mdio_r32(gsw, TRGMII_7530_base);
++ read_data &= 0x7fffffff;
++ mt7530_mdio_w32(gsw, TRGMII_7530_base, read_data); /* Release RX reset in MT7530 */
++
++ read_data = mt7530_mdio_r32(gsw, TRGMII_7530_base + 0x04);
++ read_data |= 0xC0000000;
++ mt7530_mdio_w32(gsw, TRGMII_7530_base + 0x04, read_data); /* Disable RX clock gating in MT7530 */
++
++ /* pr_err("Enable Training Mode in MT7623\n"); */
++ /*Enable Training Mode in MT7623 */
++ val = mtk_switch_r32(gsw, TRGMII_7623_base + 0x40) | 0x80000000;
++ mtk_switch_w32(gsw, val, TRGMII_7623_base + 0x40);
++ if (gsw->trgmii_force == 2000) {
++ val = mtk_switch_r32(gsw, TRGMII_7623_base + 0x40) | 0xC0000000;
++ mtk_switch_w32(gsw, val, TRGMII_7623_base + 0x40);
++ } else {
++ val = mtk_switch_r32(gsw, TRGMII_7623_base + 0x40) | 0x80000000;
++ mtk_switch_w32(gsw, val, TRGMII_7623_base + 0x40);
++ }
++ val = mtk_switch_r32(gsw, TRGMII_7623_base + 0x078) & 0xfffff0ff;
++ mtk_switch_w32(gsw, val, TRGMII_7623_base + 0x078);
++ val = mtk_switch_r32(gsw, TRGMII_7623_base + 0x50) & 0xfffff0ff;
++ mtk_switch_w32(gsw, val, TRGMII_7623_base + 0x50);
++ val = mtk_switch_r32(gsw, TRGMII_7623_base + 0x58) & 0xfffff0ff;
++ mtk_switch_w32(gsw, val, TRGMII_7623_base + 0x58);
++ val = mtk_switch_r32(gsw, TRGMII_7623_base + 0x60) & 0xfffff0ff;
++ mtk_switch_w32(gsw, val, TRGMII_7623_base + 0x60);
++ val = mtk_switch_r32(gsw, TRGMII_7623_base + 0x68) & 0xfffff0ff;
++ mtk_switch_w32(gsw, val, TRGMII_7623_base + 0x68);
++ val = mtk_switch_r32(gsw, TRGMII_7623_base + 0x70) & 0xfffff0ff;
++ mtk_switch_w32(gsw, val, TRGMII_7623_base + 0x70);
++ val = mtk_switch_r32(gsw, TRGMII_7623_base + 0x78) & 0x00000800;
++ mtk_switch_w32(gsw, val, TRGMII_7623_base + 0x78);
+ err_total_flag = 0;
++ /* pr_err("Adjust RXC delay in MT7530\n"); */
+ read_data = 0x0;
+ while (err_total_flag == 0 && (read_data != 0x68)) {
++ /* pr_err("2nd Enable EDGE CHK in MT7530\n"); */
+ /* Enable EDGE CHK in MT7530 */
+ for (i = 0; i < 5; i++) {
-+ mt7530_mdio_m32(gsw, 0x4fffffff, 0x40000000,
-+ TRGMII_7530_RD_0 + i * 8);
++ read_data =
++ mt7530_mdio_r32(gsw, TRGMII_7530_RD_0 + i * 8);
++ read_data |= 0x40000000;
++ read_data &= 0x4fffffff;
++ mt7530_mdio_w32(gsw, TRGMII_7530_RD_0 + i * 8,
++ read_data);
+ wait_loop(gsw);
-+
-+ /* 2nd Disable EDGE CHK in MT7530 */
-+ err_cnt[i] = mt7530_mdio_r32(gsw, TRGMII_7530_RD_0 + i * 8);
++ /* pr_err("2nd Disable EDGE CHK in MT7530\n"); */
++ err_cnt[i] =
++ mt7530_mdio_r32(gsw, TRGMII_7530_RD_0 + i * 8);
++ /* pr_err("***** MT7530 %dth bit ERR_CNT =%x\n",i, err_cnt[i]); */
++ /* pr_err("MT7530 %dth bit ERR_CNT =%x\n",i, err_cnt[i]); */
+ err_cnt[i] >>= 8;
+ err_cnt[i] &= 0x0000ff0f;
-+
+ rd_wd = err_cnt[i] >> 8;
+ rd_wd &= 0x000000ff;
-+
+ err_cnt[i] &= 0x0000000f;
-+ if (err_cnt[i] != 0)
++ /* read_data = mt7530_mdio_r32(gsw,0x7a10,&read_data); */
++ if (err_cnt[i] != 0) {
+ err_flag[i] = 1;
-+ else if (rd_wd != 0x55)
++ } else if (rd_wd != 0x55) {
+ err_flag[i] = 1;
-+ else
++ } else {
+ err_flag[i] = 0;
-+ if (i == 0)
++ }
++ if (i == 0) {
+ err_total_flag = err_flag[i];
-+ else
++ } else {
+ err_total_flag = err_flag[i] & err_total_flag;
-+
++ }
+ /* Disable EDGE CHK in MT7530 */
-+ mt7530_mdio_m32(gsw, 0x4fffffff, 0x40000000,
-+ TRGMII_7530_RD_0 + i * 8);
++ read_data =
++ mt7530_mdio_r32(gsw, TRGMII_7530_RD_0 + i * 8);
++ read_data |= 0x40000000;
++ read_data &= 0x4fffffff;
++ mt7530_mdio_w32(gsw, TRGMII_7530_RD_0 + i * 8,
++ read_data);
+ wait_loop(gsw);
+ }
-+
-+ /* Adjust RXC delay */
++ /*Adjust RXC delay */
+ if (err_total_flag == 0) {
-+ /* Assert RX reset in MT7530 */
-+ mt7530_mdio_m32(gsw, 0, 0x80000000, TRGMII_7530_base);
++ read_data = mt7530_mdio_r32(gsw, TRGMII_7530_base);
++ read_data |= 0x80000000;
++ mt7530_mdio_w32(gsw, TRGMII_7530_base, read_data); /* Assert RX reset in MT7530 */
+
-+ /* RX clock gating in MT7530 */
-+ mt7530_mdio_m32(gsw, 0x3fffffff, 0, TRGMII_7530_base + 0x04);
++ read_data =
++ mt7530_mdio_r32(gsw, TRGMII_7530_base + 0x04);
++ read_data &= 0x3fffffff;
++ mt7530_mdio_w32(gsw, TRGMII_7530_base + 0x04, read_data); /* RX clock gating in MT7530 */
+
+ read_data = mt7530_mdio_r32(gsw, TRGMII_7530_base);
+ tmp = read_data;
@@ -945,7 +984,9 @@ index 0000000..78c36c7
+ }
+ tap_b[i] = rd_tap; /* - rxd_step_size; */
+ pr_err("MT7530 %dth bit Tap_b = %d\n", i, tap_b[i]);
++ /* Calculate RXD delay = (TAP_A + TAP_B)/2 */
+ final_tap[i] = (tap_a[i] + tap_b[i]) / 2;
++ /* pr_err("########****** MT7530 %dth bit Final Tap = %d\n", i, final_tap[i]); */
+
+ read_data = (read_data & 0xffffff80) | final_tap[i];
+ mt7530_mdio_w32(gsw, TRGMII_7530_RD_0 + i * 8, read_data);
@@ -960,6 +1001,9 @@ index 0000000..78c36c7
+
+static void mt7530_trgmii_clock_setting(struct mt7620_gsw *gsw, u32 xtal_mode)
+{
++
++ u32 regValue;
++
+ /* TRGMII Clock */
+ _mtk_mdio_write(gsw->eth, 0, 13, 0x1f);
+ _mtk_mdio_write(gsw->eth, 0, 14, 0x410);
@@ -1034,14 +1078,26 @@ index 0000000..78c36c7
+ _mtk_mdio_write(gsw->eth, 0, 13, 0x401f);
+ _mtk_mdio_write(gsw->eth, 0, 14, 0xa038);
+
++// udelay(120); /* for MT7623 bring up test */
++
+ _mtk_mdio_write(gsw->eth, 0, 13, 0x1f);
+ _mtk_mdio_write(gsw->eth, 0, 14, 0x410);
+ _mtk_mdio_write(gsw->eth, 0, 13, 0x401f);
+ _mtk_mdio_write(gsw->eth, 0, 14, 0x3);
+
-+ mt7530_mdio_m32(gsw, 0xfffffffc, 0x1, 0x7830);
-+ mt7530_mdio_m32(gsw, 0xcfffffff, 0, 0x7a40);
++ regValue = mt7530_mdio_r32(gsw, 0x7830);
++ regValue &= 0xFFFFFFFC;
++ regValue |= 0x00000001;
++ mt7530_mdio_w32(gsw, 0x7830, regValue);
++
++ regValue = mt7530_mdio_r32(gsw, 0x7a40);
++ regValue &= ~(0x1 << 30);
++ regValue &= ~(0x1 << 28);
++ mt7530_mdio_w32(gsw, 0x7a40, regValue);
++
+ mt7530_mdio_w32(gsw, 0x7a78, 0x55);
++// udelay(100); /* for mt7623 bring up test */
++
+ mtk_switch_m32(gsw, 0x7fffffff, 0, 0x300);
+
+ trgmii_calibration_7623(gsw);
@@ -1050,20 +1106,21 @@ index 0000000..78c36c7
+ mtk_switch_m32(gsw, 0, 0x80000000, 0x300);
+ mtk_switch_m32(gsw, 0, 0x7fffffff, 0x300);
+
-+ /* MT7530 RXC reset */
-+ mt7530_mdio_m32(gsw, 0, BIT(31), 0x7a00);
++ /*MT7530 RXC reset */
++ regValue = mt7530_mdio_r32(gsw, 0x7a00);
++ regValue |= (0x1 << 31);
++ mt7530_mdio_w32(gsw, 0x7a00, regValue);
+ mdelay(1);
-+
-+ mt7530_mdio_m32(gsw, ~BIT(31), 0, 0x7a00);
++ regValue &= ~(0x1 << 31);
++ mt7530_mdio_w32(gsw, 0x7a00, regValue);
+ mdelay(100);
+}
+
-+static void mt7623_hw_init(struct mtk_eth *eth, struct mt7620_gsw *gsw,
-+ struct device_node *np)
++static void mt7623_hw_init(struct mtk_eth *eth, struct mt7620_gsw *gsw, struct device_node *np)
+{
-+ u32 i;
-+ u32 val;
-+ u32 xtal_mode;
++ u32 i;
++ u32 val;
++ u32 xtal_mode;
+
+ regmap_update_bits(gsw->ethsys, ETHSYS_CLKCFG0,
+ ETHSYS_TRGMII_CLK_SEL362_5,
@@ -1074,8 +1131,7 @@ index 0000000..78c36c7
+ mtk_switch_m32(gsw, 0, TRGMII_RCK_CTRL_RX_RST, GSW_TRGMII_RCK_CTRL);
+
+ /* Hardware reset Switch */
-+ //device_reset(eth->dev);
-+ printk("%s:%s[%d]reset_switch\n", __FILE__, __func__, __LINE__);
++ device_reset(eth->dev);
+
+ /* Wait for Switch Reset Completed*/
+ for (i = 0; i < 100; i++) {
@@ -1118,10 +1174,16 @@ index 0000000..78c36c7
+ val |= MHWTRAP_MANUAL;
+ mt7530_mdio_w32(gsw, MT7530_MHWTRAP, val);
+
-+ xtal_mode = mt7530_mdio_r32(gsw, MT7530_HWTRAP);
-+ xtal_mode >>= HWTRAP_XTAL_SHIFT;
-+ xtal_mode &= HWTRAP_XTAL_MASK;
-+ if (xtal_mode == MT7623_XTAL_40) {
++ val = mt7530_mdio_r32(gsw, 0x7800);
++ val = (val >> 9) & 0x3;
++ pr_err("!!%s: Mhz value= %d\n", __func__, val);
++ if (val == 0x3) {
++ xtal_mode = 1;
++ /* 25Mhz Xtal - do nothing */
++ } else if (val == 0x2) {
++ /* 40Mhz */
++ xtal_mode = 2;
++
+ /* disable MT7530 core clock */
+ _mtk_mdio_write(gsw->eth, 0, 13, 0x1f);
+ _mtk_mdio_write(gsw->eth, 0, 14, 0x410);
@@ -1152,38 +1214,58 @@ index 0000000..78c36c7
+ _mtk_mdio_write(gsw->eth, 0, 13, 0x1f);
+ _mtk_mdio_write(gsw->eth, 0, 14, 0x410);
+ _mtk_mdio_write(gsw->eth, 0, 13, 0x401f);
++ } else {
++ xtal_mode = 3;
++ /* 20Mhz Xtal - TODO */
+ }
+
+ /* RGMII */
+ _mtk_mdio_write(gsw->eth, 0, 14, 0x1);
+
+ /* set MT7530 central align */
-+ mt7530_mdio_m32(gsw, ~BIT(0), BIT(1), MT7530_P6ECR);
-+ mt7530_mdio_m32(gsw, ~BIT(30), 0, MT7530_TRGMII_TXCTRL);
-+ mt7530_mdio_w32(gsw, MT7530_TRGMII_TCK_CTRL, 0x855);
++ val = mt7530_mdio_r32(gsw, 0x7830);
++ val &= ~1;
++ val |= 1<<1;
++ mt7530_mdio_w32(gsw, 0x7830, val);
++
++ val = mt7530_mdio_r32(gsw, 0x7a40);
++ val &= ~(1<<30);
++ mt7530_mdio_w32(gsw, 0x7a40, val);
++
++ mt7530_mdio_w32(gsw, 0x7a78, 0x855);
+
+ /* delay setting for 10/1000M */
-+ mt7530_mdio_w32(gsw, MT7530_P5RGMIIRXCR, 0x104);
-+ mt7530_mdio_w32(gsw, MT7530_P5RGMIITXCR, 0x10);
++ mt7530_mdio_w32(gsw, 0x7b00, 0x104);
++ mt7530_mdio_w32(gsw, 0x7b04, 0x10);
+
+ /* lower Tx Driving */
-+ mt7530_mdio_w32(gsw, MT7530_TRGMII_TD0_ODT, 0x88);
-+ mt7530_mdio_w32(gsw, MT7530_TRGMII_TD1_ODT, 0x88);
-+ mt7530_mdio_w32(gsw, MT7530_TRGMII_TD2_ODT, 0x88);
-+ mt7530_mdio_w32(gsw, MT7530_TRGMII_TD3_ODT, 0x88);
-+ mt7530_mdio_w32(gsw, MT7530_TRGMII_TD4_ODT, 0x88);
-+ mt7530_mdio_w32(gsw, MT7530_TRGMII_TD5_ODT, 0x88);
-+ mt7530_mdio_w32(gsw, MT7530_IO_DRV_CR, 0x11);
++ mt7530_mdio_w32(gsw, 0x7a54, 0x88);
++ mt7530_mdio_w32(gsw, 0x7a5c, 0x88);
++ mt7530_mdio_w32(gsw, 0x7a64, 0x88);
++ mt7530_mdio_w32(gsw, 0x7a6c, 0x88);
++ mt7530_mdio_w32(gsw, 0x7a74, 0x88);
++ mt7530_mdio_w32(gsw, 0x7a7c, 0x88);
++ mt7530_mdio_w32(gsw, 0x7810, 0x11);
+
+ /* Set MT7623/MT7683 TX Driving */
-+ mtk_switch_w32(gsw, 0x88, GSW_TRGMII_TD0_ODT);
-+ mtk_switch_w32(gsw, 0x88, GSW_TRGMII_TD0_ODT);
-+ mtk_switch_w32(gsw, 0x88, GSW_TRGMII_TD0_ODT);
-+ mtk_switch_w32(gsw, 0x88, GSW_TRGMII_TD0_ODT);
-+ mtk_switch_w32(gsw, 0x88, GSW_TRGMII_TXCTL_ODT);
-+ mtk_switch_w32(gsw, 0x88, GSW_TRGMII_TCK_ODT);
++ mtk_switch_w32(gsw, 0x88, 0x354);
++ mtk_switch_w32(gsw, 0x88, 0x35c);
++ mtk_switch_w32(gsw, 0x88, 0x364);
++ mtk_switch_w32(gsw, 0x88, 0x36c);
++ mtk_switch_w32(gsw, 0x88, 0x374);
++ mtk_switch_w32(gsw, 0x88, 0x37c);
++
++#if defined (CONFIG_GE2_RGMII_AN)
++// *(volatile u_long *)(0xf0005f00) = 0xe00; //Set GE2 driving and slew rate
++#else
++ // *(volatile u_long *)(0xf0005f00) = 0xa00; //Set GE2 driving and slew rate
++#endif
++ // *(volatile u_long *)(0xf00054c0) = 0x5; //set GE2 TDSEL
++ // *(volatile u_long *)(0xf0005ed0) = 0; //set GE2 TUNE
++
++ mt7530_trgmii_clock_setting(gsw, xtal_mode);
+
-+// mt7530_trgmii_clock_setting(gsw, xtal_mode);
++ //LANWANPartition(gsw);
+
+ /* disable EEE */
+ for (i = 0; i <= 4; i++) {
@@ -1217,7 +1299,7 @@ index 0000000..78c36c7
+ /* Disable HW auto downshift*/
+ _mtk_mdio_write(gsw->eth, i, 31, 0x1);
+ val = _mtk_mdio_read(gsw->eth, i, 0x14);
-+ val &= ~BIT(4);
++ val &= ~(1<<4);
+ _mtk_mdio_write(gsw->eth, i, 0x14, val);
+ }
+
@@ -1253,14 +1335,14 @@ index 0000000..78c36c7
+ gsw = platform_get_drvdata(pdev);
+ if (!gsw)
+ return -ENODEV;
-+ eth->sw_priv = gsw;
+ gsw->eth = eth;
++ eth->sw_priv = gsw;
+
+ mt7623_hw_init(eth, gsw, np);
+
+ request_threaded_irq(gsw->irq, gsw_interrupt_mt7623, NULL, 0,
-+ "gsw", eth);
-+ mt7530_mdio_w32(gsw, MT7530_SYS_INT_EN, 0x1f);
++ "gsw", eth);
++ mt7530_mdio_w32(gsw, 0x7008, 0x1f);
+
+ return 0;
+}
@@ -1278,6 +1360,7 @@ index 0000000..78c36c7
+ return -ENOMEM;
+
+ gsw->dev = &pdev->dev;
++ gsw->trgmii_force = 2000;
+ gsw->irq = irq_of_parse_and_map(np, 0);
+ if (gsw->irq < 0)
+ return -EINVAL;
@@ -1303,6 +1386,7 @@ index 0000000..78c36c7
+ return ret;
+
+ gsw->clk_trgpll = devm_clk_get(&pdev->dev, "trgpll");
++
+ if (IS_ERR(gsw->clk_trgpll))
+ return -ENODEV;
+
@@ -1330,6 +1414,13 @@ index 0000000..78c36c7
+ gpio_set_value(reset_pin, 1);
+ mdelay(100);
+
++ /* Set GE2 driving and slew rate */
++ regmap_write(gsw->pctl, 0xF00, 0xa00);
++ /* set GE2 TDSEL */
++ regmap_write(gsw->pctl, 0x4C0, 0x5);
++ /* set GE2 TUNE */
++ regmap_write(gsw->pctl, 0xED0, 0x0);
++
+ platform_set_drvdata(pdev, gsw);
+
+ return 0;
@@ -1342,7 +1433,7 @@ index 0000000..78c36c7
+ clk_disable_unprepare(gsw->clk_trgpll);
+
+ pm_runtime_put_sync(&pdev->dev);
-+ pm_runtime_disable(&pdev->dev);
++ pm_runtime_disable(&pdev->dev);
+
+ platform_set_drvdata(pdev, NULL);
+
@@ -2205,7 +2296,7 @@ index 0000000..1fc8c62
+
+#endif
diff --git a/drivers/net/ethernet/mediatek/mtk_eth_soc.c b/drivers/net/ethernet/mediatek/mtk_eth_soc.c
-index ba3afa5..62058a2 100644
+index 7f2126b..dd7f6e3 100644
--- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c
+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c
@@ -24,6 +24,9 @@
@@ -2227,51 +2318,37 @@ index ba3afa5..62058a2 100644
}
dev_err(eth->dev, "mdio: MDIO timeout\n");
-@@ -132,36 +135,20 @@ static int mtk_mdio_read(struct mii_bus *bus, int phy_addr, int phy_reg)
-
- static void mtk_phy_link_adjust(struct net_device *dev)
- {
-+ return;
-+
- struct mtk_mac *mac = netdev_priv(dev);
- u32 mcr = MAC_MCR_MAX_RX_1536 | MAC_MCR_IPG_CFG |
- MAC_MCR_FORCE_MODE | MAC_MCR_TX_EN |
+@@ -138,6 +141,15 @@ static void mtk_phy_link_adjust(struct net_device *dev)
MAC_MCR_RX_EN | MAC_MCR_BACKOFF_EN |
MAC_MCR_BACKPR_EN;
-- switch (mac->phy_dev->speed) {
-- case SPEED_1000:
-- mcr |= MAC_MCR_SPEED_1000;
-- break;
-- case SPEED_100:
-- mcr |= MAC_MCR_SPEED_100;
-- break;
-- };
--
-- if (mac->phy_dev->link)
-- mcr |= MAC_MCR_FORCE_LINK;
--
-- if (mac->phy_dev->duplex)
-- mcr |= MAC_MCR_FORCE_DPX;
--
-- if (mac->phy_dev->pause)
-- mcr |= MAC_MCR_FORCE_RX_FC | MAC_MCR_FORCE_TX_FC;
--
-+ mcr |= MAC_MCR_SPEED_1000;
-+ mcr |= MAC_MCR_FORCE_LINK;
-+ mcr |= MAC_MCR_FORCE_DPX;
-+ mcr |= MAC_MCR_FORCE_RX_FC | MAC_MCR_FORCE_TX_FC;
++ if (!mac->id) {
++ mcr |= MAC_MCR_SPEED_1000;
++ mcr |= MAC_MCR_FORCE_LINK;
++ mcr |= MAC_MCR_FORCE_DPX;
++ mcr |= MAC_MCR_FORCE_RX_FC | MAC_MCR_FORCE_TX_FC;
++ mtk_w32(mac->hw, mcr, MTK_MAC_MCR(mac->id));
++ return;
++ }
++
+ switch (mac->phy_dev->speed) {
+ case SPEED_1000:
+ mcr |= MAC_MCR_SPEED_1000;
+@@ -157,11 +169,12 @@ static void mtk_phy_link_adjust(struct net_device *dev)
+ mcr |= MAC_MCR_FORCE_RX_FC | MAC_MCR_FORCE_TX_FC;
+
mtk_w32(mac->hw, mcr, MTK_MAC_MCR(mac->id));
-
-- if (mac->phy_dev->link)
-- netif_carrier_on(dev);
-- else
-- netif_carrier_off(dev);
+ if (mac->phy_dev->link)
+ netif_carrier_on(dev);
+ else
+ netif_carrier_off(dev);
++
+ return;
}
static int mtk_phy_connect_node(struct mtk_eth *eth, struct mtk_mac *mac,
-@@ -193,7 +180,7 @@ static int mtk_phy_connect_node(struct mtk_eth *eth, struct mtk_mac *mac,
+@@ -193,7 +206,7 @@ static int mtk_phy_connect_node(struct mtk_eth *eth, struct mtk_mac *mac,
dev_info(eth->dev,
"connected mac %d to PHY at %s [uid=%08x, driver=%s]\n",
@@ -2280,7 +2357,7 @@ index ba3afa5..62058a2 100644
phydev->drv->name);
mac->phy_dev = phydev;
-@@ -634,7 +621,6 @@ static int mtk_tx_map(struct sk_buff *skb, struct net_device *dev,
+@@ -634,7 +647,6 @@ static int mtk_tx_map(struct sk_buff *skb, struct net_device *dev,
spin_unlock_irqrestore(&eth->page_lock, flags);
@@ -2288,7 +2365,7 @@ index ba3afa5..62058a2 100644
skb_tx_timestamp(skb);
ring->next_free = mtk_qdma_phys_to_virt(ring, txd->txd2);
-@@ -882,7 +868,6 @@ static int mtk_poll_tx(struct mtk_eth *eth, int budget, bool *tx_again)
+@@ -884,7 +896,6 @@ static int mtk_poll_tx(struct mtk_eth *eth, int budget, bool *tx_again)
for (i = 0; i < MTK_MAC_COUNT; i++) {
if (!eth->netdev[i] || !done[i])
continue;
@@ -2296,7 +2373,7 @@ index ba3afa5..62058a2 100644
total += done[i];
}
-@@ -1249,6 +1234,8 @@ static int mtk_open(struct net_device *dev)
+@@ -1251,6 +1262,8 @@ static int mtk_open(struct net_device *dev)
phy_start(mac->phy_dev);
netif_start_queue(dev);
@@ -2305,7 +2382,7 @@ index ba3afa5..62058a2 100644
return 0;
}
-@@ -1281,6 +1268,7 @@ static int mtk_stop(struct net_device *dev)
+@@ -1283,6 +1296,7 @@ static int mtk_stop(struct net_device *dev)
struct mtk_mac *mac = netdev_priv(dev);
struct mtk_eth *eth = mac->hw;
@@ -2313,7 +2390,7 @@ index ba3afa5..62058a2 100644
netif_tx_disable(dev);
phy_stop(mac->phy_dev);
-@@ -1326,6 +1314,7 @@ static int __init mtk_hw_init(struct mtk_eth *eth)
+@@ -1328,6 +1342,7 @@ static int __init mtk_hw_init(struct mtk_eth *eth)
/* Enable RX VLan Offloading */
mtk_w32(eth, 1, MTK_CDMP_EG_CTRL);
@@ -2321,7 +2398,7 @@ index ba3afa5..62058a2 100644
err = devm_request_irq(eth->dev, eth->irq, mtk_handle_irq, 0,
dev_name(eth->dev), eth);
if (err)
-@@ -1358,6 +1347,8 @@ static int __init mtk_hw_init(struct mtk_eth *eth)
+@@ -1360,6 +1375,8 @@ static int __init mtk_hw_init(struct mtk_eth *eth)
mtk_w32(eth, val, MTK_GDMA_FWD_CFG(i));
}
@@ -2330,7 +2407,7 @@ index ba3afa5..62058a2 100644
return 0;
}
-@@ -1464,11 +1455,13 @@ static int mtk_set_settings(struct net_device *dev,
+@@ -1466,11 +1483,13 @@ static int mtk_set_settings(struct net_device *dev,
{
struct mtk_mac *mac = netdev_priv(dev);
@@ -2348,7 +2425,7 @@ index ba3afa5..62058a2 100644
}
return phy_ethtool_sset(mac->phy_dev, cmd);
-@@ -1561,7 +1554,6 @@ static void mtk_get_ethtool_stats(struct net_device *dev,
+@@ -1563,7 +1582,6 @@ static void mtk_get_ethtool_stats(struct net_device *dev,
data_src = (u64*)hwstats;
data_dst = data;
start = u64_stats_fetch_begin_irq(&hwstats->syncp);
@@ -2356,7 +2433,7 @@ index ba3afa5..62058a2 100644
for (i = 0; i < ARRAY_SIZE(mtk_ethtool_stats); i++)
*data_dst++ = *(data_src + mtk_ethtool_stats[i].offset);
} while (u64_stats_fetch_retry_irq(&hwstats->syncp, start));
-@@ -1733,6 +1725,9 @@ static int mtk_probe(struct platform_device *pdev)
+@@ -1734,6 +1752,9 @@ static int mtk_probe(struct platform_device *pdev)
clk_prepare_enable(eth->clk_gp1);
clk_prepare_enable(eth->clk_gp2);
@@ -2387,23 +2464,6 @@ index 48a5292..d737d61 100644
+int mt7623_gsw_config(struct mtk_eth *eth);
+
#endif /* MTK_ETH_H */
-diff --git a/lib/dynamic_queue_limits.c b/lib/dynamic_queue_limits.c
-index f346715..b04f8e6 100644
---- a/lib/dynamic_queue_limits.c
-+++ b/lib/dynamic_queue_limits.c
-@@ -23,8 +23,10 @@ void dql_completed(struct dql *dql, unsigned int count)
- num_queued = ACCESS_ONCE(dql->num_queued);
-
- /* Can't complete more than what's in queue */
-- BUG_ON(count > num_queued - dql->num_completed);
--
-+ if (count > num_queued - dql->num_completed) {
-+ printk("%s:%s[%d]\n", __FILE__, __func__, __LINE__);
-+ count = 0;
-+ }
- completed = dql->num_completed + count;
- limit = dql->limit;
- ovlimit = POSDIFF(num_queued - dql->num_completed, limit);
--
1.7.10.4
diff --git a/target/linux/mediatek/patches-4.4/0053-dont-disable-clocks.patch b/target/linux/mediatek/patches-4.4/0058-dont-disable-clocks.patch
index 9ec5c89..d91915c 100644
--- a/target/linux/mediatek/patches-4.4/0053-dont-disable-clocks.patch
+++ b/target/linux/mediatek/patches-4.4/0058-dont-disable-clocks.patch
@@ -1,7 +1,7 @@
-From 308cdd2b743a5e01b26d79c8fb89e513dea09856 Mon Sep 17 00:00:00 2001
+From 36875ed8153d9b1eeae676579302a2fc746b286b Mon Sep 17 00:00:00 2001
From: John Crispin <blogic@openwrt.org>
Date: Tue, 23 Jun 2015 23:46:00 +0200
-Subject: [PATCH 53/53] dont disable clocks
+Subject: [PATCH 58/66] dont disable clocks
---
drivers/clk/clk.c | 2 +-
diff --git a/target/linux/mediatek/patches-4.4/0059-mtd-nand-add-an-mtd_to_nand-helper.patch b/target/linux/mediatek/patches-4.4/0059-mtd-nand-add-an-mtd_to_nand-helper.patch
new file mode 100644
index 0000000..636575e
--- /dev/null
+++ b/target/linux/mediatek/patches-4.4/0059-mtd-nand-add-an-mtd_to_nand-helper.patch
@@ -0,0 +1,35 @@
+From 179937ef20beb9d4af4807f3540d4dfc4d48516a Mon Sep 17 00:00:00 2001
+From: Boris BREZILLON <boris.brezillon@free-electrons.com>
+Date: Mon, 16 Nov 2015 14:37:35 +0100
+Subject: [PATCH 59/66] mtd: nand: add an mtd_to_nand() helper
+
+Some drivers are retrieving the nand_chip pointer using the container_of
+macro on a struct wrapping both the nand_chip and the mtd_info struct while
+the standard way of retrieving this pointer is through mtd->priv.
+Provide an helper to do that.
+
+Signed-off-by: Boris Brezillon <boris.brezillon@free-electrons.com>
+Signed-off-by: Brian Norris <computersforpeace@gmail.com>
+---
+ include/linux/mtd/nand.h | 5 +++++
+ 1 file changed, 5 insertions(+)
+
+diff --git a/include/linux/mtd/nand.h b/include/linux/mtd/nand.h
+index 5a9d1d4..a4839b3 100644
+--- a/include/linux/mtd/nand.h
++++ b/include/linux/mtd/nand.h
+@@ -719,6 +719,11 @@ struct nand_chip {
+ void *priv;
+ };
+
++static inline struct nand_chip *mtd_to_nand(struct mtd_info *mtd)
++{
++ return mtd->priv;
++}
++
+ /*
+ * NAND Flash Manufacturer ID Codes
+ */
+--
+1.7.10.4
+
diff --git a/target/linux/mediatek/patches-4.4/0060-mtd-nand-add-nand_to_mtd-helper.patch b/target/linux/mediatek/patches-4.4/0060-mtd-nand-add-nand_to_mtd-helper.patch
new file mode 100644
index 0000000..d68a2fe
--- /dev/null
+++ b/target/linux/mediatek/patches-4.4/0060-mtd-nand-add-nand_to_mtd-helper.patch
@@ -0,0 +1,32 @@
+From 8c32f64172fbf43d23c99dc4d32f5a1cb5eb08ae Mon Sep 17 00:00:00 2001
+From: Boris BREZILLON <boris.brezillon@free-electrons.com>
+Date: Tue, 1 Dec 2015 12:03:07 +0100
+Subject: [PATCH 60/66] mtd: nand: add nand_to_mtd() helper
+
+Add a new helper to retrieve the MTD device attached to a NAND chip.
+
+Signed-off-by: Boris Brezillon <boris.brezillon@free-electrons.com>
+Signed-off-by: Brian Norris <computersforpeace@gmail.com>
+---
+ include/linux/mtd/nand.h | 5 +++++
+ 1 file changed, 5 insertions(+)
+
+diff --git a/include/linux/mtd/nand.h b/include/linux/mtd/nand.h
+index a4839b3..c75424f 100644
+--- a/include/linux/mtd/nand.h
++++ b/include/linux/mtd/nand.h
+@@ -724,6 +724,11 @@ static inline struct nand_chip *mtd_to_nand(struct mtd_info *mtd)
+ return mtd->priv;
+ }
+
++static inline struct mtd_info *nand_to_mtd(struct nand_chip *chip)
++{
++ return &chip->mtd;
++}
++
+ /*
+ * NAND Flash Manufacturer ID Codes
+ */
+--
+1.7.10.4
+
diff --git a/target/linux/mediatek/patches-4.4/0061-mtd-nand-add-helpers-to-access-priv.patch b/target/linux/mediatek/patches-4.4/0061-mtd-nand-add-helpers-to-access-priv.patch
new file mode 100644
index 0000000..49fbcbc
--- /dev/null
+++ b/target/linux/mediatek/patches-4.4/0061-mtd-nand-add-helpers-to-access-priv.patch
@@ -0,0 +1,39 @@
+From 738a76df006dedd1feb87c596867438b7d59027a Mon Sep 17 00:00:00 2001
+From: Boris BREZILLON <boris.brezillon@free-electrons.com>
+Date: Thu, 10 Dec 2015 09:00:39 +0100
+Subject: [PATCH 61/66] mtd: nand: add helpers to access ->priv
+
+Add two helpers to access the field reserved for private controller data.
+This makes it clearer what this field is reserved for and ease future
+refactoring.
+
+Signed-off-by: Boris Brezillon <boris.brezillon@free-electrons.com>
+Signed-off-by: Brian Norris <computersforpeace@gmail.com>
+---
+ include/linux/mtd/nand.h | 10 ++++++++++
+ 1 file changed, 10 insertions(+)
+
+diff --git a/include/linux/mtd/nand.h b/include/linux/mtd/nand.h
+index c75424f..345f864 100644
+--- a/include/linux/mtd/nand.h
++++ b/include/linux/mtd/nand.h
+@@ -729,6 +729,16 @@ static inline struct mtd_info *nand_to_mtd(struct nand_chip *chip)
+ return &chip->mtd;
+ }
+
++static inline void *nand_get_controller_data(struct nand_chip *chip)
++{
++ return chip->priv;
++}
++
++static inline void nand_set_controller_data(struct nand_chip *chip, void *priv)
++{
++ chip->priv = priv;
++}
++
+ /*
+ * NAND Flash Manufacturer ID Codes
+ */
+--
+1.7.10.4
+
diff --git a/target/linux/mediatek/patches-4.4/0062-mtd-nand-embed-an-mtd_info-structure-into-nand_chip.patch b/target/linux/mediatek/patches-4.4/0062-mtd-nand-embed-an-mtd_info-structure-into-nand_chip.patch
new file mode 100644
index 0000000..598f879
--- /dev/null
+++ b/target/linux/mediatek/patches-4.4/0062-mtd-nand-embed-an-mtd_info-structure-into-nand_chip.patch
@@ -0,0 +1,42 @@
+From 088bf341472e8da8595d49f15af9becf3a4b52e7 Mon Sep 17 00:00:00 2001
+From: Boris BREZILLON <boris.brezillon@free-electrons.com>
+Date: Tue, 1 Dec 2015 12:03:06 +0100
+Subject: [PATCH 62/66] mtd: nand: embed an mtd_info structure into nand_chip
+
+Currently all NAND controller drivers are providing both the mtd_info and
+nand_chip struct and then let the NAND subsystem to initialize a few
+things before registering the mtd instance to the MTD layer.
+Embed an mtd_info field into nand_chip to add some consistency to all NAND
+controller drivers.
+This change will also help factorizing boilerplate code copied in all NAND
+drivers.
+
+Signed-off-by: Boris Brezillon <boris.brezillon@free-electrons.com>
+Signed-off-by: Brian Norris <computersforpeace@gmail.com>
+---
+ include/linux/mtd/nand.h | 2 ++
+ 1 file changed, 2 insertions(+)
+
+diff --git a/include/linux/mtd/nand.h b/include/linux/mtd/nand.h
+index 345f864..1ded588 100644
+--- a/include/linux/mtd/nand.h
++++ b/include/linux/mtd/nand.h
+@@ -540,6 +540,7 @@ struct nand_buffers {
+
+ /**
+ * struct nand_chip - NAND Private Flash Chip Data
++ * @mtd: MTD device registered to the MTD framework
+ * @IO_ADDR_R: [BOARDSPECIFIC] address to read the 8 I/O lines of the
+ * flash device
+ * @IO_ADDR_W: [BOARDSPECIFIC] address to write the 8 I/O lines of the
+@@ -640,6 +641,7 @@ struct nand_buffers {
+ */
+
+ struct nand_chip {
++ struct mtd_info mtd;
+ void __iomem *IO_ADDR_R;
+ void __iomem *IO_ADDR_W;
+
+--
+1.7.10.4
+
diff --git a/target/linux/mediatek/patches-4.4/0063-mtd-add-get-set-of_node-flash_node-helpers.patch b/target/linux/mediatek/patches-4.4/0063-mtd-add-get-set-of_node-flash_node-helpers.patch
new file mode 100644
index 0000000..b72ecfd
--- /dev/null
+++ b/target/linux/mediatek/patches-4.4/0063-mtd-add-get-set-of_node-flash_node-helpers.patch
@@ -0,0 +1,87 @@
+From 63c8331b826ad5f21cb0175308099f18d5fe526a Mon Sep 17 00:00:00 2001
+From: John Crispin <blogic@openwrt.org>
+Date: Tue, 22 Mar 2016 03:52:07 +0100
+Subject: [PATCH 63/66] mtd: add get/set of_node/flash_node helpers
+
+We are going to begin using the mtd->dev.of_node field for MTD device
+nodes, so let's add helpers for it. Also, we'll be making some
+conversions on spi_nor (and nand_chip eventually) too, so get that ready
+with their own helpers.
+
+Signed-off-by: Brian Norris <computersforpeace@gmail.com>
+Reviewed-by: Boris Brezillon <boris.brezillon@free-electrons.com>
+---
+ include/linux/mtd/mtd.h | 11 +++++++++++
+ include/linux/mtd/nand.h | 11 +++++++++++
+ include/linux/mtd/spi-nor.h | 11 +++++++++++
+ 3 files changed, 33 insertions(+)
+
+diff --git a/include/linux/mtd/mtd.h b/include/linux/mtd/mtd.h
+index f17fa75..cc84923 100644
+--- a/include/linux/mtd/mtd.h
++++ b/include/linux/mtd/mtd.h
+@@ -254,6 +254,17 @@ struct mtd_info {
+ int usecount;
+ };
+
++static inline void mtd_set_of_node(struct mtd_info *mtd,
++ struct device_node *np)
++{
++ mtd->dev.of_node = np;
++}
++
++static inline struct device_node *mtd_get_of_node(struct mtd_info *mtd)
++{
++ return mtd->dev.of_node;
++}
++
+ int mtd_erase(struct mtd_info *mtd, struct erase_info *instr);
+ int mtd_point(struct mtd_info *mtd, loff_t from, size_t len, size_t *retlen,
+ void **virt, resource_size_t *phys);
+diff --git a/include/linux/mtd/nand.h b/include/linux/mtd/nand.h
+index 1ded588..3c34ca4 100644
+--- a/include/linux/mtd/nand.h
++++ b/include/linux/mtd/nand.h
+@@ -741,6 +741,17 @@ static inline void nand_set_controller_data(struct nand_chip *chip, void *priv)
+ chip->priv = priv;
+ }
+
++static inline void nand_set_flash_node(struct nand_chip *chip,
++ struct device_node *np)
++{
++ chip->flash_node = np;
++}
++
++static inline struct device_node *nand_get_flash_node(struct nand_chip *chip)
++{
++ return chip->flash_node;
++}
++
+ /*
+ * NAND Flash Manufacturer ID Codes
+ */
+diff --git a/include/linux/mtd/spi-nor.h b/include/linux/mtd/spi-nor.h
+index c8723b6..6d991df 100644
+--- a/include/linux/mtd/spi-nor.h
++++ b/include/linux/mtd/spi-nor.h
+@@ -185,6 +185,17 @@ struct spi_nor {
+ void *priv;
+ };
+
++static inline void spi_nor_set_flash_node(struct spi_nor *nor,
++ struct device_node *np)
++{
++ nor->flash_node = np;
++}
++
++static inline struct device_node *spi_nor_get_flash_node(struct spi_nor *nor)
++{
++ return nor->flash_node;
++}
++
+ /**
+ * spi_nor_scan() - scan the SPI NOR
+ * @nor: the spi_nor structure
+--
+1.7.10.4
+
diff --git a/target/linux/mediatek/patches-4.4/0064-mtd-mediatek-device-tree-docs-for-MTK-Smart-Device-G.patch b/target/linux/mediatek/patches-4.4/0064-mtd-mediatek-device-tree-docs-for-MTK-Smart-Device-G.patch
new file mode 100644
index 0000000..533ff56
--- /dev/null
+++ b/target/linux/mediatek/patches-4.4/0064-mtd-mediatek-device-tree-docs-for-MTK-Smart-Device-G.patch
@@ -0,0 +1,64 @@
+From 91f978e8a8f27eb9988d33904eaba55309b6c0b9 Mon Sep 17 00:00:00 2001
+From: Jorge Ramirez-Ortiz <jorge.ramirez-ortiz@linaro.org>
+Date: Wed, 2 Mar 2016 12:00:11 -0500
+Subject: [PATCH 64/66] mtd: mediatek: device tree docs for MTK Smart Device
+ Gen1 NAND
+
+This patch adds documentation support for Smart Device Gen1 type of
+NAND controllers.
+
+Mediatek's SoC 2701 is one of the SoCs that implements this controller.
+
+Signed-off-by: Jorge Ramirez-Ortiz <jorge.ramirez-ortiz@linaro.org>
+---
+ .../devicetree/bindings/mtd/mtksdg1-nand.txt | 38 ++++++++++++++++++++
+ 1 file changed, 38 insertions(+)
+ create mode 100644 Documentation/devicetree/bindings/mtd/mtksdg1-nand.txt
+
+diff --git a/Documentation/devicetree/bindings/mtd/mtksdg1-nand.txt b/Documentation/devicetree/bindings/mtd/mtksdg1-nand.txt
+new file mode 100644
+index 0000000..129d17b
+--- /dev/null
++++ b/Documentation/devicetree/bindings/mtd/mtksdg1-nand.txt
+@@ -0,0 +1,38 @@
++MTK Smart Device SoCs NAND controller DT binding
++
++Required properties:
++- compatible: Should be "mediatek,mt2701-nfc".
++- reg: The first contains base physical address and size of
++ NAND controller's registers. The second contains base
++ physical address and size of NAND ECC engine.
++- interrupts: the NFC NFI interrupt, and the NFC ECC interrupt
++- clocks: NAND controller clocks.
++- clock-names: NAND controller clocks internal name.
++- vmch-supply: NAND power supply.
++- #address-cells: Partition address, should be set 1.
++- #size-cells: Partition size, should be set 1.
++
++Optional properties:
++
++nand-on-flash-bbt: Use a flash based bad block table.
++
++Optional subnodes:
++- Partitions, see Documentation/devicetree/bindings/mtd/partition.txt
++
++Example:
++
++ nand: nand@1100d000 {
++ compatible = "mediatek,mt2701-nfc";
++ reg = <0 0x1100d000 0 0x1000>, <0 0x1100e000 0 0x1000>;
++ interrupts = <GIC_SPI 56 IRQ_TYPE_LEVEL_LOW>,
++ <GIC_SPI 55 IRQ_TYPE_LEVEL_LOW>;
++ clocks = <&pericfg CLK_PERI_NFI>, <&pericfg CLK_PERI_NFI_ECC>,
++ <&pericfg CLK_PERI_NFI_PAD>;
++ clock-names = "nfi_ck", "nfi_ecc_ck", "nfi_pad_ck";
++ vmch-supply = <&mt6323_vmch_reg>;
++ status = "disabled";
++ #address-cells = <1>;
++ #size-cells = <1>;
++
++ ...
++ };
+--
+1.7.10.4
+
diff --git a/target/linux/mediatek/patches-4.4/0065-mtd-mediatek-driver-for-MTK-Smart-Device-Gen1-NAND.patch b/target/linux/mediatek/patches-4.4/0065-mtd-mediatek-driver-for-MTK-Smart-Device-Gen1-NAND.patch
new file mode 100644
index 0000000..c21ca1d
--- /dev/null
+++ b/target/linux/mediatek/patches-4.4/0065-mtd-mediatek-driver-for-MTK-Smart-Device-Gen1-NAND.patch
@@ -0,0 +1,1798 @@
+From 7a9d3c8c4084fd37fa14c0e8db2830623f5da8cc Mon Sep 17 00:00:00 2001
+From: Jorge Ramirez-Ortiz <jorge.ramirez-ortiz@linaro.org>
+Date: Wed, 2 Mar 2016 12:00:12 -0500
+Subject: [PATCH 65/66] mtd: mediatek: driver for MTK Smart Device Gen1 NAND
+
+This patch adds support for mediatek's SDG1 NFC nand controller
+embedded in SoC 2701.
+
+UBIFS support has been successfully tested.
+
+Signed-off-by: Jorge Ramirez-Ortiz <jorge.ramirez-ortiz@linaro.org>
+---
+ drivers/mtd/nand/Kconfig | 6 +
+ drivers/mtd/nand/Makefile | 1 +
+ drivers/mtd/nand/mtksdg1_nand.c | 1535 +++++++++++++++++++++++++++++++++++
+ drivers/mtd/nand/mtksdg1_nand_ecc.h | 75 ++
+ drivers/mtd/nand/mtksdg1_nand_nfi.h | 119 +++
+ 5 files changed, 1736 insertions(+)
+ create mode 100644 drivers/mtd/nand/mtksdg1_nand.c
+ create mode 100644 drivers/mtd/nand/mtksdg1_nand_ecc.h
+ create mode 100644 drivers/mtd/nand/mtksdg1_nand_nfi.h
+
+diff --git a/drivers/mtd/nand/Kconfig b/drivers/mtd/nand/Kconfig
+index 2896640..5ec072a 100644
+--- a/drivers/mtd/nand/Kconfig
++++ b/drivers/mtd/nand/Kconfig
+@@ -546,4 +546,10 @@ config MTD_NAND_HISI504
+ help
+ Enables support for NAND controller on Hisilicon SoC Hip04.
+
++config MTD_NAND_MTKSDG1
++ tristate "Support for NAND controller on MTK Smart Device SoCs"
++ depends on HAS_DMA
++ help
++ Enables support for NAND controller on MTK Smart Device SoCs.
++
+ endif # MTD_NAND
+diff --git a/drivers/mtd/nand/Makefile b/drivers/mtd/nand/Makefile
+index 2c7f014..2a2620c 100644
+--- a/drivers/mtd/nand/Makefile
++++ b/drivers/mtd/nand/Makefile
+@@ -55,5 +55,6 @@ obj-$(CONFIG_MTD_NAND_BCM47XXNFLASH) += bcm47xxnflash/
+ obj-$(CONFIG_MTD_NAND_SUNXI) += sunxi_nand.o
+ obj-$(CONFIG_MTD_NAND_HISI504) += hisi504_nand.o
+ obj-$(CONFIG_MTD_NAND_BRCMNAND) += brcmnand/
++obj-$(CONFIG_MTD_NAND_MTKSDG1) += mtksdg1_nand.o
+
+ nand-objs := nand_base.o nand_bbt.o nand_timings.o
+diff --git a/drivers/mtd/nand/mtksdg1_nand.c b/drivers/mtd/nand/mtksdg1_nand.c
+new file mode 100644
+index 0000000..55dd17d
+--- /dev/null
++++ b/drivers/mtd/nand/mtksdg1_nand.c
+@@ -0,0 +1,1535 @@
++/*
++ * MTK smart device NAND Flash controller driver.
++ * Copyright (C) 2015-2016 MediaTek Inc.
++ * Authors: Xiaolei Li <xiaolei.li@mediatek.com>
++ * Jorge Ramirez-Ortiz <jorge.ramirez-ortiz@linaro.org>
++ *
++ * This program is free software; you can redistribute it and/or modify
++ * it under the terms of the GNU General Public License version 2 as
++ * published by the Free Software Foundation.
++ *
++ * This program is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
++ * GNU General Public License for more details.
++ */
++
++#include <linux/platform_device.h>
++#include <linux/dma-mapping.h>
++#include <linux/interrupt.h>
++#include <linux/of_mtd.h>
++#include <linux/delay.h>
++#include <linux/clk.h>
++#include <linux/mtd/partitions.h>
++#include <linux/mtd/nand.h>
++#include <linux/mtd/mtd.h>
++#include <linux/module.h>
++
++#include "mtksdg1_nand_nfi.h"
++#include "mtksdg1_nand_ecc.h"
++
++#define MTK_IRQ_ECC "mtksdg1-nand-ecc"
++#define MTK_IRQ_NFI "mtksdg1-nand-nfi"
++#define MTK_NAME "mtksdg1-nand"
++
++#define KB(x) ((x) * 1024UL)
++#define MB(x) (KB(x) * 1024UL)
++
++#define SECTOR_SHIFT (10)
++#define SECTOR_SIZE (1UL << SECTOR_SHIFT)
++#define BYTES_TO_SECTORS(x) ((x) >> SECTOR_SHIFT)
++#define SECTORS_TO_BYTES(x) ((x) << SECTOR_SHIFT)
++
++#define MTK_TIMEOUT (500)
++#define MTK_RESET_TIMEOUT (1 * HZ)
++
++#define MTK_ECC_PARITY_BITS (14)
++#define MTK_NAND_MAX_CHIP (2)
++
++#define MTK_OOB_ON (1)
++#define MTK_OOB_OFF (0)
++
++/* raw accesses do not use ECC (ecc = !raw) */
++#define MTK_ECC_OFF (1)
++#define MTK_ECC_ON (0)
++
++struct mtk_nfc_clk {
++ struct clk *nfiecc_clk;
++ struct clk *nfi_clk;
++ struct clk *pad_clk;
++};
++
++struct mtk_nfc_saved_reg {
++ struct {
++ u32 enccnfg;
++ u32 deccnfg;
++ } ecc;
++ struct {
++ u32 emp_thresh;
++ u16 pagefmt;
++ u32 acccon;
++ u16 cnrnb;
++ u16 csel;
++ } nfi;
++};
++
++struct mtk_nfc_host {
++ struct mtk_nfc_clk clk;
++ struct nand_chip chip;
++ struct device *dev;
++
++ struct {
++ struct completion complete;
++ void __iomem *base;
++ } nfi;
++
++ struct {
++ struct completion complete;
++ void __iomem *base;
++ u32 dec_sec;
++ } ecc;
++
++ u32 fdm_reg[MTKSDG1_NFI_FDM_REG_SIZE / sizeof(u32)];
++ bool switch_oob;
++ u32 row_nob;
++ u8 *buffer;
++
++#ifdef CONFIG_PM_SLEEP
++ struct mtk_nfc_saved_reg saved_reg;
++#endif
++};
++
++static struct nand_ecclayout nand_2k_64 = {
++ .oobfree = { {0, 16} },
++};
++
++static struct nand_ecclayout nand_4k_128 = {
++ .oobfree = { {0, 32} },
++};
++
++/* NFI register access */
++static inline void mtk_nfi_writel(struct mtk_nfc_host *host, u32 val, u32 reg)
++{
++ writel(val, host->nfi.base + reg);
++}
++static inline void mtk_nfi_writew(struct mtk_nfc_host *host, u16 val, u32 reg)
++{
++ writew(val, host->nfi.base + reg);
++}
++static inline u32 mtk_nfi_readl(struct mtk_nfc_host *host, u32 reg)
++{
++ return readl_relaxed(host->nfi.base + reg);
++}
++static inline u16 mtk_nfi_readw(struct mtk_nfc_host *host, u32 reg)
++{
++ return readw_relaxed(host->nfi.base + reg);
++}
++static inline u8 mtk_nfi_readb(struct mtk_nfc_host *host, u32 reg)
++{
++ return readb_relaxed(host->nfi.base + reg);
++}
++
++/* ECC register access */
++static inline void mtk_ecc_writel(struct mtk_nfc_host *host, u32 val, u32 reg)
++{
++ writel(val, host->ecc.base + reg);
++}
++static inline void mtk_ecc_writew(struct mtk_nfc_host *host, u16 val, u32 reg)
++{
++ writew(val, host->ecc.base + reg);
++}
++static inline u32 mtk_ecc_readl(struct mtk_nfc_host *host, u32 reg)
++{
++ return readl_relaxed(host->ecc.base + reg);
++}
++static inline u16 mtk_ecc_readw(struct mtk_nfc_host *host, u32 reg)
++{
++ return readw_relaxed(host->ecc.base + reg);
++}
++
++static void mtk_nfc_hw_reset(struct mtk_nfc_host *host)
++{
++ unsigned long timeout = MTK_RESET_TIMEOUT;
++ struct device *dev = host->dev;
++ u32 val;
++
++ /* reset the state machine, data fifo and fdm data */
++ mtk_nfi_writel(host, CON_FIFO_FLUSH | CON_NFI_RST, MTKSDG1_NFI_CON);
++ timeout += jiffies;
++ do {
++ val = mtk_nfi_readl(host, MTKSDG1_NFI_MASTER_STA);
++ val &= MASTER_STA_MASK;
++ if (!val)
++ return;
++ usleep_range(50, 100);
++
++ } while (time_before(jiffies, timeout));
++
++ dev_warn(dev, "nfi master active after in reset [0x%x] = 0x%x\n",
++ MTKSDG1_NFI_MASTER_STA, val);
++};
++
++static int mtk_nfc_set_command(struct mtk_nfc_host *host, u8 command)
++{
++ unsigned long timeout = msecs_to_jiffies(MTK_TIMEOUT);
++ struct device *dev = host->dev;
++ u32 val;
++
++ mtk_nfi_writel(host, command, MTKSDG1_NFI_CMD);
++
++ /* wait for the NFI core to enter command mode */
++ timeout += jiffies;
++ do {
++ val = mtk_nfi_readl(host, MTKSDG1_NFI_STA);
++ val &= STA_CMD;
++ if (!val)
++ return 0;
++ cpu_relax();
++
++ } while (time_before(jiffies, timeout));
++ dev_warn(dev, "nfi core timed out entering command mode\n");
++
++ return -EIO;
++}
++
++static int mtk_nfc_set_address(struct mtk_nfc_host *host, u32 column, u32 row,
++ u8 colnob, u8 row_nob)
++{
++ unsigned long timeout = msecs_to_jiffies(MTK_TIMEOUT);
++ struct device *dev = host->dev;
++ u32 addr_nob, val;
++
++ addr_nob = colnob | (row_nob << ADDR_ROW_NOB_SHIFT);
++ mtk_nfi_writel(host, column, MTKSDG1_NFI_COLADDR);
++ mtk_nfi_writel(host, row, MTKSDG1_NFI_ROWADDR);
++ mtk_nfi_writel(host, addr_nob, MTKSDG1_NFI_ADDRNOB);
++
++ /* wait for the NFI core to enter address mode */
++ timeout += jiffies;
++ do {
++ val = mtk_nfi_readl(host, MTKSDG1_NFI_STA);
++ val &= STA_ADDR;
++ if (!val)
++ return 0;
++ cpu_relax();
++
++ } while (time_before(jiffies, timeout));
++
++ dev_warn(dev, "nfi core timed out entering address mode\n");
++
++ return -EIO;
++}
++
++static inline void mtk_ecc_encoder_idle(struct mtk_nfc_host *host)
++{
++ unsigned long timeout = msecs_to_jiffies(MTK_TIMEOUT);
++ struct device *dev = host->dev;
++ u32 val;
++
++ timeout += jiffies;
++ do {
++ val = mtk_ecc_readl(host, MTKSDG1_ECC_ENCIDLE);
++ val &= ENC_IDLE;
++ if (val)
++ return;
++ cpu_relax();
++
++ } while (time_before(jiffies, timeout));
++
++ dev_warn(dev, "hw init ecc encoder not idle\n");
++}
++
++static inline void mtk_ecc_decoder_idle(struct mtk_nfc_host *host)
++{
++ unsigned long timeout = msecs_to_jiffies(MTK_TIMEOUT);
++ struct device *dev = host->dev;
++ u32 val;
++
++ timeout += jiffies;
++ do {
++ val = mtk_ecc_readw(host, MTKSDG1_ECC_DECIDLE);
++ val &= DEC_IDLE;
++ if (val)
++ return;
++ cpu_relax();
++
++ } while (time_before(jiffies, timeout));
++
++ dev_warn(dev, "hw init ecc decoder not idle\n");
++}
++
++static int mtk_nfc_transfer_done(struct mtk_nfc_host *host, u32 sectors)
++{
++ unsigned long timeout = msecs_to_jiffies(MTK_TIMEOUT);
++ u32 cnt;
++
++ /* wait for the sector count */
++ timeout += jiffies;
++ do {
++ cnt = mtk_nfi_readl(host, MTKSDG1_NFI_ADDRCNTR);
++ cnt &= CNTR_MASK;
++ if (cnt >= sectors)
++ return 0;
++ cpu_relax();
++
++ } while (time_before(jiffies, timeout));
++
++ return -EIO;
++}
++
++static int mtk_nfc_subpage_done(struct mtk_nfc_host *host, int sectors)
++{
++ unsigned long timeout = msecs_to_jiffies(MTK_TIMEOUT);
++ u32 val;
++
++ timeout += jiffies;
++ do {
++ val = mtk_nfi_readl(host, MTKSDG1_NFI_BYTELEN);
++ val &= CNTR_MASK;
++ if (val >= sectors)
++ return 0;
++ cpu_relax();
++
++ } while (time_before(jiffies, timeout));
++
++ return -EIO;
++}
++
++static inline int mtk_nfc_data_ready(struct mtk_nfc_host *host)
++{
++ unsigned long timeout = msecs_to_jiffies(MTK_TIMEOUT);
++ u8 val;
++
++ timeout += jiffies;
++ do {
++ val = mtk_nfi_readw(host, MTKSDG1_NFI_PIO_DIRDY);
++ val &= PIO_DI_RDY;
++ if (val)
++ return 0;
++ cpu_relax();
++
++ } while (time_before(jiffies, timeout));
++
++ /* data _MUST_ not be accessed */
++ return -EIO;
++}
++
++static int mtk_nfc_hw_runtime_config(struct mtd_info *mtd)
++{
++ struct nand_chip *chip = mtd_to_nand(mtd);
++ struct mtk_nfc_host *host = nand_get_controller_data(chip);
++ struct device *dev = host->dev;
++ u32 dec_size, enc_size;
++ u32 ecc_bit, ecc_level;
++ u32 spare, fmt;
++ u32 reg;
++
++ host->row_nob = 1;
++ if (chip->chipsize > MB(32))
++ host->row_nob = chip->chipsize > MB(128) ? 3 : 2;
++
++ spare = mtd->oobsize / BYTES_TO_SECTORS(mtd->writesize);
++ switch (spare) {
++ case 16:
++ ecc_bit = ECC_CNFG_4BIT;
++ ecc_level = 4;
++ break;
++ case 32:
++ ecc_bit = ECC_CNFG_12BIT;
++ ecc_level = 12;
++ break;
++ default:
++ dev_err(dev, "invalid spare size per sector: %d\n", spare);
++ return -EINVAL;
++ }
++
++ chip->ecc.strength = ecc_level;
++ chip->ecc.size = SECTOR_SIZE;
++
++ switch (mtd->writesize) {
++ case KB(2):
++ fmt = PAGEFMT_512_2K;
++ chip->ecc.layout = &nand_2k_64;
++ break;
++ case KB(4):
++ fmt = PAGEFMT_2K_4K;
++ chip->ecc.layout = &nand_4k_128;
++ break;
++ case KB(8):
++ fmt = PAGEFMT_4K_8K;
++ break;
++ default:
++ dev_err(dev, "invalid page size: %d\n", mtd->writesize);
++ return -EINVAL;
++ }
++
++ /* configure PAGE FMT */
++ reg = fmt;
++ reg |= PAGEFMT_SPARE_16 << PAGEFMT_SPARE_SHIFT;
++ reg |= MTKSDG1_NFI_FDM_REG_SIZE << PAGEFMT_FDM_SHIFT;
++ reg |= MTKSDG1_NFI_FDM_REG_SIZE << PAGEFMT_FDM_ECC_SHIFT;
++ mtk_nfi_writew(host, reg, MTKSDG1_NFI_PAGEFMT);
++
++ /* configure ECC encoder (in bits) */
++ enc_size = (SECTOR_SIZE + MTKSDG1_NFI_FDM_REG_SIZE) << 3;
++ reg = ecc_bit | ECC_NFI_MODE | (enc_size << ECC_MS_SHIFT);
++ mtk_ecc_writel(host, reg, MTKSDG1_ECC_ENCCNFG);
++
++ /* configure ECC decoder (inbits) */
++ dec_size = enc_size + ecc_level * MTK_ECC_PARITY_BITS;
++ reg = ecc_bit | ECC_NFI_MODE | (dec_size << ECC_MS_SHIFT);
++ reg |= (DEC_CNFG_CORRECT | DEC_EMPTY_EN);
++ mtk_ecc_writel(host, reg, MTKSDG1_ECC_DECCNFG);
++
++ return 0;
++}
++
++static void mtk_nfc_device_reset(struct mtk_nfc_host *host)
++{
++ unsigned long timeout = msecs_to_jiffies(MTK_TIMEOUT);
++ struct device *dev = host->dev;
++ u16 chip;
++ int rc;
++
++ mtk_nfc_hw_reset(host);
++
++ /* enable reset done interrupt */
++ mtk_nfi_writew(host, INTR_RST_DONE_EN, MTKSDG1_NFI_INTR_EN);
++
++ /* configure FSM for reset operation */
++ mtk_nfi_writew(host, CNFG_OP_RESET, MTKSDG1_NFI_CNFG);
++
++ init_completion(&host->nfi.complete);
++
++ mtk_nfc_set_command(host, NAND_CMD_RESET);
++ rc = wait_for_completion_timeout(&host->nfi.complete, timeout);
++ if (!rc) {
++ chip = mtk_nfi_readw(host, MTKSDG1_NFI_CSEL);
++ dev_err(dev, "device(%d) reset timeout\n", chip);
++ }
++}
++
++static void mtk_nfc_select_chip(struct mtd_info *mtd, int chip)
++{
++ struct nand_chip *nand = mtd_to_nand(mtd);
++ struct mtk_nfc_host *host = nand_get_controller_data(nand);
++
++ if (chip < 0)
++ return;
++
++ mtk_nfi_writel(host, chip, MTKSDG1_NFI_CSEL);
++}
++
++static inline bool mtk_nfc_cmd_supported(unsigned command)
++{
++ switch (command) {
++ case NAND_CMD_RESET:
++ case NAND_CMD_READID:
++ case NAND_CMD_STATUS:
++ case NAND_CMD_READOOB:
++ case NAND_CMD_ERASE1:
++ case NAND_CMD_ERASE2:
++ case NAND_CMD_SEQIN:
++ case NAND_CMD_PAGEPROG:
++ case NAND_CMD_CACHEDPROG:
++ case NAND_CMD_READ0:
++ return true;
++ default:
++ return false;
++ }
++}
++
++static void mtk_nfc_cmdfunc(struct mtd_info *mtd, unsigned command, int column,
++ int page_addr)
++{
++ struct mtk_nfc_host *host = nand_get_controller_data(mtd_to_nand(mtd));
++ unsigned long const cmd_timeout = msecs_to_jiffies(MTK_TIMEOUT);
++ struct completion *p = &host->nfi.complete;
++ u32 val;
++ int rc;
++
++ if (mtk_nfc_cmd_supported(command))
++ mtk_nfc_hw_reset(host);
++
++ switch (command) {
++ case NAND_CMD_RESET:
++ mtk_nfc_device_reset(host);
++ break;
++ case NAND_CMD_READID:
++ val = CNFG_READ_EN | CNFG_BYTE_RW | CNFG_OP_SRD;
++ mtk_nfi_writew(host, val, MTKSDG1_NFI_CNFG);
++ mtk_nfc_set_command(host, NAND_CMD_READID);
++ mtk_nfc_set_address(host, column, 0, 1, 0);
++ mtk_nfi_writel(host, CON_SRD, MTKSDG1_NFI_CON);
++ break;
++ case NAND_CMD_STATUS:
++ val = CNFG_READ_EN | CNFG_BYTE_RW | CNFG_OP_SRD;
++ mtk_nfi_writew(host, val, MTKSDG1_NFI_CNFG);
++ mtk_nfc_set_command(host, NAND_CMD_STATUS);
++ mtk_nfi_writel(host, CON_SRD, MTKSDG1_NFI_CON);
++ break;
++ case NAND_CMD_READOOB:
++ val = CNFG_READ_EN | CNFG_BYTE_RW | CNFG_OP_READ;
++ mtk_nfi_writew(host, val, MTKSDG1_NFI_CNFG);
++ mtk_nfc_set_command(host, NAND_CMD_READ0);
++ column += mtd->writesize;
++ mtk_nfc_set_address(host, column, page_addr, 2, host->row_nob);
++ val = CON_BRD | (1 << CON_SEC_SHIFT);
++ mtk_nfi_writel(host, val, MTKSDG1_NFI_CON);
++ break;
++ case NAND_CMD_ERASE1:
++ mtk_nfi_writew(host, INTR_ERS_DONE_EN, MTKSDG1_NFI_INTR_EN);
++ mtk_nfi_writew(host, CNFG_OP_ERASE, MTKSDG1_NFI_CNFG);
++ mtk_nfc_set_command(host, NAND_CMD_ERASE1);
++ mtk_nfc_set_address(host, 0, page_addr, 0, host->row_nob);
++ break;
++ case NAND_CMD_ERASE2:
++ init_completion(p);
++ mtk_nfc_set_command(host, NAND_CMD_ERASE2);
++ rc = wait_for_completion_timeout(p, cmd_timeout);
++ if (!rc)
++ dev_err(host->dev, "erase command timeout\n");
++ break;
++ case NAND_CMD_SEQIN:
++ mtk_nfi_writew(host, CNFG_OP_PRGM, MTKSDG1_NFI_CNFG);
++ mtk_nfc_set_command(host, NAND_CMD_SEQIN);
++ mtk_nfc_set_address(host, column, page_addr, 2, host->row_nob);
++ break;
++ case NAND_CMD_PAGEPROG:
++ case NAND_CMD_CACHEDPROG:
++ mtk_nfi_writew(host, INTR_BUSY_RT_EN, MTKSDG1_NFI_INTR_EN);
++ init_completion(p);
++ mtk_nfc_set_command(host, command);
++ rc = wait_for_completion_timeout(p, cmd_timeout);
++ if (!rc)
++ dev_err(host->dev, "pageprogr command timeout\n");
++ break;
++ case NAND_CMD_READ0:
++ val = CNFG_OP_READ | CNFG_READ_EN;
++ mtk_nfi_writew(host, val, MTKSDG1_NFI_CNFG);
++ mtk_nfc_set_command(host, NAND_CMD_READ0);
++ break;
++ default:
++ dev_warn(host->dev, "command 0x%x not supported\n", command);
++ break;
++ }
++}
++
++static uint8_t mtk_nfc_read_byte(struct mtd_info *mtd)
++{
++ struct nand_chip *chip = mtd_to_nand(mtd);
++ struct mtk_nfc_host *host = nand_get_controller_data(chip);
++ int rc;
++
++ rc = mtk_nfc_data_ready(host);
++ if (rc < 0) {
++ dev_err(host->dev, "data not ready\n");
++ return NAND_STATUS_FAIL;
++ }
++
++ return mtk_nfi_readb(host, MTKSDG1_NFI_DATAR);
++}
++
++static void mtk_nfc_write_fdm(struct nand_chip *chip, u32 sectors)
++{
++ struct mtk_nfc_host *host = nand_get_controller_data(chip);
++ u8 *src, *dst;
++ int i, j, reg;
++
++ for (i = 0; i < sectors ; i++) {
++ /* read FDM from OOB into private area */
++ src = chip->oob_poi + i * MTKSDG1_NFI_FDM_REG_SIZE;
++ dst = (u8 *)host->fdm_reg;
++ memcpy(dst, src, MTKSDG1_NFI_FDM_REG_SIZE);
++
++ /* write FDM to registers */
++ for (j = 0; j < ARRAY_SIZE(host->fdm_reg); j++) {
++ reg = MTKSDG1_NFI_FDM0L + i * MTKSDG1_NFI_FDM_REG_SIZE;
++ reg += j * sizeof(host->fdm_reg[0]);
++ mtk_nfi_writel(host, host->fdm_reg[j], reg);
++ }
++ }
++}
++
++static int mtk_nfc_write_page(struct mtd_info *mtd,
++ struct nand_chip *chip, const uint8_t *buf,
++ int oob_on, int page, int raw)
++{
++
++ struct mtk_nfc_host *host = nand_get_controller_data(chip);
++ struct completion *nfi = &host->nfi.complete;
++ struct device *dev = host->dev;
++ const bool use_ecc = !raw;
++ void *q = (void *) buf;
++ dma_addr_t dma_addr;
++ size_t dmasize;
++ u32 reg;
++ int ret;
++
++ dmasize = mtd->writesize + (raw ? mtd->oobsize : 0);
++
++ dma_addr = dma_map_single(dev, q, dmasize, DMA_TO_DEVICE);
++ if (dma_mapping_error(host->dev, dma_addr)) {
++ dev_err(host->dev, "dma mapping error\n");
++ return -EINVAL;
++ }
++
++ reg = mtk_nfi_readw(host, MTKSDG1_NFI_CNFG);
++ reg |= CNFG_AHB | CNFG_DMA_BURST_EN;
++ if (use_ecc) {
++ /**
++ * OOB will be generated
++ * - FDM: from register
++ * - ECC: from HW
++ */
++ reg |= CNFG_AUTO_FMT_EN | CNFG_HW_ECC_EN;
++ mtk_nfi_writew(host, reg, MTKSDG1_NFI_CNFG);
++
++ mtk_ecc_encoder_idle(host);
++ mtk_ecc_writew(host, ENC_EN, MTKSDG1_ECC_ENCCON);
++
++ /* write OOB into the FDM registers (OOB area in MTK NAND) */
++ if (oob_on)
++ mtk_nfc_write_fdm(chip, chip->ecc.steps);
++ } else {
++ /* OOB is part of the DMA transfer */
++ mtk_nfi_writew(host, reg, MTKSDG1_NFI_CNFG);
++ }
++
++ mtk_nfi_writel(host, chip->ecc.steps << CON_SEC_SHIFT, MTKSDG1_NFI_CON);
++ mtk_nfi_writel(host, lower_32_bits(dma_addr), MTKSDG1_NFI_STRADDR);
++ mtk_nfi_writew(host, INTR_AHB_DONE_EN, MTKSDG1_NFI_INTR_EN);
++
++ init_completion(nfi);
++
++ /* start DMA */
++ reg = mtk_nfi_readl(host, MTKSDG1_NFI_CON) | CON_BWR;
++ mtk_nfi_writel(host, reg, MTKSDG1_NFI_CON);
++
++ ret = wait_for_completion_timeout(nfi, msecs_to_jiffies(MTK_TIMEOUT));
++ if (!ret) {
++ dev_err(dev, "program ahb done timeout\n");
++ mtk_nfi_writew(host, 0, MTKSDG1_NFI_INTR_EN);
++ ret = -ETIMEDOUT;
++ goto timeout;
++ }
++
++ ret = mtk_nfc_transfer_done(host, chip->ecc.steps);
++ if (ret < 0)
++ dev_err(dev, "hwecc write timeout\n");
++timeout:
++ dma_unmap_single(host->dev, dma_addr, dmasize, DMA_TO_DEVICE);
++
++ if (use_ecc) {
++ mtk_ecc_encoder_idle(host);
++ mtk_ecc_writew(host, ENC_DE, MTKSDG1_ECC_ENCCON);
++ }
++
++ mtk_nfi_writel(host, 0, MTKSDG1_NFI_CON);
++
++ return ret;
++}
++
++static int mtk_nfc_write_page_hwecc(struct mtd_info *mtd,
++ struct nand_chip *chip, const uint8_t *buf,
++ int oob_on, int page)
++{
++ return mtk_nfc_write_page(mtd, chip, buf, oob_on, page, MTK_ECC_ON);
++}
++
++static int mtk_nfc_write_page_raw(struct mtd_info *mtd, struct nand_chip *chip,
++ const uint8_t *buf, int oob_on, int pg)
++{
++ struct mtk_nfc_host *host = nand_get_controller_data(chip);
++ uint8_t *src, *dst;
++ size_t len;
++ u32 i;
++
++ memset(host->buffer, 0xff, mtd->writesize + mtd->oobsize);
++
++ /* MTK internal 4KB page data layout:
++ * ----------------------------------
++ * PAGE = 4KB, SECTOR = 1KB, OOB=128B
++ * page = sector_oob1 + sector_oob2 + sector_oob3 + sector_oob4
++ * sector_oob = data (1KB) + FDM (8B) + ECC parity (21B) + free (3B)
++ *
++ */
++ len = SECTOR_SIZE + mtd->oobsize / chip->ecc.steps;
++
++ for (i = 0; i < chip->ecc.steps; i++) {
++
++ if (buf) {
++ src = (uint8_t *) buf + i * SECTOR_SIZE;
++ dst = host->buffer + i * len;
++ memcpy(dst, src, SECTOR_SIZE);
++ }
++
++ if (oob_on) {
++ src = chip->oob_poi + i * MTKSDG1_NFI_FDM_REG_SIZE;
++ dst = host->buffer + i * len + SECTOR_SIZE;
++ memcpy(dst, src, MTKSDG1_NFI_FDM_REG_SIZE);
++ }
++ }
++
++ return mtk_nfc_write_page(mtd, chip, host->buffer, MTK_OOB_OFF, pg,
++ MTK_ECC_OFF);
++}
++
++static int mtk_nfc_sector_encode(struct nand_chip *chip, u8 *data)
++{
++ struct mtk_nfc_host *host = nand_get_controller_data(chip);
++ struct completion *ecc = &host->ecc.complete;
++ u32 reg, parity_bytes, i;
++ dma_addr_t dma_addr;
++ u32 *parity_region;
++ int rc, ret = 0;
++ size_t dmasize;
++
++ dmasize = SECTOR_SIZE + MTKSDG1_NFI_FDM_REG_SIZE;
++ dma_addr = dma_map_single(host->dev, data, dmasize, DMA_TO_DEVICE);
++ if (dma_mapping_error(host->dev, dma_addr)) {
++ dev_err(host->dev, "dma mapping error\n");
++ return -EINVAL;
++ }
++
++ /* enable the encoder in DMA mode to calculate the ECC bytes */
++ reg = mtk_ecc_readl(host, MTKSDG1_ECC_ENCCNFG);
++ reg &= (~ECC_ENC_MODE_MASK);
++ reg |= ECC_DMA_MODE;
++ mtk_ecc_writel(host, reg, MTKSDG1_ECC_ENCCNFG);
++
++ mtk_ecc_writel(host, ENC_IRQEN, MTKSDG1_ECC_ENCIRQ_EN);
++ mtk_ecc_writel(host, lower_32_bits(dma_addr), MTKSDG1_ECC_ENCDIADDR);
++
++ init_completion(ecc);
++ mtk_ecc_writew(host, ENC_EN, MTKSDG1_ECC_ENCCON);
++
++ rc = wait_for_completion_timeout(ecc, msecs_to_jiffies(MTK_TIMEOUT));
++ if (!rc) {
++ dev_err(host->dev, "ecc encode done timeout\n");
++ mtk_ecc_writel(host, 0, MTKSDG1_ECC_ENCIRQ_EN);
++ ret = -ETIMEDOUT;
++ goto timeout;
++ }
++
++ mtk_ecc_encoder_idle(host);
++
++ /**
++ * Program ECC bytes to OOB
++ * per sector oob = FDM + ECC + SPARE
++ */
++
++ parity_region = (u32 *) (data + SECTOR_SIZE + MTKSDG1_NFI_FDM_REG_SIZE);
++ parity_bytes = (chip->ecc.strength * MTK_ECC_PARITY_BITS + 7) >> 3;
++
++ /* write the parity bytes generated by the ECC back to the OOB region */
++ for (i = 0; i < parity_bytes; i += sizeof(u32))
++ *parity_region++ = mtk_ecc_readl(host, MTKSDG1_ECC_ENCPAR0 + i);
++
++timeout:
++
++ dma_unmap_single(host->dev, dma_addr, dmasize, DMA_TO_DEVICE);
++
++ mtk_ecc_writew(host, 0, MTKSDG1_ECC_ENCCON);
++ reg = mtk_ecc_readl(host, MTKSDG1_ECC_ENCCNFG);
++ reg &= (~ECC_ENC_MODE_MASK);
++ reg |= ECC_NFI_MODE;
++ mtk_ecc_writel(host, reg, MTKSDG1_ECC_ENCCNFG);
++
++ return ret;
++}
++
++static int mtk_nfc_write_subpage_hwecc(struct mtd_info *mtd,
++ struct nand_chip *chip, uint32_t offset, uint32_t data_len,
++ const uint8_t *buf, int oob_on, int pg)
++{
++ struct mtk_nfc_host *host = nand_get_controller_data(chip);
++ uint8_t *src, *dst;
++ u32 start, end;
++ size_t len;
++ int i, ret;
++
++ start = BYTES_TO_SECTORS(offset);
++ end = BYTES_TO_SECTORS(offset + data_len + SECTOR_SIZE - 1);
++
++ len = SECTOR_SIZE + mtd->oobsize / chip->ecc.steps;
++
++ memset(host->buffer, 0xff, mtd->writesize + mtd->oobsize);
++ for (i = 0; i < chip->ecc.steps; i++) {
++
++ /* write data */
++ src = (uint8_t *) buf + i * SECTOR_SIZE;
++ dst = host->buffer + i * len;
++ memcpy(dst, src, SECTOR_SIZE);
++
++ if (i < start)
++ continue;
++
++ if (i >= end)
++ continue;
++
++ /* write fdm */
++ if (oob_on) {
++ src = chip->oob_poi + i * MTKSDG1_NFI_FDM_REG_SIZE;
++ dst = host->buffer + i * len + SECTOR_SIZE;
++ memcpy(dst, src, MTKSDG1_NFI_FDM_REG_SIZE);
++ }
++
++ /* point to the start of data */
++ src = host->buffer + i * len;
++
++ /* program the CRC back to the OOB */
++ ret = mtk_nfc_sector_encode(chip, src);
++ if (ret < 0)
++ return ret;
++ }
++
++ /* use the data in the private buffer (now with FDM and CRC) to perform
++ * a raw write
++ */
++ src = host->buffer;
++ return mtk_nfc_write_page(mtd, chip, src, MTK_OOB_OFF, pg, MTK_ECC_OFF);
++}
++
++static int mtk_nfc_write_oob(struct mtd_info *mtd, struct nand_chip *chip,
++ int page)
++{
++ u8 *buf = chip->buffers->databuf;
++ int ret;
++
++ memset(buf, 0xff, mtd->writesize);
++ chip->cmdfunc(mtd, NAND_CMD_SEQIN, 0x00, page);
++ ret = mtk_nfc_write_page_hwecc(mtd, chip, buf, MTK_OOB_ON, page);
++ if (ret < 0)
++ return -EIO;
++
++ chip->cmdfunc(mtd, NAND_CMD_PAGEPROG, -1, -1);
++ ret = chip->waitfunc(mtd, chip);
++
++ return ret & NAND_STATUS_FAIL ? -EIO : 0;
++}
++
++static int mtk_nfc_write_oob_raw(struct mtd_info *mtd, struct nand_chip *chip,
++ int page)
++{
++ int ret;
++
++ chip->cmdfunc(mtd, NAND_CMD_SEQIN, 0x00, page);
++ ret = mtk_nfc_write_page_raw(mtd, chip, NULL, MTK_OOB_ON, page);
++ if (ret < 0)
++ return -EIO;
++
++ chip->cmdfunc(mtd, NAND_CMD_PAGEPROG, -1, -1);
++ ret = chip->waitfunc(mtd, chip);
++
++ return ret & NAND_STATUS_FAIL ? -EIO : 0;
++}
++
++static int mtk_nfc_ecc_check(struct mtd_info *mtd, struct nand_chip *chip,
++ u32 sectors)
++{
++ struct mtk_nfc_host *host = nand_get_controller_data(chip);
++ u32 offset, i, err, max_bitflip;
++
++ max_bitflip = 0;
++
++ for (i = 0; i < sectors; i++) {
++ offset = (i >> 2) << 2;
++ err = mtk_ecc_readl(host, MTKSDG1_ECC_DECENUM0 + offset);
++ err = err >> ((i % 4) * 8);
++ err &= ERR_MASK;
++ if (err == ERR_MASK) {
++ /* uncorrectable errors */
++ mtd->ecc_stats.failed++;
++ continue;
++ }
++
++ mtd->ecc_stats.corrected += err;
++ max_bitflip = max_t(u32, max_bitflip, err);
++ }
++
++ return max_bitflip;
++}
++
++static void mtk_nfc_read_fdm(struct nand_chip *chip, u32 sectors)
++{
++ struct mtk_nfc_host *host = nand_get_controller_data(chip);
++ int i, j, reg;
++ u8 *dst, *src;
++
++ for (i = 0; i < sectors; i++) {
++ /* read FDM register into host memory */
++ for (j = 0; j < ARRAY_SIZE(host->fdm_reg); j++) {
++ reg = MTKSDG1_NFI_FDM0L + i * MTKSDG1_NFI_FDM_REG_SIZE;
++ reg += j * sizeof(host->fdm_reg[0]);
++ host->fdm_reg[j] = mtk_nfi_readl(host, reg);
++ }
++
++ /* copy FDM register from host to OOB */
++ src = (u8 *)host->fdm_reg;
++ dst = chip->oob_poi + i * MTKSDG1_NFI_FDM_REG_SIZE;
++ memcpy(dst, src, MTKSDG1_NFI_FDM_REG_SIZE);
++ }
++}
++
++static int mtk_nfc_update_oob(struct mtd_info *mtd, struct nand_chip *chip,
++ u8 *buf, u32 sectors)
++{
++ struct mtk_nfc_host *host = nand_get_controller_data(chip);
++ int i, bitflips = 0;
++
++ /* if the page is empty, no bitflips and clear data and oob */
++ if (mtk_nfi_readl(host, MTKSDG1_NFI_STA) & STA_EMP_PAGE) {
++ memset(buf, 0xff, SECTORS_TO_BYTES(sectors));
++
++ /* empty page: update OOB with 0xFF */
++ for (i = 0; i < sectors; i++) {
++ memset(chip->oob_poi + i * MTKSDG1_NFI_FDM_REG_SIZE,
++ 0xff, MTKSDG1_NFI_FDM_REG_SIZE);
++ }
++ } else {
++ /* update OOB with HW info */
++ mtk_nfc_read_fdm(chip, sectors);
++
++ /* return the bitflips */
++ bitflips = mtk_nfc_ecc_check(mtd, chip, sectors);
++ }
++
++ return bitflips;
++}
++
++static int mtk_nfc_block_markbad(struct mtd_info *mtd, loff_t ofs)
++{
++ struct nand_chip *chip = mtd_to_nand(mtd);
++ u8 *buf = chip->buffers->databuf;
++ int rc, i, pg;
++
++ /* block_markbad writes 0x00 at data and OOB */
++ memset(buf, 0x00, mtd->writesize + mtd->oobsize);
++
++ /* Write to first/last page(s) if necessary */
++ if (chip->bbt_options & NAND_BBT_SCANLASTPAGE)
++ ofs += mtd->erasesize - mtd->writesize;
++
++ i = 0;
++ do {
++ pg = (int)(ofs >> chip->page_shift);
++
++ /**
++ * write 0x00 to DATA & OOB in flash
++ * No need to reorganize the page since it is all 0x00
++ */
++ chip->cmdfunc(mtd, NAND_CMD_SEQIN, 0x00, pg);
++ rc = mtk_nfc_write_page(mtd, chip, buf, MTK_OOB_OFF, pg,
++ MTK_ECC_OFF);
++ if (rc < 0)
++ return rc;
++
++ chip->cmdfunc(mtd, NAND_CMD_PAGEPROG, -1, -1);
++ rc = chip->waitfunc(mtd, chip);
++ rc = rc & NAND_STATUS_FAIL ? -EIO : 0;
++ if (rc < 0)
++ return rc;
++
++ ofs += mtd->writesize;
++ i++;
++
++ } while ((chip->bbt_options & NAND_BBT_SCAN2NDPAGE) && i < 2);
++
++ return 0;
++}
++
++static int mtk_nfc_read_subpage(struct mtd_info *mtd, struct nand_chip *chip,
++ uint32_t data_offs, uint32_t readlen, uint8_t *bufpoi,
++ int page, int raw)
++{
++ struct mtk_nfc_host *host = nand_get_controller_data(chip);
++ unsigned long timeout = msecs_to_jiffies(MTK_TIMEOUT);
++ u32 reg, column, spare, sectors, start, end;
++ struct completion *nfi, *ecc;
++ const bool use_ecc = !raw;
++ int bitflips = -EIO;
++ dma_addr_t dma_addr;
++ size_t len;
++ u8 *buf;
++ int rc;
++
++ nfi = &host->nfi.complete;
++ ecc = &host->ecc.complete;
++
++ start = BYTES_TO_SECTORS(data_offs);
++ end = BYTES_TO_SECTORS(data_offs + readlen + SECTOR_SIZE - 1);
++ sectors = end - start;
++
++ spare = mtd->oobsize / chip->ecc.steps;
++ column = start * (SECTOR_SIZE + spare);
++
++ len = SECTORS_TO_BYTES(sectors) + (raw ? sectors * spare : 0);
++ buf = bufpoi + SECTORS_TO_BYTES(start);
++
++ /* map the device memory */
++ dma_addr = dma_map_single(host->dev, buf, len, DMA_FROM_DEVICE);
++ if (dma_mapping_error(host->dev, dma_addr)) {
++ dev_err(host->dev, "dma mapping error\n");
++ return -EINVAL;
++ }
++
++ /* configure the transfer */
++ reg = mtk_nfi_readw(host, MTKSDG1_NFI_CNFG);
++ reg |= CNFG_DMA_BURST_EN | CNFG_AHB;
++ if (use_ecc) {
++ reg |= CNFG_AUTO_FMT_EN | CNFG_HW_ECC_EN;
++ mtk_nfi_writew(host, reg, MTKSDG1_NFI_CNFG);
++
++ /* enable encoder */
++ mtk_ecc_decoder_idle(host);
++ mtk_ecc_writel(host, DEC_EN, MTKSDG1_ECC_DECCON);
++ } else
++ mtk_nfi_writew(host, reg, MTKSDG1_NFI_CNFG);
++
++ mtk_nfi_writel(host, sectors << CON_SEC_SHIFT, MTKSDG1_NFI_CON);
++ mtk_nfi_writew(host, INTR_BUSY_RT_EN, MTKSDG1_NFI_INTR_EN);
++
++ init_completion(nfi);
++
++ mtk_nfc_set_address(host, column, page, 2, host->row_nob);
++ mtk_nfc_set_command(host, NAND_CMD_READSTART);
++ rc = wait_for_completion_timeout(nfi, timeout);
++ if (!rc) {
++ dev_err(host->dev, "read busy return timeout\n");
++ goto error;
++ }
++
++ mtk_nfi_writew(host, INTR_AHB_DONE_EN, MTKSDG1_NFI_INTR_EN);
++ mtk_nfi_writel(host, lower_32_bits(dma_addr), MTKSDG1_NFI_STRADDR);
++
++ if (use_ecc) {
++ /* program ECC with sector count */
++ host->ecc.dec_sec = sectors;
++ init_completion(ecc);
++ mtk_ecc_writew(host, DEC_IRQEN, MTKSDG1_ECC_DECIRQ_EN);
++ }
++
++ init_completion(nfi);
++
++ /* start DMA */
++ reg = mtk_nfi_readl(host, MTKSDG1_NFI_CON) | CON_BRD;
++ mtk_nfi_writel(host, reg, MTKSDG1_NFI_CON);
++
++ rc = wait_for_completion_timeout(nfi, timeout);
++ if (!rc)
++ dev_warn(host->dev, "read ahb/dma done timeout\n");
++
++ /* DMA interrupt didn't trigger, check page done just in case */
++ rc = mtk_nfc_subpage_done(host, sectors);
++ if (rc < 0) {
++ dev_err(host->dev, "subpage done timeout\n");
++ goto error;
++ }
++
++ /* raw transfer successful */
++ bitflips = 0;
++
++ if (use_ecc) {
++ rc = wait_for_completion_timeout(ecc, timeout);
++ if (!rc) {
++ dev_err(host->dev, "ecc decode timeout\n");
++ host->ecc.dec_sec = 0;
++ bitflips = -ETIMEDOUT;
++ goto error;
++ }
++ bitflips = mtk_nfc_update_oob(mtd, chip, buf, sectors);
++ }
++
++error:
++ dma_unmap_single(host->dev, dma_addr, len, DMA_FROM_DEVICE);
++
++ if (use_ecc) {
++ /* make sure the ECC dec irq is disabled */
++ mtk_ecc_writew(host, 0, MTKSDG1_ECC_DECIRQ_EN);
++ mtk_ecc_decoder_idle(host);
++
++ /* disable ECC dec */
++ mtk_ecc_writew(host, 0, MTKSDG1_ECC_DECCON);
++ }
++
++ mtk_nfi_writel(host, 0, MTKSDG1_NFI_CON);
++
++ return bitflips;
++}
++
++static int mtk_nfc_read_subpage_hwecc(struct mtd_info *mtd,
++ struct nand_chip *chip, uint32_t data_offs,
++ uint32_t readlen, uint8_t *bufpoi, int page)
++{
++ return mtk_nfc_read_subpage(mtd, chip, data_offs, readlen,
++ bufpoi, page, MTK_ECC_ON);
++}
++
++static int mtk_nfc_read_page_hwecc(struct mtd_info *mtd, struct nand_chip *chip,
++ uint8_t *buf, int oob_on, int page)
++{
++ return mtk_nfc_read_subpage_hwecc(mtd, chip, 0, mtd->writesize,
++ buf, page);
++}
++
++static int mtk_nfc_read_page_raw(struct mtd_info *mtd, struct nand_chip *chip,
++ uint8_t *buf, int oob_on, int page)
++{
++ struct mtk_nfc_host *host = nand_get_controller_data(chip);
++ uint8_t *src, *dst;
++ int i, ret;
++ size_t len;
++
++ dst = host->buffer;
++ memset(dst, 0xff, mtd->writesize + mtd->oobsize);
++ ret = mtk_nfc_read_subpage(mtd, chip, 0, mtd->writesize, dst, page, 1);
++ if (ret < 0)
++ return ret;
++
++ len = SECTOR_SIZE + mtd->oobsize / chip->ecc.steps;
++
++ /* copy to the output buffer */
++ for (i = 0; i < chip->ecc.steps; i++) {
++
++ /* copy sector data */
++ if (buf) {
++ src = host->buffer + i * len;
++ dst = buf + i * SECTOR_SIZE;
++ memcpy(dst, src, SECTOR_SIZE);
++ }
++
++ /* copy FDM data to OOB */
++ if (oob_on) {
++ src = host->buffer + i * len + SECTOR_SIZE;
++ dst = chip->oob_poi + i * MTKSDG1_NFI_FDM_REG_SIZE;
++ memcpy(dst, src, MTKSDG1_NFI_FDM_REG_SIZE);
++ }
++ }
++
++ return ret;
++}
++
++static void mtk_nfc_switch_oob(struct mtd_info *mtd, struct nand_chip *chip,
++ uint8_t *buf)
++{
++ struct mtk_nfc_host *host = nand_get_controller_data(chip);
++ size_t spare;
++ u32 sectors;
++ u8 *bufpoi;
++ int len;
++
++ spare = mtd->oobsize / chip->ecc.steps;
++ sectors = mtd->writesize / (SECTOR_SIZE + spare);
++
++ /**
++ * MTK: DATA+oob1, DATA+oob2, DATA+oob3 ...
++ * LNX: DATA+OOB
++ */
++ /* point to the last oob_i from the NAND device*/
++ bufpoi = buf + mtd->writesize - (sectors * spare);
++ len = sizeof(host->fdm_reg);
++
++ /* copy NAND oob to private area */
++ memcpy(host->fdm_reg, bufpoi, len);
++
++ /* copy oob_poi to NAND */
++ memcpy(bufpoi, chip->oob_poi, len);
++
++ /* copy NAND oob to oob_poi */
++ memcpy(chip->oob_poi, host->fdm_reg, sizeof(host->fdm_reg));
++ memset(host->fdm_reg, 0x00, len);
++}
++
++static int mtk_nfc_read_oob(struct mtd_info *mtd, struct nand_chip *chip,
++ int page)
++{
++ struct mtk_nfc_host *host = nand_get_controller_data(chip);
++ u8 *buf = chip->buffers->databuf;
++ struct mtd_ecc_stats stats;
++ int ret;
++
++ stats = mtd->ecc_stats;
++
++ memset(buf, 0xff, mtd->writesize);
++ chip->cmdfunc(mtd, NAND_CMD_READ0, 0, page);
++
++ ret = mtk_nfc_read_page_hwecc(mtd, chip, buf, 1, page);
++
++ if (host->switch_oob)
++ mtk_nfc_switch_oob(mtd, chip, buf);
++
++ if (ret < mtd->bitflip_threshold)
++ mtd->ecc_stats.corrected = stats.corrected;
++
++ return ret;
++}
++
++static int mtk_nfc_read_oob_raw(struct mtd_info *mtd, struct nand_chip *chip,
++ int page)
++{
++ chip->cmdfunc(mtd, NAND_CMD_READ0, 0, page);
++
++ return mtk_nfc_read_page_raw(mtd, chip, NULL, MTK_OOB_ON, page);
++}
++
++static inline void mtk_nfc_hw_init(struct mtk_nfc_host *host)
++{
++ mtk_nfi_writel(host, 0x10804211, MTKSDG1_NFI_ACCCON);
++ mtk_nfi_writew(host, 0xf1, MTKSDG1_NFI_CNRNB);
++ mtk_nfc_hw_reset(host);
++
++ /* clear interrupt */
++ mtk_nfi_readl(host, MTKSDG1_NFI_INTR_STA);
++ mtk_nfi_writel(host, 0, MTKSDG1_NFI_INTR_EN);
++
++ /* ECC encoder init */
++ mtk_ecc_encoder_idle(host);
++ mtk_ecc_writew(host, ENC_DE, MTKSDG1_ECC_ENCCON);
++
++ /* ECC decoder init */
++ mtk_ecc_decoder_idle(host);
++ mtk_ecc_writel(host, DEC_DE, MTKSDG1_ECC_DECCON);
++}
++
++static irqreturn_t mtk_nfi_irq(int irq, void *devid)
++{
++ struct mtk_nfc_host *host = devid;
++ u16 sta, ien;
++
++ sta = mtk_nfi_readw(host, MTKSDG1_NFI_INTR_STA);
++ ien = mtk_nfi_readw(host, MTKSDG1_NFI_INTR_EN);
++
++ if (!(sta & ien))
++ return IRQ_NONE;
++
++ mtk_nfi_writew(host, ~sta & ien, MTKSDG1_NFI_INTR_EN);
++ complete(&host->nfi.complete);
++
++ return IRQ_HANDLED;
++}
++
++static irqreturn_t mtk_ecc_irq(int irq, void *devid)
++{
++ struct mtk_nfc_host *host = devid;
++ u32 reg_val, mask;
++
++ reg_val = mtk_ecc_readw(host, MTKSDG1_ECC_DECIRQ_STA);
++ if (reg_val & DEC_IRQEN) {
++ if (host->ecc.dec_sec) {
++ mask = 1 << (host->ecc.dec_sec - 1);
++ reg_val = mtk_ecc_readw(host, MTKSDG1_ECC_DECDONE);
++ if (mask & reg_val) {
++ host->ecc.dec_sec = 0;
++ complete(&host->ecc.complete);
++ mtk_ecc_writew(host, 0, MTKSDG1_ECC_DECIRQ_EN);
++ }
++ } else
++ dev_warn(host->dev, "spurious DEC_IRQ\n");
++
++ return IRQ_HANDLED;
++ }
++
++ reg_val = mtk_ecc_readl(host, MTKSDG1_ECC_ENCIRQ_STA);
++ if (reg_val & ENC_IRQEN) {
++ complete(&host->ecc.complete);
++ mtk_ecc_writel(host, 0, MTKSDG1_ECC_ENCIRQ_EN);
++
++ return IRQ_HANDLED;
++ }
++
++ return IRQ_NONE;
++}
++
++static int mtk_nfc_enable_clk(struct device *dev, struct mtk_nfc_clk *clk)
++{
++ int ret;
++
++ ret = clk_prepare_enable(clk->nfi_clk);
++ if (ret) {
++ dev_err(dev, "failed to enable nfi clk\n");
++ return ret;
++ }
++
++ ret = clk_prepare_enable(clk->nfiecc_clk);
++ if (ret) {
++ dev_err(dev, "failed to enable nfiecc clk\n");
++ goto out_nfiecc_clk_disable;
++ }
++
++ ret = clk_prepare_enable(clk->pad_clk);
++ if (ret) {
++ dev_err(dev, "failed to enable pad clk\n");
++ goto out_pad_clk_disable;
++ }
++
++ return 0;
++
++out_pad_clk_disable:
++ clk_disable_unprepare(clk->nfiecc_clk);
++
++out_nfiecc_clk_disable:
++ clk_disable_unprepare(clk->nfi_clk);
++
++ return ret;
++}
++
++static void mtk_nfc_disable_clk(struct mtk_nfc_clk *clk)
++{
++ clk_disable_unprepare(clk->nfi_clk);
++ clk_disable_unprepare(clk->nfiecc_clk);
++ clk_disable_unprepare(clk->pad_clk);
++}
++
++static int mtk_nfc_probe(struct platform_device *pdev)
++{
++ struct device *dev = &pdev->dev;
++ struct device_node *np = dev->of_node;
++ struct mtk_nfc_host *host;
++ struct nand_chip *chip;
++ struct mtd_info *mtd;
++ struct resource *res;
++ int ret, irq;
++ size_t len;
++
++ host = devm_kzalloc(dev, sizeof(*host), GFP_KERNEL);
++ if (!host)
++ return -ENOMEM;
++
++ chip = &host->chip;
++ mtd = nand_to_mtd(chip);
++ host->dev = dev;
++
++ res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
++ host->nfi.base = devm_ioremap_resource(dev, res);
++ if (IS_ERR(host->nfi.base)) {
++ ret = PTR_ERR(host->nfi.base);
++ dev_err(dev, "no nfi base\n");
++ return ret;
++ }
++
++ res = platform_get_resource(pdev, IORESOURCE_MEM, 1);
++ host->ecc.base = devm_ioremap_resource(dev, res);
++ if (IS_ERR(host->ecc.base)) {
++ ret = PTR_ERR(host->ecc.base);
++ dev_err(dev, "no ecc base\n");
++ return ret;
++ }
++
++ host->clk.nfi_clk = devm_clk_get(dev, "nfi_clk");
++ if (IS_ERR(host->clk.nfi_clk)) {
++ dev_err(dev, "no clk\n");
++ ret = PTR_ERR(host->clk.nfi_clk);
++ return ret;
++ }
++
++ host->clk.nfiecc_clk = devm_clk_get(dev, "nfiecc_clk");
++ if (IS_ERR(host->clk.nfiecc_clk)) {
++ dev_err(dev, "no ecc clk\n");
++ ret = PTR_ERR(host->clk.nfiecc_clk);
++ return ret;
++ }
++
++ host->clk.pad_clk = devm_clk_get(dev, "pad_clk");
++ if (IS_ERR(host->clk.pad_clk)) {
++ dev_err(dev, "no pad clk\n");
++ ret = PTR_ERR(host->clk.pad_clk);
++ return ret;
++ }
++
++ ret = mtk_nfc_enable_clk(dev, &host->clk);
++ if (ret)
++ return ret;
++
++ irq = platform_get_irq(pdev, 0);
++ if (irq < 0) {
++ dev_err(dev, "no nfi irq resource\n");
++ ret = -EINVAL;
++ goto clk_disable;
++ }
++
++ ret = devm_request_irq(dev, irq, mtk_nfi_irq, 0x0, MTK_IRQ_NFI, host);
++ if (ret) {
++ dev_err(dev, "failed to request nfi irq\n");
++ goto clk_disable;
++ }
++
++ irq = platform_get_irq(pdev, 1);
++ if (irq < 0) {
++ dev_err(dev, "no ecc irq resource\n");
++ ret = -EINVAL;
++ goto clk_disable;
++ }
++
++ ret = devm_request_irq(dev, irq, mtk_ecc_irq, 0x0, MTK_IRQ_ECC, host);
++ if (ret) {
++ dev_err(dev, "failed to request ecc irq\n");
++ goto clk_disable;
++ }
++
++ ret = dma_set_mask(dev, DMA_BIT_MASK(32));
++ if (ret) {
++ dev_err(dev, "failed to set dma mask\n");
++ goto clk_disable;
++ }
++
++ platform_set_drvdata(pdev, host);
++
++ mtd_set_of_node(mtd, np);
++ mtd->owner = THIS_MODULE;
++ mtd->dev.parent = dev;
++ mtd->name = MTK_NAME;
++
++ nand_set_controller_data(chip, host);
++ chip->options |= NAND_USE_BOUNCE_BUFFER | NAND_SUBPAGE_READ;
++ chip->block_markbad = mtk_nfc_block_markbad;
++ chip->select_chip = mtk_nfc_select_chip;
++ chip->read_byte = mtk_nfc_read_byte;
++ chip->cmdfunc = mtk_nfc_cmdfunc;
++ chip->ecc.mode = NAND_ECC_HW;
++ chip->ecc.write_subpage = mtk_nfc_write_subpage_hwecc;
++ chip->ecc.write_page_raw = mtk_nfc_write_page_raw;
++ chip->ecc.write_page = mtk_nfc_write_page_hwecc;
++ chip->ecc.write_oob_raw = mtk_nfc_write_oob_raw;
++ chip->ecc.write_oob = mtk_nfc_write_oob;
++ chip->ecc.read_subpage = mtk_nfc_read_subpage_hwecc;
++ chip->ecc.read_page_raw = mtk_nfc_read_page_raw;
++ chip->ecc.read_oob_raw = mtk_nfc_read_oob_raw;
++ chip->ecc.read_page = mtk_nfc_read_page_hwecc;
++ chip->ecc.read_oob = mtk_nfc_read_oob;
++
++ mtk_nfc_hw_init(host);
++
++ ret = nand_scan_ident(mtd, MTK_NAND_MAX_CHIP, NULL);
++ if (ret) {
++ ret = -ENODEV;
++ goto clk_disable;
++ }
++
++ ret = mtk_nfc_hw_runtime_config(mtd);
++ if (ret < 0) {
++ dev_err(dev, "nand device not supported\n");
++ goto clk_disable;
++ }
++
++ len = mtd->writesize + mtd->oobsize;
++ host->buffer = devm_kzalloc(dev, len, GFP_KERNEL);
++ if (!host->buffer) {
++ ret = -ENOMEM;
++ goto clk_disable;
++ }
++
++ /* required to create bbt table if not present */
++ host->switch_oob = true;
++ ret = nand_scan_tail(mtd);
++ if (ret) {
++ ret = -ENODEV;
++ goto clk_disable;
++ }
++ host->switch_oob = false;
++
++ ret = mtd_device_parse_register(mtd, NULL, NULL, NULL, 0);
++ if (ret) {
++ dev_err(dev, "mtd parse partition error\n");
++ goto nand_free;
++ }
++
++ return 0;
++
++nand_free:
++ nand_release(mtd);
++
++clk_disable:
++ mtk_nfc_disable_clk(&host->clk);
++
++ return ret;
++}
++
++static int mtk_nfc_remove(struct platform_device *pdev)
++{
++ struct mtk_nfc_host *host = platform_get_drvdata(pdev);
++ struct mtd_info *mtd = nand_to_mtd(&host->chip);
++
++ nand_release(mtd);
++ mtk_nfc_disable_clk(&host->clk);
++
++ return 0;
++}
++
++#ifdef CONFIG_PM_SLEEP
++static int mtk_nfc_suspend(struct device *dev)
++{
++ struct mtk_nfc_host *host = dev_get_drvdata(dev);
++ struct mtk_nfc_saved_reg *reg = &host->saved_reg;
++
++ reg->nfi.emp_thresh = mtk_nfi_readl(host, MTKSDG1_NFI_EMPTY_THRESH);
++ reg->ecc.enccnfg = mtk_ecc_readl(host, MTKSDG1_ECC_ENCCNFG);
++ reg->ecc.deccnfg = mtk_ecc_readl(host, MTKSDG1_ECC_DECCNFG);
++ reg->nfi.pagefmt = mtk_nfi_readw(host, MTKSDG1_NFI_PAGEFMT);
++ reg->nfi.acccon = mtk_nfi_readl(host, MTKSDG1_NFI_ACCCON);
++ reg->nfi.cnrnb = mtk_nfi_readw(host, MTKSDG1_NFI_CNRNB);
++ reg->nfi.csel = mtk_nfi_readw(host, MTKSDG1_NFI_CSEL);
++
++ mtk_nfc_disable_clk(&host->clk);
++
++ return 0;
++}
++
++static int mtk_nfc_resume(struct device *dev)
++{
++ struct mtk_nfc_host *host = dev_get_drvdata(dev);
++ struct mtk_nfc_saved_reg *reg = &host->saved_reg;
++ struct nand_chip *chip = &host->chip;
++ struct mtd_info *mtd = nand_to_mtd(chip);
++ int ret;
++ u32 i;
++
++ udelay(200);
++
++ ret = mtk_nfc_enable_clk(dev, &host->clk);
++ if (ret)
++ return ret;
++
++ for (i = 0; i < chip->numchips; i++) {
++ chip->select_chip(mtd, i);
++ chip->cmdfunc(mtd, NAND_CMD_RESET, -1, -1);
++ }
++
++ mtk_nfi_writel(host, reg->nfi.emp_thresh, MTKSDG1_NFI_EMPTY_THRESH);
++ mtk_nfi_writew(host, reg->nfi.pagefmt, MTKSDG1_NFI_PAGEFMT);
++ mtk_ecc_writel(host, reg->ecc.enccnfg, MTKSDG1_ECC_ENCCNFG);
++ mtk_ecc_writel(host, reg->ecc.deccnfg, MTKSDG1_ECC_DECCNFG);
++ mtk_nfi_writel(host, reg->nfi.acccon, MTKSDG1_NFI_ACCCON);
++ mtk_nfi_writew(host, reg->nfi.cnrnb, MTKSDG1_NFI_CNRNB);
++ mtk_nfi_writew(host, reg->nfi.csel, MTKSDG1_NFI_CSEL);
++
++ return 0;
++}
++
++static SIMPLE_DEV_PM_OPS(mtk_nfc_pm_ops, mtk_nfc_suspend, mtk_nfc_resume);
++#endif
++
++static const struct of_device_id mtk_nfc_id_table[] = {
++ { .compatible = "mediatek,mt2701-nfc" },
++ {}
++};
++MODULE_DEVICE_TABLE(of, mtk_nfc_id_table);
++
++static struct platform_driver mtk_nfc_driver = {
++ .probe = mtk_nfc_probe,
++ .remove = mtk_nfc_remove,
++ .driver = {
++ .name = MTK_NAME,
++ .of_match_table = mtk_nfc_id_table,
++#ifdef CONFIG_PM_SLEEP
++ .pm = &mtk_nfc_pm_ops,
++#endif
++ },
++};
++
++module_platform_driver(mtk_nfc_driver);
++
++MODULE_LICENSE("GPL");
++MODULE_AUTHOR("Xiaolei Li <xiaolei.li@mediatek.com>");
++MODULE_DESCRIPTION("MTK Nand Flash Controller Driver");
++
+diff --git a/drivers/mtd/nand/mtksdg1_nand_ecc.h b/drivers/mtd/nand/mtksdg1_nand_ecc.h
+new file mode 100644
+index 0000000..d90b196
+--- /dev/null
++++ b/drivers/mtd/nand/mtksdg1_nand_ecc.h
+@@ -0,0 +1,75 @@
++/*
++ * MTK smart device ECC engine register.
++ * Copyright (C) 2015-2016 MediaTek Inc.
++ * Author: Xiaolei.Li <xiaolei.li@mediatek.com>
++ *
++ * 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.
++ *
++ * 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.
++ */
++
++#ifndef MTKSDG1_NAND_ECC_H
++#define MTKSDG1_NAND_ECC_H
++
++/* ECC engine register definition */
++#define MTKSDG1_ECC_ENCCON (0x00)
++#define ENC_EN (1)
++#define ENC_DE (0)
++
++#define MTKSDG1_ECC_ENCCNFG (0x04)
++#define ECC_CNFG_4BIT (0)
++#define ECC_CNFG_12BIT (4)
++#define ECC_NFI_MODE BIT(5)
++#define ECC_DMA_MODE (0)
++#define ECC_ENC_MODE_MASK (0x3 << 5)
++#define ECC_MS_SHIFT (16)
++
++#define MTKSDG1_ECC_ENCDIADDR (0x08)
++
++#define MTKSDG1_ECC_ENCIDLE (0x0C)
++#define ENC_IDLE BIT(0)
++
++#define MTKSDG1_ECC_ENCPAR0 (0x10)
++#define MTKSDG1_ECC_ENCSTA (0x7C)
++
++#define MTKSDG1_ECC_ENCIRQ_EN (0x80)
++#define ENC_IRQEN BIT(0)
++
++#define MTKSDG1_ECC_ENCIRQ_STA (0x84)
++
++#define MTKSDG1_ECC_DECCON (0x100)
++#define DEC_EN (1)
++#define DEC_DE (0)
++
++#define MTKSDG1_ECC_DECCNFG (0x104)
++#define DEC_EMPTY_EN BIT(31)
++#define DEC_CNFG_FER (0x1 << 12)
++#define DEC_CNFG_EL (0x2 << 12)
++#define DEC_CNFG_CORRECT (0x3 << 12)
++
++#define MTKSDG1_ECC_DECIDLE (0x10C)
++#define DEC_IDLE BIT(0)
++
++#define MTKSDG1_ECC_DECFER (0x110)
++
++#define MTKSDG1_ECC_DECENUM0 (0x114)
++#define ERR_MASK (0x3f)
++
++#define MTKSDG1_ECC_DECDONE (0x124)
++
++#define MTKSDG1_ECC_DECEL0 (0x128)
++
++#define MTKSDG1_ECC_DECIRQ_EN (0x200)
++#define DEC_IRQEN BIT(0)
++
++#define MTKSDG1_ECC_DECIRQ_STA (0x204)
++
++#define MTKSDG1_ECC_DECFSM (0x208)
++#define DECFSM_MASK (0x7f0f0f0f)
++#define DECFSM_IDLE (0x01010101)
++#endif
+diff --git a/drivers/mtd/nand/mtksdg1_nand_nfi.h b/drivers/mtd/nand/mtksdg1_nand_nfi.h
+new file mode 100644
+index 0000000..a9aa6f6
+--- /dev/null
++++ b/drivers/mtd/nand/mtksdg1_nand_nfi.h
+@@ -0,0 +1,119 @@
++/*
++ * MTK smart device NAND Flash controller register.
++ * Copyright (C) 2015-2016 MediaTek Inc.
++ * Author: Xiaolei.Li <xiaolei.li@mediatek.com>
++ *
++ * 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.
++ *
++ * 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.
++ */
++
++#ifndef MTKSDG1_NAND_NFI_H
++#define MTKSDG1_NAND_NFI_H
++
++/* NAND controller register definition */
++#define MTKSDG1_NFI_CNFG (0x00)
++#define CNFG_AHB BIT(0)
++#define CNFG_READ_EN BIT(1)
++#define CNFG_DMA_BURST_EN BIT(2)
++#define CNFG_BYTE_RW BIT(6)
++#define CNFG_HW_ECC_EN BIT(8)
++#define CNFG_AUTO_FMT_EN BIT(9)
++#define CNFG_OP_IDLE (0 << 12)
++#define CNFG_OP_READ (1 << 12)
++#define CNFG_OP_SRD (2 << 12)
++#define CNFG_OP_PRGM (3 << 12)
++#define CNFG_OP_ERASE (4 << 12)
++#define CNFG_OP_RESET (5 << 12)
++#define CNFG_OP_CUST (6 << 12)
++
++#define MTKSDG1_NFI_PAGEFMT (0x04)
++#define PAGEFMT_FDM_ECC_SHIFT (12)
++#define PAGEFMT_FDM_SHIFT (8)
++#define PAGEFMT_SPARE_16 (0)
++#define PAGEFMT_SPARE_32 (4)
++#define PAGEFMT_SPARE_SHIFT (4)
++#define PAGEFMT_SEC_SEL_512 BIT(2)
++#define PAGEFMT_512_2K (0)
++#define PAGEFMT_2K_4K (1)
++#define PAGEFMT_4K_8K (2)
++
++/* NFI control */
++#define MTKSDG1_NFI_CON (0x08)
++#define CON_FIFO_FLUSH BIT(0)
++#define CON_NFI_RST BIT(1)
++#define CON_SRD BIT(4) /* single read */
++#define CON_BRD BIT(8) /* burst read */
++#define CON_BWR BIT(9) /* burst write */
++#define CON_SEC_SHIFT (12)
++
++/* Timming control register */
++#define MTKSDG1_NFI_ACCCON (0x0C)
++
++#define MTKSDG1_NFI_INTR_EN (0x10)
++#define INTR_RD_DONE_EN BIT(0)
++#define INTR_WR_DONE_EN BIT(1)
++#define INTR_RST_DONE_EN BIT(2)
++#define INTR_ERS_DONE_EN BIT(3)
++#define INTR_BUSY_RT_EN BIT(4)
++#define INTR_AHB_DONE_EN BIT(6)
++
++#define MTKSDG1_NFI_INTR_STA (0x14)
++
++#define MTKSDG1_NFI_CMD (0x20)
++
++#define MTKSDG1_NFI_ADDRNOB (0x30)
++#define ADDR_ROW_NOB_SHIFT (4)
++
++#define MTKSDG1_NFI_COLADDR (0x34)
++#define MTKSDG1_NFI_ROWADDR (0x38)
++#define MTKSDG1_NFI_STRDATA (0x40)
++#define MTKSDG1_NFI_CNRNB (0x44)
++#define MTKSDG1_NFI_DATAW (0x50)
++#define MTKSDG1_NFI_DATAR (0x54)
++#define MTKSDG1_NFI_PIO_DIRDY (0x58)
++#define PIO_DI_RDY (0x01)
++
++/* NFI state*/
++#define MTKSDG1_NFI_STA (0x60)
++#define STA_CMD BIT(0)
++#define STA_ADDR BIT(1)
++#define STA_DATAR BIT(2)
++#define STA_DATAW BIT(3)
++#define STA_EMP_PAGE BIT(12)
++
++#define MTKSDG1_NFI_FIFOSTA (0x64)
++
++#define MTKSDG1_NFI_ADDRCNTR (0x70)
++#define CNTR_MASK GENMASK(16, 12)
++
++#define MTKSDG1_NFI_STRADDR (0x80)
++#define MTKSDG1_NFI_BYTELEN (0x84)
++#define MTKSDG1_NFI_CSEL (0x90)
++#define MTKSDG1_NFI_IOCON (0x94)
++
++/* FDM data for sector: FDM0[L,H] - FDMF[L,H] */
++#define MTKSDG1_NFI_FDM_MAX_SEC (0x10)
++#define MTKSDG1_NFI_FDM_REG_SIZE (8)
++#define MTKSDG1_NFI_FDM0L (0xA0)
++#define MTKSDG1_NFI_FDM0M (0xA4)
++
++
++#define MTKSDG1_NFI_FIFODATA0 (0x190)
++#define MTKSDG1_NFI_DEBUG_CON1 (0x220)
++#define MTKSDG1_NFI_MASTER_STA (0x224)
++#define MASTER_STA_MASK (0x0FFF)
++
++#define MTKSDG1_NFI_RANDOM_CNFG (0x238)
++#define MTKSDG1_NFI_EMPTY_THRESH (0x23C)
++#define MTKSDG1_NFI_NAND_TYPE (0x240)
++#define MTKSDG1_NFI_ACCCON1 (0x244)
++#define MTKSDG1_NFI_DELAY_CTRL (0x248)
++
++#endif
++
+--
+1.7.10.4
+
diff --git a/target/linux/mediatek/patches-4.4/0066-net-next-mediatek-mtk_cal_txd_req-returns-bad-value.patch b/target/linux/mediatek/patches-4.4/0066-net-next-mediatek-mtk_cal_txd_req-returns-bad-value.patch
new file mode 100644
index 0000000..28899c4
--- /dev/null
+++ b/target/linux/mediatek/patches-4.4/0066-net-next-mediatek-mtk_cal_txd_req-returns-bad-value.patch
@@ -0,0 +1,31 @@
+From a160c7846e1f81b5cd6c5d0fbe5c1f8757e8884b Mon Sep 17 00:00:00 2001
+From: John Crispin <blogic@openwrt.org>
+Date: Tue, 22 Mar 2016 04:42:27 +0100
+Subject: [PATCH 66/66] net-next: mediatek: mtk_cal_txd_req() returns bad
+ value
+
+The code used to also support the PDMA engine, which had 2 packet pointers
+per descriptor. Because of this we have to divide the result by 2 and round
+it up. This is no longer needed as the code only supports QDMA.
+
+Signed-off-by: John Crispin <blogic@openwrt.org>
+---
+ drivers/net/ethernet/mediatek/mtk_eth_soc.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/net/ethernet/mediatek/mtk_eth_soc.c b/drivers/net/ethernet/mediatek/mtk_eth_soc.c
+index dd7f6e3..da9968ae 100644
+--- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c
++++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c
+@@ -693,7 +693,7 @@ static inline int mtk_cal_txd_req(struct sk_buff *skb)
+ nfrags += skb_shinfo(skb)->nr_frags;
+ }
+
+- return DIV_ROUND_UP(nfrags, 2);
++ return nfrags;
+ }
+
+ static int mtk_start_xmit(struct sk_buff *skb, struct net_device *dev)
+--
+1.7.10.4
+