diff options
author | John Crispin <john@openwrt.org> | 2016-03-22 21:14:51 +0000 |
---|---|---|
committer | John Crispin <john@openwrt.org> | 2016-03-22 21:14:51 +0000 |
commit | 30d3a8c512c259614dd3da9cd1ef8d125c981555 (patch) | |
tree | de6aa075fcb885d2109e8936a099e2a9f618482f /target/linux/mediatek | |
parent | 1898144b5f0f5cfe45f09222e6ccd1544defb619 (diff) | |
download | upstream-30d3a8c512c259614dd3da9cd1ef8d125c981555.tar.gz upstream-30d3a8c512c259614dd3da9cd1ef8d125c981555.tar.bz2 upstream-30d3a8c512c259614dd3da9cd1ef8d125c981555.zip |
mediatek: update patches
fixes trgmii on old eco and adds nand support
Signed-off-by: John Crispin <blogic@openwrt.org>
SVN-Revision: 49066
Diffstat (limited to 'target/linux/mediatek')
68 files changed, 2672 insertions, 303 deletions
diff --git a/target/linux/mediatek/base-files/etc/board.d/02_network b/target/linux/mediatek/base-files/etc/board.d/02_network index 93d3d1e435..b936d0e150 100755 --- a/target/linux/mediatek/base-files/etc/board.d/02_network +++ b/target/linux/mediatek/base-files/etc/board.d/02_network @@ -11,9 +11,9 @@ mediatek_setup_interfaces() case $board in mt7623_evb) - ucidef_set_interfaces_lan_wan "eth1" "eth0" + ucidef_set_interfaces_lan_wan "eth0" "eth1" ucidef_add_switch "switch0" \ - "0:lan" "1:lan" "2:lan" "3:lan" "4:wan" "5@eth1" "6@eth0" + "0:lan" "1:lan" "2:lan" "3:lan" "4:wan" "6@eth0" "5@eth1" ;; esac } diff --git a/target/linux/mediatek/config-4.4 b/target/linux/mediatek/config-4.4 index a236d74576..259e65cb36 100644 --- a/target/linux/mediatek/config-4.4 +++ b/target/linux/mediatek/config-4.4 @@ -56,7 +56,7 @@ CONFIG_CLKSRC_MMIO=y CONFIG_CLKSRC_OF=y CONFIG_CLKSRC_PROBE=y CONFIG_CLONE_BACKWARDS=y -CONFIG_CMDLINE="earlyprintk console=ttyS0,115200" +CONFIG_CMDLINE="earlyprintk console=ttyS0,115200 block2mtd=/dev/mmcblk0,65536,eMMC,5 mtdparts=eMMC:256k(mbr),512k(uboot),256k(config),256k(factory),32M(bootimg),32M(recovery),1024M(rootfs),2048M(usrdata),-(bmtpool)" CONFIG_CMDLINE_FORCE=y CONFIG_COMMON_CLK=y CONFIG_COMMON_CLK_MEDIATEK=y @@ -278,6 +278,7 @@ CONFIG_MMC_SDHCI=y CONFIG_MMC_SDHCI_PLTFM=y # CONFIG_MMC_TIFM_SD is not set CONFIG_MODULES_USE_ELF_REL=y +CONFIG_MTD_BLOCK2MTD=y CONFIG_MTD_M25P80=y CONFIG_MTD_SPI_NOR=y CONFIG_MTK_INFRACFG=y 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 8917ac328f..239e434dbb 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 53781dc3be..f99496ae62 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 43ed31c816..0fc766cada 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 79f849f3c9..1b45c44161 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 6bbeecbb00..505292e6a6 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 6b00dc2274..e02b7a546b 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 3d6bc709cf..c562647e36 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 0cbe27ddbb..6e80e1adc4 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 f9670e45f6..e2bb10dedd 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 c78d7f8aad..bb4eb5b84f 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 64d31334d6..fc1a35ac7d 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 81e67ca4ca..6c7632ee9f 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 35b613710f..11f2cf9ea9 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 77696b37d7..58de1fe217 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 3f91087385..974f39ea3a 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 0ed28c3340..fca1fab9f3 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 fb6e417a46..685a496f85 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 981d71f7ab..216d388572 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 05e000b5c5..188728d779 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 d52b8ebe6c..e9ce56e3af 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 053c4fe220..b7aae926c8 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 6d76ae3a7d..eefbffdf41 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 85ff55128f..af0a68f213 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 227483355a..53db649c25 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 9e12892bc4..36a7a85582 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 1ff25157e9..bf26783964 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 970860cff7..2607f93b65 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 80bb4ff3c1..24521cb369 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 f8a1cd151c..eab74bcf30 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 24e59e8e16..9039cc1f38 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 b44413681f..fd44518320 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 7f389b3e7d..5ee4ea4240 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 67ef86966c..55881e0ffd 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 aa34aaf368..e73c43a38a 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 9bfc90d504..8451679633 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 e18f47d0c3..7f7a905a7e 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 e5896658e6..ed225a5daf 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 025188347c..ad8ff5ff3b 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 c76e27bcaa..5cde24249d 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 77f46e7b48..a01f992c81 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 15445a7c3c..a7e8775edf 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 e7a23f75e1..b31f063679 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 113c8de7b4..9d2379dc96 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 30576b76b7..0550087533 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 7831eb613e..3b8a752c1c 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 b6b237dc45..f5b7f2363d 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 36702dca34..37d7fd1904 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 43e8795ae0..34a033e450 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 5bfc00f068..a3e3efd999 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 2358b6a8c0..d2bd7a866f 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 deb6eff453..fe1f4af182 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 0000000000..5e542916e0 --- /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 0000000000..89ad003855 --- /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(ð->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 0000000000..d00d9b6bcb --- /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 0000000000..4bf0947db8 --- /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 0000000000..00e5c8bfc8 --- /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 10d9d71e06..1e78d49999 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(ð->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 9ec5c89a2f..d91915ccde 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 0000000000..636575ef7e --- /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 0000000000..d68a2feaa5 --- /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 0000000000..49fbcbcc70 --- /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 0000000000..598f879f59 --- /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 0000000000..b72ecfdc8a --- /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 0000000000..533ff56877 --- /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 0000000000..c21ca1db93 --- /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 0000000000..28899c46da --- /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 + |