diff --git a/package/firmware/ath10k-firmware/Makefile b/package/firmware/ath10k-firmware/Makefile index af883e6f03..6eb7cf9a99 100644 --- a/package/firmware/ath10k-firmware/Makefile +++ b/package/firmware/ath10k-firmware/Makefile @@ -64,92 +64,92 @@ define Download/ct-firmware-htt URL_FILE:=$($(1)_FIRMWARE_FILE_CT_HTT) endef -QCA988X_FIRMWARE_FILE_CT:=firmware-2-ct-full-community-22.bin.lede.015 +QCA988X_FIRMWARE_FILE_CT:=firmware-2-ct-full-community-22.bin.lede.017 define Download/ath10k-firmware-qca988x-ct $(call Download/ct-firmware,QCA988X,) - HASH:=a3a760d0d72707feffa496b6d2266bd9195f09806553b36420b60c0f12b8b87e + HASH:=2f0bf766e400a4c5726e77b128eb8c141ebaa778526fe2c7c5083f3b17659dbf endef $(eval $(call Download,ath10k-firmware-qca988x-ct)) -QCA988X_FIRMWARE_FILE_CT_HTT:=firmware-2-ct-full-htt-mgt-community-22.bin.lede.015 +QCA988X_FIRMWARE_FILE_CT_HTT:=firmware-2-ct-full-htt-mgt-community-22.bin.lede.017 define Download/ath10k-firmware-qca988x-ct-htt $(call Download/ct-firmware-htt,QCA988X,) - HASH:=3114a54103d2b492fa1ef903769721f59953c829020d62502a1ec411ab4146d5 + HASH:=5e4285d5c6eee159a25ca14c6ce26022c32380bd7bafaedfc0c5de1510119007 endef $(eval $(call Download,ath10k-firmware-qca988x-ct-htt)) -QCA9887_FIRMWARE_FILE_CT:=firmware-2-ct-full-community-22.bin.lede.015 +QCA9887_FIRMWARE_FILE_CT:=firmware-2-ct-full-community-22.bin.lede.017 define Download/ath10k-firmware-qca9887-ct $(call Download/ct-firmware,QCA9887,ath10k-9887) - HASH:=71e8b76dfd7c786d2f57bb7df207dcd13a91d3b492cfbd28916f084d0d1bb5e7 + HASH:=4fa30e0e1972ca3b06225a731df0f93a1b73ac67fea5bf54bb55dea3bbc0da6a endef $(eval $(call Download,ath10k-firmware-qca9887-ct)) -QCA9887_FIRMWARE_FILE_CT_HTT:=firmware-2-ct-full-htt-mgt-community-22.bin.lede.015 +QCA9887_FIRMWARE_FILE_CT_HTT:=firmware-2-ct-full-htt-mgt-community-22.bin.lede.017 define Download/ath10k-firmware-qca9887-ct-htt $(call Download/ct-firmware-htt,QCA9887,ath10k-9887) - HASH:=b085e5d2239727b72bc647a76864431b8ac48438e6a33b1d55edc2222468f6ff + HASH:=dc681b6b1e45956e7c2e418ab05eee5c943d13e775209196d9bd931ff6493935 endef $(eval $(call Download,ath10k-firmware-qca9887-ct-htt)) -QCA99X0_FIRMWARE_FILE_CT:=firmware-5-ct-full-community-12.bin-lede.015 +QCA99X0_FIRMWARE_FILE_CT:=firmware-5-ct-full-community-12.bin-lede.017 define Download/ath10k-firmware-qca99x0-ct $(call Download/ct-firmware,QCA99X0,ath10k-10-4b) - HASH:=edebe2f6f169cdd05c81a8a78156fb3426a66f415e7946af2ae4b7310fca5fe3 + HASH:=289ea845d4bbae6f36b3af2a13a5eaa07097f52d10f7b7306cfc9e2dd394f889 endef $(eval $(call Download,ath10k-firmware-qca99x0-ct)) -QCA99X0_FIRMWARE_FILE_CT_HTT:=firmware-5-ct-full-htt-mgt-community-12.bin-lede.015 +QCA99X0_FIRMWARE_FILE_CT_HTT:=firmware-5-ct-full-htt-mgt-community-12.bin-lede.017 define Download/ath10k-firmware-qca99x0-ct-htt $(call Download/ct-firmware-htt,QCA99X0,ath10k-10-4b) - HASH:=1ef67fb07da9082886e4dd554dfc19256e10b500faf9e4b2a5774d0238130bae + HASH:=adedcd3d379a910bc3a5257d75f8970e11319f4cd9c1b34440d35821602a8b9c endef $(eval $(call Download,ath10k-firmware-qca99x0-ct-htt)) -QCA9984_FIRMWARE_FILE_CT:=firmware-5-ct-full-community-12.bin-lede.015 +QCA9984_FIRMWARE_FILE_CT:=firmware-5-ct-full-community-12.bin-lede.017 define Download/ath10k-firmware-qca9984-ct $(call Download/ct-firmware,QCA9984,ath10k-9984-10-4b) - HASH:=c2f04da3285aad37baef9c37c9905a31927175dd234cd4378fd56c106e5c9379 + HASH:=8175be5b3946bddc042be018ff7713e67b41b59374ef4cdd183185b59274c91a endef $(eval $(call Download,ath10k-firmware-qca9984-ct)) -QCA9984_FIRMWARE_FILE_CT_HTT:=firmware-5-ct-full-htt-mgt-community-12.bin-lede.015 +QCA9984_FIRMWARE_FILE_CT_HTT:=firmware-5-ct-full-htt-mgt-community-12.bin-lede.017 define Download/ath10k-firmware-qca9984-ct-htt $(call Download/ct-firmware-htt,QCA9984,ath10k-9984-10-4b) - HASH:=0c9ede1036750d68885e6481fa84f3cb72192b8440b47719344f7327a030f05d + HASH:=eb8b894cfe0d1aaa87f130bb7fd1815ef07b951c14df8a2ceaeb780df8f640e0 endef $(eval $(call Download,ath10k-firmware-qca9984-ct-htt)) -QCA4019_FIRMWARE_FILE_CT:=firmware-5-ct-full-community-12.bin-lede.015 +QCA4019_FIRMWARE_FILE_CT:=firmware-5-ct-full-community-12.bin-lede.017 define Download/ath10k-firmware-qca4019-ct $(call Download/ct-firmware,QCA4019,ath10k-4019-10-4b) - HASH:=1acbb7e7a6300091715a3dfe1b248c7833734961de52cc3465c1ed231a4d84f1 + HASH:=29e9f662c4cd287213877abfbb90fbabb5e32dd3710d3ade82aa94a0921972ae endef $(eval $(call Download,ath10k-firmware-qca4019-ct)) -QCA4019_FIRMWARE_FILE_CT_HTT:=firmware-5-ct-full-htt-mgt-community-12.bin-lede.015 +QCA4019_FIRMWARE_FILE_CT_HTT:=firmware-5-ct-full-htt-mgt-community-12.bin-lede.017 define Download/ath10k-firmware-qca4019-ct-htt $(call Download/ct-firmware-htt,QCA4019,ath10k-4019-10-4b) - HASH:=1065e4d3e55da84ec9e69268a4c5dba55ea33827c48a7c14bb8f0c167eb11b4c + HASH:=559c911f23856b1d3d864ce714d1bef7262bf6638e93e057ecf8d5dba48ca1e6 endef $(eval $(call Download,ath10k-firmware-qca4019-ct-htt)) -QCA9888_FIRMWARE_FILE_CT:=firmware-5-ct-full-community-12.bin-lede.015 +QCA9888_FIRMWARE_FILE_CT:=firmware-5-ct-full-community-12.bin-lede.017 define Download/ath10k-firmware-qca9888-ct $(call Download/ct-firmware,QCA9888,ath10k-9888-10-4b) - HASH:=559ebd16872a8b43443c51bb4b7d021e5b75e65893d333d9393f3f6012f4ac79 + HASH:=b295880a8b08ec2680d85daaf5f20232a0e73d9cc579bf3efd7ffae24ea340d7 endef $(eval $(call Download,ath10k-firmware-qca9888-ct)) -QCA9888_FIRMWARE_FILE_CT_HTT:=firmware-5-ct-full-htt-mgt-community-12.bin-lede.015 +QCA9888_FIRMWARE_FILE_CT_HTT:=firmware-5-ct-full-htt-mgt-community-12.bin-lede.017 define Download/ath10k-firmware-qca9888-ct-htt $(call Download/ct-firmware-htt,QCA9888,ath10k-9888-10-4b) - HASH:=4feaf5e7c4c1745f499ba8c3125db41675800ebedaea455c418c117805c5b372 + HASH:=26fe7c00df10e93373a0f9f105e85d02bb8b1cdd629183ce22a5147138336aec endef $(eval $(call Download,ath10k-firmware-qca9888-ct-htt)) diff --git a/package/kernel/ath10k-ct/Makefile b/package/kernel/ath10k-ct/Makefile index ca4fa93788..c4a55b6af5 100644 --- a/package/kernel/ath10k-ct/Makefile +++ b/package/kernel/ath10k-ct/Makefile @@ -8,9 +8,9 @@ PKG_LICENSE_FILES:= PKG_SOURCE_URL:=https://github.com/greearb/ath10k-ct.git PKG_SOURCE_PROTO:=git -PKG_SOURCE_DATE:=2020-02-18 -PKG_SOURCE_VERSION:=bed49a5f6824fcd8757fd27f6b2a4f6ea933bf2f -PKG_MIRROR_HASH:=4f16b1b44b0be6c2dba92754e78888533fdc6bfbf63ae673301a49c47c5e53ea +PKG_SOURCE_DATE:=2020-03-25 +PKG_SOURCE_VERSION:=3d173a471d3e583f2885ce68190c4387424cecc5 +PKG_MIRROR_HASH:=496279322f3cd26b262d4999cb5a8c1ea022e92a7bb0d43d008bce235abb9a65 # Build the 5.4 ath10k-ct driver version. Other option is "-4.19". # Probably this should match as closely as diff --git a/package/kernel/mac80211/files/lib/netifd/wireless/mac80211.sh b/package/kernel/mac80211/files/lib/netifd/wireless/mac80211.sh index 4a4189bbfe..08e9ee96ab 100644 --- a/package/kernel/mac80211/files/lib/netifd/wireless/mac80211.sh +++ b/package/kernel/mac80211/files/lib/netifd/wireless/mac80211.sh @@ -954,8 +954,10 @@ drv_mac80211_setup() { [ "${NEW_MD5}" = "${OLD_MD5}" ] || { ubus call hostapd.$primary_ap reload no_reload=$? - mac80211_vap_cleanup hostapd "${OLDAPLIST}" - [ -n "${NEWAPLIST}" ] && mac80211_iw_interface_add "$phy" "${NEWAPLIST%% *}" __ap || return + if [ "$no_reload" != "0" ]; then + mac80211_vap_cleanup hostapd "${OLDAPLIST}" + [ -n "${NEWAPLIST}" ] && mac80211_iw_interface_add "$phy" "${NEWAPLIST%% *}" __ap || return + fi } fi if [ "$no_reload" != "0" ]; then diff --git a/package/kernel/mac80211/patches/brcm/300-brcmfmac-add-stub-for-monitor-interface-xmit.patch b/package/kernel/mac80211/patches/brcm/300-brcmfmac-add-stub-for-monitor-interface-xmit.patch new file mode 100644 index 0000000000..8280918fa2 --- /dev/null +++ b/package/kernel/mac80211/patches/brcm/300-brcmfmac-add-stub-for-monitor-interface-xmit.patch @@ -0,0 +1,100 @@ +From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= +Date: Fri, 27 Mar 2020 13:40:50 +0100 +Subject: [PATCH] brcmfmac: add stub for monitor interface xmit +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +According to the struct net_device_ops documentation .ndo_start_xmit is +"Required; cannot be NULL.". Missing it may crash kernel easily: + +[ 341.216709] Unable to handle kernel NULL pointer dereference at virtual address 00000000 +[ 341.224836] pgd = 26088755 +[ 341.227544] [00000000] *pgd=00000000 +[ 341.231135] Internal error: Oops: 80000007 [#1] SMP ARM +[ 341.236367] Modules linked in: pppoe ppp_async iptable_nat brcmfmac xt_state xt_nat xt_conntrack xt_REDIRECT xt_MASQU +[ 341.304689] CPU: 0 PID: 0 Comm: swapper/0 Not tainted 5.4.24 #0 +[ 341.310621] Hardware name: BCM5301X +[ 341.314116] PC is at 0x0 +[ 341.316664] LR is at dev_hard_start_xmit+0x8c/0x11c +[ 341.321546] pc : [<00000000>] lr : [] psr: 60000113 +[ 341.327821] sp : c0801c30 ip : c610cf00 fp : c08048e4 +[ 341.333051] r10: c073a63a r9 : c08044dc r8 : c6c04e00 +[ 341.338283] r7 : 00000000 r6 : c60f5000 r5 : 00000000 r4 : c6a9c3c0 +[ 341.344820] r3 : 00000000 r2 : bf25a13c r1 : c60f5000 r0 : c6a9c3c0 +[ 341.351358] Flags: nZCv IRQs on FIQs on Mode SVC_32 ISA ARM Segment none +[ 341.358504] Control: 10c5387d Table: 0611c04a DAC: 00000051 +[ 341.364257] Process swapper/0 (pid: 0, stack limit = 0xc68ed0ca) +[ 341.370271] Stack: (0xc0801c30 to 0xc0802000) +[ 341.374633] 1c20: c6e7d480 c0802d00 c60f5050 c0801c6c +[ 341.382825] 1c40: c60f5000 c6a9c3c0 c6f90000 c6f9005c c6c04e00 c60f5000 00000000 c6f9005c +[ 341.391015] 1c60: 00000000 c04a033c 00f90200 00000010 c6a9c3c0 c6a9c3c0 c6f90000 00000000 +[ 341.399205] 1c80: 00000000 00000000 00000000 c046a7ac c6f9005c 00000001 fffffff4 00000000 +[ 341.407395] 1ca0: c6f90200 00000000 c60f5000 c0479550 00000000 c6f90200 c6a9c3c0 16000000 +[ 341.415586] 1cc0: 0000001c 6f4ad52f c6197040 b6df9387 36000000 c0520404 c073a80c c6a9c3c0 +[ 341.423777] 1ce0: 00000000 c6d643c0 c6a9c3c0 c0800024 00000001 00000001 c6d643c8 c6a9c3c0 +[ 341.431967] 1d00: c081b9c0 c7abca80 c610c840 c081b9c0 0000001c 00400000 c6bc5e6c c0522fb4 +[ 341.440157] 1d20: c6d64400 00000004 c6bc5e0a 00000000 c60f5000 c7abca80 c081b9c0 c0522f54 +[ 341.448348] 1d40: c6a9c3c0 c7abca80 c0803e48 c0549c94 c610c828 0000000a c0801d74 00000003 +[ 341.456538] 1d60: c6ec8f0a 00000000 c60f5000 c7abca80 c081b9c0 c0548520 0000000a 00000000 +[ 341.464728] 1d80: 00000000 003a0000 00000000 00000000 00000000 00000000 00000000 00000000 +[ 341.472919] 1da0: 000002ff 00000000 00000000 16000000 00000000 00000000 00000000 00000000 +[ 341.481110] 1dc0: 00000000 0000008f 00000000 00000000 00000000 2d132a69 c6bc5e40 00000000 +[ 341.489300] 1de0: c6bc5e40 c6a9c3c0 00000000 c6ec8e50 00000001 c054b070 00000001 00000000 +[ 341.497490] 1e00: c0807200 c6bc5e00 00000000 ffffe000 00000100 c054aea4 00000000 00000000 +[ 341.505681] 1e20: 00000122 00400000 c0802d00 c0172e80 6f56a70e ffffffff 6f56a70e c7eb9cc0 +[ 341.513871] 1e40: c7eb82c0 00000000 c0801e60 c017309c 00000000 00000000 07780000 c07382c0 +[ 341.522061] 1e60: 00000000 c7eb9cc0 c0739cc0 c0803f74 c0801e70 c0801e70 c0801ea4 c013d380 +[ 341.530253] 1e80: 00000000 000000a0 00000001 c0802084 c0802080 40000001 ffffe000 00000100 +[ 341.538443] 1ea0: c0802080 c01021e8 c8803100 10c5387d 00000000 c07341f0 c0739880 0000000a +[ 341.546633] 1ec0: c0734180 00001017 c0802d00 c062aa98 00200002 c062aa60 c8803100 c073984c +[ 341.554823] 1ee0: 00000000 00000001 00000000 c7810000 c8803100 10c5387d 00000000 c011c188 +[ 341.563014] 1f00: c073984c c015f0f8 c0804244 c0815ae4 c880210c c8802100 c0801f40 c037c584 +[ 341.571204] 1f20: c01035f8 60000013 ffffffff c0801f74 c080afd4 c0800000 10c5387d c0101a8c +[ 341.579395] 1f40: 00000000 004ac9dc c7eba4b4 c010ee60 ffffe000 c0803e68 c0803ea8 00000001 +[ 341.587587] 1f60: c080afd4 c062ca20 10c5387d 00000000 00000000 c0801f90 c01035f4 c01035f8 +[ 341.595776] 1f80: 60000013 ffffffff 00000051 00000000 ffffe000 c013ff50 000000ce c0803e40 +[ 341.603967] 1fa0: c082216c 00000000 00000001 c072ba38 10c5387d c0140214 c0822184 c0700df8 +[ 341.612157] 1fc0: ffffffff ffffffff 00000000 c070058c c072ba38 2d162e71 00000000 c0700330 +[ 341.620348] 1fe0: 00000051 10c0387d 000000ff 00a521d0 413fc090 00000000 00000000 00000000 +[ 341.628558] [] (dev_hard_start_xmit) from [] (sch_direct_xmit+0xe4/0x2bc) +[ 341.637106] [] (sch_direct_xmit) from [] (__dev_queue_xmit+0x6a4/0x72c) +[ 341.645481] [] (__dev_queue_xmit) from [] (ip6_finish_output2+0x18c/0x434) +[ 341.654112] [] (ip6_finish_output2) from [] (ip6_output+0x5c/0xd0) +[ 341.662053] [] (ip6_output) from [] (mld_sendpack+0x1a0/0x1a8) +[ 341.669640] [] (mld_sendpack) from [] (mld_ifc_timer_expire+0x1cc/0x2e4) +[ 341.678111] [] (mld_ifc_timer_expire) from [] (call_timer_fn.constprop.3+0x24/0x98) +[ 341.687527] [] (call_timer_fn.constprop.3) from [] (run_timer_softirq+0x1a8/0x1e4) +[ 341.696860] [] (run_timer_softirq) from [] (__do_softirq+0x120/0x2b0) +[ 341.705066] [] (__do_softirq) from [] (irq_exit+0x78/0x84) +[ 341.712317] [] (irq_exit) from [] (__handle_domain_irq+0x60/0xb4) +[ 341.720179] [] (__handle_domain_irq) from [] (gic_handle_irq+0x4c/0x90) +[ 341.728549] [] (gic_handle_irq) from [] (__irq_svc+0x6c/0x90) + +Fixes: 20f2c5fa3af0 ("brcmfmac: add initial support for monitor mode") +Signed-off-by: Rafał Miłecki +--- + drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.c | 9 +++++++++ + 1 file changed, 9 insertions(+) + +--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.c ++++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.c +@@ -746,9 +746,18 @@ static int brcmf_net_mon_stop(struct net + return err; + } + ++static netdev_tx_t brcmf_net_mon_start_xmit(struct sk_buff *skb, ++ struct net_device *ndev) ++{ ++ dev_kfree_skb_any(skb); ++ ++ return NETDEV_TX_OK; ++} ++ + static const struct net_device_ops brcmf_netdev_ops_mon = { + .ndo_open = brcmf_net_mon_open, + .ndo_stop = brcmf_net_mon_stop, ++ .ndo_start_xmit = brcmf_net_mon_start_xmit, + }; + + int brcmf_net_mon_attach(struct brcmf_if *ifp) diff --git a/package/kernel/mac80211/patches/brcm/860-brcmfmac-register-wiphy-s-during-module_init.patch b/package/kernel/mac80211/patches/brcm/860-brcmfmac-register-wiphy-s-during-module_init.patch index a1bcbfaec8..c18a5bfa4a 100644 --- a/package/kernel/mac80211/patches/brcm/860-brcmfmac-register-wiphy-s-during-module_init.patch +++ b/package/kernel/mac80211/patches/brcm/860-brcmfmac-register-wiphy-s-during-module_init.patch @@ -13,7 +13,7 @@ Signed-off-by: Rafał Miłecki --- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.c +++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.c -@@ -1545,6 +1545,7 @@ int __init brcmf_core_init(void) +@@ -1554,6 +1554,7 @@ int __init brcmf_core_init(void) { if (!schedule_work(&brcmf_driver_work)) return -EBUSY; diff --git a/target/linux/mediatek/files-4.19/arch/arm64/boot/dts/mediatek/mt7622-elecom-wrc-2533gent.dts b/target/linux/mediatek/files-4.19/arch/arm64/boot/dts/mediatek/mt7622-elecom-wrc-2533gent.dts new file mode 100644 index 0000000000..7a5814e3f6 --- /dev/null +++ b/target/linux/mediatek/files-4.19/arch/arm64/boot/dts/mediatek/mt7622-elecom-wrc-2533gent.dts @@ -0,0 +1,612 @@ +/* + * Copyright (c) 2017 MediaTek Inc. + * Author: Ming Huang + * Sean Wang + * + * SPDX-License-Identifier: (GPL-2.0 OR MIT) + */ + +/dts-v1/; +#include +#include + +#include "mt7622.dtsi" +#include "mt6380.dtsi" + +/ { + model = "Elecom WRC-2533"; + compatible = "elecom,wrc-2533gent", "mediatek,mt7622"; + + aliases { + led-boot = &led_power; + led-failsafe = &led_power; + led-running = &led_power; + led-upgrade = &led_power; + serial0 = &uart0; + }; + + chosen { + stdout-path = "serial0:115200n8"; + bootargs = "earlycon=uart8250,mmio32,0x11002000 swiotlb=512 console=ttyS0,115200n8"; + }; + + cpus { + cpu@0 { + proc-supply = <&mt6380_vcpu_reg>; + sram-supply = <&mt6380_vm_reg>; + }; + + cpu@1 { + proc-supply = <&mt6380_vcpu_reg>; + sram-supply = <&mt6380_vm_reg>; + }; + }; + + gpio-keys { + compatible = "gpio-keys"; + poll-interval = <100>; + + wps { + label = "wps"; + linux,code = ; + gpios = <&pio 0 GPIO_ACTIVE_HIGH>; + }; + + factory { + label = "factory"; + linux,code = ; + gpios = <&pio 102 GPIO_ACTIVE_LOW>; + }; + + switch0 { + label = "switch0"; + gpios = <&pio 1 GPIO_ACTIVE_LOW>; + linux,code = ; + linux,input-type = ; + }; + + switch1 { + label = "switch1"; + gpios = <&pio 16 GPIO_ACTIVE_LOW>; + linux,code = ; + linux,input-type = ; + }; + + switch2 { + label = "switch2"; + gpios = <&pio 17 GPIO_ACTIVE_LOW>; + linux,code = ; + linux,input-type = ; + }; + + switch3 { + label = "switch3"; + gpios = <&pio 18 GPIO_ACTIVE_LOW>; + linux,code = ; + linux,input-type = ; + }; + }; + + leds { + compatible = "gpio-leds"; + + led_power: power_g { + label = "wrc-2533:green:power"; + gpios = <&pio 2 GPIO_ACTIVE_HIGH>; + }; + + power_b { + label = "wrc-2533:blue:power"; + gpios = <&pio 19 GPIO_ACTIVE_HIGH>; + }; + + power_r { + label = "wrc-2533:red:power"; + gpios = <&pio 73 GPIO_ACTIVE_HIGH>; + }; + + usb { + label = "wrc-2533:blue:usb"; + gpios = <&pio 74 GPIO_ACTIVE_HIGH>; + }; + + wps { + label = "wrc-2533:red:wps"; + gpios = <&pio 76 GPIO_ACTIVE_LOW>; + }; + + wifi2 { + label = "wrc-2533:blue:wifi2g"; + gpios = <&pio 85 GPIO_ACTIVE_LOW>; + }; + + wifi5 { + label = "wrc-2533:blue:wifi5g"; + gpios = <&pio 91 GPIO_ACTIVE_LOW>; + }; + }; + + reg_usb_vbus: regulator { + compatible = "regulator-fixed"; + regulator-name = "usb_vbus"; + regulator-min-microvolt = <5000000>; + regulator-max-microvolt = <5000000>; + gpio = <&pio 22 GPIO_ACTIVE_LOW>; + enable-active-high; + }; + + memory { + reg = <0 0x40000000 0 0x3F000000>; + }; + + reg_1p8v: regulator-1p8v { + compatible = "regulator-fixed"; + regulator-name = "fixed-1.8V"; + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <1800000>; + regulator-always-on; + }; + + reg_3p3v: regulator-3p3v { + compatible = "regulator-fixed"; + regulator-name = "fixed-3.3V"; + regulator-min-microvolt = <3300000>; + regulator-max-microvolt = <3300000>; + regulator-boot-on; + regulator-always-on; + }; + + rtkgsw: rtkgsw@0 { + compatible = "mediatek,rtk-gsw"; + mediatek,ethsys = <ðsys>; + mediatek,mdio = <&mdio>; + mediatek,reset-pin = <&pio 54 0>; + status = "okay"; + }; +}; + +&pcie { + pinctrl-names = "default", "pcie1_pins"; + pinctrl-0 = <&pcie0_pins>; + pinctrl-1 = <&pcie1_pins>; + status = "okay"; + + pcie@0,0 { + status = "okay"; + mt7615@0,0 { + reg = <0x0000 0 0 0 0>; + mediatek,mtd-eeprom = <&factory 0x05000>; + }; + }; + + pcie@1,0 { + status = "okay"; + }; +}; + +&pio { + /* eMMC is shared pin with parallel NAND */ + emmc_pins_default: emmc-pins-default { + mux { + function = "emmc", "emmc_rst"; + groups = "emmc"; + }; + + /* "NDL0","NDL1","NDL2","NDL3","NDL4","NDL5","NDL6","NDL7", + * "NRB","NCLE" pins are used as DAT0,DAT1,DAT2,DAT3,DAT4, + * DAT5,DAT6,DAT7,CMD,CLK for eMMC respectively + */ + conf-cmd-dat { + pins = "NDL0", "NDL1", "NDL2", + "NDL3", "NDL4", "NDL5", + "NDL6", "NDL7", "NRB"; + input-enable; + bias-pull-up; + }; + + conf-clk { + pins = "NCLE"; + bias-pull-down; + }; + }; + + emmc_pins_uhs: emmc-pins-uhs { + mux { + function = "emmc"; + groups = "emmc"; + }; + + conf-cmd-dat { + pins = "NDL0", "NDL1", "NDL2", + "NDL3", "NDL4", "NDL5", + "NDL6", "NDL7", "NRB"; + input-enable; + drive-strength = <4>; + bias-pull-up; + }; + + conf-clk { + pins = "NCLE"; + drive-strength = <4>; + bias-pull-down; + }; + }; + + eth_pins: eth-pins { + mux { + function = "eth"; + groups = "mdc_mdio", "rgmii_via_gmac2"; + }; + }; + + i2c1_pins: i2c1-pins { + mux { + function = "i2c"; + groups = "i2c1_0"; + }; + }; + + i2c2_pins: i2c2-pins { + mux { + function = "i2c"; + groups = "i2c2_0"; + }; + }; + + i2s1_pins: i2s1-pins { + mux { + function = "i2s"; + groups = "i2s_out_mclk_bclk_ws", + "i2s1_in_data", + "i2s1_out_data"; + }; + + conf { + pins = "I2S1_IN", "I2S1_OUT", "I2S_BCLK", + "I2S_WS", "I2S_MCLK"; + drive-strength = <12>; + bias-pull-down; + }; + }; + + irrx_pins: irrx-pins { + mux { + function = "ir"; + groups = "ir_1_rx"; + }; + }; + + irtx_pins: irtx-pins { + mux { + function = "ir"; + groups = "ir_1_tx"; + }; + }; + + /* Parallel nand is shared pin with eMMC */ + parallel_nand_pins: parallel-nand-pins { + mux { + function = "flash"; + groups = "par_nand"; + }; + }; + + pcie0_pins: pcie0-pins { + mux { + function = "pcie"; + groups = "pcie0_pad_perst", + "pcie0_1_waken", + "pcie0_1_clkreq"; + }; + }; + + pcie1_pins: pcie1-pins { + mux { + function = "pcie"; + groups = "pcie1_pad_perst", + "pcie1_0_waken", + "pcie1_0_clkreq"; + }; + }; + + pmic_bus_pins: pmic-bus-pins { + mux { + function = "pmic"; + groups = "pmic_bus"; + }; + }; + + pwm7_pins: pwm1-2-pins { + mux { + function = "pwm"; + groups = "pwm_ch7_2"; + }; + }; + + wled_pins: wled-pins { + mux { + function = "led"; + groups = "wled"; + }; + }; + + sd0_pins_default: sd0-pins-default { + mux { + function = "sd"; + groups = "sd_0"; + }; + + /* "I2S2_OUT, "I2S4_IN"", "I2S3_IN", "I2S2_IN", + * "I2S4_OUT", "I2S3_OUT" are used as DAT0, DAT1, + * DAT2, DAT3, CMD, CLK for SD respectively. + */ + conf-cmd-data { + pins = "I2S2_OUT", "I2S4_IN", "I2S3_IN", + "I2S2_IN","I2S4_OUT"; + input-enable; + drive-strength = <8>; + bias-pull-up; + }; + conf-clk { + pins = "I2S3_OUT"; + drive-strength = <12>; + bias-pull-down; + }; + conf-cd { + pins = "TXD3"; + bias-pull-up; + }; + }; + + sd0_pins_uhs: sd0-pins-uhs { + mux { + function = "sd"; + groups = "sd_0"; + }; + + conf-cmd-data { + pins = "I2S2_OUT", "I2S4_IN", "I2S3_IN", + "I2S2_IN","I2S4_OUT"; + input-enable; + bias-pull-up; + }; + + conf-clk { + pins = "I2S3_OUT"; + bias-pull-down; + }; + }; + + /* Serial NAND is shared pin with SPI-NOR */ + serial_nand_pins: serial-nand-pins { + mux { + function = "flash"; + groups = "snfi"; + }; + }; + + spic0_pins: spic0-pins { + mux { + function = "spi"; + groups = "spic0_0"; + }; + }; + + spic1_pins: spic1-pins { + mux { + function = "spi"; + groups = "spic1_0"; + }; + }; + + /* SPI-NOR is shared pin with serial NAND */ + spi_nor_pins: spi-nor-pins { + mux { + function = "flash"; + groups = "spi_nor"; + }; + }; + + /* serial NAND is shared pin with SPI-NOR */ + serial_nand_pins: serial-nand-pins { + mux { + function = "flash"; + groups = "snfi"; + }; + }; + + uart0_pins: uart0-pins { + mux { + function = "uart"; + groups = "uart0_0_tx_rx" ; + }; + }; + + uart2_pins: uart2-pins { + mux { + function = "uart"; + groups = "uart2_1_tx_rx" ; + }; + }; + + watchdog_pins: watchdog-pins { + mux { + function = "watchdog"; + groups = "watchdog"; + }; + }; +}; + +&bch { + status = "okay"; +}; + +&btif { + status = "okay"; +}; + +&cir { + pinctrl-names = "default"; + pinctrl-0 = <&irrx_pins>; + status = "okay"; +}; + +ð { + status = "okay"; + pinctrl-names = "default"; + pinctrl-0 = <ð_pins>; + gmac0: mac@0 { + compatible = "mediatek,eth-mac"; + reg = <0>; + phy-mode = "sgmii"; + fixed-link { + speed = <1000>; + full-duplex; + pause; + }; + }; + gmac1: mac@1 { + compatible = "mediatek,eth-mac"; + reg = <1>; + phy-mode = "rgmii"; + fixed-link { + speed = <1000>; + full-duplex; + pause; + }; + }; + mdio: mdio-bus { + #address-cells = <1>; + #size-cells = <0>; + }; +}; + +&i2c1 { + pinctrl-names = "default"; + pinctrl-0 = <&i2c1_pins>; + status = "okay"; +}; + +&i2c2 { + pinctrl-names = "default"; + pinctrl-0 = <&i2c2_pins>; + status = "okay"; +}; + +&pwm { + pinctrl-names = "default"; + pinctrl-0 = <&pwm7_pins>; + status = "okay"; +}; + +&pwrap { + pinctrl-names = "default"; + pinctrl-0 = <&pmic_bus_pins>; + + status = "okay"; +}; + +&snfi { + pinctrl-names = "default"; + pinctrl-0 = <&serial_nand_pins>; + status = "okay"; + + spi_nand@0 { + #address-cells = <1>; + #size-cells = <1>; + compatible = "spi-nand"; + spi-max-frequency = <104000000>; + reg = <0>; + + partitions { + compatible = "fixed-partitions"; + #address-cells = <1>; + #size-cells = <1>; + + partition@0 { + label = "Preloader"; + reg = <0x00000 0x0080000>; + read-only; + }; + + partition@80000 { + label = "ATF"; + reg = <0x80000 0x0040000>; + read-only; + }; + + partition@c0000 { + label = "uboot"; + reg = <0xc0000 0x0080000>; + read-only; + }; + + partition@140000 { + label = "uboot-env"; + reg = <0x140000 0x0080000>; + read-only; + }; + + factory: partition@1c0000 { + label = "factory"; + reg = <0x1c0000 0x0040000>; + read-only; + }; + + partition@200000 { + label = "Kernel"; + reg = <0x200000 0x2000000>; + }; + + partition@2200000 { + label = "reserved"; + reg = <0x2200000 0x4000000>; + }; + }; + }; +}; + +&spi0 { + pinctrl-names = "default"; + pinctrl-0 = <&spic0_pins>; + status = "okay"; +}; + +&spi1 { + pinctrl-names = "default"; + pinctrl-0 = <&spic1_pins>; + status = "okay"; +}; + +&ssusb { + vusb33-supply = <®_3p3v>; + vbus-supply = <®_usb_vbus>; + status = "okay"; +}; + +&u3phy { + status = "okay"; +}; + +&uart0 { + pinctrl-names = "default"; + pinctrl-0 = <&uart0_pins>; + status = "okay"; +}; + +&uart2 { + pinctrl-names = "default"; + pinctrl-0 = <&uart2_pins>; + status = "okay"; +}; + +&watchdog { + pinctrl-names = "default"; + pinctrl-0 = <&watchdog_pins>; + status = "okay"; +}; + +&wmac { + mediatek,mtd-eeprom = <&factory 0x0000>; + status = "okay"; +}; diff --git a/target/linux/mediatek/files-5.4/arch/arm64/boot/dts/mediatek/mt7622-elecom-wrc-2533gent.dts b/target/linux/mediatek/files-5.4/arch/arm64/boot/dts/mediatek/mt7622-elecom-wrc-2533gent.dts new file mode 100644 index 0000000000..7a5814e3f6 --- /dev/null +++ b/target/linux/mediatek/files-5.4/arch/arm64/boot/dts/mediatek/mt7622-elecom-wrc-2533gent.dts @@ -0,0 +1,612 @@ +/* + * Copyright (c) 2017 MediaTek Inc. + * Author: Ming Huang + * Sean Wang + * + * SPDX-License-Identifier: (GPL-2.0 OR MIT) + */ + +/dts-v1/; +#include +#include + +#include "mt7622.dtsi" +#include "mt6380.dtsi" + +/ { + model = "Elecom WRC-2533"; + compatible = "elecom,wrc-2533gent", "mediatek,mt7622"; + + aliases { + led-boot = &led_power; + led-failsafe = &led_power; + led-running = &led_power; + led-upgrade = &led_power; + serial0 = &uart0; + }; + + chosen { + stdout-path = "serial0:115200n8"; + bootargs = "earlycon=uart8250,mmio32,0x11002000 swiotlb=512 console=ttyS0,115200n8"; + }; + + cpus { + cpu@0 { + proc-supply = <&mt6380_vcpu_reg>; + sram-supply = <&mt6380_vm_reg>; + }; + + cpu@1 { + proc-supply = <&mt6380_vcpu_reg>; + sram-supply = <&mt6380_vm_reg>; + }; + }; + + gpio-keys { + compatible = "gpio-keys"; + poll-interval = <100>; + + wps { + label = "wps"; + linux,code = ; + gpios = <&pio 0 GPIO_ACTIVE_HIGH>; + }; + + factory { + label = "factory"; + linux,code = ; + gpios = <&pio 102 GPIO_ACTIVE_LOW>; + }; + + switch0 { + label = "switch0"; + gpios = <&pio 1 GPIO_ACTIVE_LOW>; + linux,code = ; + linux,input-type = ; + }; + + switch1 { + label = "switch1"; + gpios = <&pio 16 GPIO_ACTIVE_LOW>; + linux,code = ; + linux,input-type = ; + }; + + switch2 { + label = "switch2"; + gpios = <&pio 17 GPIO_ACTIVE_LOW>; + linux,code = ; + linux,input-type = ; + }; + + switch3 { + label = "switch3"; + gpios = <&pio 18 GPIO_ACTIVE_LOW>; + linux,code = ; + linux,input-type = ; + }; + }; + + leds { + compatible = "gpio-leds"; + + led_power: power_g { + label = "wrc-2533:green:power"; + gpios = <&pio 2 GPIO_ACTIVE_HIGH>; + }; + + power_b { + label = "wrc-2533:blue:power"; + gpios = <&pio 19 GPIO_ACTIVE_HIGH>; + }; + + power_r { + label = "wrc-2533:red:power"; + gpios = <&pio 73 GPIO_ACTIVE_HIGH>; + }; + + usb { + label = "wrc-2533:blue:usb"; + gpios = <&pio 74 GPIO_ACTIVE_HIGH>; + }; + + wps { + label = "wrc-2533:red:wps"; + gpios = <&pio 76 GPIO_ACTIVE_LOW>; + }; + + wifi2 { + label = "wrc-2533:blue:wifi2g"; + gpios = <&pio 85 GPIO_ACTIVE_LOW>; + }; + + wifi5 { + label = "wrc-2533:blue:wifi5g"; + gpios = <&pio 91 GPIO_ACTIVE_LOW>; + }; + }; + + reg_usb_vbus: regulator { + compatible = "regulator-fixed"; + regulator-name = "usb_vbus"; + regulator-min-microvolt = <5000000>; + regulator-max-microvolt = <5000000>; + gpio = <&pio 22 GPIO_ACTIVE_LOW>; + enable-active-high; + }; + + memory { + reg = <0 0x40000000 0 0x3F000000>; + }; + + reg_1p8v: regulator-1p8v { + compatible = "regulator-fixed"; + regulator-name = "fixed-1.8V"; + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <1800000>; + regulator-always-on; + }; + + reg_3p3v: regulator-3p3v { + compatible = "regulator-fixed"; + regulator-name = "fixed-3.3V"; + regulator-min-microvolt = <3300000>; + regulator-max-microvolt = <3300000>; + regulator-boot-on; + regulator-always-on; + }; + + rtkgsw: rtkgsw@0 { + compatible = "mediatek,rtk-gsw"; + mediatek,ethsys = <ðsys>; + mediatek,mdio = <&mdio>; + mediatek,reset-pin = <&pio 54 0>; + status = "okay"; + }; +}; + +&pcie { + pinctrl-names = "default", "pcie1_pins"; + pinctrl-0 = <&pcie0_pins>; + pinctrl-1 = <&pcie1_pins>; + status = "okay"; + + pcie@0,0 { + status = "okay"; + mt7615@0,0 { + reg = <0x0000 0 0 0 0>; + mediatek,mtd-eeprom = <&factory 0x05000>; + }; + }; + + pcie@1,0 { + status = "okay"; + }; +}; + +&pio { + /* eMMC is shared pin with parallel NAND */ + emmc_pins_default: emmc-pins-default { + mux { + function = "emmc", "emmc_rst"; + groups = "emmc"; + }; + + /* "NDL0","NDL1","NDL2","NDL3","NDL4","NDL5","NDL6","NDL7", + * "NRB","NCLE" pins are used as DAT0,DAT1,DAT2,DAT3,DAT4, + * DAT5,DAT6,DAT7,CMD,CLK for eMMC respectively + */ + conf-cmd-dat { + pins = "NDL0", "NDL1", "NDL2", + "NDL3", "NDL4", "NDL5", + "NDL6", "NDL7", "NRB"; + input-enable; + bias-pull-up; + }; + + conf-clk { + pins = "NCLE"; + bias-pull-down; + }; + }; + + emmc_pins_uhs: emmc-pins-uhs { + mux { + function = "emmc"; + groups = "emmc"; + }; + + conf-cmd-dat { + pins = "NDL0", "NDL1", "NDL2", + "NDL3", "NDL4", "NDL5", + "NDL6", "NDL7", "NRB"; + input-enable; + drive-strength = <4>; + bias-pull-up; + }; + + conf-clk { + pins = "NCLE"; + drive-strength = <4>; + bias-pull-down; + }; + }; + + eth_pins: eth-pins { + mux { + function = "eth"; + groups = "mdc_mdio", "rgmii_via_gmac2"; + }; + }; + + i2c1_pins: i2c1-pins { + mux { + function = "i2c"; + groups = "i2c1_0"; + }; + }; + + i2c2_pins: i2c2-pins { + mux { + function = "i2c"; + groups = "i2c2_0"; + }; + }; + + i2s1_pins: i2s1-pins { + mux { + function = "i2s"; + groups = "i2s_out_mclk_bclk_ws", + "i2s1_in_data", + "i2s1_out_data"; + }; + + conf { + pins = "I2S1_IN", "I2S1_OUT", "I2S_BCLK", + "I2S_WS", "I2S_MCLK"; + drive-strength = <12>; + bias-pull-down; + }; + }; + + irrx_pins: irrx-pins { + mux { + function = "ir"; + groups = "ir_1_rx"; + }; + }; + + irtx_pins: irtx-pins { + mux { + function = "ir"; + groups = "ir_1_tx"; + }; + }; + + /* Parallel nand is shared pin with eMMC */ + parallel_nand_pins: parallel-nand-pins { + mux { + function = "flash"; + groups = "par_nand"; + }; + }; + + pcie0_pins: pcie0-pins { + mux { + function = "pcie"; + groups = "pcie0_pad_perst", + "pcie0_1_waken", + "pcie0_1_clkreq"; + }; + }; + + pcie1_pins: pcie1-pins { + mux { + function = "pcie"; + groups = "pcie1_pad_perst", + "pcie1_0_waken", + "pcie1_0_clkreq"; + }; + }; + + pmic_bus_pins: pmic-bus-pins { + mux { + function = "pmic"; + groups = "pmic_bus"; + }; + }; + + pwm7_pins: pwm1-2-pins { + mux { + function = "pwm"; + groups = "pwm_ch7_2"; + }; + }; + + wled_pins: wled-pins { + mux { + function = "led"; + groups = "wled"; + }; + }; + + sd0_pins_default: sd0-pins-default { + mux { + function = "sd"; + groups = "sd_0"; + }; + + /* "I2S2_OUT, "I2S4_IN"", "I2S3_IN", "I2S2_IN", + * "I2S4_OUT", "I2S3_OUT" are used as DAT0, DAT1, + * DAT2, DAT3, CMD, CLK for SD respectively. + */ + conf-cmd-data { + pins = "I2S2_OUT", "I2S4_IN", "I2S3_IN", + "I2S2_IN","I2S4_OUT"; + input-enable; + drive-strength = <8>; + bias-pull-up; + }; + conf-clk { + pins = "I2S3_OUT"; + drive-strength = <12>; + bias-pull-down; + }; + conf-cd { + pins = "TXD3"; + bias-pull-up; + }; + }; + + sd0_pins_uhs: sd0-pins-uhs { + mux { + function = "sd"; + groups = "sd_0"; + }; + + conf-cmd-data { + pins = "I2S2_OUT", "I2S4_IN", "I2S3_IN", + "I2S2_IN","I2S4_OUT"; + input-enable; + bias-pull-up; + }; + + conf-clk { + pins = "I2S3_OUT"; + bias-pull-down; + }; + }; + + /* Serial NAND is shared pin with SPI-NOR */ + serial_nand_pins: serial-nand-pins { + mux { + function = "flash"; + groups = "snfi"; + }; + }; + + spic0_pins: spic0-pins { + mux { + function = "spi"; + groups = "spic0_0"; + }; + }; + + spic1_pins: spic1-pins { + mux { + function = "spi"; + groups = "spic1_0"; + }; + }; + + /* SPI-NOR is shared pin with serial NAND */ + spi_nor_pins: spi-nor-pins { + mux { + function = "flash"; + groups = "spi_nor"; + }; + }; + + /* serial NAND is shared pin with SPI-NOR */ + serial_nand_pins: serial-nand-pins { + mux { + function = "flash"; + groups = "snfi"; + }; + }; + + uart0_pins: uart0-pins { + mux { + function = "uart"; + groups = "uart0_0_tx_rx" ; + }; + }; + + uart2_pins: uart2-pins { + mux { + function = "uart"; + groups = "uart2_1_tx_rx" ; + }; + }; + + watchdog_pins: watchdog-pins { + mux { + function = "watchdog"; + groups = "watchdog"; + }; + }; +}; + +&bch { + status = "okay"; +}; + +&btif { + status = "okay"; +}; + +&cir { + pinctrl-names = "default"; + pinctrl-0 = <&irrx_pins>; + status = "okay"; +}; + +ð { + status = "okay"; + pinctrl-names = "default"; + pinctrl-0 = <ð_pins>; + gmac0: mac@0 { + compatible = "mediatek,eth-mac"; + reg = <0>; + phy-mode = "sgmii"; + fixed-link { + speed = <1000>; + full-duplex; + pause; + }; + }; + gmac1: mac@1 { + compatible = "mediatek,eth-mac"; + reg = <1>; + phy-mode = "rgmii"; + fixed-link { + speed = <1000>; + full-duplex; + pause; + }; + }; + mdio: mdio-bus { + #address-cells = <1>; + #size-cells = <0>; + }; +}; + +&i2c1 { + pinctrl-names = "default"; + pinctrl-0 = <&i2c1_pins>; + status = "okay"; +}; + +&i2c2 { + pinctrl-names = "default"; + pinctrl-0 = <&i2c2_pins>; + status = "okay"; +}; + +&pwm { + pinctrl-names = "default"; + pinctrl-0 = <&pwm7_pins>; + status = "okay"; +}; + +&pwrap { + pinctrl-names = "default"; + pinctrl-0 = <&pmic_bus_pins>; + + status = "okay"; +}; + +&snfi { + pinctrl-names = "default"; + pinctrl-0 = <&serial_nand_pins>; + status = "okay"; + + spi_nand@0 { + #address-cells = <1>; + #size-cells = <1>; + compatible = "spi-nand"; + spi-max-frequency = <104000000>; + reg = <0>; + + partitions { + compatible = "fixed-partitions"; + #address-cells = <1>; + #size-cells = <1>; + + partition@0 { + label = "Preloader"; + reg = <0x00000 0x0080000>; + read-only; + }; + + partition@80000 { + label = "ATF"; + reg = <0x80000 0x0040000>; + read-only; + }; + + partition@c0000 { + label = "uboot"; + reg = <0xc0000 0x0080000>; + read-only; + }; + + partition@140000 { + label = "uboot-env"; + reg = <0x140000 0x0080000>; + read-only; + }; + + factory: partition@1c0000 { + label = "factory"; + reg = <0x1c0000 0x0040000>; + read-only; + }; + + partition@200000 { + label = "Kernel"; + reg = <0x200000 0x2000000>; + }; + + partition@2200000 { + label = "reserved"; + reg = <0x2200000 0x4000000>; + }; + }; + }; +}; + +&spi0 { + pinctrl-names = "default"; + pinctrl-0 = <&spic0_pins>; + status = "okay"; +}; + +&spi1 { + pinctrl-names = "default"; + pinctrl-0 = <&spic1_pins>; + status = "okay"; +}; + +&ssusb { + vusb33-supply = <®_3p3v>; + vbus-supply = <®_usb_vbus>; + status = "okay"; +}; + +&u3phy { + status = "okay"; +}; + +&uart0 { + pinctrl-names = "default"; + pinctrl-0 = <&uart0_pins>; + status = "okay"; +}; + +&uart2 { + pinctrl-names = "default"; + pinctrl-0 = <&uart2_pins>; + status = "okay"; +}; + +&watchdog { + pinctrl-names = "default"; + pinctrl-0 = <&watchdog_pins>; + status = "okay"; +}; + +&wmac { + mediatek,mtd-eeprom = <&factory 0x0000>; + status = "okay"; +}; diff --git a/target/linux/mediatek/image/mt7622.mk b/target/linux/mediatek/image/mt7622.mk index 0d8af5a9ee..0aea5dc488 100644 --- a/target/linux/mediatek/image/mt7622.mk +++ b/target/linux/mediatek/image/mt7622.mk @@ -16,3 +16,14 @@ define Device/bpi_bananapi-r64 DEVICE_PACKAGES := kmod-usb-ohci kmod-usb2 kmod-usb3 kmod-ata-ahci-mtk endef TARGET_DEVICES += bpi_bananapi-r64 + +define Device/elecom-wrc-2533gent + DEVICE_VENDOR := Elecom + DEVICE_MODEL := Elecom WRC-2533GENT + DEVICE_DTS := mt7622-elecom-wrc-2533gent + DEVICE_DTS_DIR := $(DTS_DIR)/mediatek + DEVICE_PACKAGES := kmod-usb-ohci kmod-usb2 kmod-usb3 \ + kmod-mt7615e mt7622bt-firmware swconfig + SUPPORTED_DEVICES := elecom,wrc-2533gent +endef +TARGET_DEVICES += elecom-wrc-2533gent diff --git a/target/linux/mediatek/mt7622/base-files/etc/board.d/02_network b/target/linux/mediatek/mt7622/base-files/etc/board.d/02_network index d719a35dec..18ad24d046 100755 --- a/target/linux/mediatek/mt7622/base-files/etc/board.d/02_network +++ b/target/linux/mediatek/mt7622/base-files/etc/board.d/02_network @@ -9,6 +9,10 @@ mediatek_setup_interfaces() local board="$1" case $board in + 'elecom,wrc-2533gent') + ucidef_add_switch "switch0" \ + "0:lan" "1:lan" "2:lan" "3:lan" "4:wan" "6u@eth0" "5u@eth1" + ;; esac } diff --git a/target/linux/mediatek/mt7622/base-files/lib/upgrade/platform.sh b/target/linux/mediatek/mt7622/base-files/lib/upgrade/platform.sh index f2264592a4..c5b4cf306b 100755 --- a/target/linux/mediatek/mt7622/base-files/lib/upgrade/platform.sh +++ b/target/linux/mediatek/mt7622/base-files/lib/upgrade/platform.sh @@ -8,14 +8,23 @@ platform_do_upgrade() { esac } -PART_NAME=firmware +PART_NAME=Kernel platform_check_image() { local board=$(board_name) + local magic="$(get_magic_long "$1")" [ "$#" -gt 1 ] && return 1 case "$board" in + elecom,wrc-2533gent) + [ "$magic" != "d00dfeed" ] && { + echo "Invalid image type." + return 1 + } + return 0 + ;; + *) echo "Sysupgrade is not supported on your board yet." return 1 diff --git a/target/linux/mediatek/mt7622/config-5.4 b/target/linux/mediatek/mt7622/config-5.4 index f867844885..f8bb25ee0b 100755 --- a/target/linux/mediatek/mt7622/config-5.4 +++ b/target/linux/mediatek/mt7622/config-5.4 @@ -1,7 +1,5 @@ CONFIG_64BIT=y CONFIG_AHCI_MTK=y -# CONFIG_ARCH_AGILEX is not set -# CONFIG_ARCH_BITMAIN is not set CONFIG_ARCH_CLOCKSOURCE_DATA=y CONFIG_ARCH_DMA_ADDR_T_64BIT=y CONFIG_ARCH_ENABLE_MEMORY_HOTPLUG=y @@ -83,27 +81,18 @@ CONFIG_ARCH_WANT_DEFAULT_TOPDOWN_MMAP_LAYOUT=y CONFIG_ARCH_WANT_FRAME_POINTERS=y CONFIG_ARCH_WANT_HUGE_PMD_SHARE=y CONFIG_ARM64=y -# CONFIG_ARM64_16K_PAGES is not set CONFIG_ARM64_4K_PAGES=y -# CONFIG_ARM64_64K_PAGES is not set CONFIG_ARM64_CNP=y CONFIG_ARM64_CONT_SHIFT=4 -# CONFIG_ARM64_CRYPTO is not set CONFIG_ARM64_ERRATUM_1165522=y CONFIG_ARM64_ERRATUM_1286807=y CONFIG_ARM64_ERRATUM_1418040=y CONFIG_ARM64_HW_AFDBM=y -# CONFIG_ARM64_LSE_ATOMICS is not set -# CONFIG_ARM64_MODULE_PLTS is not set CONFIG_ARM64_PAGE_SHIFT=12 CONFIG_ARM64_PAN=y CONFIG_ARM64_PA_BITS=48 CONFIG_ARM64_PA_BITS_48=y -# CONFIG_ARM64_PMEM is not set -# CONFIG_ARM64_PSEUDO_NMI is not set -# CONFIG_ARM64_PTDUMP_DEBUGFS is not set CONFIG_ARM64_PTR_AUTH=y -# CONFIG_ARM64_RANDOMIZE_TEXT_OFFSET is not set CONFIG_ARM64_SSBD=y CONFIG_ARM64_SVE=y # CONFIG_ARM64_SW_TTBR0_PAN is not set @@ -111,7 +100,6 @@ CONFIG_ARM64_TAGGED_ADDR_ABI=y CONFIG_ARM64_UAO=y CONFIG_ARM64_VA_BITS=39 CONFIG_ARM64_VA_BITS_39=y -# CONFIG_ARM64_VA_BITS_48 is not set CONFIG_ARM64_VHE=y CONFIG_ARM64_WORKAROUND_REPEAT_TLBI=y # CONFIG_ARMV8_DEPRECATED is not set @@ -126,10 +114,8 @@ CONFIG_ARM_GIC_V3_ITS_PCI=y CONFIG_ARM_MEDIATEK_CPUFREQ=y CONFIG_ARM_PMU=y CONFIG_ARM_PSCI_FW=y -# CONFIG_ARM_SP805_WATCHDOG is not set CONFIG_ATA=y CONFIG_AUDIT_ARCH_COMPAT_GENERIC=y -# CONFIG_BACKLIGHT_CLASS_DEVICE is not set CONFIG_BLK_DEV_SD=y CONFIG_BLK_MQ_PCI=y CONFIG_BLK_PM=y @@ -153,10 +139,7 @@ CONFIG_BT_LE=y CONFIG_BT_MTKUART=y CONFIG_BT_QCA=y CONFIG_CAVIUM_TX2_ERRATUM_219=y -CONFIG_CC_CAN_LINK=y -CONFIG_CC_HAS_ASM_INLINE=y CONFIG_CC_HAS_KASAN_GENERIC=y -CONFIG_CC_HAS_WARN_MAYBE_UNINITIALIZED=y CONFIG_CLKDEV_LOOKUP=y CONFIG_CLKSRC_MMIO=y CONFIG_CLOCK_THERMAL=y @@ -195,10 +178,10 @@ CONFIG_COMMON_CLK_MT8516=y CONFIG_COMPAT=y CONFIG_COMPAT_32BIT_TIME=y CONFIG_COMPAT_BINFMT_ELF=y +CONFIG_COMPAT_NETLINK_MESSAGES=y CONFIG_COMPAT_OLD_SIGACTION=y CONFIG_CONSOLE_LOGLEVEL_DEFAULT=15 # CONFIG_CPUFREQ_DT is not set -# CONFIG_CPU_BIG_ENDIAN is not set CONFIG_CPU_FREQ=y # CONFIG_CPU_FREQ_DEFAULT_GOV_PERFORMANCE is not set CONFIG_CPU_FREQ_DEFAULT_GOV_USERSPACE=y @@ -214,10 +197,8 @@ CONFIG_CPU_FREQ_STAT=y CONFIG_CPU_RMAP=y CONFIG_CPU_THERMAL=y CONFIG_CRC16=y -CONFIG_CRYPTO_ACOMP2=y CONFIG_CRYPTO_AEAD=y CONFIG_CRYPTO_AEAD2=y -CONFIG_CRYPTO_AKCIPHER2=y CONFIG_CRYPTO_CMAC=y CONFIG_CRYPTO_DRBG=y CONFIG_CRYPTO_DRBG_HMAC=y @@ -231,7 +212,6 @@ CONFIG_CRYPTO_HMAC=y CONFIG_CRYPTO_JITTERENTROPY=y CONFIG_CRYPTO_KPP=y CONFIG_CRYPTO_KPP2=y -CONFIG_CRYPTO_LIB_AES=y CONFIG_CRYPTO_LIB_SHA256=y CONFIG_CRYPTO_MANAGER=y CONFIG_CRYPTO_MANAGER2=y @@ -258,7 +238,6 @@ CONFIG_DYNAMIC_DEBUG=y CONFIG_EDAC_SUPPORT=y CONFIG_EFI_EARLYCON=y CONFIG_EINT_MTK=y -# CONFIG_ENERGY_MODEL is not set CONFIG_FIXED_PHY=y CONFIG_FIX_EARLYCON_MEM=y # CONFIG_FLATMEM_MANUAL is not set @@ -266,7 +245,6 @@ CONFIG_FONT_8x16=y CONFIG_FONT_AUTOSELECT=y CONFIG_FONT_SUPPORT=y CONFIG_FRAME_POINTER=y -# CONFIG_FSL_QDMA is not set CONFIG_FUJITSU_ERRATUM_010001=y CONFIG_FW_LOADER_PAGED_BUF=y CONFIG_GENERIC_ALLOCATOR=y @@ -299,7 +277,6 @@ CONFIG_GENERIC_STRNLEN_USER=y CONFIG_GENERIC_TIME_VSYSCALL=y CONFIG_GLOB=y CONFIG_GPIOLIB=y -# CONFIG_HABANA_AI is not set CONFIG_HANDLE_DOMAIN_IRQ=y CONFIG_HARDEN_BRANCH_PREDICTOR=y CONFIG_HARDIRQS_SW_RESEND=y @@ -331,6 +308,7 @@ CONFIG_HAVE_CLK_PREPARE=y CONFIG_HAVE_CMPXCHG_DOUBLE=y CONFIG_HAVE_CMPXCHG_LOCAL=y CONFIG_HAVE_CONTEXT_TRACKING=y +CONFIG_HAVE_COPY_THREAD_TLS=y CONFIG_HAVE_C_RECORDMCOUNT=y CONFIG_HAVE_DEBUG_BUGVERBOSE=y CONFIG_HAVE_DEBUG_KMEMLEAK=y @@ -362,17 +340,12 @@ CONFIG_HAVE_SYSCALL_TRACEPOINTS=y CONFIG_HAVE_UID16=y CONFIG_HAVE_VIRT_CPU_ACCOUNTING_GEN=y CONFIG_HOLES_IN_ZONE=y -# CONFIG_HUGETLBFS is not set CONFIG_ICPLUS_PHY=y -# CONFIG_IGC is not set CONFIG_IIO=y -# CONFIG_IIO_BUFFER is not set -# CONFIG_IIO_TRIGGER is not set CONFIG_IKCONFIG=y CONFIG_IKCONFIG_PROC=y CONFIG_ILLEGAL_POINTER_VALUE=0xdead000000000000 CONFIG_INITRAMFS_SOURCE="" -CONFIG_INIT_STACK_NONE=y CONFIG_INLINE_READ_LOCK=y CONFIG_INLINE_READ_LOCK_BH=y CONFIG_INLINE_READ_LOCK_IRQ=y @@ -412,11 +385,9 @@ CONFIG_MEDIATEK_MT6577_AUXADC=y CONFIG_MEDIATEK_WATCHDOG=y CONFIG_MEDIA_SUPPORT=y CONFIG_MEMFD_CREATE=y -# CONFIG_MEMORY_HOTPLUG is not set CONFIG_MESSAGE_LOGLEVEL_DEFAULT=7 CONFIG_MFD_SYSCON=y CONFIG_MIGRATION=y -# CONFIG_MISC_ALCOR_PCI is not set CONFIG_MMC=y CONFIG_MMC_MTK=y # CONFIG_MMC_TIFM_SD is not set @@ -424,8 +395,13 @@ CONFIG_MODULES_TREE_LOOKUP=y CONFIG_MODULES_USE_ELF_RELA=y CONFIG_MT753X_GSW=y CONFIG_MTD_NAND_CORE=y +CONFIG_MTD_NAND_ECC_SW_HAMMING=y +CONFIG_MTD_NAND_MTK=y +CONFIG_MTD_RAW_NAND=y CONFIG_MTD_SPI_NAND=y CONFIG_MTD_SPI_NOR=y +CONFIG_MTD_SPLIT_FIRMWARE=y +CONFIG_MTD_SPLIT_FIT_FW=y # CONFIG_MTK_CMDQ is not set # CONFIG_MTK_CQDMA is not set CONFIG_MTK_EFUSE=y @@ -446,9 +422,7 @@ CONFIG_NLS=y CONFIG_NO_HZ_COMMON=y CONFIG_NO_HZ_IDLE=y CONFIG_NR_CPUS=2 -# CONFIG_NUMA is not set CONFIG_NVMEM=y -# CONFIG_NVMEM_REBOOT_MODE is not set CONFIG_NVMEM_SYSFS=y # CONFIG_OCTEONTX2_AF is not set CONFIG_OF=y @@ -469,7 +443,6 @@ CONFIG_PCIE_MEDIATEK=y CONFIG_PCI_DEBUG=y CONFIG_PCI_DOMAINS=y CONFIG_PCI_DOMAINS_GENERIC=y -# CONFIG_PCI_MESON is not set CONFIG_PCI_MSI=y CONFIG_PCI_MSI_IRQ_DOMAIN=y CONFIG_PERF_EVENTS=y @@ -491,9 +464,7 @@ CONFIG_PINCTRL_MT8516=y CONFIG_PINCTRL_MTK=y CONFIG_PINCTRL_MTK_MOORE=y CONFIG_PM=y -# CONFIG_PMS7003 is not set CONFIG_PM_CLK=y -# CONFIG_PM_DEBUG is not set CONFIG_PM_GENERIC_DOMAINS=y CONFIG_PM_GENERIC_DOMAINS_OF=y CONFIG_PM_OPP=y @@ -507,7 +478,6 @@ CONFIG_PWM_MEDIATEK=y CONFIG_PWM_SYSFS=y CONFIG_QUEUED_RWLOCKS=y CONFIG_QUEUED_SPINLOCKS=y -# CONFIG_RANDOMIZE_BASE is not set CONFIG_RAS=y CONFIG_RATIONAL=y # CONFIG_RAVE_SP_CORE is not set @@ -517,12 +487,10 @@ CONFIG_REALTEK_PHY=y CONFIG_REFCOUNT_FULL=y CONFIG_REGMAP=y CONFIG_REGMAP_MMIO=y -CONFIG_REGMAP_SPI=y CONFIG_REGULATOR=y CONFIG_REGULATOR_FIXED_VOLTAGE=y CONFIG_REGULATOR_MT6380=y CONFIG_RESET_CONTROLLER=y -CONFIG_RFKILL_LEDS=y CONFIG_RFS_ACCEL=y CONFIG_RODATA_FULL_DEFAULT_ENABLED=y CONFIG_RPS=y @@ -532,18 +500,15 @@ CONFIG_RTC_I2C_AND_SPI=y CONFIG_RWSEM_SPIN_ON_OWNER=y CONFIG_SCHED_MC=y CONFIG_SCSI=y -# CONFIG_SCSI_MYRS is not set # CONFIG_SECTION_MISMATCH_WARN_ONLY is not set CONFIG_SERIAL_8250_FSL=y CONFIG_SERIAL_8250_MT6577=y CONFIG_SERIAL_8250_NR_UARTS=3 CONFIG_SERIAL_8250_RUNTIME_UARTS=3 -# CONFIG_SERIAL_AMBA_PL011 is not set CONFIG_SERIAL_DEV_BUS=y CONFIG_SERIAL_DEV_CTRL_TTYPORT=y CONFIG_SERIAL_MCTRL_GPIO=y CONFIG_SERIAL_OF_PLATFORM=y -CONFIG_SGL_ALLOC=y CONFIG_SG_POOL=y CONFIG_SMP=y CONFIG_SPARSEMEM=y @@ -556,6 +521,8 @@ CONFIG_SPI=y CONFIG_SPI_MASTER=y CONFIG_SPI_MEM=y CONFIG_SPI_MT65XX=y +# CONFIG_SPI_MTK_NOR is not set +CONFIG_SPI_MTK_SNFI=y CONFIG_SRCU=y CONFIG_SWIOTLB=y CONFIG_SWPHY=y @@ -577,7 +544,6 @@ CONFIG_THREAD_INFO_IN_TASK=y CONFIG_TICK_CPU_ACCOUNTING=y CONFIG_TIMER_OF=y CONFIG_TIMER_PROBE=y -# CONFIG_TI_CPSW_PHY_SEL is not set CONFIG_TREE_RCU=y CONFIG_TREE_SRCU=y # CONFIG_UCLAMP_TASK is not set diff --git a/target/linux/mediatek/mt7629/config-5.4 b/target/linux/mediatek/mt7629/config-5.4 index 44cb3a1752..3805eba40e 100644 --- a/target/linux/mediatek/mt7629/config-5.4 +++ b/target/linux/mediatek/mt7629/config-5.4 @@ -238,6 +238,9 @@ CONFIG_MODULES_TREE_LOOKUP=y CONFIG_MODULES_USE_ELF_REL=y CONFIG_MT753X_GSW=y CONFIG_MTD_NAND_CORE=y +CONFIG_MTD_NAND_ECC_SW_HAMMING=y +CONFIG_MTD_NAND_MTK=y +CONFIG_MTD_RAW_NAND=y CONFIG_MTD_SPI_NAND=y CONFIG_MTD_SPI_NOR=y CONFIG_MTD_SPLIT_FIRMWARE=y @@ -335,8 +338,9 @@ CONFIG_SPARSE_IRQ=y CONFIG_SPI=y CONFIG_SPI_MASTER=y CONFIG_SPI_MEM=y -# CONFIG_SPI_MT65XX is not set -CONFIG_SPI_MTK_NOR=y +CONFIG_SPI_MT65XX=y +# CONFIG_SPI_MTK_NOR is not set +CONFIG_SPI_MTK_SNFI=y CONFIG_SRCU=y CONFIG_STACKTRACE=y # CONFIG_SWAP is not set diff --git a/target/linux/mediatek/patches-5.4/0301-mtd-mtk-ecc-move-mtk-ecc-header-file-to-include-mtd.patch b/target/linux/mediatek/patches-5.4/0301-mtd-mtk-ecc-move-mtk-ecc-header-file-to-include-mtd.patch new file mode 100644 index 0000000000..fd303552ee --- /dev/null +++ b/target/linux/mediatek/patches-5.4/0301-mtd-mtk-ecc-move-mtk-ecc-header-file-to-include-mtd.patch @@ -0,0 +1,139 @@ +From a2479dc254ebe31c84fbcfda73f35e2321576494 Mon Sep 17 00:00:00 2001 +From: Xiangsheng Hou +Date: Tue, 19 Mar 2019 13:57:38 +0800 +Subject: [PATCH 1/6] mtd: mtk ecc: move mtk ecc header file to include/mtd + +Change-Id: I8dc1d30e21b40d68ef5efd9587012f82970156a5 +Signed-off-by: Xiangsheng Hou +--- + drivers/mtd/nand/raw/mtk_ecc.c | 3 +-- + drivers/mtd/nand/raw/mtk_nand.c | 2 +- + {drivers/mtd/nand/raw => include/linux/mtd}/mtk_ecc.h | 0 + 3 files changed, 2 insertions(+), 3 deletions(-) + rename {drivers/mtd/nand/raw => include/linux/mtd}/mtk_ecc.h (100%) + +--- a/drivers/mtd/nand/raw/mtk_ecc.c ++++ b/drivers/mtd/nand/raw/mtk_ecc.c +@@ -23,8 +23,7 @@ + #include + #include + #include +- +-#include "mtk_ecc.h" ++#include + + #define ECC_IDLE_MASK BIT(0) + #define ECC_IRQ_EN BIT(0) +--- a/drivers/mtd/nand/raw/mtk_nand.c ++++ b/drivers/mtd/nand/raw/mtk_nand.c +@@ -25,7 +25,7 @@ + #include + #include + #include +-#include "mtk_ecc.h" ++#include + + /* NAND controller register definition */ + #define NFI_CNFG (0x00) +--- /dev/null ++++ b/include/linux/mtd/mtk_ecc.h +@@ -0,0 +1,49 @@ ++/* ++ * MTK SDG1 ECC controller ++ * ++ * Copyright (c) 2016 Mediatek ++ * Authors: Xiaolei Li ++ * Jorge Ramirez-Ortiz ++ * This program is free software; you can redistribute it and/or modify it ++ * under the terms of the GNU General Public License version 2 as published ++ * by the Free Software Foundation. ++ */ ++ ++#ifndef __DRIVERS_MTD_NAND_MTK_ECC_H__ ++#define __DRIVERS_MTD_NAND_MTK_ECC_H__ ++ ++#include ++ ++enum mtk_ecc_mode {ECC_DMA_MODE = 0, ECC_NFI_MODE = 1}; ++enum mtk_ecc_operation {ECC_ENCODE, ECC_DECODE}; ++ ++struct device_node; ++struct mtk_ecc; ++ ++struct mtk_ecc_stats { ++ u32 corrected; ++ u32 bitflips; ++ u32 failed; ++}; ++ ++struct mtk_ecc_config { ++ enum mtk_ecc_operation op; ++ enum mtk_ecc_mode mode; ++ dma_addr_t addr; ++ u32 strength; ++ u32 sectors; ++ u32 len; ++}; ++ ++int mtk_ecc_encode(struct mtk_ecc *, struct mtk_ecc_config *, u8 *, u32); ++void mtk_ecc_get_stats(struct mtk_ecc *, struct mtk_ecc_stats *, int); ++int mtk_ecc_wait_done(struct mtk_ecc *, enum mtk_ecc_operation); ++int mtk_ecc_enable(struct mtk_ecc *, struct mtk_ecc_config *); ++void mtk_ecc_disable(struct mtk_ecc *); ++void mtk_ecc_adjust_strength(struct mtk_ecc *ecc, u32 *p); ++unsigned int mtk_ecc_get_parity_bits(struct mtk_ecc *ecc); ++ ++struct mtk_ecc *of_mtk_ecc_get(struct device_node *); ++void mtk_ecc_release(struct mtk_ecc *); ++ ++#endif +--- a/drivers/mtd/nand/raw/mtk_ecc.h ++++ /dev/null +@@ -1,47 +0,0 @@ +-/* SPDX-License-Identifier: GPL-2.0 OR MIT */ +-/* +- * MTK SDG1 ECC controller +- * +- * Copyright (c) 2016 Mediatek +- * Authors: Xiaolei Li +- * Jorge Ramirez-Ortiz +- */ +- +-#ifndef __DRIVERS_MTD_NAND_MTK_ECC_H__ +-#define __DRIVERS_MTD_NAND_MTK_ECC_H__ +- +-#include +- +-enum mtk_ecc_mode {ECC_DMA_MODE = 0, ECC_NFI_MODE = 1}; +-enum mtk_ecc_operation {ECC_ENCODE, ECC_DECODE}; +- +-struct device_node; +-struct mtk_ecc; +- +-struct mtk_ecc_stats { +- u32 corrected; +- u32 bitflips; +- u32 failed; +-}; +- +-struct mtk_ecc_config { +- enum mtk_ecc_operation op; +- enum mtk_ecc_mode mode; +- dma_addr_t addr; +- u32 strength; +- u32 sectors; +- u32 len; +-}; +- +-int mtk_ecc_encode(struct mtk_ecc *, struct mtk_ecc_config *, u8 *, u32); +-void mtk_ecc_get_stats(struct mtk_ecc *, struct mtk_ecc_stats *, int); +-int mtk_ecc_wait_done(struct mtk_ecc *, enum mtk_ecc_operation); +-int mtk_ecc_enable(struct mtk_ecc *, struct mtk_ecc_config *); +-void mtk_ecc_disable(struct mtk_ecc *); +-void mtk_ecc_adjust_strength(struct mtk_ecc *ecc, u32 *p); +-unsigned int mtk_ecc_get_parity_bits(struct mtk_ecc *ecc); +- +-struct mtk_ecc *of_mtk_ecc_get(struct device_node *); +-void mtk_ecc_release(struct mtk_ecc *); +- +-#endif diff --git a/target/linux/mediatek/patches-5.4/0303-mtd-spinand-disable-on-die-ECC.patch b/target/linux/mediatek/patches-5.4/0303-mtd-spinand-disable-on-die-ECC.patch new file mode 100644 index 0000000000..cdf214688c --- /dev/null +++ b/target/linux/mediatek/patches-5.4/0303-mtd-spinand-disable-on-die-ECC.patch @@ -0,0 +1,31 @@ +From b341f120cfc9ca1dfd48364b7f36ac2c1fbdea43 Mon Sep 17 00:00:00 2001 +From: Xiangsheng Hou +Date: Wed, 3 Apr 2019 16:30:01 +0800 +Subject: [PATCH 3/6] mtd: spinand: disable on-die ECC + +Change-Id: I9745adaed5295202fabbe8ab8947885c57a5b847 +Signed-off-by: Xiangsheng Hou +--- + drivers/mtd/nand/spi/core.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +--- a/drivers/mtd/nand/spi/core.c ++++ b/drivers/mtd/nand/spi/core.c +@@ -552,7 +552,7 @@ static int spinand_mtd_read(struct mtd_i + int ret = 0; + + if (ops->mode != MTD_OPS_RAW && spinand->eccinfo.ooblayout) +- enable_ecc = true; ++ enable_ecc = false; + + mutex_lock(&spinand->lock); + +@@ -600,7 +600,7 @@ static int spinand_mtd_write(struct mtd_ + int ret = 0; + + if (ops->mode != MTD_OPS_RAW && mtd->ooblayout) +- enable_ecc = true; ++ enable_ecc = false; + + mutex_lock(&spinand->lock); + diff --git a/target/linux/mediatek/patches-5.4/0306-spi-spi-mem-MediaTek-Add-SPI-NAND-Flash-interface-dr.patch b/target/linux/mediatek/patches-5.4/0306-spi-spi-mem-MediaTek-Add-SPI-NAND-Flash-interface-dr.patch new file mode 100644 index 0000000000..4e266bf183 --- /dev/null +++ b/target/linux/mediatek/patches-5.4/0306-spi-spi-mem-MediaTek-Add-SPI-NAND-Flash-interface-dr.patch @@ -0,0 +1,1246 @@ +From 1ecb38eabd90efe93957d0a822a167560c39308a Mon Sep 17 00:00:00 2001 +From: Xiangsheng Hou +Date: Wed, 20 Mar 2019 16:19:51 +0800 +Subject: [PATCH 6/6] spi: spi-mem: MediaTek: Add SPI NAND Flash interface + driver for MediaTek MT7622 + +Change-Id: I3e78406bb9b46b0049d3988a5c71c7069e4f809c +Signed-off-by: Xiangsheng Hou +--- + drivers/spi/Kconfig | 9 + + drivers/spi/Makefile | 1 + + drivers/spi/spi-mtk-snfi.c | 1183 ++++++++++++++++++++++++++++++++++++ + 3 files changed, 1193 insertions(+) + create mode 100644 drivers/spi/spi-mtk-snfi.c + +--- a/drivers/spi/Makefile 2020-03-02 15:33:05.223669793 +0800 ++++ b/drivers/spi/Makefile 2020-03-02 15:33:44.146364315 +0800 +@@ -60,6 +60,7 @@ + obj-$(CONFIG_SPI_MPC52xx_PSC) += spi-mpc52xx-psc.o + obj-$(CONFIG_SPI_MPC52xx) += spi-mpc52xx.o + obj-$(CONFIG_SPI_MT65XX) += spi-mt65xx.o ++obj-$(CONFIG_SPI_MTK_SNFI) += spi-mtk-snfi.o + obj-$(CONFIG_SPI_MT7621) += spi-mt7621.o + obj-$(CONFIG_SPI_MXIC) += spi-mxic.o + obj-$(CONFIG_SPI_MXS) += spi-mxs.o +--- a/drivers/spi/Kconfig 2020-03-02 15:33:11.183468935 +0800 ++++ b/drivers/spi/Kconfig 2020-03-02 15:34:53.304079101 +0800 +@@ -427,6 +427,15 @@ + say Y or M here.If you are not sure, say N. + SPI drivers for Mediatek MT65XX and MT81XX series ARM SoCs. + ++config SPI_MTK_SNFI ++ tristate "MediaTek SPI NAND interface" ++ select MTD_SPI_NAND ++ help ++ This selects the SPI NAND FLASH interface(SNFI), ++ which could be found on MediaTek Soc. ++ Say Y or M here.If you are not sure, say N. ++ Note Parallel Nand and SPI NAND is alternative on MediaTek SoCs. ++ + config SPI_MT7621 + tristate "MediaTek MT7621 SPI Controller" + depends on RALINK || COMPILE_TEST +--- /dev/null ++++ b/drivers/spi/spi-mtk-snfi.c +@@ -0,0 +1,1200 @@ ++// SPDX-License-Identifier: GPL-2.0 ++/* ++ * Driver for MediaTek SPI Nand interface ++ * ++ * Copyright (C) 2018 MediaTek Inc. ++ * Authors: Xiangsheng Hou ++ * ++ */ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++/* NAND controller register definition */ ++/* NFI control */ ++#define NFI_CNFG 0x00 ++#define CNFG_DMA 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_PROGRAM (3UL << 12) ++#define CNFG_OP_CUST (6UL << 12) ++#define NFI_PAGEFMT 0x04 ++#define PAGEFMT_512 0 ++#define PAGEFMT_2K 1 ++#define PAGEFMT_4K 2 ++#define PAGEFMT_FDM_SHIFT 8 ++#define PAGEFMT_FDM_ECC_SHIFT 12 ++#define NFI_CON 0x08 ++#define CON_FIFO_FLUSH BIT(0) ++#define CON_NFI_RST BIT(1) ++#define CON_BRD BIT(8) ++#define CON_BWR BIT(9) ++#define CON_SEC_SHIFT 12 ++#define NFI_INTR_EN 0x10 ++#define INTR_AHB_DONE_EN BIT(6) ++#define NFI_INTR_STA 0x14 ++#define NFI_CMD 0x20 ++#define NFI_STA 0x60 ++#define STA_EMP_PAGE BIT(12) ++#define NAND_FSM_MASK (0x1f << 24) ++#define NFI_FSM_MASK (0xf << 16) ++#define NFI_ADDRCNTR 0x70 ++#define CNTR_MASK GENMASK(16, 12) ++#define ADDRCNTR_SEC_SHIFT 12 ++#define ADDRCNTR_SEC(val) \ ++ (((val) & CNTR_MASK) >> ADDRCNTR_SEC_SHIFT) ++#define NFI_STRADDR 0x80 ++#define NFI_BYTELEN 0x84 ++#define NFI_CSEL 0x90 ++#define NFI_FDML(x) (0xa0 + (x) * sizeof(u32) * 2) ++#define NFI_FDMM(x) (0xa4 + (x) * sizeof(u32) * 2) ++#define NFI_MASTER_STA 0x224 ++#define MASTER_STA_MASK 0x0fff ++/* NFI_SPI control */ ++#define SNFI_MAC_OUTL 0x504 ++#define SNFI_MAC_INL 0x508 ++#define SNFI_RD_CTL2 0x510 ++#define RD_CMD_MASK 0x00ff ++#define RD_DUMMY_SHIFT 8 ++#define SNFI_RD_CTL3 0x514 ++#define RD_ADDR_MASK 0xffff ++#define SNFI_MISC_CTL 0x538 ++#define RD_MODE_X2 BIT(16) ++#define RD_MODE_X4 (2UL << 16) ++#define RD_QDUAL_IO (4UL << 16) ++#define RD_MODE_MASK (7UL << 16) ++#define RD_CUSTOM_EN BIT(6) ++#define WR_CUSTOM_EN BIT(7) ++#define WR_X4_EN BIT(20) ++#define SW_RST BIT(28) ++#define SNFI_MISC_CTL2 0x53c ++#define WR_LEN_SHIFT 16 ++#define SNFI_PG_CTL1 0x524 ++#define WR_LOAD_CMD_SHIFT 8 ++#define SNFI_PG_CTL2 0x528 ++#define WR_LOAD_ADDR_MASK 0xffff ++#define SNFI_MAC_CTL 0x500 ++#define MAC_WIP BIT(0) ++#define MAC_WIP_READY BIT(1) ++#define MAC_TRIG BIT(2) ++#define MAC_EN BIT(3) ++#define MAC_SIO_SEL BIT(4) ++#define SNFI_STA_CTL1 0x550 ++#define SPI_STATE_IDLE 0xf ++#define SNFI_CNFG 0x55c ++#define SNFI_MODE_EN BIT(0) ++#define SNFI_GPRAM_DATA 0x800 ++#define SNFI_GPRAM_MAX_LEN 16 ++ ++/* Dummy command trigger NFI to spi mode */ ++#define NAND_CMD_DUMMYREAD 0x00 ++#define NAND_CMD_DUMMYPROG 0x80 ++ ++#define MTK_TIMEOUT 500000 ++#define MTK_RESET_TIMEOUT 1000000 ++#define MTK_SNFC_MIN_SPARE 16 ++#define KB(x) ((x) * 1024UL) ++ ++/* ++ * supported spare size of each IP. ++ * order should be the same with the spare size bitfiled defination of ++ * register NFI_PAGEFMT. ++ */ ++static const u8 spare_size_mt7622[] = { ++ 16, 26, 27, 28 ++}; ++ ++struct mtk_snfi_caps { ++ const u8 *spare_size; ++ u8 num_spare_size; ++ u32 nand_sec_size; ++ u8 nand_fdm_size; ++ u8 nand_fdm_ecc_size; ++ u8 ecc_parity_bits; ++ u8 pageformat_spare_shift; ++ u8 bad_mark_swap; ++}; ++ ++struct mtk_snfi_bad_mark_ctl { ++ void (*bm_swap)(struct spi_mem *mem, u8 *buf, int raw); ++ u32 sec; ++ u32 pos; ++}; ++ ++struct mtk_snfi_nand_chip { ++ struct mtk_snfi_bad_mark_ctl bad_mark; ++ u32 spare_per_sector; ++}; ++ ++struct mtk_snfi_clk { ++ struct clk *nfi_clk; ++ struct clk *spi_clk; ++}; ++ ++struct mtk_snfi { ++ const struct mtk_snfi_caps *caps; ++ struct mtk_snfi_nand_chip snfi_nand; ++ struct mtk_snfi_clk clk; ++ struct mtk_ecc_config ecc_cfg; ++ struct mtk_ecc *ecc; ++ struct completion done; ++ struct device *dev; ++ ++ void __iomem *regs; ++ ++ u8 *buffer; ++}; ++ ++static inline u8 *oob_ptr(struct spi_mem *mem, int i) ++{ ++ struct spinand_device *spinand = spi_mem_get_drvdata(mem); ++ struct mtk_snfi *snfi = spi_controller_get_devdata(mem->spi->master); ++ struct mtk_snfi_nand_chip *snfi_nand = &snfi->snfi_nand; ++ u8 *poi; ++ ++ /* map the sector's FDM data to free oob: ++ * the beginning of the oob area stores the FDM data of bad mark ++ */ ++ ++ if (i < snfi_nand->bad_mark.sec) ++ poi = spinand->oobbuf + (i + 1) * snfi->caps->nand_fdm_size; ++ else if (i == snfi_nand->bad_mark.sec) ++ poi = spinand->oobbuf; ++ else ++ poi = spinand->oobbuf + i * snfi->caps->nand_fdm_size; ++ ++ return poi; ++} ++ ++static inline int mtk_data_len(struct spi_mem *mem) ++{ ++ struct mtk_snfi *snfi = spi_controller_get_devdata(mem->spi->master); ++ struct mtk_snfi_nand_chip *snfi_nand = &snfi->snfi_nand; ++ ++ return snfi->caps->nand_sec_size + snfi_nand->spare_per_sector; ++} ++ ++static inline u8 *mtk_oob_ptr(struct spi_mem *mem, ++ const u8 *p, int i) ++{ ++ struct mtk_snfi *snfi = spi_controller_get_devdata(mem->spi->master); ++ ++ return (u8 *)p + i * mtk_data_len(mem) + snfi->caps->nand_sec_size; ++} ++ ++static void mtk_snfi_bad_mark_swap(struct spi_mem *mem, ++ u8 *buf, int raw) ++{ ++ struct spinand_device *spinand = spi_mem_get_drvdata(mem); ++ struct mtk_snfi *snfi = spi_controller_get_devdata(mem->spi->master); ++ struct mtk_snfi_nand_chip *snfi_nand = &snfi->snfi_nand; ++ u32 bad_pos = snfi_nand->bad_mark.pos; ++ ++ if (raw) ++ bad_pos += snfi_nand->bad_mark.sec * mtk_data_len(mem); ++ else ++ bad_pos += snfi_nand->bad_mark.sec * snfi->caps->nand_sec_size; ++ ++ swap(spinand->oobbuf[0], buf[bad_pos]); ++} ++ ++static void mtk_snfi_set_bad_mark_ctl(struct mtk_snfi_bad_mark_ctl *bm_ctl, ++ struct spi_mem *mem) ++{ ++ struct spinand_device *spinand = spi_mem_get_drvdata(mem); ++ struct mtd_info *mtd = spinand_to_mtd(spinand); ++ ++ bm_ctl->bm_swap = mtk_snfi_bad_mark_swap; ++ bm_ctl->sec = mtd->writesize / mtk_data_len(mem); ++ bm_ctl->pos = mtd->writesize % mtk_data_len(mem); ++} ++ ++static void mtk_snfi_mac_enable(struct mtk_snfi *snfi) ++{ ++ u32 mac; ++ ++ mac = readl(snfi->regs + SNFI_MAC_CTL); ++ mac &= ~MAC_SIO_SEL; ++ mac |= MAC_EN; ++ ++ writel(mac, snfi->regs + SNFI_MAC_CTL); ++} ++ ++static int mtk_snfi_mac_trigger(struct mtk_snfi *snfi) ++{ ++ u32 mac, reg; ++ int ret = 0; ++ ++ mac = readl(snfi->regs + SNFI_MAC_CTL); ++ mac |= MAC_TRIG; ++ writel(mac, snfi->regs + SNFI_MAC_CTL); ++ ++ ret = readl_poll_timeout_atomic(snfi->regs + SNFI_MAC_CTL, reg, ++ reg & MAC_WIP_READY, 10, ++ MTK_TIMEOUT); ++ if (ret < 0) { ++ dev_err(snfi->dev, "polling wip ready for read timeout\n"); ++ return -EIO; ++ } ++ ++ ret = readl_poll_timeout_atomic(snfi->regs + SNFI_MAC_CTL, reg, ++ !(reg & MAC_WIP), 10, ++ MTK_TIMEOUT); ++ if (ret < 0) { ++ dev_err(snfi->dev, "polling flash update timeout\n"); ++ return -EIO; ++ } ++ ++ return ret; ++} ++ ++static void mtk_snfi_mac_leave(struct mtk_snfi *snfi) ++{ ++ u32 mac; ++ ++ mac = readl(snfi->regs + SNFI_MAC_CTL); ++ mac &= ~(MAC_TRIG | MAC_EN | MAC_SIO_SEL); ++ writel(mac, snfi->regs + SNFI_MAC_CTL); ++} ++ ++static int mtk_snfi_mac_op(struct mtk_snfi *snfi) ++{ ++ int ret = 0; ++ ++ mtk_snfi_mac_enable(snfi); ++ ++ ret = mtk_snfi_mac_trigger(snfi); ++ if (ret) ++ return ret; ++ ++ mtk_snfi_mac_leave(snfi); ++ ++ return ret; ++} ++ ++static irqreturn_t mtk_snfi_irq(int irq, void *id) ++{ ++ struct mtk_snfi *snfi = id; ++ u16 sta, ien; ++ ++ sta = readw(snfi->regs + NFI_INTR_STA); ++ ien = readw(snfi->regs + NFI_INTR_EN); ++ ++ if (!(sta & ien)) ++ return IRQ_NONE; ++ ++ writew(~sta & ien, snfi->regs + NFI_INTR_EN); ++ complete(&snfi->done); ++ ++ return IRQ_HANDLED; ++} ++ ++static int mtk_snfi_enable_clk(struct device *dev, struct mtk_snfi_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->spi_clk); ++ if (ret) { ++ dev_err(dev, "failed to enable spi clk\n"); ++ clk_disable_unprepare(clk->nfi_clk); ++ return ret; ++ } ++ ++ return 0; ++} ++ ++static void mtk_snfi_disable_clk(struct mtk_snfi_clk *clk) ++{ ++ clk_disable_unprepare(clk->nfi_clk); ++ clk_disable_unprepare(clk->spi_clk); ++} ++ ++static int mtk_snfi_reset(struct mtk_snfi *snfi) ++{ ++ u32 val; ++ int ret; ++ ++ /* SW reset controller */ ++ val = readl(snfi->regs + SNFI_MISC_CTL) | SW_RST; ++ writel(val, snfi->regs + SNFI_MISC_CTL); ++ ++ ret = readw_poll_timeout(snfi->regs + SNFI_STA_CTL1, val, ++ !(val & SPI_STATE_IDLE), 50, ++ MTK_RESET_TIMEOUT); ++ if (ret) { ++ dev_warn(snfi->dev, "spi state active in reset [0x%x] = 0x%x\n", ++ SNFI_STA_CTL1, val); ++ return ret; ++ } ++ ++ val = readl(snfi->regs + SNFI_MISC_CTL); ++ val &= ~SW_RST; ++ writel(val, snfi->regs + SNFI_MISC_CTL); ++ ++ /* reset all registers and force the NFI master to terminate */ ++ writew(CON_FIFO_FLUSH | CON_NFI_RST, snfi->regs + NFI_CON); ++ ret = readw_poll_timeout(snfi->regs + NFI_STA, val, ++ !(val & (NFI_FSM_MASK | NAND_FSM_MASK)), 50, ++ MTK_RESET_TIMEOUT); ++ if (ret) { ++ dev_warn(snfi->dev, "nfi active in reset [0x%x] = 0x%x\n", ++ NFI_STA, val); ++ return ret; ++ } ++ ++ return 0; ++} ++ ++static int mtk_snfi_set_spare_per_sector(struct spinand_device *spinand, ++ const struct mtk_snfi_caps *caps, ++ u32 *sps) ++{ ++ struct mtd_info *mtd = spinand_to_mtd(spinand); ++ const u8 *spare = caps->spare_size; ++ u32 sectors, i, closest_spare = 0; ++ ++ sectors = mtd->writesize / caps->nand_sec_size; ++ *sps = mtd->oobsize / sectors; ++ ++ if (*sps < MTK_SNFC_MIN_SPARE) ++ return -EINVAL; ++ ++ for (i = 0; i < caps->num_spare_size; i++) { ++ if (*sps >= spare[i] && spare[i] >= spare[closest_spare]) { ++ closest_spare = i; ++ if (*sps == spare[i]) ++ break; ++ } ++ } ++ ++ *sps = spare[closest_spare]; ++ ++ return 0; ++} ++ ++static void mtk_snfi_read_fdm_data(struct spi_mem *mem, ++ u32 sectors) ++{ ++ struct mtk_snfi *snfi = spi_controller_get_devdata(mem->spi->master); ++ const struct mtk_snfi_caps *caps = snfi->caps; ++ u32 vall, valm; ++ int i, j; ++ u8 *oobptr; ++ ++ for (i = 0; i < sectors; i++) { ++ oobptr = oob_ptr(mem, i); ++ vall = readl(snfi->regs + NFI_FDML(i)); ++ valm = readl(snfi->regs + NFI_FDMM(i)); ++ ++ for (j = 0; j < caps->nand_fdm_size; j++) ++ oobptr[j] = (j >= 4 ? valm : vall) >> ((j % 4) * 8); ++ } ++} ++ ++static void mtk_snfi_write_fdm_data(struct spi_mem *mem, ++ u32 sectors) ++{ ++ struct mtk_snfi *snfi = spi_controller_get_devdata(mem->spi->master); ++ const struct mtk_snfi_caps *caps = snfi->caps; ++ u32 vall, valm; ++ int i, j; ++ u8 *oobptr; ++ ++ for (i = 0; i < sectors; i++) { ++ oobptr = oob_ptr(mem, i); ++ vall = 0; ++ valm = 0; ++ for (j = 0; j < 8; j++) { ++ if (j < 4) ++ vall |= (j < caps->nand_fdm_size ? oobptr[j] : ++ 0xff) << (j * 8); ++ else ++ valm |= (j < caps->nand_fdm_size ? oobptr[j] : ++ 0xff) << ((j - 4) * 8); ++ } ++ writel(vall, snfi->regs + NFI_FDML(i)); ++ writel(valm, snfi->regs + NFI_FDMM(i)); ++ } ++} ++ ++static int mtk_snfi_update_ecc_stats(struct spi_mem *mem, ++ u8 *buf, u32 sectors) ++{ ++ struct spinand_device *spinand = spi_mem_get_drvdata(mem); ++ struct mtd_info *mtd = spinand_to_mtd(spinand); ++ struct mtk_snfi *snfi = spi_controller_get_devdata(mem->spi->master); ++ struct mtk_ecc_stats stats; ++ int rc, i; ++ ++ rc = readl(snfi->regs + NFI_STA) & STA_EMP_PAGE; ++ if (rc) { ++ memset(buf, 0xff, sectors * snfi->caps->nand_sec_size); ++ for (i = 0; i < sectors; i++) ++ memset(spinand->oobbuf, 0xff, ++ snfi->caps->nand_fdm_size); ++ return 0; ++ } ++ ++ mtk_ecc_get_stats(snfi->ecc, &stats, sectors); ++ mtd->ecc_stats.corrected += stats.corrected; ++ mtd->ecc_stats.failed += stats.failed; ++ ++ return 0; ++} ++ ++static int mtk_snfi_hw_runtime_config(struct spi_mem *mem) ++{ ++ struct spinand_device *spinand = spi_mem_get_drvdata(mem); ++ struct mtd_info *mtd = spinand_to_mtd(spinand); ++ struct nand_device *nand = mtd_to_nanddev(mtd); ++ struct mtk_snfi *snfi = spi_controller_get_devdata(mem->spi->master); ++ const struct mtk_snfi_caps *caps = snfi->caps; ++ struct mtk_snfi_nand_chip *snfi_nand = &snfi->snfi_nand; ++ u32 fmt, spare, i = 0; ++ int ret; ++ ++ ret = mtk_snfi_set_spare_per_sector(spinand, caps, &spare); ++ if (ret) ++ return ret; ++ ++ /* calculate usable oob bytes for ecc parity data */ ++ snfi_nand->spare_per_sector = spare; ++ spare -= caps->nand_fdm_size; ++ ++ nand->memorg.oobsize = snfi_nand->spare_per_sector ++ * (mtd->writesize / caps->nand_sec_size); ++ mtd->oobsize = nanddev_per_page_oobsize(nand); ++ ++ snfi->ecc_cfg.strength = (spare << 3) / caps->ecc_parity_bits; ++ mtk_ecc_adjust_strength(snfi->ecc, &snfi->ecc_cfg.strength); ++ ++ switch (mtd->writesize) { ++ case 512: ++ fmt = PAGEFMT_512; ++ break; ++ case KB(2): ++ fmt = PAGEFMT_2K; ++ break; ++ case KB(4): ++ fmt = PAGEFMT_4K; ++ break; ++ default: ++ dev_err(snfi->dev, "invalid page len: %d\n", mtd->writesize); ++ return -EINVAL; ++ } ++ ++ /* Setup PageFormat */ ++ while (caps->spare_size[i] != snfi_nand->spare_per_sector) { ++ i++; ++ if (i == (caps->num_spare_size - 1)) { ++ dev_err(snfi->dev, "invalid spare size %d\n", ++ snfi_nand->spare_per_sector); ++ return -EINVAL; ++ } ++ } ++ ++ fmt |= i << caps->pageformat_spare_shift; ++ fmt |= caps->nand_fdm_size << PAGEFMT_FDM_SHIFT; ++ fmt |= caps->nand_fdm_ecc_size << PAGEFMT_FDM_ECC_SHIFT; ++ writel(fmt, snfi->regs + NFI_PAGEFMT); ++ ++ snfi->ecc_cfg.len = caps->nand_sec_size + caps->nand_fdm_ecc_size; ++ ++ mtk_snfi_set_bad_mark_ctl(&snfi_nand->bad_mark, mem); ++ ++ return 0; ++} ++ ++static int mtk_snfi_read_from_cache(struct spi_mem *mem, ++ const struct spi_mem_op *op, int oob_on) ++{ ++ struct mtk_snfi *snfi = spi_controller_get_devdata(mem->spi->master); ++ struct spinand_device *spinand = spi_mem_get_drvdata(mem); ++ struct mtd_info *mtd = spinand_to_mtd(spinand); ++ u32 sectors = mtd->writesize / snfi->caps->nand_sec_size; ++ struct mtk_snfi_nand_chip *snfi_nand = &snfi->snfi_nand; ++ u32 reg, len, col_addr = 0; ++ int dummy_cycle, ret; ++ dma_addr_t dma_addr; ++ ++ len = sectors * (snfi->caps->nand_sec_size ++ + snfi_nand->spare_per_sector); ++ ++ dma_addr = dma_map_single(snfi->dev, snfi->buffer, ++ len, DMA_FROM_DEVICE); ++ ret = dma_mapping_error(snfi->dev, dma_addr); ++ if (ret) { ++ dev_err(snfi->dev, "dma mapping error\n"); ++ return -EINVAL; ++ } ++ ++ /* set Read cache command and dummy cycle */ ++ dummy_cycle = (op->dummy.nbytes << 3) >> (ffs(op->dummy.buswidth) - 1); ++ reg = ((op->cmd.opcode & RD_CMD_MASK) | ++ (dummy_cycle << RD_DUMMY_SHIFT)); ++ writel(reg, snfi->regs + SNFI_RD_CTL2); ++ ++ writel((col_addr & RD_ADDR_MASK), snfi->regs + SNFI_RD_CTL3); ++ ++ reg = readl(snfi->regs + SNFI_MISC_CTL); ++ reg |= RD_CUSTOM_EN; ++ reg &= ~(RD_MODE_MASK | WR_X4_EN); ++ ++ /* set data and addr buswidth */ ++ if (op->data.buswidth == 4) ++ reg |= RD_MODE_X4; ++ else if (op->data.buswidth == 2) ++ reg |= RD_MODE_X2; ++ ++ if (op->addr.buswidth == 4 || op->addr.buswidth == 2) ++ reg |= RD_QDUAL_IO; ++ writel(reg, snfi->regs + SNFI_MISC_CTL); ++ ++ writel(len, snfi->regs + SNFI_MISC_CTL2); ++ writew(sectors << CON_SEC_SHIFT, snfi->regs + NFI_CON); ++ reg = readw(snfi->regs + NFI_CNFG); ++ reg |= CNFG_READ_EN | CNFG_DMA_BURST_EN | CNFG_DMA | CNFG_OP_CUST; ++ ++ if (!oob_on) { ++ reg |= CNFG_AUTO_FMT_EN | CNFG_HW_ECC_EN; ++ writew(reg, snfi->regs + NFI_CNFG); ++ ++ snfi->ecc_cfg.mode = ECC_NFI_MODE; ++ snfi->ecc_cfg.sectors = sectors; ++ snfi->ecc_cfg.op = ECC_DECODE; ++ ret = mtk_ecc_enable(snfi->ecc, &snfi->ecc_cfg); ++ if (ret) { ++ dev_err(snfi->dev, "ecc enable failed\n"); ++ /* clear NFI_CNFG */ ++ reg &= ~(CNFG_READ_EN | CNFG_DMA_BURST_EN | CNFG_DMA | ++ CNFG_AUTO_FMT_EN | CNFG_HW_ECC_EN); ++ writew(reg, snfi->regs + NFI_CNFG); ++ goto out; ++ } ++ } else { ++ writew(reg, snfi->regs + NFI_CNFG); ++ } ++ ++ writel(lower_32_bits(dma_addr), snfi->regs + NFI_STRADDR); ++ readw(snfi->regs + NFI_INTR_STA); ++ writew(INTR_AHB_DONE_EN, snfi->regs + NFI_INTR_EN); ++ ++ init_completion(&snfi->done); ++ ++ /* set dummy command to trigger NFI enter SPI mode */ ++ writew(NAND_CMD_DUMMYREAD, snfi->regs + NFI_CMD); ++ reg = readl(snfi->regs + NFI_CON) | CON_BRD; ++ writew(reg, snfi->regs + NFI_CON); ++ ++ ret = wait_for_completion_timeout(&snfi->done, msecs_to_jiffies(500)); ++ if (!ret) { ++ dev_err(snfi->dev, "read ahb done timeout\n"); ++ writew(0, snfi->regs + NFI_INTR_EN); ++ ret = -ETIMEDOUT; ++ goto out; ++ } ++ ++ ret = readl_poll_timeout_atomic(snfi->regs + NFI_BYTELEN, reg, ++ ADDRCNTR_SEC(reg) >= sectors, 10, ++ MTK_TIMEOUT); ++ if (ret < 0) { ++ dev_err(snfi->dev, "polling read byte len timeout\n"); ++ ret = -EIO; ++ } else { ++ if (!oob_on) { ++ ret = mtk_ecc_wait_done(snfi->ecc, ECC_DECODE); ++ if (ret) { ++ dev_warn(snfi->dev, "wait ecc done timeout\n"); ++ } else { ++ mtk_snfi_update_ecc_stats(mem, snfi->buffer, ++ sectors); ++ mtk_snfi_read_fdm_data(mem, sectors); ++ } ++ } ++ } ++ ++ if (oob_on) ++ goto out; ++ ++ mtk_ecc_disable(snfi->ecc); ++out: ++ dma_unmap_single(snfi->dev, dma_addr, len, DMA_FROM_DEVICE); ++ writel(0, snfi->regs + NFI_CON); ++ writel(0, snfi->regs + NFI_CNFG); ++ reg = readl(snfi->regs + SNFI_MISC_CTL); ++ reg &= ~RD_CUSTOM_EN; ++ writel(reg, snfi->regs + SNFI_MISC_CTL); ++ ++ return ret; ++} ++ ++static int mtk_snfi_write_to_cache(struct spi_mem *mem, ++ const struct spi_mem_op *op, ++ int oob_on) ++{ ++ struct mtk_snfi *snfi = spi_controller_get_devdata(mem->spi->master); ++ struct spinand_device *spinand = spi_mem_get_drvdata(mem); ++ struct mtd_info *mtd = spinand_to_mtd(spinand); ++ u32 sectors = mtd->writesize / snfi->caps->nand_sec_size; ++ struct mtk_snfi_nand_chip *snfi_nand = &snfi->snfi_nand; ++ u32 reg, len, col_addr = 0; ++ dma_addr_t dma_addr; ++ int ret; ++ ++ len = sectors * (snfi->caps->nand_sec_size ++ + snfi_nand->spare_per_sector); ++ ++ dma_addr = dma_map_single(snfi->dev, snfi->buffer, len, ++ DMA_TO_DEVICE); ++ ret = dma_mapping_error(snfi->dev, dma_addr); ++ if (ret) { ++ dev_err(snfi->dev, "dma mapping error\n"); ++ return -EINVAL; ++ } ++ ++ /* set program load cmd and address */ ++ reg = (op->cmd.opcode << WR_LOAD_CMD_SHIFT); ++ writel(reg, snfi->regs + SNFI_PG_CTL1); ++ writel(col_addr & WR_LOAD_ADDR_MASK, snfi->regs + SNFI_PG_CTL2); ++ ++ reg = readl(snfi->regs + SNFI_MISC_CTL); ++ reg |= WR_CUSTOM_EN; ++ reg &= ~(RD_MODE_MASK | WR_X4_EN); ++ ++ if (op->data.buswidth == 4) ++ reg |= WR_X4_EN; ++ writel(reg, snfi->regs + SNFI_MISC_CTL); ++ ++ writel(len << WR_LEN_SHIFT, snfi->regs + SNFI_MISC_CTL2); ++ writew(sectors << CON_SEC_SHIFT, snfi->regs + NFI_CON); ++ ++ reg = readw(snfi->regs + NFI_CNFG); ++ reg &= ~(CNFG_READ_EN | CNFG_BYTE_RW); ++ reg |= CNFG_DMA | CNFG_DMA_BURST_EN | CNFG_OP_PROGRAM; ++ ++ if (!oob_on) { ++ reg |= CNFG_AUTO_FMT_EN | CNFG_HW_ECC_EN; ++ writew(reg, snfi->regs + NFI_CNFG); ++ ++ snfi->ecc_cfg.mode = ECC_NFI_MODE; ++ snfi->ecc_cfg.op = ECC_ENCODE; ++ ret = mtk_ecc_enable(snfi->ecc, &snfi->ecc_cfg); ++ if (ret) { ++ dev_err(snfi->dev, "ecc enable failed\n"); ++ /* clear NFI_CNFG */ ++ reg &= ~(CNFG_DMA_BURST_EN | CNFG_DMA | ++ CNFG_AUTO_FMT_EN | CNFG_HW_ECC_EN); ++ writew(reg, snfi->regs + NFI_CNFG); ++ dma_unmap_single(snfi->dev, dma_addr, len, ++ DMA_FROM_DEVICE); ++ goto out; ++ } ++ /* write OOB into the FDM registers (OOB area in MTK NAND) */ ++ mtk_snfi_write_fdm_data(mem, sectors); ++ } else { ++ writew(reg, snfi->regs + NFI_CNFG); ++ } ++ writel(lower_32_bits(dma_addr), snfi->regs + NFI_STRADDR); ++ readw(snfi->regs + NFI_INTR_STA); ++ writew(INTR_AHB_DONE_EN, snfi->regs + NFI_INTR_EN); ++ ++ init_completion(&snfi->done); ++ ++ /* set dummy command to trigger NFI enter SPI mode */ ++ writew(NAND_CMD_DUMMYPROG, snfi->regs + NFI_CMD); ++ reg = readl(snfi->regs + NFI_CON) | CON_BWR; ++ writew(reg, snfi->regs + NFI_CON); ++ ++ ret = wait_for_completion_timeout(&snfi->done, msecs_to_jiffies(500)); ++ if (!ret) { ++ dev_err(snfi->dev, "custom program done timeout\n"); ++ writew(0, snfi->regs + NFI_INTR_EN); ++ ret = -ETIMEDOUT; ++ goto ecc_disable; ++ } ++ ++ ret = readl_poll_timeout_atomic(snfi->regs + NFI_ADDRCNTR, reg, ++ ADDRCNTR_SEC(reg) >= sectors, ++ 10, MTK_TIMEOUT); ++ if (ret) ++ dev_err(snfi->dev, "hwecc write timeout\n"); ++ ++ecc_disable: ++ mtk_ecc_disable(snfi->ecc); ++ ++out: ++ dma_unmap_single(snfi->dev, dma_addr, len, DMA_TO_DEVICE); ++ writel(0, snfi->regs + NFI_CON); ++ writel(0, snfi->regs + NFI_CNFG); ++ reg = readl(snfi->regs + SNFI_MISC_CTL); ++ reg &= ~WR_CUSTOM_EN; ++ writel(reg, snfi->regs + SNFI_MISC_CTL); ++ ++ return ret; ++} ++ ++static int mtk_snfi_read(struct spi_mem *mem, ++ const struct spi_mem_op *op) ++{ ++ struct spinand_device *spinand = spi_mem_get_drvdata(mem); ++ struct mtk_snfi *snfi = spi_controller_get_devdata(mem->spi->master); ++ struct mtd_info *mtd = spinand_to_mtd(spinand); ++ struct mtk_snfi_nand_chip *snfi_nand = &snfi->snfi_nand; ++ u32 col_addr = op->addr.val; ++ int i, ret, sectors, oob_on = false; ++ ++ if (col_addr == mtd->writesize) ++ oob_on = true; ++ ++ ret = mtk_snfi_read_from_cache(mem, op, oob_on); ++ if (ret) { ++ dev_warn(snfi->dev, "read from cache fail\n"); ++ return ret; ++ } ++ ++ sectors = mtd->writesize / snfi->caps->nand_sec_size; ++ for (i = 0; i < sectors; i++) { ++ if (oob_on) ++ memcpy(oob_ptr(mem, i), ++ mtk_oob_ptr(mem, snfi->buffer, i), ++ snfi->caps->nand_fdm_size); ++ ++ if (i == snfi_nand->bad_mark.sec && snfi->caps->bad_mark_swap) ++ snfi_nand->bad_mark.bm_swap(mem, snfi->buffer, ++ oob_on); ++ } ++ ++ if (!oob_on) ++ memcpy(spinand->databuf, snfi->buffer, mtd->writesize); ++ ++ return ret; ++} ++ ++static int mtk_snfi_write(struct spi_mem *mem, ++ const struct spi_mem_op *op) ++{ ++ struct spinand_device *spinand = spi_mem_get_drvdata(mem); ++ struct mtk_snfi *snfi = spi_controller_get_devdata(mem->spi->master); ++ struct mtd_info *mtd = spinand_to_mtd(spinand); ++ struct mtk_snfi_nand_chip *snfi_nand = &snfi->snfi_nand; ++ u32 ret, i, sectors, col_addr = op->addr.val; ++ int oob_on = false; ++ ++ if (col_addr == mtd->writesize) ++ oob_on = true; ++ ++ sectors = mtd->writesize / snfi->caps->nand_sec_size; ++ memset(snfi->buffer, 0xff, mtd->writesize + mtd->oobsize); ++ ++ if (!oob_on) ++ memcpy(snfi->buffer, spinand->databuf, mtd->writesize); ++ ++ for (i = 0; i < sectors; i++) { ++ if (i == snfi_nand->bad_mark.sec && snfi->caps->bad_mark_swap) ++ snfi_nand->bad_mark.bm_swap(mem, snfi->buffer, oob_on); ++ ++ if (oob_on) ++ memcpy(mtk_oob_ptr(mem, snfi->buffer, i), ++ oob_ptr(mem, i), ++ snfi->caps->nand_fdm_size); ++ } ++ ++ ret = mtk_snfi_write_to_cache(mem, op, oob_on); ++ if (ret) ++ dev_warn(snfi->dev, "write to cache fail\n"); ++ ++ return ret; ++} ++ ++static int mtk_snfi_command_exec(struct mtk_snfi *snfi, ++ const u8 *txbuf, u8 *rxbuf, ++ const u32 txlen, const u32 rxlen) ++{ ++ u32 tmp, i, j, reg, m; ++ u8 *p_tmp = (u8 *)(&tmp); ++ int ret = 0; ++ ++ /* Moving tx data to NFI_SPI GPRAM */ ++ for (i = 0, m = 0; i < txlen; ) { ++ for (j = 0, tmp = 0; i < txlen && j < 4; i++, j++) ++ p_tmp[j] = txbuf[i]; ++ ++ writel(tmp, snfi->regs + SNFI_GPRAM_DATA + m); ++ m += 4; ++ } ++ ++ writel(txlen, snfi->regs + SNFI_MAC_OUTL); ++ writel(rxlen, snfi->regs + SNFI_MAC_INL); ++ ret = mtk_snfi_mac_op(snfi); ++ if (ret) ++ return ret; ++ ++ /* For NULL input data, this loop will be skipped */ ++ if (rxlen) ++ for (i = 0, m = 0; i < rxlen; ) { ++ reg = readl(snfi->regs + ++ SNFI_GPRAM_DATA + m); ++ for (j = 0; i < rxlen && j < 4; i++, j++, rxbuf++) { ++ if (m == 0 && i == 0) ++ j = i + txlen; ++ *rxbuf = (reg >> (j * 8)) & 0xFF; ++ } ++ m += 4; ++ } ++ ++ return ret; ++} ++ ++/* ++ * mtk_snfi_exec_op - to process command/data to send to the ++ * SPI NAND by mtk controller ++ */ ++static int mtk_snfi_exec_op(struct spi_mem *mem, ++ const struct spi_mem_op *op) ++ ++{ ++ struct mtk_snfi *snfi = spi_controller_get_devdata(mem->spi->master); ++ struct spinand_device *spinand = spi_mem_get_drvdata(mem); ++ struct mtd_info *mtd = spinand_to_mtd(spinand); ++ struct nand_device *nand = mtd_to_nanddev(mtd); ++ const struct spi_mem_op *read_cache; ++ const struct spi_mem_op *write_cache; ++ const struct spi_mem_op *update_cache; ++ u32 tmpbufsize, txlen = 0, rxlen = 0; ++ u8 *txbuf, *rxbuf = NULL, *buf; ++ int i, ret = 0; ++ ++ ret = mtk_snfi_reset(snfi); ++ if (ret) { ++ dev_warn(snfi->dev, "reset spi memory controller fail\n"); ++ return ret; ++ } ++ ++ /*if bbt initial, framework have detect nand information */ ++ if (nand->bbt.cache) { ++ read_cache = spinand->op_templates.read_cache; ++ write_cache = spinand->op_templates.write_cache; ++ update_cache = spinand->op_templates.update_cache; ++ ++ ret = mtk_snfi_hw_runtime_config(mem); ++ if (ret) ++ return ret; ++ ++ /* For Read/Write with cache, Erase use framework flow */ ++ if (op->cmd.opcode == read_cache->cmd.opcode) { ++ ret = mtk_snfi_read(mem, op); ++ if (ret) ++ dev_warn(snfi->dev, "snfi read fail\n"); ++ ++ return ret; ++ } else if ((op->cmd.opcode == write_cache->cmd.opcode) ++ || (op->cmd.opcode == update_cache->cmd.opcode)) { ++ ret = mtk_snfi_write(mem, op); ++ if (ret) ++ dev_warn(snfi->dev, "snfi write fail\n"); ++ ++ return ret; ++ } ++ } ++ ++ tmpbufsize = sizeof(op->cmd.opcode) + op->addr.nbytes + ++ op->dummy.nbytes + op->data.nbytes; ++ ++ txbuf = kzalloc(tmpbufsize, GFP_KERNEL); ++ if (!txbuf) ++ return -ENOMEM; ++ ++ txbuf[txlen++] = op->cmd.opcode; ++ ++ if (op->addr.nbytes) ++ for (i = 0; i < op->addr.nbytes; i++) ++ txbuf[txlen++] = op->addr.val >> ++ (8 * (op->addr.nbytes - i - 1)); ++ ++ txlen += op->dummy.nbytes; ++ ++ if (op->data.dir == SPI_MEM_DATA_OUT) ++ for (i = 0; i < op->data.nbytes; i++) { ++ buf = (u8 *)op->data.buf.out; ++ txbuf[txlen++] = buf[i]; ++ } ++ ++ if (op->data.dir == SPI_MEM_DATA_IN) { ++ rxbuf = (u8 *)op->data.buf.in; ++ rxlen += op->data.nbytes; ++ } ++ ++ ret = mtk_snfi_command_exec(snfi, txbuf, rxbuf, txlen, rxlen); ++ kfree(txbuf); ++ ++ return ret; ++} ++ ++static int mtk_snfi_init(struct mtk_snfi *snfi) ++{ ++ int ret; ++ ++ /* Reset the state machine and data FIFO */ ++ ret = mtk_snfi_reset(snfi); ++ if (ret) { ++ dev_warn(snfi->dev, "MTK reset controller fail\n"); ++ return ret; ++ } ++ ++ snfi->buffer = devm_kzalloc(snfi->dev, 4096 + 256, GFP_KERNEL); ++ if (!snfi->buffer) ++ return -ENOMEM; ++ ++ /* Clear interrupt, read clear. */ ++ readw(snfi->regs + NFI_INTR_STA); ++ writew(0, snfi->regs + NFI_INTR_EN); ++ ++ writel(0, snfi->regs + NFI_CON); ++ writel(0, snfi->regs + NFI_CNFG); ++ ++ /* Change to NFI_SPI mode. */ ++ writel(SNFI_MODE_EN, snfi->regs + SNFI_CNFG); ++ ++ return 0; ++} ++ ++static int mtk_snfi_check_buswidth(u8 width) ++{ ++ switch (width) { ++ case 1: ++ case 2: ++ case 4: ++ return 0; ++ ++ default: ++ break; ++ } ++ ++ return -ENOTSUPP; ++} ++ ++static bool mtk_snfi_supports_op(struct spi_mem *mem, ++ const struct spi_mem_op *op) ++{ ++ int ret = 0; ++ ++ /* For MTK Spi Nand controller, cmd buswidth just support 1 bit*/ ++ if (op->cmd.buswidth != 1) ++ ret = -ENOTSUPP; ++ ++ if (op->addr.nbytes) ++ ret |= mtk_snfi_check_buswidth(op->addr.buswidth); ++ ++ if (op->dummy.nbytes) ++ ret |= mtk_snfi_check_buswidth(op->dummy.buswidth); ++ ++ if (op->data.nbytes) ++ ret |= mtk_snfi_check_buswidth(op->data.buswidth); ++ ++ if (ret) ++ return false; ++ ++ return true; ++} ++ ++static const struct spi_controller_mem_ops mtk_snfi_ops = { ++ .supports_op = mtk_snfi_supports_op, ++ .exec_op = mtk_snfi_exec_op, ++}; ++ ++static const struct mtk_snfi_caps snfi_mt7622 = { ++ .spare_size = spare_size_mt7622, ++ .num_spare_size = 4, ++ .nand_sec_size = 512, ++ .nand_fdm_size = 8, ++ .nand_fdm_ecc_size = 1, ++ .ecc_parity_bits = 13, ++ .pageformat_spare_shift = 4, ++ .bad_mark_swap = 0, ++}; ++ ++static const struct mtk_snfi_caps snfi_mt7629 = { ++ .spare_size = spare_size_mt7622, ++ .num_spare_size = 4, ++ .nand_sec_size = 512, ++ .nand_fdm_size = 8, ++ .nand_fdm_ecc_size = 1, ++ .ecc_parity_bits = 13, ++ .pageformat_spare_shift = 4, ++ .bad_mark_swap = 1, ++}; ++ ++static const struct of_device_id mtk_snfi_id_table[] = { ++ { .compatible = "mediatek,mt7622-snfi", .data = &snfi_mt7622, }, ++ { .compatible = "mediatek,mt7629-snfi", .data = &snfi_mt7629, }, ++ { /* sentinel */ } ++}; ++ ++static int mtk_snfi_probe(struct platform_device *pdev) ++{ ++ struct device *dev = &pdev->dev; ++ struct device_node *np = dev->of_node; ++ struct spi_controller *ctlr; ++ struct mtk_snfi *snfi; ++ struct resource *res; ++ int ret = 0, irq; ++ ++ ctlr = spi_alloc_master(&pdev->dev, sizeof(*snfi)); ++ if (!ctlr) ++ return -ENOMEM; ++ ++ snfi = spi_controller_get_devdata(ctlr); ++ snfi->caps = of_device_get_match_data(dev); ++ snfi->dev = dev; ++ ++ snfi->ecc = of_mtk_ecc_get(np); ++ if (IS_ERR_OR_NULL(snfi->ecc)) ++ goto err_put_master; ++ ++ res = platform_get_resource(pdev, IORESOURCE_MEM, 0); ++ snfi->regs = devm_ioremap_resource(dev, res); ++ if (IS_ERR(snfi->regs)) { ++ ret = PTR_ERR(snfi->regs); ++ goto release_ecc; ++ } ++ ++ /* find the clocks */ ++ snfi->clk.nfi_clk = devm_clk_get(dev, "nfi_clk"); ++ if (IS_ERR(snfi->clk.nfi_clk)) { ++ dev_err(dev, "no nfi clk\n"); ++ ret = PTR_ERR(snfi->clk.nfi_clk); ++ goto release_ecc; ++ } ++ ++ snfi->clk.spi_clk = devm_clk_get(dev, "spi_clk"); ++ if (IS_ERR(snfi->clk.spi_clk)) { ++ dev_err(dev, "no spi clk\n"); ++ ret = PTR_ERR(snfi->clk.spi_clk); ++ goto release_ecc; ++ } ++ ++ ret = mtk_snfi_enable_clk(dev, &snfi->clk); ++ if (ret) ++ goto release_ecc; ++ ++ /* find the irq */ ++ irq = platform_get_irq(pdev, 0); ++ if (irq < 0) { ++ dev_err(dev, "no snfi irq resource\n"); ++ ret = -EINVAL; ++ goto clk_disable; ++ } ++ ++ ret = devm_request_irq(dev, irq, mtk_snfi_irq, 0, "mtk-snfi", snfi); ++ if (ret) { ++ dev_err(dev, "failed to request snfi 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; ++ } ++ ++ ctlr->dev.of_node = np; ++ ctlr->mem_ops = &mtk_snfi_ops; ++ ++ platform_set_drvdata(pdev, snfi); ++ ret = mtk_snfi_init(snfi); ++ if (ret) { ++ dev_err(dev, "failed to init snfi\n"); ++ goto clk_disable; ++ } ++ ++ ret = devm_spi_register_master(dev, ctlr); ++ if (ret) ++ goto clk_disable; ++ ++ return 0; ++ ++clk_disable: ++ mtk_snfi_disable_clk(&snfi->clk); ++ ++release_ecc: ++ mtk_ecc_release(snfi->ecc); ++ ++err_put_master: ++ spi_master_put(ctlr); ++ ++ dev_err(dev, "MediaTek SPI NAND interface probe failed %d\n", ret); ++ return ret; ++} ++ ++static int mtk_snfi_remove(struct platform_device *pdev) ++{ ++ struct mtk_snfi *snfi = platform_get_drvdata(pdev); ++ ++ mtk_snfi_disable_clk(&snfi->clk); ++ ++ return 0; ++} ++ ++static int mtk_snfi_suspend(struct platform_device *pdev, pm_message_t state) ++{ ++ struct mtk_snfi *snfi = platform_get_drvdata(pdev); ++ ++ mtk_snfi_disable_clk(&snfi->clk); ++ ++ return 0; ++} ++ ++static int mtk_snfi_resume(struct platform_device *pdev) ++{ ++ struct device *dev = &pdev->dev; ++ struct mtk_snfi *snfi = dev_get_drvdata(dev); ++ int ret; ++ ++ ret = mtk_snfi_enable_clk(dev, &snfi->clk); ++ if (ret) ++ return ret; ++ ++ ret = mtk_snfi_init(snfi); ++ if (ret) ++ dev_err(dev, "failed to init snfi controller\n"); ++ ++ return ret; ++} ++ ++static struct platform_driver mtk_snfi_driver = { ++ .driver = { ++ .name = "mtk-snfi", ++ .of_match_table = mtk_snfi_id_table, ++ }, ++ .probe = mtk_snfi_probe, ++ .remove = mtk_snfi_remove, ++ .suspend = mtk_snfi_suspend, ++ .resume = mtk_snfi_resume, ++}; ++ ++module_platform_driver(mtk_snfi_driver); ++ ++MODULE_LICENSE("GPL v2"); ++MODULE_AUTHOR("Xiangsheng Hou "); ++MODULE_DESCRIPTION("Mediatek SPI Memory Interface Driver"); diff --git a/target/linux/mediatek/patches-5.4/0307-dts-mt7629-add-snand-support.patch b/target/linux/mediatek/patches-5.4/0307-dts-mt7629-add-snand-support.patch new file mode 100644 index 0000000000..2775563b09 --- /dev/null +++ b/target/linux/mediatek/patches-5.4/0307-dts-mt7629-add-snand-support.patch @@ -0,0 +1,97 @@ +From c813fbe806257c574240770ef716fbee19f7dbfa Mon Sep 17 00:00:00 2001 +From: Xiangsheng Hou +Date: Thu, 6 Jun 2019 16:29:04 +0800 +Subject: [PATCH] spi: spi-mem: Mediatek: Add SPI Nand support for MT7629 + +Signed-off-by: Xiangsheng Hou +--- + arch/arm/boot/dts/mt7629-rfb.dts | 45 ++++++++++++++++++++++++++++++++ + arch/arm/boot/dts/mt7629.dtsi | 22 ++++++++++++++++ + 3 files changed, 79 insertions(+) + +--- a/arch/arm/boot/dts/mt7629.dtsi ++++ b/arch/arm/boot/dts/mt7629.dtsi +@@ -259,6 +259,28 @@ + status = "disabled"; + }; + ++ bch: ecc@1100e000 { ++ compatible = "mediatek,mt7622-ecc"; ++ reg = <0x1100e000 0x1000>; ++ interrupts = ; ++ clocks = <&pericfg CLK_PERI_NFIECC_PD>; ++ clock-names = "nfiecc_clk"; ++ status = "disabled"; ++ }; ++ ++ snfi: spi@1100d000 { ++ compatible = "mediatek,mt7629-snfi"; ++ reg = <0x1100d000 0x1000>; ++ interrupts = ; ++ clocks = <&pericfg CLK_PERI_NFI_PD>, ++ <&pericfg CLK_PERI_SNFI_PD>; ++ clock-names = "nfi_clk", "spi_clk"; ++ ecc-engine = <&bch>; ++ #address-cells = <1>; ++ #size-cells = <0>; ++ status = "disabled"; ++ }; ++ + spi: spi@1100a000 { + compatible = "mediatek,mt7629-spi", + "mediatek,mt7622-spi"; +--- a/arch/arm/boot/dts/mt7629-rfb.dts ++++ b/arch/arm/boot/dts/mt7629-rfb.dts +@@ -281,6 +281,52 @@ + }; + }; + ++&bch { ++ status = "okay"; ++}; ++ ++&snfi { ++ pinctrl-names = "default"; ++ pinctrl-0 = <&serial_nand_pins>; ++ status = "okay"; ++ ++ spi_nand@0 { ++ #address-cells = <1>; ++ #size-cells = <1>; ++ compatible = "spi-nand"; ++ spi-max-frequency = <104000000>; ++ reg = <0>; ++ ++ partitions { ++ compatible = "fixed-partitions"; ++ #address-cells = <1>; ++ #size-cells = <1>; ++ ++ partition@0 { ++ label = "Bootloader"; ++ reg = <0x00000 0x0100000>; ++ read-only; ++ }; ++ ++ partition@100000 { ++ label = "Config"; ++ reg = <0x100000 0x0040000>; ++ }; ++ ++ partition@140000 { ++ label = "factory"; ++ reg = <0x140000 0x0080000>; ++ }; ++ ++ partition@1c0000 { ++ label = "firmware"; ++ reg = <0x1c0000 0x1000000>; ++ }; ++ ++ }; ++ }; ++}; ++ + &spi { + pinctrl-names = "default"; + pinctrl-0 = <&spi_pins>; diff --git a/target/linux/mediatek/patches-5.4/0308-dts-mt7622-add-snand-support.patch b/target/linux/mediatek/patches-5.4/0308-dts-mt7622-add-snand-support.patch new file mode 100644 index 0000000000..7c135cf2bf --- /dev/null +++ b/target/linux/mediatek/patches-5.4/0308-dts-mt7622-add-snand-support.patch @@ -0,0 +1,98 @@ +diff -urN a/arch/arm64/boot/dts/mediatek/mt7622.dtsi b/arch/arm64/boot/dts/mediatek/mt7622.dtsi +--- a/arch/arm64/boot/dts/mediatek/mt7622.dtsi 2020-03-02 17:16:13.700464470 +0800 ++++ b/arch/arm64/boot/dts/mediatek/mt7622.dtsi 2020-03-02 17:15:55.276885406 +0800 +@@ -554,6 +554,19 @@ + status = "disabled"; + }; + ++ snfi: spi@1100d000 { ++ compatible = "mediatek,mt7622-snfi"; ++ reg = <0 0x1100d000 0 0x1000>; ++ interrupts = ; ++ clocks = <&pericfg CLK_PERI_NFI_PD>, ++ <&pericfg CLK_PERI_SNFI_PD>; ++ clock-names = "nfi_clk", "spi_clk"; ++ ecc-engine = <&bch>; ++ #address-cells = <1>; ++ #size-cells = <0>; ++ status = "disabled"; ++ }; ++ + nor_flash: spi@11014000 { + compatible = "mediatek,mt7622-nor", + "mediatek,mt8173-nor"; +diff -urN a/arch/arm64/boot/dts/mediatek/mt7622-rfb1.dts b/arch/arm64/boot/dts/mediatek/mt7622-rfb1.dts +--- a/arch/arm64/boot/dts/mediatek/mt7622-rfb1.dts 2020-03-02 17:16:25.492193459 +0800 ++++ b/arch/arm64/boot/dts/mediatek/mt7622-rfb1.dts 2020-03-02 17:16:35.243968416 +0800 +@@ -108,7 +108,7 @@ + }; + + &bch { +- status = "disabled"; ++ status = "okay"; + }; + + &btif { +@@ -541,6 +541,62 @@ + status = "disable"; + }; + ++&snfi { ++ pinctrl-names = "default"; ++ pinctrl-0 = <&serial_nand_pins>; ++ status = "okay"; ++ ++ spi_nand@0 { ++ #address-cells = <1>; ++ #size-cells = <1>; ++ compatible = "spi-nand"; ++ spi-max-frequency = <104000000>; ++ reg = <0>; ++ ++ partitions { ++ compatible = "fixed-partitions"; ++ #address-cells = <1>; ++ #size-cells = <1>; ++ ++ partition@0 { ++ label = "Preloader"; ++ reg = <0x00000 0x0080000>; ++ read-only; ++ }; ++ ++ partition@80000 { ++ label = "ATF"; ++ reg = <0x80000 0x0040000>; ++ }; ++ ++ partition@c0000 { ++ label = "Bootloader"; ++ reg = <0xc0000 0x0080000>; ++ }; ++ ++ partition@140000 { ++ label = "Config"; ++ reg = <0x140000 0x0080000>; ++ }; ++ ++ partition@1c0000 { ++ label = "Factory"; ++ reg = <0x1c0000 0x0040000>; ++ }; ++ ++ partition@200000 { ++ label = "firmware"; ++ reg = <0x200000 0x2000000>; ++ }; ++ ++ partition@2200000 { ++ label = "User_data"; ++ reg = <0x2200000 0x4000000>; ++ }; ++ }; ++ }; ++}; ++ + &spi0 { + pinctrl-names = "default"; + pinctrl-0 = <&spic0_pins>; diff --git a/target/linux/mediatek/patches-5.4/0310-dts-add-wmac-support-for-mt7622-rfb1.patch b/target/linux/mediatek/patches-5.4/0310-dts-add-wmac-support-for-mt7622-rfb1.patch new file mode 100644 index 0000000000..463602e552 --- /dev/null +++ b/target/linux/mediatek/patches-5.4/0310-dts-add-wmac-support-for-mt7622-rfb1.patch @@ -0,0 +1,32 @@ +diff --git a/arch/arm64/boot/dts/mediatek/mt7622-rfb1.dts b/arch/arm64/boot/dts/mediatek/mt7622-rfb1.dts +index 1ec68de..44cc80c 100644 +--- a/arch/arm64/boot/dts/mediatek/mt7622-rfb1.dts ++++ b/arch/arm64/boot/dts/mediatek/mt7622-rfb1.dts +@@ -105,6 +105,18 @@ + regulator-boot-on; + regulator-always-on; + }; ++ ++ wmac: wmac@18000000 { ++ compatible = "mediatek,mt7622-wmac"; ++ reg = <0 0x18000000 0 0x100000>; ++ interrupts = ; ++ ++ mediatek,infracfg = <&infracfg>; ++ status = "okay"; ++ ++ power-domains = <&scpsys MT7622_POWER_DOMAIN_WB>; ++ mediatek,mtd-eeprom = <&factory 0x0000>; ++ }; + }; + + &bch { +@@ -579,7 +591,7 @@ + reg = <0x140000 0x0080000>; + }; + +- partition@1c0000 { ++ factory: partition@1c0000 { + label = "Factory"; + reg = <0x1c0000 0x0040000>; + };