From 050da2107a7eb2a571a8a3d0cee21cc6a44b72b8 Mon Sep 17 00:00:00 2001
From: John Crispin <john@phrozen.org>
Date: Mon, 7 May 2018 12:07:32 +0200
Subject: [PATCH] mediatek: backport upstream mediatek patches

Signed-off-by: John Crispin <john@phrozen.org>
---
 target/linux/mediatek/32/target.mk            |   13 -
 target/linux/mediatek/Makefile                |    4 +-
 target/linux/mediatek/base-files/etc/inittab  |    2 +-
 .../base-files/lib/upgrade/platform.sh        |   64 +-
 target/linux/mediatek/image/32.mk             |   32 -
 target/linux/mediatek/image/Makefile          |   34 +-
 target/linux/mediatek/image/mt7623.mk         |    6 +
 .../linux/mediatek/{ => mt7623}/config-4.14   |   15 +-
 .../{32 => mt7623}/profiles/default.mk        |    0
 target/linux/mediatek/mt7623/target.mk        |   16 +
 ...dd-reset-controller-dt-bindings-requ.patch |  120 +
 ...rap-fixup-warnings-from-coding-style.patch |   76 +
 ...support-option-to-disable-usb3-ports.patch |  117 +
 ...-remove-dummy-wakeup-debounce-clocks.patch |  126 +
 ...-add-optional-mcu-and-dma-bus-clocks.patch |  233 ++
 ...-usb-mtu3-support-36-bit-DMA-address.patch |  373 +++
 ...CE-RG_IDDIG-to-implement-manual-DRD-.patch |  290 ++
 ...9-usb-mtu3-add-support-for-usb3.1-IP.patch |  165 ++
 ...get-optional-vbus-for-host-only-mode.patch |   45 +
 ...et-invalid-dr_mode-as-dual-role-mode.patch |   34 +
 ..._sel-for-u2port-only-if-works-as-dua.patch |   49 +
 ...mtu3-add-a-optional-property-to-disa.patch |   30 +
 ...mtu3-remove-dummy-clocks-and-add-opt.patch |   46 +
 ...gs-usb-mtu3-remove-optional-pinctrls.patch |   35 +
 ...mediatek-add-MT7622-string-to-the-PM.patch |   43 +
 ...ap-add-pwrap_read32-for-reading-in-3.patch |  139 +
 ...ap-add-pwrap_write32-for-writing-in-.patch |  137 +
 ...ap-refactor-pwrap_init-for-the-vario.patch |  232 ++
 ...ap-add-MediaTek-MT6380-as-one-slave-.patch |  103 +
 ...ap-add-common-way-for-setup-CS-timin.patch |  124 +
 ...tek-pwrap-add-support-for-MT7622-SoC.patch |  242 ++
 ...ce-Kconfig-for-all-SoC-drivers-under.patch |   62 +
 ...leanup-message-for-platform-selectio.patch |   39 +
 ...y-phy-mtk-tphy-add-set_mode-callback.patch |   91 +
 ...-dma_set_mask_and_coherent-in-probe-.patch |   40 +
 ...-ports-count-from-xhci-in-xhci_mtk_s.patch |   60 +
 ...-mtk-check-clock-stability-of-U3_MAC.patch |   41 +
 ...support-option-to-disable-usb3-ports.patch |   92 +
 ...-remove-dummy-wakeup-debounce-clocks.patch |   93 +
 ...-add-optional-mcu-and-dma-bus-clocks.patch |  146 ++
 ...dify-description-for-MTK-xHCI-config.patch |   37 +
 ...mtk-xhci-add-a-optional-property-to-.patch |   30 +
 ...mtk-xhci-remove-dummy-clocks-and-add.patch |   63 +
 ...add-new-compatible-strings-and-impro.patch |   47 +
 ...d-mtk-nor-add-suspend-resume-support.patch |  133 +
 ...mediatek-add-bindings-for-MediaTek-S.patch |   47 +
 ...tek-add-driver-for-RTC-on-MT7622-SoC.patch |  481 ++++
 ...ance-the-description-for-MediaTek-PM.patch |   44 +
 ...nge-the-compile-sequence-of-mtk_nand.patch |   36 +
 ...Add-reg-source_cg-latch-ck-for-Media.patch |   65 +
 ...ediatek-add-support-of-mt2701-mt2712.patch |  192 ++
 ...Mediatek-Document-bindings-for-MT271.patch |  226 ++
 ...ek-Add-dt-bindings-for-MT2712-clocks.patch |  452 ++++
 ...lk-mediatek-Add-MT2712-clock-support.patch | 2331 +++++++++++++++++
 ...k-mediatek-document-clk-bindings-for.patch |  217 ++
 ...-clocks-dt-bindings-required-header-.patch |  316 +++
 ...tek-add-clock-support-for-MT7622-SoC.patch | 1407 ++++++++++
 ...-remove-mediatek-mt8135-mmc-from-mmc.patch |   66 +
 ...e-hs400_tune_response-only-for-mt817.patch |   75 +
 ...3-mmc-mediatek-add-pad_tune0-support.patch |  261 ++
 ...add-async-fifo-and-data-tune-support.patch |  175 ++
 ...-mmc-mediatek-add-busy_check-support.patch |   72 +
 ...-stop_clk-fix-and-enhance_rx-support.patch |  173 ++
 ...iatek-add-support-of-source_cg-clock.patch |   90 +
 ...58-mmc-mediatek-add-latch-ck-support.patch |   50 +
 ...rove-eMMC-hs400-mode-read-performanc.patch |   73 +
 ...fer-to-use-rise-edge-latching-for-cm.patch |   33 +
 ...m-mediatek-Add-MT2712-MT7622-support.patch |  150 ++
 ...-nand_reset-to-reset-NAND-devices-in.patch |   46 +
 ...atek-add-mt2712-into-compatible-list.patch |   29 +
 ...0165-mtd-nand-mtk-update-DT-bindings.patch |   46 +
 ...port-different-MTK-NAND-flash-contro.patch |  389 +++
 ...Support-MT7622-NAND-flash-controller.patch |  116 +
 ...ndings-add-mmc-support-to-MT7623-SoC.patch |   31 +
 ...trl-add-bindings-for-MediaTek-MT7622.patch |  377 +++
 ...-cleanup-for-placing-all-drivers-und.patch |   37 +
 ...ek-add-pinctrl-driver-for-MT7622-SoC.patch | 1686 ++++++++++++
 ...-group-drivers-under-indpendent-menu.patch |  228 ++
 ...up-test-building-of-MediaTek-clock-d.patch |   32 +
 ...mediatek-add-condition-to-property-m.patch |   32 +
 ...ove-superfluous-pin-setup-for-MT7622.patch |  106 +
 ...-all-warnings-for-missing-struct-clk.patch |   73 +
 ...-use-auto-instead-of-force-to-bypass.patch |   80 +
 ...-make-shared-banks-optional-for-V1-T.patch |   35 +
 ...tk-tphy-use-of_device_get_match_data.patch |   56 +
 ...x-error-handling-in-mt2701_afe_pcm_d.patch |   86 +
 ...ek-rework-clock-functions-for-MT2701.patch |  932 +++++++
 ...atek-cleanup-audio-driver-for-MT2701.patch |  439 ++++
 ...date-clock-related-properties-of-MT2.patch |  263 ++
 ...-add-some-core-clocks-for-MT2701-AFE.patch |  100 +
 ...dify-MT2701-AFE-driver-to-adapt-mfd-.patch |  135 +
 ...date-MT2701-AFE-documentation-to-ada.patch |  217 ++
 ...error-code-for-getting-extcon-device.patch |   31 +
 ...s-remote-wakeup-for-mt2712-with-two-.patch |  245 ++
 ...sb-mtu3-update-USB-wakeup-properties.patch |   52 +
 ...ports-remote-wakeup-for-mt2712-with-.patch |  273 ++
 ...low-imod-interval-to-be-configurable.patch |  155 ++
 ...mtk-xhci-update-USB-wakeup-propertie.patch |   54 +
 ...ust-dependency-of-reset.c-to-avoid-u.patch |   77 +
 ...-mt7622-fix-potential-uninitialized-.patch |   54 +
 ...-mt7622-align-error-handling-of-mtk_.patch |   55 +
 ...modify-functions-name-more-generally.patch |  559 ++++
 ...g-mediatek-Setup-default-RNG-quality.patch |   30 +
 ...s-thermal-add-binding-for-MT7622-SoC.patch |   31 +
 ...9-thermal-mtk-Cleanup-unused-defines.patch |   56 +
 ...-mediatek-add-support-for-MT7622-SoC.patch |   86 +
 ...k-mediatek-add-missing-required-rese.patch |   73 +
 ...-bindings-add-support-for-MT7622-SoC.patch |   27 +
 ...-mediatek-add-support-for-MT7622-SoC.patch |   47 +
 ...ngine-Add-MediaTek-High-Speed-DMA-co.patch |   57 +
 ...ek-Add-MediaTek-High-Speed-DMA-contr.patch | 1144 ++++++++
 ...k-mediatek-update-audsys-documentati.patch |   50 +
 ...k-mediatek-add-audsys-support-for-MT.patch |   28 +
 ...ate-missing-clock-data-for-MT7622-au.patch |   45 +
 ...-devm_of_platform_populate-for-MT762.patch |   47 +
 ...22-add-clock-controller-device-nodes.patch |  135 +
 ...-add-power-domain-controller-device-.patch |   50 +
 ...622-add-pinctrl-related-device-nodes.patch |  259 ++
 ...mt7622-add-PMIC-MT6380-related-nodes.patch |  165 ++
 ...622-add-cpufreq-related-device-nodes.patch |  119 +
 ...mt7622-turn-uart0-clock-to-real-ones.patch |   50 +
 ...-add-SoC-and-peripheral-related-devi.patch |  427 +++
 ...t7622-add-flash-related-device-nodes.patch |  103 +
 ...dts-mt7622-add-ethernet-device-nodes.patch |   91 +
 ...m64-dts-mt7622-add-PCIe-device-nodes.patch |  123 +
 ...m64-dts-mt7622-add-SATA-device-nodes.patch |   94 +
 ...rm64-dts-mt7622-add-usb-device-nodes.patch |  126 +
 ...7622-add-High-Speed-DMA-device-nodes.patch |   36 +
 ...-mt7622-add-mmc-related-device-nodes.patch |  207 ++
 ...config-for-testing-these-new-drivers.patch |  294 +++
 130 files changed, 21978 insertions(+), 99 deletions(-)
 delete mode 100644 target/linux/mediatek/32/target.mk
 delete mode 100644 target/linux/mediatek/image/32.mk
 create mode 100644 target/linux/mediatek/image/mt7623.mk
 rename target/linux/mediatek/{ => mt7623}/config-4.14 (98%)
 rename target/linux/mediatek/{32 => mt7623}/profiles/default.mk (100%)
 create mode 100644 target/linux/mediatek/mt7623/target.mk
 create mode 100644 target/linux/mediatek/patches-4.14/0101-reset-mediatek-add-reset-controller-dt-bindings-requ.patch
 create mode 100644 target/linux/mediatek/patches-4.14/0102-soc-mediatek-pwrap-fixup-warnings-from-coding-style.patch
 create mode 100644 target/linux/mediatek/patches-4.14/0104-usb-mtu3-support-option-to-disable-usb3-ports.patch
 create mode 100644 target/linux/mediatek/patches-4.14/0105-usb-mtu3-remove-dummy-wakeup-debounce-clocks.patch
 create mode 100644 target/linux/mediatek/patches-4.14/0106-usb-mtu3-add-optional-mcu-and-dma-bus-clocks.patch
 create mode 100644 target/linux/mediatek/patches-4.14/0107-usb-mtu3-support-36-bit-DMA-address.patch
 create mode 100644 target/linux/mediatek/patches-4.14/0108-usb-mtu3-use-FORCE-RG_IDDIG-to-implement-manual-DRD-.patch
 create mode 100644 target/linux/mediatek/patches-4.14/0109-usb-mtu3-add-support-for-usb3.1-IP.patch
 create mode 100644 target/linux/mediatek/patches-4.14/0110-usb-mtu3-get-optional-vbus-for-host-only-mode.patch
 create mode 100644 target/linux/mediatek/patches-4.14/0111-usb-mtu3-set-invalid-dr_mode-as-dual-role-mode.patch
 create mode 100644 target/linux/mediatek/patches-4.14/0112-usb-mtu3-set-otg_sel-for-u2port-only-if-works-as-dua.patch
 create mode 100644 target/linux/mediatek/patches-4.14/0113-dt-bindings-usb-mtu3-add-a-optional-property-to-disa.patch
 create mode 100644 target/linux/mediatek/patches-4.14/0114-dt-bindings-usb-mtu3-remove-dummy-clocks-and-add-opt.patch
 create mode 100644 target/linux/mediatek/patches-4.14/0115-dt-bindings-usb-mtu3-remove-optional-pinctrls.patch
 create mode 100644 target/linux/mediatek/patches-4.14/0116-dt-bindings-arm-mediatek-add-MT7622-string-to-the-PM.patch
 create mode 100644 target/linux/mediatek/patches-4.14/0117-soc-mediatek-pwrap-add-pwrap_read32-for-reading-in-3.patch
 create mode 100644 target/linux/mediatek/patches-4.14/0118-soc-mediatek-pwrap-add-pwrap_write32-for-writing-in-.patch
 create mode 100644 target/linux/mediatek/patches-4.14/0119-soc-mediatek-pwrap-refactor-pwrap_init-for-the-vario.patch
 create mode 100644 target/linux/mediatek/patches-4.14/0120-soc-mediatek-pwrap-add-MediaTek-MT6380-as-one-slave-.patch
 create mode 100644 target/linux/mediatek/patches-4.14/0121-soc-mediatek-pwrap-add-common-way-for-setup-CS-timin.patch
 create mode 100644 target/linux/mediatek/patches-4.14/0122-soc-mediatek-pwrap-add-support-for-MT7622-SoC.patch
 create mode 100644 target/linux/mediatek/patches-4.14/0123-soc-mediatek-place-Kconfig-for-all-SoC-drivers-under.patch
 create mode 100644 target/linux/mediatek/patches-4.14/0124-arm64-mediatek-cleanup-message-for-platform-selectio.patch
 create mode 100644 target/linux/mediatek/patches-4.14/0125-phy-phy-mtk-tphy-add-set_mode-callback.patch
 create mode 100644 target/linux/mediatek/patches-4.14/0126-usb-xhci-mtk-use-dma_set_mask_and_coherent-in-probe-.patch
 create mode 100644 target/linux/mediatek/patches-4.14/0127-usb-xhci-mtk-use-ports-count-from-xhci-in-xhci_mtk_s.patch
 create mode 100644 target/linux/mediatek/patches-4.14/0128-usb-xhci-mtk-check-clock-stability-of-U3_MAC.patch
 create mode 100644 target/linux/mediatek/patches-4.14/0129-usb-xhci-mtk-support-option-to-disable-usb3-ports.patch
 create mode 100644 target/linux/mediatek/patches-4.14/0130-usb-xhci-mtk-remove-dummy-wakeup-debounce-clocks.patch
 create mode 100644 target/linux/mediatek/patches-4.14/0131-usb-xhci-mtk-add-optional-mcu-and-dma-bus-clocks.patch
 create mode 100644 target/linux/mediatek/patches-4.14/0132-usb-host-modify-description-for-MTK-xHCI-config.patch
 create mode 100644 target/linux/mediatek/patches-4.14/0133-dt-bindings-usb-mtk-xhci-add-a-optional-property-to-.patch
 create mode 100644 target/linux/mediatek/patches-4.14/0134-dt-bindings-usb-mtk-xhci-remove-dummy-clocks-and-add.patch
 create mode 100644 target/linux/mediatek/patches-4.14/0135-dt-bindings-mtd-add-new-compatible-strings-and-impro.patch
 create mode 100644 target/linux/mediatek/patches-4.14/0136-mtd-mtk-nor-add-suspend-resume-support.patch
 create mode 100644 target/linux/mediatek/patches-4.14/0137-dt-bindings-rtc-mediatek-add-bindings-for-MediaTek-S.patch
 create mode 100644 target/linux/mediatek/patches-4.14/0138-rtc-mediatek-add-driver-for-RTC-on-MT7622-SoC.patch
 create mode 100644 target/linux/mediatek/patches-4.14/0139-rtc-mediatek-enhance-the-description-for-MediaTek-PM.patch
 create mode 100644 target/linux/mediatek/patches-4.14/0140-mtd-nand-mtk-change-the-compile-sequence-of-mtk_nand.patch
 create mode 100644 target/linux/mediatek/patches-4.14/0142-mmc-dt-bindings-Add-reg-source_cg-latch-ck-for-Media.patch
 create mode 100644 target/linux/mediatek/patches-4.14/0143-mmc-mediatek-add-support-of-mt2701-mt2712.patch
 create mode 100644 target/linux/mediatek/patches-4.14/0144-dt-bindings-ARM-Mediatek-Document-bindings-for-MT271.patch
 create mode 100644 target/linux/mediatek/patches-4.14/0145-clk-mediatek-Add-dt-bindings-for-MT2712-clocks.patch
 create mode 100644 target/linux/mediatek/patches-4.14/0146-clk-mediatek-Add-MT2712-clock-support.patch
 create mode 100644 target/linux/mediatek/patches-4.14/0147-dt-bindings-clock-mediatek-document-clk-bindings-for.patch
 create mode 100644 target/linux/mediatek/patches-4.14/0149-clk-mediatek-add-clocks-dt-bindings-required-header-.patch
 create mode 100644 target/linux/mediatek/patches-4.14/0150-clk-mediatek-add-clock-support-for-MT7622-SoC.patch
 create mode 100644 target/linux/mediatek/patches-4.14/0151-arm64-dts-mt8173-remove-mediatek-mt8135-mmc-from-mmc.patch
 create mode 100644 target/linux/mediatek/patches-4.14/0152-mmc-mediatek-make-hs400_tune_response-only-for-mt817.patch
 create mode 100644 target/linux/mediatek/patches-4.14/0153-mmc-mediatek-add-pad_tune0-support.patch
 create mode 100644 target/linux/mediatek/patches-4.14/0154-mmc-mediatek-add-async-fifo-and-data-tune-support.patch
 create mode 100644 target/linux/mediatek/patches-4.14/0155-mmc-mediatek-add-busy_check-support.patch
 create mode 100644 target/linux/mediatek/patches-4.14/0156-mmc-mediatek-add-stop_clk-fix-and-enhance_rx-support.patch
 create mode 100644 target/linux/mediatek/patches-4.14/0157-mmc-mediatek-add-support-of-source_cg-clock.patch
 create mode 100644 target/linux/mediatek/patches-4.14/0158-mmc-mediatek-add-latch-ck-support.patch
 create mode 100644 target/linux/mediatek/patches-4.14/0159-mmc-mediatek-improve-eMMC-hs400-mode-read-performanc.patch
 create mode 100644 target/linux/mediatek/patches-4.14/0160-mmc-mediatek-perfer-to-use-rise-edge-latching-for-cm.patch
 create mode 100644 target/linux/mediatek/patches-4.14/0161-pwm-mediatek-Add-MT2712-MT7622-support.patch
 create mode 100644 target/linux/mediatek/patches-4.14/0162-mtd-nand-mtk-use-nand_reset-to-reset-NAND-devices-in.patch
 create mode 100644 target/linux/mediatek/patches-4.14/0164-cpufreq-mediatek-add-mt2712-into-compatible-list.patch
 create mode 100644 target/linux/mediatek/patches-4.14/0165-mtd-nand-mtk-update-DT-bindings.patch
 create mode 100644 target/linux/mediatek/patches-4.14/0166-mtd-nand-mtk-Support-different-MTK-NAND-flash-contro.patch
 create mode 100644 target/linux/mediatek/patches-4.14/0167-mtd-nand-mtk-Support-MT7622-NAND-flash-controller.patch
 create mode 100644 target/linux/mediatek/patches-4.14/0168-mmc-dt-bindings-add-mmc-support-to-MT7623-SoC.patch
 create mode 100644 target/linux/mediatek/patches-4.14/0169-dt-bindings-pinctrl-add-bindings-for-MediaTek-MT7622.patch
 create mode 100644 target/linux/mediatek/patches-4.14/0170-pinctrl-mediatek-cleanup-for-placing-all-drivers-und.patch
 create mode 100644 target/linux/mediatek/patches-4.14/0171-pinctrl-mediatek-add-pinctrl-driver-for-MT7622-SoC.patch
 create mode 100644 target/linux/mediatek/patches-4.14/0172-clk-mediatek-group-drivers-under-indpendent-menu.patch
 create mode 100644 target/linux/mediatek/patches-4.14/0173-clk-mediatek-fixup-test-building-of-MediaTek-clock-d.patch
 create mode 100644 target/linux/mediatek/patches-4.14/0174-dt-bindings-net-mediatek-add-condition-to-property-m.patch
 create mode 100644 target/linux/mediatek/patches-4.14/0175-net-mediatek-remove-superfluous-pin-setup-for-MT7622.patch
 create mode 100644 target/linux/mediatek/patches-4.14/0176-clk-mediatek-Fix-all-warnings-for-missing-struct-clk.patch
 create mode 100644 target/linux/mediatek/patches-4.14/0177-phy-phy-mtk-tphy-use-auto-instead-of-force-to-bypass.patch
 create mode 100644 target/linux/mediatek/patches-4.14/0178-phy-phy-mtk-tphy-make-shared-banks-optional-for-V1-T.patch
 create mode 100644 target/linux/mediatek/patches-4.14/0179-phy-phy-mtk-tphy-use-of_device_get_match_data.patch
 create mode 100644 target/linux/mediatek/patches-4.14/0180-ASoC-mediatek-fix-error-handling-in-mt2701_afe_pcm_d.patch
 create mode 100644 target/linux/mediatek/patches-4.14/0181-ASoC-mediatek-rework-clock-functions-for-MT2701.patch
 create mode 100644 target/linux/mediatek/patches-4.14/0182-ASoC-mediatek-cleanup-audio-driver-for-MT2701.patch
 create mode 100644 target/linux/mediatek/patches-4.14/0183-ASoC-mediatek-update-clock-related-properties-of-MT2.patch
 create mode 100644 target/linux/mediatek/patches-4.14/0184-ASoC-mediatek-add-some-core-clocks-for-MT2701-AFE.patch
 create mode 100644 target/linux/mediatek/patches-4.14/0185-ASoC-mediatek-modify-MT2701-AFE-driver-to-adapt-mfd-.patch
 create mode 100644 target/linux/mediatek/patches-4.14/0186-ASoC-mediatek-update-MT2701-AFE-documentation-to-ada.patch
 create mode 100644 target/linux/mediatek/patches-4.14/0187-usb-mtu3-fix-error-code-for-getting-extcon-device.patch
 create mode 100644 target/linux/mediatek/patches-4.14/0188-usb-mtu3-supports-remote-wakeup-for-mt2712-with-two-.patch
 create mode 100644 target/linux/mediatek/patches-4.14/0189-dt-bindings-usb-mtu3-update-USB-wakeup-properties.patch
 create mode 100644 target/linux/mediatek/patches-4.14/0190-usb-xhci-mtk-supports-remote-wakeup-for-mt2712-with-.patch
 create mode 100644 target/linux/mediatek/patches-4.14/0191-usb-xhci-allow-imod-interval-to-be-configurable.patch
 create mode 100644 target/linux/mediatek/patches-4.14/0192-dt-bindings-usb-mtk-xhci-update-USB-wakeup-propertie.patch
 create mode 100644 target/linux/mediatek/patches-4.14/0193-clk-mediatek-adjust-dependency-of-reset.c-to-avoid-u.patch
 create mode 100644 target/linux/mediatek/patches-4.14/0194-pinctrl-mediatek-mt7622-fix-potential-uninitialized-.patch
 create mode 100644 target/linux/mediatek/patches-4.14/0195-pinctrl-mediatek-mt7622-align-error-handling-of-mtk_.patch
 create mode 100644 target/linux/mediatek/patches-4.14/0196-mtd-mtk-nor-modify-functions-name-more-generally.patch
 create mode 100644 target/linux/mediatek/patches-4.14/0197-hwrng-mediatek-Setup-default-RNG-quality.patch
 create mode 100644 target/linux/mediatek/patches-4.14/0198-dt-bindings-thermal-add-binding-for-MT7622-SoC.patch
 create mode 100644 target/linux/mediatek/patches-4.14/0199-thermal-mtk-Cleanup-unused-defines.patch
 create mode 100644 target/linux/mediatek/patches-4.14/0200-thermal-mediatek-add-support-for-MT7622-SoC.patch
 create mode 100644 target/linux/mediatek/patches-4.14/0201-dt-bindings-clock-mediatek-add-missing-required-rese.patch
 create mode 100644 target/linux/mediatek/patches-4.14/0202-mmc-dt-bindings-add-support-for-MT7622-SoC.patch
 create mode 100644 target/linux/mediatek/patches-4.14/0203-mmc-mediatek-add-support-for-MT7622-SoC.patch
 create mode 100644 target/linux/mediatek/patches-4.14/0204-dt-bindings-dmaengine-Add-MediaTek-High-Speed-DMA-co.patch
 create mode 100644 target/linux/mediatek/patches-4.14/0205-dmaengine-mediatek-Add-MediaTek-High-Speed-DMA-contr.patch
 create mode 100644 target/linux/mediatek/patches-4.14/0206-dt-bindings-clock-mediatek-update-audsys-documentati.patch
 create mode 100644 target/linux/mediatek/patches-4.14/0207-dt-bindings-clock-mediatek-add-audsys-support-for-MT.patch
 create mode 100644 target/linux/mediatek/patches-4.14/0208-clk-mediatek-update-missing-clock-data-for-MT7622-au.patch
 create mode 100644 target/linux/mediatek/patches-4.14/0209-clk-mediatek-add-devm_of_platform_populate-for-MT762.patch
 create mode 100644 target/linux/mediatek/patches-4.14/0210-arm64-dts-mt7622-add-clock-controller-device-nodes.patch
 create mode 100644 target/linux/mediatek/patches-4.14/0211-arm64-dts-mt7622-add-power-domain-controller-device-.patch
 create mode 100644 target/linux/mediatek/patches-4.14/0212-arm64-dts-mt7622-add-pinctrl-related-device-nodes.patch
 create mode 100644 target/linux/mediatek/patches-4.14/0213-arm64-dts-mt7622-add-PMIC-MT6380-related-nodes.patch
 create mode 100644 target/linux/mediatek/patches-4.14/0214-arm64-dts-mt7622-add-cpufreq-related-device-nodes.patch
 create mode 100644 target/linux/mediatek/patches-4.14/0215-arm64-dts-mt7622-turn-uart0-clock-to-real-ones.patch
 create mode 100644 target/linux/mediatek/patches-4.14/0216-arm64-dts-mt7622-add-SoC-and-peripheral-related-devi.patch
 create mode 100644 target/linux/mediatek/patches-4.14/0217-arm64-dts-mt7622-add-flash-related-device-nodes.patch
 create mode 100644 target/linux/mediatek/patches-4.14/0218-arm64-dts-mt7622-add-ethernet-device-nodes.patch
 create mode 100644 target/linux/mediatek/patches-4.14/0219-arm64-dts-mt7622-add-PCIe-device-nodes.patch
 create mode 100644 target/linux/mediatek/patches-4.14/0220-arm64-dts-mt7622-add-SATA-device-nodes.patch
 create mode 100644 target/linux/mediatek/patches-4.14/0221-arm64-dts-mt7622-add-usb-device-nodes.patch
 create mode 100644 target/linux/mediatek/patches-4.14/0222-arm64-dts-mt7622-add-High-Speed-DMA-device-nodes.patch
 create mode 100644 target/linux/mediatek/patches-4.14/0223-arm64-dts-mt7622-add-mmc-related-device-nodes.patch
 create mode 100644 target/linux/mediatek/patches-4.14/0224-add-mt7622-defconfig-for-testing-these-new-drivers.patch

diff --git a/target/linux/mediatek/32/target.mk b/target/linux/mediatek/32/target.mk
deleted file mode 100644
index 0a444c2758..0000000000
--- a/target/linux/mediatek/32/target.mk
+++ /dev/null
@@ -1,13 +0,0 @@
-#
-# Copyright (C) 2009 OpenWrt.org
-#
-
-SUBTARGET:=32
-BOARDNAME:=32bit
-CPU_TYPE:=cortex-a7
-CPU_SUBTYPE:=neon-vfpv4
-
-define Target/Description
-	Build firmware images for MediaTek 32bit ARM based boards.
-endef
-
diff --git a/target/linux/mediatek/Makefile b/target/linux/mediatek/Makefile
index 6b30f3b19d..7b8742da61 100644
--- a/target/linux/mediatek/Makefile
+++ b/target/linux/mediatek/Makefile
@@ -5,14 +5,12 @@ include $(TOPDIR)/rules.mk
 ARCH:=arm
 BOARD:=mediatek
 BOARDNAME:=MediaTek Ralink ARM
-SUBTARGETS:=32
+SUBTARGETS:=mt7623
 FEATURES:=squashfs nand ramdisk fpu
 MAINTAINER:=John Crispin <john@phrozen.org>
 
 KERNEL_PATCHVER:=4.14
 
-KERNELNAME:=Image dtbs zImage
-
 include $(INCLUDE_DIR)/target.mk
 DEFAULT_PACKAGES += \
 	kmod-mt76 kmod-leds-gpio kmod-gpio-button-hotplug \
diff --git a/target/linux/mediatek/base-files/etc/inittab b/target/linux/mediatek/base-files/etc/inittab
index b169c82745..9820e7144b 100644
--- a/target/linux/mediatek/base-files/etc/inittab
+++ b/target/linux/mediatek/base-files/etc/inittab
@@ -1,3 +1,3 @@
 ::sysinit:/etc/init.d/rcS S boot
 ::shutdown:/etc/init.d/rcS K shutdown
-ttyS0::askfirst:/usr/libexec/login.sh
+::askconsole:/usr/libexec/login.sh
diff --git a/target/linux/mediatek/base-files/lib/upgrade/platform.sh b/target/linux/mediatek/base-files/lib/upgrade/platform.sh
index 0429ca8b89..646ce0dc53 100755
--- a/target/linux/mediatek/base-files/lib/upgrade/platform.sh
+++ b/target/linux/mediatek/base-files/lib/upgrade/platform.sh
@@ -1,49 +1,29 @@
-#
-# Copyright (C) 2016 OpenWrt.org
-#
+platform_do_upgrade() {                 
+	default_do_upgrade "$ARGV"                                               
+}                                                                                
 
-platform_do_upgrade() {
-	local tar_file="$1"
-	local board="$(board_name)"
+PART_NAME=firmware
 
-	case "$(board_name)" in
-	mediatek,mt7623-rfb-nand-ephy |\
-	mediatek,mt7623-rfb-nand)
-		nand_do_upgrade $1
-		;;
-	*)
-		echo "flashing kernel"
-		tar xf $tar_file sysupgrade-$board/kernel -O | mtd write - kernel
+platform_check_image() {                                                         
+	local board=$(board_name)                                                
+	local magic="$(get_magic_long "$1")"                                     
 
-		echo "flashing rootfs"
-		tar xf $tar_file sysupgrade-$board/root -O | mtd write - rootfs
+	[ "$#" -gt 1 ] && return 1                                               
 
-		return 0
-		;;
-	esac
-}
+	case "$board" in                                                       
+	bananapi,bpi-r2)                                                       
+		[ "$magic" != "27051956" ] && {   
+			echo "Invalid image type."
+			return 1                                     
+		}                                                    
+		return 0                                             
+		;;                                                   
 
-platform_check_image() {
-	local tar_file="$1"
-	local board=$(board_name)
-
-	case "$board" in
-	bananapi,bpi-r2 |\
-	mediatek,mt7623a-rfb-emmc)
-		local kernel_length=`(tar xf $tar_file sysupgrade-$board/kernel -O | wc -c) 2> /dev/null`
-		local rootfs_length=`(tar xf $tar_file sysupgrade-$board/root -O | wc -c) 2> /dev/null`
-		;;
-
-	*)
+	*)                                                           
 		echo "Sysupgrade is not supported on your board yet."
-		return 1
-		;;
-	esac
-
-	[ "$kernel_length" = 0 -o "$rootfs_length" = 0 ] && {
-		echo "The upgarde image is corrupt."
-		return 1
-	}
+		return 1                                             
+		;;                                
+	esac                                      
 
-	return 0
-}
+	return 0                                                                                         
+}                   
diff --git a/target/linux/mediatek/image/32.mk b/target/linux/mediatek/image/32.mk
deleted file mode 100644
index 7b7e303124..0000000000
--- a/target/linux/mediatek/image/32.mk
+++ /dev/null
@@ -1,32 +0,0 @@
-define Image/BuilduImage
-	$(CP) $(KDIR)/zImage$(2) $(KDIR)/zImage-$(1)$(2)
-	cat $(LINUX_DIR)/arch/arm/boot/dts/$1.dtb >> $(KDIR)/zImage-$(1)$(2)
-	mkimage -A arm -O linux -T kernel -C none -a 0x80008000 -e 0x80008000 -n 'MIPS OpenWrt Linux-$(LINUX_VERSION)'  -d $(KDIR)/zImage-$(1)$(2) $(KDIR)/uImage-$(1)$(2)
-endef
-
-define Image/Build/SysupgradeCombined
-	$(call Image/BuilduImage,$1)
-ifneq ($(CONFIG_TARGET_ROOTFS_INITRAMFS),)
-	$(call Image/BuilduImage,$1,-initramfs)
-	$(CP) $(KDIR)/uImage-$(1)-initramfs $(BIN_DIR)/$(IMG_PREFIX)-uImage-$(1)-initramfs
-endif
-	mkdir -p "$(KDIR_TMP)/sysupgrade-$(3)/"
-	echo "BOARD=$(3)" > "$(KDIR_TMP)/sysupgrade-$(3)/CONTROL"
-	$(CP) "$(KDIR)/root.$(2)" "$(KDIR_TMP)/sysupgrade-$(3)/root"
-	$(CP) "$(KDIR)/uImage-$(1)" "$(KDIR_TMP)/sysupgrade-$(3)/kernel"
-	(cd "$(KDIR_TMP)"; $(TAR) cvf \
-		"$(BIN_DIR)/$(IMG_PREFIX)-$(3)-sysupgrade.tar" sysupgrade-$(3) \
-			$(if $(SOURCE_DATE_EPOCH),--mtime="@$(SOURCE_DATE_EPOCH)") \
-	)
-endef
-
-COMPAT_BPI-R2:=bananapi,bpi-r2
-COMPAT_EMMC:=mediatek,mt7623a-rfb-emmc
-
-define Image/Build/squashfs
-	$(call prepare_generic_squashfs,$(KDIR)/root.squashfs)
-	$(CP) $(KDIR)/root.squashfs $(BIN_DIR)/$(IMG_PREFIX)-root.squashfs
-
-	$(call Image/Build/SysupgradeCombined,mt7623n-bananapi-bpi-r2,squashfs,$$(COMPAT_BPI-R2))
-	$(call Image/Build/SysupgradeCombined,mt7623a-rfb-emmc,squashfs,$$(COMPAT_EMMC))
-endef
diff --git a/target/linux/mediatek/image/Makefile b/target/linux/mediatek/image/Makefile
index 6721259b20..9e2575b7ee 100644
--- a/target/linux/mediatek/image/Makefile
+++ b/target/linux/mediatek/image/Makefile
@@ -1,10 +1,42 @@
+#
+# Copyright (C) 2012-2015 OpenWrt.org
+# Copyright (C) 2016-2017 LEDE project
+#
+# This is free software, licensed under the GNU General Public License v2.
+# See /LICENSE for more information.
+#
 include $(TOPDIR)/rules.mk
 include $(INCLUDE_DIR)/image.mk
 
-include $(SUBTARGET).mk
+# for arm
+KERNEL_LOADADDR := 0x80008000
+
+# build dtb
+define Build/dtb
+        $(call Image/BuildDTB,$(DEVICE_DTS_DIR)/$(DEVICE_DTS).dts,$(DEVICE_DTS_DIR)/$(DEVICE_DTS).dtb)
+	$(CP) $(DEVICE_DTS_DIR)/$(DEVICE_DTS).dtb $(BIN_DIR)/
+endef
+
+# default all platform image(fit) build 
+define Device/Default
+  PROFILES = Default $$(DEVICE_NAME)
+  KERNEL_NAME := zImage
+  FILESYSTEMS := squashfs
+  DEVICE_DTS_DIR := $(DTS_DIR)
+  IMAGES := sysupgrade.bin
+  IMAGE/sysupgrade.bin := append-kernel | append-rootfs | pad-rootfs | append-metadata 
+  KERNEL_NAME := zImage
+  KERNEL := dtb | kernel-bin | append-dtb | uImage none
+  KERNEL_INITRAMFS := dtb | kernel-bin | append-dtb | uImage none
+endef
+
+ifeq ($(SUBTARGET),mt7623)
+include mt7623.mk
+endif
 
 define Image/Build
 	$(call Image/Build/$(1),$(1))
 endef
 
 $(eval $(call BuildImage))
+
diff --git a/target/linux/mediatek/image/mt7623.mk b/target/linux/mediatek/image/mt7623.mk
new file mode 100644
index 0000000000..ddb4faa480
--- /dev/null
+++ b/target/linux/mediatek/image/mt7623.mk
@@ -0,0 +1,6 @@
+define Device/7623n-bananapi-bpi-r2
+  DEVICE_TITLE := MTK7623n BananaPi R2
+  DEVICE_DTS := mt7623n-bananapi-bpi-r2
+endef
+
+TARGET_DEVICES += 7623n-bananapi-bpi-r2
diff --git a/target/linux/mediatek/config-4.14 b/target/linux/mediatek/mt7623/config-4.14
similarity index 98%
rename from target/linux/mediatek/config-4.14
rename to target/linux/mediatek/mt7623/config-4.14
index 02365ca2c4..4cdd0e76e1 100644
--- a/target/linux/mediatek/config-4.14
+++ b/target/linux/mediatek/mt7623/config-4.14
@@ -1,4 +1,3 @@
-# CONFIG_AHCI_MTK is not set
 # CONFIG_AIO is not set
 CONFIG_ALIGNMENT_TRAP=y
 CONFIG_ARCH_CLOCKSOURCE_DATA=y
@@ -63,7 +62,7 @@ CONFIG_CLKDEV_LOOKUP=y
 CONFIG_CLKSRC_MMIO=y
 CONFIG_CLONE_BACKWARDS=y
 CONFIG_CMDLINE="earlyprintk console=ttyS0,115200 rootfstype=squashfs,jffs2"
-CONFIG_CMDLINE_FORCE=y
+CONFIG_CMDLINE_FROM_BOOTLOADER=y
 CONFIG_COMMON_CLK=y
 CONFIG_COMMON_CLK_MEDIATEK=y
 CONFIG_COMMON_CLK_MT2701=y
@@ -73,6 +72,7 @@ CONFIG_COMMON_CLK_MT2701_HIFSYS=y
 CONFIG_COMMON_CLK_MT2701_IMGSYS=y
 CONFIG_COMMON_CLK_MT2701_MMSYS=y
 CONFIG_COMMON_CLK_MT2701_VDECSYS=y
+# CONFIG_COMMON_CLK_MT7622 is not set
 # CONFIG_COMMON_CLK_MT8135 is not set
 # CONFIG_COMMON_CLK_MT8173 is not set
 CONFIG_COMPACTION=y
@@ -257,7 +257,6 @@ CONFIG_IIO=y
 # CONFIG_IIO_BUFFER is not set
 # CONFIG_IIO_TRIGGER is not set
 CONFIG_INITRAMFS_COMPRESSION=""
-# CONFIG_INITRAMFS_FORCE is not set
 CONFIG_INITRAMFS_ROOT_GID=1000
 CONFIG_INITRAMFS_ROOT_UID=1000
 CONFIG_INITRAMFS_SOURCE="/openwrt/trunk/build_dir/target-arm_cortex-a7_musl-1.1.14_eabi/root-mediatek /openwrt/trunk/target/linux/generic/image/initramfs-base-files.txt"
@@ -276,11 +275,11 @@ CONFIG_LIBFDT=y
 CONFIG_LOCK_SPIN_ON_OWNER=y
 CONFIG_LZO_COMPRESS=y
 CONFIG_LZO_DECOMPRESS=y
-CONFIG_MACH_MT2701=y
+# CONFIG_MACH_MT2701 is not set
 # CONFIG_MACH_MT6589 is not set
 # CONFIG_MACH_MT6592 is not set
 CONFIG_MACH_MT7623=y
-CONFIG_MACH_MT8127=y
+# CONFIG_MACH_MT8127 is not set
 # CONFIG_MACH_MT8135 is not set
 CONFIG_MAGIC_SYSRQ=y
 CONFIG_MDIO_BITBANG=y
@@ -311,6 +310,8 @@ CONFIG_MTD_NAND=y
 CONFIG_MTD_NAND_ECC=y
 CONFIG_MTD_NAND_MTK=y
 CONFIG_MTD_SPI_NOR=y
+CONFIG_MTD_SPLIT_FIRMWARE=y
+CONFIG_MTD_SPLIT_UIMAGE_FW=y
 CONFIG_MTD_UBI=y
 CONFIG_MTD_UBI_BEB_LIMIT=20
 CONFIG_MTD_UBI_BLOCK=y
@@ -318,6 +319,7 @@ CONFIG_MTD_UBI_BLOCK=y
 # CONFIG_MTD_UBI_GLUEBI is not set
 CONFIG_MTD_UBI_WL_THRESHOLD=4096
 CONFIG_MTK_EFUSE=y
+# CONFIG_MTK_HSDMA is not set
 CONFIG_MTK_INFRACFG=y
 # CONFIG_MTK_IOMMU is not set
 # CONFIG_MTK_IOMMU_V1 is not set
@@ -377,7 +379,6 @@ CONFIG_PHY_MTK_TPHY=y
 CONFIG_PINCTRL=y
 CONFIG_PINCTRL_MT2701=y
 CONFIG_PINCTRL_MT6397=y
-CONFIG_PINCTRL_MT8127=y
 CONFIG_PINCTRL_MTK=y
 CONFIG_PM=y
 CONFIG_PM_CLK=y
@@ -422,6 +423,7 @@ CONFIG_RPS=y
 CONFIG_RTC_CLASS=y
 # CONFIG_RTC_DRV_CMOS is not set
 # CONFIG_RTC_DRV_MT6397 is not set
+# CONFIG_RTC_DRV_MT7622 is not set
 CONFIG_RTC_I2C_AND_SPI=y
 CONFIG_RWSEM_SPIN_ON_OWNER=y
 CONFIG_RWSEM_XCHGADD_ALGORITHM=y
@@ -470,7 +472,6 @@ CONFIG_UNINLINE_SPIN_UNLOCK=y
 CONFIG_USB=y
 CONFIG_USB_COMMON=y
 # CONFIG_USB_EHCI_HCD is not set
-# CONFIG_USB_MTU3 is not set
 CONFIG_USB_SUPPORT=y
 CONFIG_USB_XHCI_HCD=y
 CONFIG_USB_XHCI_MTK=y
diff --git a/target/linux/mediatek/32/profiles/default.mk b/target/linux/mediatek/mt7623/profiles/default.mk
similarity index 100%
rename from target/linux/mediatek/32/profiles/default.mk
rename to target/linux/mediatek/mt7623/profiles/default.mk
diff --git a/target/linux/mediatek/mt7623/target.mk b/target/linux/mediatek/mt7623/target.mk
new file mode 100644
index 0000000000..9f995f9951
--- /dev/null
+++ b/target/linux/mediatek/mt7623/target.mk
@@ -0,0 +1,16 @@
+#
+# Copyright (C) 2009 OpenWrt.org
+#
+
+ARCH:=arm
+SUBTARGET:=mt7623
+BOARDNAME:=MT7623
+CPU_TYPE:=cortex-a7
+CPU_SUBTYPE:=neon-vfpv4
+
+KERNELNAME:=Image dtbs zImage
+
+define Target/Description
+	Build firmware images for MediaTek mt7623 ARM based boards.
+endef
+
diff --git a/target/linux/mediatek/patches-4.14/0101-reset-mediatek-add-reset-controller-dt-bindings-requ.patch b/target/linux/mediatek/patches-4.14/0101-reset-mediatek-add-reset-controller-dt-bindings-requ.patch
new file mode 100644
index 0000000000..64f3107162
--- /dev/null
+++ b/target/linux/mediatek/patches-4.14/0101-reset-mediatek-add-reset-controller-dt-bindings-requ.patch
@@ -0,0 +1,120 @@
+From 5d6a82632eb7258c8ca49cc96c18b8b4071b6639 Mon Sep 17 00:00:00 2001
+From: Sean Wang <sean.wang@mediatek.com>
+Date: Wed, 20 Sep 2017 17:40:16 +0800
+Subject: [PATCH 101/224] reset: mediatek: add reset controller dt-bindings
+ required header for MT7622 SoC
+
+Add the reset controller dt-bindings exported from infracfg, pericfg,
+hifsys and ethsys which could be found on MT7622 SoC. So that we can
+reference them from within a device-tree file.
+
+Signed-off-by: Sean Wang <sean.wang@mediatek.com>
+Signed-off-by: Philipp Zabel <p.zabel@pengutronix.de>
+---
+ include/dt-bindings/reset/mt7622-reset.h | 94 ++++++++++++++++++++++++++++++++
+ 1 file changed, 94 insertions(+)
+ create mode 100644 include/dt-bindings/reset/mt7622-reset.h
+
+diff --git a/include/dt-bindings/reset/mt7622-reset.h b/include/dt-bindings/reset/mt7622-reset.h
+new file mode 100644
+index 000000000000..234052f80417
+--- /dev/null
++++ b/include/dt-bindings/reset/mt7622-reset.h
+@@ -0,0 +1,94 @@
++/*
++ * Copyright (c) 2017 MediaTek Inc.
++ * Author: Sean Wang <sean.wang@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 _DT_BINDINGS_RESET_CONTROLLER_MT7622
++#define _DT_BINDINGS_RESET_CONTROLLER_MT7622
++
++/* INFRACFG resets */
++#define MT7622_INFRA_EMI_REG_RST		0
++#define MT7622_INFRA_DRAMC0_A0_RST		1
++#define MT7622_INFRA_APCIRQ_EINT_RST		3
++#define MT7622_INFRA_APXGPT_RST			4
++#define MT7622_INFRA_SCPSYS_RST			5
++#define MT7622_INFRA_PMIC_WRAP_RST		7
++#define MT7622_INFRA_IRRX_RST			9
++#define MT7622_INFRA_EMI_RST			16
++#define MT7622_INFRA_WED0_RST			17
++#define MT7622_INFRA_DRAMC_RST			18
++#define MT7622_INFRA_CCI_INTF_RST		19
++#define MT7622_INFRA_TRNG_RST			21
++#define MT7622_INFRA_SYSIRQ_RST			22
++#define MT7622_INFRA_WED1_RST			25
++
++/* PERICFG Subsystem resets */
++#define MT7622_PERI_UART0_SW_RST		0
++#define MT7622_PERI_UART1_SW_RST		1
++#define MT7622_PERI_UART2_SW_RST		2
++#define MT7622_PERI_UART3_SW_RST		3
++#define MT7622_PERI_UART4_SW_RST		4
++#define MT7622_PERI_BTIF_SW_RST			6
++#define MT7622_PERI_PWM_SW_RST			8
++#define MT7622_PERI_AUXADC_SW_RST		10
++#define MT7622_PERI_DMA_SW_RST			11
++#define MT7622_PERI_IRTX_SW_RST			13
++#define MT7622_PERI_NFI_SW_RST			14
++#define MT7622_PERI_THERM_SW_RST		16
++#define MT7622_PERI_MSDC0_SW_RST		19
++#define MT7622_PERI_MSDC1_SW_RST		20
++#define MT7622_PERI_I2C0_SW_RST			22
++#define MT7622_PERI_I2C1_SW_RST			23
++#define MT7622_PERI_I2C2_SW_RST			24
++#define MT7622_PERI_SPI0_SW_RST			33
++#define MT7622_PERI_SPI1_SW_RST			34
++#define MT7622_PERI_FLASHIF_SW_RST		36
++
++/* TOPRGU resets */
++#define MT7622_TOPRGU_INFRA_RST			0
++#define MT7622_TOPRGU_ETHDMA_RST		1
++#define MT7622_TOPRGU_DDRPHY_RST		6
++#define MT7622_TOPRGU_INFRA_AO_RST		8
++#define MT7622_TOPRGU_CONN_RST			9
++#define MT7622_TOPRGU_APMIXED_RST		10
++#define MT7622_TOPRGU_CONN_MCU_RST		12
++
++/* PCIe/SATA Subsystem resets */
++#define MT7622_SATA_PHY_REG_RST			12
++#define MT7622_SATA_PHY_SW_RST			13
++#define MT7622_SATA_AXI_BUS_RST			15
++#define MT7622_PCIE1_CORE_RST			19
++#define MT7622_PCIE1_MMIO_RST			20
++#define MT7622_PCIE1_HRST			21
++#define MT7622_PCIE1_USER_RST			22
++#define MT7622_PCIE1_PIPE_RST			23
++#define MT7622_PCIE0_CORE_RST			27
++#define MT7622_PCIE0_MMIO_RST			28
++#define MT7622_PCIE0_HRST			29
++#define MT7622_PCIE0_USER_RST			30
++#define MT7622_PCIE0_PIPE_RST			31
++
++/* SSUSB Subsystem resets */
++#define MT7622_SSUSB_PHY_PWR_RST		3
++#define MT7622_SSUSB_MAC_PWR_RST		4
++
++/* ETHSYS Subsystem resets */
++#define MT7622_ETHSYS_SYS_RST			0
++#define MT7622_ETHSYS_MCM_RST			2
++#define MT7622_ETHSYS_HSDMA_RST			5
++#define MT7622_ETHSYS_FE_RST			6
++#define MT7622_ETHSYS_GMAC_RST			23
++#define MT7622_ETHSYS_EPHY_RST			24
++#define MT7622_ETHSYS_CRYPTO_RST		29
++#define MT7622_ETHSYS_PPE_RST			31
++
++#endif  /* _DT_BINDINGS_RESET_CONTROLLER_MT7622 */
+-- 
+2.11.0
+
diff --git a/target/linux/mediatek/patches-4.14/0102-soc-mediatek-pwrap-fixup-warnings-from-coding-style.patch b/target/linux/mediatek/patches-4.14/0102-soc-mediatek-pwrap-fixup-warnings-from-coding-style.patch
new file mode 100644
index 0000000000..408de3af9f
--- /dev/null
+++ b/target/linux/mediatek/patches-4.14/0102-soc-mediatek-pwrap-fixup-warnings-from-coding-style.patch
@@ -0,0 +1,76 @@
+From c7cb4b7e750fc9a23cd80ef34ad4ef8a47f895d5 Mon Sep 17 00:00:00 2001
+From: Sean Wang <sean.wang@mediatek.com>
+Date: Thu, 21 Sep 2017 16:26:57 +0800
+Subject: [PATCH 102/224] soc: mediatek: pwrap: fixup warnings from coding
+ style
+
+fixup those warnings such as lines over 80 words and parenthesis
+alignment which would be complained by checkpatch.pl.
+
+Signed-off-by: Sean Wang <sean.wang@mediatek.com>
+Signed-off-by: Matthias Brugger <matthias.bgg@gmail.com>
+---
+ drivers/soc/mediatek/mtk-pmic-wrap.c | 20 +++++++++++++-------
+ 1 file changed, 13 insertions(+), 7 deletions(-)
+
+diff --git a/drivers/soc/mediatek/mtk-pmic-wrap.c b/drivers/soc/mediatek/mtk-pmic-wrap.c
+index c2048382830f..f095faac1e04 100644
+--- a/drivers/soc/mediatek/mtk-pmic-wrap.c
++++ b/drivers/soc/mediatek/mtk-pmic-wrap.c
+@@ -827,7 +827,8 @@ static int pwrap_init_cipher(struct pmic_wrapper *wrp)
+ 	/* wait for cipher data ready@PMIC */
+ 	ret = pwrap_wait_for_state(wrp, pwrap_is_pmic_cipher_ready);
+ 	if (ret) {
+-		dev_err(wrp->dev, "timeout waiting for cipher data ready@PMIC\n");
++		dev_err(wrp->dev,
++			"timeout waiting for cipher data ready@PMIC\n");
+ 		return ret;
+ 	}
+ 
+@@ -1159,23 +1160,27 @@ static int pwrap_probe(struct platform_device *pdev)
+ 		if (IS_ERR(wrp->bridge_base))
+ 			return PTR_ERR(wrp->bridge_base);
+ 
+-		wrp->rstc_bridge = devm_reset_control_get(wrp->dev, "pwrap-bridge");
++		wrp->rstc_bridge = devm_reset_control_get(wrp->dev,
++							  "pwrap-bridge");
+ 		if (IS_ERR(wrp->rstc_bridge)) {
+ 			ret = PTR_ERR(wrp->rstc_bridge);
+-			dev_dbg(wrp->dev, "cannot get pwrap-bridge reset: %d\n", ret);
++			dev_dbg(wrp->dev,
++				"cannot get pwrap-bridge reset: %d\n", ret);
+ 			return ret;
+ 		}
+ 	}
+ 
+ 	wrp->clk_spi = devm_clk_get(wrp->dev, "spi");
+ 	if (IS_ERR(wrp->clk_spi)) {
+-		dev_dbg(wrp->dev, "failed to get clock: %ld\n", PTR_ERR(wrp->clk_spi));
++		dev_dbg(wrp->dev, "failed to get clock: %ld\n",
++			PTR_ERR(wrp->clk_spi));
+ 		return PTR_ERR(wrp->clk_spi);
+ 	}
+ 
+ 	wrp->clk_wrap = devm_clk_get(wrp->dev, "wrap");
+ 	if (IS_ERR(wrp->clk_wrap)) {
+-		dev_dbg(wrp->dev, "failed to get clock: %ld\n", PTR_ERR(wrp->clk_wrap));
++		dev_dbg(wrp->dev, "failed to get clock: %ld\n",
++			PTR_ERR(wrp->clk_wrap));
+ 		return PTR_ERR(wrp->clk_wrap);
+ 	}
+ 
+@@ -1220,8 +1225,9 @@ static int pwrap_probe(struct platform_device *pdev)
+ 	pwrap_writel(wrp, wrp->master->int_en_all, PWRAP_INT_EN);
+ 
+ 	irq = platform_get_irq(pdev, 0);
+-	ret = devm_request_irq(wrp->dev, irq, pwrap_interrupt, IRQF_TRIGGER_HIGH,
+-			"mt-pmic-pwrap", wrp);
++	ret = devm_request_irq(wrp->dev, irq, pwrap_interrupt,
++			       IRQF_TRIGGER_HIGH,
++			       "mt-pmic-pwrap", wrp);
+ 	if (ret)
+ 		goto err_out2;
+ 
+-- 
+2.11.0
+
diff --git a/target/linux/mediatek/patches-4.14/0104-usb-mtu3-support-option-to-disable-usb3-ports.patch b/target/linux/mediatek/patches-4.14/0104-usb-mtu3-support-option-to-disable-usb3-ports.patch
new file mode 100644
index 0000000000..51b5bcffc5
--- /dev/null
+++ b/target/linux/mediatek/patches-4.14/0104-usb-mtu3-support-option-to-disable-usb3-ports.patch
@@ -0,0 +1,117 @@
+From 7a46c3488c48a0fbe313ed25c12af3fb3af48a01 Mon Sep 17 00:00:00 2001
+From: Chunfeng Yun <chunfeng.yun@mediatek.com>
+Date: Fri, 13 Oct 2017 17:10:38 +0800
+Subject: [PATCH 104/224] usb: mtu3: support option to disable usb3 ports
+
+Add support to disable specific usb3 ports, it's useful when
+usb3 phy is shared with PCIe or SATA, because we should disable
+the corresponding usb3 port if the phy is used by PCIe or SATA.
+
+Signed-off-by: Chunfeng Yun <chunfeng.yun@mediatek.com>
+Signed-off-by: Felipe Balbi <felipe.balbi@linux.intel.com>
+---
+ drivers/usb/mtu3/mtu3.h      |  3 +++
+ drivers/usb/mtu3/mtu3_host.c | 16 +++++++++++++---
+ drivers/usb/mtu3/mtu3_plat.c |  8 ++++++--
+ 3 files changed, 22 insertions(+), 5 deletions(-)
+
+diff --git a/drivers/usb/mtu3/mtu3.h b/drivers/usb/mtu3/mtu3.h
+index b26fffc58446..112723d6e7bc 100644
+--- a/drivers/usb/mtu3/mtu3.h
++++ b/drivers/usb/mtu3/mtu3.h
+@@ -210,6 +210,8 @@ struct otg_switch_mtk {
+  *		host only, device only or dual-role mode
+  * @u2_ports: number of usb2.0 host ports
+  * @u3_ports: number of usb3.0 host ports
++ * @u3p_dis_msk: mask of disabling usb3 ports, for example, bit0==1 to
++ *		disable u3port0, bit1==1 to disable u3port1,... etc
+  * @dbgfs_root: only used when supports manual dual-role switch via debugfs
+  * @wakeup_en: it's true when supports remote wakeup in host mode
+  * @wk_deb_p0: port0's wakeup debounce clock
+@@ -232,6 +234,7 @@ struct ssusb_mtk {
+ 	bool is_host;
+ 	int u2_ports;
+ 	int u3_ports;
++	int u3p_dis_msk;
+ 	struct dentry *dbgfs_root;
+ 	/* usb wakeup for host mode */
+ 	bool wakeup_en;
+diff --git a/drivers/usb/mtu3/mtu3_host.c b/drivers/usb/mtu3/mtu3_host.c
+index e42d308b8dc2..4dd9508a60b5 100644
+--- a/drivers/usb/mtu3/mtu3_host.c
++++ b/drivers/usb/mtu3/mtu3_host.c
+@@ -151,6 +151,7 @@ int ssusb_host_enable(struct ssusb_mtk *ssusb)
+ 	void __iomem *ibase = ssusb->ippc_base;
+ 	int num_u3p = ssusb->u3_ports;
+ 	int num_u2p = ssusb->u2_ports;
++	int u3_ports_disabed;
+ 	u32 check_clk;
+ 	u32 value;
+ 	int i;
+@@ -158,8 +159,14 @@ int ssusb_host_enable(struct ssusb_mtk *ssusb)
+ 	/* power on host ip */
+ 	mtu3_clrbits(ibase, U3D_SSUSB_IP_PW_CTRL1, SSUSB_IP_HOST_PDN);
+ 
+-	/* power on and enable all u3 ports */
++	/* power on and enable u3 ports except skipped ones */
++	u3_ports_disabed = 0;
+ 	for (i = 0; i < num_u3p; i++) {
++		if ((0x1 << i) & ssusb->u3p_dis_msk) {
++			u3_ports_disabed++;
++			continue;
++		}
++
+ 		value = mtu3_readl(ibase, SSUSB_U3_CTRL(i));
+ 		value &= ~(SSUSB_U3_PORT_PDN | SSUSB_U3_PORT_DIS);
+ 		value |= SSUSB_U3_PORT_HOST_SEL;
+@@ -175,7 +182,7 @@ int ssusb_host_enable(struct ssusb_mtk *ssusb)
+ 	}
+ 
+ 	check_clk = SSUSB_XHCI_RST_B_STS;
+-	if (num_u3p)
++	if (num_u3p > u3_ports_disabed)
+ 		check_clk = SSUSB_U3_MAC_RST_B_STS;
+ 
+ 	return ssusb_check_clocks(ssusb, check_clk);
+@@ -190,8 +197,11 @@ int ssusb_host_disable(struct ssusb_mtk *ssusb, bool suspend)
+ 	int ret;
+ 	int i;
+ 
+-	/* power down and disable all u3 ports */
++	/* power down and disable u3 ports except skipped ones */
+ 	for (i = 0; i < num_u3p; i++) {
++		if ((0x1 << i) & ssusb->u3p_dis_msk)
++			continue;
++
+ 		value = mtu3_readl(ibase, SSUSB_U3_CTRL(i));
+ 		value |= SSUSB_U3_PORT_PDN;
+ 		value |= suspend ? 0 : SSUSB_U3_PORT_DIS;
+diff --git a/drivers/usb/mtu3/mtu3_plat.c b/drivers/usb/mtu3/mtu3_plat.c
+index 088e3e685c4f..9edad30c8ae5 100644
+--- a/drivers/usb/mtu3/mtu3_plat.c
++++ b/drivers/usb/mtu3/mtu3_plat.c
+@@ -276,6 +276,10 @@ static int get_ssusb_rscs(struct platform_device *pdev, struct ssusb_mtk *ssusb)
+ 	if (ret)
+ 		return ret;
+ 
++	/* optional property, ignore the error if it does not exist */
++	of_property_read_u32(node, "mediatek,u3p-dis-msk",
++			     &ssusb->u3p_dis_msk);
++
+ 	if (ssusb->dr_mode != USB_DR_MODE_OTG)
+ 		return 0;
+ 
+@@ -304,8 +308,8 @@ static int get_ssusb_rscs(struct platform_device *pdev, struct ssusb_mtk *ssusb)
+ 		}
+ 	}
+ 
+-	dev_info(dev, "dr_mode: %d, is_u3_dr: %d\n",
+-		ssusb->dr_mode, otg_sx->is_u3_drd);
++	dev_info(dev, "dr_mode: %d, is_u3_dr: %d, u3p_dis_msk:%x\n",
++		ssusb->dr_mode, otg_sx->is_u3_drd, ssusb->u3p_dis_msk);
+ 
+ 	return 0;
+ }
+-- 
+2.11.0
+
diff --git a/target/linux/mediatek/patches-4.14/0105-usb-mtu3-remove-dummy-wakeup-debounce-clocks.patch b/target/linux/mediatek/patches-4.14/0105-usb-mtu3-remove-dummy-wakeup-debounce-clocks.patch
new file mode 100644
index 0000000000..adf1cec90b
--- /dev/null
+++ b/target/linux/mediatek/patches-4.14/0105-usb-mtu3-remove-dummy-wakeup-debounce-clocks.patch
@@ -0,0 +1,126 @@
+From 50005796f146351dc9c34bbf8898b305c562e964 Mon Sep 17 00:00:00 2001
+From: Chunfeng Yun <chunfeng.yun@mediatek.com>
+Date: Fri, 13 Oct 2017 17:10:39 +0800
+Subject: [PATCH 105/224] usb: mtu3: remove dummy wakeup debounce clocks
+
+The wakeup debounce clocks for each ports in fact are not
+needed, so remove them.
+
+Signed-off-by: Chunfeng Yun <chunfeng.yun@mediatek.com>
+Signed-off-by: Felipe Balbi <felipe.balbi@linux.intel.com>
+---
+ drivers/usb/mtu3/mtu3.h      |  4 ----
+ drivers/usb/mtu3/mtu3_host.c | 57 ++++----------------------------------------
+ 2 files changed, 4 insertions(+), 57 deletions(-)
+
+diff --git a/drivers/usb/mtu3/mtu3.h b/drivers/usb/mtu3/mtu3.h
+index 112723d6e7bc..6d3278e46431 100644
+--- a/drivers/usb/mtu3/mtu3.h
++++ b/drivers/usb/mtu3/mtu3.h
+@@ -214,8 +214,6 @@ struct otg_switch_mtk {
+  *		disable u3port0, bit1==1 to disable u3port1,... etc
+  * @dbgfs_root: only used when supports manual dual-role switch via debugfs
+  * @wakeup_en: it's true when supports remote wakeup in host mode
+- * @wk_deb_p0: port0's wakeup debounce clock
+- * @wk_deb_p1: it's optional, and depends on port1 is supported or not
+  */
+ struct ssusb_mtk {
+ 	struct device *dev;
+@@ -238,8 +236,6 @@ struct ssusb_mtk {
+ 	struct dentry *dbgfs_root;
+ 	/* usb wakeup for host mode */
+ 	bool wakeup_en;
+-	struct clk *wk_deb_p0;
+-	struct clk *wk_deb_p1;
+ 	struct regmap *pericfg;
+ };
+ 
+diff --git a/drivers/usb/mtu3/mtu3_host.c b/drivers/usb/mtu3/mtu3_host.c
+index 4dd9508a60b5..edcc59148171 100644
+--- a/drivers/usb/mtu3/mtu3_host.c
++++ b/drivers/usb/mtu3/mtu3_host.c
+@@ -79,20 +79,6 @@ int ssusb_wakeup_of_property_parse(struct ssusb_mtk *ssusb,
+ 	if (!ssusb->wakeup_en)
+ 		return 0;
+ 
+-	ssusb->wk_deb_p0 = devm_clk_get(dev, "wakeup_deb_p0");
+-	if (IS_ERR(ssusb->wk_deb_p0)) {
+-		dev_err(dev, "fail to get wakeup_deb_p0\n");
+-		return PTR_ERR(ssusb->wk_deb_p0);
+-	}
+-
+-	if (of_property_read_bool(dn, "wakeup_deb_p1")) {
+-		ssusb->wk_deb_p1 = devm_clk_get(dev, "wakeup_deb_p1");
+-		if (IS_ERR(ssusb->wk_deb_p1)) {
+-			dev_err(dev, "fail to get wakeup_deb_p1\n");
+-			return PTR_ERR(ssusb->wk_deb_p1);
+-		}
+-	}
+-
+ 	ssusb->pericfg = syscon_regmap_lookup_by_phandle(dn,
+ 						"mediatek,syscon-wakeup");
+ 	if (IS_ERR(ssusb->pericfg)) {
+@@ -103,36 +89,6 @@ int ssusb_wakeup_of_property_parse(struct ssusb_mtk *ssusb,
+ 	return 0;
+ }
+ 
+-static int ssusb_wakeup_clks_enable(struct ssusb_mtk *ssusb)
+-{
+-	int ret;
+-
+-	ret = clk_prepare_enable(ssusb->wk_deb_p0);
+-	if (ret) {
+-		dev_err(ssusb->dev, "failed to enable wk_deb_p0\n");
+-		goto usb_p0_err;
+-	}
+-
+-	ret = clk_prepare_enable(ssusb->wk_deb_p1);
+-	if (ret) {
+-		dev_err(ssusb->dev, "failed to enable wk_deb_p1\n");
+-		goto usb_p1_err;
+-	}
+-
+-	return 0;
+-
+-usb_p1_err:
+-	clk_disable_unprepare(ssusb->wk_deb_p0);
+-usb_p0_err:
+-	return -EINVAL;
+-}
+-
+-static void ssusb_wakeup_clks_disable(struct ssusb_mtk *ssusb)
+-{
+-	clk_disable_unprepare(ssusb->wk_deb_p1);
+-	clk_disable_unprepare(ssusb->wk_deb_p0);
+-}
+-
+ static void host_ports_num_get(struct ssusb_mtk *ssusb)
+ {
+ 	u32 xhci_cap;
+@@ -286,19 +242,14 @@ void ssusb_host_exit(struct ssusb_mtk *ssusb)
+ 
+ int ssusb_wakeup_enable(struct ssusb_mtk *ssusb)
+ {
+-	int ret = 0;
+-
+-	if (ssusb->wakeup_en) {
+-		ret = ssusb_wakeup_clks_enable(ssusb);
++	if (ssusb->wakeup_en)
+ 		ssusb_wakeup_ip_sleep_en(ssusb);
+-	}
+-	return ret;
++
++	return 0;
+ }
+ 
+ void ssusb_wakeup_disable(struct ssusb_mtk *ssusb)
+ {
+-	if (ssusb->wakeup_en) {
++	if (ssusb->wakeup_en)
+ 		ssusb_wakeup_ip_sleep_dis(ssusb);
+-		ssusb_wakeup_clks_disable(ssusb);
+-	}
+ }
+-- 
+2.11.0
+
diff --git a/target/linux/mediatek/patches-4.14/0106-usb-mtu3-add-optional-mcu-and-dma-bus-clocks.patch b/target/linux/mediatek/patches-4.14/0106-usb-mtu3-add-optional-mcu-and-dma-bus-clocks.patch
new file mode 100644
index 0000000000..93a8c65294
--- /dev/null
+++ b/target/linux/mediatek/patches-4.14/0106-usb-mtu3-add-optional-mcu-and-dma-bus-clocks.patch
@@ -0,0 +1,233 @@
+From 677805f6d83524717b46b3cde74aa455dbf6299f Mon Sep 17 00:00:00 2001
+From: Chunfeng Yun <chunfeng.yun@mediatek.com>
+Date: Fri, 13 Oct 2017 17:10:40 +0800
+Subject: [PATCH 106/224] usb: mtu3: add optional mcu and dma bus clocks
+
+There are mcu_bus and dma_bus clocks needed to be turned on/off by
+driver on some SoCs, so add them as optional ones
+
+Signed-off-by: Chunfeng Yun <chunfeng.yun@mediatek.com>
+Signed-off-by: Felipe Balbi <felipe.balbi@linux.intel.com>
+---
+ drivers/usb/mtu3/mtu3.h      |   5 ++
+ drivers/usb/mtu3/mtu3_plat.c | 121 +++++++++++++++++++++++++++++--------------
+ 2 files changed, 86 insertions(+), 40 deletions(-)
+
+diff --git a/drivers/usb/mtu3/mtu3.h b/drivers/usb/mtu3/mtu3.h
+index 6d3278e46431..2795294ec92a 100644
+--- a/drivers/usb/mtu3/mtu3.h
++++ b/drivers/usb/mtu3/mtu3.h
+@@ -206,6 +206,9 @@ struct otg_switch_mtk {
+  * @ippc_base: register base address of IP Power and Clock interface (IPPC)
+  * @vusb33: usb3.3V shared by device/host IP
+  * @sys_clk: system clock of mtu3, shared by device/host IP
++ * @ref_clk: reference clock
++ * @mcu_clk: mcu_bus_ck clock for AHB bus etc
++ * @dma_clk: dma_bus_ck clock for AXI bus etc
+  * @dr_mode: works in which mode:
+  *		host only, device only or dual-role mode
+  * @u2_ports: number of usb2.0 host ports
+@@ -226,6 +229,8 @@ struct ssusb_mtk {
+ 	struct regulator *vusb33;
+ 	struct clk *sys_clk;
+ 	struct clk *ref_clk;
++	struct clk *mcu_clk;
++	struct clk *dma_clk;
+ 	/* otg */
+ 	struct otg_switch_mtk otg_switch;
+ 	enum usb_dr_mode dr_mode;
+diff --git a/drivers/usb/mtu3/mtu3_plat.c b/drivers/usb/mtu3/mtu3_plat.c
+index 9edad30c8ae5..fb8992011bde 100644
+--- a/drivers/usb/mtu3/mtu3_plat.c
++++ b/drivers/usb/mtu3/mtu3_plat.c
+@@ -110,15 +110,9 @@ static void ssusb_phy_power_off(struct ssusb_mtk *ssusb)
+ 		phy_power_off(ssusb->phys[i]);
+ }
+ 
+-static int ssusb_rscs_init(struct ssusb_mtk *ssusb)
++static int ssusb_clks_enable(struct ssusb_mtk *ssusb)
+ {
+-	int ret = 0;
+-
+-	ret = regulator_enable(ssusb->vusb33);
+-	if (ret) {
+-		dev_err(ssusb->dev, "failed to enable vusb33\n");
+-		goto vusb33_err;
+-	}
++	int ret;
+ 
+ 	ret = clk_prepare_enable(ssusb->sys_clk);
+ 	if (ret) {
+@@ -132,6 +126,52 @@ static int ssusb_rscs_init(struct ssusb_mtk *ssusb)
+ 		goto ref_clk_err;
+ 	}
+ 
++	ret = clk_prepare_enable(ssusb->mcu_clk);
++	if (ret) {
++		dev_err(ssusb->dev, "failed to enable mcu_clk\n");
++		goto mcu_clk_err;
++	}
++
++	ret = clk_prepare_enable(ssusb->dma_clk);
++	if (ret) {
++		dev_err(ssusb->dev, "failed to enable dma_clk\n");
++		goto dma_clk_err;
++	}
++
++	return 0;
++
++dma_clk_err:
++	clk_disable_unprepare(ssusb->mcu_clk);
++mcu_clk_err:
++	clk_disable_unprepare(ssusb->ref_clk);
++ref_clk_err:
++	clk_disable_unprepare(ssusb->sys_clk);
++sys_clk_err:
++	return ret;
++}
++
++static void ssusb_clks_disable(struct ssusb_mtk *ssusb)
++{
++	clk_disable_unprepare(ssusb->dma_clk);
++	clk_disable_unprepare(ssusb->mcu_clk);
++	clk_disable_unprepare(ssusb->ref_clk);
++	clk_disable_unprepare(ssusb->sys_clk);
++}
++
++static int ssusb_rscs_init(struct ssusb_mtk *ssusb)
++{
++	int ret = 0;
++
++	ret = regulator_enable(ssusb->vusb33);
++	if (ret) {
++		dev_err(ssusb->dev, "failed to enable vusb33\n");
++		goto vusb33_err;
++	}
++
++	ret = ssusb_clks_enable(ssusb);
++	if (ret)
++		goto clks_err;
++
+ 	ret = ssusb_phy_init(ssusb);
+ 	if (ret) {
+ 		dev_err(ssusb->dev, "failed to init phy\n");
+@@ -149,20 +189,16 @@ static int ssusb_rscs_init(struct ssusb_mtk *ssusb)
+ phy_err:
+ 	ssusb_phy_exit(ssusb);
+ phy_init_err:
+-	clk_disable_unprepare(ssusb->ref_clk);
+-ref_clk_err:
+-	clk_disable_unprepare(ssusb->sys_clk);
+-sys_clk_err:
++	ssusb_clks_disable(ssusb);
++clks_err:
+ 	regulator_disable(ssusb->vusb33);
+ vusb33_err:
+-
+ 	return ret;
+ }
+ 
+ static void ssusb_rscs_exit(struct ssusb_mtk *ssusb)
+ {
+-	clk_disable_unprepare(ssusb->sys_clk);
+-	clk_disable_unprepare(ssusb->ref_clk);
++	ssusb_clks_disable(ssusb);
+ 	regulator_disable(ssusb->vusb33);
+ 	ssusb_phy_power_off(ssusb);
+ 	ssusb_phy_exit(ssusb);
+@@ -203,6 +239,19 @@ static int get_iddig_pinctrl(struct ssusb_mtk *ssusb)
+ 	return 0;
+ }
+ 
++/* ignore the error if the clock does not exist */
++static struct clk *get_optional_clk(struct device *dev, const char *id)
++{
++	struct clk *opt_clk;
++
++	opt_clk = devm_clk_get(dev, id);
++	/* ignore error number except EPROBE_DEFER */
++	if (IS_ERR(opt_clk) && (PTR_ERR(opt_clk) != -EPROBE_DEFER))
++		opt_clk = NULL;
++
++	return opt_clk;
++}
++
+ static int get_ssusb_rscs(struct platform_device *pdev, struct ssusb_mtk *ssusb)
+ {
+ 	struct device_node *node = pdev->dev.of_node;
+@@ -225,18 +274,17 @@ static int get_ssusb_rscs(struct platform_device *pdev, struct ssusb_mtk *ssusb)
+ 		return PTR_ERR(ssusb->sys_clk);
+ 	}
+ 
+-	/*
+-	 * reference clock is usually a "fixed-clock", make it optional
+-	 * for backward compatibility and ignore the error if it does
+-	 * not exist.
+-	 */
+-	ssusb->ref_clk = devm_clk_get(dev, "ref_ck");
+-	if (IS_ERR(ssusb->ref_clk)) {
+-		if (PTR_ERR(ssusb->ref_clk) == -EPROBE_DEFER)
+-			return -EPROBE_DEFER;
++	ssusb->ref_clk = get_optional_clk(dev, "ref_ck");
++	if (IS_ERR(ssusb->ref_clk))
++		return PTR_ERR(ssusb->ref_clk);
+ 
+-		ssusb->ref_clk = NULL;
+-	}
++	ssusb->mcu_clk = get_optional_clk(dev, "mcu_ck");
++	if (IS_ERR(ssusb->mcu_clk))
++		return PTR_ERR(ssusb->mcu_clk);
++
++	ssusb->dma_clk = get_optional_clk(dev, "dma_ck");
++	if (IS_ERR(ssusb->dma_clk))
++		return PTR_ERR(ssusb->dma_clk);
+ 
+ 	ssusb->num_phys = of_count_phandle_with_args(node,
+ 			"phys", "#phy-cells");
+@@ -451,8 +499,7 @@ static int __maybe_unused mtu3_suspend(struct device *dev)
+ 
+ 	ssusb_host_disable(ssusb, true);
+ 	ssusb_phy_power_off(ssusb);
+-	clk_disable_unprepare(ssusb->sys_clk);
+-	clk_disable_unprepare(ssusb->ref_clk);
++	ssusb_clks_disable(ssusb);
+ 	ssusb_wakeup_enable(ssusb);
+ 
+ 	return 0;
+@@ -470,27 +517,21 @@ static int __maybe_unused mtu3_resume(struct device *dev)
+ 		return 0;
+ 
+ 	ssusb_wakeup_disable(ssusb);
+-	ret = clk_prepare_enable(ssusb->sys_clk);
+-	if (ret)
+-		goto err_sys_clk;
+-
+-	ret = clk_prepare_enable(ssusb->ref_clk);
++	ret = ssusb_clks_enable(ssusb);
+ 	if (ret)
+-		goto err_ref_clk;
++		goto clks_err;
+ 
+ 	ret = ssusb_phy_power_on(ssusb);
+ 	if (ret)
+-		goto err_power_on;
++		goto phy_err;
+ 
+ 	ssusb_host_enable(ssusb);
+ 
+ 	return 0;
+ 
+-err_power_on:
+-	clk_disable_unprepare(ssusb->ref_clk);
+-err_ref_clk:
+-	clk_disable_unprepare(ssusb->sys_clk);
+-err_sys_clk:
++phy_err:
++	ssusb_clks_disable(ssusb);
++clks_err:
+ 	return ret;
+ }
+ 
+-- 
+2.11.0
+
diff --git a/target/linux/mediatek/patches-4.14/0107-usb-mtu3-support-36-bit-DMA-address.patch b/target/linux/mediatek/patches-4.14/0107-usb-mtu3-support-36-bit-DMA-address.patch
new file mode 100644
index 0000000000..652116d0da
--- /dev/null
+++ b/target/linux/mediatek/patches-4.14/0107-usb-mtu3-support-36-bit-DMA-address.patch
@@ -0,0 +1,373 @@
+From d366bf086a61b7a895d8819a3c1349b9c6b8e40f Mon Sep 17 00:00:00 2001
+From: Chunfeng Yun <chunfeng.yun@mediatek.com>
+Date: Fri, 13 Oct 2017 17:10:41 +0800
+Subject: [PATCH 107/224] usb: mtu3: support 36-bit DMA address
+
+add support for 36-bit DMA address
+
+[ Felipe Balbi: fix printk format for dma_addr_t ]
+
+Signed-off-by: Chunfeng Yun <chunfeng.yun@mediatek.com>
+Signed-off-by: Felipe Balbi <felipe.balbi@linux.intel.com>
+---
+ drivers/usb/mtu3/mtu3.h         |  17 ++++++-
+ drivers/usb/mtu3/mtu3_core.c    |  34 +++++++++++++-
+ drivers/usb/mtu3/mtu3_hw_regs.h |  10 ++++
+ drivers/usb/mtu3/mtu3_qmu.c     | 102 +++++++++++++++++++++++++++++++++-------
+ 4 files changed, 142 insertions(+), 21 deletions(-)
+
+diff --git a/drivers/usb/mtu3/mtu3.h b/drivers/usb/mtu3/mtu3.h
+index 2795294ec92a..ef2dc92a2109 100644
+--- a/drivers/usb/mtu3/mtu3.h
++++ b/drivers/usb/mtu3/mtu3.h
+@@ -46,6 +46,9 @@ struct mtu3_request;
+ #define	MU3D_EP_RXCR1(epnum)	(U3D_RX1CSR1 + (((epnum) - 1) * 0x10))
+ #define	MU3D_EP_RXCR2(epnum)	(U3D_RX1CSR2 + (((epnum) - 1) * 0x10))
+ 
++#define USB_QMU_TQHIAR(epnum)	(U3D_TXQHIAR1 + (((epnum) - 1) * 0x4))
++#define USB_QMU_RQHIAR(epnum)	(U3D_RXQHIAR1 + (((epnum) - 1) * 0x4))
++
+ #define USB_QMU_RQCSR(epnum)	(U3D_RXQCSR1 + (((epnum) - 1) * 0x10))
+ #define USB_QMU_RQSAR(epnum)	(U3D_RXQSAR1 + (((epnum) - 1) * 0x10))
+ #define USB_QMU_RQCPR(epnum)	(U3D_RXQCPR1 + (((epnum) - 1) * 0x10))
+@@ -138,23 +141,33 @@ struct mtu3_fifo_info {
+  *	Checksum value is calculated over the 16 bytes of the GPD by default;
+  * @data_buf_len (RX ONLY): This value indicates the length of
+  *	the assigned data buffer
++ * @tx_ext_addr (TX ONLY): [3:0] are 4 extension bits of @buffer,
++ *	[7:4] are 4 extension bits of @next_gpd
+  * @next_gpd: Physical address of the next GPD
+  * @buffer: Physical address of the data buffer
+  * @buf_len:
+  *	(TX): This value indicates the length of the assigned data buffer
+  *	(RX): The total length of data received
+  * @ext_len: reserved
++ * @rx_ext_addr(RX ONLY): [3:0] are 4 extension bits of @buffer,
++ *	[7:4] are 4 extension bits of @next_gpd
+  * @ext_flag:
+  *	bit5 (TX ONLY): Zero Length Packet (ZLP),
+  */
+ struct qmu_gpd {
+ 	__u8 flag;
+ 	__u8 chksum;
+-	__le16 data_buf_len;
++	union {
++		__le16 data_buf_len;
++		__le16 tx_ext_addr;
++	};
+ 	__le32 next_gpd;
+ 	__le32 buffer;
+ 	__le16 buf_len;
+-	__u8 ext_len;
++	union {
++		__u8 ext_len;
++		__u8 rx_ext_addr;
++	};
+ 	__u8 ext_flag;
+ } __packed;
+ 
+diff --git a/drivers/usb/mtu3/mtu3_core.c b/drivers/usb/mtu3/mtu3_core.c
+index 947579842ad7..cd4528f5f337 100644
+--- a/drivers/usb/mtu3/mtu3_core.c
++++ b/drivers/usb/mtu3/mtu3_core.c
+@@ -17,6 +17,7 @@
+  *
+  */
+ 
++#include <linux/dma-mapping.h>
+ #include <linux/kernel.h>
+ #include <linux/module.h>
+ #include <linux/of_address.h>
+@@ -759,7 +760,31 @@ static void mtu3_hw_exit(struct mtu3 *mtu)
+ 	mtu3_mem_free(mtu);
+ }
+ 
+-/*-------------------------------------------------------------------------*/
++/**
++ * we set 32-bit DMA mask by default, here check whether the controller
++ * supports 36-bit DMA or not, if it does, set 36-bit DMA mask.
++ */
++static int mtu3_set_dma_mask(struct mtu3 *mtu)
++{
++	struct device *dev = mtu->dev;
++	bool is_36bit = false;
++	int ret = 0;
++	u32 value;
++
++	value = mtu3_readl(mtu->mac_base, U3D_MISC_CTRL);
++	if (value & DMA_ADDR_36BIT) {
++		is_36bit = true;
++		ret = dma_set_mask_and_coherent(dev, DMA_BIT_MASK(36));
++		/* If set 36-bit DMA mask fails, fall back to 32-bit DMA mask */
++		if (ret) {
++			is_36bit = false;
++			ret = dma_set_mask_and_coherent(dev, DMA_BIT_MASK(32));
++		}
++	}
++	dev_info(dev, "dma mask: %s bits\n", is_36bit ? "36" : "32");
++
++	return ret;
++}
+ 
+ int ssusb_gadget_init(struct ssusb_mtk *ssusb)
+ {
+@@ -820,6 +845,12 @@ int ssusb_gadget_init(struct ssusb_mtk *ssusb)
+ 		return ret;
+ 	}
+ 
++	ret = mtu3_set_dma_mask(mtu);
++	if (ret) {
++		dev_err(dev, "mtu3 set dma_mask failed:%d\n", ret);
++		goto dma_mask_err;
++	}
++
+ 	ret = devm_request_irq(dev, mtu->irq, mtu3_irq, 0, dev_name(dev), mtu);
+ 	if (ret) {
+ 		dev_err(dev, "request irq %d failed!\n", mtu->irq);
+@@ -845,6 +876,7 @@ int ssusb_gadget_init(struct ssusb_mtk *ssusb)
+ gadget_err:
+ 	device_init_wakeup(dev, false);
+ 
++dma_mask_err:
+ irq_err:
+ 	mtu3_hw_exit(mtu);
+ 	ssusb->u3d = NULL;
+diff --git a/drivers/usb/mtu3/mtu3_hw_regs.h b/drivers/usb/mtu3/mtu3_hw_regs.h
+index 06b29664470f..b6059752dc12 100644
+--- a/drivers/usb/mtu3/mtu3_hw_regs.h
++++ b/drivers/usb/mtu3/mtu3_hw_regs.h
+@@ -58,6 +58,8 @@
+ #define U3D_QCR1		(SSUSB_DEV_BASE + 0x0404)
+ #define U3D_QCR2		(SSUSB_DEV_BASE + 0x0408)
+ #define U3D_QCR3		(SSUSB_DEV_BASE + 0x040C)
++#define U3D_TXQHIAR1		(SSUSB_DEV_BASE + 0x0484)
++#define U3D_RXQHIAR1		(SSUSB_DEV_BASE + 0x04C4)
+ 
+ #define U3D_TXQCSR1		(SSUSB_DEV_BASE + 0x0510)
+ #define U3D_TXQSAR1		(SSUSB_DEV_BASE + 0x0514)
+@@ -189,6 +191,13 @@
+ #define QMU_RX_COZ(x)		(BIT(16) << (x))
+ #define QMU_RX_ZLP(x)		(BIT(0) << (x))
+ 
++/* U3D_TXQHIAR1 */
++/* U3D_RXQHIAR1 */
++#define QMU_LAST_DONE_PTR_HI(x)	(((x) >> 16) & 0xf)
++#define QMU_CUR_GPD_ADDR_HI(x)	(((x) >> 8) & 0xf)
++#define QMU_START_ADDR_HI_MSK	GENMASK(3, 0)
++#define QMU_START_ADDR_HI(x)	(((x) & 0xf) << 0)
++
+ /* U3D_TXQCSR1 */
+ /* U3D_RXQCSR1 */
+ #define QMU_Q_ACTIVE		BIT(15)
+@@ -225,6 +234,7 @@
+ #define CAP_TX_EP_NUM(x)	((x) & 0x1f)
+ 
+ /* U3D_MISC_CTRL */
++#define DMA_ADDR_36BIT		BIT(31)
+ #define VBUS_ON			BIT(1)
+ #define VBUS_FRC_EN		BIT(0)
+ 
+diff --git a/drivers/usb/mtu3/mtu3_qmu.c b/drivers/usb/mtu3/mtu3_qmu.c
+index 7d9ba8a52368..42145a3f1422 100644
+--- a/drivers/usb/mtu3/mtu3_qmu.c
++++ b/drivers/usb/mtu3/mtu3_qmu.c
+@@ -40,7 +40,58 @@
+ #define GPD_FLAGS_IOC	BIT(7)
+ 
+ #define GPD_EXT_FLAG_ZLP	BIT(5)
++#define GPD_EXT_NGP(x)		(((x) & 0xf) << 4)
++#define GPD_EXT_BUF(x)		(((x) & 0xf) << 0)
+ 
++#define HILO_GEN64(hi, lo) (((u64)(hi) << 32) + (lo))
++#define HILO_DMA(hi, lo)	\
++	((dma_addr_t)HILO_GEN64((le32_to_cpu(hi)), (le32_to_cpu(lo))))
++
++static dma_addr_t read_txq_cur_addr(void __iomem *mbase, u8 epnum)
++{
++	u32 txcpr;
++	u32 txhiar;
++
++	txcpr = mtu3_readl(mbase, USB_QMU_TQCPR(epnum));
++	txhiar = mtu3_readl(mbase, USB_QMU_TQHIAR(epnum));
++
++	return HILO_DMA(QMU_CUR_GPD_ADDR_HI(txhiar), txcpr);
++}
++
++static dma_addr_t read_rxq_cur_addr(void __iomem *mbase, u8 epnum)
++{
++	u32 rxcpr;
++	u32 rxhiar;
++
++	rxcpr = mtu3_readl(mbase, USB_QMU_RQCPR(epnum));
++	rxhiar = mtu3_readl(mbase, USB_QMU_RQHIAR(epnum));
++
++	return HILO_DMA(QMU_CUR_GPD_ADDR_HI(rxhiar), rxcpr);
++}
++
++static void write_txq_start_addr(void __iomem *mbase, u8 epnum, dma_addr_t dma)
++{
++	u32 tqhiar;
++
++	mtu3_writel(mbase, USB_QMU_TQSAR(epnum),
++		    cpu_to_le32(lower_32_bits(dma)));
++	tqhiar = mtu3_readl(mbase, USB_QMU_TQHIAR(epnum));
++	tqhiar &= ~QMU_START_ADDR_HI_MSK;
++	tqhiar |= QMU_START_ADDR_HI(upper_32_bits(dma));
++	mtu3_writel(mbase, USB_QMU_TQHIAR(epnum), tqhiar);
++}
++
++static void write_rxq_start_addr(void __iomem *mbase, u8 epnum, dma_addr_t dma)
++{
++	u32 rqhiar;
++
++	mtu3_writel(mbase, USB_QMU_RQSAR(epnum),
++		    cpu_to_le32(lower_32_bits(dma)));
++	rqhiar = mtu3_readl(mbase, USB_QMU_RQHIAR(epnum));
++	rqhiar &= ~QMU_START_ADDR_HI_MSK;
++	rqhiar |= QMU_START_ADDR_HI(upper_32_bits(dma));
++	mtu3_writel(mbase, USB_QMU_RQHIAR(epnum), rqhiar);
++}
+ 
+ static struct qmu_gpd *gpd_dma_to_virt(struct mtu3_gpd_ring *ring,
+ 		dma_addr_t dma_addr)
+@@ -193,21 +244,27 @@ static int mtu3_prepare_tx_gpd(struct mtu3_ep *mep, struct mtu3_request *mreq)
+ 	struct mtu3_gpd_ring *ring = &mep->gpd_ring;
+ 	struct qmu_gpd *gpd = ring->enqueue;
+ 	struct usb_request *req = &mreq->request;
++	dma_addr_t enq_dma;
++	u16 ext_addr;
+ 
+ 	/* set all fields to zero as default value */
+ 	memset(gpd, 0, sizeof(*gpd));
+ 
+-	gpd->buffer = cpu_to_le32((u32)req->dma);
++	gpd->buffer = cpu_to_le32(lower_32_bits(req->dma));
++	ext_addr = GPD_EXT_BUF(upper_32_bits(req->dma));
+ 	gpd->buf_len = cpu_to_le16(req->length);
+ 	gpd->flag |= GPD_FLAGS_IOC;
+ 
+ 	/* get the next GPD */
+ 	enq = advance_enq_gpd(ring);
+-	dev_dbg(mep->mtu->dev, "TX-EP%d queue gpd=%p, enq=%p\n",
+-		mep->epnum, gpd, enq);
++	enq_dma = gpd_virt_to_dma(ring, enq);
++	dev_dbg(mep->mtu->dev, "TX-EP%d queue gpd=%p, enq=%p, qdma=%pad\n",
++		mep->epnum, gpd, enq, enq_dma);
+ 
+ 	enq->flag &= ~GPD_FLAGS_HWO;
+-	gpd->next_gpd = cpu_to_le32((u32)gpd_virt_to_dma(ring, enq));
++	gpd->next_gpd = cpu_to_le32(lower_32_bits(enq_dma));
++	ext_addr |= GPD_EXT_NGP(upper_32_bits(enq_dma));
++	gpd->tx_ext_addr = cpu_to_le16(ext_addr);
+ 
+ 	if (req->zero)
+ 		gpd->ext_flag |= GPD_EXT_FLAG_ZLP;
+@@ -226,21 +283,27 @@ static int mtu3_prepare_rx_gpd(struct mtu3_ep *mep, struct mtu3_request *mreq)
+ 	struct mtu3_gpd_ring *ring = &mep->gpd_ring;
+ 	struct qmu_gpd *gpd = ring->enqueue;
+ 	struct usb_request *req = &mreq->request;
++	dma_addr_t enq_dma;
++	u16 ext_addr;
+ 
+ 	/* set all fields to zero as default value */
+ 	memset(gpd, 0, sizeof(*gpd));
+ 
+-	gpd->buffer = cpu_to_le32((u32)req->dma);
++	gpd->buffer = cpu_to_le32(lower_32_bits(req->dma));
++	ext_addr = GPD_EXT_BUF(upper_32_bits(req->dma));
+ 	gpd->data_buf_len = cpu_to_le16(req->length);
+ 	gpd->flag |= GPD_FLAGS_IOC;
+ 
+ 	/* get the next GPD */
+ 	enq = advance_enq_gpd(ring);
+-	dev_dbg(mep->mtu->dev, "RX-EP%d queue gpd=%p, enq=%p\n",
+-		mep->epnum, gpd, enq);
++	enq_dma = gpd_virt_to_dma(ring, enq);
++	dev_dbg(mep->mtu->dev, "RX-EP%d queue gpd=%p, enq=%p, qdma=%pad\n",
++		mep->epnum, gpd, enq, enq_dma);
+ 
+ 	enq->flag &= ~GPD_FLAGS_HWO;
+-	gpd->next_gpd = cpu_to_le32((u32)gpd_virt_to_dma(ring, enq));
++	gpd->next_gpd = cpu_to_le32(lower_32_bits(enq_dma));
++	ext_addr |= GPD_EXT_NGP(upper_32_bits(enq_dma));
++	gpd->rx_ext_addr = cpu_to_le16(ext_addr);
+ 	gpd->chksum = qmu_calc_checksum((u8 *)gpd);
+ 	gpd->flag |= GPD_FLAGS_HWO;
+ 
+@@ -267,8 +330,8 @@ int mtu3_qmu_start(struct mtu3_ep *mep)
+ 
+ 	if (mep->is_in) {
+ 		/* set QMU start address */
+-		mtu3_writel(mbase, USB_QMU_TQSAR(mep->epnum), ring->dma);
+-		mtu3_setbits(mbase, MU3D_EP_TXCR0(mep->epnum), TX_DMAREQEN);
++		write_txq_start_addr(mbase, epnum, ring->dma);
++		mtu3_setbits(mbase, MU3D_EP_TXCR0(epnum), TX_DMAREQEN);
+ 		mtu3_setbits(mbase, U3D_QCR0, QMU_TX_CS_EN(epnum));
+ 		/* send zero length packet according to ZLP flag in GPD */
+ 		mtu3_setbits(mbase, U3D_QCR1, QMU_TX_ZLP(epnum));
+@@ -282,8 +345,8 @@ int mtu3_qmu_start(struct mtu3_ep *mep)
+ 		mtu3_writel(mbase, USB_QMU_TQCSR(epnum), QMU_Q_START);
+ 
+ 	} else {
+-		mtu3_writel(mbase, USB_QMU_RQSAR(mep->epnum), ring->dma);
+-		mtu3_setbits(mbase, MU3D_EP_RXCR0(mep->epnum), RX_DMAREQEN);
++		write_rxq_start_addr(mbase, epnum, ring->dma);
++		mtu3_setbits(mbase, MU3D_EP_RXCR0(epnum), RX_DMAREQEN);
+ 		mtu3_setbits(mbase, U3D_QCR0, QMU_RX_CS_EN(epnum));
+ 		/* don't expect ZLP */
+ 		mtu3_clrbits(mbase, U3D_QCR3, QMU_RX_ZLP(epnum));
+@@ -353,9 +416,9 @@ static void qmu_tx_zlp_error_handler(struct mtu3 *mtu, u8 epnum)
+ 	struct mtu3_gpd_ring *ring = &mep->gpd_ring;
+ 	void __iomem *mbase = mtu->mac_base;
+ 	struct qmu_gpd *gpd_current = NULL;
+-	dma_addr_t gpd_dma = mtu3_readl(mbase, USB_QMU_TQCPR(epnum));
+ 	struct usb_request *req = NULL;
+ 	struct mtu3_request *mreq;
++	dma_addr_t cur_gpd_dma;
+ 	u32 txcsr = 0;
+ 	int ret;
+ 
+@@ -365,7 +428,8 @@ static void qmu_tx_zlp_error_handler(struct mtu3 *mtu, u8 epnum)
+ 	else
+ 		return;
+ 
+-	gpd_current = gpd_dma_to_virt(ring, gpd_dma);
++	cur_gpd_dma = read_txq_cur_addr(mbase, epnum);
++	gpd_current = gpd_dma_to_virt(ring, cur_gpd_dma);
+ 
+ 	if (le16_to_cpu(gpd_current->buf_len) != 0) {
+ 		dev_err(mtu->dev, "TX EP%d buffer length error(!=0)\n", epnum);
+@@ -408,12 +472,13 @@ static void qmu_done_tx(struct mtu3 *mtu, u8 epnum)
+ 	void __iomem *mbase = mtu->mac_base;
+ 	struct qmu_gpd *gpd = ring->dequeue;
+ 	struct qmu_gpd *gpd_current = NULL;
+-	dma_addr_t gpd_dma = mtu3_readl(mbase, USB_QMU_TQCPR(epnum));
+ 	struct usb_request *request = NULL;
+ 	struct mtu3_request *mreq;
++	dma_addr_t cur_gpd_dma;
+ 
+ 	/*transfer phy address got from QMU register to virtual address */
+-	gpd_current = gpd_dma_to_virt(ring, gpd_dma);
++	cur_gpd_dma = read_txq_cur_addr(mbase, epnum);
++	gpd_current = gpd_dma_to_virt(ring, cur_gpd_dma);
+ 
+ 	dev_dbg(mtu->dev, "%s EP%d, last=%p, current=%p, enq=%p\n",
+ 		__func__, epnum, gpd, gpd_current, ring->enqueue);
+@@ -446,11 +511,12 @@ static void qmu_done_rx(struct mtu3 *mtu, u8 epnum)
+ 	void __iomem *mbase = mtu->mac_base;
+ 	struct qmu_gpd *gpd = ring->dequeue;
+ 	struct qmu_gpd *gpd_current = NULL;
+-	dma_addr_t gpd_dma = mtu3_readl(mbase, USB_QMU_RQCPR(epnum));
+ 	struct usb_request *req = NULL;
+ 	struct mtu3_request *mreq;
++	dma_addr_t cur_gpd_dma;
+ 
+-	gpd_current = gpd_dma_to_virt(ring, gpd_dma);
++	cur_gpd_dma = read_rxq_cur_addr(mbase, epnum);
++	gpd_current = gpd_dma_to_virt(ring, cur_gpd_dma);
+ 
+ 	dev_dbg(mtu->dev, "%s EP%d, last=%p, current=%p, enq=%p\n",
+ 		__func__, epnum, gpd, gpd_current, ring->enqueue);
+-- 
+2.11.0
+
diff --git a/target/linux/mediatek/patches-4.14/0108-usb-mtu3-use-FORCE-RG_IDDIG-to-implement-manual-DRD-.patch b/target/linux/mediatek/patches-4.14/0108-usb-mtu3-use-FORCE-RG_IDDIG-to-implement-manual-DRD-.patch
new file mode 100644
index 0000000000..ce454feb23
--- /dev/null
+++ b/target/linux/mediatek/patches-4.14/0108-usb-mtu3-use-FORCE-RG_IDDIG-to-implement-manual-DRD-.patch
@@ -0,0 +1,290 @@
+From 6c4995c9a8ba8841ba640201636954c84f494587 Mon Sep 17 00:00:00 2001
+From: Chunfeng Yun <chunfeng.yun@mediatek.com>
+Date: Fri, 13 Oct 2017 17:10:42 +0800
+Subject: [PATCH 108/224] usb: mtu3: use FORCE/RG_IDDIG to implement manual DRD
+ switch
+
+In order to keep manual DRD switch independent on IDDIG interrupt,
+make use of FORCE/RG_IDDIG instead of IDDIG EINT interrupt to
+implement manual DRD switch function.
+
+Signed-off-by: Chunfeng Yun <chunfeng.yun@mediatek.com>
+Signed-off-by: Felipe Balbi <felipe.balbi@linux.intel.com>
+---
+ drivers/usb/mtu3/mtu3.h         | 18 ++++++++----
+ drivers/usb/mtu3/mtu3_dr.c      | 61 ++++++++++++++++++++++++++++++-----------
+ drivers/usb/mtu3/mtu3_dr.h      |  6 ++++
+ drivers/usb/mtu3/mtu3_host.c    |  5 ++++
+ drivers/usb/mtu3/mtu3_hw_regs.h |  2 ++
+ drivers/usb/mtu3/mtu3_plat.c    | 38 ++-----------------------
+ 6 files changed, 74 insertions(+), 56 deletions(-)
+
+diff --git a/drivers/usb/mtu3/mtu3.h b/drivers/usb/mtu3/mtu3.h
+index ef2dc92a2109..b0c2b5dca045 100644
+--- a/drivers/usb/mtu3/mtu3.h
++++ b/drivers/usb/mtu3/mtu3.h
+@@ -115,6 +115,19 @@ enum mtu3_g_ep0_state {
+ };
+ 
+ /**
++ * MTU3_DR_FORCE_NONE: automatically switch host and periperal mode
++ *		by IDPIN signal.
++ * MTU3_DR_FORCE_HOST: force to enter host mode and override OTG
++ *		IDPIN signal.
++ * MTU3_DR_FORCE_DEVICE: force to enter peripheral mode.
++ */
++enum mtu3_dr_force_mode {
++	MTU3_DR_FORCE_NONE = 0,
++	MTU3_DR_FORCE_HOST,
++	MTU3_DR_FORCE_DEVICE,
++};
++
++/**
+  * @base: the base address of fifo
+  * @limit: the bitmap size in bits
+  * @bitmap: fifo bitmap in unit of @MTU3_EP_FIFO_UNIT
+@@ -196,7 +209,6 @@ struct mtu3_gpd_ring {
+ *		xHCI driver initialization, it's necessary for system bootup
+ *		as device.
+ * @is_u3_drd: whether port0 supports usb3.0 dual-role device or not
+-* @id_*: used to maually switch between host and device modes by idpin
+ * @manual_drd_enabled: it's true when supports dual-role device by debugfs
+ *		to switch host/device modes depending on user input.
+ */
+@@ -207,10 +219,6 @@ struct otg_switch_mtk {
+ 	struct notifier_block id_nb;
+ 	struct delayed_work extcon_reg_dwork;
+ 	bool is_u3_drd;
+-	/* dual-role switch by debugfs */
+-	struct pinctrl *id_pinctrl;
+-	struct pinctrl_state *id_float;
+-	struct pinctrl_state *id_ground;
+ 	bool manual_drd_enabled;
+ };
+ 
+diff --git a/drivers/usb/mtu3/mtu3_dr.c b/drivers/usb/mtu3/mtu3_dr.c
+index 560256115b23..ec442cd5a1ad 100644
+--- a/drivers/usb/mtu3/mtu3_dr.c
++++ b/drivers/usb/mtu3/mtu3_dr.c
+@@ -261,21 +261,22 @@ static void extcon_register_dwork(struct work_struct *work)
+  * depending on user input.
+  * This is useful in special cases, such as uses TYPE-A receptacle but also
+  * wants to support dual-role mode.
+- * It generates cable state changes by pulling up/down IDPIN and
+- * notifies driver to switch mode by "extcon-usb-gpio".
+- * NOTE: when use MICRO receptacle, should not enable this interface.
+  */
+ static void ssusb_mode_manual_switch(struct ssusb_mtk *ssusb, int to_host)
+ {
+ 	struct otg_switch_mtk *otg_sx = &ssusb->otg_switch;
+ 
+-	if (to_host)
+-		pinctrl_select_state(otg_sx->id_pinctrl, otg_sx->id_ground);
+-	else
+-		pinctrl_select_state(otg_sx->id_pinctrl, otg_sx->id_float);
++	if (to_host) {
++		ssusb_set_force_mode(ssusb, MTU3_DR_FORCE_HOST);
++		ssusb_set_mailbox(otg_sx, MTU3_VBUS_OFF);
++		ssusb_set_mailbox(otg_sx, MTU3_ID_GROUND);
++	} else {
++		ssusb_set_force_mode(ssusb, MTU3_DR_FORCE_DEVICE);
++		ssusb_set_mailbox(otg_sx, MTU3_ID_FLOAT);
++		ssusb_set_mailbox(otg_sx, MTU3_VBUS_VALID);
++	}
+ }
+ 
+-
+ static int ssusb_mode_show(struct seq_file *sf, void *unused)
+ {
+ 	struct ssusb_mtk *ssusb = sf->private;
+@@ -388,17 +389,45 @@ static void ssusb_debugfs_exit(struct ssusb_mtk *ssusb)
+ 	debugfs_remove_recursive(ssusb->dbgfs_root);
+ }
+ 
++void ssusb_set_force_mode(struct ssusb_mtk *ssusb,
++			  enum mtu3_dr_force_mode mode)
++{
++	u32 value;
++
++	value = mtu3_readl(ssusb->ippc_base, SSUSB_U2_CTRL(0));
++	switch (mode) {
++	case MTU3_DR_FORCE_DEVICE:
++		value |= SSUSB_U2_PORT_FORCE_IDDIG | SSUSB_U2_PORT_RG_IDDIG;
++		break;
++	case MTU3_DR_FORCE_HOST:
++		value |= SSUSB_U2_PORT_FORCE_IDDIG;
++		value &= ~SSUSB_U2_PORT_RG_IDDIG;
++		break;
++	case MTU3_DR_FORCE_NONE:
++		value &= ~(SSUSB_U2_PORT_FORCE_IDDIG | SSUSB_U2_PORT_RG_IDDIG);
++		break;
++	default:
++		return;
++	}
++	mtu3_writel(ssusb->ippc_base, SSUSB_U2_CTRL(0), value);
++}
++
+ int ssusb_otg_switch_init(struct ssusb_mtk *ssusb)
+ {
+ 	struct otg_switch_mtk *otg_sx = &ssusb->otg_switch;
+ 
+-	INIT_DELAYED_WORK(&otg_sx->extcon_reg_dwork, extcon_register_dwork);
+-
+-	if (otg_sx->manual_drd_enabled)
++	if (otg_sx->manual_drd_enabled) {
+ 		ssusb_debugfs_init(ssusb);
+-
+-	/* It is enough to delay 1s for waiting for host initialization */
+-	schedule_delayed_work(&otg_sx->extcon_reg_dwork, HZ);
++	} else {
++		INIT_DELAYED_WORK(&otg_sx->extcon_reg_dwork,
++				  extcon_register_dwork);
++
++		/*
++		 * It is enough to delay 1s for waiting for
++		 * host initialization
++		 */
++		schedule_delayed_work(&otg_sx->extcon_reg_dwork, HZ);
++	}
+ 
+ 	return 0;
+ }
+@@ -407,8 +436,8 @@ void ssusb_otg_switch_exit(struct ssusb_mtk *ssusb)
+ {
+ 	struct otg_switch_mtk *otg_sx = &ssusb->otg_switch;
+ 
+-	cancel_delayed_work(&otg_sx->extcon_reg_dwork);
+-
+ 	if (otg_sx->manual_drd_enabled)
+ 		ssusb_debugfs_exit(ssusb);
++	else
++		cancel_delayed_work(&otg_sx->extcon_reg_dwork);
+ }
+diff --git a/drivers/usb/mtu3/mtu3_dr.h b/drivers/usb/mtu3/mtu3_dr.h
+index 9b228b5811b0..0f0cbac00192 100644
+--- a/drivers/usb/mtu3/mtu3_dr.h
++++ b/drivers/usb/mtu3/mtu3_dr.h
+@@ -87,6 +87,8 @@ static inline void ssusb_gadget_exit(struct ssusb_mtk *ssusb)
+ int ssusb_otg_switch_init(struct ssusb_mtk *ssusb);
+ void ssusb_otg_switch_exit(struct ssusb_mtk *ssusb);
+ int ssusb_set_vbus(struct otg_switch_mtk *otg_sx, int is_on);
++void ssusb_set_force_mode(struct ssusb_mtk *ssusb,
++			  enum mtu3_dr_force_mode mode);
+ 
+ #else
+ 
+@@ -103,6 +105,10 @@ static inline int ssusb_set_vbus(struct otg_switch_mtk *otg_sx, int is_on)
+ 	return 0;
+ }
+ 
++static inline void
++ssusb_set_force_mode(struct ssusb_mtk *ssusb, enum mtu3_dr_force_mode mode)
++{}
++
+ #endif
+ 
+ #endif		/* _MTU3_DR_H_ */
+diff --git a/drivers/usb/mtu3/mtu3_host.c b/drivers/usb/mtu3/mtu3_host.c
+index edcc59148171..ec76b86dd887 100644
+--- a/drivers/usb/mtu3/mtu3_host.c
++++ b/drivers/usb/mtu3/mtu3_host.c
+@@ -189,6 +189,8 @@ int ssusb_host_disable(struct ssusb_mtk *ssusb, bool suspend)
+ 
+ static void ssusb_host_setup(struct ssusb_mtk *ssusb)
+ {
++	struct otg_switch_mtk *otg_sx = &ssusb->otg_switch;
++
+ 	host_ports_num_get(ssusb);
+ 
+ 	/*
+@@ -197,6 +199,9 @@ static void ssusb_host_setup(struct ssusb_mtk *ssusb)
+ 	 */
+ 	ssusb_host_enable(ssusb);
+ 
++	if (otg_sx->manual_drd_enabled)
++		ssusb_set_force_mode(ssusb, MTU3_DR_FORCE_HOST);
++
+ 	/* if port0 supports dual-role, works as host mode by default */
+ 	ssusb_set_vbus(&ssusb->otg_switch, 1);
+ }
+diff --git a/drivers/usb/mtu3/mtu3_hw_regs.h b/drivers/usb/mtu3/mtu3_hw_regs.h
+index b6059752dc12..a7e35f6ad90a 100644
+--- a/drivers/usb/mtu3/mtu3_hw_regs.h
++++ b/drivers/usb/mtu3/mtu3_hw_regs.h
+@@ -472,6 +472,8 @@
+ #define SSUSB_U3_PORT_DIS		BIT(0)
+ 
+ /* U3D_SSUSB_U2_CTRL_0P */
++#define SSUSB_U2_PORT_RG_IDDIG		BIT(12)
++#define SSUSB_U2_PORT_FORCE_IDDIG	BIT(11)
+ #define SSUSB_U2_PORT_VBUSVALID	BIT(9)
+ #define SSUSB_U2_PORT_OTG_SEL		BIT(7)
+ #define SSUSB_U2_PORT_HOST		BIT(2)
+diff --git a/drivers/usb/mtu3/mtu3_plat.c b/drivers/usb/mtu3/mtu3_plat.c
+index fb8992011bde..1e473b068650 100644
+--- a/drivers/usb/mtu3/mtu3_plat.c
++++ b/drivers/usb/mtu3/mtu3_plat.c
+@@ -21,7 +21,6 @@
+ #include <linux/module.h>
+ #include <linux/of_address.h>
+ #include <linux/of_irq.h>
+-#include <linux/pinctrl/consumer.h>
+ #include <linux/platform_device.h>
+ 
+ #include "mtu3.h"
+@@ -212,33 +211,6 @@ static void ssusb_ip_sw_reset(struct ssusb_mtk *ssusb)
+ 	mtu3_clrbits(ssusb->ippc_base, U3D_SSUSB_IP_PW_CTRL0, SSUSB_IP_SW_RST);
+ }
+ 
+-static int get_iddig_pinctrl(struct ssusb_mtk *ssusb)
+-{
+-	struct otg_switch_mtk *otg_sx = &ssusb->otg_switch;
+-
+-	otg_sx->id_pinctrl = devm_pinctrl_get(ssusb->dev);
+-	if (IS_ERR(otg_sx->id_pinctrl)) {
+-		dev_err(ssusb->dev, "Cannot find id pinctrl!\n");
+-		return PTR_ERR(otg_sx->id_pinctrl);
+-	}
+-
+-	otg_sx->id_float =
+-		pinctrl_lookup_state(otg_sx->id_pinctrl, "id_float");
+-	if (IS_ERR(otg_sx->id_float)) {
+-		dev_err(ssusb->dev, "Cannot find pinctrl id_float!\n");
+-		return PTR_ERR(otg_sx->id_float);
+-	}
+-
+-	otg_sx->id_ground =
+-		pinctrl_lookup_state(otg_sx->id_pinctrl, "id_ground");
+-	if (IS_ERR(otg_sx->id_ground)) {
+-		dev_err(ssusb->dev, "Cannot find pinctrl id_ground!\n");
+-		return PTR_ERR(otg_sx->id_ground);
+-	}
+-
+-	return 0;
+-}
+-
+ /* ignore the error if the clock does not exist */
+ static struct clk *get_optional_clk(struct device *dev, const char *id)
+ {
+@@ -349,15 +321,11 @@ static int get_ssusb_rscs(struct platform_device *pdev, struct ssusb_mtk *ssusb)
+ 			dev_err(ssusb->dev, "couldn't get extcon device\n");
+ 			return -EPROBE_DEFER;
+ 		}
+-		if (otg_sx->manual_drd_enabled) {
+-			ret = get_iddig_pinctrl(ssusb);
+-			if (ret)
+-				return ret;
+-		}
+ 	}
+ 
+-	dev_info(dev, "dr_mode: %d, is_u3_dr: %d, u3p_dis_msk:%x\n",
+-		ssusb->dr_mode, otg_sx->is_u3_drd, ssusb->u3p_dis_msk);
++	dev_info(dev, "dr_mode: %d, is_u3_dr: %d, u3p_dis_msk: %x, drd: %s\n",
++		ssusb->dr_mode, otg_sx->is_u3_drd, ssusb->u3p_dis_msk,
++		otg_sx->manual_drd_enabled ? "manual" : "auto");
+ 
+ 	return 0;
+ }
+-- 
+2.11.0
+
diff --git a/target/linux/mediatek/patches-4.14/0109-usb-mtu3-add-support-for-usb3.1-IP.patch b/target/linux/mediatek/patches-4.14/0109-usb-mtu3-add-support-for-usb3.1-IP.patch
new file mode 100644
index 0000000000..020dabf782
--- /dev/null
+++ b/target/linux/mediatek/patches-4.14/0109-usb-mtu3-add-support-for-usb3.1-IP.patch
@@ -0,0 +1,165 @@
+From 8f444887e23b9f0ea31aaae74fbc18171714d8d2 Mon Sep 17 00:00:00 2001
+From: Chunfeng Yun <chunfeng.yun@mediatek.com>
+Date: Fri, 13 Oct 2017 17:10:43 +0800
+Subject: [PATCH 109/224] usb: mtu3: add support for usb3.1 IP
+
+Support SuperSpeedPlus for usb3.1 device IP
+
+Signed-off-by: Chunfeng Yun <chunfeng.yun@mediatek.com>
+Signed-off-by: Felipe Balbi <felipe.balbi@linux.intel.com>
+---
+ drivers/usb/mtu3/mtu3.h            |  1 +
+ drivers/usb/mtu3/mtu3_core.c       | 14 +++++++++++---
+ drivers/usb/mtu3/mtu3_gadget.c     |  3 ++-
+ drivers/usb/mtu3/mtu3_gadget_ep0.c | 16 ++++++++--------
+ drivers/usb/mtu3/mtu3_hw_regs.h    |  1 +
+ 5 files changed, 23 insertions(+), 12 deletions(-)
+
+diff --git a/drivers/usb/mtu3/mtu3.h b/drivers/usb/mtu3/mtu3.h
+index b0c2b5dca045..d80e4e813248 100644
+--- a/drivers/usb/mtu3/mtu3.h
++++ b/drivers/usb/mtu3/mtu3.h
+@@ -94,6 +94,7 @@ enum mtu3_speed {
+ 	MTU3_SPEED_FULL = 1,
+ 	MTU3_SPEED_HIGH = 3,
+ 	MTU3_SPEED_SUPER = 4,
++	MTU3_SPEED_SUPER_PLUS = 5,
+ };
+ 
+ /**
+diff --git a/drivers/usb/mtu3/mtu3_core.c b/drivers/usb/mtu3/mtu3_core.c
+index cd4528f5f337..67f7a309aba7 100644
+--- a/drivers/usb/mtu3/mtu3_core.c
++++ b/drivers/usb/mtu3/mtu3_core.c
+@@ -237,7 +237,7 @@ void mtu3_ep_stall_set(struct mtu3_ep *mep, bool set)
+ 
+ void mtu3_dev_on_off(struct mtu3 *mtu, int is_on)
+ {
+-	if (mtu->is_u3_ip && (mtu->max_speed == USB_SPEED_SUPER))
++	if (mtu->is_u3_ip && mtu->max_speed >= USB_SPEED_SUPER)
+ 		mtu3_ss_func_set(mtu, is_on);
+ 	else
+ 		mtu3_hs_softconn_set(mtu, is_on);
+@@ -547,6 +547,9 @@ static void mtu3_set_speed(struct mtu3 *mtu)
+ 		mtu3_clrbits(mbase, U3D_USB3_CONFIG, USB3_EN);
+ 		/* HS/FS detected by HW */
+ 		mtu3_setbits(mbase, U3D_POWER_MANAGEMENT, HS_ENABLE);
++	} else if (mtu->max_speed == USB_SPEED_SUPER) {
++		mtu3_clrbits(mtu->ippc_base, SSUSB_U3_CTRL(0),
++			     SSUSB_U3_PORT_SSP_SPEED);
+ 	}
+ 
+ 	dev_info(mtu->dev, "max_speed: %s\n",
+@@ -624,6 +627,10 @@ static irqreturn_t mtu3_link_isr(struct mtu3 *mtu)
+ 		udev_speed = USB_SPEED_SUPER;
+ 		maxpkt = 512;
+ 		break;
++	case MTU3_SPEED_SUPER_PLUS:
++		udev_speed = USB_SPEED_SUPER_PLUS;
++		maxpkt = 512;
++		break;
+ 	default:
+ 		udev_speed = USB_SPEED_UNKNOWN;
+ 		break;
+@@ -825,14 +832,15 @@ int ssusb_gadget_init(struct ssusb_mtk *ssusb)
+ 	case USB_SPEED_FULL:
+ 	case USB_SPEED_HIGH:
+ 	case USB_SPEED_SUPER:
++	case USB_SPEED_SUPER_PLUS:
+ 		break;
+ 	default:
+ 		dev_err(dev, "invalid max_speed: %s\n",
+ 			usb_speed_string(mtu->max_speed));
+ 		/* fall through */
+ 	case USB_SPEED_UNKNOWN:
+-		/* default as SS */
+-		mtu->max_speed = USB_SPEED_SUPER;
++		/* default as SSP */
++		mtu->max_speed = USB_SPEED_SUPER_PLUS;
+ 		break;
+ 	}
+ 
+diff --git a/drivers/usb/mtu3/mtu3_gadget.c b/drivers/usb/mtu3/mtu3_gadget.c
+index 434fca58143c..b495471f689f 100644
+--- a/drivers/usb/mtu3/mtu3_gadget.c
++++ b/drivers/usb/mtu3/mtu3_gadget.c
+@@ -89,6 +89,7 @@ static int mtu3_ep_enable(struct mtu3_ep *mep)
+ 
+ 	switch (mtu->g.speed) {
+ 	case USB_SPEED_SUPER:
++	case USB_SPEED_SUPER_PLUS:
+ 		if (usb_endpoint_xfer_int(desc) ||
+ 				usb_endpoint_xfer_isoc(desc)) {
+ 			interval = desc->bInterval;
+@@ -456,7 +457,7 @@ static int mtu3_gadget_wakeup(struct usb_gadget *gadget)
+ 		return  -EOPNOTSUPP;
+ 
+ 	spin_lock_irqsave(&mtu->lock, flags);
+-	if (mtu->g.speed == USB_SPEED_SUPER) {
++	if (mtu->g.speed >= USB_SPEED_SUPER) {
+ 		mtu3_setbits(mtu->mac_base, U3D_LINK_POWER_CONTROL, UX_EXIT);
+ 	} else {
+ 		mtu3_setbits(mtu->mac_base, U3D_POWER_MANAGEMENT, RESUME);
+diff --git a/drivers/usb/mtu3/mtu3_gadget_ep0.c b/drivers/usb/mtu3/mtu3_gadget_ep0.c
+index 958d74dd2b78..020b25314a68 100644
+--- a/drivers/usb/mtu3/mtu3_gadget_ep0.c
++++ b/drivers/usb/mtu3/mtu3_gadget_ep0.c
+@@ -212,8 +212,8 @@ ep0_get_status(struct mtu3 *mtu, const struct usb_ctrlrequest *setup)
+ 	case USB_RECIP_DEVICE:
+ 		result[0] = mtu->is_self_powered << USB_DEVICE_SELF_POWERED;
+ 		result[0] |= mtu->may_wakeup << USB_DEVICE_REMOTE_WAKEUP;
+-		/* superspeed only */
+-		if (mtu->g.speed == USB_SPEED_SUPER) {
++
++		if (mtu->g.speed >= USB_SPEED_SUPER) {
+ 			result[0] |= mtu->u1_enable << USB_DEV_STAT_U1_ENABLED;
+ 			result[0] |= mtu->u2_enable << USB_DEV_STAT_U2_ENABLED;
+ 		}
+@@ -329,8 +329,8 @@ static int ep0_handle_feature_dev(struct mtu3 *mtu,
+ 		handled = handle_test_mode(mtu, setup);
+ 		break;
+ 	case USB_DEVICE_U1_ENABLE:
+-		if (mtu->g.speed != USB_SPEED_SUPER ||
+-			mtu->g.state != USB_STATE_CONFIGURED)
++		if (mtu->g.speed < USB_SPEED_SUPER ||
++		    mtu->g.state != USB_STATE_CONFIGURED)
+ 			break;
+ 
+ 		lpc = mtu3_readl(mbase, U3D_LINK_POWER_CONTROL);
+@@ -344,8 +344,8 @@ static int ep0_handle_feature_dev(struct mtu3 *mtu,
+ 		handled = 1;
+ 		break;
+ 	case USB_DEVICE_U2_ENABLE:
+-		if (mtu->g.speed != USB_SPEED_SUPER ||
+-			mtu->g.state != USB_STATE_CONFIGURED)
++		if (mtu->g.speed < USB_SPEED_SUPER ||
++		    mtu->g.state != USB_STATE_CONFIGURED)
+ 			break;
+ 
+ 		lpc = mtu3_readl(mbase, U3D_LINK_POWER_CONTROL);
+@@ -384,8 +384,8 @@ static int ep0_handle_feature(struct mtu3 *mtu,
+ 		break;
+ 	case USB_RECIP_INTERFACE:
+ 		/* superspeed only */
+-		if ((value == USB_INTRF_FUNC_SUSPEND)
+-			&& (mtu->g.speed == USB_SPEED_SUPER)) {
++		if (value == USB_INTRF_FUNC_SUSPEND &&
++		    mtu->g.speed >= USB_SPEED_SUPER) {
+ 			/*
+ 			 * forward the request because function drivers
+ 			 * should handle it
+diff --git a/drivers/usb/mtu3/mtu3_hw_regs.h b/drivers/usb/mtu3/mtu3_hw_regs.h
+index a7e35f6ad90a..6953436a1688 100644
+--- a/drivers/usb/mtu3/mtu3_hw_regs.h
++++ b/drivers/usb/mtu3/mtu3_hw_regs.h
+@@ -467,6 +467,7 @@
+ #define SSUSB_VBUS_CHG_INT_B_EN		BIT(6)
+ 
+ /* U3D_SSUSB_U3_CTRL_0P */
++#define SSUSB_U3_PORT_SSP_SPEED	BIT(9)
+ #define SSUSB_U3_PORT_HOST_SEL		BIT(2)
+ #define SSUSB_U3_PORT_PDN		BIT(1)
+ #define SSUSB_U3_PORT_DIS		BIT(0)
+-- 
+2.11.0
+
diff --git a/target/linux/mediatek/patches-4.14/0110-usb-mtu3-get-optional-vbus-for-host-only-mode.patch b/target/linux/mediatek/patches-4.14/0110-usb-mtu3-get-optional-vbus-for-host-only-mode.patch
new file mode 100644
index 0000000000..d55fe7dbe2
--- /dev/null
+++ b/target/linux/mediatek/patches-4.14/0110-usb-mtu3-get-optional-vbus-for-host-only-mode.patch
@@ -0,0 +1,45 @@
+From b6712b72d1273e792ee8a533048ba731a3709163 Mon Sep 17 00:00:00 2001
+From: Chunfeng Yun <chunfeng.yun@mediatek.com>
+Date: Fri, 13 Oct 2017 17:10:44 +0800
+Subject: [PATCH 110/224] usb: mtu3: get optional vbus for host only mode
+
+When dr_mode is set as USB_DR_MODE_HOST, it's better to try to
+get optional vbus, this can increase flexibility, although we
+can set vbus as always on for regulator or put it in host driver
+to turn it on.
+
+Signed-off-by: Chunfeng Yun <chunfeng.yun@mediatek.com>
+Signed-off-by: Felipe Balbi <felipe.balbi@linux.intel.com>
+---
+ drivers/usb/mtu3/mtu3_plat.c | 8 ++++----
+ 1 file changed, 4 insertions(+), 4 deletions(-)
+
+diff --git a/drivers/usb/mtu3/mtu3_plat.c b/drivers/usb/mtu3/mtu3_plat.c
+index 1e473b068650..7ca81f4e78a3 100644
+--- a/drivers/usb/mtu3/mtu3_plat.c
++++ b/drivers/usb/mtu3/mtu3_plat.c
+@@ -300,10 +300,6 @@ static int get_ssusb_rscs(struct platform_device *pdev, struct ssusb_mtk *ssusb)
+ 	of_property_read_u32(node, "mediatek,u3p-dis-msk",
+ 			     &ssusb->u3p_dis_msk);
+ 
+-	if (ssusb->dr_mode != USB_DR_MODE_OTG)
+-		return 0;
+-
+-	/* if dual-role mode is supported */
+ 	vbus = devm_regulator_get(&pdev->dev, "vbus");
+ 	if (IS_ERR(vbus)) {
+ 		dev_err(dev, "failed to get vbus\n");
+@@ -311,6 +307,10 @@ static int get_ssusb_rscs(struct platform_device *pdev, struct ssusb_mtk *ssusb)
+ 	}
+ 	otg_sx->vbus = vbus;
+ 
++	if (ssusb->dr_mode == USB_DR_MODE_HOST)
++		return 0;
++
++	/* if dual-role mode is supported */
+ 	otg_sx->is_u3_drd = of_property_read_bool(node, "mediatek,usb3-drd");
+ 	otg_sx->manual_drd_enabled =
+ 		of_property_read_bool(node, "enable-manual-drd");
+-- 
+2.11.0
+
diff --git a/target/linux/mediatek/patches-4.14/0111-usb-mtu3-set-invalid-dr_mode-as-dual-role-mode.patch b/target/linux/mediatek/patches-4.14/0111-usb-mtu3-set-invalid-dr_mode-as-dual-role-mode.patch
new file mode 100644
index 0000000000..1c23d15eca
--- /dev/null
+++ b/target/linux/mediatek/patches-4.14/0111-usb-mtu3-set-invalid-dr_mode-as-dual-role-mode.patch
@@ -0,0 +1,34 @@
+From e315036cdbf8dad7cff4df9dfe8bcff2eddf2277 Mon Sep 17 00:00:00 2001
+From: Chunfeng Yun <chunfeng.yun@mediatek.com>
+Date: Fri, 13 Oct 2017 17:10:45 +0800
+Subject: [PATCH 111/224] usb: mtu3: set invalid dr_mode as dual-role mode
+
+Treat dr_mode of USB_DR_MODE_UNKNOWN as USB_DR_MODE_OTG to
+enhance functional robustness.
+
+Signed-off-by: Chunfeng Yun <chunfeng.yun@mediatek.com>
+Signed-off-by: Felipe Balbi <felipe.balbi@linux.intel.com>
+---
+ drivers/usb/mtu3/mtu3_plat.c | 6 ++----
+ 1 file changed, 2 insertions(+), 4 deletions(-)
+
+diff --git a/drivers/usb/mtu3/mtu3_plat.c b/drivers/usb/mtu3/mtu3_plat.c
+index 7ca81f4e78a3..9ff33579b42e 100644
+--- a/drivers/usb/mtu3/mtu3_plat.c
++++ b/drivers/usb/mtu3/mtu3_plat.c
+@@ -283,10 +283,8 @@ static int get_ssusb_rscs(struct platform_device *pdev, struct ssusb_mtk *ssusb)
+ 		return PTR_ERR(ssusb->ippc_base);
+ 
+ 	ssusb->dr_mode = usb_get_dr_mode(dev);
+-	if (ssusb->dr_mode == USB_DR_MODE_UNKNOWN) {
+-		dev_err(dev, "dr_mode is error\n");
+-		return -EINVAL;
+-	}
++	if (ssusb->dr_mode == USB_DR_MODE_UNKNOWN)
++		ssusb->dr_mode = USB_DR_MODE_OTG;
+ 
+ 	if (ssusb->dr_mode == USB_DR_MODE_PERIPHERAL)
+ 		return 0;
+-- 
+2.11.0
+
diff --git a/target/linux/mediatek/patches-4.14/0112-usb-mtu3-set-otg_sel-for-u2port-only-if-works-as-dua.patch b/target/linux/mediatek/patches-4.14/0112-usb-mtu3-set-otg_sel-for-u2port-only-if-works-as-dua.patch
new file mode 100644
index 0000000000..3a74fe534f
--- /dev/null
+++ b/target/linux/mediatek/patches-4.14/0112-usb-mtu3-set-otg_sel-for-u2port-only-if-works-as-dua.patch
@@ -0,0 +1,49 @@
+From 36f70702b66cd3453b65d46b5c26ea87d8897363 Mon Sep 17 00:00:00 2001
+From: Chunfeng Yun <chunfeng.yun@mediatek.com>
+Date: Fri, 13 Oct 2017 17:10:46 +0800
+Subject: [PATCH 112/224] usb: mtu3: set otg_sel for u2port only if works as
+ dual-role mode
+
+When set otg_sel(SSUSB_U2_PORT_OTG_SEL) for u2port which supports
+dual-role mode, the controller will automatically switch mode
+between host and device according to IDDIG signal. But if the
+u2port only supports device mode, and no IDDIG pin is provided,
+setting otg_sel may cause failure of detection by host.
+So set it only for dual-role mode.
+
+Signed-off-by: Chunfeng Yun <chunfeng.yun@mediatek.com>
+Signed-off-by: Felipe Balbi <felipe.balbi@linux.intel.com>
+---
+ drivers/usb/mtu3/mtu3_core.c | 9 +++++++--
+ 1 file changed, 7 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/usb/mtu3/mtu3_core.c b/drivers/usb/mtu3/mtu3_core.c
+index 67f7a309aba7..7c149a7da14e 100644
+--- a/drivers/usb/mtu3/mtu3_core.c
++++ b/drivers/usb/mtu3/mtu3_core.c
+@@ -115,7 +115,9 @@ static int mtu3_device_enable(struct mtu3 *mtu)
+ 	mtu3_clrbits(ibase, SSUSB_U2_CTRL(0),
+ 		(SSUSB_U2_PORT_DIS | SSUSB_U2_PORT_PDN |
+ 		SSUSB_U2_PORT_HOST_SEL));
+-	mtu3_setbits(ibase, SSUSB_U2_CTRL(0), SSUSB_U2_PORT_OTG_SEL);
++
++	if (mtu->ssusb->dr_mode == USB_DR_MODE_OTG)
++		mtu3_setbits(ibase, SSUSB_U2_CTRL(0), SSUSB_U2_PORT_OTG_SEL);
+ 
+ 	return ssusb_check_clocks(mtu->ssusb, check_clk);
+ }
+@@ -130,7 +132,10 @@ static void mtu3_device_disable(struct mtu3 *mtu)
+ 
+ 	mtu3_setbits(ibase, SSUSB_U2_CTRL(0),
+ 		SSUSB_U2_PORT_DIS | SSUSB_U2_PORT_PDN);
+-	mtu3_clrbits(ibase, SSUSB_U2_CTRL(0), SSUSB_U2_PORT_OTG_SEL);
++
++	if (mtu->ssusb->dr_mode == USB_DR_MODE_OTG)
++		mtu3_clrbits(ibase, SSUSB_U2_CTRL(0), SSUSB_U2_PORT_OTG_SEL);
++
+ 	mtu3_setbits(ibase, U3D_SSUSB_IP_PW_CTRL2, SSUSB_IP_DEV_PDN);
+ }
+ 
+-- 
+2.11.0
+
diff --git a/target/linux/mediatek/patches-4.14/0113-dt-bindings-usb-mtu3-add-a-optional-property-to-disa.patch b/target/linux/mediatek/patches-4.14/0113-dt-bindings-usb-mtu3-add-a-optional-property-to-disa.patch
new file mode 100644
index 0000000000..c45f7d2e1c
--- /dev/null
+++ b/target/linux/mediatek/patches-4.14/0113-dt-bindings-usb-mtu3-add-a-optional-property-to-disa.patch
@@ -0,0 +1,30 @@
+From 6b6f2c178ee2cd57713993e3cf0afbe4effb2578 Mon Sep 17 00:00:00 2001
+From: Chunfeng Yun <chunfeng.yun@mediatek.com>
+Date: Fri, 13 Oct 2017 17:10:47 +0800
+Subject: [PATCH 113/224] dt-bindings: usb: mtu3: add a optional property to
+ disable u3ports
+
+Add a new optional property to disable u3ports
+
+Signed-off-by: Chunfeng Yun <chunfeng.yun@mediatek.com>
+Signed-off-by: Felipe Balbi <felipe.balbi@linux.intel.com>
+---
+ Documentation/devicetree/bindings/usb/mediatek,mtu3.txt | 2 ++
+ 1 file changed, 2 insertions(+)
+
+diff --git a/Documentation/devicetree/bindings/usb/mediatek,mtu3.txt b/Documentation/devicetree/bindings/usb/mediatek,mtu3.txt
+index 49f54767cd21..7c611d14a0a0 100644
+--- a/Documentation/devicetree/bindings/usb/mediatek,mtu3.txt
++++ b/Documentation/devicetree/bindings/usb/mediatek,mtu3.txt
+@@ -44,6 +44,8 @@ Optional properties:
+  - mediatek,enable-wakeup : supports ip sleep wakeup used by host mode
+  - mediatek,syscon-wakeup : phandle to syscon used to access USB wakeup
+ 	control register, it depends on "mediatek,enable-wakeup".
++ - mediatek,u3p-dis-msk : mask to disable u3ports, bit0 for u3port0,
++	bit1 for u3port1, ... etc;
+ 
+ Sub-nodes:
+ The xhci should be added as subnode to mtu3 as shown in the following example
+-- 
+2.11.0
+
diff --git a/target/linux/mediatek/patches-4.14/0114-dt-bindings-usb-mtu3-remove-dummy-clocks-and-add-opt.patch b/target/linux/mediatek/patches-4.14/0114-dt-bindings-usb-mtu3-remove-dummy-clocks-and-add-opt.patch
new file mode 100644
index 0000000000..71e44b31f6
--- /dev/null
+++ b/target/linux/mediatek/patches-4.14/0114-dt-bindings-usb-mtu3-remove-dummy-clocks-and-add-opt.patch
@@ -0,0 +1,46 @@
+From 2c90367440a0dbf9962e7a7f701b0e7a320d325a Mon Sep 17 00:00:00 2001
+From: Chunfeng Yun <chunfeng.yun@mediatek.com>
+Date: Fri, 13 Oct 2017 17:10:48 +0800
+Subject: [PATCH 114/224] dt-bindings: usb: mtu3: remove dummy clocks and add
+ optional ones
+
+Remove dummy clocks for usb wakeup and add optional ones for
+mcu_bus and dma_bus bus.
+
+Signed-off-by: Chunfeng Yun <chunfeng.yun@mediatek.com>
+Signed-off-by: Felipe Balbi <felipe.balbi@linux.intel.com>
+---
+ Documentation/devicetree/bindings/usb/mediatek,mtu3.txt | 10 ++++------
+ 1 file changed, 4 insertions(+), 6 deletions(-)
+
+diff --git a/Documentation/devicetree/bindings/usb/mediatek,mtu3.txt b/Documentation/devicetree/bindings/usb/mediatek,mtu3.txt
+index 7c611d14a0a0..49c982bb5bfc 100644
+--- a/Documentation/devicetree/bindings/usb/mediatek,mtu3.txt
++++ b/Documentation/devicetree/bindings/usb/mediatek,mtu3.txt
+@@ -14,9 +14,9 @@ Required properties:
+  - vusb33-supply : regulator of USB avdd3.3v
+  - clocks : a list of phandle + clock-specifier pairs, one for each
+ 	entry in clock-names
+- - clock-names : must contain "sys_ck" and "ref_ck" for clock of controller;
+-	"wakeup_deb_p0" and "wakeup_deb_p1" are optional, they are
+-	depends on "mediatek,enable-wakeup"
++ - clock-names : must contain "sys_ck" for clock of controller,
++	the following clocks are optional:
++	"ref_ck", "mcu_ck" and "dam_ck";
+  - phys : a list of phandle + phy specifier pairs
+  - dr_mode : should be one of "host", "peripheral" or "otg",
+ 	refer to usb/generic.txt
+@@ -65,9 +65,7 @@ ssusb: usb@11271000 {
+ 	clocks = <&topckgen CLK_TOP_USB30_SEL>, <&clk26m>,
+ 		 <&pericfg CLK_PERI_USB0>,
+ 		 <&pericfg CLK_PERI_USB1>;
+-	clock-names = "sys_ck", "ref_ck",
+-		      "wakeup_deb_p0",
+-		      "wakeup_deb_p1";
++	clock-names = "sys_ck", "ref_ck";
+ 	vusb33-supply = <&mt6397_vusb_reg>;
+ 	vbus-supply = <&usb_p0_vbus>;
+ 	extcon = <&extcon_usb>;
+-- 
+2.11.0
+
diff --git a/target/linux/mediatek/patches-4.14/0115-dt-bindings-usb-mtu3-remove-optional-pinctrls.patch b/target/linux/mediatek/patches-4.14/0115-dt-bindings-usb-mtu3-remove-optional-pinctrls.patch
new file mode 100644
index 0000000000..ea5cf5f8af
--- /dev/null
+++ b/target/linux/mediatek/patches-4.14/0115-dt-bindings-usb-mtu3-remove-optional-pinctrls.patch
@@ -0,0 +1,35 @@
+From df2f0d10213798a806c90bc06db6bed501e7bf7d Mon Sep 17 00:00:00 2001
+From: Chunfeng Yun <chunfeng.yun@mediatek.com>
+Date: Fri, 13 Oct 2017 17:10:49 +0800
+Subject: [PATCH 115/224] dt-bindings: usb: mtu3: remove optional pinctrls
+
+Remove optional pinctrls due to using FORCE/RG_IDDIG to implement
+manual switch function.
+
+Signed-off-by: Chunfeng Yun <chunfeng.yun@mediatek.com>
+Signed-off-by: Felipe Balbi <felipe.balbi@linux.intel.com>
+---
+ Documentation/devicetree/bindings/usb/mediatek,mtu3.txt | 7 ++++---
+ 1 file changed, 4 insertions(+), 3 deletions(-)
+
+diff --git a/Documentation/devicetree/bindings/usb/mediatek,mtu3.txt b/Documentation/devicetree/bindings/usb/mediatek,mtu3.txt
+index 49c982bb5bfc..b2271d8e6b50 100644
+--- a/Documentation/devicetree/bindings/usb/mediatek,mtu3.txt
++++ b/Documentation/devicetree/bindings/usb/mediatek,mtu3.txt
+@@ -30,9 +30,10 @@ Optional properties:
+ 	when supports dual-role mode.
+  - vbus-supply : reference to the VBUS regulator, needed when supports
+ 	dual-role mode.
+- - pinctl-names : a pinctrl state named "default" must be defined,
+-	"id_float" and "id_ground" are optinal which depends on
+-	"mediatek,enable-manual-drd"
++ - pinctrl-names : a pinctrl state named "default" is optional, and need be
++	defined if auto drd switch is enabled, that means the property dr_mode
++	is set as "otg", and meanwhile the property "mediatek,enable-manual-drd"
++	is not set.
+  - pinctrl-0 : pin control group
+ 	See: Documentation/devicetree/bindings/pinctrl/pinctrl-bindings.txt
+ 
+-- 
+2.11.0
+
diff --git a/target/linux/mediatek/patches-4.14/0116-dt-bindings-arm-mediatek-add-MT7622-string-to-the-PM.patch b/target/linux/mediatek/patches-4.14/0116-dt-bindings-arm-mediatek-add-MT7622-string-to-the-PM.patch
new file mode 100644
index 0000000000..540c1273a4
--- /dev/null
+++ b/target/linux/mediatek/patches-4.14/0116-dt-bindings-arm-mediatek-add-MT7622-string-to-the-PM.patch
@@ -0,0 +1,43 @@
+From 1567cde49a0f2304e18c08e2ccd830e0686fc0a7 Mon Sep 17 00:00:00 2001
+From: Sean Wang <sean.wang@mediatek.com>
+Date: Wed, 18 Oct 2017 16:28:42 +0800
+Subject: [PATCH 116/224] dt-bindings: arm: mediatek: add MT7622 string to the
+ PMIC wrapper doc
+
+Signed-off-by: Chenglin Xu <chenglin.xu@mediatek.com>
+Signed-off-by: Sean Wang <sean.wang@mediatek.com>
+Acked-by: Rob Herring <robh@kernel.org>
+Signed-off-by: Matthias Brugger <matthias.bgg@gmail.com>
+---
+ Documentation/devicetree/bindings/soc/mediatek/pwrap.txt | 6 +++++-
+ 1 file changed, 5 insertions(+), 1 deletion(-)
+
+diff --git a/Documentation/devicetree/bindings/soc/mediatek/pwrap.txt b/Documentation/devicetree/bindings/soc/mediatek/pwrap.txt
+index 107700d00df4..bf80e3f96f8c 100644
+--- a/Documentation/devicetree/bindings/soc/mediatek/pwrap.txt
++++ b/Documentation/devicetree/bindings/soc/mediatek/pwrap.txt
+@@ -19,6 +19,7 @@ IP Pairing
+ Required properties in pwrap device node.
+ - compatible:
+ 	"mediatek,mt2701-pwrap" for MT2701/7623 SoCs
++	"mediatek,mt7622-pwrap" for MT7622 SoCs
+ 	"mediatek,mt8135-pwrap" for MT8135 SoCs
+ 	"mediatek,mt8173-pwrap" for MT8173 SoCs
+ - interrupts: IRQ for pwrap in SOC
+@@ -36,9 +37,12 @@ Required properties in pwrap device node.
+ - clocks: Must contain an entry for each entry in clock-names.
+ 
+ Optional properities:
+-- pmic: Mediatek PMIC MFD is the child device of pwrap
++- pmic: Using either MediaTek PMIC MFD as the child device of pwrap
+   See the following for child node definitions:
+   Documentation/devicetree/bindings/mfd/mt6397.txt
++  or the regulator-only device as the child device of pwrap, such as MT6380.
++  See the following definitions for such kinds of devices.
++  Documentation/devicetree/bindings/regulator/mt6380-regulator.txt
+ 
+ Example:
+ 	pwrap: pwrap@1000f000 {
+-- 
+2.11.0
+
diff --git a/target/linux/mediatek/patches-4.14/0117-soc-mediatek-pwrap-add-pwrap_read32-for-reading-in-3.patch b/target/linux/mediatek/patches-4.14/0117-soc-mediatek-pwrap-add-pwrap_read32-for-reading-in-3.patch
new file mode 100644
index 0000000000..c178ddca7a
--- /dev/null
+++ b/target/linux/mediatek/patches-4.14/0117-soc-mediatek-pwrap-add-pwrap_read32-for-reading-in-3.patch
@@ -0,0 +1,139 @@
+From 9c37953bd08daa3ca227098d763e980d1898add3 Mon Sep 17 00:00:00 2001
+From: Sean Wang <sean.wang@mediatek.com>
+Date: Wed, 18 Oct 2017 16:28:43 +0800
+Subject: [PATCH 117/224] soc: mediatek: pwrap: add pwrap_read32 for reading in
+ 32-bit mode
+
+Some regulators such as MediaTek MT6380 has to be read in 32-bit mode.
+So the patch adds pwrap_read32, rename old pwrap_read into pwrap_read16
+and one function pointer is introduced for increasing flexibility allowing
+the determination which mode is used by the pwrap slave detection through
+device tree.
+
+Signed-off-by: Chenglin Xu <chenglin.xu@mediatek.com>
+Signed-off-by: Chen Zhong <chen.zhong@mediatek.com>
+Signed-off-by: Sean Wang <sean.wang@mediatek.com>
+Signed-off-by: Matthias Brugger <matthias.bgg@gmail.com>
+---
+ drivers/soc/mediatek/mtk-pmic-wrap.c | 55 +++++++++++++++++++++++++++++++++++-
+ 1 file changed, 54 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/soc/mediatek/mtk-pmic-wrap.c b/drivers/soc/mediatek/mtk-pmic-wrap.c
+index f095faac1e04..06930e2ebe4c 100644
+--- a/drivers/soc/mediatek/mtk-pmic-wrap.c
++++ b/drivers/soc/mediatek/mtk-pmic-wrap.c
+@@ -487,6 +487,7 @@ static int mt8135_regs[] = {
+ 
+ enum pmic_type {
+ 	PMIC_MT6323,
++	PMIC_MT6380,
+ 	PMIC_MT6397,
+ };
+ 
+@@ -496,9 +497,16 @@ enum pwrap_type {
+ 	PWRAP_MT8173,
+ };
+ 
++struct pmic_wrapper;
+ struct pwrap_slv_type {
+ 	const u32 *dew_regs;
+ 	enum pmic_type type;
++	/*
++	 * pwrap operations are highly associated with the PMIC types,
++	 * so the pointers added increases flexibility allowing determination
++	 * which type is used by the detection through device tree.
++	 */
++	int (*pwrap_read)(struct pmic_wrapper *wrp, u32 adr, u32 *rdata);
+ };
+ 
+ struct pmic_wrapper {
+@@ -609,7 +617,7 @@ static int pwrap_write(struct pmic_wrapper *wrp, u32 adr, u32 wdata)
+ 	return 0;
+ }
+ 
+-static int pwrap_read(struct pmic_wrapper *wrp, u32 adr, u32 *rdata)
++static int pwrap_read16(struct pmic_wrapper *wrp, u32 adr, u32 *rdata)
+ {
+ 	int ret;
+ 
+@@ -632,6 +640,39 @@ static int pwrap_read(struct pmic_wrapper *wrp, u32 adr, u32 *rdata)
+ 	return 0;
+ }
+ 
++static int pwrap_read32(struct pmic_wrapper *wrp, u32 adr, u32 *rdata)
++{
++	int ret, msb;
++
++	*rdata = 0;
++	for (msb = 0; msb < 2; msb++) {
++		ret = pwrap_wait_for_state(wrp, pwrap_is_fsm_idle);
++		if (ret) {
++			pwrap_leave_fsm_vldclr(wrp);
++			return ret;
++		}
++
++		pwrap_writel(wrp, ((msb << 30) | (adr << 16)),
++			     PWRAP_WACS2_CMD);
++
++		ret = pwrap_wait_for_state(wrp, pwrap_is_fsm_vldclr);
++		if (ret)
++			return ret;
++
++		*rdata += (PWRAP_GET_WACS_RDATA(pwrap_readl(wrp,
++			   PWRAP_WACS2_RDATA)) << (16 * msb));
++
++		pwrap_writel(wrp, 1, PWRAP_WACS2_VLDCLR);
++	}
++
++	return 0;
++}
++
++static int pwrap_read(struct pmic_wrapper *wrp, u32 adr, u32 *rdata)
++{
++	return wrp->slave->pwrap_read(wrp, adr, rdata);
++}
++
+ static int pwrap_regmap_read(void *context, u32 adr, u32 *rdata)
+ {
+ 	return pwrap_read(context, adr, rdata);
+@@ -752,6 +793,8 @@ static int pwrap_mt2701_init_reg_clock(struct pmic_wrapper *wrp)
+ 		pwrap_writel(wrp, 0x2, PWRAP_CSLEXT_START);
+ 		pwrap_writel(wrp, 0x2, PWRAP_CSLEXT_END);
+ 		break;
++	default:
++		break;
+ 	}
+ 
+ 	return 0;
+@@ -815,6 +858,8 @@ static int pwrap_init_cipher(struct pmic_wrapper *wrp)
+ 		pwrap_write(wrp, wrp->slave->dew_regs[PWRAP_DEW_CIPHER_EN],
+ 			    0x1);
+ 		break;
++	default:
++		break;
+ 	}
+ 
+ 	/* wait for cipher data ready@AP */
+@@ -1036,11 +1081,19 @@ static const struct regmap_config pwrap_regmap_config = {
+ static const struct pwrap_slv_type pmic_mt6323 = {
+ 	.dew_regs = mt6323_regs,
+ 	.type = PMIC_MT6323,
++	.pwrap_read = pwrap_read16,
++};
++
++static const struct pwrap_slv_type pmic_mt6380 = {
++	.dew_regs = NULL,
++	.type = PMIC_MT6380,
++	.pwrap_read = pwrap_read32,
+ };
+ 
+ static const struct pwrap_slv_type pmic_mt6397 = {
+ 	.dew_regs = mt6397_regs,
+ 	.type = PMIC_MT6397,
++	.pwrap_read = pwrap_read16,
+ };
+ 
+ static const struct of_device_id of_slave_match_tbl[] = {
+-- 
+2.11.0
+
diff --git a/target/linux/mediatek/patches-4.14/0118-soc-mediatek-pwrap-add-pwrap_write32-for-writing-in-.patch b/target/linux/mediatek/patches-4.14/0118-soc-mediatek-pwrap-add-pwrap_write32-for-writing-in-.patch
new file mode 100644
index 0000000000..6048d6e40b
--- /dev/null
+++ b/target/linux/mediatek/patches-4.14/0118-soc-mediatek-pwrap-add-pwrap_write32-for-writing-in-.patch
@@ -0,0 +1,137 @@
+From 635f800995e4ea2a18ce7520d816dab018ce091f Mon Sep 17 00:00:00 2001
+From: Sean Wang <sean.wang@mediatek.com>
+Date: Wed, 18 Oct 2017 16:28:44 +0800
+Subject: [PATCH 118/224] soc: mediatek: pwrap: add pwrap_write32 for writing
+ in 32-bit mode
+
+Some regulators such as MediaTek MT6380 also has to be written in
+32-bit mode. So the patch adds pwrap_write32, rename old pwrap_write
+into pwrap_write16 and one additional function pointer is introduced
+for increasing flexibility allowing the determination which mode is
+used by the pwrap slave detection through device tree.
+
+Signed-off-by: Chenglin Xu <chenglin.xu@mediatek.com>
+Signed-off-by: Chen Zhong <chen.zhong@mediatek.com>
+Signed-off-by: Sean Wang <sean.wang@mediatek.com>
+Signed-off-by: Matthias Brugger <matthias.bgg@gmail.com>
+---
+ drivers/soc/mediatek/mtk-pmic-wrap.c | 70 +++++++++++++++++++++++++++---------
+ 1 file changed, 54 insertions(+), 16 deletions(-)
+
+diff --git a/drivers/soc/mediatek/mtk-pmic-wrap.c b/drivers/soc/mediatek/mtk-pmic-wrap.c
+index 06930e2ebe4c..2d3a8faae124 100644
+--- a/drivers/soc/mediatek/mtk-pmic-wrap.c
++++ b/drivers/soc/mediatek/mtk-pmic-wrap.c
+@@ -507,6 +507,7 @@ struct pwrap_slv_type {
+ 	 * which type is used by the detection through device tree.
+ 	 */
+ 	int (*pwrap_read)(struct pmic_wrapper *wrp, u32 adr, u32 *rdata);
++	int (*pwrap_write)(struct pmic_wrapper *wrp, u32 adr, u32 wdata);
+ };
+ 
+ struct pmic_wrapper {
+@@ -601,22 +602,6 @@ static int pwrap_wait_for_state(struct pmic_wrapper *wrp,
+ 	} while (1);
+ }
+ 
+-static int pwrap_write(struct pmic_wrapper *wrp, u32 adr, u32 wdata)
+-{
+-	int ret;
+-
+-	ret = pwrap_wait_for_state(wrp, pwrap_is_fsm_idle);
+-	if (ret) {
+-		pwrap_leave_fsm_vldclr(wrp);
+-		return ret;
+-	}
+-
+-	pwrap_writel(wrp, (1 << 31) | ((adr >> 1) << 16) | wdata,
+-			PWRAP_WACS2_CMD);
+-
+-	return 0;
+-}
+-
+ static int pwrap_read16(struct pmic_wrapper *wrp, u32 adr, u32 *rdata)
+ {
+ 	int ret;
+@@ -673,6 +658,56 @@ static int pwrap_read(struct pmic_wrapper *wrp, u32 adr, u32 *rdata)
+ 	return wrp->slave->pwrap_read(wrp, adr, rdata);
+ }
+ 
++static int pwrap_write16(struct pmic_wrapper *wrp, u32 adr, u32 wdata)
++{
++	int ret;
++
++	ret = pwrap_wait_for_state(wrp, pwrap_is_fsm_idle);
++	if (ret) {
++		pwrap_leave_fsm_vldclr(wrp);
++		return ret;
++	}
++
++	pwrap_writel(wrp, (1 << 31) | ((adr >> 1) << 16) | wdata,
++		     PWRAP_WACS2_CMD);
++
++	return 0;
++}
++
++static int pwrap_write32(struct pmic_wrapper *wrp, u32 adr, u32 wdata)
++{
++	int ret, msb, rdata;
++
++	for (msb = 0; msb < 2; msb++) {
++		ret = pwrap_wait_for_state(wrp, pwrap_is_fsm_idle);
++		if (ret) {
++			pwrap_leave_fsm_vldclr(wrp);
++			return ret;
++		}
++
++		pwrap_writel(wrp, (1 << 31) | (msb << 30) | (adr << 16) |
++			     ((wdata >> (msb * 16)) & 0xffff),
++			     PWRAP_WACS2_CMD);
++
++		/*
++		 * The pwrap_read operation is the requirement of hardware used
++		 * for the synchronization between two successive 16-bit
++		 * pwrap_writel operations composing one 32-bit bus writing.
++		 * Otherwise, we'll find the result fails on the lower 16-bit
++		 * pwrap writing.
++		 */
++		if (!msb)
++			pwrap_read(wrp, adr, &rdata);
++	}
++
++	return 0;
++}
++
++static int pwrap_write(struct pmic_wrapper *wrp, u32 adr, u32 wdata)
++{
++	return wrp->slave->pwrap_write(wrp, adr, wdata);
++}
++
+ static int pwrap_regmap_read(void *context, u32 adr, u32 *rdata)
+ {
+ 	return pwrap_read(context, adr, rdata);
+@@ -1082,18 +1117,21 @@ static const struct pwrap_slv_type pmic_mt6323 = {
+ 	.dew_regs = mt6323_regs,
+ 	.type = PMIC_MT6323,
+ 	.pwrap_read = pwrap_read16,
++	.pwrap_write = pwrap_write16,
+ };
+ 
+ static const struct pwrap_slv_type pmic_mt6380 = {
+ 	.dew_regs = NULL,
+ 	.type = PMIC_MT6380,
+ 	.pwrap_read = pwrap_read32,
++	.pwrap_write = pwrap_write32,
+ };
+ 
+ static const struct pwrap_slv_type pmic_mt6397 = {
+ 	.dew_regs = mt6397_regs,
+ 	.type = PMIC_MT6397,
+ 	.pwrap_read = pwrap_read16,
++	.pwrap_write = pwrap_write16,
+ };
+ 
+ static const struct of_device_id of_slave_match_tbl[] = {
+-- 
+2.11.0
+
diff --git a/target/linux/mediatek/patches-4.14/0119-soc-mediatek-pwrap-refactor-pwrap_init-for-the-vario.patch b/target/linux/mediatek/patches-4.14/0119-soc-mediatek-pwrap-refactor-pwrap_init-for-the-vario.patch
new file mode 100644
index 0000000000..c730fb1eec
--- /dev/null
+++ b/target/linux/mediatek/patches-4.14/0119-soc-mediatek-pwrap-refactor-pwrap_init-for-the-vario.patch
@@ -0,0 +1,232 @@
+From 16bebe4ad52083316907fb7149c797cd331f5948 Mon Sep 17 00:00:00 2001
+From: Sean Wang <sean.wang@mediatek.com>
+Date: Wed, 18 Oct 2017 16:28:45 +0800
+Subject: [PATCH 119/224] soc: mediatek: pwrap: refactor pwrap_init for the
+ various PMIC types
+
+pwrap initialization is highly associated with the base SoC and the
+target PMICs, so slight refactorization is made here for allowing
+pwrap_init to run on those PMICs with different capability from the
+previous MediaTek PMICs and the determination for the enablement of the
+pwrap capability depending on PMIC type. Apart from this, the patch
+makes the driver more extensible especially when more PMICs join into
+the pwrap driver.
+
+Signed-off-by: Chenglin Xu <chenglin.xu@mediatek.com>
+Signed-off-by: Sean Wang <sean.wang@mediatek.com>
+Signed-off-by: Matthias Brugger <matthias.bgg@gmail.com>
+---
+ drivers/soc/mediatek/mtk-pmic-wrap.c | 130 ++++++++++++++++++++++++-----------
+ 1 file changed, 90 insertions(+), 40 deletions(-)
+
+diff --git a/drivers/soc/mediatek/mtk-pmic-wrap.c b/drivers/soc/mediatek/mtk-pmic-wrap.c
+index 2d3a8faae124..e3398e37a7a6 100644
+--- a/drivers/soc/mediatek/mtk-pmic-wrap.c
++++ b/drivers/soc/mediatek/mtk-pmic-wrap.c
+@@ -70,6 +70,12 @@
+ 					  PWRAP_WDT_SRC_EN_HARB_STAUPD_DLE | \
+ 					  PWRAP_WDT_SRC_EN_HARB_STAUPD_ALE)
+ 
++/* Group of bits used for shown slave capability */
++#define PWRAP_SLV_CAP_SPI	BIT(0)
++#define PWRAP_SLV_CAP_DUALIO	BIT(1)
++#define PWRAP_SLV_CAP_SECURITY	BIT(2)
++#define HAS_CAP(_c, _x)	(((_c) & (_x)) == (_x))
++
+ /* defines for slave device wrapper registers */
+ enum dew_regs {
+ 	PWRAP_DEW_BASE,
+@@ -501,6 +507,8 @@ struct pmic_wrapper;
+ struct pwrap_slv_type {
+ 	const u32 *dew_regs;
+ 	enum pmic_type type;
++	/* Flags indicating the capability for the target slave */
++	u32 caps;
+ 	/*
+ 	 * pwrap operations are highly associated with the PMIC types,
+ 	 * so the pointers added increases flexibility allowing determination
+@@ -787,6 +795,37 @@ static int pwrap_init_sidly(struct pmic_wrapper *wrp)
+ 	return 0;
+ }
+ 
++static int pwrap_init_dual_io(struct pmic_wrapper *wrp)
++{
++	int ret;
++	u32 rdata;
++
++	/* Enable dual IO mode */
++	pwrap_write(wrp, wrp->slave->dew_regs[PWRAP_DEW_DIO_EN], 1);
++
++	/* Check IDLE & INIT_DONE in advance */
++	ret = pwrap_wait_for_state(wrp,
++				   pwrap_is_fsm_idle_and_sync_idle);
++	if (ret) {
++		dev_err(wrp->dev, "%s fail, ret=%d\n", __func__, ret);
++		return ret;
++	}
++
++	pwrap_writel(wrp, 1, PWRAP_DIO_EN);
++
++	/* Read Test */
++	pwrap_read(wrp,
++		   wrp->slave->dew_regs[PWRAP_DEW_READ_TEST], &rdata);
++	if (rdata != PWRAP_DEW_READ_TEST_VAL) {
++		dev_err(wrp->dev,
++			"Read failed on DIO mode: 0x%04x!=0x%04x\n",
++			PWRAP_DEW_READ_TEST_VAL, rdata);
++		return -EFAULT;
++	}
++
++	return 0;
++}
++
+ static int pwrap_mt8135_init_reg_clock(struct pmic_wrapper *wrp)
+ {
+ 	pwrap_writel(wrp, 0x4, PWRAP_CSHEXT);
+@@ -935,6 +974,30 @@ static int pwrap_init_cipher(struct pmic_wrapper *wrp)
+ 	return 0;
+ }
+ 
++static int pwrap_init_security(struct pmic_wrapper *wrp)
++{
++	int ret;
++
++	/* Enable encryption */
++	ret = pwrap_init_cipher(wrp);
++	if (ret)
++		return ret;
++
++	/* Signature checking - using CRC */
++	if (pwrap_write(wrp,
++			wrp->slave->dew_regs[PWRAP_DEW_CRC_EN], 0x1))
++		return -EFAULT;
++
++	pwrap_writel(wrp, 0x1, PWRAP_CRC_EN);
++	pwrap_writel(wrp, 0x0, PWRAP_SIG_MODE);
++	pwrap_writel(wrp, wrp->slave->dew_regs[PWRAP_DEW_CRC_VAL],
++		     PWRAP_SIG_ADR);
++	pwrap_writel(wrp,
++		     wrp->master->arb_en_all, PWRAP_HIPRIO_ARB_EN);
++
++	return 0;
++}
++
+ static int pwrap_mt8135_init_soc_specific(struct pmic_wrapper *wrp)
+ {
+ 	/* enable pwrap events and pwrap bridge in AP side */
+@@ -995,7 +1058,6 @@ static int pwrap_mt2701_init_soc_specific(struct pmic_wrapper *wrp)
+ static int pwrap_init(struct pmic_wrapper *wrp)
+ {
+ 	int ret;
+-	u32 rdata;
+ 
+ 	reset_control_reset(wrp->rstc);
+ 	if (wrp->rstc_bridge)
+@@ -1007,10 +1069,12 @@ static int pwrap_init(struct pmic_wrapper *wrp)
+ 		pwrap_writel(wrp, 0, PWRAP_DCM_DBC_PRD);
+ 	}
+ 
+-	/* Reset SPI slave */
+-	ret = pwrap_reset_spislave(wrp);
+-	if (ret)
+-		return ret;
++	if (HAS_CAP(wrp->slave->caps, PWRAP_SLV_CAP_SPI)) {
++		/* Reset SPI slave */
++		ret = pwrap_reset_spislave(wrp);
++		if (ret)
++			return ret;
++	}
+ 
+ 	pwrap_writel(wrp, 1, PWRAP_WRAP_EN);
+ 
+@@ -1022,45 +1086,26 @@ static int pwrap_init(struct pmic_wrapper *wrp)
+ 	if (ret)
+ 		return ret;
+ 
+-	/* Setup serial input delay */
+-	ret = pwrap_init_sidly(wrp);
+-	if (ret)
+-		return ret;
+-
+-	/* Enable dual IO mode */
+-	pwrap_write(wrp, wrp->slave->dew_regs[PWRAP_DEW_DIO_EN], 1);
+-
+-	/* Check IDLE & INIT_DONE in advance */
+-	ret = pwrap_wait_for_state(wrp, pwrap_is_fsm_idle_and_sync_idle);
+-	if (ret) {
+-		dev_err(wrp->dev, "%s fail, ret=%d\n", __func__, ret);
+-		return ret;
++	if (HAS_CAP(wrp->slave->caps, PWRAP_SLV_CAP_SPI)) {
++		/* Setup serial input delay */
++		ret = pwrap_init_sidly(wrp);
++		if (ret)
++			return ret;
+ 	}
+ 
+-	pwrap_writel(wrp, 1, PWRAP_DIO_EN);
+-
+-	/* Read Test */
+-	pwrap_read(wrp, wrp->slave->dew_regs[PWRAP_DEW_READ_TEST], &rdata);
+-	if (rdata != PWRAP_DEW_READ_TEST_VAL) {
+-		dev_err(wrp->dev, "Read test failed after switch to DIO mode: 0x%04x != 0x%04x\n",
+-				PWRAP_DEW_READ_TEST_VAL, rdata);
+-		return -EFAULT;
++	if (HAS_CAP(wrp->slave->caps, PWRAP_SLV_CAP_DUALIO)) {
++		/* Enable dual I/O mode */
++		ret = pwrap_init_dual_io(wrp);
++		if (ret)
++			return ret;
+ 	}
+ 
+-	/* Enable encryption */
+-	ret = pwrap_init_cipher(wrp);
+-	if (ret)
+-		return ret;
+-
+-	/* Signature checking - using CRC */
+-	if (pwrap_write(wrp, wrp->slave->dew_regs[PWRAP_DEW_CRC_EN], 0x1))
+-		return -EFAULT;
+-
+-	pwrap_writel(wrp, 0x1, PWRAP_CRC_EN);
+-	pwrap_writel(wrp, 0x0, PWRAP_SIG_MODE);
+-	pwrap_writel(wrp, wrp->slave->dew_regs[PWRAP_DEW_CRC_VAL],
+-		     PWRAP_SIG_ADR);
+-	pwrap_writel(wrp, wrp->master->arb_en_all, PWRAP_HIPRIO_ARB_EN);
++	if (HAS_CAP(wrp->slave->caps, PWRAP_SLV_CAP_SECURITY)) {
++		/* Enable security on bus */
++		ret = pwrap_init_security(wrp);
++		if (ret)
++			return ret;
++	}
+ 
+ 	if (wrp->master->type == PWRAP_MT8135)
+ 		pwrap_writel(wrp, 0x7, PWRAP_RRARB_EN);
+@@ -1116,6 +1161,8 @@ static const struct regmap_config pwrap_regmap_config = {
+ static const struct pwrap_slv_type pmic_mt6323 = {
+ 	.dew_regs = mt6323_regs,
+ 	.type = PMIC_MT6323,
++	.caps = PWRAP_SLV_CAP_SPI | PWRAP_SLV_CAP_DUALIO |
++		PWRAP_SLV_CAP_SECURITY,
+ 	.pwrap_read = pwrap_read16,
+ 	.pwrap_write = pwrap_write16,
+ };
+@@ -1123,6 +1170,7 @@ static const struct pwrap_slv_type pmic_mt6323 = {
+ static const struct pwrap_slv_type pmic_mt6380 = {
+ 	.dew_regs = NULL,
+ 	.type = PMIC_MT6380,
++	.caps = 0,
+ 	.pwrap_read = pwrap_read32,
+ 	.pwrap_write = pwrap_write32,
+ };
+@@ -1130,6 +1178,8 @@ static const struct pwrap_slv_type pmic_mt6380 = {
+ static const struct pwrap_slv_type pmic_mt6397 = {
+ 	.dew_regs = mt6397_regs,
+ 	.type = PMIC_MT6397,
++	.caps = PWRAP_SLV_CAP_SPI | PWRAP_SLV_CAP_DUALIO |
++		PWRAP_SLV_CAP_SECURITY,
+ 	.pwrap_read = pwrap_read16,
+ 	.pwrap_write = pwrap_write16,
+ };
+-- 
+2.11.0
+
diff --git a/target/linux/mediatek/patches-4.14/0120-soc-mediatek-pwrap-add-MediaTek-MT6380-as-one-slave-.patch b/target/linux/mediatek/patches-4.14/0120-soc-mediatek-pwrap-add-MediaTek-MT6380-as-one-slave-.patch
new file mode 100644
index 0000000000..532c42c40c
--- /dev/null
+++ b/target/linux/mediatek/patches-4.14/0120-soc-mediatek-pwrap-add-MediaTek-MT6380-as-one-slave-.patch
@@ -0,0 +1,103 @@
+From 81c54afc5bc918ea3ed65cc356236b302b1f21ca Mon Sep 17 00:00:00 2001
+From: Sean Wang <sean.wang@mediatek.com>
+Date: Wed, 18 Oct 2017 16:28:46 +0800
+Subject: [PATCH 120/224] soc: mediatek: pwrap: add MediaTek MT6380 as one
+ slave of pwrap
+
+Add MediaTek MT6380 regulator becoming one of PMIC wrapper slave
+and also add extra new regmap_config of 32-bit mode for MT6380
+since old regmap_config of 16-bit mode can't be fit into the need.
+
+Signed-off-by: Chenglin Xu <chenglin.xu@mediatek.com>
+Signed-off-by: Chen Zhong <chen.zhong@mediatek.com>
+Signed-off-by: Sean Wang <sean.wang@mediatek.com>
+Signed-off-by: Matthias Brugger <matthias.bgg@gmail.com>
+---
+ drivers/soc/mediatek/mtk-pmic-wrap.c | 24 +++++++++++++++++++++---
+ 1 file changed, 21 insertions(+), 3 deletions(-)
+
+diff --git a/drivers/soc/mediatek/mtk-pmic-wrap.c b/drivers/soc/mediatek/mtk-pmic-wrap.c
+index e3398e37a7a6..45c3e44d8f40 100644
+--- a/drivers/soc/mediatek/mtk-pmic-wrap.c
++++ b/drivers/soc/mediatek/mtk-pmic-wrap.c
+@@ -507,6 +507,7 @@ struct pmic_wrapper;
+ struct pwrap_slv_type {
+ 	const u32 *dew_regs;
+ 	enum pmic_type type;
++	const struct regmap_config *regmap;
+ 	/* Flags indicating the capability for the target slave */
+ 	u32 caps;
+ 	/*
+@@ -1149,7 +1150,7 @@ static irqreturn_t pwrap_interrupt(int irqno, void *dev_id)
+ 	return IRQ_HANDLED;
+ }
+ 
+-static const struct regmap_config pwrap_regmap_config = {
++static const struct regmap_config pwrap_regmap_config16 = {
+ 	.reg_bits = 16,
+ 	.val_bits = 16,
+ 	.reg_stride = 2,
+@@ -1158,9 +1159,19 @@ static const struct regmap_config pwrap_regmap_config = {
+ 	.max_register = 0xffff,
+ };
+ 
++static const struct regmap_config pwrap_regmap_config32 = {
++	.reg_bits = 32,
++	.val_bits = 32,
++	.reg_stride = 4,
++	.reg_read = pwrap_regmap_read,
++	.reg_write = pwrap_regmap_write,
++	.max_register = 0xffff,
++};
++
+ static const struct pwrap_slv_type pmic_mt6323 = {
+ 	.dew_regs = mt6323_regs,
+ 	.type = PMIC_MT6323,
++	.regmap = &pwrap_regmap_config16,
+ 	.caps = PWRAP_SLV_CAP_SPI | PWRAP_SLV_CAP_DUALIO |
+ 		PWRAP_SLV_CAP_SECURITY,
+ 	.pwrap_read = pwrap_read16,
+@@ -1170,6 +1181,7 @@ static const struct pwrap_slv_type pmic_mt6323 = {
+ static const struct pwrap_slv_type pmic_mt6380 = {
+ 	.dew_regs = NULL,
+ 	.type = PMIC_MT6380,
++	.regmap = &pwrap_regmap_config32,
+ 	.caps = 0,
+ 	.pwrap_read = pwrap_read32,
+ 	.pwrap_write = pwrap_write32,
+@@ -1178,6 +1190,7 @@ static const struct pwrap_slv_type pmic_mt6380 = {
+ static const struct pwrap_slv_type pmic_mt6397 = {
+ 	.dew_regs = mt6397_regs,
+ 	.type = PMIC_MT6397,
++	.regmap = &pwrap_regmap_config16,
+ 	.caps = PWRAP_SLV_CAP_SPI | PWRAP_SLV_CAP_DUALIO |
+ 		PWRAP_SLV_CAP_SECURITY,
+ 	.pwrap_read = pwrap_read16,
+@@ -1189,9 +1202,14 @@ static const struct of_device_id of_slave_match_tbl[] = {
+ 		.compatible = "mediatek,mt6323",
+ 		.data = &pmic_mt6323,
+ 	}, {
++		/* The MT6380 PMIC only implements a regulator, so we bind it
++		 * directly instead of using a MFD.
++		 */
++		.compatible = "mediatek,mt6380-regulator",
++		.data = &pmic_mt6380,
++	}, {
+ 		.compatible = "mediatek,mt6397",
+ 		.data = &pmic_mt6397,
+-	}, {
+ 		/* sentinel */
+ 	}
+ };
+@@ -1372,7 +1390,7 @@ static int pwrap_probe(struct platform_device *pdev)
+ 	if (ret)
+ 		goto err_out2;
+ 
+-	wrp->regmap = devm_regmap_init(wrp->dev, NULL, wrp, &pwrap_regmap_config);
++	wrp->regmap = devm_regmap_init(wrp->dev, NULL, wrp, wrp->slave->regmap);
+ 	if (IS_ERR(wrp->regmap)) {
+ 		ret = PTR_ERR(wrp->regmap);
+ 		goto err_out2;
+-- 
+2.11.0
+
diff --git a/target/linux/mediatek/patches-4.14/0121-soc-mediatek-pwrap-add-common-way-for-setup-CS-timin.patch b/target/linux/mediatek/patches-4.14/0121-soc-mediatek-pwrap-add-common-way-for-setup-CS-timin.patch
new file mode 100644
index 0000000000..cab2178e2b
--- /dev/null
+++ b/target/linux/mediatek/patches-4.14/0121-soc-mediatek-pwrap-add-common-way-for-setup-CS-timin.patch
@@ -0,0 +1,124 @@
+From 442c890727e0f585154662b0908fbe3a7986052a Mon Sep 17 00:00:00 2001
+From: Sean Wang <sean.wang@mediatek.com>
+Date: Wed, 18 Oct 2017 16:28:47 +0800
+Subject: [PATCH 121/224] soc: mediatek: pwrap: add common way for setup CS
+ timing extenstion
+
+Multiple platforms would always use their own way handling CS timing
+extension on the bus which leads to a little bit code duplication.
+Therefore, the patch groups the similar logic to handle CS timing
+extension into the common function which allows the following SoCs
+have more reusability for configing CS timing.
+
+Signed-off-by: Chenglin Xu <chenglin.xu@mediatek.com>
+Signed-off-by: Sean Wang <sean.wang@mediatek.com>
+Signed-off-by: Matthias Brugger <matthias.bgg@gmail.com>
+---
+ drivers/soc/mediatek/mtk-pmic-wrap.c | 59 ++++++++++++++++++++++--------------
+ 1 file changed, 37 insertions(+), 22 deletions(-)
+
+diff --git a/drivers/soc/mediatek/mtk-pmic-wrap.c b/drivers/soc/mediatek/mtk-pmic-wrap.c
+index 45c3e44d8f40..cbc3f0e82337 100644
+--- a/drivers/soc/mediatek/mtk-pmic-wrap.c
++++ b/drivers/soc/mediatek/mtk-pmic-wrap.c
+@@ -827,23 +827,44 @@ static int pwrap_init_dual_io(struct pmic_wrapper *wrp)
+ 	return 0;
+ }
+ 
+-static int pwrap_mt8135_init_reg_clock(struct pmic_wrapper *wrp)
++/*
++ * pwrap_init_chip_select_ext is used to configure CS extension time for each
++ * phase during data transactions on the pwrap bus.
++ */
++static void pwrap_init_chip_select_ext(struct pmic_wrapper *wrp, u8 hext_write,
++				       u8 hext_read, u8 lext_start,
++				       u8 lext_end)
+ {
+-	pwrap_writel(wrp, 0x4, PWRAP_CSHEXT);
+-	pwrap_writel(wrp, 0x0, PWRAP_CSHEXT_WRITE);
+-	pwrap_writel(wrp, 0x4, PWRAP_CSHEXT_READ);
+-	pwrap_writel(wrp, 0x0, PWRAP_CSLEXT_START);
+-	pwrap_writel(wrp, 0x0, PWRAP_CSLEXT_END);
++	/*
++	 * After finishing a write and read transaction, extends CS high time
++	 * to be at least xT of BUS CLK as hext_write and hext_read specifies
++	 * respectively.
++	 */
++	pwrap_writel(wrp, hext_write, PWRAP_CSHEXT_WRITE);
++	pwrap_writel(wrp, hext_read, PWRAP_CSHEXT_READ);
+ 
+-	return 0;
++	/*
++	 * Extends CS low time after CSL and before CSH command to be at
++	 * least xT of BUS CLK as lext_start and lext_end specifies
++	 * respectively.
++	 */
++	pwrap_writel(wrp, lext_start, PWRAP_CSLEXT_START);
++	pwrap_writel(wrp, lext_end, PWRAP_CSLEXT_END);
+ }
+ 
+-static int pwrap_mt8173_init_reg_clock(struct pmic_wrapper *wrp)
++static int pwrap_common_init_reg_clock(struct pmic_wrapper *wrp)
+ {
+-	pwrap_writel(wrp, 0x0, PWRAP_CSHEXT_WRITE);
+-	pwrap_writel(wrp, 0x4, PWRAP_CSHEXT_READ);
+-	pwrap_writel(wrp, 0x2, PWRAP_CSLEXT_START);
+-	pwrap_writel(wrp, 0x2, PWRAP_CSLEXT_END);
++	switch (wrp->master->type) {
++	case PWRAP_MT8173:
++		pwrap_init_chip_select_ext(wrp, 0, 4, 2, 2);
++		break;
++	case PWRAP_MT8135:
++		pwrap_writel(wrp, 0x4, PWRAP_CSHEXT);
++		pwrap_init_chip_select_ext(wrp, 0, 4, 0, 0);
++		break;
++	default:
++		break;
++	}
+ 
+ 	return 0;
+ }
+@@ -853,20 +874,14 @@ static int pwrap_mt2701_init_reg_clock(struct pmic_wrapper *wrp)
+ 	switch (wrp->slave->type) {
+ 	case PMIC_MT6397:
+ 		pwrap_writel(wrp, 0xc, PWRAP_RDDMY);
+-		pwrap_writel(wrp, 0x4, PWRAP_CSHEXT_WRITE);
+-		pwrap_writel(wrp, 0x0, PWRAP_CSHEXT_READ);
+-		pwrap_writel(wrp, 0x2, PWRAP_CSLEXT_START);
+-		pwrap_writel(wrp, 0x2, PWRAP_CSLEXT_END);
++		pwrap_init_chip_select_ext(wrp, 4, 0, 2, 2);
+ 		break;
+ 
+ 	case PMIC_MT6323:
+ 		pwrap_writel(wrp, 0x8, PWRAP_RDDMY);
+ 		pwrap_write(wrp, wrp->slave->dew_regs[PWRAP_DEW_RDDMY_NO],
+ 			    0x8);
+-		pwrap_writel(wrp, 0x5, PWRAP_CSHEXT_WRITE);
+-		pwrap_writel(wrp, 0x0, PWRAP_CSHEXT_READ);
+-		pwrap_writel(wrp, 0x2, PWRAP_CSLEXT_START);
+-		pwrap_writel(wrp, 0x2, PWRAP_CSLEXT_END);
++		pwrap_init_chip_select_ext(wrp, 5, 0, 2, 2);
+ 		break;
+ 	default:
+ 		break;
+@@ -1235,7 +1250,7 @@ static const struct pmic_wrapper_type pwrap_mt8135 = {
+ 	.spi_w = PWRAP_MAN_CMD_SPI_WRITE,
+ 	.wdt_src = PWRAP_WDT_SRC_MASK_ALL,
+ 	.has_bridge = 1,
+-	.init_reg_clock = pwrap_mt8135_init_reg_clock,
++	.init_reg_clock = pwrap_common_init_reg_clock,
+ 	.init_soc_specific = pwrap_mt8135_init_soc_specific,
+ };
+ 
+@@ -1247,7 +1262,7 @@ static const struct pmic_wrapper_type pwrap_mt8173 = {
+ 	.spi_w = PWRAP_MAN_CMD_SPI_WRITE,
+ 	.wdt_src = PWRAP_WDT_SRC_MASK_NO_STAUPD,
+ 	.has_bridge = 0,
+-	.init_reg_clock = pwrap_mt8173_init_reg_clock,
++	.init_reg_clock = pwrap_common_init_reg_clock,
+ 	.init_soc_specific = pwrap_mt8173_init_soc_specific,
+ };
+ 
+-- 
+2.11.0
+
diff --git a/target/linux/mediatek/patches-4.14/0122-soc-mediatek-pwrap-add-support-for-MT7622-SoC.patch b/target/linux/mediatek/patches-4.14/0122-soc-mediatek-pwrap-add-support-for-MT7622-SoC.patch
new file mode 100644
index 0000000000..6556444108
--- /dev/null
+++ b/target/linux/mediatek/patches-4.14/0122-soc-mediatek-pwrap-add-support-for-MT7622-SoC.patch
@@ -0,0 +1,242 @@
+From 87996dabef0d83bbd2ed5264b83b01224bc42968 Mon Sep 17 00:00:00 2001
+From: Chenglin Xu <chenglin.xu@mediatek.com>
+Date: Wed, 18 Oct 2017 16:28:48 +0800
+Subject: [PATCH 122/224] soc: mediatek: pwrap: add support for MT7622 SoC
+
+Add the registers, callbacks and data structures required to make the
+PMIC wrapper work on MT7622.
+
+Signed-off-by: Chenglin Xu <chenglin.xu@mediatek.com>
+Signed-off-by: Chen Zhong <chen.zhong@mediatek.com>
+Signed-off-by: Sean Wang <sean.wang@mediatek.com>
+Signed-off-by: Matthias Brugger <matthias.bgg@gmail.com>
+---
+ drivers/soc/mediatek/mtk-pmic-wrap.c | 170 +++++++++++++++++++++++++++++++++++
+ 1 file changed, 170 insertions(+)
+
+diff --git a/drivers/soc/mediatek/mtk-pmic-wrap.c b/drivers/soc/mediatek/mtk-pmic-wrap.c
+index cbc3f0e82337..5d61d127e1d7 100644
+--- a/drivers/soc/mediatek/mtk-pmic-wrap.c
++++ b/drivers/soc/mediatek/mtk-pmic-wrap.c
+@@ -214,6 +214,36 @@ enum pwrap_regs {
+ 	PWRAP_ADC_RDATA_ADDR1,
+ 	PWRAP_ADC_RDATA_ADDR2,
+ 
++	/* MT7622 only regs */
++	PWRAP_EINT_STA0_ADR,
++	PWRAP_EINT_STA1_ADR,
++	PWRAP_STA,
++	PWRAP_CLR,
++	PWRAP_DVFS_ADR8,
++	PWRAP_DVFS_WDATA8,
++	PWRAP_DVFS_ADR9,
++	PWRAP_DVFS_WDATA9,
++	PWRAP_DVFS_ADR10,
++	PWRAP_DVFS_WDATA10,
++	PWRAP_DVFS_ADR11,
++	PWRAP_DVFS_WDATA11,
++	PWRAP_DVFS_ADR12,
++	PWRAP_DVFS_WDATA12,
++	PWRAP_DVFS_ADR13,
++	PWRAP_DVFS_WDATA13,
++	PWRAP_DVFS_ADR14,
++	PWRAP_DVFS_WDATA14,
++	PWRAP_DVFS_ADR15,
++	PWRAP_DVFS_WDATA15,
++	PWRAP_EXT_CK,
++	PWRAP_ADC_RDATA_ADDR,
++	PWRAP_GPS_STA,
++	PWRAP_SW_RST,
++	PWRAP_DVFS_STEP_CTRL0,
++	PWRAP_DVFS_STEP_CTRL1,
++	PWRAP_DVFS_STEP_CTRL2,
++	PWRAP_SPI2_CTRL,
++
+ 	/* MT8135 only regs */
+ 	PWRAP_CSHEXT,
+ 	PWRAP_EVENT_IN_EN,
+@@ -336,6 +366,118 @@ static int mt2701_regs[] = {
+ 	[PWRAP_ADC_RDATA_ADDR2] =	0x154,
+ };
+ 
++static int mt7622_regs[] = {
++	[PWRAP_MUX_SEL] =		0x0,
++	[PWRAP_WRAP_EN] =		0x4,
++	[PWRAP_DIO_EN] =		0x8,
++	[PWRAP_SIDLY] =			0xC,
++	[PWRAP_RDDMY] =			0x10,
++	[PWRAP_SI_CK_CON] =		0x14,
++	[PWRAP_CSHEXT_WRITE] =		0x18,
++	[PWRAP_CSHEXT_READ] =		0x1C,
++	[PWRAP_CSLEXT_START] =		0x20,
++	[PWRAP_CSLEXT_END] =		0x24,
++	[PWRAP_STAUPD_PRD] =		0x28,
++	[PWRAP_STAUPD_GRPEN] =		0x2C,
++	[PWRAP_EINT_STA0_ADR] =		0x30,
++	[PWRAP_EINT_STA1_ADR] =		0x34,
++	[PWRAP_STA] =			0x38,
++	[PWRAP_CLR] =			0x3C,
++	[PWRAP_STAUPD_MAN_TRIG] =	0x40,
++	[PWRAP_STAUPD_STA] =		0x44,
++	[PWRAP_WRAP_STA] =		0x48,
++	[PWRAP_HARB_INIT] =		0x4C,
++	[PWRAP_HARB_HPRIO] =		0x50,
++	[PWRAP_HIPRIO_ARB_EN] =		0x54,
++	[PWRAP_HARB_STA0] =		0x58,
++	[PWRAP_HARB_STA1] =		0x5C,
++	[PWRAP_MAN_EN] =		0x60,
++	[PWRAP_MAN_CMD] =		0x64,
++	[PWRAP_MAN_RDATA] =		0x68,
++	[PWRAP_MAN_VLDCLR] =		0x6C,
++	[PWRAP_WACS0_EN] =		0x70,
++	[PWRAP_INIT_DONE0] =		0x74,
++	[PWRAP_WACS0_CMD] =		0x78,
++	[PWRAP_WACS0_RDATA] =		0x7C,
++	[PWRAP_WACS0_VLDCLR] =		0x80,
++	[PWRAP_WACS1_EN] =		0x84,
++	[PWRAP_INIT_DONE1] =		0x88,
++	[PWRAP_WACS1_CMD] =		0x8C,
++	[PWRAP_WACS1_RDATA] =		0x90,
++	[PWRAP_WACS1_VLDCLR] =		0x94,
++	[PWRAP_WACS2_EN] =		0x98,
++	[PWRAP_INIT_DONE2] =		0x9C,
++	[PWRAP_WACS2_CMD] =		0xA0,
++	[PWRAP_WACS2_RDATA] =		0xA4,
++	[PWRAP_WACS2_VLDCLR] =		0xA8,
++	[PWRAP_INT_EN] =		0xAC,
++	[PWRAP_INT_FLG_RAW] =		0xB0,
++	[PWRAP_INT_FLG] =		0xB4,
++	[PWRAP_INT_CLR] =		0xB8,
++	[PWRAP_SIG_ADR] =		0xBC,
++	[PWRAP_SIG_MODE] =		0xC0,
++	[PWRAP_SIG_VALUE] =		0xC4,
++	[PWRAP_SIG_ERRVAL] =		0xC8,
++	[PWRAP_CRC_EN] =		0xCC,
++	[PWRAP_TIMER_EN] =		0xD0,
++	[PWRAP_TIMER_STA] =		0xD4,
++	[PWRAP_WDT_UNIT] =		0xD8,
++	[PWRAP_WDT_SRC_EN] =		0xDC,
++	[PWRAP_WDT_FLG] =		0xE0,
++	[PWRAP_DEBUG_INT_SEL] =		0xE4,
++	[PWRAP_DVFS_ADR0] =		0xE8,
++	[PWRAP_DVFS_WDATA0] =		0xEC,
++	[PWRAP_DVFS_ADR1] =		0xF0,
++	[PWRAP_DVFS_WDATA1] =		0xF4,
++	[PWRAP_DVFS_ADR2] =		0xF8,
++	[PWRAP_DVFS_WDATA2] =		0xFC,
++	[PWRAP_DVFS_ADR3] =		0x100,
++	[PWRAP_DVFS_WDATA3] =		0x104,
++	[PWRAP_DVFS_ADR4] =		0x108,
++	[PWRAP_DVFS_WDATA4] =		0x10C,
++	[PWRAP_DVFS_ADR5] =		0x110,
++	[PWRAP_DVFS_WDATA5] =		0x114,
++	[PWRAP_DVFS_ADR6] =		0x118,
++	[PWRAP_DVFS_WDATA6] =		0x11C,
++	[PWRAP_DVFS_ADR7] =		0x120,
++	[PWRAP_DVFS_WDATA7] =		0x124,
++	[PWRAP_DVFS_ADR8] =		0x128,
++	[PWRAP_DVFS_WDATA8] =		0x12C,
++	[PWRAP_DVFS_ADR9] =		0x130,
++	[PWRAP_DVFS_WDATA9] =		0x134,
++	[PWRAP_DVFS_ADR10] =		0x138,
++	[PWRAP_DVFS_WDATA10] =		0x13C,
++	[PWRAP_DVFS_ADR11] =		0x140,
++	[PWRAP_DVFS_WDATA11] =		0x144,
++	[PWRAP_DVFS_ADR12] =		0x148,
++	[PWRAP_DVFS_WDATA12] =		0x14C,
++	[PWRAP_DVFS_ADR13] =		0x150,
++	[PWRAP_DVFS_WDATA13] =		0x154,
++	[PWRAP_DVFS_ADR14] =		0x158,
++	[PWRAP_DVFS_WDATA14] =		0x15C,
++	[PWRAP_DVFS_ADR15] =		0x160,
++	[PWRAP_DVFS_WDATA15] =		0x164,
++	[PWRAP_SPMINF_STA] =		0x168,
++	[PWRAP_CIPHER_KEY_SEL] =	0x16C,
++	[PWRAP_CIPHER_IV_SEL] =		0x170,
++	[PWRAP_CIPHER_EN] =		0x174,
++	[PWRAP_CIPHER_RDY] =		0x178,
++	[PWRAP_CIPHER_MODE] =		0x17C,
++	[PWRAP_CIPHER_SWRST] =		0x180,
++	[PWRAP_DCM_EN] =		0x184,
++	[PWRAP_DCM_DBC_PRD] =		0x188,
++	[PWRAP_EXT_CK] =		0x18C,
++	[PWRAP_ADC_CMD_ADDR] =		0x190,
++	[PWRAP_PWRAP_ADC_CMD] =		0x194,
++	[PWRAP_ADC_RDATA_ADDR] =	0x198,
++	[PWRAP_GPS_STA] =		0x19C,
++	[PWRAP_SW_RST] =		0x1A0,
++	[PWRAP_DVFS_STEP_CTRL0] =	0x238,
++	[PWRAP_DVFS_STEP_CTRL1] =	0x23C,
++	[PWRAP_DVFS_STEP_CTRL2] =	0x240,
++	[PWRAP_SPI2_CTRL] =		0x244,
++};
++
+ static int mt8173_regs[] = {
+ 	[PWRAP_MUX_SEL] =		0x0,
+ 	[PWRAP_WRAP_EN] =		0x4,
+@@ -499,6 +641,7 @@ enum pmic_type {
+ 
+ enum pwrap_type {
+ 	PWRAP_MT2701,
++	PWRAP_MT7622,
+ 	PWRAP_MT8135,
+ 	PWRAP_MT8173,
+ };
+@@ -927,6 +1070,9 @@ static int pwrap_init_cipher(struct pmic_wrapper *wrp)
+ 	case PWRAP_MT8173:
+ 		pwrap_writel(wrp, 1, PWRAP_CIPHER_EN);
+ 		break;
++	case PWRAP_MT7622:
++		pwrap_writel(wrp, 0, PWRAP_CIPHER_EN);
++		break;
+ 	}
+ 
+ 	/* Config cipher mode @PMIC */
+@@ -1071,6 +1217,15 @@ static int pwrap_mt2701_init_soc_specific(struct pmic_wrapper *wrp)
+ 	return 0;
+ }
+ 
++static int pwrap_mt7622_init_soc_specific(struct pmic_wrapper *wrp)
++{
++	pwrap_writel(wrp, 0, PWRAP_STAUPD_PRD);
++	/* enable 2wire SPI master */
++	pwrap_writel(wrp, 0x8000000, PWRAP_SPI2_CTRL);
++
++	return 0;
++}
++
+ static int pwrap_init(struct pmic_wrapper *wrp)
+ {
+ 	int ret;
+@@ -1242,6 +1397,18 @@ static const struct pmic_wrapper_type pwrap_mt2701 = {
+ 	.init_soc_specific = pwrap_mt2701_init_soc_specific,
+ };
+ 
++static const struct pmic_wrapper_type pwrap_mt7622 = {
++	.regs = mt7622_regs,
++	.type = PWRAP_MT7622,
++	.arb_en_all = 0xff,
++	.int_en_all = ~(u32)BIT(31),
++	.spi_w = PWRAP_MAN_CMD_SPI_WRITE,
++	.wdt_src = PWRAP_WDT_SRC_MASK_ALL,
++	.has_bridge = 0,
++	.init_reg_clock = pwrap_common_init_reg_clock,
++	.init_soc_specific = pwrap_mt7622_init_soc_specific,
++};
++
+ static const struct pmic_wrapper_type pwrap_mt8135 = {
+ 	.regs = mt8135_regs,
+ 	.type = PWRAP_MT8135,
+@@ -1271,6 +1438,9 @@ static const struct of_device_id of_pwrap_match_tbl[] = {
+ 		.compatible = "mediatek,mt2701-pwrap",
+ 		.data = &pwrap_mt2701,
+ 	}, {
++		.compatible = "mediatek,mt7622-pwrap",
++		.data = &pwrap_mt7622,
++	}, {
+ 		.compatible = "mediatek,mt8135-pwrap",
+ 		.data = &pwrap_mt8135,
+ 	}, {
+-- 
+2.11.0
+
diff --git a/target/linux/mediatek/patches-4.14/0123-soc-mediatek-place-Kconfig-for-all-SoC-drivers-under.patch b/target/linux/mediatek/patches-4.14/0123-soc-mediatek-place-Kconfig-for-all-SoC-drivers-under.patch
new file mode 100644
index 0000000000..4735f845be
--- /dev/null
+++ b/target/linux/mediatek/patches-4.14/0123-soc-mediatek-place-Kconfig-for-all-SoC-drivers-under.patch
@@ -0,0 +1,62 @@
+From 21501b17e017cb10f1a64a73e62e3e2e91a52efa Mon Sep 17 00:00:00 2001
+From: Sean Wang <sean.wang@mediatek.com>
+Date: Thu, 5 Oct 2017 11:17:49 +0800
+Subject: [PATCH 123/224] soc: mediatek: place Kconfig for all SoC drivers
+ under menu
+
+Add cleanup for placing all Kconfig for all MediaTek SoC drivers under
+the independent menu as other SoCs vendor usually did. Since the menu
+would be shown depending on "ARCH_MEDIATEK || COMPILE_TEST" selected and
+MTK_PMIC_WRAP is still safe compiling with the case of "COMPILE_TEST"
+only, the superfluous dependency for those items under the menu also is
+also being removed for the sake of simplicity.
+
+Signed-off-by: Sean Wang <sean.wang@mediatek.com>
+Reviewed-by: Jean Delvare <jdelvare@suse.de>
+Signed-off-by: Matthias Brugger <matthias.bgg@gmail.com>
+---
+ drivers/soc/mediatek/Kconfig | 8 +++++---
+ 1 file changed, 5 insertions(+), 3 deletions(-)
+
+diff --git a/drivers/soc/mediatek/Kconfig b/drivers/soc/mediatek/Kconfig
+index 609bb3424c14..a7d0667338f2 100644
+--- a/drivers/soc/mediatek/Kconfig
++++ b/drivers/soc/mediatek/Kconfig
+@@ -1,9 +1,11 @@
+ #
+ # MediaTek SoC drivers
+ #
++menu "MediaTek SoC drivers"
++	depends on ARCH_MEDIATEK || COMPILE_TEST
++
+ config MTK_INFRACFG
+ 	bool "MediaTek INFRACFG Support"
+-	depends on ARCH_MEDIATEK || COMPILE_TEST
+ 	select REGMAP
+ 	help
+ 	  Say yes here to add support for the MediaTek INFRACFG controller. The
+@@ -12,7 +14,6 @@ config MTK_INFRACFG
+ 
+ config MTK_PMIC_WRAP
+ 	tristate "MediaTek PMIC Wrapper Support"
+-	depends on ARCH_MEDIATEK
+ 	depends on RESET_CONTROLLER
+ 	select REGMAP
+ 	help
+@@ -22,7 +23,6 @@ config MTK_PMIC_WRAP
+ 
+ config MTK_SCPSYS
+ 	bool "MediaTek SCPSYS Support"
+-	depends on ARCH_MEDIATEK || COMPILE_TEST
+ 	default ARCH_MEDIATEK
+ 	select REGMAP
+ 	select MTK_INFRACFG
+@@ -30,3 +30,5 @@ config MTK_SCPSYS
+ 	help
+ 	  Say yes here to add support for the MediaTek SCPSYS power domain
+ 	  driver.
++
++endmenu
+-- 
+2.11.0
+
diff --git a/target/linux/mediatek/patches-4.14/0124-arm64-mediatek-cleanup-message-for-platform-selectio.patch b/target/linux/mediatek/patches-4.14/0124-arm64-mediatek-cleanup-message-for-platform-selectio.patch
new file mode 100644
index 0000000000..0e7fa9c1d3
--- /dev/null
+++ b/target/linux/mediatek/patches-4.14/0124-arm64-mediatek-cleanup-message-for-platform-selectio.patch
@@ -0,0 +1,39 @@
+From f9bea440dd8dbf1eda8644e4b1d76503053f17b6 Mon Sep 17 00:00:00 2001
+From: Sean Wang <sean.wang@mediatek.com>
+Date: Thu, 19 Oct 2017 17:52:54 +0800
+Subject: [PATCH 124/224] arm64: mediatek: cleanup message for platform
+ selection
+
+The latest kernel tree already can support more MediaTek platforms such as
+MT2712 and MT7622, so additional descriptions for those platforms are added
+and certain cleanups are also being made here.
+
+Signed-off-by: Sean Wang <sean.wang@mediatek.com>
+Signed-off-by: Matthias Brugger <matthias.bgg@gmail.com>
+---
+ arch/arm64/Kconfig.platforms | 5 +++--
+ 1 file changed, 3 insertions(+), 2 deletions(-)
+
+diff --git a/arch/arm64/Kconfig.platforms b/arch/arm64/Kconfig.platforms
+index 6b54ee8c1262..ab69f5fce261 100644
+--- a/arch/arm64/Kconfig.platforms
++++ b/arch/arm64/Kconfig.platforms
+@@ -91,12 +91,13 @@ config ARCH_HISI
+ 	  This enables support for Hisilicon ARMv8 SoC family
+ 
+ config ARCH_MEDIATEK
+-	bool "Mediatek MT65xx & MT81xx ARMv8 SoC"
++	bool "MediaTek SoC Family"
+ 	select ARM_GIC
+ 	select PINCTRL
+ 	select MTK_TIMER
+ 	help
+-	  Support for Mediatek MT65xx & MT81xx ARMv8 SoCs
++	  This enables support for MediaTek MT27xx, MT65xx, MT76xx
++	  & MT81xx ARMv8 SoCs
+ 
+ config ARCH_MESON
+ 	bool "Amlogic Platforms"
+-- 
+2.11.0
+
diff --git a/target/linux/mediatek/patches-4.14/0125-phy-phy-mtk-tphy-add-set_mode-callback.patch b/target/linux/mediatek/patches-4.14/0125-phy-phy-mtk-tphy-add-set_mode-callback.patch
new file mode 100644
index 0000000000..75b3908c8d
--- /dev/null
+++ b/target/linux/mediatek/patches-4.14/0125-phy-phy-mtk-tphy-add-set_mode-callback.patch
@@ -0,0 +1,91 @@
+From d42ebed1aa669c5a897ec0aa5e1ede8d9069894a Mon Sep 17 00:00:00 2001
+From: Chunfeng Yun <chunfeng.yun@mediatek.com>
+Date: Thu, 21 Sep 2017 18:31:49 +0800
+Subject: [PATCH 125/224] phy: phy-mtk-tphy: add set_mode callback
+
+This is used to force PHY with USB OTG function to enter a specific
+mode, and override OTG IDPIN(or IDDIG) signal.
+
+Signed-off-by: Chunfeng Yun <chunfeng.yun@mediatek.com>
+Signed-off-by: Kishon Vijay Abraham I <kishon@ti.com>
+---
+ drivers/phy/mediatek/phy-mtk-tphy.c | 39 +++++++++++++++++++++++++++++++++++++
+ 1 file changed, 39 insertions(+)
+
+diff --git a/drivers/phy/mediatek/phy-mtk-tphy.c b/drivers/phy/mediatek/phy-mtk-tphy.c
+index 721a2a1c97ef..402385f2562a 100644
+--- a/drivers/phy/mediatek/phy-mtk-tphy.c
++++ b/drivers/phy/mediatek/phy-mtk-tphy.c
+@@ -96,9 +96,11 @@
+ 
+ #define U3P_U2PHYDTM1		0x06C
+ #define P2C_RG_UART_EN			BIT(16)
++#define P2C_FORCE_IDDIG		BIT(9)
+ #define P2C_RG_VBUSVALID		BIT(5)
+ #define P2C_RG_SESSEND			BIT(4)
+ #define P2C_RG_AVALID			BIT(2)
++#define P2C_RG_IDDIG			BIT(1)
+ 
+ #define U3P_U3_CHIP_GPIO_CTLD		0x0c
+ #define P3C_REG_IP_SW_RST		BIT(31)
+@@ -585,6 +587,31 @@ static void u2_phy_instance_exit(struct mtk_tphy *tphy,
+ 	}
+ }
+ 
++static void u2_phy_instance_set_mode(struct mtk_tphy *tphy,
++				     struct mtk_phy_instance *instance,
++				     enum phy_mode mode)
++{
++	struct u2phy_banks *u2_banks = &instance->u2_banks;
++	u32 tmp;
++
++	tmp = readl(u2_banks->com + U3P_U2PHYDTM1);
++	switch (mode) {
++	case PHY_MODE_USB_DEVICE:
++		tmp |= P2C_FORCE_IDDIG | P2C_RG_IDDIG;
++		break;
++	case PHY_MODE_USB_HOST:
++		tmp |= P2C_FORCE_IDDIG;
++		tmp &= ~P2C_RG_IDDIG;
++		break;
++	case PHY_MODE_USB_OTG:
++		tmp &= ~(P2C_FORCE_IDDIG | P2C_RG_IDDIG);
++		break;
++	default:
++		return;
++	}
++	writel(tmp, u2_banks->com + U3P_U2PHYDTM1);
++}
++
+ static void pcie_phy_instance_init(struct mtk_tphy *tphy,
+ 	struct mtk_phy_instance *instance)
+ {
+@@ -881,6 +908,17 @@ static int mtk_phy_exit(struct phy *phy)
+ 	return 0;
+ }
+ 
++static int mtk_phy_set_mode(struct phy *phy, enum phy_mode mode)
++{
++	struct mtk_phy_instance *instance = phy_get_drvdata(phy);
++	struct mtk_tphy *tphy = dev_get_drvdata(phy->dev.parent);
++
++	if (instance->type == PHY_TYPE_USB2)
++		u2_phy_instance_set_mode(tphy, instance, mode);
++
++	return 0;
++}
++
+ static struct phy *mtk_phy_xlate(struct device *dev,
+ 					struct of_phandle_args *args)
+ {
+@@ -931,6 +969,7 @@ static const struct phy_ops mtk_tphy_ops = {
+ 	.exit		= mtk_phy_exit,
+ 	.power_on	= mtk_phy_power_on,
+ 	.power_off	= mtk_phy_power_off,
++	.set_mode	= mtk_phy_set_mode,
+ 	.owner		= THIS_MODULE,
+ };
+ 
+-- 
+2.11.0
+
diff --git a/target/linux/mediatek/patches-4.14/0126-usb-xhci-mtk-use-dma_set_mask_and_coherent-in-probe-.patch b/target/linux/mediatek/patches-4.14/0126-usb-xhci-mtk-use-dma_set_mask_and_coherent-in-probe-.patch
new file mode 100644
index 0000000000..70ed474d05
--- /dev/null
+++ b/target/linux/mediatek/patches-4.14/0126-usb-xhci-mtk-use-dma_set_mask_and_coherent-in-probe-.patch
@@ -0,0 +1,40 @@
+From 9f617ce19c5dab429a539d411204ae220b5b8cd6 Mon Sep 17 00:00:00 2001
+From: Chunfeng Yun <chunfeng.yun@mediatek.com>
+Date: Fri, 13 Oct 2017 16:26:33 +0800
+Subject: [PATCH 126/224] usb: xhci-mtk: use dma_set_mask_and_coherent() in
+ probe function
+
+This patch uses the simpler dma_set_mask_and_coherent() instead of
+doing these as separate steps
+
+Signed-off-by: Chunfeng Yun <chunfeng.yun@mediatek.com>
+Acked-by: Mathias Nyman <mathias.nyman@linux.intel.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/usb/host/xhci-mtk.c | 7 +------
+ 1 file changed, 1 insertion(+), 6 deletions(-)
+
+diff --git a/drivers/usb/host/xhci-mtk.c b/drivers/usb/host/xhci-mtk.c
+index 8fb60657ed4f..c197a6d9e157 100644
+--- a/drivers/usb/host/xhci-mtk.c
++++ b/drivers/usb/host/xhci-mtk.c
+@@ -606,15 +606,10 @@ static int xhci_mtk_probe(struct platform_device *pdev)
+ 	}
+ 
+ 	/* Initialize dma_mask and coherent_dma_mask to 32-bits */
+-	ret = dma_set_coherent_mask(dev, DMA_BIT_MASK(32));
++	ret = dma_set_mask_and_coherent(dev, DMA_BIT_MASK(32));
+ 	if (ret)
+ 		goto disable_clk;
+ 
+-	if (!dev->dma_mask)
+-		dev->dma_mask = &dev->coherent_dma_mask;
+-	else
+-		dma_set_mask(dev, DMA_BIT_MASK(32));
+-
+ 	hcd = usb_create_hcd(driver, dev, dev_name(dev));
+ 	if (!hcd) {
+ 		ret = -ENOMEM;
+-- 
+2.11.0
+
diff --git a/target/linux/mediatek/patches-4.14/0127-usb-xhci-mtk-use-ports-count-from-xhci-in-xhci_mtk_s.patch b/target/linux/mediatek/patches-4.14/0127-usb-xhci-mtk-use-ports-count-from-xhci-in-xhci_mtk_s.patch
new file mode 100644
index 0000000000..67fc84ed3d
--- /dev/null
+++ b/target/linux/mediatek/patches-4.14/0127-usb-xhci-mtk-use-ports-count-from-xhci-in-xhci_mtk_s.patch
@@ -0,0 +1,60 @@
+From f97aa71fe34135e7fc8da6231e61ee06f79d739d Mon Sep 17 00:00:00 2001
+From: Chunfeng Yun <chunfeng.yun@mediatek.com>
+Date: Fri, 13 Oct 2017 16:26:34 +0800
+Subject: [PATCH 127/224] usb: xhci-mtk: use ports count from xhci in
+ xhci_mtk_sch_init()
+
+Make use of ports count from xhci but not from ippc in
+xhci_mtk_sch_init()
+
+Signed-off-by: Chunfeng Yun <chunfeng.yun@mediatek.com>
+Acked-by: Mathias Nyman <mathias.nyman@linux.intel.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/usb/host/xhci-mtk-sch.c | 3 ++-
+ drivers/usb/host/xhci-mtk.c     | 3 ---
+ 2 files changed, 2 insertions(+), 4 deletions(-)
+
+diff --git a/drivers/usb/host/xhci-mtk-sch.c b/drivers/usb/host/xhci-mtk-sch.c
+index 6e7ddf6cafae..bfc51bc902b8 100644
+--- a/drivers/usb/host/xhci-mtk-sch.c
++++ b/drivers/usb/host/xhci-mtk-sch.c
+@@ -287,12 +287,13 @@ static bool need_bw_sch(struct usb_host_endpoint *ep,
+ 
+ int xhci_mtk_sch_init(struct xhci_hcd_mtk *mtk)
+ {
++	struct xhci_hcd *xhci = hcd_to_xhci(mtk->hcd);
+ 	struct mu3h_sch_bw_info *sch_array;
+ 	int num_usb_bus;
+ 	int i;
+ 
+ 	/* ss IN and OUT are separated */
+-	num_usb_bus = mtk->num_u3_ports * 2 + mtk->num_u2_ports;
++	num_usb_bus = xhci->num_usb3_ports * 2 + xhci->num_usb2_ports;
+ 
+ 	sch_array = kcalloc(num_usb_bus, sizeof(*sch_array), GFP_KERNEL);
+ 	if (sch_array == NULL)
+diff --git a/drivers/usb/host/xhci-mtk.c b/drivers/usb/host/xhci-mtk.c
+index c197a6d9e157..9502ca408f01 100644
+--- a/drivers/usb/host/xhci-mtk.c
++++ b/drivers/usb/host/xhci-mtk.c
+@@ -492,7 +492,6 @@ static void xhci_mtk_quirks(struct device *dev, struct xhci_hcd *xhci)
+ /* called during probe() after chip reset completes */
+ static int xhci_mtk_setup(struct usb_hcd *hcd)
+ {
+-	struct xhci_hcd *xhci = hcd_to_xhci(hcd);
+ 	struct xhci_hcd_mtk *mtk = hcd_to_mtk(hcd);
+ 	int ret;
+ 
+@@ -507,8 +506,6 @@ static int xhci_mtk_setup(struct usb_hcd *hcd)
+ 		return ret;
+ 
+ 	if (usb_hcd_is_primary_hcd(hcd)) {
+-		mtk->num_u3_ports = xhci->num_usb3_ports;
+-		mtk->num_u2_ports = xhci->num_usb2_ports;
+ 		ret = xhci_mtk_sch_init(mtk);
+ 		if (ret)
+ 			return ret;
+-- 
+2.11.0
+
diff --git a/target/linux/mediatek/patches-4.14/0128-usb-xhci-mtk-check-clock-stability-of-U3_MAC.patch b/target/linux/mediatek/patches-4.14/0128-usb-xhci-mtk-check-clock-stability-of-U3_MAC.patch
new file mode 100644
index 0000000000..d046574216
--- /dev/null
+++ b/target/linux/mediatek/patches-4.14/0128-usb-xhci-mtk-check-clock-stability-of-U3_MAC.patch
@@ -0,0 +1,41 @@
+From 4422c4efeed2a8b9fa745c6e529623d89c0be75e Mon Sep 17 00:00:00 2001
+From: Chunfeng Yun <chunfeng.yun@mediatek.com>
+Date: Fri, 13 Oct 2017 16:26:35 +0800
+Subject: [PATCH 128/224] usb: xhci-mtk: check clock stability of U3_MAC
+
+This is useful to find out the root cause when the Super Speed doesn't
+work. Such as when the T-PHY is switched to PCIe or SATA, and affects
+Super Speed function, the check will fail.
+
+Signed-off-by: Chunfeng Yun <chunfeng.yun@mediatek.com>
+Acked-by: Mathias Nyman <mathias.nyman@linux.intel.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/usb/host/xhci-mtk.c | 4 ++++
+ 1 file changed, 4 insertions(+)
+
+diff --git a/drivers/usb/host/xhci-mtk.c b/drivers/usb/host/xhci-mtk.c
+index 9502ca408f01..7a92bb782e5c 100644
+--- a/drivers/usb/host/xhci-mtk.c
++++ b/drivers/usb/host/xhci-mtk.c
+@@ -43,6 +43,7 @@
+ 
+ /* ip_pw_sts1 register */
+ #define STS1_IP_SLEEP_STS	BIT(30)
++#define STS1_U3_MAC_RST	BIT(16)
+ #define STS1_XHCI_RST		BIT(11)
+ #define STS1_SYS125_RST	BIT(10)
+ #define STS1_REF_RST		BIT(8)
+@@ -125,6 +126,9 @@ static int xhci_mtk_host_enable(struct xhci_hcd_mtk *mtk)
+ 	check_val = STS1_SYSPLL_STABLE | STS1_REF_RST |
+ 			STS1_SYS125_RST | STS1_XHCI_RST;
+ 
++	if (mtk->num_u3_ports)
++		check_val |= STS1_U3_MAC_RST;
++
+ 	ret = readl_poll_timeout(&ippc->ip_pw_sts1, value,
+ 			  (check_val == (value & check_val)), 100, 20000);
+ 	if (ret) {
+-- 
+2.11.0
+
diff --git a/target/linux/mediatek/patches-4.14/0129-usb-xhci-mtk-support-option-to-disable-usb3-ports.patch b/target/linux/mediatek/patches-4.14/0129-usb-xhci-mtk-support-option-to-disable-usb3-ports.patch
new file mode 100644
index 0000000000..90e2aed441
--- /dev/null
+++ b/target/linux/mediatek/patches-4.14/0129-usb-xhci-mtk-support-option-to-disable-usb3-ports.patch
@@ -0,0 +1,92 @@
+From 13a1b2e927893cbb046a1ec5a55ec3516873a3f6 Mon Sep 17 00:00:00 2001
+From: Chunfeng Yun <chunfeng.yun@mediatek.com>
+Date: Fri, 13 Oct 2017 16:26:36 +0800
+Subject: [PATCH 129/224] usb: xhci-mtk: support option to disable usb3 ports
+
+Add support to disable specific usb3 ports, it's useful when
+usb3 phy is shared with PCIe or SATA, because we should disable
+the corresponding usb3 port if the phy is used by PCIe or SATA.
+Sometimes it's helpful to analyse and solve problems.
+
+Signed-off-by: Chunfeng Yun <chunfeng.yun@mediatek.com>
+Acked-by: Mathias Nyman <mathias.nyman@linux.intel.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/usb/host/xhci-mtk.c | 18 +++++++++++++++---
+ drivers/usb/host/xhci-mtk.h |  1 +
+ 2 files changed, 16 insertions(+), 3 deletions(-)
+
+diff --git a/drivers/usb/host/xhci-mtk.c b/drivers/usb/host/xhci-mtk.c
+index 7a92bb782e5c..97ba51e4e149 100644
+--- a/drivers/usb/host/xhci-mtk.c
++++ b/drivers/usb/host/xhci-mtk.c
+@@ -92,6 +92,7 @@ static int xhci_mtk_host_enable(struct xhci_hcd_mtk *mtk)
+ {
+ 	struct mu3c_ippc_regs __iomem *ippc = mtk->ippc_regs;
+ 	u32 value, check_val;
++	int u3_ports_disabed = 0;
+ 	int ret;
+ 	int i;
+ 
+@@ -103,8 +104,13 @@ static int xhci_mtk_host_enable(struct xhci_hcd_mtk *mtk)
+ 	value &= ~CTRL1_IP_HOST_PDN;
+ 	writel(value, &ippc->ip_pw_ctr1);
+ 
+-	/* power on and enable all u3 ports */
++	/* power on and enable u3 ports except skipped ones */
+ 	for (i = 0; i < mtk->num_u3_ports; i++) {
++		if ((0x1 << i) & mtk->u3p_dis_msk) {
++			u3_ports_disabed++;
++			continue;
++		}
++
+ 		value = readl(&ippc->u3_ctrl_p[i]);
+ 		value &= ~(CTRL_U3_PORT_PDN | CTRL_U3_PORT_DIS);
+ 		value |= CTRL_U3_PORT_HOST_SEL;
+@@ -126,7 +132,7 @@ static int xhci_mtk_host_enable(struct xhci_hcd_mtk *mtk)
+ 	check_val = STS1_SYSPLL_STABLE | STS1_REF_RST |
+ 			STS1_SYS125_RST | STS1_XHCI_RST;
+ 
+-	if (mtk->num_u3_ports)
++	if (mtk->num_u3_ports > u3_ports_disabed)
+ 		check_val |= STS1_U3_MAC_RST;
+ 
+ 	ret = readl_poll_timeout(&ippc->ip_pw_sts1, value,
+@@ -149,8 +155,11 @@ static int xhci_mtk_host_disable(struct xhci_hcd_mtk *mtk)
+ 	if (!mtk->has_ippc)
+ 		return 0;
+ 
+-	/* power down all u3 ports */
++	/* power down u3 ports except skipped ones */
+ 	for (i = 0; i < mtk->num_u3_ports; i++) {
++		if ((0x1 << i) & mtk->u3p_dis_msk)
++			continue;
++
+ 		value = readl(&ippc->u3_ctrl_p[i]);
+ 		value |= CTRL_U3_PORT_PDN;
+ 		writel(value, &ippc->u3_ctrl_p[i]);
+@@ -573,6 +582,9 @@ static int xhci_mtk_probe(struct platform_device *pdev)
+ 	}
+ 
+ 	mtk->lpm_support = of_property_read_bool(node, "usb3-lpm-capable");
++	/* optional property, ignore the error if it does not exist */
++	of_property_read_u32(node, "mediatek,u3p-dis-msk",
++			     &mtk->u3p_dis_msk);
+ 
+ 	ret = usb_wakeup_of_property_parse(mtk, node);
+ 	if (ret)
+diff --git a/drivers/usb/host/xhci-mtk.h b/drivers/usb/host/xhci-mtk.h
+index 3aa5e1d25064..db55a12f1585 100644
+--- a/drivers/usb/host/xhci-mtk.h
++++ b/drivers/usb/host/xhci-mtk.h
+@@ -121,6 +121,7 @@ struct xhci_hcd_mtk {
+ 	bool has_ippc;
+ 	int num_u2_ports;
+ 	int num_u3_ports;
++	int u3p_dis_msk;
+ 	struct regulator *vusb33;
+ 	struct regulator *vbus;
+ 	struct clk *sys_clk;	/* sys and mac clock */
+-- 
+2.11.0
+
diff --git a/target/linux/mediatek/patches-4.14/0130-usb-xhci-mtk-remove-dummy-wakeup-debounce-clocks.patch b/target/linux/mediatek/patches-4.14/0130-usb-xhci-mtk-remove-dummy-wakeup-debounce-clocks.patch
new file mode 100644
index 0000000000..cb595ff7de
--- /dev/null
+++ b/target/linux/mediatek/patches-4.14/0130-usb-xhci-mtk-remove-dummy-wakeup-debounce-clocks.patch
@@ -0,0 +1,93 @@
+From 25adaf94e0fcbf6c1b47cb610edb7f5c23c53139 Mon Sep 17 00:00:00 2001
+From: Chunfeng Yun <chunfeng.yun@mediatek.com>
+Date: Fri, 13 Oct 2017 16:26:37 +0800
+Subject: [PATCH 130/224] usb: xhci-mtk: remove dummy wakeup debounce clocks
+
+The wakeup debounce clocks for each ports in fact are not
+needed, so remove them.
+
+Signed-off-by: Chunfeng Yun <chunfeng.yun@mediatek.com>
+Acked-by: Mathias Nyman <mathias.nyman@linux.intel.com>
+Reviewed-by: Matthias Brugger <matthias.bgg@gmail.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/usb/host/xhci-mtk.c | 33 ---------------------------------
+ drivers/usb/host/xhci-mtk.h |  2 --
+ 2 files changed, 35 deletions(-)
+
+diff --git a/drivers/usb/host/xhci-mtk.c b/drivers/usb/host/xhci-mtk.c
+index 97ba51e4e149..d60463c07c54 100644
+--- a/drivers/usb/host/xhci-mtk.c
++++ b/drivers/usb/host/xhci-mtk.c
+@@ -237,25 +237,8 @@ static int xhci_mtk_clks_enable(struct xhci_hcd_mtk *mtk)
+ 		goto sys_clk_err;
+ 	}
+ 
+-	if (mtk->wakeup_src) {
+-		ret = clk_prepare_enable(mtk->wk_deb_p0);
+-		if (ret) {
+-			dev_err(mtk->dev, "failed to enable wk_deb_p0\n");
+-			goto usb_p0_err;
+-		}
+-
+-		ret = clk_prepare_enable(mtk->wk_deb_p1);
+-		if (ret) {
+-			dev_err(mtk->dev, "failed to enable wk_deb_p1\n");
+-			goto usb_p1_err;
+-		}
+-	}
+ 	return 0;
+ 
+-usb_p1_err:
+-	clk_disable_unprepare(mtk->wk_deb_p0);
+-usb_p0_err:
+-	clk_disable_unprepare(mtk->sys_clk);
+ sys_clk_err:
+ 	clk_disable_unprepare(mtk->ref_clk);
+ ref_clk_err:
+@@ -264,10 +247,6 @@ static int xhci_mtk_clks_enable(struct xhci_hcd_mtk *mtk)
+ 
+ static void xhci_mtk_clks_disable(struct xhci_hcd_mtk *mtk)
+ {
+-	if (mtk->wakeup_src) {
+-		clk_disable_unprepare(mtk->wk_deb_p1);
+-		clk_disable_unprepare(mtk->wk_deb_p0);
+-	}
+ 	clk_disable_unprepare(mtk->sys_clk);
+ 	clk_disable_unprepare(mtk->ref_clk);
+ }
+@@ -371,18 +350,6 @@ static int usb_wakeup_of_property_parse(struct xhci_hcd_mtk *mtk,
+ 	if (!mtk->wakeup_src)
+ 		return 0;
+ 
+-	mtk->wk_deb_p0 = devm_clk_get(dev, "wakeup_deb_p0");
+-	if (IS_ERR(mtk->wk_deb_p0)) {
+-		dev_err(dev, "fail to get wakeup_deb_p0\n");
+-		return PTR_ERR(mtk->wk_deb_p0);
+-	}
+-
+-	mtk->wk_deb_p1 = devm_clk_get(dev, "wakeup_deb_p1");
+-	if (IS_ERR(mtk->wk_deb_p1)) {
+-		dev_err(dev, "fail to get wakeup_deb_p1\n");
+-		return PTR_ERR(mtk->wk_deb_p1);
+-	}
+-
+ 	mtk->pericfg = syscon_regmap_lookup_by_phandle(dn,
+ 						"mediatek,syscon-wakeup");
+ 	if (IS_ERR(mtk->pericfg)) {
+diff --git a/drivers/usb/host/xhci-mtk.h b/drivers/usb/host/xhci-mtk.h
+index db55a12f1585..67783a7af509 100644
+--- a/drivers/usb/host/xhci-mtk.h
++++ b/drivers/usb/host/xhci-mtk.h
+@@ -126,8 +126,6 @@ struct xhci_hcd_mtk {
+ 	struct regulator *vbus;
+ 	struct clk *sys_clk;	/* sys and mac clock */
+ 	struct clk *ref_clk;
+-	struct clk *wk_deb_p0;	/* port0's wakeup debounce clock */
+-	struct clk *wk_deb_p1;
+ 	struct regmap *pericfg;
+ 	struct phy **phys;
+ 	int num_phys;
+-- 
+2.11.0
+
diff --git a/target/linux/mediatek/patches-4.14/0131-usb-xhci-mtk-add-optional-mcu-and-dma-bus-clocks.patch b/target/linux/mediatek/patches-4.14/0131-usb-xhci-mtk-add-optional-mcu-and-dma-bus-clocks.patch
new file mode 100644
index 0000000000..a533826937
--- /dev/null
+++ b/target/linux/mediatek/patches-4.14/0131-usb-xhci-mtk-add-optional-mcu-and-dma-bus-clocks.patch
@@ -0,0 +1,146 @@
+From 9dce908d64ffb8b0ab71cb3a4b79db398d2e6dc3 Mon Sep 17 00:00:00 2001
+From: Chunfeng Yun <chunfeng.yun@mediatek.com>
+Date: Fri, 13 Oct 2017 16:26:38 +0800
+Subject: [PATCH 131/224] usb: xhci-mtk: add optional mcu and dma bus clocks
+
+There are mcu_bus and dma_bus clocks needed to be controlled by
+driver on some SoCs, so add them as optional ones
+
+Signed-off-by: Chunfeng Yun <chunfeng.yun@mediatek.com>
+Acked-by: Mathias Nyman <mathias.nyman@linux.intel.com>
+Reviewed-by: Matthias Brugger <matthias.bgg@gmail.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/usb/host/xhci-mtk.c | 79 ++++++++++++++++++++++++++++++++++-----------
+ drivers/usb/host/xhci-mtk.h |  2 ++
+ 2 files changed, 62 insertions(+), 19 deletions(-)
+
+diff --git a/drivers/usb/host/xhci-mtk.c b/drivers/usb/host/xhci-mtk.c
+index d60463c07c54..e5caabe7eebe 100644
+--- a/drivers/usb/host/xhci-mtk.c
++++ b/drivers/usb/host/xhci-mtk.c
+@@ -221,6 +221,44 @@ static int xhci_mtk_ssusb_config(struct xhci_hcd_mtk *mtk)
+ 	return xhci_mtk_host_enable(mtk);
+ }
+ 
++/* ignore the error if the clock does not exist */
++static struct clk *optional_clk_get(struct device *dev, const char *id)
++{
++	struct clk *opt_clk;
++
++	opt_clk = devm_clk_get(dev, id);
++	/* ignore error number except EPROBE_DEFER */
++	if (IS_ERR(opt_clk) && (PTR_ERR(opt_clk) != -EPROBE_DEFER))
++		opt_clk = NULL;
++
++	return opt_clk;
++}
++
++static int xhci_mtk_clks_get(struct xhci_hcd_mtk *mtk)
++{
++	struct device *dev = mtk->dev;
++
++	mtk->sys_clk = devm_clk_get(dev, "sys_ck");
++	if (IS_ERR(mtk->sys_clk)) {
++		dev_err(dev, "fail to get sys_ck\n");
++		return PTR_ERR(mtk->sys_clk);
++	}
++
++	mtk->ref_clk = optional_clk_get(dev, "ref_ck");
++	if (IS_ERR(mtk->ref_clk))
++		return PTR_ERR(mtk->ref_clk);
++
++	mtk->mcu_clk = optional_clk_get(dev, "mcu_ck");
++	if (IS_ERR(mtk->mcu_clk))
++		return PTR_ERR(mtk->mcu_clk);
++
++	mtk->dma_clk = optional_clk_get(dev, "dma_ck");
++	if (IS_ERR(mtk->dma_clk))
++		return PTR_ERR(mtk->dma_clk);
++
++	return 0;
++}
++
+ static int xhci_mtk_clks_enable(struct xhci_hcd_mtk *mtk)
+ {
+ 	int ret;
+@@ -237,16 +275,34 @@ static int xhci_mtk_clks_enable(struct xhci_hcd_mtk *mtk)
+ 		goto sys_clk_err;
+ 	}
+ 
++	ret = clk_prepare_enable(mtk->mcu_clk);
++	if (ret) {
++		dev_err(mtk->dev, "failed to enable mcu_clk\n");
++		goto mcu_clk_err;
++	}
++
++	ret = clk_prepare_enable(mtk->dma_clk);
++	if (ret) {
++		dev_err(mtk->dev, "failed to enable dma_clk\n");
++		goto dma_clk_err;
++	}
++
+ 	return 0;
+ 
++dma_clk_err:
++	clk_disable_unprepare(mtk->mcu_clk);
++mcu_clk_err:
++	clk_disable_unprepare(mtk->sys_clk);
+ sys_clk_err:
+ 	clk_disable_unprepare(mtk->ref_clk);
+ ref_clk_err:
+-	return -EINVAL;
++	return ret;
+ }
+ 
+ static void xhci_mtk_clks_disable(struct xhci_hcd_mtk *mtk)
+ {
++	clk_disable_unprepare(mtk->dma_clk);
++	clk_disable_unprepare(mtk->mcu_clk);
+ 	clk_disable_unprepare(mtk->sys_clk);
+ 	clk_disable_unprepare(mtk->ref_clk);
+ }
+@@ -529,24 +585,9 @@ static int xhci_mtk_probe(struct platform_device *pdev)
+ 		return PTR_ERR(mtk->vusb33);
+ 	}
+ 
+-	mtk->sys_clk = devm_clk_get(dev, "sys_ck");
+-	if (IS_ERR(mtk->sys_clk)) {
+-		dev_err(dev, "fail to get sys_ck\n");
+-		return PTR_ERR(mtk->sys_clk);
+-	}
+-
+-	/*
+-	 * reference clock is usually a "fixed-clock", make it optional
+-	 * for backward compatibility and ignore the error if it does
+-	 * not exist.
+-	 */
+-	mtk->ref_clk = devm_clk_get(dev, "ref_ck");
+-	if (IS_ERR(mtk->ref_clk)) {
+-		if (PTR_ERR(mtk->ref_clk) == -EPROBE_DEFER)
+-			return -EPROBE_DEFER;
+-
+-		mtk->ref_clk = NULL;
+-	}
++	ret = xhci_mtk_clks_get(mtk);
++	if (ret)
++		return ret;
+ 
+ 	mtk->lpm_support = of_property_read_bool(node, "usb3-lpm-capable");
+ 	/* optional property, ignore the error if it does not exist */
+diff --git a/drivers/usb/host/xhci-mtk.h b/drivers/usb/host/xhci-mtk.h
+index 67783a7af509..45ff5c67efb5 100644
+--- a/drivers/usb/host/xhci-mtk.h
++++ b/drivers/usb/host/xhci-mtk.h
+@@ -126,6 +126,8 @@ struct xhci_hcd_mtk {
+ 	struct regulator *vbus;
+ 	struct clk *sys_clk;	/* sys and mac clock */
+ 	struct clk *ref_clk;
++	struct clk *mcu_clk;
++	struct clk *dma_clk;
+ 	struct regmap *pericfg;
+ 	struct phy **phys;
+ 	int num_phys;
+-- 
+2.11.0
+
diff --git a/target/linux/mediatek/patches-4.14/0132-usb-host-modify-description-for-MTK-xHCI-config.patch b/target/linux/mediatek/patches-4.14/0132-usb-host-modify-description-for-MTK-xHCI-config.patch
new file mode 100644
index 0000000000..87e1b3daa9
--- /dev/null
+++ b/target/linux/mediatek/patches-4.14/0132-usb-host-modify-description-for-MTK-xHCI-config.patch
@@ -0,0 +1,37 @@
+From d975bd8976c4d19fbfbaafe269dd466e281a2e3e Mon Sep 17 00:00:00 2001
+From: Chunfeng Yun <chunfeng.yun@mediatek.com>
+Date: Fri, 13 Oct 2017 16:26:39 +0800
+Subject: [PATCH 132/224] usb: host: modify description for MTK xHCI config
+
+Due to all MediaTek SoCs with xHCI host controller use this
+driver, remove limitation for specific SoCs
+
+Signed-off-by: Chunfeng Yun <chunfeng.yun@mediatek.com>
+Acked-by: Mathias Nyman <mathias.nyman@linux.intel.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/usb/host/Kconfig | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/usb/host/Kconfig b/drivers/usb/host/Kconfig
+index fa5692dec832..bc09a2e4faeb 100644
+--- a/drivers/usb/host/Kconfig
++++ b/drivers/usb/host/Kconfig
+@@ -45,12 +45,12 @@ config USB_XHCI_PLATFORM
+ 	  If unsure, say N.
+ 
+ config USB_XHCI_MTK
+-	tristate "xHCI support for Mediatek MT65xx/MT7621"
++	tristate "xHCI support for MediaTek SoCs"
+ 	select MFD_SYSCON
+ 	depends on (MIPS && SOC_MT7621) || ARCH_MEDIATEK || COMPILE_TEST
+ 	---help---
+ 	  Say 'Y' to enable the support for the xHCI host controller
+-	  found in Mediatek MT65xx SoCs.
++	  found in MediaTek SoCs.
+ 	  If unsure, say N.
+ 
+ config USB_XHCI_MVEBU
+-- 
+2.11.0
+
diff --git a/target/linux/mediatek/patches-4.14/0133-dt-bindings-usb-mtk-xhci-add-a-optional-property-to-.patch b/target/linux/mediatek/patches-4.14/0133-dt-bindings-usb-mtk-xhci-add-a-optional-property-to-.patch
new file mode 100644
index 0000000000..e59f46a1fe
--- /dev/null
+++ b/target/linux/mediatek/patches-4.14/0133-dt-bindings-usb-mtk-xhci-add-a-optional-property-to-.patch
@@ -0,0 +1,30 @@
+From 3a2dce7d84793ec60cff173e17e3669acaade8c9 Mon Sep 17 00:00:00 2001
+From: Chunfeng Yun <chunfeng.yun@mediatek.com>
+Date: Fri, 13 Oct 2017 16:26:40 +0800
+Subject: [PATCH 133/224] dt-bindings: usb: mtk-xhci: add a optional property
+ to disable u3ports
+
+Add a new optional property to disable u3ports
+
+Signed-off-by: Chunfeng Yun <chunfeng.yun@mediatek.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ Documentation/devicetree/bindings/usb/mediatek,mtk-xhci.txt | 2 ++
+ 1 file changed, 2 insertions(+)
+
+diff --git a/Documentation/devicetree/bindings/usb/mediatek,mtk-xhci.txt b/Documentation/devicetree/bindings/usb/mediatek,mtk-xhci.txt
+index 5611a2e4ddf0..2d9b459bd890 100644
+--- a/Documentation/devicetree/bindings/usb/mediatek,mtk-xhci.txt
++++ b/Documentation/devicetree/bindings/usb/mediatek,mtk-xhci.txt
+@@ -38,6 +38,8 @@ Optional properties:
+ 	mode;
+  - mediatek,syscon-wakeup : phandle to syscon used to access USB wakeup
+ 	control register, it depends on "mediatek,wakeup-src".
++ - mediatek,u3p-dis-msk : mask to disable u3ports, bit0 for u3port0,
++	bit1 for u3port1, ... etc;
+  - vbus-supply : reference to the VBUS regulator;
+  - usb3-lpm-capable : supports USB3.0 LPM
+  - pinctrl-names : a pinctrl state named "default" must be defined
+-- 
+2.11.0
+
diff --git a/target/linux/mediatek/patches-4.14/0134-dt-bindings-usb-mtk-xhci-remove-dummy-clocks-and-add.patch b/target/linux/mediatek/patches-4.14/0134-dt-bindings-usb-mtk-xhci-remove-dummy-clocks-and-add.patch
new file mode 100644
index 0000000000..9d196ab498
--- /dev/null
+++ b/target/linux/mediatek/patches-4.14/0134-dt-bindings-usb-mtk-xhci-remove-dummy-clocks-and-add.patch
@@ -0,0 +1,63 @@
+From a96468412cac8abd66667c322fbcda756cc3abc9 Mon Sep 17 00:00:00 2001
+From: Chunfeng Yun <chunfeng.yun@mediatek.com>
+Date: Fri, 13 Oct 2017 16:26:41 +0800
+Subject: [PATCH 134/224] dt-bindings: usb: mtk-xhci: remove dummy clocks and
+ add optional ones
+
+Remove dummy clocks for usb wakeup and add optional ones for
+MCU_BUS_CK and DMA_BUS_CK.
+
+Signed-off-by: Chunfeng Yun <chunfeng.yun@mediatek.com>
+Acked-by: Rob Herring <robh@kernel.org>
+Reviewed-by: Matthias Brugger <matthias.bgg@gmail.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ .../devicetree/bindings/usb/mediatek,mtk-xhci.txt      | 18 ++++++++----------
+ 1 file changed, 8 insertions(+), 10 deletions(-)
+
+diff --git a/Documentation/devicetree/bindings/usb/mediatek,mtk-xhci.txt b/Documentation/devicetree/bindings/usb/mediatek,mtk-xhci.txt
+index 2d9b459bd890..30595964876a 100644
+--- a/Documentation/devicetree/bindings/usb/mediatek,mtk-xhci.txt
++++ b/Documentation/devicetree/bindings/usb/mediatek,mtk-xhci.txt
+@@ -26,10 +26,11 @@ Required properties:
+  - clocks : a list of phandle + clock-specifier pairs, one for each
+ 	entry in clock-names
+  - clock-names : must contain
+-	"sys_ck": for clock of xHCI MAC
+-	"ref_ck": for reference clock of xHCI MAC
+-	"wakeup_deb_p0": for USB wakeup debounce clock of port0
+-	"wakeup_deb_p1": for USB wakeup debounce clock of port1
++	"sys_ck": controller clock used by normal mode,
++	the following ones are optional:
++	"ref_ck": reference clock used by low power mode etc,
++	"mcu_ck": mcu_bus clock for register access,
++	"dma_ck": dma_bus clock for data transfer by DMA
+ 
+  - phys : a list of phandle + phy specifier pairs
+ 
+@@ -57,9 +58,7 @@ usb30: usb@11270000 {
+ 	clocks = <&topckgen CLK_TOP_USB30_SEL>, <&clk26m>,
+ 		 <&pericfg CLK_PERI_USB0>,
+ 		 <&pericfg CLK_PERI_USB1>;
+-	clock-names = "sys_ck", "ref_ck",
+-		      "wakeup_deb_p0",
+-		      "wakeup_deb_p1";
++	clock-names = "sys_ck", "ref_ck";
+ 	phys = <&phy_port0 PHY_TYPE_USB3>,
+ 	       <&phy_port1 PHY_TYPE_USB2>;
+ 	vusb33-supply = <&mt6397_vusb_reg>;
+@@ -91,9 +90,8 @@ Required properties:
+ 
+  - clocks : a list of phandle + clock-specifier pairs, one for each
+ 	entry in clock-names
+- - clock-names : must be
+-	"sys_ck": for clock of xHCI MAC
+-	"ref_ck": for reference clock of xHCI MAC
++ - clock-names : must contain "sys_ck", and the following ones are optional:
++	"ref_ck", "mcu_ck" and "dma_ck"
+ 
+ Optional properties:
+  - vbus-supply : reference to the VBUS regulator;
+-- 
+2.11.0
+
diff --git a/target/linux/mediatek/patches-4.14/0135-dt-bindings-mtd-add-new-compatible-strings-and-impro.patch b/target/linux/mediatek/patches-4.14/0135-dt-bindings-mtd-add-new-compatible-strings-and-impro.patch
new file mode 100644
index 0000000000..4c699860c8
--- /dev/null
+++ b/target/linux/mediatek/patches-4.14/0135-dt-bindings-mtd-add-new-compatible-strings-and-impro.patch
@@ -0,0 +1,47 @@
+From 2af9a8582cb28e786a8cbd913f41e6db9adcf3dc Mon Sep 17 00:00:00 2001
+From: Guochun Mao <guochun.mao@mediatek.com>
+Date: Thu, 21 Sep 2017 20:45:05 +0800
+Subject: [PATCH 135/224] dt-bindings: mtd: add new compatible strings and
+ improve description
+
+Add "mediatak,mt2712-nor" and "mediatek,mt7622-nor"
+for nor flash node's compatible strings.
+Explicate the fallback compatible.
+
+Acked-by: Rob Herring <robh@kernel.org>
+Signed-off-by: Guochun Mao <guochun.mao@mediatek.com>
+Signed-off-by: Cyrille Pitchen <cyrille.pitchen@wedev4u.fr>
+---
+ Documentation/devicetree/bindings/mtd/mtk-quadspi.txt | 15 +++++++++------
+ 1 file changed, 9 insertions(+), 6 deletions(-)
+
+diff --git a/Documentation/devicetree/bindings/mtd/mtk-quadspi.txt b/Documentation/devicetree/bindings/mtd/mtk-quadspi.txt
+index 840f9405dcf0..56d3668e2c50 100644
+--- a/Documentation/devicetree/bindings/mtd/mtk-quadspi.txt
++++ b/Documentation/devicetree/bindings/mtd/mtk-quadspi.txt
+@@ -1,13 +1,16 @@
+ * Serial NOR flash controller for MTK MT81xx (and similar)
+ 
+ Required properties:
+-- compatible: 	  The possible values are:
+-		  "mediatek,mt2701-nor"
+-		  "mediatek,mt7623-nor"
++- compatible: 	  For mt8173, compatible should be "mediatek,mt8173-nor",
++		  and it's the fallback compatible for other Soc.
++		  For every other SoC, should contain both the SoC-specific compatible
++		  string and "mediatek,mt8173-nor".
++		  The possible values are:
++		  "mediatek,mt2701-nor", "mediatek,mt8173-nor"
++		  "mediatek,mt2712-nor", "mediatek,mt8173-nor"
++		  "mediatek,mt7622-nor", "mediatek,mt8173-nor"
++		  "mediatek,mt7623-nor", "mediatek,mt8173-nor"
+ 		  "mediatek,mt8173-nor"
+-		  For mt8173, compatible should be "mediatek,mt8173-nor".
+-		  For every other SoC, should contain both the SoC-specific compatible string
+-		  and "mediatek,mt8173-nor".
+ - reg: 		  physical base address and length of the controller's register
+ - clocks: 	  the phandle of the clocks needed by the nor controller
+ - clock-names: 	  the names of the clocks
+-- 
+2.11.0
+
diff --git a/target/linux/mediatek/patches-4.14/0136-mtd-mtk-nor-add-suspend-resume-support.patch b/target/linux/mediatek/patches-4.14/0136-mtd-mtk-nor-add-suspend-resume-support.patch
new file mode 100644
index 0000000000..248e195f45
--- /dev/null
+++ b/target/linux/mediatek/patches-4.14/0136-mtd-mtk-nor-add-suspend-resume-support.patch
@@ -0,0 +1,133 @@
+From 8947f8cd407a55db816cd03fc03b59096210978e Mon Sep 17 00:00:00 2001
+From: Guochun Mao <guochun.mao@mediatek.com>
+Date: Thu, 21 Sep 2017 20:45:06 +0800
+Subject: [PATCH 136/224] mtd: mtk-nor: add suspend/resume support
+
+Abstract functions of clock setting, to avoid duplicated code,
+these functions been used in new feature.
+Implement suspend/resume functions.
+
+Signed-off-by: Guochun Mao <guochun.mao@mediatek.com>
+Signed-off-by: Cyrille Pitchen <cyrille.pitchen@wedev4u.fr>
+---
+ drivers/mtd/spi-nor/mtk-quadspi.c | 70 ++++++++++++++++++++++++++++++++-------
+ 1 file changed, 58 insertions(+), 12 deletions(-)
+
+diff --git a/drivers/mtd/spi-nor/mtk-quadspi.c b/drivers/mtd/spi-nor/mtk-quadspi.c
+index c258c7adf1c5..abe455ccd68b 100644
+--- a/drivers/mtd/spi-nor/mtk-quadspi.c
++++ b/drivers/mtd/spi-nor/mtk-quadspi.c
+@@ -404,6 +404,29 @@ static int mt8173_nor_write_reg(struct spi_nor *nor, u8 opcode, u8 *buf,
+ 	return ret;
+ }
+ 
++static void mt8173_nor_disable_clk(struct mt8173_nor *mt8173_nor)
++{
++	clk_disable_unprepare(mt8173_nor->spi_clk);
++	clk_disable_unprepare(mt8173_nor->nor_clk);
++}
++
++static int mt8173_nor_enable_clk(struct mt8173_nor *mt8173_nor)
++{
++	int ret;
++
++	ret = clk_prepare_enable(mt8173_nor->spi_clk);
++	if (ret)
++		return ret;
++
++	ret = clk_prepare_enable(mt8173_nor->nor_clk);
++	if (ret) {
++		clk_disable_unprepare(mt8173_nor->spi_clk);
++		return ret;
++	}
++
++	return 0;
++}
++
+ static int mtk_nor_init(struct mt8173_nor *mt8173_nor,
+ 			struct device_node *flash_node)
+ {
+@@ -468,15 +491,11 @@ static int mtk_nor_drv_probe(struct platform_device *pdev)
+ 		return PTR_ERR(mt8173_nor->nor_clk);
+ 
+ 	mt8173_nor->dev = &pdev->dev;
+-	ret = clk_prepare_enable(mt8173_nor->spi_clk);
++
++	ret = mt8173_nor_enable_clk(mt8173_nor);
+ 	if (ret)
+ 		return ret;
+ 
+-	ret = clk_prepare_enable(mt8173_nor->nor_clk);
+-	if (ret) {
+-		clk_disable_unprepare(mt8173_nor->spi_clk);
+-		return ret;
+-	}
+ 	/* only support one attached flash */
+ 	flash_np = of_get_next_available_child(pdev->dev.of_node, NULL);
+ 	if (!flash_np) {
+@@ -487,10 +506,9 @@ static int mtk_nor_drv_probe(struct platform_device *pdev)
+ 	ret = mtk_nor_init(mt8173_nor, flash_np);
+ 
+ nor_free:
+-	if (ret) {
+-		clk_disable_unprepare(mt8173_nor->spi_clk);
+-		clk_disable_unprepare(mt8173_nor->nor_clk);
+-	}
++	if (ret)
++		mt8173_nor_disable_clk(mt8173_nor);
++
+ 	return ret;
+ }
+ 
+@@ -498,11 +516,38 @@ static int mtk_nor_drv_remove(struct platform_device *pdev)
+ {
+ 	struct mt8173_nor *mt8173_nor = platform_get_drvdata(pdev);
+ 
+-	clk_disable_unprepare(mt8173_nor->spi_clk);
+-	clk_disable_unprepare(mt8173_nor->nor_clk);
++	mt8173_nor_disable_clk(mt8173_nor);
++
++	return 0;
++}
++
++#ifdef CONFIG_PM_SLEEP
++static int mtk_nor_suspend(struct device *dev)
++{
++	struct mt8173_nor *mt8173_nor = dev_get_drvdata(dev);
++
++	mt8173_nor_disable_clk(mt8173_nor);
++
+ 	return 0;
+ }
+ 
++static int mtk_nor_resume(struct device *dev)
++{
++	struct mt8173_nor *mt8173_nor = dev_get_drvdata(dev);
++
++	return mt8173_nor_enable_clk(mt8173_nor);
++}
++
++static const struct dev_pm_ops mtk_nor_dev_pm_ops = {
++	.suspend = mtk_nor_suspend,
++	.resume = mtk_nor_resume,
++};
++
++#define MTK_NOR_DEV_PM_OPS	(&mtk_nor_dev_pm_ops)
++#else
++#define MTK_NOR_DEV_PM_OPS	NULL
++#endif
++
+ static const struct of_device_id mtk_nor_of_ids[] = {
+ 	{ .compatible = "mediatek,mt8173-nor"},
+ 	{ /* sentinel */ }
+@@ -514,6 +559,7 @@ static struct platform_driver mtk_nor_driver = {
+ 	.remove = mtk_nor_drv_remove,
+ 	.driver = {
+ 		.name = "mtk-nor",
++		.pm = MTK_NOR_DEV_PM_OPS,
+ 		.of_match_table = mtk_nor_of_ids,
+ 	},
+ };
+-- 
+2.11.0
+
diff --git a/target/linux/mediatek/patches-4.14/0137-dt-bindings-rtc-mediatek-add-bindings-for-MediaTek-S.patch b/target/linux/mediatek/patches-4.14/0137-dt-bindings-rtc-mediatek-add-bindings-for-MediaTek-S.patch
new file mode 100644
index 0000000000..2488276b69
--- /dev/null
+++ b/target/linux/mediatek/patches-4.14/0137-dt-bindings-rtc-mediatek-add-bindings-for-MediaTek-S.patch
@@ -0,0 +1,47 @@
+From 3254edde244fcbcce3bf4da1ade9db2db558ae28 Mon Sep 17 00:00:00 2001
+From: Sean Wang <sean.wang@mediatek.com>
+Date: Mon, 23 Oct 2017 15:16:44 +0800
+Subject: [PATCH 137/224] dt-bindings: rtc: mediatek: add bindings for MediaTek
+ SoC based RTC
+
+Add device-tree binding for MediaTek SoC based RTC
+
+Cc: devicetree@vger.kernel.org
+Signed-off-by: Sean Wang <sean.wang@mediatek.com>
+Acked-by: Rob Herring <robh@kernel.org>
+Signed-off-by: Alexandre Belloni <alexandre.belloni@free-electrons.com>
+---
+ .../devicetree/bindings/rtc/rtc-mt7622.txt          | 21 +++++++++++++++++++++
+ 1 file changed, 21 insertions(+)
+ create mode 100644 Documentation/devicetree/bindings/rtc/rtc-mt7622.txt
+
+diff --git a/Documentation/devicetree/bindings/rtc/rtc-mt7622.txt b/Documentation/devicetree/bindings/rtc/rtc-mt7622.txt
+new file mode 100644
+index 000000000000..09fe8f51476f
+--- /dev/null
++++ b/Documentation/devicetree/bindings/rtc/rtc-mt7622.txt
+@@ -0,0 +1,21 @@
++Device-Tree bindings for MediaTek SoC based RTC
++
++Required properties:
++- compatible	    : Should be
++			"mediatek,mt7622-rtc", "mediatek,soc-rtc" : for MT7622 SoC
++- reg 		    : Specifies base physical address and size of the registers;
++- interrupts	    : Should contain the interrupt for RTC alarm;
++- clocks	    : Specifies list of clock specifiers, corresponding to
++		      entries in clock-names property;
++- clock-names	    : Should contain "rtc" entries
++
++Example:
++
++rtc: rtc@10212800 {
++	compatible = "mediatek,mt7622-rtc",
++		     "mediatek,soc-rtc";
++	reg = <0 0x10212800 0 0x200>;
++	interrupts = <GIC_SPI 129 IRQ_TYPE_LEVEL_LOW>;
++	clocks = <&topckgen CLK_TOP_RTC>;
++	clock-names = "rtc";
++};
+-- 
+2.11.0
+
diff --git a/target/linux/mediatek/patches-4.14/0138-rtc-mediatek-add-driver-for-RTC-on-MT7622-SoC.patch b/target/linux/mediatek/patches-4.14/0138-rtc-mediatek-add-driver-for-RTC-on-MT7622-SoC.patch
new file mode 100644
index 0000000000..6be78ac4ca
--- /dev/null
+++ b/target/linux/mediatek/patches-4.14/0138-rtc-mediatek-add-driver-for-RTC-on-MT7622-SoC.patch
@@ -0,0 +1,481 @@
+From 4cf0b74c175cb5cb751e449223c0baafc2f98499 Mon Sep 17 00:00:00 2001
+From: Sean Wang <sean.wang@mediatek.com>
+Date: Mon, 23 Oct 2017 15:16:45 +0800
+Subject: [PATCH 138/224] rtc: mediatek: add driver for RTC on MT7622 SoC
+
+This patch introduces the driver for the RTC on MT7622 SoC.
+
+Signed-off-by: Sean Wang <sean.wang@mediatek.com>
+Reviewed-by: Yingjoe Chen <yingjoe.chen@mediatek.com>
+Signed-off-by: Alexandre Belloni <alexandre.belloni@free-electrons.com>
+---
+ drivers/rtc/Kconfig      |  10 ++
+ drivers/rtc/Makefile     |   1 +
+ drivers/rtc/rtc-mt7622.c | 422 +++++++++++++++++++++++++++++++++++++++++++++++
+ 3 files changed, 433 insertions(+)
+ create mode 100644 drivers/rtc/rtc-mt7622.c
+
+diff --git a/drivers/rtc/Kconfig b/drivers/rtc/Kconfig
+index e0e58f3b1420..322752ebc5a7 100644
+--- a/drivers/rtc/Kconfig
++++ b/drivers/rtc/Kconfig
+@@ -1715,6 +1715,16 @@ config RTC_DRV_MT6397
+ 
+ 	  If you want to use Mediatek(R) RTC interface, select Y or M here.
+ 
++config RTC_DRV_MT7622
++	tristate "MediaTek SoC based RTC"
++	depends on ARCH_MEDIATEK || COMPILE_TEST
++	help
++	  This enables support for the real time clock built in the MediaTek
++	  SoCs.
++
++	  This drive can also be built as a module. If so, the module
++	  will be called rtc-mt7622.
++
+ config RTC_DRV_XGENE
+ 	tristate "APM X-Gene RTC"
+ 	depends on HAS_IOMEM
+diff --git a/drivers/rtc/Makefile b/drivers/rtc/Makefile
+index 7230014c92af..5ec891a81f4f 100644
+--- a/drivers/rtc/Makefile
++++ b/drivers/rtc/Makefile
+@@ -102,6 +102,7 @@ obj-$(CONFIG_RTC_DRV_MPC5121)	+= rtc-mpc5121.o
+ obj-$(CONFIG_RTC_DRV_VRTC)	+= rtc-mrst.o
+ obj-$(CONFIG_RTC_DRV_MSM6242)	+= rtc-msm6242.o
+ obj-$(CONFIG_RTC_DRV_MT6397)	+= rtc-mt6397.o
++obj-$(CONFIG_RTC_DRV_MT7622)	+= rtc-mt7622.o
+ obj-$(CONFIG_RTC_DRV_MV)	+= rtc-mv.o
+ obj-$(CONFIG_RTC_DRV_MXC)	+= rtc-mxc.o
+ obj-$(CONFIG_RTC_DRV_NUC900)	+= rtc-nuc900.o
+diff --git a/drivers/rtc/rtc-mt7622.c b/drivers/rtc/rtc-mt7622.c
+new file mode 100644
+index 000000000000..d79b9ae4d237
+--- /dev/null
++++ b/drivers/rtc/rtc-mt7622.c
+@@ -0,0 +1,422 @@
++/*
++ * Driver for MediaTek SoC based RTC
++ *
++ * Copyright (C) 2017 Sean Wang <sean.wang@mediatek.com>
++ *
++ * 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; either version 2 of
++ * the License, or (at your option) any later version.
++ *
++ * 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/clk.h>
++#include <linux/interrupt.h>
++#include <linux/module.h>
++#include <linux/of_address.h>
++#include <linux/of_device.h>
++#include <linux/platform_device.h>
++#include <linux/rtc.h>
++
++#define MTK_RTC_DEV KBUILD_MODNAME
++
++#define MTK_RTC_PWRCHK1		0x4
++#define	RTC_PWRCHK1_MAGIC	0xc6
++
++#define MTK_RTC_PWRCHK2		0x8
++#define	RTC_PWRCHK2_MAGIC	0x9a
++
++#define MTK_RTC_KEY		0xc
++#define	RTC_KEY_MAGIC		0x59
++
++#define MTK_RTC_PROT1		0x10
++#define	RTC_PROT1_MAGIC		0xa3
++
++#define MTK_RTC_PROT2		0x14
++#define	RTC_PROT2_MAGIC		0x57
++
++#define MTK_RTC_PROT3		0x18
++#define	RTC_PROT3_MAGIC		0x67
++
++#define MTK_RTC_PROT4		0x1c
++#define	RTC_PROT4_MAGIC		0xd2
++
++#define MTK_RTC_CTL		0x20
++#define	RTC_RC_STOP		BIT(0)
++
++#define MTK_RTC_DEBNCE		0x2c
++#define	RTC_DEBNCE_MASK		GENMASK(2, 0)
++
++#define MTK_RTC_INT		0x30
++#define RTC_INT_AL_STA		BIT(4)
++
++/*
++ * Ranges from 0x40 to 0x78 provide RTC time setup for year, month,
++ * day of month, day of week, hour, minute and second.
++ */
++#define MTK_RTC_TREG(_t, _f)	(0x40 + (0x4 * (_f)) + ((_t) * 0x20))
++
++#define MTK_RTC_AL_CTL		0x7c
++#define	RTC_AL_EN		BIT(0)
++#define	RTC_AL_ALL		GENMASK(7, 0)
++
++/*
++ * The offset is used in the translation for the year between in struct
++ * rtc_time and in hardware register MTK_RTC_TREG(x,MTK_YEA)
++ */
++#define MTK_RTC_TM_YR_OFFSET	100
++
++/*
++ * The lowest value for the valid tm_year. RTC hardware would take incorrectly
++ * tm_year 100 as not a leap year and thus it is also required being excluded
++ * from the valid options.
++ */
++#define MTK_RTC_TM_YR_L		(MTK_RTC_TM_YR_OFFSET + 1)
++
++/*
++ * The most year the RTC can hold is 99 and the next to 99 in year register
++ * would be wraparound to 0, for MT7622.
++ */
++#define MTK_RTC_HW_YR_LIMIT	99
++
++/* The highest value for the valid tm_year */
++#define MTK_RTC_TM_YR_H		(MTK_RTC_TM_YR_OFFSET + MTK_RTC_HW_YR_LIMIT)
++
++/* Simple macro helps to check whether the hardware supports the tm_year */
++#define MTK_RTC_TM_YR_VALID(_y)	((_y) >= MTK_RTC_TM_YR_L && \
++				 (_y) <= MTK_RTC_TM_YR_H)
++
++/* Types of the function the RTC provides are time counter and alarm. */
++enum {
++	MTK_TC,
++	MTK_AL,
++};
++
++/* Indexes are used for the pointer to relevant registers in MTK_RTC_TREG */
++enum {
++	MTK_YEA,
++	MTK_MON,
++	MTK_DOM,
++	MTK_DOW,
++	MTK_HOU,
++	MTK_MIN,
++	MTK_SEC
++};
++
++struct mtk_rtc {
++	struct rtc_device *rtc;
++	void __iomem *base;
++	int irq;
++	struct clk *clk;
++};
++
++static void mtk_w32(struct mtk_rtc *rtc, u32 reg, u32 val)
++{
++	writel_relaxed(val, rtc->base + reg);
++}
++
++static u32 mtk_r32(struct mtk_rtc *rtc, u32 reg)
++{
++	return readl_relaxed(rtc->base + reg);
++}
++
++static void mtk_rmw(struct mtk_rtc *rtc, u32 reg, u32 mask, u32 set)
++{
++	u32 val;
++
++	val = mtk_r32(rtc, reg);
++	val &= ~mask;
++	val |= set;
++	mtk_w32(rtc, reg, val);
++}
++
++static void mtk_set(struct mtk_rtc *rtc, u32 reg, u32 val)
++{
++	mtk_rmw(rtc, reg, 0, val);
++}
++
++static void mtk_clr(struct mtk_rtc *rtc, u32 reg, u32 val)
++{
++	mtk_rmw(rtc, reg, val, 0);
++}
++
++static void mtk_rtc_hw_init(struct mtk_rtc *hw)
++{
++	/* The setup of the init sequence is for allowing RTC got to work */
++	mtk_w32(hw, MTK_RTC_PWRCHK1, RTC_PWRCHK1_MAGIC);
++	mtk_w32(hw, MTK_RTC_PWRCHK2, RTC_PWRCHK2_MAGIC);
++	mtk_w32(hw, MTK_RTC_KEY, RTC_KEY_MAGIC);
++	mtk_w32(hw, MTK_RTC_PROT1, RTC_PROT1_MAGIC);
++	mtk_w32(hw, MTK_RTC_PROT2, RTC_PROT2_MAGIC);
++	mtk_w32(hw, MTK_RTC_PROT3, RTC_PROT3_MAGIC);
++	mtk_w32(hw, MTK_RTC_PROT4, RTC_PROT4_MAGIC);
++	mtk_rmw(hw, MTK_RTC_DEBNCE, RTC_DEBNCE_MASK, 0);
++	mtk_clr(hw, MTK_RTC_CTL, RTC_RC_STOP);
++}
++
++static void mtk_rtc_get_alarm_or_time(struct mtk_rtc *hw, struct rtc_time *tm,
++				      int time_alarm)
++{
++	u32 year, mon, mday, wday, hour, min, sec;
++
++	/*
++	 * Read again until the field of the second is not changed which
++	 * ensures all fields in the consistent state. Note that MTK_SEC must
++	 * be read first. In this way, it guarantees the others remain not
++	 * changed when the results for two MTK_SEC consecutive reads are same.
++	 */
++	do {
++		sec = mtk_r32(hw, MTK_RTC_TREG(time_alarm, MTK_SEC));
++		min = mtk_r32(hw, MTK_RTC_TREG(time_alarm, MTK_MIN));
++		hour = mtk_r32(hw, MTK_RTC_TREG(time_alarm, MTK_HOU));
++		wday = mtk_r32(hw, MTK_RTC_TREG(time_alarm, MTK_DOW));
++		mday = mtk_r32(hw, MTK_RTC_TREG(time_alarm, MTK_DOM));
++		mon = mtk_r32(hw, MTK_RTC_TREG(time_alarm, MTK_MON));
++		year = mtk_r32(hw, MTK_RTC_TREG(time_alarm, MTK_YEA));
++	} while (sec != mtk_r32(hw, MTK_RTC_TREG(time_alarm, MTK_SEC)));
++
++	tm->tm_sec  = sec;
++	tm->tm_min  = min;
++	tm->tm_hour = hour;
++	tm->tm_wday = wday;
++	tm->tm_mday = mday;
++	tm->tm_mon  = mon - 1;
++
++	/* Rebase to the absolute year which userspace queries */
++	tm->tm_year = year + MTK_RTC_TM_YR_OFFSET;
++}
++
++static void mtk_rtc_set_alarm_or_time(struct mtk_rtc *hw, struct rtc_time *tm,
++				      int time_alarm)
++{
++	u32 year;
++
++	/* Rebase to the relative year which RTC hardware requires */
++	year = tm->tm_year - MTK_RTC_TM_YR_OFFSET;
++
++	mtk_w32(hw, MTK_RTC_TREG(time_alarm, MTK_YEA), year);
++	mtk_w32(hw, MTK_RTC_TREG(time_alarm, MTK_MON), tm->tm_mon + 1);
++	mtk_w32(hw, MTK_RTC_TREG(time_alarm, MTK_DOW), tm->tm_wday);
++	mtk_w32(hw, MTK_RTC_TREG(time_alarm, MTK_DOM), tm->tm_mday);
++	mtk_w32(hw, MTK_RTC_TREG(time_alarm, MTK_HOU), tm->tm_hour);
++	mtk_w32(hw, MTK_RTC_TREG(time_alarm, MTK_MIN), tm->tm_min);
++	mtk_w32(hw, MTK_RTC_TREG(time_alarm, MTK_SEC), tm->tm_sec);
++}
++
++static irqreturn_t mtk_rtc_alarmirq(int irq, void *id)
++{
++	struct mtk_rtc *hw = (struct mtk_rtc *)id;
++	u32 irq_sta;
++
++	irq_sta = mtk_r32(hw, MTK_RTC_INT);
++	if (irq_sta & RTC_INT_AL_STA) {
++		/* Stop alarm also implicitly disables the alarm interrupt */
++		mtk_w32(hw, MTK_RTC_AL_CTL, 0);
++		rtc_update_irq(hw->rtc, 1, RTC_IRQF | RTC_AF);
++
++		/* Ack alarm interrupt status */
++		mtk_w32(hw, MTK_RTC_INT, RTC_INT_AL_STA);
++		return IRQ_HANDLED;
++	}
++
++	return IRQ_NONE;
++}
++
++static int mtk_rtc_gettime(struct device *dev, struct rtc_time *tm)
++{
++	struct mtk_rtc *hw = dev_get_drvdata(dev);
++
++	mtk_rtc_get_alarm_or_time(hw, tm, MTK_TC);
++
++	return rtc_valid_tm(tm);
++}
++
++static int mtk_rtc_settime(struct device *dev, struct rtc_time *tm)
++{
++	struct mtk_rtc *hw = dev_get_drvdata(dev);
++
++	if (!MTK_RTC_TM_YR_VALID(tm->tm_year))
++		return -EINVAL;
++
++	/* Stop time counter before setting a new one*/
++	mtk_set(hw, MTK_RTC_CTL, RTC_RC_STOP);
++
++	mtk_rtc_set_alarm_or_time(hw, tm, MTK_TC);
++
++	/* Restart the time counter */
++	mtk_clr(hw, MTK_RTC_CTL, RTC_RC_STOP);
++
++	return 0;
++}
++
++static int mtk_rtc_getalarm(struct device *dev, struct rtc_wkalrm *wkalrm)
++{
++	struct mtk_rtc *hw = dev_get_drvdata(dev);
++	struct rtc_time *alrm_tm = &wkalrm->time;
++
++	mtk_rtc_get_alarm_or_time(hw, alrm_tm, MTK_AL);
++
++	wkalrm->enabled = !!(mtk_r32(hw, MTK_RTC_AL_CTL) & RTC_AL_EN);
++	wkalrm->pending = !!(mtk_r32(hw, MTK_RTC_INT) & RTC_INT_AL_STA);
++
++	return 0;
++}
++
++static int mtk_rtc_setalarm(struct device *dev, struct rtc_wkalrm *wkalrm)
++{
++	struct mtk_rtc *hw = dev_get_drvdata(dev);
++	struct rtc_time *alrm_tm = &wkalrm->time;
++
++	if (!MTK_RTC_TM_YR_VALID(alrm_tm->tm_year))
++		return -EINVAL;
++
++	/*
++	 * Stop the alarm also implicitly including disables interrupt before
++	 * setting a new one.
++	 */
++	mtk_clr(hw, MTK_RTC_AL_CTL, RTC_AL_EN);
++
++	/*
++	 * Avoid contention between mtk_rtc_setalarm and IRQ handler so that
++	 * disabling the interrupt and awaiting for pending IRQ handler to
++	 * complete.
++	 */
++	synchronize_irq(hw->irq);
++
++	mtk_rtc_set_alarm_or_time(hw, alrm_tm, MTK_AL);
++
++	/* Restart the alarm with the new setup */
++	mtk_w32(hw, MTK_RTC_AL_CTL, RTC_AL_ALL);
++
++	return 0;
++}
++
++static const struct rtc_class_ops mtk_rtc_ops = {
++	.read_time		= mtk_rtc_gettime,
++	.set_time		= mtk_rtc_settime,
++	.read_alarm		= mtk_rtc_getalarm,
++	.set_alarm		= mtk_rtc_setalarm,
++};
++
++static const struct of_device_id mtk_rtc_match[] = {
++	{ .compatible = "mediatek,mt7622-rtc" },
++	{ .compatible = "mediatek,soc-rtc" },
++	{},
++};
++
++static int mtk_rtc_probe(struct platform_device *pdev)
++{
++	struct mtk_rtc *hw;
++	struct resource *res;
++	int ret;
++
++	hw = devm_kzalloc(&pdev->dev, sizeof(*hw), GFP_KERNEL);
++	if (!hw)
++		return -ENOMEM;
++
++	platform_set_drvdata(pdev, hw);
++
++	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
++	hw->base = devm_ioremap_resource(&pdev->dev, res);
++	if (IS_ERR(hw->base))
++		return PTR_ERR(hw->base);
++
++	hw->clk = devm_clk_get(&pdev->dev, "rtc");
++	if (IS_ERR(hw->clk)) {
++		dev_err(&pdev->dev, "No clock\n");
++		return PTR_ERR(hw->clk);
++	}
++
++	ret = clk_prepare_enable(hw->clk);
++	if (ret)
++		return ret;
++
++	hw->irq = platform_get_irq(pdev, 0);
++	if (hw->irq < 0) {
++		dev_err(&pdev->dev, "No IRQ resource\n");
++		ret = hw->irq;
++		goto err;
++	}
++
++	ret = devm_request_irq(&pdev->dev, hw->irq, mtk_rtc_alarmirq,
++			       0, dev_name(&pdev->dev), hw);
++	if (ret) {
++		dev_err(&pdev->dev, "Can't request IRQ\n");
++		goto err;
++	}
++
++	mtk_rtc_hw_init(hw);
++
++	device_init_wakeup(&pdev->dev, true);
++
++	hw->rtc = devm_rtc_device_register(&pdev->dev, pdev->name,
++					   &mtk_rtc_ops, THIS_MODULE);
++	if (IS_ERR(hw->rtc)) {
++		ret = PTR_ERR(hw->rtc);
++		dev_err(&pdev->dev, "Unable to register device\n");
++		goto err;
++	}
++
++	return 0;
++err:
++	clk_disable_unprepare(hw->clk);
++
++	return ret;
++}
++
++static int mtk_rtc_remove(struct platform_device *pdev)
++{
++	struct mtk_rtc *hw = platform_get_drvdata(pdev);
++
++	clk_disable_unprepare(hw->clk);
++
++	return 0;
++}
++
++#ifdef CONFIG_PM_SLEEP
++static int mtk_rtc_suspend(struct device *dev)
++{
++	struct mtk_rtc *hw = dev_get_drvdata(dev);
++
++	if (device_may_wakeup(dev))
++		enable_irq_wake(hw->irq);
++
++	return 0;
++}
++
++static int mtk_rtc_resume(struct device *dev)
++{
++	struct mtk_rtc *hw = dev_get_drvdata(dev);
++
++	if (device_may_wakeup(dev))
++		disable_irq_wake(hw->irq);
++
++	return 0;
++}
++
++static SIMPLE_DEV_PM_OPS(mtk_rtc_pm_ops, mtk_rtc_suspend, mtk_rtc_resume);
++
++#define MTK_RTC_PM_OPS (&mtk_rtc_pm_ops)
++#else	/* CONFIG_PM */
++#define MTK_RTC_PM_OPS NULL
++#endif	/* CONFIG_PM */
++
++static struct platform_driver mtk_rtc_driver = {
++	.probe	= mtk_rtc_probe,
++	.remove	= mtk_rtc_remove,
++	.driver = {
++		.name = MTK_RTC_DEV,
++		.of_match_table = mtk_rtc_match,
++		.pm = MTK_RTC_PM_OPS,
++	},
++};
++
++module_platform_driver(mtk_rtc_driver);
++
++MODULE_DESCRIPTION("MediaTek SoC based RTC Driver");
++MODULE_AUTHOR("Sean Wang <sean.wang@mediatek.com>");
++MODULE_LICENSE("GPL");
+-- 
+2.11.0
+
diff --git a/target/linux/mediatek/patches-4.14/0139-rtc-mediatek-enhance-the-description-for-MediaTek-PM.patch b/target/linux/mediatek/patches-4.14/0139-rtc-mediatek-enhance-the-description-for-MediaTek-PM.patch
new file mode 100644
index 0000000000..d492731669
--- /dev/null
+++ b/target/linux/mediatek/patches-4.14/0139-rtc-mediatek-enhance-the-description-for-MediaTek-PM.patch
@@ -0,0 +1,44 @@
+From ff4f8c2c894f1e6b5b5551571e22b2f947545bff Mon Sep 17 00:00:00 2001
+From: Sean Wang <sean.wang@mediatek.com>
+Date: Mon, 23 Oct 2017 15:16:46 +0800
+Subject: [PATCH 139/224] rtc: mediatek: enhance the description for MediaTek
+ PMIC based RTC
+
+Give a better description for original MediaTek RTC driver as PMIC based
+RTC in order to distinguish SoC based RTC. Also turning all words with
+Mediatek to MediaTek here.
+
+Cc: Eddie Huang <eddie.huang@mediatek.com>
+Signed-off-by: Sean Wang <sean.wang@mediatek.com>
+Acked-by: Eddie Huang <eddie.huang@mediatek.com>
+Signed-off-by: Alexandre Belloni <alexandre.belloni@free-electrons.com>
+---
+ drivers/rtc/Kconfig | 8 ++++----
+ 1 file changed, 4 insertions(+), 4 deletions(-)
+
+diff --git a/drivers/rtc/Kconfig b/drivers/rtc/Kconfig
+index 322752ebc5a7..616fe53c788e 100644
+--- a/drivers/rtc/Kconfig
++++ b/drivers/rtc/Kconfig
+@@ -1706,14 +1706,14 @@ config RTC_DRV_MOXART
+ 	   will be called rtc-moxart
+ 
+ config RTC_DRV_MT6397
+-	tristate "Mediatek Real Time Clock driver"
++	tristate "MediaTek PMIC based RTC"
+ 	depends on MFD_MT6397 || (COMPILE_TEST && IRQ_DOMAIN)
+ 	help
+-	  This selects the Mediatek(R) RTC driver. RTC is part of Mediatek
++	  This selects the MediaTek(R) RTC driver. RTC is part of MediaTek
+ 	  MT6397 PMIC. You should enable MT6397 PMIC MFD before select
+-	  Mediatek(R) RTC driver.
++	  MediaTek(R) RTC driver.
+ 
+-	  If you want to use Mediatek(R) RTC interface, select Y or M here.
++	  If you want to use MediaTek(R) RTC interface, select Y or M here.
+ 
+ config RTC_DRV_MT7622
+ 	tristate "MediaTek SoC based RTC"
+-- 
+2.11.0
+
diff --git a/target/linux/mediatek/patches-4.14/0140-mtd-nand-mtk-change-the-compile-sequence-of-mtk_nand.patch b/target/linux/mediatek/patches-4.14/0140-mtd-nand-mtk-change-the-compile-sequence-of-mtk_nand.patch
new file mode 100644
index 0000000000..6a31a60b28
--- /dev/null
+++ b/target/linux/mediatek/patches-4.14/0140-mtd-nand-mtk-change-the-compile-sequence-of-mtk_nand.patch
@@ -0,0 +1,36 @@
+From 71f568692a6d0a746d72c32d46a1bc09486b9dbb Mon Sep 17 00:00:00 2001
+From: Xiaolei Li <xiaolei.li@mediatek.com>
+Date: Sat, 28 Oct 2017 14:52:23 +0800
+Subject: [PATCH 140/224] mtd: nand: mtk: change the compile sequence of
+ mtk_nand.o and mtk_ecc.o
+
+There will get mtk ecc handler during mtk nand probe now.
+If mtk ecc module is not initialized, then mtk nand probe will return
+-EPROBE_DEFER, and retry later.
+
+Change the compile sequence of mtk_nand.o and mtk_ecc.o, initialize mtk
+ecc module before mtk nand module. This makes mtk nand module initialized
+as soon as possible.
+
+Signed-off-by: Xiaolei Li <xiaolei.li@mediatek.com>
+Signed-off-by: Boris Brezillon <boris.brezillon@free-electrons.com>
+---
+ drivers/mtd/nand/Makefile | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/mtd/nand/Makefile b/drivers/mtd/nand/Makefile
+index ade5fc4c3819..57f4cdedf137 100644
+--- a/drivers/mtd/nand/Makefile
++++ b/drivers/mtd/nand/Makefile
+@@ -58,7 +58,7 @@ 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_QCOM)		+= qcom_nandc.o
+-obj-$(CONFIG_MTD_NAND_MTK)		+= mtk_nand.o mtk_ecc.o
++obj-$(CONFIG_MTD_NAND_MTK)		+= mtk_ecc.o mtk_nand.o
+ 
+ nand-objs := nand_base.o nand_bbt.o nand_timings.o nand_ids.o
+ nand-objs += nand_amd.o
+-- 
+2.11.0
+
diff --git a/target/linux/mediatek/patches-4.14/0142-mmc-dt-bindings-Add-reg-source_cg-latch-ck-for-Media.patch b/target/linux/mediatek/patches-4.14/0142-mmc-dt-bindings-Add-reg-source_cg-latch-ck-for-Media.patch
new file mode 100644
index 0000000000..77190abd76
--- /dev/null
+++ b/target/linux/mediatek/patches-4.14/0142-mmc-dt-bindings-Add-reg-source_cg-latch-ck-for-Media.patch
@@ -0,0 +1,65 @@
+From 9ff279fef1a47a152993bf23f8d75fd233c27015 Mon Sep 17 00:00:00 2001
+From: Chaotian Jing <chaotian.jing@mediatek.com>
+Date: Mon, 16 Oct 2017 09:46:28 +0800
+Subject: [PATCH 142/224] mmc: dt-bindings: Add reg/source_cg/latch-ck for
+ Mediatek MMC bindings
+
+Change the comptiable for support of multi-platform
+Make compatible explicit, as MMC host of mt8173 has difference with
+mt8135(mt8173 supports hs400 and hs400_tune),so that need separate
+mt8173/mt8135 compatible name.
+Add description for reg
+Add description for source_cg
+Add description for mediatek,latch-ck
+Note that source_cg and mediatek,latch-ck are optional for some projects,
+eg, MT2701 do not have source_cg, and MT2712 do not need
+mediatek,latch-ck
+
+Signed-off-by: Chaotian Jing <chaotian.jing@mediatek.com>
+Acked-by: Rob Herring <robh@kernel.org>
+Tested-by: Sean Wang <sean.wang@mediatek.com>
+Signed-off-by: Ulf Hansson <ulf.hansson@linaro.org>
+---
+ Documentation/devicetree/bindings/mmc/mtk-sd.txt | 18 +++++++++++++++---
+ 1 file changed, 15 insertions(+), 3 deletions(-)
+
+diff --git a/Documentation/devicetree/bindings/mmc/mtk-sd.txt b/Documentation/devicetree/bindings/mmc/mtk-sd.txt
+index 4182ea36ca5b..72d2a734ab85 100644
+--- a/Documentation/devicetree/bindings/mmc/mtk-sd.txt
++++ b/Documentation/devicetree/bindings/mmc/mtk-sd.txt
+@@ -7,10 +7,18 @@ This file documents differences between the core properties in mmc.txt
+ and the properties used by the msdc driver.
+ 
+ Required properties:
+-- compatible: Should be "mediatek,mt8173-mmc","mediatek,mt8135-mmc"
++- compatible: value should be either of the following.
++	"mediatek,mt8135-mmc": for mmc host ip compatible with mt8135
++	"mediatek,mt8173-mmc": for mmc host ip compatible with mt8173
++	"mediatek,mt2701-mmc": for mmc host ip compatible with mt2701
++	"mediatek,mt2712-mmc": for mmc host ip compatible with mt2712
++- reg: physical base address of the controller and length
+ - interrupts: Should contain MSDC interrupt number
+-- clocks: MSDC source clock, HCLK
+-- clock-names: "source", "hclk"
++- clocks: Should contain phandle for the clock feeding the MMC controller
++- clock-names: Should contain the following:
++	"source" - source clock (required)
++	"hclk" - HCLK which used for host (required)
++	"source_cg" - independent source clock gate (required for MT2712)
+ - pinctrl-names: should be "default", "state_uhs"
+ - pinctrl-0: should contain default/high speed pin ctrl
+ - pinctrl-1: should contain uhs mode pin ctrl
+@@ -30,6 +38,10 @@ Optional properties:
+ - mediatek,hs400-cmd-resp-sel-rising:  HS400 command response sample selection
+ 				       If present,HS400 command responses are sampled on rising edges.
+ 				       If not present,HS400 command responses are sampled on falling edges.
++- mediatek,latch-ck: Some SoCs do not support enhance_rx, need set correct latch-ck to avoid data crc
++		     error caused by stop clock(fifo full)
++		     Valid range = [0:0x7]. if not present, default value is 0.
++		     applied to compatible "mediatek,mt2701-mmc".
+ 
+ Examples:
+ mmc0: mmc@11230000 {
+-- 
+2.11.0
+
diff --git a/target/linux/mediatek/patches-4.14/0143-mmc-mediatek-add-support-of-mt2701-mt2712.patch b/target/linux/mediatek/patches-4.14/0143-mmc-mediatek-add-support-of-mt2701-mt2712.patch
new file mode 100644
index 0000000000..d315eda865
--- /dev/null
+++ b/target/linux/mediatek/patches-4.14/0143-mmc-mediatek-add-support-of-mt2701-mt2712.patch
@@ -0,0 +1,192 @@
+From 8119f3e147deaf97a66e953fecf3d2b0edbb07fd Mon Sep 17 00:00:00 2001
+From: Chaotian Jing <chaotian.jing@mediatek.com>
+Date: Mon, 16 Oct 2017 09:46:29 +0800
+Subject: [PATCH 143/224] mmc: mediatek: add support of mt2701/mt2712
+
+mt2701/mt2712 has 12bit clock div, which is not compatible with
+mt8135/mt8173. and, some additional features will be added in
+mt2701/mt2712, so that need distinguish it by comatibale name.
+
+Signed-off-by: Chaotian Jing <chaotian.jing@mediatek.com>
+Tested-by: Sean Wang <sean.wang@mediatek.com>
+Signed-off-by: Ulf Hansson <ulf.hansson@linaro.org>
+---
+ drivers/mmc/host/mtk-sd.c | 82 +++++++++++++++++++++++++++++++++++++++--------
+ 1 file changed, 69 insertions(+), 13 deletions(-)
+
+diff --git a/drivers/mmc/host/mtk-sd.c b/drivers/mmc/host/mtk-sd.c
+index 267f7ab08420..643c795f1bdd 100644
+--- a/drivers/mmc/host/mtk-sd.c
++++ b/drivers/mmc/host/mtk-sd.c
+@@ -95,6 +95,9 @@
+ #define MSDC_CFG_CKDIV          (0xff << 8)	/* RW */
+ #define MSDC_CFG_CKMOD          (0x3 << 16)	/* RW */
+ #define MSDC_CFG_HS400_CK_MODE  (0x1 << 18)	/* RW */
++#define MSDC_CFG_HS400_CK_MODE_EXTRA  (0x1 << 22)	/* RW */
++#define MSDC_CFG_CKDIV_EXTRA    (0xfff << 8)	/* RW */
++#define MSDC_CFG_CKMOD_EXTRA    (0x3 << 20)	/* RW */
+ 
+ /* MSDC_IOCON mask */
+ #define MSDC_IOCON_SDR104CKS    (0x1 << 0)	/* RW */
+@@ -295,6 +298,10 @@ struct msdc_save_para {
+ 	u32 emmc50_cfg0;
+ };
+ 
++struct mtk_mmc_compatible {
++	u8 clk_div_bits;
++};
++
+ struct msdc_tune_para {
+ 	u32 iocon;
+ 	u32 pad_tune;
+@@ -309,6 +316,7 @@ struct msdc_delay_phase {
+ 
+ struct msdc_host {
+ 	struct device *dev;
++	const struct mtk_mmc_compatible *dev_comp;
+ 	struct mmc_host *mmc;	/* mmc structure */
+ 	int cmd_rsp;
+ 
+@@ -350,6 +358,31 @@ struct msdc_host {
+ 	struct msdc_tune_para saved_tune_para; /* tune result of CMD21/CMD19 */
+ };
+ 
++static const struct mtk_mmc_compatible mt8135_compat = {
++	.clk_div_bits = 8,
++};
++
++static const struct mtk_mmc_compatible mt8173_compat = {
++	.clk_div_bits = 8,
++};
++
++static const struct mtk_mmc_compatible mt2701_compat = {
++	.clk_div_bits = 12,
++};
++
++static const struct mtk_mmc_compatible mt2712_compat = {
++	.clk_div_bits = 12,
++};
++
++static const struct of_device_id msdc_of_ids[] = {
++	{ .compatible = "mediatek,mt8135-mmc", .data = &mt8135_compat},
++	{ .compatible = "mediatek,mt8173-mmc", .data = &mt8173_compat},
++	{ .compatible = "mediatek,mt2701-mmc", .data = &mt2701_compat},
++	{ .compatible = "mediatek,mt2712-mmc", .data = &mt2712_compat},
++	{}
++};
++MODULE_DEVICE_TABLE(of, msdc_of_ids);
++
+ static void sdr_set_bits(void __iomem *reg, u32 bs)
+ {
+ 	u32 val = readl(reg);
+@@ -509,7 +542,12 @@ static void msdc_set_timeout(struct msdc_host *host, u32 ns, u32 clks)
+ 		timeout = (ns + clk_ns - 1) / clk_ns + clks;
+ 		/* in 1048576 sclk cycle unit */
+ 		timeout = (timeout + (0x1 << 20) - 1) >> 20;
+-		sdr_get_field(host->base + MSDC_CFG, MSDC_CFG_CKMOD, &mode);
++		if (host->dev_comp->clk_div_bits == 8)
++			sdr_get_field(host->base + MSDC_CFG,
++				      MSDC_CFG_CKMOD, &mode);
++		else
++			sdr_get_field(host->base + MSDC_CFG,
++				      MSDC_CFG_CKMOD_EXTRA, &mode);
+ 		/*DDR mode will double the clk cycles for data timeout */
+ 		timeout = mode >= 2 ? timeout * 2 : timeout;
+ 		timeout = timeout > 1 ? timeout - 1 : 0;
+@@ -548,7 +586,11 @@ static void msdc_set_mclk(struct msdc_host *host, unsigned char timing, u32 hz)
+ 
+ 	flags = readl(host->base + MSDC_INTEN);
+ 	sdr_clr_bits(host->base + MSDC_INTEN, flags);
+-	sdr_clr_bits(host->base + MSDC_CFG, MSDC_CFG_HS400_CK_MODE);
++	if (host->dev_comp->clk_div_bits == 8)
++		sdr_clr_bits(host->base + MSDC_CFG, MSDC_CFG_HS400_CK_MODE);
++	else
++		sdr_clr_bits(host->base + MSDC_CFG,
++			     MSDC_CFG_HS400_CK_MODE_EXTRA);
+ 	if (timing == MMC_TIMING_UHS_DDR50 ||
+ 	    timing == MMC_TIMING_MMC_DDR52 ||
+ 	    timing == MMC_TIMING_MMC_HS400) {
+@@ -568,8 +610,12 @@ static void msdc_set_mclk(struct msdc_host *host, unsigned char timing, u32 hz)
+ 
+ 		if (timing == MMC_TIMING_MMC_HS400 &&
+ 		    hz >= (host->src_clk_freq >> 1)) {
+-			sdr_set_bits(host->base + MSDC_CFG,
+-				     MSDC_CFG_HS400_CK_MODE);
++			if (host->dev_comp->clk_div_bits == 8)
++				sdr_set_bits(host->base + MSDC_CFG,
++					     MSDC_CFG_HS400_CK_MODE);
++			else
++				sdr_set_bits(host->base + MSDC_CFG,
++					     MSDC_CFG_HS400_CK_MODE_EXTRA);
+ 			sclk = host->src_clk_freq >> 1;
+ 			div = 0; /* div is ignore when bit18 is set */
+ 		}
+@@ -587,8 +633,15 @@ static void msdc_set_mclk(struct msdc_host *host, unsigned char timing, u32 hz)
+ 			sclk = (host->src_clk_freq >> 2) / div;
+ 		}
+ 	}
+-	sdr_set_field(host->base + MSDC_CFG, MSDC_CFG_CKMOD | MSDC_CFG_CKDIV,
+-		      (mode << 8) | div);
++	if (host->dev_comp->clk_div_bits == 8)
++		sdr_set_field(host->base + MSDC_CFG,
++			      MSDC_CFG_CKMOD | MSDC_CFG_CKDIV,
++			      (mode << 8) | div);
++	else
++		sdr_set_field(host->base + MSDC_CFG,
++			      MSDC_CFG_CKMOD_EXTRA | MSDC_CFG_CKDIV_EXTRA,
++			      (mode << 12) | div);
++
+ 	sdr_set_bits(host->base + MSDC_CFG, MSDC_CFG_CKPDN);
+ 	while (!(readl(host->base + MSDC_CFG) & MSDC_CFG_CKSTB))
+ 		cpu_relax();
+@@ -1617,12 +1670,17 @@ static int msdc_drv_probe(struct platform_device *pdev)
+ 	struct mmc_host *mmc;
+ 	struct msdc_host *host;
+ 	struct resource *res;
++	const struct of_device_id *of_id;
+ 	int ret;
+ 
+ 	if (!pdev->dev.of_node) {
+ 		dev_err(&pdev->dev, "No DT found\n");
+ 		return -EINVAL;
+ 	}
++
++	of_id = of_match_node(msdc_of_ids, pdev->dev.of_node);
++	if (!of_id)
++		return -EINVAL;
+ 	/* Allocate MMC host for this device */
+ 	mmc = mmc_alloc_host(sizeof(struct msdc_host), &pdev->dev);
+ 	if (!mmc)
+@@ -1686,11 +1744,15 @@ static int msdc_drv_probe(struct platform_device *pdev)
+ 	msdc_of_property_parse(pdev, host);
+ 
+ 	host->dev = &pdev->dev;
++	host->dev_comp = of_id->data;
+ 	host->mmc = mmc;
+ 	host->src_clk_freq = clk_get_rate(host->src_clk);
+ 	/* Set host parameters to mmc */
+ 	mmc->ops = &mt_msdc_ops;
+-	mmc->f_min = DIV_ROUND_UP(host->src_clk_freq, 4 * 255);
++	if (host->dev_comp->clk_div_bits == 8)
++		mmc->f_min = DIV_ROUND_UP(host->src_clk_freq, 4 * 255);
++	else
++		mmc->f_min = DIV_ROUND_UP(host->src_clk_freq, 4 * 4095);
+ 
+ 	mmc->caps |= MMC_CAP_ERASE | MMC_CAP_CMD23;
+ 	/* MMC core transfer sizes tunable parameters */
+@@ -1839,12 +1901,6 @@ static const struct dev_pm_ops msdc_dev_pm_ops = {
+ 	SET_RUNTIME_PM_OPS(msdc_runtime_suspend, msdc_runtime_resume, NULL)
+ };
+ 
+-static const struct of_device_id msdc_of_ids[] = {
+-	{   .compatible = "mediatek,mt8135-mmc", },
+-	{}
+-};
+-MODULE_DEVICE_TABLE(of, msdc_of_ids);
+-
+ static struct platform_driver mt_msdc_driver = {
+ 	.probe = msdc_drv_probe,
+ 	.remove = msdc_drv_remove,
+-- 
+2.11.0
+
diff --git a/target/linux/mediatek/patches-4.14/0144-dt-bindings-ARM-Mediatek-Document-bindings-for-MT271.patch b/target/linux/mediatek/patches-4.14/0144-dt-bindings-ARM-Mediatek-Document-bindings-for-MT271.patch
new file mode 100644
index 0000000000..901e6757ae
--- /dev/null
+++ b/target/linux/mediatek/patches-4.14/0144-dt-bindings-ARM-Mediatek-Document-bindings-for-MT271.patch
@@ -0,0 +1,226 @@
+From 815d90faddd22e05f05623086a9c42187fbfb1d8 Mon Sep 17 00:00:00 2001
+From: "weiyi.lu@mediatek.com" <weiyi.lu@mediatek.com>
+Date: Mon, 23 Oct 2017 12:10:32 +0800
+Subject: [PATCH 144/224] dt-bindings: ARM: Mediatek: Document bindings for
+ MT2712
+
+This patch adds the binding documentation for apmixedsys, bdpsys,
+imgsys, imgsys, infracfg, mcucfg, mfgcfg, mmsys, pericfg, topckgen,
+vdecsys and vencsys for Mediatek MT2712.
+
+Acked-by: Rob Herring <robh@kernel.org>
+Signed-off-by: Weiyi Lu <weiyi.lu@mediatek.com>
+Signed-off-by: Stephen Boyd <sboyd@codeaurora.org>
+---
+ .../bindings/arm/mediatek/mediatek,apmixedsys.txt  |  1 +
+ .../bindings/arm/mediatek/mediatek,bdpsys.txt      |  1 +
+ .../bindings/arm/mediatek/mediatek,imgsys.txt      |  1 +
+ .../bindings/arm/mediatek/mediatek,infracfg.txt    |  1 +
+ .../bindings/arm/mediatek/mediatek,jpgdecsys.txt   | 22 ++++++++++++++++++++++
+ .../bindings/arm/mediatek/mediatek,mcucfg.txt      | 22 ++++++++++++++++++++++
+ .../bindings/arm/mediatek/mediatek,mfgcfg.txt      | 22 ++++++++++++++++++++++
+ .../bindings/arm/mediatek/mediatek,mmsys.txt       |  1 +
+ .../bindings/arm/mediatek/mediatek,pericfg.txt     |  1 +
+ .../bindings/arm/mediatek/mediatek,topckgen.txt    |  1 +
+ .../bindings/arm/mediatek/mediatek,vdecsys.txt     |  1 +
+ .../bindings/arm/mediatek/mediatek,vencsys.txt     |  1 +
+ 12 files changed, 75 insertions(+)
+ create mode 100644 Documentation/devicetree/bindings/arm/mediatek/mediatek,jpgdecsys.txt
+ create mode 100644 Documentation/devicetree/bindings/arm/mediatek/mediatek,mcucfg.txt
+ create mode 100644 Documentation/devicetree/bindings/arm/mediatek/mediatek,mfgcfg.txt
+
+diff --git a/Documentation/devicetree/bindings/arm/mediatek/mediatek,apmixedsys.txt b/Documentation/devicetree/bindings/arm/mediatek/mediatek,apmixedsys.txt
+index cd977db7630c..19fc116346d6 100644
+--- a/Documentation/devicetree/bindings/arm/mediatek/mediatek,apmixedsys.txt
++++ b/Documentation/devicetree/bindings/arm/mediatek/mediatek,apmixedsys.txt
+@@ -7,6 +7,7 @@ Required Properties:
+ 
+ - compatible: Should be one of:
+ 	- "mediatek,mt2701-apmixedsys"
++	- "mediatek,mt2712-apmixedsys", "syscon"
+ 	- "mediatek,mt6797-apmixedsys"
+ 	- "mediatek,mt8135-apmixedsys"
+ 	- "mediatek,mt8173-apmixedsys"
+diff --git a/Documentation/devicetree/bindings/arm/mediatek/mediatek,bdpsys.txt b/Documentation/devicetree/bindings/arm/mediatek/mediatek,bdpsys.txt
+index 4137196dd686..4010e37c53a0 100644
+--- a/Documentation/devicetree/bindings/arm/mediatek/mediatek,bdpsys.txt
++++ b/Documentation/devicetree/bindings/arm/mediatek/mediatek,bdpsys.txt
+@@ -7,6 +7,7 @@ Required Properties:
+ 
+ - compatible: Should be:
+ 	- "mediatek,mt2701-bdpsys", "syscon"
++	- "mediatek,mt2712-bdpsys", "syscon"
+ - #clock-cells: Must be 1
+ 
+ The bdpsys controller uses the common clk binding from
+diff --git a/Documentation/devicetree/bindings/arm/mediatek/mediatek,imgsys.txt b/Documentation/devicetree/bindings/arm/mediatek/mediatek,imgsys.txt
+index 047b11ae5f45..868bd51a98be 100644
+--- a/Documentation/devicetree/bindings/arm/mediatek/mediatek,imgsys.txt
++++ b/Documentation/devicetree/bindings/arm/mediatek/mediatek,imgsys.txt
+@@ -7,6 +7,7 @@ Required Properties:
+ 
+ - compatible: Should be one of:
+ 	- "mediatek,mt2701-imgsys", "syscon"
++	- "mediatek,mt2712-imgsys", "syscon"
+ 	- "mediatek,mt6797-imgsys", "syscon"
+ 	- "mediatek,mt8173-imgsys", "syscon"
+ - #clock-cells: Must be 1
+diff --git a/Documentation/devicetree/bindings/arm/mediatek/mediatek,infracfg.txt b/Documentation/devicetree/bindings/arm/mediatek/mediatek,infracfg.txt
+index 58d58e2006b8..a3430cd96d0f 100644
+--- a/Documentation/devicetree/bindings/arm/mediatek/mediatek,infracfg.txt
++++ b/Documentation/devicetree/bindings/arm/mediatek/mediatek,infracfg.txt
+@@ -8,6 +8,7 @@ Required Properties:
+ 
+ - compatible: Should be one of:
+ 	- "mediatek,mt2701-infracfg", "syscon"
++	- "mediatek,mt2712-infracfg", "syscon"
+ 	- "mediatek,mt6797-infracfg", "syscon"
+ 	- "mediatek,mt8135-infracfg", "syscon"
+ 	- "mediatek,mt8173-infracfg", "syscon"
+diff --git a/Documentation/devicetree/bindings/arm/mediatek/mediatek,jpgdecsys.txt b/Documentation/devicetree/bindings/arm/mediatek/mediatek,jpgdecsys.txt
+new file mode 100644
+index 000000000000..2df799cd06a7
+--- /dev/null
++++ b/Documentation/devicetree/bindings/arm/mediatek/mediatek,jpgdecsys.txt
+@@ -0,0 +1,22 @@
++Mediatek jpgdecsys controller
++============================
++
++The Mediatek jpgdecsys controller provides various clocks to the system.
++
++Required Properties:
++
++- compatible: Should be:
++	- "mediatek,mt2712-jpgdecsys", "syscon"
++- #clock-cells: Must be 1
++
++The jpgdecsys controller uses the common clk binding from
++Documentation/devicetree/bindings/clock/clock-bindings.txt
++The available clocks are defined in dt-bindings/clock/mt*-clk.h.
++
++Example:
++
++jpgdecsys: syscon@19000000 {
++	compatible = "mediatek,mt2712-jpgdecsys", "syscon";
++	reg = <0 0x19000000 0 0x1000>;
++	#clock-cells = <1>;
++};
+diff --git a/Documentation/devicetree/bindings/arm/mediatek/mediatek,mcucfg.txt b/Documentation/devicetree/bindings/arm/mediatek/mediatek,mcucfg.txt
+new file mode 100644
+index 000000000000..b8fb03f3613e
+--- /dev/null
++++ b/Documentation/devicetree/bindings/arm/mediatek/mediatek,mcucfg.txt
+@@ -0,0 +1,22 @@
++Mediatek mcucfg controller
++============================
++
++The Mediatek mcucfg controller provides various clocks to the system.
++
++Required Properties:
++
++- compatible: Should be one of:
++	- "mediatek,mt2712-mcucfg", "syscon"
++- #clock-cells: Must be 1
++
++The mcucfg controller uses the common clk binding from
++Documentation/devicetree/bindings/clock/clock-bindings.txt
++The available clocks are defined in dt-bindings/clock/mt*-clk.h.
++
++Example:
++
++mcucfg: syscon@10220000 {
++	compatible = "mediatek,mt2712-mcucfg", "syscon";
++	reg = <0 0x10220000 0 0x1000>;
++	#clock-cells = <1>;
++};
+diff --git a/Documentation/devicetree/bindings/arm/mediatek/mediatek,mfgcfg.txt b/Documentation/devicetree/bindings/arm/mediatek/mediatek,mfgcfg.txt
+new file mode 100644
+index 000000000000..859e67b416d5
+--- /dev/null
++++ b/Documentation/devicetree/bindings/arm/mediatek/mediatek,mfgcfg.txt
+@@ -0,0 +1,22 @@
++Mediatek mfgcfg controller
++============================
++
++The Mediatek mfgcfg controller provides various clocks to the system.
++
++Required Properties:
++
++- compatible: Should be one of:
++	- "mediatek,mt2712-mfgcfg", "syscon"
++- #clock-cells: Must be 1
++
++The mfgcfg controller uses the common clk binding from
++Documentation/devicetree/bindings/clock/clock-bindings.txt
++The available clocks are defined in dt-bindings/clock/mt*-clk.h.
++
++Example:
++
++mfgcfg: syscon@13000000 {
++	compatible = "mediatek,mt2712-mfgcfg", "syscon";
++	reg = <0 0x13000000 0 0x1000>;
++	#clock-cells = <1>;
++};
+diff --git a/Documentation/devicetree/bindings/arm/mediatek/mediatek,mmsys.txt b/Documentation/devicetree/bindings/arm/mediatek/mediatek,mmsys.txt
+index 70529e0b58e9..4eb8bbe15c01 100644
+--- a/Documentation/devicetree/bindings/arm/mediatek/mediatek,mmsys.txt
++++ b/Documentation/devicetree/bindings/arm/mediatek/mediatek,mmsys.txt
+@@ -7,6 +7,7 @@ Required Properties:
+ 
+ - compatible: Should be one of:
+ 	- "mediatek,mt2701-mmsys", "syscon"
++	- "mediatek,mt2712-mmsys", "syscon"
+ 	- "mediatek,mt6797-mmsys", "syscon"
+ 	- "mediatek,mt8173-mmsys", "syscon"
+ - #clock-cells: Must be 1
+diff --git a/Documentation/devicetree/bindings/arm/mediatek/mediatek,pericfg.txt b/Documentation/devicetree/bindings/arm/mediatek/mediatek,pericfg.txt
+index e494366782aa..d9f092eb3550 100644
+--- a/Documentation/devicetree/bindings/arm/mediatek/mediatek,pericfg.txt
++++ b/Documentation/devicetree/bindings/arm/mediatek/mediatek,pericfg.txt
+@@ -8,6 +8,7 @@ Required Properties:
+ 
+ - compatible: Should be one of:
+ 	- "mediatek,mt2701-pericfg", "syscon"
++	- "mediatek,mt2712-pericfg", "syscon"
+ 	- "mediatek,mt8135-pericfg", "syscon"
+ 	- "mediatek,mt8173-pericfg", "syscon"
+ - #clock-cells: Must be 1
+diff --git a/Documentation/devicetree/bindings/arm/mediatek/mediatek,topckgen.txt b/Documentation/devicetree/bindings/arm/mediatek/mediatek,topckgen.txt
+index ec93ecbb9f3c..2024fc909d69 100644
+--- a/Documentation/devicetree/bindings/arm/mediatek/mediatek,topckgen.txt
++++ b/Documentation/devicetree/bindings/arm/mediatek/mediatek,topckgen.txt
+@@ -7,6 +7,7 @@ Required Properties:
+ 
+ - compatible: Should be one of:
+ 	- "mediatek,mt2701-topckgen"
++	- "mediatek,mt2712-topckgen", "syscon"
+ 	- "mediatek,mt6797-topckgen"
+ 	- "mediatek,mt8135-topckgen"
+ 	- "mediatek,mt8173-topckgen"
+diff --git a/Documentation/devicetree/bindings/arm/mediatek/mediatek,vdecsys.txt b/Documentation/devicetree/bindings/arm/mediatek/mediatek,vdecsys.txt
+index d150104f928a..ea40d05089f8 100644
+--- a/Documentation/devicetree/bindings/arm/mediatek/mediatek,vdecsys.txt
++++ b/Documentation/devicetree/bindings/arm/mediatek/mediatek,vdecsys.txt
+@@ -7,6 +7,7 @@ Required Properties:
+ 
+ - compatible: Should be one of:
+ 	- "mediatek,mt2701-vdecsys", "syscon"
++	- "mediatek,mt2712-vdecsys", "syscon"
+ 	- "mediatek,mt6797-vdecsys", "syscon"
+ 	- "mediatek,mt8173-vdecsys", "syscon"
+ - #clock-cells: Must be 1
+diff --git a/Documentation/devicetree/bindings/arm/mediatek/mediatek,vencsys.txt b/Documentation/devicetree/bindings/arm/mediatek/mediatek,vencsys.txt
+index 8a93be643647..851545357e94 100644
+--- a/Documentation/devicetree/bindings/arm/mediatek/mediatek,vencsys.txt
++++ b/Documentation/devicetree/bindings/arm/mediatek/mediatek,vencsys.txt
+@@ -6,6 +6,7 @@ The Mediatek vencsys controller provides various clocks to the system.
+ Required Properties:
+ 
+ - compatible: Should be one of:
++	- "mediatek,mt2712-vencsys", "syscon"
+ 	- "mediatek,mt6797-vencsys", "syscon"
+ 	- "mediatek,mt8173-vencsys", "syscon"
+ - #clock-cells: Must be 1
+-- 
+2.11.0
+
diff --git a/target/linux/mediatek/patches-4.14/0145-clk-mediatek-Add-dt-bindings-for-MT2712-clocks.patch b/target/linux/mediatek/patches-4.14/0145-clk-mediatek-Add-dt-bindings-for-MT2712-clocks.patch
new file mode 100644
index 0000000000..9405732563
--- /dev/null
+++ b/target/linux/mediatek/patches-4.14/0145-clk-mediatek-Add-dt-bindings-for-MT2712-clocks.patch
@@ -0,0 +1,452 @@
+From 8a64bf0c04a4b7670cf56be5b0ae63fe9d6ecd56 Mon Sep 17 00:00:00 2001
+From: "weiyi.lu@mediatek.com" <weiyi.lu@mediatek.com>
+Date: Mon, 23 Oct 2017 12:10:33 +0800
+Subject: [PATCH 145/224] clk: mediatek: Add dt-bindings for MT2712 clocks
+
+Add MT2712 clock dt-bindings, include topckgen, apmixedsys,
+infracfg, pericfg, mcucfg and subsystem clocks.
+
+Signed-off-by: Weiyi Lu <weiyi.lu@mediatek.com>
+Acked-by: Rob Herring <robh@kernel.org>
+Signed-off-by: Stephen Boyd <sboyd@codeaurora.org>
+---
+ include/dt-bindings/clock/mt2712-clk.h | 427 +++++++++++++++++++++++++++++++++
+ 1 file changed, 427 insertions(+)
+ create mode 100644 include/dt-bindings/clock/mt2712-clk.h
+
+diff --git a/include/dt-bindings/clock/mt2712-clk.h b/include/dt-bindings/clock/mt2712-clk.h
+new file mode 100644
+index 000000000000..48a8e797a617
+--- /dev/null
++++ b/include/dt-bindings/clock/mt2712-clk.h
+@@ -0,0 +1,427 @@
++/*
++ * Copyright (c) 2017 MediaTek Inc.
++ * Author: Weiyi Lu <weiyi.lu@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 _DT_BINDINGS_CLK_MT2712_H
++#define _DT_BINDINGS_CLK_MT2712_H
++
++/* APMIXEDSYS */
++
++#define CLK_APMIXED_MAINPLL		0
++#define CLK_APMIXED_UNIVPLL		1
++#define CLK_APMIXED_VCODECPLL		2
++#define CLK_APMIXED_VENCPLL		3
++#define CLK_APMIXED_APLL1		4
++#define CLK_APMIXED_APLL2		5
++#define CLK_APMIXED_LVDSPLL		6
++#define CLK_APMIXED_LVDSPLL2		7
++#define CLK_APMIXED_MSDCPLL		8
++#define CLK_APMIXED_MSDCPLL2		9
++#define CLK_APMIXED_TVDPLL		10
++#define CLK_APMIXED_MMPLL		11
++#define CLK_APMIXED_ARMCA35PLL		12
++#define CLK_APMIXED_ARMCA72PLL		13
++#define CLK_APMIXED_ETHERPLL		14
++#define CLK_APMIXED_NR_CLK		15
++
++/* TOPCKGEN */
++
++#define CLK_TOP_ARMCA35PLL		0
++#define CLK_TOP_ARMCA35PLL_600M		1
++#define CLK_TOP_ARMCA35PLL_400M		2
++#define CLK_TOP_ARMCA72PLL		3
++#define CLK_TOP_SYSPLL			4
++#define CLK_TOP_SYSPLL_D2		5
++#define CLK_TOP_SYSPLL1_D2		6
++#define CLK_TOP_SYSPLL1_D4		7
++#define CLK_TOP_SYSPLL1_D8		8
++#define CLK_TOP_SYSPLL1_D16		9
++#define CLK_TOP_SYSPLL_D3		10
++#define CLK_TOP_SYSPLL2_D2		11
++#define CLK_TOP_SYSPLL2_D4		12
++#define CLK_TOP_SYSPLL_D5		13
++#define CLK_TOP_SYSPLL3_D2		14
++#define CLK_TOP_SYSPLL3_D4		15
++#define CLK_TOP_SYSPLL_D7		16
++#define CLK_TOP_SYSPLL4_D2		17
++#define CLK_TOP_SYSPLL4_D4		18
++#define CLK_TOP_UNIVPLL			19
++#define CLK_TOP_UNIVPLL_D7		20
++#define CLK_TOP_UNIVPLL_D26		21
++#define CLK_TOP_UNIVPLL_D52		22
++#define CLK_TOP_UNIVPLL_D104		23
++#define CLK_TOP_UNIVPLL_D208		24
++#define CLK_TOP_UNIVPLL_D2		25
++#define CLK_TOP_UNIVPLL1_D2		26
++#define CLK_TOP_UNIVPLL1_D4		27
++#define CLK_TOP_UNIVPLL1_D8		28
++#define CLK_TOP_UNIVPLL_D3		29
++#define CLK_TOP_UNIVPLL2_D2		30
++#define CLK_TOP_UNIVPLL2_D4		31
++#define CLK_TOP_UNIVPLL2_D8		32
++#define CLK_TOP_UNIVPLL_D5		33
++#define CLK_TOP_UNIVPLL3_D2		34
++#define CLK_TOP_UNIVPLL3_D4		35
++#define CLK_TOP_UNIVPLL3_D8		36
++#define CLK_TOP_F_MP0_PLL1		37
++#define CLK_TOP_F_MP0_PLL2		38
++#define CLK_TOP_F_BIG_PLL1		39
++#define CLK_TOP_F_BIG_PLL2		40
++#define CLK_TOP_F_BUS_PLL1		41
++#define CLK_TOP_F_BUS_PLL2		42
++#define CLK_TOP_APLL1			43
++#define CLK_TOP_APLL1_D2		44
++#define CLK_TOP_APLL1_D4		45
++#define CLK_TOP_APLL1_D8		46
++#define CLK_TOP_APLL1_D16		47
++#define CLK_TOP_APLL2			48
++#define CLK_TOP_APLL2_D2		49
++#define CLK_TOP_APLL2_D4		50
++#define CLK_TOP_APLL2_D8		51
++#define CLK_TOP_APLL2_D16		52
++#define CLK_TOP_LVDSPLL			53
++#define CLK_TOP_LVDSPLL_D2		54
++#define CLK_TOP_LVDSPLL_D4		55
++#define CLK_TOP_LVDSPLL_D8		56
++#define CLK_TOP_LVDSPLL2		57
++#define CLK_TOP_LVDSPLL2_D2		58
++#define CLK_TOP_LVDSPLL2_D4		59
++#define CLK_TOP_LVDSPLL2_D8		60
++#define CLK_TOP_ETHERPLL_125M		61
++#define CLK_TOP_ETHERPLL_50M		62
++#define CLK_TOP_CVBS			63
++#define CLK_TOP_CVBS_D2			64
++#define CLK_TOP_SYS_26M			65
++#define CLK_TOP_MMPLL			66
++#define CLK_TOP_MMPLL_D2		67
++#define CLK_TOP_VENCPLL			68
++#define CLK_TOP_VENCPLL_D2		69
++#define CLK_TOP_VCODECPLL		70
++#define CLK_TOP_VCODECPLL_D2		71
++#define CLK_TOP_TVDPLL			72
++#define CLK_TOP_TVDPLL_D2		73
++#define CLK_TOP_TVDPLL_D4		74
++#define CLK_TOP_TVDPLL_D8		75
++#define CLK_TOP_TVDPLL_429M		76
++#define CLK_TOP_TVDPLL_429M_D2		77
++#define CLK_TOP_TVDPLL_429M_D4		78
++#define CLK_TOP_MSDCPLL			79
++#define CLK_TOP_MSDCPLL_D2		80
++#define CLK_TOP_MSDCPLL_D4		81
++#define CLK_TOP_MSDCPLL2		82
++#define CLK_TOP_MSDCPLL2_D2		83
++#define CLK_TOP_MSDCPLL2_D4		84
++#define CLK_TOP_CLK26M_D2		85
++#define CLK_TOP_D2A_ULCLK_6P5M		86
++#define CLK_TOP_VPLL3_DPIX		87
++#define CLK_TOP_VPLL_DPIX		88
++#define CLK_TOP_LTEPLL_FS26M		89
++#define CLK_TOP_DMPLL			90
++#define CLK_TOP_DSI0_LNTC		91
++#define CLK_TOP_DSI1_LNTC		92
++#define CLK_TOP_LVDSTX3_CLKDIG_CTS	93
++#define CLK_TOP_LVDSTX_CLKDIG_CTS	94
++#define CLK_TOP_CLKRTC_EXT		95
++#define CLK_TOP_CLKRTC_INT		96
++#define CLK_TOP_CSI0			97
++#define CLK_TOP_CVBSPLL			98
++#define CLK_TOP_AXI_SEL			99
++#define CLK_TOP_MEM_SEL			100
++#define CLK_TOP_MM_SEL			101
++#define CLK_TOP_PWM_SEL			102
++#define CLK_TOP_VDEC_SEL		103
++#define CLK_TOP_VENC_SEL		104
++#define CLK_TOP_MFG_SEL			105
++#define CLK_TOP_CAMTG_SEL		106
++#define CLK_TOP_UART_SEL		107
++#define CLK_TOP_SPI_SEL			108
++#define CLK_TOP_USB20_SEL		109
++#define CLK_TOP_USB30_SEL		110
++#define CLK_TOP_MSDC50_0_HCLK_SEL	111
++#define CLK_TOP_MSDC50_0_SEL		112
++#define CLK_TOP_MSDC30_1_SEL		113
++#define CLK_TOP_MSDC30_2_SEL		114
++#define CLK_TOP_MSDC30_3_SEL		115
++#define CLK_TOP_AUDIO_SEL		116
++#define CLK_TOP_AUD_INTBUS_SEL		117
++#define CLK_TOP_PMICSPI_SEL		118
++#define CLK_TOP_DPILVDS1_SEL		119
++#define CLK_TOP_ATB_SEL			120
++#define CLK_TOP_NR_SEL			121
++#define CLK_TOP_NFI2X_SEL		122
++#define CLK_TOP_IRDA_SEL		123
++#define CLK_TOP_CCI400_SEL		124
++#define CLK_TOP_AUD_1_SEL		125
++#define CLK_TOP_AUD_2_SEL		126
++#define CLK_TOP_MEM_MFG_IN_AS_SEL	127
++#define CLK_TOP_AXI_MFG_IN_AS_SEL	128
++#define CLK_TOP_SCAM_SEL		129
++#define CLK_TOP_NFIECC_SEL		130
++#define CLK_TOP_PE2_MAC_P0_SEL		131
++#define CLK_TOP_PE2_MAC_P1_SEL		132
++#define CLK_TOP_DPILVDS_SEL		133
++#define CLK_TOP_MSDC50_3_HCLK_SEL	134
++#define CLK_TOP_HDCP_SEL		135
++#define CLK_TOP_HDCP_24M_SEL		136
++#define CLK_TOP_RTC_SEL			137
++#define CLK_TOP_SPINOR_SEL		138
++#define CLK_TOP_APLL_SEL		139
++#define CLK_TOP_APLL2_SEL		140
++#define CLK_TOP_A1SYS_HP_SEL		141
++#define CLK_TOP_A2SYS_HP_SEL		142
++#define CLK_TOP_ASM_L_SEL		143
++#define CLK_TOP_ASM_M_SEL		144
++#define CLK_TOP_ASM_H_SEL		145
++#define CLK_TOP_I2SO1_SEL		146
++#define CLK_TOP_I2SO2_SEL		147
++#define CLK_TOP_I2SO3_SEL		148
++#define CLK_TOP_TDMO0_SEL		149
++#define CLK_TOP_TDMO1_SEL		150
++#define CLK_TOP_I2SI1_SEL		151
++#define CLK_TOP_I2SI2_SEL		152
++#define CLK_TOP_I2SI3_SEL		153
++#define CLK_TOP_ETHER_125M_SEL		154
++#define CLK_TOP_ETHER_50M_SEL		155
++#define CLK_TOP_JPGDEC_SEL		156
++#define CLK_TOP_SPISLV_SEL		157
++#define CLK_TOP_ETHER_50M_RMII_SEL	158
++#define CLK_TOP_CAM2TG_SEL		159
++#define CLK_TOP_DI_SEL			160
++#define CLK_TOP_TVD_SEL			161
++#define CLK_TOP_I2C_SEL			162
++#define CLK_TOP_PWM_INFRA_SEL		163
++#define CLK_TOP_MSDC0P_AES_SEL		164
++#define CLK_TOP_CMSYS_SEL		165
++#define CLK_TOP_GCPU_SEL		166
++#define CLK_TOP_AUD_APLL1_SEL		167
++#define CLK_TOP_AUD_APLL2_SEL		168
++#define CLK_TOP_DA_AUDULL_VTX_6P5M_SEL	169
++#define CLK_TOP_APLL_DIV0		170
++#define CLK_TOP_APLL_DIV1		171
++#define CLK_TOP_APLL_DIV2		172
++#define CLK_TOP_APLL_DIV3		173
++#define CLK_TOP_APLL_DIV4		174
++#define CLK_TOP_APLL_DIV5		175
++#define CLK_TOP_APLL_DIV6		176
++#define CLK_TOP_APLL_DIV7		177
++#define CLK_TOP_APLL_DIV_PDN0		178
++#define CLK_TOP_APLL_DIV_PDN1		179
++#define CLK_TOP_APLL_DIV_PDN2		180
++#define CLK_TOP_APLL_DIV_PDN3		181
++#define CLK_TOP_APLL_DIV_PDN4		182
++#define CLK_TOP_APLL_DIV_PDN5		183
++#define CLK_TOP_APLL_DIV_PDN6		184
++#define CLK_TOP_APLL_DIV_PDN7		185
++#define CLK_TOP_NR_CLK			186
++
++/* INFRACFG */
++
++#define CLK_INFRA_DBGCLK		0
++#define CLK_INFRA_GCE			1
++#define CLK_INFRA_M4U			2
++#define CLK_INFRA_KP			3
++#define CLK_INFRA_AO_SPI0		4
++#define CLK_INFRA_AO_SPI1		5
++#define CLK_INFRA_AO_UART5		6
++#define CLK_INFRA_NR_CLK		7
++
++/* PERICFG */
++
++#define CLK_PERI_NFI			0
++#define CLK_PERI_THERM			1
++#define CLK_PERI_PWM0			2
++#define CLK_PERI_PWM1			3
++#define CLK_PERI_PWM2			4
++#define CLK_PERI_PWM3			5
++#define CLK_PERI_PWM4			6
++#define CLK_PERI_PWM5			7
++#define CLK_PERI_PWM6			8
++#define CLK_PERI_PWM7			9
++#define CLK_PERI_PWM			10
++#define CLK_PERI_AP_DMA			11
++#define CLK_PERI_MSDC30_0		12
++#define CLK_PERI_MSDC30_1		13
++#define CLK_PERI_MSDC30_2		14
++#define CLK_PERI_MSDC30_3		15
++#define CLK_PERI_UART0			16
++#define CLK_PERI_UART1			17
++#define CLK_PERI_UART2			18
++#define CLK_PERI_UART3			19
++#define CLK_PERI_I2C0			20
++#define CLK_PERI_I2C1			21
++#define CLK_PERI_I2C2			22
++#define CLK_PERI_I2C3			23
++#define CLK_PERI_I2C4			24
++#define CLK_PERI_AUXADC			25
++#define CLK_PERI_SPI0			26
++#define CLK_PERI_SPI			27
++#define CLK_PERI_I2C5			28
++#define CLK_PERI_SPI2			29
++#define CLK_PERI_SPI3			30
++#define CLK_PERI_SPI5			31
++#define CLK_PERI_UART4			32
++#define CLK_PERI_SFLASH			33
++#define CLK_PERI_GMAC			34
++#define CLK_PERI_PCIE0			35
++#define CLK_PERI_PCIE1			36
++#define CLK_PERI_GMAC_PCLK		37
++#define CLK_PERI_MSDC50_0_EN		38
++#define CLK_PERI_MSDC30_1_EN		39
++#define CLK_PERI_MSDC30_2_EN		40
++#define CLK_PERI_MSDC30_3_EN		41
++#define CLK_PERI_MSDC50_0_HCLK_EN	42
++#define CLK_PERI_MSDC50_3_HCLK_EN	43
++#define CLK_PERI_NR_CLK			44
++
++/* MCUCFG */
++
++#define CLK_MCU_MP0_SEL			0
++#define CLK_MCU_MP2_SEL			1
++#define CLK_MCU_BUS_SEL			2
++#define CLK_MCU_NR_CLK			3
++
++/* MFGCFG */
++
++#define CLK_MFG_BG3D			0
++#define CLK_MFG_NR_CLK			1
++
++/* MMSYS */
++
++#define CLK_MM_SMI_COMMON		0
++#define CLK_MM_SMI_LARB0		1
++#define CLK_MM_CAM_MDP			2
++#define CLK_MM_MDP_RDMA0		3
++#define CLK_MM_MDP_RDMA1		4
++#define CLK_MM_MDP_RSZ0			5
++#define CLK_MM_MDP_RSZ1			6
++#define CLK_MM_MDP_RSZ2			7
++#define CLK_MM_MDP_TDSHP0		8
++#define CLK_MM_MDP_TDSHP1		9
++#define CLK_MM_MDP_CROP			10
++#define CLK_MM_MDP_WDMA			11
++#define CLK_MM_MDP_WROT0		12
++#define CLK_MM_MDP_WROT1		13
++#define CLK_MM_FAKE_ENG			14
++#define CLK_MM_MUTEX_32K		15
++#define CLK_MM_DISP_OVL0		16
++#define CLK_MM_DISP_OVL1		17
++#define CLK_MM_DISP_RDMA0		18
++#define CLK_MM_DISP_RDMA1		19
++#define CLK_MM_DISP_RDMA2		20
++#define CLK_MM_DISP_WDMA0		21
++#define CLK_MM_DISP_WDMA1		22
++#define CLK_MM_DISP_COLOR0		23
++#define CLK_MM_DISP_COLOR1		24
++#define CLK_MM_DISP_AAL			25
++#define CLK_MM_DISP_GAMMA		26
++#define CLK_MM_DISP_UFOE		27
++#define CLK_MM_DISP_SPLIT0		28
++#define CLK_MM_DISP_OD			29
++#define CLK_MM_DISP_PWM0_MM		30
++#define CLK_MM_DISP_PWM0_26M		31
++#define CLK_MM_DISP_PWM1_MM		32
++#define CLK_MM_DISP_PWM1_26M		33
++#define CLK_MM_DSI0_ENGINE		34
++#define CLK_MM_DSI0_DIGITAL		35
++#define CLK_MM_DSI1_ENGINE		36
++#define CLK_MM_DSI1_DIGITAL		37
++#define CLK_MM_DPI_PIXEL		38
++#define CLK_MM_DPI_ENGINE		39
++#define CLK_MM_DPI1_PIXEL		40
++#define CLK_MM_DPI1_ENGINE		41
++#define CLK_MM_LVDS_PIXEL		42
++#define CLK_MM_LVDS_CTS			43
++#define CLK_MM_SMI_LARB4		44
++#define CLK_MM_SMI_COMMON1		45
++#define CLK_MM_SMI_LARB5		46
++#define CLK_MM_MDP_RDMA2		47
++#define CLK_MM_MDP_TDSHP2		48
++#define CLK_MM_DISP_OVL2		49
++#define CLK_MM_DISP_WDMA2		50
++#define CLK_MM_DISP_COLOR2		51
++#define CLK_MM_DISP_AAL1		52
++#define CLK_MM_DISP_OD1			53
++#define CLK_MM_LVDS1_PIXEL		54
++#define CLK_MM_LVDS1_CTS		55
++#define CLK_MM_SMI_LARB7		56
++#define CLK_MM_MDP_RDMA3		57
++#define CLK_MM_MDP_WROT2		58
++#define CLK_MM_DSI2			59
++#define CLK_MM_DSI2_DIGITAL		60
++#define CLK_MM_DSI3			61
++#define CLK_MM_DSI3_DIGITAL		62
++#define CLK_MM_NR_CLK			63
++
++/* IMGSYS */
++
++#define CLK_IMG_SMI_LARB2		0
++#define CLK_IMG_SENINF_SCAM_EN		1
++#define CLK_IMG_SENINF_CAM_EN		2
++#define CLK_IMG_CAM_SV_EN		3
++#define CLK_IMG_CAM_SV1_EN		4
++#define CLK_IMG_CAM_SV2_EN		5
++#define CLK_IMG_NR_CLK			6
++
++/* BDPSYS */
++
++#define CLK_BDP_BRIDGE_B		0
++#define CLK_BDP_BRIDGE_DRAM		1
++#define CLK_BDP_LARB_DRAM		2
++#define CLK_BDP_WR_CHANNEL_VDI_PXL	3
++#define CLK_BDP_WR_CHANNEL_VDI_DRAM	4
++#define CLK_BDP_WR_CHANNEL_VDI_B	5
++#define CLK_BDP_MT_B			6
++#define CLK_BDP_DISPFMT_27M		7
++#define CLK_BDP_DISPFMT_27M_VDOUT	8
++#define CLK_BDP_DISPFMT_27_74_74	9
++#define CLK_BDP_DISPFMT_2FS		10
++#define CLK_BDP_DISPFMT_2FS_2FS74_148	11
++#define CLK_BDP_DISPFMT_B		12
++#define CLK_BDP_VDO_DRAM		13
++#define CLK_BDP_VDO_2FS			14
++#define CLK_BDP_VDO_B			15
++#define CLK_BDP_WR_CHANNEL_DI_PXL	16
++#define CLK_BDP_WR_CHANNEL_DI_DRAM	17
++#define CLK_BDP_WR_CHANNEL_DI_B		18
++#define CLK_BDP_NR_AGENT		19
++#define CLK_BDP_NR_DRAM			20
++#define CLK_BDP_NR_B			21
++#define CLK_BDP_BRIDGE_RT_B		22
++#define CLK_BDP_BRIDGE_RT_DRAM		23
++#define CLK_BDP_LARB_RT_DRAM		24
++#define CLK_BDP_TVD_TDC			25
++#define CLK_BDP_TVD_54			26
++#define CLK_BDP_TVD_CBUS		27
++#define CLK_BDP_NR_CLK			28
++
++/* VDECSYS */
++
++#define CLK_VDEC_CKEN			0
++#define CLK_VDEC_LARB1_CKEN		1
++#define CLK_VDEC_IMGRZ_CKEN		2
++#define CLK_VDEC_NR_CLK			3
++
++/* VENCSYS */
++
++#define CLK_VENC_SMI_COMMON_CON		0
++#define CLK_VENC_VENC			1
++#define CLK_VENC_SMI_LARB6		2
++#define CLK_VENC_NR_CLK			3
++
++/* JPGDECSYS */
++
++#define CLK_JPGDEC_JPGDEC1		0
++#define CLK_JPGDEC_JPGDEC		1
++#define CLK_JPGDEC_NR_CLK		2
++
++#endif /* _DT_BINDINGS_CLK_MT2712_H */
+-- 
+2.11.0
+
diff --git a/target/linux/mediatek/patches-4.14/0146-clk-mediatek-Add-MT2712-clock-support.patch b/target/linux/mediatek/patches-4.14/0146-clk-mediatek-Add-MT2712-clock-support.patch
new file mode 100644
index 0000000000..5876541d8b
--- /dev/null
+++ b/target/linux/mediatek/patches-4.14/0146-clk-mediatek-Add-MT2712-clock-support.patch
@@ -0,0 +1,2331 @@
+From ec5192303a3938d0972fde3b1f2526d8d6dd02d7 Mon Sep 17 00:00:00 2001
+From: "weiyi.lu@mediatek.com" <weiyi.lu@mediatek.com>
+Date: Mon, 23 Oct 2017 12:10:34 +0800
+Subject: [PATCH 146/224] clk: mediatek: Add MT2712 clock support
+
+Add MT2712 clock support, include topckgen, apmixedsys,
+infracfg, pericfg, mcucfg and subsystem clocks.
+
+Signed-off-by: Weiyi Lu <weiyi.lu@mediatek.com>
+[sboyd@codeaurora.org: Static on top_clk_data]
+Signed-off-by: Stephen Boyd <sboyd@codeaurora.org>
+---
+ drivers/clk/mediatek/Kconfig             |   50 ++
+ drivers/clk/mediatek/Makefile            |    8 +
+ drivers/clk/mediatek/clk-mt2712-bdp.c    |  102 +++
+ drivers/clk/mediatek/clk-mt2712-img.c    |   80 ++
+ drivers/clk/mediatek/clk-mt2712-jpgdec.c |   76 ++
+ drivers/clk/mediatek/clk-mt2712-mfg.c    |   75 ++
+ drivers/clk/mediatek/clk-mt2712-mm.c     |  170 ++++
+ drivers/clk/mediatek/clk-mt2712-vdec.c   |   94 ++
+ drivers/clk/mediatek/clk-mt2712-venc.c   |   77 ++
+ drivers/clk/mediatek/clk-mt2712.c        | 1435 ++++++++++++++++++++++++++++++
+ drivers/clk/mediatek/clk-mtk.h           |    2 +
+ drivers/clk/mediatek/clk-pll.c           |   13 +-
+ 12 files changed, 2180 insertions(+), 2 deletions(-)
+ create mode 100644 drivers/clk/mediatek/clk-mt2712-bdp.c
+ create mode 100644 drivers/clk/mediatek/clk-mt2712-img.c
+ create mode 100644 drivers/clk/mediatek/clk-mt2712-jpgdec.c
+ create mode 100644 drivers/clk/mediatek/clk-mt2712-mfg.c
+ create mode 100644 drivers/clk/mediatek/clk-mt2712-mm.c
+ create mode 100644 drivers/clk/mediatek/clk-mt2712-vdec.c
+ create mode 100644 drivers/clk/mediatek/clk-mt2712-venc.c
+ create mode 100644 drivers/clk/mediatek/clk-mt2712.c
+
+diff --git a/drivers/clk/mediatek/Kconfig b/drivers/clk/mediatek/Kconfig
+index 28739a9a6e37..300dbb551bf7 100644
+--- a/drivers/clk/mediatek/Kconfig
++++ b/drivers/clk/mediatek/Kconfig
+@@ -50,6 +50,56 @@ config COMMON_CLK_MT2701_BDPSYS
+ 	---help---
+ 	  This driver supports Mediatek MT2701 bdpsys clocks.
+ 
++config COMMON_CLK_MT2712
++	bool "Clock driver for Mediatek MT2712"
++	depends on (ARCH_MEDIATEK && ARM64) || COMPILE_TEST
++	select COMMON_CLK_MEDIATEK
++	default ARCH_MEDIATEK && ARM64
++	---help---
++	  This driver supports Mediatek MT2712 basic clocks.
++
++config COMMON_CLK_MT2712_BDPSYS
++	bool "Clock driver for Mediatek MT2712 bdpsys"
++	depends on COMMON_CLK_MT2712
++	---help---
++	  This driver supports Mediatek MT2712 bdpsys clocks.
++
++config COMMON_CLK_MT2712_IMGSYS
++	bool "Clock driver for Mediatek MT2712 imgsys"
++	depends on COMMON_CLK_MT2712
++	---help---
++	  This driver supports Mediatek MT2712 imgsys clocks.
++
++config COMMON_CLK_MT2712_JPGDECSYS
++	bool "Clock driver for Mediatek MT2712 jpgdecsys"
++	depends on COMMON_CLK_MT2712
++	---help---
++	  This driver supports Mediatek MT2712 jpgdecsys clocks.
++
++config COMMON_CLK_MT2712_MFGCFG
++	bool "Clock driver for Mediatek MT2712 mfgcfg"
++	depends on COMMON_CLK_MT2712
++	---help---
++	  This driver supports Mediatek MT2712 mfgcfg clocks.
++
++config COMMON_CLK_MT2712_MMSYS
++	bool "Clock driver for Mediatek MT2712 mmsys"
++	depends on COMMON_CLK_MT2712
++	---help---
++	  This driver supports Mediatek MT2712 mmsys clocks.
++
++config COMMON_CLK_MT2712_VDECSYS
++	bool "Clock driver for Mediatek MT2712 vdecsys"
++	depends on COMMON_CLK_MT2712
++	---help---
++	  This driver supports Mediatek MT2712 vdecsys clocks.
++
++config COMMON_CLK_MT2712_VENCSYS
++	bool "Clock driver for Mediatek MT2712 vencsys"
++	depends on COMMON_CLK_MT2712
++	---help---
++	  This driver supports Mediatek MT2712 vencsys clocks.
++
+ config COMMON_CLK_MT6797
+        bool "Clock driver for Mediatek MT6797"
+        depends on (ARCH_MEDIATEK && ARM64) || COMPILE_TEST
+diff --git a/drivers/clk/mediatek/Makefile b/drivers/clk/mediatek/Makefile
+index 2a755b5fb51b..a4e5c47c73a4 100644
+--- a/drivers/clk/mediatek/Makefile
++++ b/drivers/clk/mediatek/Makefile
+@@ -12,5 +12,13 @@ obj-$(CONFIG_COMMON_CLK_MT2701_HIFSYS) += clk-mt2701-hif.o
+ obj-$(CONFIG_COMMON_CLK_MT2701_IMGSYS) += clk-mt2701-img.o
+ obj-$(CONFIG_COMMON_CLK_MT2701_MMSYS) += clk-mt2701-mm.o
+ obj-$(CONFIG_COMMON_CLK_MT2701_VDECSYS) += clk-mt2701-vdec.o
++obj-$(CONFIG_COMMON_CLK_MT2712) += clk-mt2712.o
++obj-$(CONFIG_COMMON_CLK_MT2712_BDPSYS) += clk-mt2712-bdp.o
++obj-$(CONFIG_COMMON_CLK_MT2712_IMGSYS) += clk-mt2712-img.o
++obj-$(CONFIG_COMMON_CLK_MT2712_JPGDECSYS) += clk-mt2712-jpgdec.o
++obj-$(CONFIG_COMMON_CLK_MT2712_MFGCFG) += clk-mt2712-mfg.o
++obj-$(CONFIG_COMMON_CLK_MT2712_MMSYS) += clk-mt2712-mm.o
++obj-$(CONFIG_COMMON_CLK_MT2712_VDECSYS) += clk-mt2712-vdec.o
++obj-$(CONFIG_COMMON_CLK_MT2712_VENCSYS) += clk-mt2712-venc.o
+ obj-$(CONFIG_COMMON_CLK_MT8135) += clk-mt8135.o
+ obj-$(CONFIG_COMMON_CLK_MT8173) += clk-mt8173.o
+diff --git a/drivers/clk/mediatek/clk-mt2712-bdp.c b/drivers/clk/mediatek/clk-mt2712-bdp.c
+new file mode 100644
+index 000000000000..5fe4728c076e
+--- /dev/null
++++ b/drivers/clk/mediatek/clk-mt2712-bdp.c
+@@ -0,0 +1,102 @@
++/*
++ * Copyright (c) 2017 MediaTek Inc.
++ * Author: Weiyi Lu <weiyi.lu@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.
++ */
++
++#include <linux/clk-provider.h>
++#include <linux/platform_device.h>
++
++#include "clk-mtk.h"
++#include "clk-gate.h"
++
++#include <dt-bindings/clock/mt2712-clk.h>
++
++static const struct mtk_gate_regs bdp_cg_regs = {
++	.set_ofs = 0x100,
++	.clr_ofs = 0x100,
++	.sta_ofs = 0x100,
++};
++
++#define GATE_BDP(_id, _name, _parent, _shift) {	\
++		.id = _id,				\
++		.name = _name,				\
++		.parent_name = _parent,			\
++		.regs = &bdp_cg_regs,			\
++		.shift = _shift,			\
++		.ops = &mtk_clk_gate_ops_no_setclr,	\
++	}
++
++static const struct mtk_gate bdp_clks[] = {
++	GATE_BDP(CLK_BDP_BRIDGE_B, "bdp_bridge_b", "mm_sel", 0),
++	GATE_BDP(CLK_BDP_BRIDGE_DRAM, "bdp_bridge_d", "mm_sel", 1),
++	GATE_BDP(CLK_BDP_LARB_DRAM, "bdp_larb_d", "mm_sel", 2),
++	GATE_BDP(CLK_BDP_WR_CHANNEL_VDI_PXL, "bdp_vdi_pxl", "tvd_sel", 3),
++	GATE_BDP(CLK_BDP_WR_CHANNEL_VDI_DRAM, "bdp_vdi_d", "mm_sel", 4),
++	GATE_BDP(CLK_BDP_WR_CHANNEL_VDI_B, "bdp_vdi_b", "mm_sel", 5),
++	GATE_BDP(CLK_BDP_MT_B, "bdp_fmt_b", "mm_sel", 9),
++	GATE_BDP(CLK_BDP_DISPFMT_27M, "bdp_27m", "di_sel", 10),
++	GATE_BDP(CLK_BDP_DISPFMT_27M_VDOUT, "bdp_27m_vdout", "di_sel", 11),
++	GATE_BDP(CLK_BDP_DISPFMT_27_74_74, "bdp_27_74_74", "di_sel", 12),
++	GATE_BDP(CLK_BDP_DISPFMT_2FS, "bdp_2fs", "di_sel", 13),
++	GATE_BDP(CLK_BDP_DISPFMT_2FS_2FS74_148, "bdp_2fs74_148", "di_sel", 14),
++	GATE_BDP(CLK_BDP_DISPFMT_B, "bdp_b", "mm_sel", 15),
++	GATE_BDP(CLK_BDP_VDO_DRAM, "bdp_vdo_d", "mm_sel", 16),
++	GATE_BDP(CLK_BDP_VDO_2FS, "bdp_vdo_2fs", "di_sel", 17),
++	GATE_BDP(CLK_BDP_VDO_B, "bdp_vdo_b", "mm_sel", 18),
++	GATE_BDP(CLK_BDP_WR_CHANNEL_DI_PXL, "bdp_di_pxl", "di_sel", 19),
++	GATE_BDP(CLK_BDP_WR_CHANNEL_DI_DRAM, "bdp_di_d", "mm_sel", 20),
++	GATE_BDP(CLK_BDP_WR_CHANNEL_DI_B, "bdp_di_b", "mm_sel", 21),
++	GATE_BDP(CLK_BDP_NR_AGENT, "bdp_nr_agent", "nr_sel", 22),
++	GATE_BDP(CLK_BDP_NR_DRAM, "bdp_nr_d", "mm_sel", 23),
++	GATE_BDP(CLK_BDP_NR_B, "bdp_nr_b", "mm_sel", 24),
++	GATE_BDP(CLK_BDP_BRIDGE_RT_B, "bdp_bridge_rt_b", "mm_sel", 25),
++	GATE_BDP(CLK_BDP_BRIDGE_RT_DRAM, "bdp_bridge_rt_d", "mm_sel", 26),
++	GATE_BDP(CLK_BDP_LARB_RT_DRAM, "bdp_larb_rt_d", "mm_sel", 27),
++	GATE_BDP(CLK_BDP_TVD_TDC, "bdp_tvd_tdc", "mm_sel", 28),
++	GATE_BDP(CLK_BDP_TVD_54, "bdp_tvd_clk_54", "tvd_sel", 29),
++	GATE_BDP(CLK_BDP_TVD_CBUS, "bdp_tvd_cbus", "mm_sel", 30),
++};
++
++static int clk_mt2712_bdp_probe(struct platform_device *pdev)
++{
++	struct clk_onecell_data *clk_data;
++	int r;
++	struct device_node *node = pdev->dev.of_node;
++
++	clk_data = mtk_alloc_clk_data(CLK_BDP_NR_CLK);
++
++	mtk_clk_register_gates(node, bdp_clks, ARRAY_SIZE(bdp_clks),
++			clk_data);
++
++	r = of_clk_add_provider(node, of_clk_src_onecell_get, clk_data);
++
++	if (r != 0)
++		pr_err("%s(): could not register clock provider: %d\n",
++			__func__, r);
++
++	return r;
++}
++
++static const struct of_device_id of_match_clk_mt2712_bdp[] = {
++	{ .compatible = "mediatek,mt2712-bdpsys", },
++	{}
++};
++
++static struct platform_driver clk_mt2712_bdp_drv = {
++	.probe = clk_mt2712_bdp_probe,
++	.driver = {
++		.name = "clk-mt2712-bdp",
++		.of_match_table = of_match_clk_mt2712_bdp,
++	},
++};
++
++builtin_platform_driver(clk_mt2712_bdp_drv);
+diff --git a/drivers/clk/mediatek/clk-mt2712-img.c b/drivers/clk/mediatek/clk-mt2712-img.c
+new file mode 100644
+index 000000000000..139ff55d495e
+--- /dev/null
++++ b/drivers/clk/mediatek/clk-mt2712-img.c
+@@ -0,0 +1,80 @@
++/*
++ * Copyright (c) 2017 MediaTek Inc.
++ * Author: Weiyi Lu <weiyi.lu@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.
++ */
++
++#include <linux/clk-provider.h>
++#include <linux/platform_device.h>
++
++#include "clk-mtk.h"
++#include "clk-gate.h"
++
++#include <dt-bindings/clock/mt2712-clk.h>
++
++static const struct mtk_gate_regs img_cg_regs = {
++	.set_ofs = 0x0,
++	.clr_ofs = 0x0,
++	.sta_ofs = 0x0,
++};
++
++#define GATE_IMG(_id, _name, _parent, _shift) {	\
++		.id = _id,				\
++		.name = _name,				\
++		.parent_name = _parent,			\
++		.regs = &img_cg_regs,			\
++		.shift = _shift,			\
++		.ops = &mtk_clk_gate_ops_no_setclr,	\
++	}
++
++static const struct mtk_gate img_clks[] = {
++	GATE_IMG(CLK_IMG_SMI_LARB2, "img_smi_larb2", "mm_sel", 0),
++	GATE_IMG(CLK_IMG_SENINF_SCAM_EN, "img_scam_en", "csi0", 3),
++	GATE_IMG(CLK_IMG_SENINF_CAM_EN, "img_cam_en", "mm_sel", 8),
++	GATE_IMG(CLK_IMG_CAM_SV_EN, "img_cam_sv_en", "mm_sel", 9),
++	GATE_IMG(CLK_IMG_CAM_SV1_EN, "img_cam_sv1_en", "mm_sel", 10),
++	GATE_IMG(CLK_IMG_CAM_SV2_EN, "img_cam_sv2_en", "mm_sel", 11),
++};
++
++static int clk_mt2712_img_probe(struct platform_device *pdev)
++{
++	struct clk_onecell_data *clk_data;
++	int r;
++	struct device_node *node = pdev->dev.of_node;
++
++	clk_data = mtk_alloc_clk_data(CLK_IMG_NR_CLK);
++
++	mtk_clk_register_gates(node, img_clks, ARRAY_SIZE(img_clks),
++			clk_data);
++
++	r = of_clk_add_provider(node, of_clk_src_onecell_get, clk_data);
++
++	if (r != 0)
++		pr_err("%s(): could not register clock provider: %d\n",
++			__func__, r);
++
++	return r;
++}
++
++static const struct of_device_id of_match_clk_mt2712_img[] = {
++	{ .compatible = "mediatek,mt2712-imgsys", },
++	{}
++};
++
++static struct platform_driver clk_mt2712_img_drv = {
++	.probe = clk_mt2712_img_probe,
++	.driver = {
++		.name = "clk-mt2712-img",
++		.of_match_table = of_match_clk_mt2712_img,
++	},
++};
++
++builtin_platform_driver(clk_mt2712_img_drv);
+diff --git a/drivers/clk/mediatek/clk-mt2712-jpgdec.c b/drivers/clk/mediatek/clk-mt2712-jpgdec.c
+new file mode 100644
+index 000000000000..c7d4aada4892
+--- /dev/null
++++ b/drivers/clk/mediatek/clk-mt2712-jpgdec.c
+@@ -0,0 +1,76 @@
++/*
++ * Copyright (c) 2017 MediaTek Inc.
++ * Author: Weiyi Lu <weiyi.lu@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.
++ */
++
++#include <linux/clk-provider.h>
++#include <linux/platform_device.h>
++
++#include "clk-mtk.h"
++#include "clk-gate.h"
++
++#include <dt-bindings/clock/mt2712-clk.h>
++
++static const struct mtk_gate_regs jpgdec_cg_regs = {
++	.set_ofs = 0x4,
++	.clr_ofs = 0x8,
++	.sta_ofs = 0x0,
++};
++
++#define GATE_JPGDEC(_id, _name, _parent, _shift) {	\
++		.id = _id,				\
++		.name = _name,				\
++		.parent_name = _parent,			\
++		.regs = &jpgdec_cg_regs,			\
++		.shift = _shift,			\
++		.ops = &mtk_clk_gate_ops_setclr_inv,	\
++	}
++
++static const struct mtk_gate jpgdec_clks[] = {
++	GATE_JPGDEC(CLK_JPGDEC_JPGDEC1, "jpgdec_jpgdec1", "jpgdec_sel", 0),
++	GATE_JPGDEC(CLK_JPGDEC_JPGDEC, "jpgdec_jpgdec", "jpgdec_sel", 4),
++};
++
++static int clk_mt2712_jpgdec_probe(struct platform_device *pdev)
++{
++	struct clk_onecell_data *clk_data;
++	int r;
++	struct device_node *node = pdev->dev.of_node;
++
++	clk_data = mtk_alloc_clk_data(CLK_JPGDEC_NR_CLK);
++
++	mtk_clk_register_gates(node, jpgdec_clks, ARRAY_SIZE(jpgdec_clks),
++			clk_data);
++
++	r = of_clk_add_provider(node, of_clk_src_onecell_get, clk_data);
++
++	if (r != 0)
++		pr_err("%s(): could not register clock provider: %d\n",
++			__func__, r);
++
++	return r;
++}
++
++static const struct of_device_id of_match_clk_mt2712_jpgdec[] = {
++	{ .compatible = "mediatek,mt2712-jpgdecsys", },
++	{}
++};
++
++static struct platform_driver clk_mt2712_jpgdec_drv = {
++	.probe = clk_mt2712_jpgdec_probe,
++	.driver = {
++		.name = "clk-mt2712-jpgdec",
++		.of_match_table = of_match_clk_mt2712_jpgdec,
++	},
++};
++
++builtin_platform_driver(clk_mt2712_jpgdec_drv);
+diff --git a/drivers/clk/mediatek/clk-mt2712-mfg.c b/drivers/clk/mediatek/clk-mt2712-mfg.c
+new file mode 100644
+index 000000000000..570f72d48d4d
+--- /dev/null
++++ b/drivers/clk/mediatek/clk-mt2712-mfg.c
+@@ -0,0 +1,75 @@
++/*
++ * Copyright (c) 2017 MediaTek Inc.
++ * Author: Weiyi Lu <weiyi.lu@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.
++ */
++
++#include <linux/clk-provider.h>
++#include <linux/platform_device.h>
++
++#include "clk-mtk.h"
++#include "clk-gate.h"
++
++#include <dt-bindings/clock/mt2712-clk.h>
++
++static const struct mtk_gate_regs mfg_cg_regs = {
++	.set_ofs = 0x4,
++	.clr_ofs = 0x8,
++	.sta_ofs = 0x0,
++};
++
++#define GATE_MFG(_id, _name, _parent, _shift) {	\
++		.id = _id,				\
++		.name = _name,				\
++		.parent_name = _parent,			\
++		.regs = &mfg_cg_regs,			\
++		.shift = _shift,			\
++		.ops = &mtk_clk_gate_ops_setclr,	\
++	}
++
++static const struct mtk_gate mfg_clks[] = {
++	GATE_MFG(CLK_MFG_BG3D, "mfg_bg3d", "mfg_sel", 0),
++};
++
++static int clk_mt2712_mfg_probe(struct platform_device *pdev)
++{
++	struct clk_onecell_data *clk_data;
++	int r;
++	struct device_node *node = pdev->dev.of_node;
++
++	clk_data = mtk_alloc_clk_data(CLK_MFG_NR_CLK);
++
++	mtk_clk_register_gates(node, mfg_clks, ARRAY_SIZE(mfg_clks),
++			clk_data);
++
++	r = of_clk_add_provider(node, of_clk_src_onecell_get, clk_data);
++
++	if (r != 0)
++		pr_err("%s(): could not register clock provider: %d\n",
++			__func__, r);
++
++	return r;
++}
++
++static const struct of_device_id of_match_clk_mt2712_mfg[] = {
++	{ .compatible = "mediatek,mt2712-mfgcfg", },
++	{}
++};
++
++static struct platform_driver clk_mt2712_mfg_drv = {
++	.probe = clk_mt2712_mfg_probe,
++	.driver = {
++		.name = "clk-mt2712-mfg",
++		.of_match_table = of_match_clk_mt2712_mfg,
++	},
++};
++
++builtin_platform_driver(clk_mt2712_mfg_drv);
+diff --git a/drivers/clk/mediatek/clk-mt2712-mm.c b/drivers/clk/mediatek/clk-mt2712-mm.c
+new file mode 100644
+index 000000000000..a8b4b6d42488
+--- /dev/null
++++ b/drivers/clk/mediatek/clk-mt2712-mm.c
+@@ -0,0 +1,170 @@
++/*
++ * Copyright (c) 2017 MediaTek Inc.
++ * Author: Weiyi Lu <weiyi.lu@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.
++ */
++
++#include <linux/clk-provider.h>
++#include <linux/platform_device.h>
++
++#include "clk-mtk.h"
++#include "clk-gate.h"
++
++#include <dt-bindings/clock/mt2712-clk.h>
++
++static const struct mtk_gate_regs mm0_cg_regs = {
++	.set_ofs = 0x104,
++	.clr_ofs = 0x108,
++	.sta_ofs = 0x100,
++};
++
++static const struct mtk_gate_regs mm1_cg_regs = {
++	.set_ofs = 0x114,
++	.clr_ofs = 0x118,
++	.sta_ofs = 0x110,
++};
++
++static const struct mtk_gate_regs mm2_cg_regs = {
++	.set_ofs = 0x224,
++	.clr_ofs = 0x228,
++	.sta_ofs = 0x220,
++};
++
++#define GATE_MM0(_id, _name, _parent, _shift) {	\
++		.id = _id,				\
++		.name = _name,				\
++		.parent_name = _parent,			\
++		.regs = &mm0_cg_regs,			\
++		.shift = _shift,			\
++		.ops = &mtk_clk_gate_ops_setclr,	\
++	}
++
++#define GATE_MM1(_id, _name, _parent, _shift) {	\
++		.id = _id,				\
++		.name = _name,				\
++		.parent_name = _parent,			\
++		.regs = &mm1_cg_regs,			\
++		.shift = _shift,			\
++		.ops = &mtk_clk_gate_ops_setclr,	\
++	}
++
++#define GATE_MM2(_id, _name, _parent, _shift) {	\
++		.id = _id,				\
++		.name = _name,				\
++		.parent_name = _parent,			\
++		.regs = &mm2_cg_regs,			\
++		.shift = _shift,			\
++		.ops = &mtk_clk_gate_ops_setclr,	\
++	}
++
++static const struct mtk_gate mm_clks[] = {
++	/* MM0 */
++	GATE_MM0(CLK_MM_SMI_COMMON, "mm_smi_common", "mm_sel", 0),
++	GATE_MM0(CLK_MM_SMI_LARB0, "mm_smi_larb0", "mm_sel", 1),
++	GATE_MM0(CLK_MM_CAM_MDP, "mm_cam_mdp", "mm_sel", 2),
++	GATE_MM0(CLK_MM_MDP_RDMA0, "mm_mdp_rdma0", "mm_sel", 3),
++	GATE_MM0(CLK_MM_MDP_RDMA1, "mm_mdp_rdma1", "mm_sel", 4),
++	GATE_MM0(CLK_MM_MDP_RSZ0, "mm_mdp_rsz0", "mm_sel", 5),
++	GATE_MM0(CLK_MM_MDP_RSZ1, "mm_mdp_rsz1", "mm_sel", 6),
++	GATE_MM0(CLK_MM_MDP_RSZ2, "mm_mdp_rsz2", "mm_sel", 7),
++	GATE_MM0(CLK_MM_MDP_TDSHP0, "mm_mdp_tdshp0", "mm_sel", 8),
++	GATE_MM0(CLK_MM_MDP_TDSHP1, "mm_mdp_tdshp1", "mm_sel", 9),
++	GATE_MM0(CLK_MM_MDP_CROP, "mm_mdp_crop", "mm_sel", 10),
++	GATE_MM0(CLK_MM_MDP_WDMA, "mm_mdp_wdma", "mm_sel", 11),
++	GATE_MM0(CLK_MM_MDP_WROT0, "mm_mdp_wrot0", "mm_sel", 12),
++	GATE_MM0(CLK_MM_MDP_WROT1, "mm_mdp_wrot1", "mm_sel", 13),
++	GATE_MM0(CLK_MM_FAKE_ENG, "mm_fake_eng", "mm_sel", 14),
++	GATE_MM0(CLK_MM_MUTEX_32K, "mm_mutex_32k", "clk32k", 15),
++	GATE_MM0(CLK_MM_DISP_OVL0, "mm_disp_ovl0", "mm_sel", 16),
++	GATE_MM0(CLK_MM_DISP_OVL1, "mm_disp_ovl1", "mm_sel", 17),
++	GATE_MM0(CLK_MM_DISP_RDMA0, "mm_disp_rdma0", "mm_sel", 18),
++	GATE_MM0(CLK_MM_DISP_RDMA1, "mm_disp_rdma1", "mm_sel", 19),
++	GATE_MM0(CLK_MM_DISP_RDMA2, "mm_disp_rdma2", "mm_sel", 20),
++	GATE_MM0(CLK_MM_DISP_WDMA0, "mm_disp_wdma0", "mm_sel", 21),
++	GATE_MM0(CLK_MM_DISP_WDMA1, "mm_disp_wdma1", "mm_sel", 22),
++	GATE_MM0(CLK_MM_DISP_COLOR0, "mm_disp_color0", "mm_sel", 23),
++	GATE_MM0(CLK_MM_DISP_COLOR1, "mm_disp_color1", "mm_sel", 24),
++	GATE_MM0(CLK_MM_DISP_AAL, "mm_disp_aal", "mm_sel", 25),
++	GATE_MM0(CLK_MM_DISP_GAMMA, "mm_disp_gamma", "mm_sel", 26),
++	GATE_MM0(CLK_MM_DISP_UFOE, "mm_disp_ufoe", "mm_sel", 27),
++	GATE_MM0(CLK_MM_DISP_SPLIT0, "mm_disp_split0", "mm_sel", 28),
++	GATE_MM0(CLK_MM_DISP_OD, "mm_disp_od", "mm_sel", 31),
++	/* MM1 */
++	GATE_MM1(CLK_MM_DISP_PWM0_MM, "mm_pwm0_mm", "mm_sel", 0),
++	GATE_MM1(CLK_MM_DISP_PWM0_26M, "mm_pwm0_26m", "pwm_sel", 1),
++	GATE_MM1(CLK_MM_DISP_PWM1_MM, "mm_pwm1_mm", "mm_sel", 2),
++	GATE_MM1(CLK_MM_DISP_PWM1_26M, "mm_pwm1_26m", "pwm_sel", 3),
++	GATE_MM1(CLK_MM_DSI0_ENGINE, "mm_dsi0_engine", "mm_sel", 4),
++	GATE_MM1(CLK_MM_DSI0_DIGITAL, "mm_dsi0_digital", "dsi0_lntc", 5),
++	GATE_MM1(CLK_MM_DSI1_ENGINE, "mm_dsi1_engine", "mm_sel", 6),
++	GATE_MM1(CLK_MM_DSI1_DIGITAL, "mm_dsi1_digital", "dsi1_lntc", 7),
++	GATE_MM1(CLK_MM_DPI_PIXEL, "mm_dpi_pixel", "vpll_dpix", 8),
++	GATE_MM1(CLK_MM_DPI_ENGINE, "mm_dpi_engine", "mm_sel", 9),
++	GATE_MM1(CLK_MM_DPI1_PIXEL, "mm_dpi1_pixel", "vpll3_dpix", 10),
++	GATE_MM1(CLK_MM_DPI1_ENGINE, "mm_dpi1_engine", "mm_sel", 11),
++	GATE_MM1(CLK_MM_LVDS_PIXEL, "mm_lvds_pixel", "vpll_dpix", 16),
++	GATE_MM1(CLK_MM_LVDS_CTS, "mm_lvds_cts", "lvdstx", 17),
++	GATE_MM1(CLK_MM_SMI_LARB4, "mm_smi_larb4", "mm_sel", 18),
++	GATE_MM1(CLK_MM_SMI_COMMON1, "mm_smi_common1", "mm_sel", 21),
++	GATE_MM1(CLK_MM_SMI_LARB5, "mm_smi_larb5", "mm_sel", 22),
++	GATE_MM1(CLK_MM_MDP_RDMA2, "mm_mdp_rdma2", "mm_sel", 23),
++	GATE_MM1(CLK_MM_MDP_TDSHP2, "mm_mdp_tdshp2", "mm_sel", 24),
++	GATE_MM1(CLK_MM_DISP_OVL2, "mm_disp_ovl2", "mm_sel", 25),
++	GATE_MM1(CLK_MM_DISP_WDMA2, "mm_disp_wdma2", "mm_sel", 26),
++	GATE_MM1(CLK_MM_DISP_COLOR2, "mm_disp_color2", "mm_sel", 27),
++	GATE_MM1(CLK_MM_DISP_AAL1, "mm_disp_aal1", "mm_sel", 28),
++	GATE_MM1(CLK_MM_DISP_OD1, "mm_disp_od1", "mm_sel", 29),
++	GATE_MM1(CLK_MM_LVDS1_PIXEL, "mm_lvds1_pixel", "vpll3_dpix", 30),
++	GATE_MM1(CLK_MM_LVDS1_CTS, "mm_lvds1_cts", "lvdstx3", 31),
++	/* MM2 */
++	GATE_MM2(CLK_MM_SMI_LARB7, "mm_smi_larb7", "mm_sel", 0),
++	GATE_MM2(CLK_MM_MDP_RDMA3, "mm_mdp_rdma3", "mm_sel", 1),
++	GATE_MM2(CLK_MM_MDP_WROT2, "mm_mdp_wrot2", "mm_sel", 2),
++	GATE_MM2(CLK_MM_DSI2, "mm_dsi2", "mm_sel", 3),
++	GATE_MM2(CLK_MM_DSI2_DIGITAL, "mm_dsi2_digital", "dsi0_lntc", 4),
++	GATE_MM2(CLK_MM_DSI3, "mm_dsi3", "mm_sel", 5),
++	GATE_MM2(CLK_MM_DSI3_DIGITAL, "mm_dsi3_digital", "dsi1_lntc", 6),
++};
++
++static int clk_mt2712_mm_probe(struct platform_device *pdev)
++{
++	struct clk_onecell_data *clk_data;
++	int r;
++	struct device_node *node = pdev->dev.of_node;
++
++	clk_data = mtk_alloc_clk_data(CLK_MM_NR_CLK);
++
++	mtk_clk_register_gates(node, mm_clks, ARRAY_SIZE(mm_clks),
++			clk_data);
++
++	r = of_clk_add_provider(node, of_clk_src_onecell_get, clk_data);
++
++	if (r != 0)
++		pr_err("%s(): could not register clock provider: %d\n",
++			__func__, r);
++
++	return r;
++}
++
++static const struct of_device_id of_match_clk_mt2712_mm[] = {
++	{ .compatible = "mediatek,mt2712-mmsys", },
++	{}
++};
++
++static struct platform_driver clk_mt2712_mm_drv = {
++	.probe = clk_mt2712_mm_probe,
++	.driver = {
++		.name = "clk-mt2712-mm",
++		.of_match_table = of_match_clk_mt2712_mm,
++	},
++};
++
++builtin_platform_driver(clk_mt2712_mm_drv);
+diff --git a/drivers/clk/mediatek/clk-mt2712-vdec.c b/drivers/clk/mediatek/clk-mt2712-vdec.c
+new file mode 100644
+index 000000000000..55c64ee8cc91
+--- /dev/null
++++ b/drivers/clk/mediatek/clk-mt2712-vdec.c
+@@ -0,0 +1,94 @@
++/*
++ * Copyright (c) 2017 MediaTek Inc.
++ * Author: Weiyi Lu <weiyi.lu@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.
++ */
++
++#include <linux/clk-provider.h>
++#include <linux/platform_device.h>
++
++#include "clk-mtk.h"
++#include "clk-gate.h"
++
++#include <dt-bindings/clock/mt2712-clk.h>
++
++static const struct mtk_gate_regs vdec0_cg_regs = {
++	.set_ofs = 0x0,
++	.clr_ofs = 0x4,
++	.sta_ofs = 0x0,
++};
++
++static const struct mtk_gate_regs vdec1_cg_regs = {
++	.set_ofs = 0x8,
++	.clr_ofs = 0xc,
++	.sta_ofs = 0x8,
++};
++
++#define GATE_VDEC0(_id, _name, _parent, _shift) {	\
++		.id = _id,				\
++		.name = _name,				\
++		.parent_name = _parent,			\
++		.regs = &vdec0_cg_regs,			\
++		.shift = _shift,			\
++		.ops = &mtk_clk_gate_ops_setclr_inv,	\
++	}
++
++#define GATE_VDEC1(_id, _name, _parent, _shift) {	\
++		.id = _id,				\
++		.name = _name,				\
++		.parent_name = _parent,			\
++		.regs = &vdec1_cg_regs,			\
++		.shift = _shift,			\
++		.ops = &mtk_clk_gate_ops_setclr_inv,	\
++	}
++
++static const struct mtk_gate vdec_clks[] = {
++	/* VDEC0 */
++	GATE_VDEC0(CLK_VDEC_CKEN, "vdec_cken", "vdec_sel", 0),
++	/* VDEC1 */
++	GATE_VDEC1(CLK_VDEC_LARB1_CKEN, "vdec_larb1_cken", "vdec_sel", 0),
++	GATE_VDEC1(CLK_VDEC_IMGRZ_CKEN, "vdec_imgrz_cken", "vdec_sel", 1),
++};
++
++static int clk_mt2712_vdec_probe(struct platform_device *pdev)
++{
++	struct clk_onecell_data *clk_data;
++	int r;
++	struct device_node *node = pdev->dev.of_node;
++
++	clk_data = mtk_alloc_clk_data(CLK_VDEC_NR_CLK);
++
++	mtk_clk_register_gates(node, vdec_clks, ARRAY_SIZE(vdec_clks),
++			clk_data);
++
++	r = of_clk_add_provider(node, of_clk_src_onecell_get, clk_data);
++
++	if (r != 0)
++		pr_err("%s(): could not register clock provider: %d\n",
++			__func__, r);
++
++	return r;
++}
++
++static const struct of_device_id of_match_clk_mt2712_vdec[] = {
++	{ .compatible = "mediatek,mt2712-vdecsys", },
++	{}
++};
++
++static struct platform_driver clk_mt2712_vdec_drv = {
++	.probe = clk_mt2712_vdec_probe,
++	.driver = {
++		.name = "clk-mt2712-vdec",
++		.of_match_table = of_match_clk_mt2712_vdec,
++	},
++};
++
++builtin_platform_driver(clk_mt2712_vdec_drv);
+diff --git a/drivers/clk/mediatek/clk-mt2712-venc.c b/drivers/clk/mediatek/clk-mt2712-venc.c
+new file mode 100644
+index 000000000000..ccbfe98777c8
+--- /dev/null
++++ b/drivers/clk/mediatek/clk-mt2712-venc.c
+@@ -0,0 +1,77 @@
++/*
++ * Copyright (c) 2017 MediaTek Inc.
++ * Author: Weiyi Lu <weiyi.lu@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.
++ */
++
++#include <linux/clk-provider.h>
++#include <linux/platform_device.h>
++
++#include "clk-mtk.h"
++#include "clk-gate.h"
++
++#include <dt-bindings/clock/mt2712-clk.h>
++
++static const struct mtk_gate_regs venc_cg_regs = {
++	.set_ofs = 0x4,
++	.clr_ofs = 0x8,
++	.sta_ofs = 0x0,
++};
++
++#define GATE_VENC(_id, _name, _parent, _shift) {	\
++		.id = _id,				\
++		.name = _name,				\
++		.parent_name = _parent,			\
++		.regs = &venc_cg_regs,			\
++		.shift = _shift,			\
++		.ops = &mtk_clk_gate_ops_setclr_inv,	\
++	}
++
++static const struct mtk_gate venc_clks[] = {
++	GATE_VENC(CLK_VENC_SMI_COMMON_CON, "venc_smi", "mm_sel", 0),
++	GATE_VENC(CLK_VENC_VENC, "venc_venc", "venc_sel", 4),
++	GATE_VENC(CLK_VENC_SMI_LARB6, "venc_smi_larb6", "jpgdec_sel", 12),
++};
++
++static int clk_mt2712_venc_probe(struct platform_device *pdev)
++{
++	struct clk_onecell_data *clk_data;
++	int r;
++	struct device_node *node = pdev->dev.of_node;
++
++	clk_data = mtk_alloc_clk_data(CLK_VENC_NR_CLK);
++
++	mtk_clk_register_gates(node, venc_clks, ARRAY_SIZE(venc_clks),
++			clk_data);
++
++	r = of_clk_add_provider(node, of_clk_src_onecell_get, clk_data);
++
++	if (r != 0)
++		pr_err("%s(): could not register clock provider: %d\n",
++			__func__, r);
++
++	return r;
++}
++
++static const struct of_device_id of_match_clk_mt2712_venc[] = {
++	{ .compatible = "mediatek,mt2712-vencsys", },
++	{}
++};
++
++static struct platform_driver clk_mt2712_venc_drv = {
++	.probe = clk_mt2712_venc_probe,
++	.driver = {
++		.name = "clk-mt2712-venc",
++		.of_match_table = of_match_clk_mt2712_venc,
++	},
++};
++
++builtin_platform_driver(clk_mt2712_venc_drv);
+diff --git a/drivers/clk/mediatek/clk-mt2712.c b/drivers/clk/mediatek/clk-mt2712.c
+new file mode 100644
+index 000000000000..498d13799388
+--- /dev/null
++++ b/drivers/clk/mediatek/clk-mt2712.c
+@@ -0,0 +1,1435 @@
++/*
++ * Copyright (c) 2017 MediaTek Inc.
++ * Author: Weiyi Lu <weiyi.lu@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.
++ */
++
++#include <linux/clk.h>
++#include <linux/delay.h>
++#include <linux/mfd/syscon.h>
++#include <linux/of.h>
++#include <linux/of_address.h>
++#include <linux/of_device.h>
++#include <linux/platform_device.h>
++#include <linux/slab.h>
++
++#include "clk-mtk.h"
++#include "clk-gate.h"
++
++#include <dt-bindings/clock/mt2712-clk.h>
++
++static DEFINE_SPINLOCK(mt2712_clk_lock);
++
++static const struct mtk_fixed_clk top_fixed_clks[] = {
++	FIXED_CLK(CLK_TOP_VPLL3_DPIX, "vpll3_dpix", NULL, 200000000),
++	FIXED_CLK(CLK_TOP_VPLL_DPIX, "vpll_dpix", NULL, 200000000),
++	FIXED_CLK(CLK_TOP_LTEPLL_FS26M, "ltepll_fs26m", NULL, 26000000),
++	FIXED_CLK(CLK_TOP_DMPLL, "dmpll_ck", NULL, 350000000),
++	FIXED_CLK(CLK_TOP_DSI0_LNTC, "dsi0_lntc", NULL, 143000000),
++	FIXED_CLK(CLK_TOP_DSI1_LNTC, "dsi1_lntc", NULL, 143000000),
++	FIXED_CLK(CLK_TOP_LVDSTX3_CLKDIG_CTS, "lvdstx3", NULL, 140000000),
++	FIXED_CLK(CLK_TOP_LVDSTX_CLKDIG_CTS, "lvdstx", NULL, 140000000),
++	FIXED_CLK(CLK_TOP_CLKRTC_EXT, "clkrtc_ext", NULL, 32768),
++	FIXED_CLK(CLK_TOP_CLKRTC_INT, "clkrtc_int", NULL, 32747),
++	FIXED_CLK(CLK_TOP_CSI0, "csi0", NULL, 26000000),
++	FIXED_CLK(CLK_TOP_CVBSPLL, "cvbspll", NULL, 108000000),
++};
++
++static const struct mtk_fixed_factor top_early_divs[] = {
++	FACTOR(CLK_TOP_SYS_26M, "sys_26m", "clk26m", 1,
++		1),
++	FACTOR(CLK_TOP_CLK26M_D2, "clk26m_d2", "sys_26m", 1,
++		2),
++};
++
++static const struct mtk_fixed_factor top_divs[] = {
++	FACTOR(CLK_TOP_ARMCA35PLL, "armca35pll_ck", "armca35pll", 1,
++		1),
++	FACTOR(CLK_TOP_ARMCA35PLL_600M, "armca35pll_600m", "armca35pll_ck", 1,
++		2),
++	FACTOR(CLK_TOP_ARMCA35PLL_400M, "armca35pll_400m", "armca35pll_ck", 1,
++		3),
++	FACTOR(CLK_TOP_ARMCA72PLL, "armca72pll_ck", "armca72pll", 1,
++		1),
++	FACTOR(CLK_TOP_SYSPLL, "syspll_ck", "mainpll", 1,
++		1),
++	FACTOR(CLK_TOP_SYSPLL_D2, "syspll_d2", "syspll_ck", 1,
++		2),
++	FACTOR(CLK_TOP_SYSPLL1_D2, "syspll1_d2", "syspll_d2", 1,
++		2),
++	FACTOR(CLK_TOP_SYSPLL1_D4, "syspll1_d4", "syspll_d2", 1,
++		4),
++	FACTOR(CLK_TOP_SYSPLL1_D8, "syspll1_d8", "syspll_d2", 1,
++		8),
++	FACTOR(CLK_TOP_SYSPLL1_D16, "syspll1_d16", "syspll_d2", 1,
++		16),
++	FACTOR(CLK_TOP_SYSPLL_D3, "syspll_d3", "syspll_ck", 1,
++		3),
++	FACTOR(CLK_TOP_SYSPLL2_D2, "syspll2_d2", "syspll_d3", 1,
++		2),
++	FACTOR(CLK_TOP_SYSPLL2_D4, "syspll2_d4", "syspll_d3", 1,
++		4),
++	FACTOR(CLK_TOP_SYSPLL_D5, "syspll_d5", "syspll_ck", 1,
++		5),
++	FACTOR(CLK_TOP_SYSPLL3_D2, "syspll3_d2", "syspll_d5", 1,
++		2),
++	FACTOR(CLK_TOP_SYSPLL3_D4, "syspll3_d4", "syspll_d5", 1,
++		4),
++	FACTOR(CLK_TOP_SYSPLL_D7, "syspll_d7", "syspll_ck", 1,
++		7),
++	FACTOR(CLK_TOP_SYSPLL4_D2, "syspll4_d2", "syspll_d7", 1,
++		2),
++	FACTOR(CLK_TOP_SYSPLL4_D4, "syspll4_d4", "syspll_d7", 1,
++		4),
++	FACTOR(CLK_TOP_UNIVPLL, "univpll_ck", "univpll", 1,
++		1),
++	FACTOR(CLK_TOP_UNIVPLL_D7, "univpll_d7", "univpll_ck", 1,
++		7),
++	FACTOR(CLK_TOP_UNIVPLL_D26, "univpll_d26", "univpll_ck", 1,
++		26),
++	FACTOR(CLK_TOP_UNIVPLL_D52, "univpll_d52", "univpll_ck", 1,
++		52),
++	FACTOR(CLK_TOP_UNIVPLL_D104, "univpll_d104", "univpll_ck", 1,
++		104),
++	FACTOR(CLK_TOP_UNIVPLL_D208, "univpll_d208", "univpll_ck", 1,
++		208),
++	FACTOR(CLK_TOP_UNIVPLL_D2, "univpll_d2", "univpll_ck", 1,
++		2),
++	FACTOR(CLK_TOP_UNIVPLL1_D2, "univpll1_d2", "univpll_d2", 1,
++		2),
++	FACTOR(CLK_TOP_UNIVPLL1_D4, "univpll1_d4", "univpll_d2", 1,
++		4),
++	FACTOR(CLK_TOP_UNIVPLL1_D8, "univpll1_d8", "univpll_d2", 1,
++		8),
++	FACTOR(CLK_TOP_UNIVPLL_D3, "univpll_d3", "univpll_ck", 1,
++		3),
++	FACTOR(CLK_TOP_UNIVPLL2_D2, "univpll2_d2", "univpll_d3", 1,
++		2),
++	FACTOR(CLK_TOP_UNIVPLL2_D4, "univpll2_d4", "univpll_d3", 1,
++		4),
++	FACTOR(CLK_TOP_UNIVPLL2_D8, "univpll2_d8", "univpll_d3", 1,
++		8),
++	FACTOR(CLK_TOP_UNIVPLL_D5, "univpll_d5", "univpll_ck", 1,
++		5),
++	FACTOR(CLK_TOP_UNIVPLL3_D2, "univpll3_d2", "univpll_d5", 1,
++		2),
++	FACTOR(CLK_TOP_UNIVPLL3_D4, "univpll3_d4", "univpll_d5", 1,
++		4),
++	FACTOR(CLK_TOP_UNIVPLL3_D8, "univpll3_d8", "univpll_d5", 1,
++		8),
++	FACTOR(CLK_TOP_F_MP0_PLL1, "f_mp0_pll1_ck", "univpll_d2", 1,
++		1),
++	FACTOR(CLK_TOP_F_MP0_PLL2, "f_mp0_pll2_ck", "univpll1_d2", 1,
++		1),
++	FACTOR(CLK_TOP_F_BIG_PLL1, "f_big_pll1_ck", "univpll_d2", 1,
++		1),
++	FACTOR(CLK_TOP_F_BIG_PLL2, "f_big_pll2_ck", "univpll1_d2", 1,
++		1),
++	FACTOR(CLK_TOP_F_BUS_PLL1, "f_bus_pll1_ck", "univpll_d2", 1,
++		1),
++	FACTOR(CLK_TOP_F_BUS_PLL2, "f_bus_pll2_ck", "univpll1_d2", 1,
++		1),
++	FACTOR(CLK_TOP_APLL1, "apll1_ck", "apll1", 1,
++		1),
++	FACTOR(CLK_TOP_APLL1_D2, "apll1_d2", "apll1_ck", 1,
++		2),
++	FACTOR(CLK_TOP_APLL1_D4, "apll1_d4", "apll1_ck", 1,
++		4),
++	FACTOR(CLK_TOP_APLL1_D8, "apll1_d8", "apll1_ck", 1,
++		8),
++	FACTOR(CLK_TOP_APLL1_D16, "apll1_d16", "apll1_ck", 1,
++		16),
++	FACTOR(CLK_TOP_APLL2, "apll2_ck", "apll2", 1,
++		1),
++	FACTOR(CLK_TOP_APLL2_D2, "apll2_d2", "apll2_ck", 1,
++		2),
++	FACTOR(CLK_TOP_APLL2_D4, "apll2_d4", "apll2_ck", 1,
++		4),
++	FACTOR(CLK_TOP_APLL2_D8, "apll2_d8", "apll2_ck", 1,
++		8),
++	FACTOR(CLK_TOP_APLL2_D16, "apll2_d16", "apll2_ck", 1,
++		16),
++	FACTOR(CLK_TOP_LVDSPLL, "lvdspll_ck", "lvdspll", 1,
++		1),
++	FACTOR(CLK_TOP_LVDSPLL_D2, "lvdspll_d2", "lvdspll_ck", 1,
++		2),
++	FACTOR(CLK_TOP_LVDSPLL_D4, "lvdspll_d4", "lvdspll_ck", 1,
++		4),
++	FACTOR(CLK_TOP_LVDSPLL_D8, "lvdspll_d8", "lvdspll_ck", 1,
++		8),
++	FACTOR(CLK_TOP_LVDSPLL2, "lvdspll2_ck", "lvdspll2", 1,
++		1),
++	FACTOR(CLK_TOP_LVDSPLL2_D2, "lvdspll2_d2", "lvdspll2_ck", 1,
++		2),
++	FACTOR(CLK_TOP_LVDSPLL2_D4, "lvdspll2_d4", "lvdspll2_ck", 1,
++		4),
++	FACTOR(CLK_TOP_LVDSPLL2_D8, "lvdspll2_d8", "lvdspll2_ck", 1,
++		8),
++	FACTOR(CLK_TOP_ETHERPLL_125M, "etherpll_125m", "etherpll", 1,
++		1),
++	FACTOR(CLK_TOP_ETHERPLL_50M, "etherpll_50m", "etherpll", 1,
++		1),
++	FACTOR(CLK_TOP_CVBS, "cvbs", "cvbspll", 1,
++		1),
++	FACTOR(CLK_TOP_CVBS_D2, "cvbs_d2", "cvbs", 1,
++		2),
++	FACTOR(CLK_TOP_MMPLL, "mmpll_ck", "mmpll", 1,
++		1),
++	FACTOR(CLK_TOP_MMPLL_D2, "mmpll_d2", "mmpll_ck", 1,
++		2),
++	FACTOR(CLK_TOP_VENCPLL, "vencpll_ck", "vencpll", 1,
++		1),
++	FACTOR(CLK_TOP_VENCPLL_D2, "vencpll_d2", "vencpll_ck", 1,
++		2),
++	FACTOR(CLK_TOP_VCODECPLL, "vcodecpll_ck", "vcodecpll", 1,
++		1),
++	FACTOR(CLK_TOP_VCODECPLL_D2, "vcodecpll_d2", "vcodecpll_ck", 1,
++		2),
++	FACTOR(CLK_TOP_TVDPLL, "tvdpll_ck", "tvdpll", 1,
++		1),
++	FACTOR(CLK_TOP_TVDPLL_D2, "tvdpll_d2", "tvdpll_ck", 1,
++		2),
++	FACTOR(CLK_TOP_TVDPLL_D4, "tvdpll_d4", "tvdpll_ck", 1,
++		4),
++	FACTOR(CLK_TOP_TVDPLL_D8, "tvdpll_d8", "tvdpll_ck", 1,
++		8),
++	FACTOR(CLK_TOP_TVDPLL_429M, "tvdpll_429m", "tvdpll", 1,
++		1),
++	FACTOR(CLK_TOP_TVDPLL_429M_D2, "tvdpll_429m_d2", "tvdpll_429m", 1,
++		2),
++	FACTOR(CLK_TOP_TVDPLL_429M_D4, "tvdpll_429m_d4", "tvdpll_429m", 1,
++		4),
++	FACTOR(CLK_TOP_MSDCPLL, "msdcpll_ck", "msdcpll", 1,
++		1),
++	FACTOR(CLK_TOP_MSDCPLL_D2, "msdcpll_d2", "msdcpll_ck", 1,
++		2),
++	FACTOR(CLK_TOP_MSDCPLL_D4, "msdcpll_d4", "msdcpll_ck", 1,
++		4),
++	FACTOR(CLK_TOP_MSDCPLL2, "msdcpll2_ck", "msdcpll2", 1,
++		1),
++	FACTOR(CLK_TOP_MSDCPLL2_D2, "msdcpll2_d2", "msdcpll2_ck", 1,
++		2),
++	FACTOR(CLK_TOP_MSDCPLL2_D4, "msdcpll2_d4", "msdcpll2_ck", 1,
++		4),
++	FACTOR(CLK_TOP_D2A_ULCLK_6P5M, "d2a_ulclk_6p5m", "clk26m", 1,
++		4),
++};
++
++static const char * const axi_parents[] = {
++	"clk26m",
++	"syspll1_d2",
++	"syspll_d5",
++	"syspll1_d4",
++	"univpll_d5",
++	"univpll2_d2",
++	"msdcpll2_ck"
++};
++
++static const char * const mem_parents[] = {
++	"clk26m",
++	"dmpll_ck"
++};
++
++static const char * const mm_parents[] = {
++	"clk26m",
++	"vencpll_ck",
++	"syspll_d3",
++	"syspll1_d2",
++	"syspll_d5",
++	"syspll1_d4",
++	"univpll1_d2",
++	"univpll2_d2"
++};
++
++static const char * const pwm_parents[] = {
++	"clk26m",
++	"univpll2_d4",
++	"univpll3_d2",
++	"univpll1_d4"
++};
++
++static const char * const vdec_parents[] = {
++	"clk26m",
++	"vcodecpll_ck",
++	"tvdpll_429m",
++	"univpll_d3",
++	"vencpll_ck",
++	"syspll_d3",
++	"univpll1_d2",
++	"mmpll_d2",
++	"syspll3_d2",
++	"tvdpll_ck"
++};
++
++static const char * const venc_parents[] = {
++	"clk26m",
++	"univpll1_d2",
++	"mmpll_d2",
++	"tvdpll_d2",
++	"syspll1_d2",
++	"univpll_d5",
++	"vcodecpll_d2",
++	"univpll2_d2",
++	"syspll3_d2"
++};
++
++static const char * const mfg_parents[] = {
++	"clk26m",
++	"mmpll_ck",
++	"univpll_d3",
++	"clk26m",
++	"clk26m",
++	"clk26m",
++	"clk26m",
++	"clk26m",
++	"clk26m",
++	"syspll_d3",
++	"syspll1_d2",
++	"syspll_d5",
++	"univpll_d3",
++	"univpll1_d2",
++	"univpll_d5",
++	"univpll2_d2"
++};
++
++static const char * const camtg_parents[] = {
++	"clk26m",
++	"univpll_d52",
++	"univpll_d208",
++	"univpll_d104",
++	"clk26m_d2",
++	"univpll_d26",
++	"univpll2_d8",
++	"syspll3_d4",
++	"syspll3_d2",
++	"univpll1_d4",
++	"univpll2_d2"
++};
++
++static const char * const uart_parents[] = {
++	"clk26m",
++	"univpll2_d8"
++};
++
++static const char * const spi_parents[] = {
++	"clk26m",
++	"univpll2_d4",
++	"univpll1_d4",
++	"univpll2_d2",
++	"univpll3_d2",
++	"univpll1_d8"
++};
++
++static const char * const usb20_parents[] = {
++	"clk26m",
++	"univpll1_d8",
++	"univpll3_d4"
++};
++
++static const char * const usb30_parents[] = {
++	"clk26m",
++	"univpll3_d2",
++	"univpll3_d4",
++	"univpll2_d4"
++};
++
++static const char * const msdc50_0_h_parents[] = {
++	"clk26m",
++	"syspll1_d2",
++	"syspll2_d2",
++	"syspll4_d2",
++	"univpll_d5",
++	"univpll1_d4"
++};
++
++static const char * const msdc50_0_parents[] = {
++	"clk26m",
++	"msdcpll_ck",
++	"msdcpll_d2",
++	"univpll1_d4",
++	"syspll2_d2",
++	"msdcpll_d4",
++	"vencpll_d2",
++	"univpll1_d2",
++	"msdcpll2_ck",
++	"msdcpll2_d2",
++	"msdcpll2_d4"
++};
++
++static const char * const msdc30_1_parents[] = {
++	"clk26m",
++	"univpll2_d2",
++	"msdcpll_d2",
++	"univpll1_d4",
++	"syspll2_d2",
++	"univpll_d7",
++	"vencpll_d2"
++};
++
++static const char * const msdc30_3_parents[] = {
++	"clk26m",
++	"msdcpll2_ck",
++	"msdcpll2_d2",
++	"univpll2_d2",
++	"msdcpll2_d4",
++	"univpll1_d4",
++	"syspll2_d2",
++	"syspll_d7",
++	"univpll_d7",
++	"vencpll_d2",
++	"msdcpll_ck",
++	"msdcpll_d2",
++	"msdcpll_d4"
++};
++
++static const char * const audio_parents[] = {
++	"clk26m",
++	"syspll3_d4",
++	"syspll4_d4",
++	"syspll1_d16"
++};
++
++static const char * const aud_intbus_parents[] = {
++	"clk26m",
++	"syspll1_d4",
++	"syspll4_d2",
++	"univpll3_d2",
++	"univpll2_d8",
++	"syspll3_d2",
++	"syspll3_d4"
++};
++
++static const char * const pmicspi_parents[] = {
++	"clk26m",
++	"syspll1_d8",
++	"syspll3_d4",
++	"syspll1_d16",
++	"univpll3_d4",
++	"univpll_d26",
++	"syspll3_d4"
++};
++
++static const char * const dpilvds1_parents[] = {
++	"clk26m",
++	"lvdspll2_ck",
++	"lvdspll2_d2",
++	"lvdspll2_d4",
++	"lvdspll2_d8",
++	"clkfpc"
++};
++
++static const char * const atb_parents[] = {
++	"clk26m",
++	"syspll1_d2",
++	"univpll_d5",
++	"syspll_d5"
++};
++
++static const char * const nr_parents[] = {
++	"clk26m",
++	"univpll1_d4",
++	"syspll2_d2",
++	"syspll1_d4",
++	"univpll1_d8",
++	"univpll3_d2",
++	"univpll2_d2",
++	"syspll_d5"
++};
++
++static const char * const nfi2x_parents[] = {
++	"clk26m",
++	"syspll4_d4",
++	"univpll3_d4",
++	"univpll1_d8",
++	"syspll2_d4",
++	"univpll3_d2",
++	"syspll_d7",
++	"syspll2_d2",
++	"univpll2_d2",
++	"syspll_d5",
++	"syspll1_d2"
++};
++
++static const char * const irda_parents[] = {
++	"clk26m",
++	"univpll2_d4",
++	"syspll2_d4",
++	"univpll2_d8"
++};
++
++static const char * const cci400_parents[] = {
++	"clk26m",
++	"vencpll_ck",
++	"armca35pll_600m",
++	"armca35pll_400m",
++	"univpll_d2",
++	"syspll_d2",
++	"msdcpll_ck",
++	"univpll_d3"
++};
++
++static const char * const aud_1_parents[] = {
++	"clk26m",
++	"apll1_ck",
++	"univpll2_d4",
++	"univpll2_d8"
++};
++
++static const char * const aud_2_parents[] = {
++	"clk26m",
++	"apll2_ck",
++	"univpll2_d4",
++	"univpll2_d8"
++};
++
++static const char * const mem_mfg_parents[] = {
++	"clk26m",
++	"mmpll_ck",
++	"univpll_d3"
++};
++
++static const char * const axi_mfg_parents[] = {
++	"clk26m",
++	"axi_sel",
++	"univpll_d5"
++};
++
++static const char * const scam_parents[] = {
++	"clk26m",
++	"syspll3_d2",
++	"univpll2_d4",
++	"syspll2_d4"
++};
++
++static const char * const nfiecc_parents[] = {
++	"clk26m",
++	"nfi2x_sel",
++	"syspll_d7",
++	"syspll2_d2",
++	"univpll2_d2",
++	"univpll_d5",
++	"syspll1_d2"
++};
++
++static const char * const pe2_mac_p0_parents[] = {
++	"clk26m",
++	"syspll1_d8",
++	"syspll4_d2",
++	"syspll2_d4",
++	"univpll2_d4",
++	"syspll3_d2"
++};
++
++static const char * const dpilvds_parents[] = {
++	"clk26m",
++	"lvdspll_ck",
++	"lvdspll_d2",
++	"lvdspll_d4",
++	"lvdspll_d8",
++	"clkfpc"
++};
++
++static const char * const hdcp_parents[] = {
++	"clk26m",
++	"syspll4_d2",
++	"syspll3_d4",
++	"univpll2_d4"
++};
++
++static const char * const hdcp_24m_parents[] = {
++	"clk26m",
++	"univpll_d26",
++	"univpll_d52",
++	"univpll2_d8"
++};
++
++static const char * const rtc_parents[] = {
++	"clkrtc_int",
++	"clkrtc_ext",
++	"clk26m",
++	"univpll3_d8"
++};
++
++static const char * const spinor_parents[] = {
++	"clk26m",
++	"clk26m_d2",
++	"syspll4_d4",
++	"univpll2_d8",
++	"univpll3_d4",
++	"syspll4_d2",
++	"syspll2_d4",
++	"univpll2_d4",
++	"etherpll_125m",
++	"syspll1_d4"
++};
++
++static const char * const apll_parents[] = {
++	"clk26m",
++	"apll1_ck",
++	"apll1_d2",
++	"apll1_d4",
++	"apll1_d8",
++	"apll1_d16",
++	"apll2_ck",
++	"apll2_d2",
++	"apll2_d4",
++	"apll2_d8",
++	"apll2_d16",
++	"clk26m",
++	"clk26m"
++};
++
++static const char * const a1sys_hp_parents[] = {
++	"clk26m",
++	"apll1_ck",
++	"apll1_d2",
++	"apll1_d4",
++	"apll1_d8"
++};
++
++static const char * const a2sys_hp_parents[] = {
++	"clk26m",
++	"apll2_ck",
++	"apll2_d2",
++	"apll2_d4",
++	"apll2_d8"
++};
++
++static const char * const asm_l_parents[] = {
++	"clk26m",
++	"univpll2_d4",
++	"univpll2_d2",
++	"syspll_d5"
++};
++
++static const char * const i2so1_parents[] = {
++	"clk26m",
++	"apll1_ck",
++	"apll2_ck"
++};
++
++static const char * const ether_125m_parents[] = {
++	"clk26m",
++	"etherpll_125m",
++	"univpll3_d2"
++};
++
++static const char * const ether_50m_parents[] = {
++	"clk26m",
++	"etherpll_50m",
++	"univpll_d26",
++	"univpll3_d4"
++};
++
++static const char * const jpgdec_parents[] = {
++	"clk26m",
++	"univpll_d3",
++	"tvdpll_429m",
++	"vencpll_ck",
++	"syspll_d3",
++	"vcodecpll_ck",
++	"univpll1_d2",
++	"armca35pll_400m",
++	"tvdpll_429m_d2",
++	"tvdpll_429m_d4"
++};
++
++static const char * const spislv_parents[] = {
++	"clk26m",
++	"univpll2_d4",
++	"univpll1_d4",
++	"univpll2_d2",
++	"univpll3_d2",
++	"univpll1_d8",
++	"univpll1_d2",
++	"univpll_d5"
++};
++
++static const char * const ether_parents[] = {
++	"clk26m",
++	"etherpll_50m",
++	"univpll_d26"
++};
++
++static const char * const di_parents[] = {
++	"clk26m",
++	"tvdpll_d2",
++	"tvdpll_d4",
++	"tvdpll_d8",
++	"vencpll_ck",
++	"vencpll_d2",
++	"cvbs",
++	"cvbs_d2"
++};
++
++static const char * const tvd_parents[] = {
++	"clk26m",
++	"cvbs_d2",
++	"univpll2_d8"
++};
++
++static const char * const i2c_parents[] = {
++	"clk26m",
++	"univpll_d26",
++	"univpll2_d4",
++	"univpll3_d2",
++	"univpll1_d4"
++};
++
++static const char * const msdc0p_aes_parents[] = {
++	"clk26m",
++	"msdcpll_ck",
++	"univpll_d3",
++	"vcodecpll_ck"
++};
++
++static const char * const cmsys_parents[] = {
++	"clk26m",
++	"univpll_d3",
++	"syspll_d3",
++	"syspll1_d2",
++	"syspll2_d2"
++};
++
++static const char * const gcpu_parents[] = {
++	"clk26m",
++	"syspll_d3",
++	"syspll1_d2",
++	"univpll1_d2",
++	"univpll_d5",
++	"univpll3_d2",
++	"univpll_d3"
++};
++
++static const char * const aud_apll1_parents[] = {
++	"apll1",
++	"clkaud_ext_i_1"
++};
++
++static const char * const aud_apll2_parents[] = {
++	"apll2",
++	"clkaud_ext_i_2"
++};
++
++static const char * const audull_vtx_parents[] = {
++	"d2a_ulclk_6p5m",
++	"clkaud_ext_i_0"
++};
++
++static struct mtk_composite top_muxes[] = {
++	/* CLK_CFG_0 */
++	MUX_GATE_FLAGS(CLK_TOP_AXI_SEL, "axi_sel", axi_parents, 0x040, 0, 3,
++		7, CLK_IS_CRITICAL),
++	MUX_GATE_FLAGS(CLK_TOP_MEM_SEL, "mem_sel", mem_parents, 0x040, 8, 1,
++		15, CLK_IS_CRITICAL),
++	MUX_GATE(CLK_TOP_MM_SEL, "mm_sel",
++		mm_parents, 0x040, 24, 3, 31),
++	/* CLK_CFG_1 */
++	MUX_GATE(CLK_TOP_PWM_SEL, "pwm_sel",
++		pwm_parents, 0x050, 0, 2, 7),
++	MUX_GATE(CLK_TOP_VDEC_SEL, "vdec_sel",
++		vdec_parents, 0x050, 8, 4, 15),
++	MUX_GATE(CLK_TOP_VENC_SEL, "venc_sel",
++		venc_parents, 0x050, 16, 4, 23),
++	MUX_GATE(CLK_TOP_MFG_SEL, "mfg_sel",
++		mfg_parents, 0x050, 24, 4, 31),
++	/* CLK_CFG_2 */
++	MUX_GATE(CLK_TOP_CAMTG_SEL, "camtg_sel",
++		camtg_parents, 0x060, 0, 4, 7),
++	MUX_GATE(CLK_TOP_UART_SEL, "uart_sel",
++		uart_parents, 0x060, 8, 1, 15),
++	MUX_GATE(CLK_TOP_SPI_SEL, "spi_sel",
++		spi_parents, 0x060, 16, 3, 23),
++	MUX_GATE(CLK_TOP_USB20_SEL, "usb20_sel",
++		usb20_parents, 0x060, 24, 2, 31),
++	/* CLK_CFG_3 */
++	MUX_GATE(CLK_TOP_USB30_SEL, "usb30_sel",
++		usb30_parents, 0x070, 0, 2, 7),
++	MUX_GATE(CLK_TOP_MSDC50_0_HCLK_SEL, "msdc50_0_h_sel",
++		msdc50_0_h_parents, 0x070, 8, 3, 15),
++	MUX_GATE(CLK_TOP_MSDC50_0_SEL, "msdc50_0_sel",
++		msdc50_0_parents, 0x070, 16, 4, 23),
++	MUX_GATE(CLK_TOP_MSDC30_1_SEL, "msdc30_1_sel",
++		msdc30_1_parents, 0x070, 24, 3, 31),
++	/* CLK_CFG_4 */
++	MUX_GATE(CLK_TOP_MSDC30_2_SEL, "msdc30_2_sel",
++		msdc30_1_parents, 0x080, 0, 3, 7),
++	MUX_GATE(CLK_TOP_MSDC30_3_SEL, "msdc30_3_sel",
++		msdc30_3_parents, 0x080, 8, 4, 15),
++	MUX_GATE(CLK_TOP_AUDIO_SEL, "audio_sel",
++		audio_parents, 0x080, 16, 2, 23),
++	MUX_GATE(CLK_TOP_AUD_INTBUS_SEL, "aud_intbus_sel",
++		aud_intbus_parents, 0x080, 24, 3, 31),
++	/* CLK_CFG_5 */
++	MUX_GATE(CLK_TOP_PMICSPI_SEL, "pmicspi_sel",
++		pmicspi_parents, 0x090, 0, 3, 7),
++	MUX_GATE(CLK_TOP_DPILVDS1_SEL, "dpilvds1_sel",
++		dpilvds1_parents, 0x090, 8, 3, 15),
++	MUX_GATE(CLK_TOP_ATB_SEL, "atb_sel",
++		atb_parents, 0x090, 16, 2, 23),
++	MUX_GATE(CLK_TOP_NR_SEL, "nr_sel",
++		nr_parents, 0x090, 24, 3, 31),
++	/* CLK_CFG_6 */
++	MUX_GATE(CLK_TOP_NFI2X_SEL, "nfi2x_sel",
++		nfi2x_parents, 0x0a0, 0, 4, 7),
++	MUX_GATE(CLK_TOP_IRDA_SEL, "irda_sel",
++		irda_parents, 0x0a0, 8, 2, 15),
++	MUX_GATE(CLK_TOP_CCI400_SEL, "cci400_sel",
++		cci400_parents, 0x0a0, 16, 3, 23),
++	MUX_GATE(CLK_TOP_AUD_1_SEL, "aud_1_sel",
++		aud_1_parents, 0x0a0, 24, 2, 31),
++	/* CLK_CFG_7 */
++	MUX_GATE(CLK_TOP_AUD_2_SEL, "aud_2_sel",
++		aud_2_parents, 0x0b0, 0, 2, 7),
++	MUX_GATE(CLK_TOP_MEM_MFG_IN_AS_SEL, "mem_mfg_sel",
++		mem_mfg_parents, 0x0b0, 8, 2, 15),
++	MUX_GATE(CLK_TOP_AXI_MFG_IN_AS_SEL, "axi_mfg_sel",
++		axi_mfg_parents, 0x0b0, 16, 2, 23),
++	MUX_GATE(CLK_TOP_SCAM_SEL, "scam_sel",
++		scam_parents, 0x0b0, 24, 2, 31),
++	/* CLK_CFG_8 */
++	MUX_GATE(CLK_TOP_NFIECC_SEL, "nfiecc_sel",
++		nfiecc_parents, 0x0c0, 0, 3, 7),
++	MUX_GATE(CLK_TOP_PE2_MAC_P0_SEL, "pe2_mac_p0_sel",
++		pe2_mac_p0_parents, 0x0c0, 8, 3, 15),
++	MUX_GATE(CLK_TOP_PE2_MAC_P1_SEL, "pe2_mac_p1_sel",
++		pe2_mac_p0_parents, 0x0c0, 16, 3, 23),
++	MUX_GATE(CLK_TOP_DPILVDS_SEL, "dpilvds_sel",
++		dpilvds_parents, 0x0c0, 24, 3, 31),
++	/* CLK_CFG_9 */
++	MUX_GATE(CLK_TOP_MSDC50_3_HCLK_SEL, "msdc50_3_h_sel",
++		msdc50_0_h_parents, 0x0d0, 0, 3, 7),
++	MUX_GATE(CLK_TOP_HDCP_SEL, "hdcp_sel",
++		hdcp_parents, 0x0d0, 8, 2, 15),
++	MUX_GATE(CLK_TOP_HDCP_24M_SEL, "hdcp_24m_sel",
++		hdcp_24m_parents, 0x0d0, 16, 2, 23),
++	MUX_GATE_FLAGS(CLK_TOP_RTC_SEL, "rtc_sel", rtc_parents, 0x0d0, 24, 2,
++		31, CLK_IS_CRITICAL),
++	/* CLK_CFG_10 */
++	MUX_GATE(CLK_TOP_SPINOR_SEL, "spinor_sel",
++		spinor_parents, 0x500, 0, 4, 7),
++	MUX_GATE(CLK_TOP_APLL_SEL, "apll_sel",
++		apll_parents, 0x500, 8, 4, 15),
++	MUX_GATE(CLK_TOP_APLL2_SEL, "apll2_sel",
++		apll_parents, 0x500, 16, 4, 23),
++	MUX_GATE(CLK_TOP_A1SYS_HP_SEL, "a1sys_hp_sel",
++		a1sys_hp_parents, 0x500, 24, 3, 31),
++	/* CLK_CFG_11 */
++	MUX_GATE(CLK_TOP_A2SYS_HP_SEL, "a2sys_hp_sel",
++		a2sys_hp_parents, 0x510, 0, 3, 7),
++	MUX_GATE(CLK_TOP_ASM_L_SEL, "asm_l_sel",
++		asm_l_parents, 0x510, 8, 2, 15),
++	MUX_GATE(CLK_TOP_ASM_M_SEL, "asm_m_sel",
++		asm_l_parents, 0x510, 16, 2, 23),
++	MUX_GATE(CLK_TOP_ASM_H_SEL, "asm_h_sel",
++		asm_l_parents, 0x510, 24, 2, 31),
++	/* CLK_CFG_12 */
++	MUX_GATE(CLK_TOP_I2SO1_SEL, "i2so1_sel",
++		i2so1_parents, 0x520, 0, 2, 7),
++	MUX_GATE(CLK_TOP_I2SO2_SEL, "i2so2_sel",
++		i2so1_parents, 0x520, 8, 2, 15),
++	MUX_GATE(CLK_TOP_I2SO3_SEL, "i2so3_sel",
++		i2so1_parents, 0x520, 16, 2, 23),
++	MUX_GATE(CLK_TOP_TDMO0_SEL, "tdmo0_sel",
++		i2so1_parents, 0x520, 24, 2, 31),
++	/* CLK_CFG_13 */
++	MUX_GATE(CLK_TOP_TDMO1_SEL, "tdmo1_sel",
++		i2so1_parents, 0x530, 0, 2, 7),
++	MUX_GATE(CLK_TOP_I2SI1_SEL, "i2si1_sel",
++		i2so1_parents, 0x530, 8, 2, 15),
++	MUX_GATE(CLK_TOP_I2SI2_SEL, "i2si2_sel",
++		i2so1_parents, 0x530, 16, 2, 23),
++	MUX_GATE(CLK_TOP_I2SI3_SEL, "i2si3_sel",
++		i2so1_parents, 0x530, 24, 2, 31),
++	/* CLK_CFG_14 */
++	MUX_GATE(CLK_TOP_ETHER_125M_SEL, "ether_125m_sel",
++		ether_125m_parents, 0x540, 0, 2, 7),
++	MUX_GATE(CLK_TOP_ETHER_50M_SEL, "ether_50m_sel",
++		ether_50m_parents, 0x540, 8, 2, 15),
++	MUX_GATE(CLK_TOP_JPGDEC_SEL, "jpgdec_sel",
++		jpgdec_parents, 0x540, 16, 4, 23),
++	MUX_GATE(CLK_TOP_SPISLV_SEL, "spislv_sel",
++		spislv_parents, 0x540, 24, 3, 31),
++	/* CLK_CFG_15 */
++	MUX_GATE(CLK_TOP_ETHER_50M_RMII_SEL, "ether_sel",
++		ether_parents, 0x550, 0, 2, 7),
++	MUX_GATE(CLK_TOP_CAM2TG_SEL, "cam2tg_sel",
++		camtg_parents, 0x550, 8, 4, 15),
++	MUX_GATE(CLK_TOP_DI_SEL, "di_sel",
++		di_parents, 0x550, 16, 3, 23),
++	MUX_GATE(CLK_TOP_TVD_SEL, "tvd_sel",
++		tvd_parents, 0x550, 24, 2, 31),
++	/* CLK_CFG_16 */
++	MUX_GATE(CLK_TOP_I2C_SEL, "i2c_sel",
++		i2c_parents, 0x560, 0, 3, 7),
++	MUX_GATE(CLK_TOP_PWM_INFRA_SEL, "pwm_infra_sel",
++		pwm_parents, 0x560, 8, 2, 15),
++	MUX_GATE(CLK_TOP_MSDC0P_AES_SEL, "msdc0p_aes_sel",
++		msdc0p_aes_parents, 0x560, 16, 2, 23),
++	MUX_GATE(CLK_TOP_CMSYS_SEL, "cmsys_sel",
++		cmsys_parents, 0x560, 24, 3, 31),
++	/* CLK_CFG_17 */
++	MUX_GATE(CLK_TOP_GCPU_SEL, "gcpu_sel",
++		gcpu_parents, 0x570, 0, 3, 7),
++	/* CLK_AUDDIV_4 */
++	MUX(CLK_TOP_AUD_APLL1_SEL, "aud_apll1_sel",
++		aud_apll1_parents, 0x134, 0, 1),
++	MUX(CLK_TOP_AUD_APLL2_SEL, "aud_apll2_sel",
++		aud_apll2_parents, 0x134, 1, 1),
++	MUX(CLK_TOP_DA_AUDULL_VTX_6P5M_SEL, "audull_vtx_sel",
++		audull_vtx_parents, 0x134, 31, 1),
++};
++
++static const char * const mcu_mp0_parents[] = {
++	"clk26m",
++	"armca35pll_ck",
++	"f_mp0_pll1_ck",
++	"f_mp0_pll2_ck"
++};
++
++static const char * const mcu_mp2_parents[] = {
++	"clk26m",
++	"armca72pll_ck",
++	"f_big_pll1_ck",
++	"f_big_pll2_ck"
++};
++
++static const char * const mcu_bus_parents[] = {
++	"clk26m",
++	"cci400_sel",
++	"f_bus_pll1_ck",
++	"f_bus_pll2_ck"
++};
++
++static struct mtk_composite mcu_muxes[] = {
++	/* mp0_pll_divider_cfg */
++	MUX_GATE_FLAGS(CLK_MCU_MP0_SEL, "mcu_mp0_sel", mcu_mp0_parents, 0x7A0,
++		9, 2, -1, CLK_IS_CRITICAL),
++	/* mp2_pll_divider_cfg */
++	MUX_GATE_FLAGS(CLK_MCU_MP2_SEL, "mcu_mp2_sel", mcu_mp2_parents, 0x7A8,
++		9, 2, -1, CLK_IS_CRITICAL),
++	/* bus_pll_divider_cfg */
++	MUX_GATE_FLAGS(CLK_MCU_BUS_SEL, "mcu_bus_sel", mcu_bus_parents, 0x7C0,
++		9, 2, -1, CLK_IS_CRITICAL),
++};
++
++static const struct mtk_clk_divider top_adj_divs[] = {
++	DIV_ADJ(CLK_TOP_APLL_DIV0, "apll_div0", "i2so1_sel", 0x124, 0, 8),
++	DIV_ADJ(CLK_TOP_APLL_DIV1, "apll_div1", "i2so2_sel", 0x124, 8, 8),
++	DIV_ADJ(CLK_TOP_APLL_DIV2, "apll_div2", "i2so3_sel", 0x124, 16, 8),
++	DIV_ADJ(CLK_TOP_APLL_DIV3, "apll_div3", "tdmo0_sel", 0x124, 24, 8),
++	DIV_ADJ(CLK_TOP_APLL_DIV4, "apll_div4", "tdmo1_sel", 0x128, 0, 8),
++	DIV_ADJ(CLK_TOP_APLL_DIV5, "apll_div5", "i2si1_sel", 0x128, 8, 8),
++	DIV_ADJ(CLK_TOP_APLL_DIV6, "apll_div6", "i2si2_sel", 0x128, 16, 8),
++	DIV_ADJ(CLK_TOP_APLL_DIV7, "apll_div7", "i2si3_sel", 0x128, 24, 8),
++};
++
++static const struct mtk_gate_regs top_cg_regs = {
++	.set_ofs = 0x120,
++	.clr_ofs = 0x120,
++	.sta_ofs = 0x120,
++};
++
++#define GATE_TOP(_id, _name, _parent, _shift) {	\
++		.id = _id,				\
++		.name = _name,				\
++		.parent_name = _parent,			\
++		.regs = &top_cg_regs,			\
++		.shift = _shift,			\
++		.ops = &mtk_clk_gate_ops_no_setclr,	\
++	}
++
++static const struct mtk_gate top_clks[] = {
++	GATE_TOP(CLK_TOP_APLL_DIV_PDN0, "apll_div_pdn0", "i2so1_sel", 0),
++	GATE_TOP(CLK_TOP_APLL_DIV_PDN1, "apll_div_pdn1", "i2so2_sel", 1),
++	GATE_TOP(CLK_TOP_APLL_DIV_PDN2, "apll_div_pdn2", "i2so3_sel", 2),
++	GATE_TOP(CLK_TOP_APLL_DIV_PDN3, "apll_div_pdn3", "tdmo0_sel", 3),
++	GATE_TOP(CLK_TOP_APLL_DIV_PDN4, "apll_div_pdn4", "tdmo1_sel", 4),
++	GATE_TOP(CLK_TOP_APLL_DIV_PDN5, "apll_div_pdn5", "i2si1_sel", 5),
++	GATE_TOP(CLK_TOP_APLL_DIV_PDN6, "apll_div_pdn6", "i2si2_sel", 6),
++	GATE_TOP(CLK_TOP_APLL_DIV_PDN7, "apll_div_pdn7", "i2si3_sel", 7),
++};
++
++static const struct mtk_gate_regs infra_cg_regs = {
++	.set_ofs = 0x40,
++	.clr_ofs = 0x44,
++	.sta_ofs = 0x40,
++};
++
++#define GATE_INFRA(_id, _name, _parent, _shift) {	\
++		.id = _id,				\
++		.name = _name,				\
++		.parent_name = _parent,			\
++		.regs = &infra_cg_regs,			\
++		.shift = _shift,			\
++		.ops = &mtk_clk_gate_ops_setclr,	\
++	}
++
++static const struct mtk_gate infra_clks[] = {
++	GATE_INFRA(CLK_INFRA_DBGCLK, "infra_dbgclk", "axi_sel", 0),
++	GATE_INFRA(CLK_INFRA_GCE, "infra_gce", "axi_sel", 6),
++	GATE_INFRA(CLK_INFRA_M4U, "infra_m4u", "mem_sel", 8),
++	GATE_INFRA(CLK_INFRA_KP, "infra_kp", "axi_sel", 16),
++	GATE_INFRA(CLK_INFRA_AO_SPI0, "infra_ao_spi0", "spi_sel", 24),
++	GATE_INFRA(CLK_INFRA_AO_SPI1, "infra_ao_spi1", "spislv_sel", 25),
++	GATE_INFRA(CLK_INFRA_AO_UART5, "infra_ao_uart5", "axi_sel", 26),
++};
++
++static const struct mtk_gate_regs peri0_cg_regs = {
++	.set_ofs = 0x8,
++	.clr_ofs = 0x10,
++	.sta_ofs = 0x18,
++};
++
++static const struct mtk_gate_regs peri1_cg_regs = {
++	.set_ofs = 0xc,
++	.clr_ofs = 0x14,
++	.sta_ofs = 0x1c,
++};
++
++static const struct mtk_gate_regs peri2_cg_regs = {
++	.set_ofs = 0x42c,
++	.clr_ofs = 0x42c,
++	.sta_ofs = 0x42c,
++};
++
++#define GATE_PERI0(_id, _name, _parent, _shift) {	\
++		.id = _id,				\
++		.name = _name,				\
++		.parent_name = _parent,			\
++		.regs = &peri0_cg_regs,			\
++		.shift = _shift,			\
++		.ops = &mtk_clk_gate_ops_setclr,	\
++	}
++
++#define GATE_PERI1(_id, _name, _parent, _shift) {	\
++		.id = _id,				\
++		.name = _name,				\
++		.parent_name = _parent,			\
++		.regs = &peri1_cg_regs,			\
++		.shift = _shift,			\
++		.ops = &mtk_clk_gate_ops_setclr,	\
++	}
++
++#define GATE_PERI2(_id, _name, _parent, _shift) {	\
++		.id = _id,				\
++		.name = _name,				\
++		.parent_name = _parent,			\
++		.regs = &peri2_cg_regs,			\
++		.shift = _shift,			\
++		.ops = &mtk_clk_gate_ops_no_setclr_inv,	\
++	}
++
++static const struct mtk_gate peri_clks[] = {
++	/* PERI0 */
++	GATE_PERI0(CLK_PERI_NFI, "per_nfi",
++		"axi_sel", 0),
++	GATE_PERI0(CLK_PERI_THERM, "per_therm",
++		"axi_sel", 1),
++	GATE_PERI0(CLK_PERI_PWM0, "per_pwm0",
++		"pwm_sel", 2),
++	GATE_PERI0(CLK_PERI_PWM1, "per_pwm1",
++		"pwm_sel", 3),
++	GATE_PERI0(CLK_PERI_PWM2, "per_pwm2",
++		"pwm_sel", 4),
++	GATE_PERI0(CLK_PERI_PWM3, "per_pwm3",
++		"pwm_sel", 5),
++	GATE_PERI0(CLK_PERI_PWM4, "per_pwm4",
++		"pwm_sel", 6),
++	GATE_PERI0(CLK_PERI_PWM5, "per_pwm5",
++		"pwm_sel", 7),
++	GATE_PERI0(CLK_PERI_PWM6, "per_pwm6",
++		"pwm_sel", 8),
++	GATE_PERI0(CLK_PERI_PWM7, "per_pwm7",
++		"pwm_sel", 9),
++	GATE_PERI0(CLK_PERI_PWM, "per_pwm",
++		"pwm_sel", 10),
++	GATE_PERI0(CLK_PERI_AP_DMA, "per_ap_dma",
++		"axi_sel", 13),
++	GATE_PERI0(CLK_PERI_MSDC30_0, "per_msdc30_0",
++		"msdc50_0_sel", 14),
++	GATE_PERI0(CLK_PERI_MSDC30_1, "per_msdc30_1",
++		"msdc30_1_sel", 15),
++	GATE_PERI0(CLK_PERI_MSDC30_2, "per_msdc30_2",
++		"msdc30_2_sel", 16),
++	GATE_PERI0(CLK_PERI_MSDC30_3, "per_msdc30_3",
++		"msdc30_3_sel", 17),
++	GATE_PERI0(CLK_PERI_UART0, "per_uart0",
++		"uart_sel", 20),
++	GATE_PERI0(CLK_PERI_UART1, "per_uart1",
++		"uart_sel", 21),
++	GATE_PERI0(CLK_PERI_UART2, "per_uart2",
++		"uart_sel", 22),
++	GATE_PERI0(CLK_PERI_UART3, "per_uart3",
++		"uart_sel", 23),
++	GATE_PERI0(CLK_PERI_I2C0, "per_i2c0",
++		"axi_sel", 24),
++	GATE_PERI0(CLK_PERI_I2C1, "per_i2c1",
++		"axi_sel", 25),
++	GATE_PERI0(CLK_PERI_I2C2, "per_i2c2",
++		"axi_sel", 26),
++	GATE_PERI0(CLK_PERI_I2C3, "per_i2c3",
++		"axi_sel", 27),
++	GATE_PERI0(CLK_PERI_I2C4, "per_i2c4",
++		"axi_sel", 28),
++	GATE_PERI0(CLK_PERI_AUXADC, "per_auxadc",
++		"ltepll_fs26m", 29),
++	GATE_PERI0(CLK_PERI_SPI0, "per_spi0",
++		"spi_sel", 30),
++	/* PERI1 */
++	GATE_PERI1(CLK_PERI_SPI, "per_spi",
++		"spinor_sel", 1),
++	GATE_PERI1(CLK_PERI_I2C5, "per_i2c5",
++		"axi_sel", 3),
++	GATE_PERI1(CLK_PERI_SPI2, "per_spi2",
++		"spi_sel", 5),
++	GATE_PERI1(CLK_PERI_SPI3, "per_spi3",
++		"spi_sel", 6),
++	GATE_PERI1(CLK_PERI_SPI5, "per_spi5",
++		"spi_sel", 8),
++	GATE_PERI1(CLK_PERI_UART4, "per_uart4",
++		"uart_sel", 9),
++	GATE_PERI1(CLK_PERI_SFLASH, "per_sflash",
++		"uart_sel", 11),
++	GATE_PERI1(CLK_PERI_GMAC, "per_gmac",
++		"uart_sel", 12),
++	GATE_PERI1(CLK_PERI_PCIE0, "per_pcie0",
++		"uart_sel", 14),
++	GATE_PERI1(CLK_PERI_PCIE1, "per_pcie1",
++		"uart_sel", 15),
++	GATE_PERI1(CLK_PERI_GMAC_PCLK, "per_gmac_pclk",
++		"uart_sel", 16),
++	/* PERI2 */
++	GATE_PERI2(CLK_PERI_MSDC50_0_EN, "per_msdc50_0_en",
++		"msdc50_0_sel", 0),
++	GATE_PERI2(CLK_PERI_MSDC30_1_EN, "per_msdc30_1_en",
++		"msdc30_1_sel", 1),
++	GATE_PERI2(CLK_PERI_MSDC30_2_EN, "per_msdc30_2_en",
++		"msdc30_2_sel", 2),
++	GATE_PERI2(CLK_PERI_MSDC30_3_EN, "per_msdc30_3_en",
++		"msdc30_3_sel", 3),
++	GATE_PERI2(CLK_PERI_MSDC50_0_HCLK_EN, "per_msdc50_0_h",
++		"msdc50_0_h_sel", 4),
++	GATE_PERI2(CLK_PERI_MSDC50_3_HCLK_EN, "per_msdc50_3_h",
++		"msdc50_3_h_sel", 5),
++};
++
++#define MT2712_PLL_FMAX		(3000UL * MHZ)
++
++#define CON0_MT2712_RST_BAR	BIT(24)
++
++#define PLL_B(_id, _name, _reg, _pwr_reg, _en_mask, _flags, _pcwbits,	\
++			_pd_reg, _pd_shift, _tuner_reg, _tuner_en_reg,	\
++			_tuner_en_bit, _pcw_reg, _pcw_shift,		\
++			_div_table) {					\
++		.id = _id,						\
++		.name = _name,						\
++		.reg = _reg,						\
++		.pwr_reg = _pwr_reg,					\
++		.en_mask = _en_mask,					\
++		.flags = _flags,					\
++		.rst_bar_mask = CON0_MT2712_RST_BAR,			\
++		.fmax = MT2712_PLL_FMAX,				\
++		.pcwbits = _pcwbits,					\
++		.pd_reg = _pd_reg,					\
++		.pd_shift = _pd_shift,					\
++		.tuner_reg = _tuner_reg,				\
++		.tuner_en_reg = _tuner_en_reg,				\
++		.tuner_en_bit = _tuner_en_bit,				\
++		.pcw_reg = _pcw_reg,					\
++		.pcw_shift = _pcw_shift,				\
++		.div_table = _div_table,				\
++	}
++
++#define PLL(_id, _name, _reg, _pwr_reg, _en_mask, _flags, _pcwbits,	\
++			_pd_reg, _pd_shift, _tuner_reg, _tuner_en_reg,	\
++			_tuner_en_bit, _pcw_reg, _pcw_shift)		\
++		PLL_B(_id, _name, _reg, _pwr_reg, _en_mask, _flags,	\
++			_pcwbits, _pd_reg, _pd_shift, _tuner_reg,	\
++			_tuner_en_reg, _tuner_en_bit, _pcw_reg,		\
++			_pcw_shift, NULL)
++
++static const struct mtk_pll_div_table armca35pll_div_table[] = {
++	{ .div = 0, .freq = MT2712_PLL_FMAX },
++	{ .div = 1, .freq = 1202500000 },
++	{ .div = 2, .freq = 500500000 },
++	{ .div = 3, .freq = 315250000 },
++	{ .div = 4, .freq = 157625000 },
++	{ } /* sentinel */
++};
++
++static const struct mtk_pll_div_table armca72pll_div_table[] = {
++	{ .div = 0, .freq = MT2712_PLL_FMAX },
++	{ .div = 1, .freq = 994500000 },
++	{ .div = 2, .freq = 520000000 },
++	{ .div = 3, .freq = 315250000 },
++	{ .div = 4, .freq = 157625000 },
++	{ } /* sentinel */
++};
++
++static const struct mtk_pll_div_table mmpll_div_table[] = {
++	{ .div = 0, .freq = MT2712_PLL_FMAX },
++	{ .div = 1, .freq = 1001000000 },
++	{ .div = 2, .freq = 601250000 },
++	{ .div = 3, .freq = 250250000 },
++	{ .div = 4, .freq = 125125000 },
++	{ } /* sentinel */
++};
++
++static const struct mtk_pll_data plls[] = {
++	PLL(CLK_APMIXED_MAINPLL, "mainpll", 0x0230, 0x023C, 0xf0000101,
++		HAVE_RST_BAR, 31, 0x0230, 4, 0, 0, 0, 0x0234, 0),
++	PLL(CLK_APMIXED_UNIVPLL, "univpll", 0x0240, 0x024C, 0xfe000101,
++		HAVE_RST_BAR, 31, 0x0240, 4, 0, 0, 0, 0x0244, 0),
++	PLL(CLK_APMIXED_VCODECPLL, "vcodecpll", 0x0320, 0x032C, 0xc0000101,
++		0, 31, 0x0320, 4, 0, 0, 0, 0x0324, 0),
++	PLL(CLK_APMIXED_VENCPLL, "vencpll", 0x0280, 0x028C, 0x00000101,
++		0, 31, 0x0280, 4, 0, 0, 0, 0x0284, 0),
++	PLL(CLK_APMIXED_APLL1, "apll1", 0x0330, 0x0340, 0x00000101,
++		0, 31, 0x0330, 4, 0x0338, 0x0014, 0, 0x0334, 0),
++	PLL(CLK_APMIXED_APLL2, "apll2", 0x0350, 0x0360, 0x00000101,
++		0, 31, 0x0350, 4, 0x0358, 0x0014, 1, 0x0354, 0),
++	PLL(CLK_APMIXED_LVDSPLL, "lvdspll", 0x0370, 0x037c, 0x00000101,
++		0, 31, 0x0370, 4, 0, 0, 0, 0x0374, 0),
++	PLL(CLK_APMIXED_LVDSPLL2, "lvdspll2", 0x0390, 0x039C, 0x00000101,
++		0, 31, 0x0390, 4, 0, 0, 0, 0x0394, 0),
++	PLL(CLK_APMIXED_MSDCPLL, "msdcpll", 0x0270, 0x027C, 0x00000101,
++		0, 31, 0x0270, 4, 0, 0, 0, 0x0274, 0),
++	PLL(CLK_APMIXED_MSDCPLL2, "msdcpll2", 0x0410, 0x041C, 0x00000101,
++		0, 31, 0x0410, 4, 0, 0, 0, 0x0414, 0),
++	PLL(CLK_APMIXED_TVDPLL, "tvdpll", 0x0290, 0x029C, 0xc0000101,
++		0, 31, 0x0290, 4, 0, 0, 0, 0x0294, 0),
++	PLL_B(CLK_APMIXED_MMPLL, "mmpll", 0x0250, 0x0260, 0x00000101,
++		0, 31, 0x0250, 4, 0, 0, 0, 0x0254, 0,
++		mmpll_div_table),
++	PLL_B(CLK_APMIXED_ARMCA35PLL, "armca35pll", 0x0100, 0x0110, 0xf0000101,
++		HAVE_RST_BAR, 31, 0x0100, 4, 0, 0, 0, 0x0104, 0,
++		armca35pll_div_table),
++	PLL_B(CLK_APMIXED_ARMCA72PLL, "armca72pll", 0x0210, 0x0220, 0x00000101,
++		0, 31, 0x0210, 4, 0, 0, 0, 0x0214, 0,
++		armca72pll_div_table),
++	PLL(CLK_APMIXED_ETHERPLL, "etherpll", 0x0300, 0x030C, 0xc0000101,
++		0, 31, 0x0300, 4, 0, 0, 0, 0x0304, 0),
++};
++
++static int clk_mt2712_apmixed_probe(struct platform_device *pdev)
++{
++	struct clk_onecell_data *clk_data;
++	int r;
++	struct device_node *node = pdev->dev.of_node;
++
++	clk_data = mtk_alloc_clk_data(CLK_APMIXED_NR_CLK);
++
++	mtk_clk_register_plls(node, plls, ARRAY_SIZE(plls), clk_data);
++
++	r = of_clk_add_provider(node, of_clk_src_onecell_get, clk_data);
++
++	if (r != 0)
++		pr_err("%s(): could not register clock provider: %d\n",
++			__func__, r);
++
++	return r;
++}
++
++static struct clk_onecell_data *top_clk_data;
++
++static void clk_mt2712_top_init_early(struct device_node *node)
++{
++	int r, i;
++
++	if (!top_clk_data) {
++		top_clk_data = mtk_alloc_clk_data(CLK_TOP_NR_CLK);
++
++		for (i = 0; i < CLK_TOP_NR_CLK; i++)
++			top_clk_data->clks[i] = ERR_PTR(-EPROBE_DEFER);
++	}
++
++	mtk_clk_register_factors(top_early_divs, ARRAY_SIZE(top_early_divs),
++			top_clk_data);
++
++	r = of_clk_add_provider(node, of_clk_src_onecell_get, top_clk_data);
++	if (r)
++		pr_err("%s(): could not register clock provider: %d\n",
++			__func__, r);
++}
++
++CLK_OF_DECLARE_DRIVER(mt2712_topckgen, "mediatek,mt2712-topckgen",
++			clk_mt2712_top_init_early);
++
++static int clk_mt2712_top_probe(struct platform_device *pdev)
++{
++	int r, i;
++	struct device_node *node = pdev->dev.of_node;
++	void __iomem *base;
++	struct resource *res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
++
++	base = devm_ioremap_resource(&pdev->dev, res);
++	if (IS_ERR(base)) {
++		pr_err("%s(): ioremap failed\n", __func__);
++		return PTR_ERR(base);
++	}
++
++	if (!top_clk_data) {
++		top_clk_data = mtk_alloc_clk_data(CLK_TOP_NR_CLK);
++	} else {
++		for (i = 0; i < CLK_TOP_NR_CLK; i++) {
++			if (top_clk_data->clks[i] == ERR_PTR(-EPROBE_DEFER))
++				top_clk_data->clks[i] = ERR_PTR(-ENOENT);
++		}
++	}
++
++	mtk_clk_register_fixed_clks(top_fixed_clks, ARRAY_SIZE(top_fixed_clks),
++			top_clk_data);
++	mtk_clk_register_factors(top_early_divs, ARRAY_SIZE(top_early_divs),
++			top_clk_data);
++	mtk_clk_register_factors(top_divs, ARRAY_SIZE(top_divs), top_clk_data);
++	mtk_clk_register_composites(top_muxes, ARRAY_SIZE(top_muxes), base,
++			&mt2712_clk_lock, top_clk_data);
++	mtk_clk_register_dividers(top_adj_divs, ARRAY_SIZE(top_adj_divs), base,
++			&mt2712_clk_lock, top_clk_data);
++	mtk_clk_register_gates(node, top_clks, ARRAY_SIZE(top_clks),
++			top_clk_data);
++
++	r = of_clk_add_provider(node, of_clk_src_onecell_get, top_clk_data);
++
++	if (r != 0)
++		pr_err("%s(): could not register clock provider: %d\n",
++			__func__, r);
++
++	return r;
++}
++
++static int clk_mt2712_infra_probe(struct platform_device *pdev)
++{
++	struct clk_onecell_data *clk_data;
++	int r;
++	struct device_node *node = pdev->dev.of_node;
++
++	clk_data = mtk_alloc_clk_data(CLK_INFRA_NR_CLK);
++
++	mtk_clk_register_gates(node, infra_clks, ARRAY_SIZE(infra_clks),
++			clk_data);
++
++	r = of_clk_add_provider(node, of_clk_src_onecell_get, clk_data);
++
++	if (r != 0)
++		pr_err("%s(): could not register clock provider: %d\n",
++			__func__, r);
++
++	mtk_register_reset_controller(node, 2, 0x30);
++
++	return r;
++}
++
++static int clk_mt2712_peri_probe(struct platform_device *pdev)
++{
++	struct clk_onecell_data *clk_data;
++	int r;
++	struct device_node *node = pdev->dev.of_node;
++
++	clk_data = mtk_alloc_clk_data(CLK_PERI_NR_CLK);
++
++	mtk_clk_register_gates(node, peri_clks, ARRAY_SIZE(peri_clks),
++			clk_data);
++
++	r = of_clk_add_provider(node, of_clk_src_onecell_get, clk_data);
++
++	if (r != 0)
++		pr_err("%s(): could not register clock provider: %d\n",
++			__func__, r);
++
++	mtk_register_reset_controller(node, 2, 0);
++
++	return r;
++}
++
++static int clk_mt2712_mcu_probe(struct platform_device *pdev)
++{
++	struct clk_onecell_data *clk_data;
++	int r;
++	struct device_node *node = pdev->dev.of_node;
++	void __iomem *base;
++	struct resource *res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
++
++	base = devm_ioremap_resource(&pdev->dev, res);
++	if (IS_ERR(base)) {
++		pr_err("%s(): ioremap failed\n", __func__);
++		return PTR_ERR(base);
++	}
++
++	clk_data = mtk_alloc_clk_data(CLK_MCU_NR_CLK);
++
++	mtk_clk_register_composites(mcu_muxes, ARRAY_SIZE(mcu_muxes), base,
++			&mt2712_clk_lock, clk_data);
++
++	r = of_clk_add_provider(node, of_clk_src_onecell_get, clk_data);
++
++	if (r != 0)
++		pr_err("%s(): could not register clock provider: %d\n",
++			__func__, r);
++
++	return r;
++}
++
++static const struct of_device_id of_match_clk_mt2712[] = {
++	{
++		.compatible = "mediatek,mt2712-apmixedsys",
++		.data = clk_mt2712_apmixed_probe,
++	}, {
++		.compatible = "mediatek,mt2712-topckgen",
++		.data = clk_mt2712_top_probe,
++	}, {
++		.compatible = "mediatek,mt2712-infracfg",
++		.data = clk_mt2712_infra_probe,
++	}, {
++		.compatible = "mediatek,mt2712-pericfg",
++		.data = clk_mt2712_peri_probe,
++	}, {
++		.compatible = "mediatek,mt2712-mcucfg",
++		.data = clk_mt2712_mcu_probe,
++	}, {
++		/* sentinel */
++	}
++};
++
++static int clk_mt2712_probe(struct platform_device *pdev)
++{
++	int (*clk_probe)(struct platform_device *);
++	int r;
++
++	clk_probe = of_device_get_match_data(&pdev->dev);
++	if (!clk_probe)
++		return -EINVAL;
++
++	r = clk_probe(pdev);
++	if (r != 0)
++		dev_err(&pdev->dev,
++			"could not register clock provider: %s: %d\n",
++			pdev->name, r);
++
++	return r;
++}
++
++static struct platform_driver clk_mt2712_drv = {
++	.probe = clk_mt2712_probe,
++	.driver = {
++		.name = "clk-mt2712",
++		.owner = THIS_MODULE,
++		.of_match_table = of_match_clk_mt2712,
++	},
++};
++
++static int __init clk_mt2712_init(void)
++{
++	return platform_driver_register(&clk_mt2712_drv);
++}
++
++arch_initcall(clk_mt2712_init);
+diff --git a/drivers/clk/mediatek/clk-mtk.h b/drivers/clk/mediatek/clk-mtk.h
+index f5d6b70ce189..f48df75cc901 100644
+--- a/drivers/clk/mediatek/clk-mtk.h
++++ b/drivers/clk/mediatek/clk-mtk.h
+@@ -207,6 +207,8 @@ struct mtk_pll_data {
+ 	uint32_t en_mask;
+ 	uint32_t pd_reg;
+ 	uint32_t tuner_reg;
++	uint32_t tuner_en_reg;
++	uint8_t tuner_en_bit;
+ 	int pd_shift;
+ 	unsigned int flags;
+ 	const struct clk_ops *ops;
+diff --git a/drivers/clk/mediatek/clk-pll.c b/drivers/clk/mediatek/clk-pll.c
+index a409142e9346..3c546bae6955 100644
+--- a/drivers/clk/mediatek/clk-pll.c
++++ b/drivers/clk/mediatek/clk-pll.c
+@@ -47,6 +47,7 @@ struct mtk_clk_pll {
+ 	void __iomem	*pd_addr;
+ 	void __iomem	*pwr_addr;
+ 	void __iomem	*tuner_addr;
++	void __iomem	*tuner_en_addr;
+ 	void __iomem	*pcw_addr;
+ 	const struct mtk_pll_data *data;
+ };
+@@ -227,7 +228,10 @@ static int mtk_pll_prepare(struct clk_hw *hw)
+ 	r |= pll->data->en_mask;
+ 	writel(r, pll->base_addr + REG_CON0);
+ 
+-	if (pll->tuner_addr) {
++	if (pll->tuner_en_addr) {
++		r = readl(pll->tuner_en_addr) | BIT(pll->data->tuner_en_bit);
++		writel(r, pll->tuner_en_addr);
++	} else if (pll->tuner_addr) {
+ 		r = readl(pll->tuner_addr) | AUDPLL_TUNER_EN;
+ 		writel(r, pll->tuner_addr);
+ 	}
+@@ -254,7 +258,10 @@ static void mtk_pll_unprepare(struct clk_hw *hw)
+ 		writel(r, pll->base_addr + REG_CON0);
+ 	}
+ 
+-	if (pll->tuner_addr) {
++	if (pll->tuner_en_addr) {
++		r = readl(pll->tuner_en_addr) & ~BIT(pll->data->tuner_en_bit);
++		writel(r, pll->tuner_en_addr);
++	} else if (pll->tuner_addr) {
+ 		r = readl(pll->tuner_addr) & ~AUDPLL_TUNER_EN;
+ 		writel(r, pll->tuner_addr);
+ 	}
+@@ -297,6 +304,8 @@ static struct clk *mtk_clk_register_pll(const struct mtk_pll_data *data,
+ 	pll->pcw_addr = base + data->pcw_reg;
+ 	if (data->tuner_reg)
+ 		pll->tuner_addr = base + data->tuner_reg;
++	if (data->tuner_en_reg)
++		pll->tuner_en_addr = base + data->tuner_en_reg;
+ 	pll->hw.init = &init;
+ 	pll->data = data;
+ 
+-- 
+2.11.0
+
diff --git a/target/linux/mediatek/patches-4.14/0147-dt-bindings-clock-mediatek-document-clk-bindings-for.patch b/target/linux/mediatek/patches-4.14/0147-dt-bindings-clock-mediatek-document-clk-bindings-for.patch
new file mode 100644
index 0000000000..7cdb4168bd
--- /dev/null
+++ b/target/linux/mediatek/patches-4.14/0147-dt-bindings-clock-mediatek-document-clk-bindings-for.patch
@@ -0,0 +1,217 @@
+From acfa4eba7a4391d443b33a3d90a07eae0ef2ebca Mon Sep 17 00:00:00 2001
+From: Sean Wang <sean.wang@mediatek.com>
+Date: Thu, 5 Oct 2017 11:50:22 +0800
+Subject: [PATCH 147/224] dt-bindings: clock: mediatek: document clk bindings
+ for MediaTek MT7622 SoC
+
+This patch adds the binding documentation for apmixedsys, ethsys, hifsys,
+infracfg, pericfg, topckgen and audsys for MT7622.
+
+Signed-off-by: Chen Zhong <chen.zhong@mediatek.com>
+Signed-off-by: Sean Wang <sean.wang@mediatek.com>
+Acked-by: Rob Herring <robh@kernel.org>
+Signed-off-by: Stephen Boyd <sboyd@codeaurora.org>
+---
+ .../bindings/arm/mediatek/mediatek,apmixedsys.txt  |  1 +
+ .../bindings/arm/mediatek/mediatek,audsys.txt      | 22 ++++++++++++++++++++++
+ .../bindings/arm/mediatek/mediatek,ethsys.txt      |  1 +
+ .../bindings/arm/mediatek/mediatek,hifsys.txt      |  1 +
+ .../bindings/arm/mediatek/mediatek,infracfg.txt    |  1 +
+ .../bindings/arm/mediatek/mediatek,pciesys.txt     | 22 ++++++++++++++++++++++
+ .../bindings/arm/mediatek/mediatek,pericfg.txt     |  1 +
+ .../bindings/arm/mediatek/mediatek,sgmiisys.txt    | 22 ++++++++++++++++++++++
+ .../bindings/arm/mediatek/mediatek,ssusbsys.txt    | 22 ++++++++++++++++++++++
+ .../bindings/arm/mediatek/mediatek,topckgen.txt    |  1 +
+ 10 files changed, 94 insertions(+)
+ create mode 100644 Documentation/devicetree/bindings/arm/mediatek/mediatek,audsys.txt
+ create mode 100644 Documentation/devicetree/bindings/arm/mediatek/mediatek,pciesys.txt
+ create mode 100644 Documentation/devicetree/bindings/arm/mediatek/mediatek,sgmiisys.txt
+ create mode 100644 Documentation/devicetree/bindings/arm/mediatek/mediatek,ssusbsys.txt
+
+diff --git a/Documentation/devicetree/bindings/arm/mediatek/mediatek,apmixedsys.txt b/Documentation/devicetree/bindings/arm/mediatek/mediatek,apmixedsys.txt
+index 19fc116346d6..b404d592ce58 100644
+--- a/Documentation/devicetree/bindings/arm/mediatek/mediatek,apmixedsys.txt
++++ b/Documentation/devicetree/bindings/arm/mediatek/mediatek,apmixedsys.txt
+@@ -9,6 +9,7 @@ Required Properties:
+ 	- "mediatek,mt2701-apmixedsys"
+ 	- "mediatek,mt2712-apmixedsys", "syscon"
+ 	- "mediatek,mt6797-apmixedsys"
++	- "mediatek,mt7622-apmixedsys"
+ 	- "mediatek,mt8135-apmixedsys"
+ 	- "mediatek,mt8173-apmixedsys"
+ - #clock-cells: Must be 1
+diff --git a/Documentation/devicetree/bindings/arm/mediatek/mediatek,audsys.txt b/Documentation/devicetree/bindings/arm/mediatek/mediatek,audsys.txt
+new file mode 100644
+index 000000000000..9b8f578d5e19
+--- /dev/null
++++ b/Documentation/devicetree/bindings/arm/mediatek/mediatek,audsys.txt
+@@ -0,0 +1,22 @@
++MediaTek AUDSYS controller
++============================
++
++The MediaTek AUDSYS controller provides various clocks to the system.
++
++Required Properties:
++
++- compatible: Should be one of:
++	- "mediatek,mt7622-audsys", "syscon"
++- #clock-cells: Must be 1
++
++The AUDSYS controller uses the common clk binding from
++Documentation/devicetree/bindings/clock/clock-bindings.txt
++The available clocks are defined in dt-bindings/clock/mt*-clk.h.
++
++Example:
++
++audsys: audsys@11220000 {
++	compatible = "mediatek,mt7622-audsys", "syscon";
++	reg = <0 0x11220000 0 0x1000>;
++	#clock-cells = <1>;
++};
+diff --git a/Documentation/devicetree/bindings/arm/mediatek/mediatek,ethsys.txt b/Documentation/devicetree/bindings/arm/mediatek/mediatek,ethsys.txt
+index 768f3a5bc055..7aa3fa167668 100644
+--- a/Documentation/devicetree/bindings/arm/mediatek/mediatek,ethsys.txt
++++ b/Documentation/devicetree/bindings/arm/mediatek/mediatek,ethsys.txt
+@@ -7,6 +7,7 @@ Required Properties:
+ 
+ - compatible: Should be:
+ 	- "mediatek,mt2701-ethsys", "syscon"
++	- "mediatek,mt7622-ethsys", "syscon"
+ - #clock-cells: Must be 1
+ 
+ The ethsys controller uses the common clk binding from
+diff --git a/Documentation/devicetree/bindings/arm/mediatek/mediatek,hifsys.txt b/Documentation/devicetree/bindings/arm/mediatek/mediatek,hifsys.txt
+index beed7b594cea..f5629d64cef2 100644
+--- a/Documentation/devicetree/bindings/arm/mediatek/mediatek,hifsys.txt
++++ b/Documentation/devicetree/bindings/arm/mediatek/mediatek,hifsys.txt
+@@ -8,6 +8,7 @@ Required Properties:
+ 
+ - compatible: Should be:
+ 	- "mediatek,mt2701-hifsys", "syscon"
++	- "mediatek,mt7622-hifsys", "syscon"
+ - #clock-cells: Must be 1
+ 
+ The hifsys controller uses the common clk binding from
+diff --git a/Documentation/devicetree/bindings/arm/mediatek/mediatek,infracfg.txt b/Documentation/devicetree/bindings/arm/mediatek/mediatek,infracfg.txt
+index a3430cd96d0f..566f153f9f83 100644
+--- a/Documentation/devicetree/bindings/arm/mediatek/mediatek,infracfg.txt
++++ b/Documentation/devicetree/bindings/arm/mediatek/mediatek,infracfg.txt
+@@ -10,6 +10,7 @@ Required Properties:
+ 	- "mediatek,mt2701-infracfg", "syscon"
+ 	- "mediatek,mt2712-infracfg", "syscon"
+ 	- "mediatek,mt6797-infracfg", "syscon"
++	- "mediatek,mt7622-infracfg", "syscon"
+ 	- "mediatek,mt8135-infracfg", "syscon"
+ 	- "mediatek,mt8173-infracfg", "syscon"
+ - #clock-cells: Must be 1
+diff --git a/Documentation/devicetree/bindings/arm/mediatek/mediatek,pciesys.txt b/Documentation/devicetree/bindings/arm/mediatek/mediatek,pciesys.txt
+new file mode 100644
+index 000000000000..d5d5f1227665
+--- /dev/null
++++ b/Documentation/devicetree/bindings/arm/mediatek/mediatek,pciesys.txt
+@@ -0,0 +1,22 @@
++MediaTek PCIESYS controller
++============================
++
++The MediaTek PCIESYS controller provides various clocks to the system.
++
++Required Properties:
++
++- compatible: Should be:
++	- "mediatek,mt7622-pciesys", "syscon"
++- #clock-cells: Must be 1
++
++The PCIESYS controller uses the common clk binding from
++Documentation/devicetree/bindings/clock/clock-bindings.txt
++The available clocks are defined in dt-bindings/clock/mt*-clk.h.
++
++Example:
++
++pciesys: pciesys@1a100800 {
++	compatible = "mediatek,mt7622-pciesys", "syscon";
++	reg = <0 0x1a100800 0 0x1000>;
++	#clock-cells = <1>;
++};
+diff --git a/Documentation/devicetree/bindings/arm/mediatek/mediatek,pericfg.txt b/Documentation/devicetree/bindings/arm/mediatek/mediatek,pericfg.txt
+index d9f092eb3550..fb58ca8c2770 100644
+--- a/Documentation/devicetree/bindings/arm/mediatek/mediatek,pericfg.txt
++++ b/Documentation/devicetree/bindings/arm/mediatek/mediatek,pericfg.txt
+@@ -9,6 +9,7 @@ Required Properties:
+ - compatible: Should be one of:
+ 	- "mediatek,mt2701-pericfg", "syscon"
+ 	- "mediatek,mt2712-pericfg", "syscon"
++	- "mediatek,mt7622-pericfg", "syscon"
+ 	- "mediatek,mt8135-pericfg", "syscon"
+ 	- "mediatek,mt8173-pericfg", "syscon"
+ - #clock-cells: Must be 1
+diff --git a/Documentation/devicetree/bindings/arm/mediatek/mediatek,sgmiisys.txt b/Documentation/devicetree/bindings/arm/mediatek/mediatek,sgmiisys.txt
+new file mode 100644
+index 000000000000..d113b8e741f3
+--- /dev/null
++++ b/Documentation/devicetree/bindings/arm/mediatek/mediatek,sgmiisys.txt
+@@ -0,0 +1,22 @@
++MediaTek SGMIISYS controller
++============================
++
++The MediaTek SGMIISYS controller provides various clocks to the system.
++
++Required Properties:
++
++- compatible: Should be:
++	- "mediatek,mt7622-sgmiisys", "syscon"
++- #clock-cells: Must be 1
++
++The SGMIISYS controller uses the common clk binding from
++Documentation/devicetree/bindings/clock/clock-bindings.txt
++The available clocks are defined in dt-bindings/clock/mt*-clk.h.
++
++Example:
++
++sgmiisys: sgmiisys@1b128000 {
++	compatible = "mediatek,mt7622-sgmiisys", "syscon";
++	reg = <0 0x1b128000 0 0x1000>;
++	#clock-cells = <1>;
++};
+diff --git a/Documentation/devicetree/bindings/arm/mediatek/mediatek,ssusbsys.txt b/Documentation/devicetree/bindings/arm/mediatek/mediatek,ssusbsys.txt
+new file mode 100644
+index 000000000000..00760019da00
+--- /dev/null
++++ b/Documentation/devicetree/bindings/arm/mediatek/mediatek,ssusbsys.txt
+@@ -0,0 +1,22 @@
++MediaTek SSUSBSYS controller
++============================
++
++The MediaTek SSUSBSYS controller provides various clocks to the system.
++
++Required Properties:
++
++- compatible: Should be:
++	- "mediatek,mt7622-ssusbsys", "syscon"
++- #clock-cells: Must be 1
++
++The SSUSBSYS controller uses the common clk binding from
++Documentation/devicetree/bindings/clock/clock-bindings.txt
++The available clocks are defined in dt-bindings/clock/mt*-clk.h.
++
++Example:
++
++ssusbsys: ssusbsys@1a000000 {
++	compatible = "mediatek,mt7622-ssusbsys", "syscon";
++	reg = <0 0x1a000000 0 0x1000>;
++	#clock-cells = <1>;
++};
+diff --git a/Documentation/devicetree/bindings/arm/mediatek/mediatek,topckgen.txt b/Documentation/devicetree/bindings/arm/mediatek/mediatek,topckgen.txt
+index 2024fc909d69..24014a7e2332 100644
+--- a/Documentation/devicetree/bindings/arm/mediatek/mediatek,topckgen.txt
++++ b/Documentation/devicetree/bindings/arm/mediatek/mediatek,topckgen.txt
+@@ -9,6 +9,7 @@ Required Properties:
+ 	- "mediatek,mt2701-topckgen"
+ 	- "mediatek,mt2712-topckgen", "syscon"
+ 	- "mediatek,mt6797-topckgen"
++	- "mediatek,mt7622-topckgen"
+ 	- "mediatek,mt8135-topckgen"
+ 	- "mediatek,mt8173-topckgen"
+ - #clock-cells: Must be 1
+-- 
+2.11.0
+
diff --git a/target/linux/mediatek/patches-4.14/0149-clk-mediatek-add-clocks-dt-bindings-required-header-.patch b/target/linux/mediatek/patches-4.14/0149-clk-mediatek-add-clocks-dt-bindings-required-header-.patch
new file mode 100644
index 0000000000..fea00f32b0
--- /dev/null
+++ b/target/linux/mediatek/patches-4.14/0149-clk-mediatek-add-clocks-dt-bindings-required-header-.patch
@@ -0,0 +1,316 @@
+From ea009d063f7a3d70831788046c7285a4af4ab82d Mon Sep 17 00:00:00 2001
+From: Chen Zhong <chen.zhong@mediatek.com>
+Date: Thu, 5 Oct 2017 11:50:25 +0800
+Subject: [PATCH 149/224] clk: mediatek: add clocks dt-bindings required header
+ for MT7622 SoC
+
+Add the required header for the entire clocks dt-bindings exported
+from topckgen, apmixedsys, infracfg, pericfg, ethsys, pciesys, ssusbsys
+and audsys which could be found on MT7622 SoC.
+
+Signed-off-by: Chen Zhong <chen.zhong@mediatek.com>
+Signed-off-by: Sean Wang <sean.wang@mediatek.com>
+Signed-off-by: Stephen Boyd <sboyd@codeaurora.org>
+---
+ include/dt-bindings/clock/mt7622-clk.h | 289 +++++++++++++++++++++++++++++++++
+ 1 file changed, 289 insertions(+)
+ create mode 100644 include/dt-bindings/clock/mt7622-clk.h
+
+diff --git a/include/dt-bindings/clock/mt7622-clk.h b/include/dt-bindings/clock/mt7622-clk.h
+new file mode 100644
+index 000000000000..3e514ed51d15
+--- /dev/null
++++ b/include/dt-bindings/clock/mt7622-clk.h
+@@ -0,0 +1,289 @@
++/*
++ * Copyright (c) 2017 MediaTek Inc.
++ * Author: Chen Zhong <chen.zhong@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 _DT_BINDINGS_CLK_MT7622_H
++#define _DT_BINDINGS_CLK_MT7622_H
++
++/* TOPCKGEN */
++
++#define CLK_TOP_TO_U2_PHY		0
++#define CLK_TOP_TO_U2_PHY_1P		1
++#define CLK_TOP_PCIE0_PIPE_EN		2
++#define CLK_TOP_PCIE1_PIPE_EN		3
++#define CLK_TOP_SSUSB_TX250M		4
++#define CLK_TOP_SSUSB_EQ_RX250M		5
++#define CLK_TOP_SSUSB_CDR_REF		6
++#define CLK_TOP_SSUSB_CDR_FB		7
++#define CLK_TOP_SATA_ASIC		8
++#define CLK_TOP_SATA_RBC		9
++#define CLK_TOP_TO_USB3_SYS		10
++#define CLK_TOP_P1_1MHZ			11
++#define CLK_TOP_4MHZ			12
++#define CLK_TOP_P0_1MHZ			13
++#define CLK_TOP_TXCLK_SRC_PRE		14
++#define CLK_TOP_RTC			15
++#define CLK_TOP_MEMPLL			16
++#define CLK_TOP_DMPLL			17
++#define CLK_TOP_SYSPLL_D2		18
++#define CLK_TOP_SYSPLL1_D2		19
++#define CLK_TOP_SYSPLL1_D4		20
++#define CLK_TOP_SYSPLL1_D8		21
++#define CLK_TOP_SYSPLL2_D4		22
++#define CLK_TOP_SYSPLL2_D8		23
++#define CLK_TOP_SYSPLL_D5		24
++#define CLK_TOP_SYSPLL3_D2		25
++#define CLK_TOP_SYSPLL3_D4		26
++#define CLK_TOP_SYSPLL4_D2		27
++#define CLK_TOP_SYSPLL4_D4		28
++#define CLK_TOP_SYSPLL4_D16		29
++#define CLK_TOP_UNIVPLL			30
++#define CLK_TOP_UNIVPLL_D2		31
++#define CLK_TOP_UNIVPLL1_D2		32
++#define CLK_TOP_UNIVPLL1_D4		33
++#define CLK_TOP_UNIVPLL1_D8		34
++#define CLK_TOP_UNIVPLL1_D16		35
++#define CLK_TOP_UNIVPLL2_D2		36
++#define CLK_TOP_UNIVPLL2_D4		37
++#define CLK_TOP_UNIVPLL2_D8		38
++#define CLK_TOP_UNIVPLL2_D16		39
++#define CLK_TOP_UNIVPLL_D5		40
++#define CLK_TOP_UNIVPLL3_D2		41
++#define CLK_TOP_UNIVPLL3_D4		42
++#define CLK_TOP_UNIVPLL3_D16		43
++#define CLK_TOP_UNIVPLL_D7		44
++#define CLK_TOP_UNIVPLL_D80_D4		45
++#define CLK_TOP_UNIV48M			46
++#define CLK_TOP_SGMIIPLL		47
++#define CLK_TOP_SGMIIPLL_D2		48
++#define CLK_TOP_AUD1PLL			49
++#define CLK_TOP_AUD2PLL			50
++#define CLK_TOP_AUD_I2S2_MCK		51
++#define CLK_TOP_TO_USB3_REF		52
++#define CLK_TOP_PCIE1_MAC_EN		53
++#define CLK_TOP_PCIE0_MAC_EN		54
++#define CLK_TOP_ETH_500M		55
++#define CLK_TOP_AXI_SEL			56
++#define CLK_TOP_MEM_SEL			57
++#define CLK_TOP_DDRPHYCFG_SEL		58
++#define CLK_TOP_ETH_SEL			59
++#define CLK_TOP_PWM_SEL			60
++#define CLK_TOP_F10M_REF_SEL		61
++#define CLK_TOP_NFI_INFRA_SEL		62
++#define CLK_TOP_FLASH_SEL		63
++#define CLK_TOP_UART_SEL		64
++#define CLK_TOP_SPI0_SEL		65
++#define CLK_TOP_SPI1_SEL		66
++#define CLK_TOP_MSDC50_0_SEL		67
++#define CLK_TOP_MSDC30_0_SEL		68
++#define CLK_TOP_MSDC30_1_SEL		69
++#define CLK_TOP_A1SYS_HP_SEL		70
++#define CLK_TOP_A2SYS_HP_SEL		71
++#define CLK_TOP_INTDIR_SEL		72
++#define CLK_TOP_AUD_INTBUS_SEL		73
++#define CLK_TOP_PMICSPI_SEL		74
++#define CLK_TOP_SCP_SEL			75
++#define CLK_TOP_ATB_SEL			76
++#define CLK_TOP_HIF_SEL			77
++#define CLK_TOP_AUDIO_SEL		78
++#define CLK_TOP_U2_SEL			79
++#define CLK_TOP_AUD1_SEL		80
++#define CLK_TOP_AUD2_SEL		81
++#define CLK_TOP_IRRX_SEL		82
++#define CLK_TOP_IRTX_SEL		83
++#define CLK_TOP_ASM_L_SEL		84
++#define CLK_TOP_ASM_M_SEL		85
++#define CLK_TOP_ASM_H_SEL		86
++#define CLK_TOP_APLL1_SEL		87
++#define CLK_TOP_APLL2_SEL		88
++#define CLK_TOP_I2S0_MCK_SEL		89
++#define CLK_TOP_I2S1_MCK_SEL		90
++#define CLK_TOP_I2S2_MCK_SEL		91
++#define CLK_TOP_I2S3_MCK_SEL		92
++#define CLK_TOP_APLL1_DIV		93
++#define CLK_TOP_APLL2_DIV		94
++#define CLK_TOP_I2S0_MCK_DIV		95
++#define CLK_TOP_I2S1_MCK_DIV		96
++#define CLK_TOP_I2S2_MCK_DIV		97
++#define CLK_TOP_I2S3_MCK_DIV		98
++#define CLK_TOP_A1SYS_HP_DIV		99
++#define CLK_TOP_A2SYS_HP_DIV		100
++#define CLK_TOP_APLL1_DIV_PD		101
++#define CLK_TOP_APLL2_DIV_PD		102
++#define CLK_TOP_I2S0_MCK_DIV_PD		103
++#define CLK_TOP_I2S1_MCK_DIV_PD		104
++#define CLK_TOP_I2S2_MCK_DIV_PD		105
++#define CLK_TOP_I2S3_MCK_DIV_PD		106
++#define CLK_TOP_A1SYS_HP_DIV_PD		107
++#define CLK_TOP_A2SYS_HP_DIV_PD		108
++#define CLK_TOP_NR_CLK			109
++
++/* INFRACFG */
++
++#define CLK_INFRA_MUX1_SEL		0
++#define CLK_INFRA_DBGCLK_PD		1
++#define CLK_INFRA_AUDIO_PD		2
++#define CLK_INFRA_IRRX_PD		3
++#define CLK_INFRA_APXGPT_PD		4
++#define CLK_INFRA_PMIC_PD		5
++#define CLK_INFRA_TRNG			6
++#define CLK_INFRA_NR_CLK		7
++
++/* PERICFG */
++
++#define CLK_PERIBUS_SEL			0
++#define CLK_PERI_THERM_PD		1
++#define CLK_PERI_PWM1_PD		2
++#define CLK_PERI_PWM2_PD		3
++#define CLK_PERI_PWM3_PD		4
++#define CLK_PERI_PWM4_PD		5
++#define CLK_PERI_PWM5_PD		6
++#define CLK_PERI_PWM6_PD		7
++#define CLK_PERI_PWM7_PD		8
++#define CLK_PERI_PWM_PD			9
++#define CLK_PERI_AP_DMA_PD		10
++#define CLK_PERI_MSDC30_0_PD		11
++#define CLK_PERI_MSDC30_1_PD		12
++#define CLK_PERI_UART0_PD		13
++#define CLK_PERI_UART1_PD		14
++#define CLK_PERI_UART2_PD		15
++#define CLK_PERI_UART3_PD		16
++#define CLK_PERI_UART4_PD		17
++#define CLK_PERI_BTIF_PD		18
++#define CLK_PERI_I2C0_PD		19
++#define CLK_PERI_I2C1_PD		20
++#define CLK_PERI_I2C2_PD		21
++#define CLK_PERI_SPI1_PD		22
++#define CLK_PERI_AUXADC_PD		23
++#define CLK_PERI_SPI0_PD		24
++#define CLK_PERI_SNFI_PD		25
++#define CLK_PERI_NFI_PD			26
++#define CLK_PERI_NFIECC_PD		27
++#define CLK_PERI_FLASH_PD		28
++#define CLK_PERI_IRTX_PD		29
++#define CLK_PERI_NR_CLK			30
++
++/* APMIXEDSYS */
++
++#define CLK_APMIXED_ARMPLL		0
++#define CLK_APMIXED_MAINPLL		1
++#define CLK_APMIXED_UNIV2PLL		2
++#define CLK_APMIXED_ETH1PLL		3
++#define CLK_APMIXED_ETH2PLL		4
++#define CLK_APMIXED_AUD1PLL		5
++#define CLK_APMIXED_AUD2PLL		6
++#define CLK_APMIXED_TRGPLL		7
++#define CLK_APMIXED_SGMIPLL		8
++#define CLK_APMIXED_MAIN_CORE_EN	9
++#define CLK_APMIXED_NR_CLK		10
++
++/* AUDIOSYS */
++
++#define CLK_AUDIO_AFE			0
++#define CLK_AUDIO_HDMI			1
++#define CLK_AUDIO_SPDF			2
++#define CLK_AUDIO_APLL			3
++#define CLK_AUDIO_I2SIN1		4
++#define CLK_AUDIO_I2SIN2		5
++#define CLK_AUDIO_I2SIN3		6
++#define CLK_AUDIO_I2SIN4		7
++#define CLK_AUDIO_I2SO1			8
++#define CLK_AUDIO_I2SO2			9
++#define CLK_AUDIO_I2SO3			10
++#define CLK_AUDIO_I2SO4			11
++#define CLK_AUDIO_ASRCI1		12
++#define CLK_AUDIO_ASRCI2		13
++#define CLK_AUDIO_ASRCO1		14
++#define CLK_AUDIO_ASRCO2		15
++#define CLK_AUDIO_INTDIR		16
++#define CLK_AUDIO_A1SYS			17
++#define CLK_AUDIO_A2SYS			18
++#define CLK_AUDIO_UL1			19
++#define CLK_AUDIO_UL2			20
++#define CLK_AUDIO_UL3			21
++#define CLK_AUDIO_UL4			22
++#define CLK_AUDIO_UL5			23
++#define CLK_AUDIO_UL6			24
++#define CLK_AUDIO_DL1			25
++#define CLK_AUDIO_DL2			26
++#define CLK_AUDIO_DL3			27
++#define CLK_AUDIO_DL4			28
++#define CLK_AUDIO_DL5			29
++#define CLK_AUDIO_DL6			30
++#define CLK_AUDIO_DLMCH			31
++#define CLK_AUDIO_ARB1			32
++#define CLK_AUDIO_AWB			33
++#define CLK_AUDIO_AWB2			34
++#define CLK_AUDIO_DAI			35
++#define CLK_AUDIO_MOD			36
++#define CLK_AUDIO_ASRCI3		37
++#define CLK_AUDIO_ASRCI4		38
++#define CLK_AUDIO_ASRCO3		39
++#define CLK_AUDIO_ASRCO4		40
++#define CLK_AUDIO_MEM_ASRC1		41
++#define CLK_AUDIO_MEM_ASRC2		42
++#define CLK_AUDIO_MEM_ASRC3		43
++#define CLK_AUDIO_MEM_ASRC4		44
++#define CLK_AUDIO_MEM_ASRC5		45
++#define CLK_AUDIO_NR_CLK		46
++
++/* SSUSBSYS */
++
++#define CLK_SSUSB_U2_PHY_1P_EN		0
++#define CLK_SSUSB_U2_PHY_EN		1
++#define CLK_SSUSB_REF_EN		2
++#define CLK_SSUSB_SYS_EN		3
++#define CLK_SSUSB_MCU_EN		4
++#define CLK_SSUSB_DMA_EN		5
++#define CLK_SSUSB_NR_CLK		6
++
++/* PCIESYS */
++
++#define CLK_PCIE_P1_AUX_EN		0
++#define CLK_PCIE_P1_OBFF_EN		1
++#define CLK_PCIE_P1_AHB_EN		2
++#define CLK_PCIE_P1_AXI_EN		3
++#define CLK_PCIE_P1_MAC_EN		4
++#define CLK_PCIE_P1_PIPE_EN		5
++#define CLK_PCIE_P0_AUX_EN		6
++#define CLK_PCIE_P0_OBFF_EN		7
++#define CLK_PCIE_P0_AHB_EN		8
++#define CLK_PCIE_P0_AXI_EN		9
++#define CLK_PCIE_P0_MAC_EN		10
++#define CLK_PCIE_P0_PIPE_EN		11
++#define CLK_SATA_AHB_EN			12
++#define CLK_SATA_AXI_EN			13
++#define CLK_SATA_ASIC_EN		14
++#define CLK_SATA_RBC_EN			15
++#define CLK_SATA_PM_EN			16
++#define CLK_PCIE_NR_CLK			17
++
++/* ETHSYS */
++
++#define CLK_ETH_HSDMA_EN		0
++#define CLK_ETH_ESW_EN			1
++#define CLK_ETH_GP2_EN			2
++#define CLK_ETH_GP1_EN			3
++#define CLK_ETH_GP0_EN			4
++#define CLK_ETH_NR_CLK			5
++
++/* SGMIISYS */
++
++#define CLK_SGMII_TX250M_EN		0
++#define CLK_SGMII_RX250M_EN		1
++#define CLK_SGMII_CDR_REF		2
++#define CLK_SGMII_CDR_FB		3
++#define CLK_SGMII_NR_CLK		4
++
++#endif /* _DT_BINDINGS_CLK_MT7622_H */
++
+-- 
+2.11.0
+
diff --git a/target/linux/mediatek/patches-4.14/0150-clk-mediatek-add-clock-support-for-MT7622-SoC.patch b/target/linux/mediatek/patches-4.14/0150-clk-mediatek-add-clock-support-for-MT7622-SoC.patch
new file mode 100644
index 0000000000..ea015e8d6a
--- /dev/null
+++ b/target/linux/mediatek/patches-4.14/0150-clk-mediatek-add-clock-support-for-MT7622-SoC.patch
@@ -0,0 +1,1407 @@
+From b24e830d69f1fa637284c093410645a059b60028 Mon Sep 17 00:00:00 2001
+From: Sean Wang <sean.wang@mediatek.com>
+Date: Thu, 5 Oct 2017 11:50:24 +0800
+Subject: [PATCH 150/224] clk: mediatek: add clock support for MT7622 SoC
+
+Add all supported clocks exported from every susbystem found on MT7622 SoC
+such as topckgen, apmixedsys, infracfg, pericfg , pciessys, ssusbsys,
+ethsys and audsys.
+
+Signed-off-by: Chen Zhong <chen.zhong@mediatek.com>
+Signed-off-by: Sean Wang <sean.wang@mediatek.com>
+Signed-off-by: Stephen Boyd <sboyd@codeaurora.org>
+---
+ drivers/clk/mediatek/Kconfig          |  30 ++
+ drivers/clk/mediatek/Makefile         |   4 +
+ drivers/clk/mediatek/clk-mt7622-aud.c | 195 +++++++++
+ drivers/clk/mediatek/clk-mt7622-eth.c | 156 +++++++
+ drivers/clk/mediatek/clk-mt7622-hif.c | 169 ++++++++
+ drivers/clk/mediatek/clk-mt7622.c     | 780 ++++++++++++++++++++++++++++++++++
+ 6 files changed, 1334 insertions(+)
+ create mode 100644 drivers/clk/mediatek/clk-mt7622-aud.c
+ create mode 100644 drivers/clk/mediatek/clk-mt7622-eth.c
+ create mode 100644 drivers/clk/mediatek/clk-mt7622-hif.c
+ create mode 100644 drivers/clk/mediatek/clk-mt7622.c
+
+diff --git a/drivers/clk/mediatek/Kconfig b/drivers/clk/mediatek/Kconfig
+index 300dbb551bf7..59dc0aad553c 100644
+--- a/drivers/clk/mediatek/Kconfig
++++ b/drivers/clk/mediatek/Kconfig
+@@ -132,6 +132,36 @@ config COMMON_CLK_MT6797_VENCSYS
+        ---help---
+          This driver supports Mediatek MT6797 vencsys clocks.
+ 
++config COMMON_CLK_MT7622
++	bool "Clock driver for MediaTek MT7622"
++	depends on ARCH_MEDIATEK || COMPILE_TEST
++	select COMMON_CLK_MEDIATEK
++	default ARCH_MEDIATEK
++	---help---
++	  This driver supports MediaTek MT7622 basic clocks and clocks
++	  required for various periperals found on MediaTek.
++
++config COMMON_CLK_MT7622_ETHSYS
++	bool "Clock driver for MediaTek MT7622 ETHSYS"
++	depends on COMMON_CLK_MT7622
++	---help---
++	  This driver add support for clocks for Ethernet and SGMII
++	  required on MediaTek MT7622 SoC.
++
++config COMMON_CLK_MT7622_HIFSYS
++	bool "Clock driver for MediaTek MT7622 HIFSYS"
++	depends on COMMON_CLK_MT7622
++	---help---
++	  This driver supports MediaTek MT7622 HIFSYS clocks providing
++	  to PCI-E and USB.
++
++config COMMON_CLK_MT7622_AUDSYS
++	bool "Clock driver for MediaTek MT7622 AUDSYS"
++	depends on COMMON_CLK_MT7622
++	---help---
++	  This driver supports MediaTek MT7622 AUDSYS clocks providing
++	  to audio consumers such as I2S and TDM.
++
+ config COMMON_CLK_MT8135
+ 	bool "Clock driver for Mediatek MT8135"
+ 	depends on (ARCH_MEDIATEK && ARM) || COMPILE_TEST
+diff --git a/drivers/clk/mediatek/Makefile b/drivers/clk/mediatek/Makefile
+index a4e5c47c73a4..de8c3d0bb4ca 100644
+--- a/drivers/clk/mediatek/Makefile
++++ b/drivers/clk/mediatek/Makefile
+@@ -20,5 +20,9 @@ obj-$(CONFIG_COMMON_CLK_MT2712_MFGCFG) += clk-mt2712-mfg.o
+ obj-$(CONFIG_COMMON_CLK_MT2712_MMSYS) += clk-mt2712-mm.o
+ obj-$(CONFIG_COMMON_CLK_MT2712_VDECSYS) += clk-mt2712-vdec.o
+ obj-$(CONFIG_COMMON_CLK_MT2712_VENCSYS) += clk-mt2712-venc.o
++obj-$(CONFIG_COMMON_CLK_MT7622) += clk-mt7622.o
++obj-$(CONFIG_COMMON_CLK_MT7622_ETHSYS) += clk-mt7622-eth.o
++obj-$(CONFIG_COMMON_CLK_MT7622_HIFSYS) += clk-mt7622-hif.o
++obj-$(CONFIG_COMMON_CLK_MT7622_AUDSYS) += clk-mt7622-aud.o
+ obj-$(CONFIG_COMMON_CLK_MT8135) += clk-mt8135.o
+ obj-$(CONFIG_COMMON_CLK_MT8173) += clk-mt8173.o
+diff --git a/drivers/clk/mediatek/clk-mt7622-aud.c b/drivers/clk/mediatek/clk-mt7622-aud.c
+new file mode 100644
+index 000000000000..fad7d9fc53ba
+--- /dev/null
++++ b/drivers/clk/mediatek/clk-mt7622-aud.c
+@@ -0,0 +1,195 @@
++/*
++ * Copyright (c) 2017 MediaTek Inc.
++ * Author: Chen Zhong <chen.zhong@mediatek.com>
++ *	   Sean Wang <sean.wang@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.
++ */
++
++#include <linux/clk-provider.h>
++#include <linux/of.h>
++#include <linux/of_address.h>
++#include <linux/of_device.h>
++#include <linux/platform_device.h>
++
++#include "clk-mtk.h"
++#include "clk-gate.h"
++
++#include <dt-bindings/clock/mt7622-clk.h>
++
++#define GATE_AUDIO0(_id, _name, _parent, _shift) {	\
++		.id = _id,				\
++		.name = _name,				\
++		.parent_name = _parent,			\
++		.regs = &audio0_cg_regs,			\
++		.shift = _shift,			\
++		.ops = &mtk_clk_gate_ops_no_setclr,	\
++	}
++
++#define GATE_AUDIO1(_id, _name, _parent, _shift) {	\
++		.id = _id,				\
++		.name = _name,				\
++		.parent_name = _parent,			\
++		.regs = &audio1_cg_regs,			\
++		.shift = _shift,			\
++		.ops = &mtk_clk_gate_ops_no_setclr,	\
++	}
++
++#define GATE_AUDIO2(_id, _name, _parent, _shift) {	\
++		.id = _id,				\
++		.name = _name,				\
++		.parent_name = _parent,			\
++		.regs = &audio2_cg_regs,			\
++		.shift = _shift,			\
++		.ops = &mtk_clk_gate_ops_no_setclr,	\
++	}
++
++#define GATE_AUDIO3(_id, _name, _parent, _shift) {	\
++		.id = _id,				\
++		.name = _name,				\
++		.parent_name = _parent,			\
++		.regs = &audio3_cg_regs,			\
++		.shift = _shift,			\
++		.ops = &mtk_clk_gate_ops_no_setclr,	\
++	}
++
++static const struct mtk_gate_regs audio0_cg_regs = {
++	.set_ofs = 0x0,
++	.clr_ofs = 0x0,
++	.sta_ofs = 0x0,
++};
++
++static const struct mtk_gate_regs audio1_cg_regs = {
++	.set_ofs = 0x10,
++	.clr_ofs = 0x10,
++	.sta_ofs = 0x10,
++};
++
++static const struct mtk_gate_regs audio2_cg_regs = {
++	.set_ofs = 0x14,
++	.clr_ofs = 0x14,
++	.sta_ofs = 0x14,
++};
++
++static const struct mtk_gate_regs audio3_cg_regs = {
++	.set_ofs = 0x634,
++	.clr_ofs = 0x634,
++	.sta_ofs = 0x634,
++};
++
++static const struct mtk_gate audio_clks[] = {
++	/* AUDIO0 */
++	GATE_AUDIO0(CLK_AUDIO_AFE, "audio_afe", "rtc", 2),
++	GATE_AUDIO0(CLK_AUDIO_HDMI, "audio_hdmi", "apll1_ck_sel", 20),
++	GATE_AUDIO0(CLK_AUDIO_SPDF, "audio_spdf", "apll1_ck_sel", 21),
++	GATE_AUDIO0(CLK_AUDIO_APLL, "audio_apll", "apll1_ck_sel", 23),
++	/* AUDIO1 */
++	GATE_AUDIO1(CLK_AUDIO_I2SIN1, "audio_i2sin1", "a1sys_hp_sel", 0),
++	GATE_AUDIO1(CLK_AUDIO_I2SIN2, "audio_i2sin2", "a1sys_hp_sel", 1),
++	GATE_AUDIO1(CLK_AUDIO_I2SIN3, "audio_i2sin3", "a1sys_hp_sel", 2),
++	GATE_AUDIO1(CLK_AUDIO_I2SIN4, "audio_i2sin4", "a1sys_hp_sel", 3),
++	GATE_AUDIO1(CLK_AUDIO_I2SO1, "audio_i2so1", "a1sys_hp_sel", 6),
++	GATE_AUDIO1(CLK_AUDIO_I2SO2, "audio_i2so2", "a1sys_hp_sel", 7),
++	GATE_AUDIO1(CLK_AUDIO_I2SO3, "audio_i2so3", "a1sys_hp_sel", 8),
++	GATE_AUDIO1(CLK_AUDIO_I2SO4, "audio_i2so4", "a1sys_hp_sel", 9),
++	GATE_AUDIO1(CLK_AUDIO_ASRCI1, "audio_asrci1", "asm_h_sel", 12),
++	GATE_AUDIO1(CLK_AUDIO_ASRCI2, "audio_asrci2", "asm_h_sel", 13),
++	GATE_AUDIO1(CLK_AUDIO_ASRCO1, "audio_asrco1", "asm_h_sel", 14),
++	GATE_AUDIO1(CLK_AUDIO_ASRCO2, "audio_asrco2", "asm_h_sel", 15),
++	GATE_AUDIO1(CLK_AUDIO_INTDIR, "audio_intdir", "intdir_sel", 20),
++	GATE_AUDIO1(CLK_AUDIO_A1SYS, "audio_a1sys", "a1sys_hp_sel", 21),
++	GATE_AUDIO1(CLK_AUDIO_A2SYS, "audio_a2sys", "a2sys_hp_sel", 22),
++	/* AUDIO2 */
++	GATE_AUDIO2(CLK_AUDIO_UL1, "audio_ul1", "a1sys_hp_sel", 0),
++	GATE_AUDIO2(CLK_AUDIO_UL2, "audio_ul2", "a1sys_hp_sel", 1),
++	GATE_AUDIO2(CLK_AUDIO_UL3, "audio_ul3", "a1sys_hp_sel", 2),
++	GATE_AUDIO2(CLK_AUDIO_UL4, "audio_ul4", "a1sys_hp_sel", 3),
++	GATE_AUDIO2(CLK_AUDIO_UL5, "audio_ul5", "a1sys_hp_sel", 4),
++	GATE_AUDIO2(CLK_AUDIO_UL6, "audio_ul6", "a1sys_hp_sel", 5),
++	GATE_AUDIO2(CLK_AUDIO_DL1, "audio_dl1", "a1sys_hp_sel", 6),
++	GATE_AUDIO2(CLK_AUDIO_DL2, "audio_dl2", "a1sys_hp_sel", 7),
++	GATE_AUDIO2(CLK_AUDIO_DL3, "audio_dl3", "a1sys_hp_sel", 8),
++	GATE_AUDIO2(CLK_AUDIO_DL4, "audio_dl4", "a1sys_hp_sel", 9),
++	GATE_AUDIO2(CLK_AUDIO_DL5, "audio_dl5", "a1sys_hp_sel", 10),
++	GATE_AUDIO2(CLK_AUDIO_DL6, "audio_dl6", "a1sys_hp_sel", 11),
++	GATE_AUDIO2(CLK_AUDIO_DLMCH, "audio_dlmch", "a1sys_hp_sel", 12),
++	GATE_AUDIO2(CLK_AUDIO_ARB1, "audio_arb1", "a1sys_hp_sel", 13),
++	GATE_AUDIO2(CLK_AUDIO_AWB, "audio_awb", "a1sys_hp_sel", 14),
++	GATE_AUDIO2(CLK_AUDIO_AWB2, "audio_awb2", "a1sys_hp_sel", 15),
++	GATE_AUDIO2(CLK_AUDIO_DAI, "audio_dai", "a1sys_hp_sel", 16),
++	GATE_AUDIO2(CLK_AUDIO_MOD, "audio_mod", "a1sys_hp_sel", 17),
++	/* AUDIO3 */
++	GATE_AUDIO3(CLK_AUDIO_ASRCI3, "audio_asrci3", "asm_h_sel", 2),
++	GATE_AUDIO3(CLK_AUDIO_ASRCI4, "audio_asrci4", "asm_h_sel", 3),
++	GATE_AUDIO3(CLK_AUDIO_ASRCO3, "audio_asrco3", "asm_h_sel", 6),
++	GATE_AUDIO3(CLK_AUDIO_ASRCO4, "audio_asrco4", "asm_h_sel", 7),
++	GATE_AUDIO3(CLK_AUDIO_MEM_ASRC1, "audio_mem_asrc1", "asm_h_sel", 10),
++	GATE_AUDIO3(CLK_AUDIO_MEM_ASRC2, "audio_mem_asrc2", "asm_h_sel", 11),
++	GATE_AUDIO3(CLK_AUDIO_MEM_ASRC3, "audio_mem_asrc3", "asm_h_sel", 12),
++	GATE_AUDIO3(CLK_AUDIO_MEM_ASRC4, "audio_mem_asrc4", "asm_h_sel", 13),
++	GATE_AUDIO3(CLK_AUDIO_MEM_ASRC5, "audio_mem_asrc5", "asm_h_sel", 14),
++};
++
++static int clk_mt7622_audiosys_init(struct platform_device *pdev)
++{
++	struct clk_onecell_data *clk_data;
++	struct device_node *node = pdev->dev.of_node;
++	int r;
++
++	clk_data = mtk_alloc_clk_data(CLK_AUDIO_NR_CLK);
++
++	mtk_clk_register_gates(node, audio_clks, ARRAY_SIZE(audio_clks),
++			       clk_data);
++
++	r = of_clk_add_provider(node, of_clk_src_onecell_get, clk_data);
++	if (r)
++		dev_err(&pdev->dev,
++			"could not register clock provider: %s: %d\n",
++			pdev->name, r);
++
++	return r;
++}
++
++static const struct of_device_id of_match_clk_mt7622_aud[] = {
++	{
++		.compatible = "mediatek,mt7622-audsys",
++		.data = clk_mt7622_audiosys_init,
++	}, {
++		/* sentinel */
++	}
++};
++
++static int clk_mt7622_aud_probe(struct platform_device *pdev)
++{
++	int (*clk_init)(struct platform_device *);
++	int r;
++
++	clk_init = of_device_get_match_data(&pdev->dev);
++	if (!clk_init)
++		return -EINVAL;
++
++	r = clk_init(pdev);
++	if (r)
++		dev_err(&pdev->dev,
++			"could not register clock provider: %s: %d\n",
++			pdev->name, r);
++
++	return r;
++}
++
++static struct platform_driver clk_mt7622_aud_drv = {
++	.probe = clk_mt7622_aud_probe,
++	.driver = {
++		.name = "clk-mt7622-aud",
++		.of_match_table = of_match_clk_mt7622_aud,
++	},
++};
++
++builtin_platform_driver(clk_mt7622_aud_drv);
+diff --git a/drivers/clk/mediatek/clk-mt7622-eth.c b/drivers/clk/mediatek/clk-mt7622-eth.c
+new file mode 100644
+index 000000000000..6328127bbb3c
+--- /dev/null
++++ b/drivers/clk/mediatek/clk-mt7622-eth.c
+@@ -0,0 +1,156 @@
++/*
++ * Copyright (c) 2017 MediaTek Inc.
++ * Author: Chen Zhong <chen.zhong@mediatek.com>
++ *	   Sean Wang <sean.wang@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.
++ */
++
++#include <linux/clk-provider.h>
++#include <linux/of.h>
++#include <linux/of_address.h>
++#include <linux/of_device.h>
++#include <linux/platform_device.h>
++
++#include "clk-mtk.h"
++#include "clk-gate.h"
++
++#include <dt-bindings/clock/mt7622-clk.h>
++
++#define GATE_ETH(_id, _name, _parent, _shift) {	\
++		.id = _id,				\
++		.name = _name,				\
++		.parent_name = _parent,			\
++		.regs = &eth_cg_regs,			\
++		.shift = _shift,			\
++		.ops = &mtk_clk_gate_ops_no_setclr_inv,	\
++	}
++
++static const struct mtk_gate_regs eth_cg_regs = {
++	.set_ofs = 0x30,
++	.clr_ofs = 0x30,
++	.sta_ofs = 0x30,
++};
++
++static const struct mtk_gate eth_clks[] = {
++	GATE_ETH(CLK_ETH_HSDMA_EN, "eth_hsdma_en", "eth_sel", 5),
++	GATE_ETH(CLK_ETH_ESW_EN, "eth_esw_en", "eth_500m", 6),
++	GATE_ETH(CLK_ETH_GP2_EN, "eth_gp2_en", "txclk_src_pre", 7),
++	GATE_ETH(CLK_ETH_GP1_EN, "eth_gp1_en", "txclk_src_pre", 8),
++	GATE_ETH(CLK_ETH_GP0_EN, "eth_gp0_en", "txclk_src_pre", 9),
++};
++
++static const struct mtk_gate_regs sgmii_cg_regs = {
++	.set_ofs = 0xE4,
++	.clr_ofs = 0xE4,
++	.sta_ofs = 0xE4,
++};
++
++#define GATE_SGMII(_id, _name, _parent, _shift) {	\
++		.id = _id,				\
++		.name = _name,				\
++		.parent_name = _parent,			\
++		.regs = &sgmii_cg_regs,			\
++		.shift = _shift,			\
++		.ops = &mtk_clk_gate_ops_no_setclr_inv,	\
++	}
++
++static const struct mtk_gate sgmii_clks[] = {
++	GATE_SGMII(CLK_SGMII_TX250M_EN, "sgmii_tx250m_en",
++		   "ssusb_tx250m", 2),
++	GATE_SGMII(CLK_SGMII_RX250M_EN, "sgmii_rx250m_en",
++		   "ssusb_eq_rx250m", 3),
++	GATE_SGMII(CLK_SGMII_CDR_REF, "sgmii_cdr_ref",
++		   "ssusb_cdr_ref", 4),
++	GATE_SGMII(CLK_SGMII_CDR_FB, "sgmii_cdr_fb",
++		   "ssusb_cdr_fb", 5),
++};
++
++static int clk_mt7622_ethsys_init(struct platform_device *pdev)
++{
++	struct clk_onecell_data *clk_data;
++	struct device_node *node = pdev->dev.of_node;
++	int r;
++
++	clk_data = mtk_alloc_clk_data(CLK_ETH_NR_CLK);
++
++	mtk_clk_register_gates(node, eth_clks, ARRAY_SIZE(eth_clks),
++			       clk_data);
++
++	r = of_clk_add_provider(node, of_clk_src_onecell_get, clk_data);
++	if (r)
++		dev_err(&pdev->dev,
++			"could not register clock provider: %s: %d\n",
++			pdev->name, r);
++
++	mtk_register_reset_controller(node, 1, 0x34);
++
++	return r;
++}
++
++static int clk_mt7622_sgmiisys_init(struct platform_device *pdev)
++{
++	struct clk_onecell_data *clk_data;
++	struct device_node *node = pdev->dev.of_node;
++	int r;
++
++	clk_data = mtk_alloc_clk_data(CLK_SGMII_NR_CLK);
++
++	mtk_clk_register_gates(node, sgmii_clks, ARRAY_SIZE(sgmii_clks),
++			       clk_data);
++
++	r = of_clk_add_provider(node, of_clk_src_onecell_get, clk_data);
++	if (r)
++		dev_err(&pdev->dev,
++			"could not register clock provider: %s: %d\n",
++			pdev->name, r);
++
++	return r;
++}
++
++static const struct of_device_id of_match_clk_mt7622_eth[] = {
++	{
++		.compatible = "mediatek,mt7622-ethsys",
++		.data = clk_mt7622_ethsys_init,
++	}, {
++		.compatible = "mediatek,mt7622-sgmiisys",
++		.data = clk_mt7622_sgmiisys_init,
++	}, {
++		/* sentinel */
++	}
++};
++
++static int clk_mt7622_eth_probe(struct platform_device *pdev)
++{
++	int (*clk_init)(struct platform_device *);
++	int r;
++
++	clk_init = of_device_get_match_data(&pdev->dev);
++	if (!clk_init)
++		return -EINVAL;
++
++	r = clk_init(pdev);
++	if (r)
++		dev_err(&pdev->dev,
++			"could not register clock provider: %s: %d\n",
++			pdev->name, r);
++
++	return r;
++}
++
++static struct platform_driver clk_mt7622_eth_drv = {
++	.probe = clk_mt7622_eth_probe,
++	.driver = {
++		.name = "clk-mt7622-eth",
++		.of_match_table = of_match_clk_mt7622_eth,
++	},
++};
++
++builtin_platform_driver(clk_mt7622_eth_drv);
+diff --git a/drivers/clk/mediatek/clk-mt7622-hif.c b/drivers/clk/mediatek/clk-mt7622-hif.c
+new file mode 100644
+index 000000000000..a6e8534276c6
+--- /dev/null
++++ b/drivers/clk/mediatek/clk-mt7622-hif.c
+@@ -0,0 +1,169 @@
++/*
++ * Copyright (c) 2017 MediaTek Inc.
++ * Author: Chen Zhong <chen.zhong@mediatek.com>
++ *	   Sean Wang <sean.wang@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.
++ */
++
++#include <linux/clk-provider.h>
++#include <linux/of.h>
++#include <linux/of_address.h>
++#include <linux/of_device.h>
++#include <linux/platform_device.h>
++
++#include "clk-mtk.h"
++#include "clk-gate.h"
++
++#include <dt-bindings/clock/mt7622-clk.h>
++
++#define GATE_PCIE(_id, _name, _parent, _shift) {	\
++		.id = _id,				\
++		.name = _name,				\
++		.parent_name = _parent,			\
++		.regs = &pcie_cg_regs,			\
++		.shift = _shift,			\
++		.ops = &mtk_clk_gate_ops_no_setclr_inv,	\
++	}
++
++#define GATE_SSUSB(_id, _name, _parent, _shift) {	\
++		.id = _id,				\
++		.name = _name,				\
++		.parent_name = _parent,			\
++		.regs = &ssusb_cg_regs,			\
++		.shift = _shift,			\
++		.ops = &mtk_clk_gate_ops_no_setclr_inv,	\
++	}
++
++static const struct mtk_gate_regs pcie_cg_regs = {
++	.set_ofs = 0x30,
++	.clr_ofs = 0x30,
++	.sta_ofs = 0x30,
++};
++
++static const struct mtk_gate_regs ssusb_cg_regs = {
++	.set_ofs = 0x30,
++	.clr_ofs = 0x30,
++	.sta_ofs = 0x30,
++};
++
++static const struct mtk_gate ssusb_clks[] = {
++	GATE_SSUSB(CLK_SSUSB_U2_PHY_1P_EN, "ssusb_u2_phy_1p",
++		   "to_u2_phy_1p", 0),
++	GATE_SSUSB(CLK_SSUSB_U2_PHY_EN, "ssusb_u2_phy_en", "to_u2_phy", 1),
++	GATE_SSUSB(CLK_SSUSB_REF_EN, "ssusb_ref_en", "to_usb3_ref", 5),
++	GATE_SSUSB(CLK_SSUSB_SYS_EN, "ssusb_sys_en", "to_usb3_sys", 6),
++	GATE_SSUSB(CLK_SSUSB_MCU_EN, "ssusb_mcu_en", "axi_sel", 7),
++	GATE_SSUSB(CLK_SSUSB_DMA_EN, "ssusb_dma_en", "hif_sel", 8),
++};
++
++static const struct mtk_gate pcie_clks[] = {
++	GATE_PCIE(CLK_PCIE_P1_AUX_EN, "pcie_p1_aux_en", "p1_1mhz", 12),
++	GATE_PCIE(CLK_PCIE_P1_OBFF_EN, "pcie_p1_obff_en", "free_run_4mhz", 13),
++	GATE_PCIE(CLK_PCIE_P1_AHB_EN, "pcie_p1_ahb_en", "axi_sel", 14),
++	GATE_PCIE(CLK_PCIE_P1_AXI_EN, "pcie_p1_axi_en", "hif_sel", 15),
++	GATE_PCIE(CLK_PCIE_P1_MAC_EN, "pcie_p1_mac_en", "pcie1_mac_en", 16),
++	GATE_PCIE(CLK_PCIE_P1_PIPE_EN, "pcie_p1_pipe_en", "pcie1_pipe_en", 17),
++	GATE_PCIE(CLK_PCIE_P0_AUX_EN, "pcie_p0_aux_en", "p0_1mhz", 18),
++	GATE_PCIE(CLK_PCIE_P0_OBFF_EN, "pcie_p0_obff_en", "free_run_4mhz", 19),
++	GATE_PCIE(CLK_PCIE_P0_AHB_EN, "pcie_p0_ahb_en", "axi_sel", 20),
++	GATE_PCIE(CLK_PCIE_P0_AXI_EN, "pcie_p0_axi_en", "hif_sel", 21),
++	GATE_PCIE(CLK_PCIE_P0_MAC_EN, "pcie_p0_mac_en", "pcie0_mac_en", 22),
++	GATE_PCIE(CLK_PCIE_P0_PIPE_EN, "pcie_p0_pipe_en", "pcie0_pipe_en", 23),
++	GATE_PCIE(CLK_SATA_AHB_EN, "sata_ahb_en", "axi_sel", 26),
++	GATE_PCIE(CLK_SATA_AXI_EN, "sata_axi_en", "hif_sel", 27),
++	GATE_PCIE(CLK_SATA_ASIC_EN, "sata_asic_en", "sata_asic", 28),
++	GATE_PCIE(CLK_SATA_RBC_EN, "sata_rbc_en", "sata_rbc", 29),
++	GATE_PCIE(CLK_SATA_PM_EN, "sata_pm_en", "univpll2_d4", 30),
++};
++
++static int clk_mt7622_ssusbsys_init(struct platform_device *pdev)
++{
++	struct clk_onecell_data *clk_data;
++	struct device_node *node = pdev->dev.of_node;
++	int r;
++
++	clk_data = mtk_alloc_clk_data(CLK_SSUSB_NR_CLK);
++
++	mtk_clk_register_gates(node, ssusb_clks, ARRAY_SIZE(ssusb_clks),
++			       clk_data);
++
++	r = of_clk_add_provider(node, of_clk_src_onecell_get, clk_data);
++	if (r)
++		dev_err(&pdev->dev,
++			"could not register clock provider: %s: %d\n",
++			pdev->name, r);
++
++	mtk_register_reset_controller(node, 1, 0x34);
++
++	return r;
++}
++
++static int clk_mt7622_pciesys_init(struct platform_device *pdev)
++{
++	struct clk_onecell_data *clk_data;
++	struct device_node *node = pdev->dev.of_node;
++	int r;
++
++	clk_data = mtk_alloc_clk_data(CLK_PCIE_NR_CLK);
++
++	mtk_clk_register_gates(node, pcie_clks, ARRAY_SIZE(pcie_clks),
++			       clk_data);
++
++	r = of_clk_add_provider(node, of_clk_src_onecell_get, clk_data);
++	if (r)
++		dev_err(&pdev->dev,
++			"could not register clock provider: %s: %d\n",
++			pdev->name, r);
++
++	mtk_register_reset_controller(node, 1, 0x34);
++
++	return r;
++}
++
++static const struct of_device_id of_match_clk_mt7622_hif[] = {
++	{
++		.compatible = "mediatek,mt7622-pciesys",
++		.data = clk_mt7622_pciesys_init,
++	}, {
++		.compatible = "mediatek,mt7622-ssusbsys",
++		.data = clk_mt7622_ssusbsys_init,
++	}, {
++		/* sentinel */
++	}
++};
++
++static int clk_mt7622_hif_probe(struct platform_device *pdev)
++{
++	int (*clk_init)(struct platform_device *);
++	int r;
++
++	clk_init = of_device_get_match_data(&pdev->dev);
++	if (!clk_init)
++		return -EINVAL;
++
++	r = clk_init(pdev);
++	if (r)
++		dev_err(&pdev->dev,
++			"could not register clock provider: %s: %d\n",
++			pdev->name, r);
++
++	return r;
++}
++
++static struct platform_driver clk_mt7622_hif_drv = {
++	.probe = clk_mt7622_hif_probe,
++	.driver = {
++		.name = "clk-mt7622-hif",
++		.of_match_table = of_match_clk_mt7622_hif,
++	},
++};
++
++builtin_platform_driver(clk_mt7622_hif_drv);
+diff --git a/drivers/clk/mediatek/clk-mt7622.c b/drivers/clk/mediatek/clk-mt7622.c
+new file mode 100644
+index 000000000000..92f7e32770c6
+--- /dev/null
++++ b/drivers/clk/mediatek/clk-mt7622.c
+@@ -0,0 +1,780 @@
++/*
++ * Copyright (c) 2017 MediaTek Inc.
++ * Author: Chen Zhong <chen.zhong@mediatek.com>
++ *	   Sean Wang <sean.wang@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.
++ */
++
++#include <linux/clk-provider.h>
++#include <linux/of.h>
++#include <linux/of_address.h>
++#include <linux/of_device.h>
++#include <linux/platform_device.h>
++
++#include "clk-mtk.h"
++#include "clk-gate.h"
++#include "clk-cpumux.h"
++
++#include <dt-bindings/clock/mt7622-clk.h>
++#include <linux/clk.h> /* for consumer */
++
++#define MT7622_PLL_FMAX		(2500UL * MHZ)
++#define CON0_MT7622_RST_BAR	BIT(27)
++
++#define PLL_xtal(_id, _name, _reg, _pwr_reg, _en_mask, _flags, _pcwbits,\
++			_pd_reg, _pd_shift, _tuner_reg, _pcw_reg,	\
++			_pcw_shift, _div_table, _parent_name) {		\
++		.id = _id,						\
++		.name = _name,						\
++		.reg = _reg,						\
++		.pwr_reg = _pwr_reg,					\
++		.en_mask = _en_mask,					\
++		.flags = _flags,					\
++		.rst_bar_mask = CON0_MT7622_RST_BAR,			\
++		.fmax = MT7622_PLL_FMAX,				\
++		.pcwbits = _pcwbits,					\
++		.pd_reg = _pd_reg,					\
++		.pd_shift = _pd_shift,					\
++		.tuner_reg = _tuner_reg,				\
++		.pcw_reg = _pcw_reg,					\
++		.pcw_shift = _pcw_shift,				\
++		.div_table = _div_table,				\
++		.parent_name = _parent_name,				\
++	}
++
++#define PLL(_id, _name, _reg, _pwr_reg, _en_mask, _flags, _pcwbits,	\
++			_pd_reg, _pd_shift, _tuner_reg, _pcw_reg,	\
++			_pcw_shift)					\
++	PLL_xtal(_id, _name, _reg, _pwr_reg, _en_mask, _flags, _pcwbits,\
++		 _pd_reg, _pd_shift, _tuner_reg, _pcw_reg, _pcw_shift,  \
++		 NULL, "clkxtal")
++
++#define GATE_APMIXED(_id, _name, _parent, _shift) {			\
++		.id = _id,						\
++		.name = _name,						\
++		.parent_name = _parent,					\
++		.regs = &apmixed_cg_regs,				\
++		.shift = _shift,					\
++		.ops = &mtk_clk_gate_ops_no_setclr_inv,			\
++	}
++
++#define GATE_INFRA(_id, _name, _parent, _shift) {			\
++		.id = _id,						\
++		.name = _name,						\
++		.parent_name = _parent,					\
++		.regs = &infra_cg_regs,					\
++		.shift = _shift,					\
++		.ops = &mtk_clk_gate_ops_setclr,			\
++	}
++
++#define GATE_TOP0(_id, _name, _parent, _shift) {			\
++		.id = _id,						\
++		.name = _name,						\
++		.parent_name = _parent,					\
++		.regs = &top0_cg_regs,					\
++		.shift = _shift,					\
++		.ops = &mtk_clk_gate_ops_no_setclr,			\
++	}
++
++#define GATE_TOP1(_id, _name, _parent, _shift) {			\
++		.id = _id,						\
++		.name = _name,						\
++		.parent_name = _parent,					\
++		.regs = &top1_cg_regs,					\
++		.shift = _shift,					\
++		.ops = &mtk_clk_gate_ops_no_setclr,			\
++	}
++
++#define GATE_PERI0(_id, _name, _parent, _shift) {			\
++		.id = _id,						\
++		.name = _name,						\
++		.parent_name = _parent,					\
++		.regs = &peri0_cg_regs,					\
++		.shift = _shift,					\
++		.ops = &mtk_clk_gate_ops_setclr,			\
++	}
++
++#define GATE_PERI1(_id, _name, _parent, _shift) {			\
++		.id = _id,						\
++		.name = _name,						\
++		.parent_name = _parent,					\
++		.regs = &peri1_cg_regs,					\
++		.shift = _shift,					\
++		.ops = &mtk_clk_gate_ops_setclr,			\
++	}
++
++static DEFINE_SPINLOCK(mt7622_clk_lock);
++
++static const char * const infra_mux1_parents[] = {
++	"clkxtal",
++	"armpll",
++	"main_core_en",
++	"armpll"
++};
++
++static const char * const axi_parents[] = {
++	"clkxtal",
++	"syspll1_d2",
++	"syspll_d5",
++	"syspll1_d4",
++	"univpll_d5",
++	"univpll2_d2",
++	"univpll_d7"
++};
++
++static const char * const mem_parents[] = {
++	"clkxtal",
++	"dmpll_ck"
++};
++
++static const char * const ddrphycfg_parents[] = {
++	"clkxtal",
++	"syspll1_d8"
++};
++
++static const char * const eth_parents[] = {
++	"clkxtal",
++	"syspll1_d2",
++	"univpll1_d2",
++	"syspll1_d4",
++	"univpll_d5",
++	"clk_null",
++	"univpll_d7"
++};
++
++static const char * const pwm_parents[] = {
++	"clkxtal",
++	"univpll2_d4"
++};
++
++static const char * const f10m_ref_parents[] = {
++	"clkxtal",
++	"syspll4_d16"
++};
++
++static const char * const nfi_infra_parents[] = {
++	"clkxtal",
++	"clkxtal",
++	"clkxtal",
++	"clkxtal",
++	"clkxtal",
++	"clkxtal",
++	"clkxtal",
++	"clkxtal",
++	"univpll2_d8",
++	"syspll1_d8",
++	"univpll1_d8",
++	"syspll4_d2",
++	"univpll2_d4",
++	"univpll3_d2",
++	"syspll1_d4"
++};
++
++static const char * const flash_parents[] = {
++	"clkxtal",
++	"univpll_d80_d4",
++	"syspll2_d8",
++	"syspll3_d4",
++	"univpll3_d4",
++	"univpll1_d8",
++	"syspll2_d4",
++	"univpll2_d4"
++};
++
++static const char * const uart_parents[] = {
++	"clkxtal",
++	"univpll2_d8"
++};
++
++static const char * const spi0_parents[] = {
++	"clkxtal",
++	"syspll3_d2",
++	"clkxtal",
++	"syspll2_d4",
++	"syspll4_d2",
++	"univpll2_d4",
++	"univpll1_d8",
++	"clkxtal"
++};
++
++static const char * const spi1_parents[] = {
++	"clkxtal",
++	"syspll3_d2",
++	"clkxtal",
++	"syspll4_d4",
++	"syspll4_d2",
++	"univpll2_d4",
++	"univpll1_d8",
++	"clkxtal"
++};
++
++static const char * const msdc30_0_parents[] = {
++	"clkxtal",
++	"univpll2_d16",
++	"univ48m"
++};
++
++static const char * const a1sys_hp_parents[] = {
++	"clkxtal",
++	"aud1pll_ck",
++	"aud2pll_ck",
++	"clkxtal"
++};
++
++static const char * const intdir_parents[] = {
++	"clkxtal",
++	"syspll_d2",
++	"univpll_d2",
++	"sgmiipll_ck"
++};
++
++static const char * const aud_intbus_parents[] = {
++	"clkxtal",
++	"syspll1_d4",
++	"syspll4_d2",
++	"syspll3_d2"
++};
++
++static const char * const pmicspi_parents[] = {
++	"clkxtal",
++	"clk_null",
++	"clk_null",
++	"clk_null",
++	"clk_null",
++	"univpll2_d16"
++};
++
++static const char * const atb_parents[] = {
++	"clkxtal",
++	"syspll1_d2",
++	"syspll_d5"
++};
++
++static const char * const audio_parents[] = {
++	"clkxtal",
++	"syspll3_d4",
++	"syspll4_d4",
++	"univpll1_d16"
++};
++
++static const char * const usb20_parents[] = {
++	"clkxtal",
++	"univpll3_d4",
++	"syspll1_d8",
++	"clkxtal"
++};
++
++static const char * const aud1_parents[] = {
++	"clkxtal",
++	"aud1pll_ck"
++};
++
++static const char * const aud2_parents[] = {
++	"clkxtal",
++	"aud2pll_ck"
++};
++
++static const char * const asm_l_parents[] = {
++	"clkxtal",
++	"syspll_d5",
++	"univpll2_d2",
++	"univpll2_d4"
++};
++
++static const char * const apll1_ck_parents[] = {
++	"aud1_sel",
++	"aud2_sel"
++};
++
++static const char * const peribus_ck_parents[] = {
++	"syspll1_d8",
++	"syspll1_d4"
++};
++
++static const struct mtk_gate_regs apmixed_cg_regs = {
++	.set_ofs = 0x8,
++	.clr_ofs = 0x8,
++	.sta_ofs = 0x8,
++};
++
++static const struct mtk_gate_regs infra_cg_regs = {
++	.set_ofs = 0x40,
++	.clr_ofs = 0x44,
++	.sta_ofs = 0x48,
++};
++
++static const struct mtk_gate_regs top0_cg_regs = {
++	.set_ofs = 0x120,
++	.clr_ofs = 0x120,
++	.sta_ofs = 0x120,
++};
++
++static const struct mtk_gate_regs top1_cg_regs = {
++	.set_ofs = 0x128,
++	.clr_ofs = 0x128,
++	.sta_ofs = 0x128,
++};
++
++static const struct mtk_gate_regs peri0_cg_regs = {
++	.set_ofs = 0x8,
++	.clr_ofs = 0x10,
++	.sta_ofs = 0x18,
++};
++
++static const struct mtk_gate_regs peri1_cg_regs = {
++	.set_ofs = 0xC,
++	.clr_ofs = 0x14,
++	.sta_ofs = 0x1C,
++};
++
++static const struct mtk_pll_data plls[] = {
++	PLL(CLK_APMIXED_ARMPLL, "armpll", 0x0200, 0x020C, 0x00000001,
++	    PLL_AO, 21, 0x0204, 24, 0, 0x0204, 0),
++	PLL(CLK_APMIXED_MAINPLL, "mainpll", 0x0210, 0x021C, 0x00000001,
++	    HAVE_RST_BAR, 21, 0x0214, 24, 0, 0x0214, 0),
++	PLL(CLK_APMIXED_UNIV2PLL, "univ2pll", 0x0220, 0x022C, 0x00000001,
++	    HAVE_RST_BAR, 7, 0x0224, 24, 0, 0x0224, 14),
++	PLL(CLK_APMIXED_ETH1PLL, "eth1pll", 0x0300, 0x0310, 0x00000001,
++	    0, 21, 0x0300, 1, 0, 0x0304, 0),
++	PLL(CLK_APMIXED_ETH2PLL, "eth2pll", 0x0314, 0x0320, 0x00000001,
++	    0, 21, 0x0314, 1, 0, 0x0318, 0),
++	PLL(CLK_APMIXED_AUD1PLL, "aud1pll", 0x0324, 0x0330, 0x00000001,
++	    0, 31, 0x0324, 1, 0, 0x0328, 0),
++	PLL(CLK_APMIXED_AUD2PLL, "aud2pll", 0x0334, 0x0340, 0x00000001,
++	    0, 31, 0x0334, 1, 0, 0x0338, 0),
++	PLL(CLK_APMIXED_TRGPLL, "trgpll", 0x0344, 0x0354, 0x00000001,
++	    0, 21, 0x0344, 1, 0, 0x0348, 0),
++	PLL(CLK_APMIXED_SGMIPLL, "sgmipll", 0x0358, 0x0368, 0x00000001,
++	    0, 21, 0x0358, 1, 0, 0x035C, 0),
++};
++
++static const struct mtk_gate apmixed_clks[] = {
++	GATE_APMIXED(CLK_APMIXED_MAIN_CORE_EN, "main_core_en", "mainpll", 5),
++};
++
++static const struct mtk_gate infra_clks[] = {
++	GATE_INFRA(CLK_INFRA_DBGCLK_PD, "infra_dbgclk_pd", "axi_sel", 0),
++	GATE_INFRA(CLK_INFRA_TRNG, "trng_ck", "axi_sel", 2),
++	GATE_INFRA(CLK_INFRA_AUDIO_PD, "infra_audio_pd", "aud_intbus_sel", 5),
++	GATE_INFRA(CLK_INFRA_IRRX_PD, "infra_irrx_pd", "irrx_sel", 16),
++	GATE_INFRA(CLK_INFRA_APXGPT_PD, "infra_apxgpt_pd", "f10m_ref_sel", 18),
++	GATE_INFRA(CLK_INFRA_PMIC_PD, "infra_pmic_pd", "pmicspi_sel", 22),
++};
++
++static const struct mtk_fixed_clk top_fixed_clks[] = {
++	FIXED_CLK(CLK_TOP_TO_U2_PHY, "to_u2_phy", "clkxtal",
++		  31250000),
++	FIXED_CLK(CLK_TOP_TO_U2_PHY_1P, "to_u2_phy_1p", "clkxtal",
++		  31250000),
++	FIXED_CLK(CLK_TOP_PCIE0_PIPE_EN, "pcie0_pipe_en", "clkxtal",
++		  125000000),
++	FIXED_CLK(CLK_TOP_PCIE1_PIPE_EN, "pcie1_pipe_en", "clkxtal",
++		  125000000),
++	FIXED_CLK(CLK_TOP_SSUSB_TX250M, "ssusb_tx250m", "clkxtal",
++		  250000000),
++	FIXED_CLK(CLK_TOP_SSUSB_EQ_RX250M, "ssusb_eq_rx250m", "clkxtal",
++		  250000000),
++	FIXED_CLK(CLK_TOP_SSUSB_CDR_REF, "ssusb_cdr_ref", "clkxtal",
++		  33333333),
++	FIXED_CLK(CLK_TOP_SSUSB_CDR_FB, "ssusb_cdr_fb", "clkxtal",
++		  50000000),
++	FIXED_CLK(CLK_TOP_SATA_ASIC, "sata_asic", "clkxtal",
++		  50000000),
++	FIXED_CLK(CLK_TOP_SATA_RBC, "sata_rbc", "clkxtal",
++		  50000000),
++};
++
++static const struct mtk_fixed_factor top_divs[] = {
++	FACTOR(CLK_TOP_TO_USB3_SYS, "to_usb3_sys", "eth1pll", 1, 4),
++	FACTOR(CLK_TOP_P1_1MHZ, "p1_1mhz", "eth1pll", 1, 500),
++	FACTOR(CLK_TOP_4MHZ, "free_run_4mhz", "eth1pll", 1, 125),
++	FACTOR(CLK_TOP_P0_1MHZ, "p0_1mhz", "eth1pll", 1, 500),
++	FACTOR(CLK_TOP_TXCLK_SRC_PRE, "txclk_src_pre", "sgmiipll_d2", 1, 1),
++	FACTOR(CLK_TOP_RTC, "rtc", "clkxtal", 1, 1024),
++	FACTOR(CLK_TOP_MEMPLL, "mempll", "clkxtal", 32, 1),
++	FACTOR(CLK_TOP_DMPLL, "dmpll_ck", "mempll", 1, 1),
++	FACTOR(CLK_TOP_SYSPLL_D2, "syspll_d2", "mainpll", 1, 2),
++	FACTOR(CLK_TOP_SYSPLL1_D2, "syspll1_d2", "mainpll", 1, 4),
++	FACTOR(CLK_TOP_SYSPLL1_D4, "syspll1_d4", "mainpll", 1, 8),
++	FACTOR(CLK_TOP_SYSPLL1_D8, "syspll1_d8", "mainpll", 1, 16),
++	FACTOR(CLK_TOP_SYSPLL2_D4, "syspll2_d4", "mainpll", 1, 12),
++	FACTOR(CLK_TOP_SYSPLL2_D8, "syspll2_d8", "mainpll", 1, 24),
++	FACTOR(CLK_TOP_SYSPLL_D5, "syspll_d5", "mainpll", 1, 5),
++	FACTOR(CLK_TOP_SYSPLL3_D2, "syspll3_d2", "mainpll", 1, 10),
++	FACTOR(CLK_TOP_SYSPLL3_D4, "syspll3_d4", "mainpll", 1, 20),
++	FACTOR(CLK_TOP_SYSPLL4_D2, "syspll4_d2", "mainpll", 1, 14),
++	FACTOR(CLK_TOP_SYSPLL4_D4, "syspll4_d4", "mainpll", 1, 28),
++	FACTOR(CLK_TOP_SYSPLL4_D16, "syspll4_d16", "mainpll", 1, 112),
++	FACTOR(CLK_TOP_UNIVPLL, "univpll", "univ2pll", 1, 2),
++	FACTOR(CLK_TOP_UNIVPLL_D2, "univpll_d2", "univpll", 1, 2),
++	FACTOR(CLK_TOP_UNIVPLL1_D2, "univpll1_d2", "univpll", 1, 4),
++	FACTOR(CLK_TOP_UNIVPLL1_D4, "univpll1_d4", "univpll", 1, 8),
++	FACTOR(CLK_TOP_UNIVPLL1_D8, "univpll1_d8", "univpll", 1, 16),
++	FACTOR(CLK_TOP_UNIVPLL1_D16, "univpll1_d16", "univpll", 1, 32),
++	FACTOR(CLK_TOP_UNIVPLL2_D2, "univpll2_d2", "univpll", 1, 6),
++	FACTOR(CLK_TOP_UNIVPLL2_D4, "univpll2_d4", "univpll", 1, 12),
++	FACTOR(CLK_TOP_UNIVPLL2_D8, "univpll2_d8", "univpll", 1, 24),
++	FACTOR(CLK_TOP_UNIVPLL2_D16, "univpll2_d16", "univpll", 1, 48),
++	FACTOR(CLK_TOP_UNIVPLL_D5, "univpll_d5", "univpll", 1, 5),
++	FACTOR(CLK_TOP_UNIVPLL3_D2, "univpll3_d2", "univpll", 1, 10),
++	FACTOR(CLK_TOP_UNIVPLL3_D4, "univpll3_d4", "univpll", 1, 20),
++	FACTOR(CLK_TOP_UNIVPLL3_D16, "univpll3_d16", "univpll", 1, 80),
++	FACTOR(CLK_TOP_UNIVPLL_D7, "univpll_d7", "univpll", 1, 7),
++	FACTOR(CLK_TOP_UNIVPLL_D80_D4, "univpll_d80_d4", "univpll", 1, 320),
++	FACTOR(CLK_TOP_UNIV48M, "univ48m", "univpll", 1, 25),
++	FACTOR(CLK_TOP_SGMIIPLL, "sgmiipll_ck", "sgmipll", 1, 1),
++	FACTOR(CLK_TOP_SGMIIPLL_D2, "sgmiipll_d2", "sgmipll", 1, 2),
++	FACTOR(CLK_TOP_AUD1PLL, "aud1pll_ck", "aud1pll", 1, 1),
++	FACTOR(CLK_TOP_AUD2PLL, "aud2pll_ck", "aud2pll", 1, 1),
++	FACTOR(CLK_TOP_AUD_I2S2_MCK, "aud_i2s2_mck", "i2s2_mck_sel", 1, 2),
++	FACTOR(CLK_TOP_TO_USB3_REF, "to_usb3_ref", "univpll2_d4", 1, 4),
++	FACTOR(CLK_TOP_PCIE1_MAC_EN, "pcie1_mac_en", "univpll1_d4", 1, 1),
++	FACTOR(CLK_TOP_PCIE0_MAC_EN, "pcie0_mac_en", "univpll1_d4", 1, 1),
++	FACTOR(CLK_TOP_ETH_500M, "eth_500m", "eth1pll", 1, 1),
++};
++
++static const struct mtk_gate top_clks[] = {
++	/* TOP0 */
++	GATE_TOP0(CLK_TOP_APLL1_DIV_PD, "apll1_ck_div_pd", "apll1_ck_div", 0),
++	GATE_TOP0(CLK_TOP_APLL2_DIV_PD, "apll2_ck_div_pd", "apll2_ck_div", 1),
++	GATE_TOP0(CLK_TOP_I2S0_MCK_DIV_PD, "i2s0_mck_div_pd", "i2s0_mck_div",
++		  2),
++	GATE_TOP0(CLK_TOP_I2S1_MCK_DIV_PD, "i2s1_mck_div_pd", "i2s1_mck_div",
++		  3),
++	GATE_TOP0(CLK_TOP_I2S2_MCK_DIV_PD, "i2s2_mck_div_pd", "i2s2_mck_div",
++		  4),
++	GATE_TOP0(CLK_TOP_I2S3_MCK_DIV_PD, "i2s3_mck_div_pd", "i2s3_mck_div",
++		  5),
++
++	/* TOP1 */
++	GATE_TOP1(CLK_TOP_A1SYS_HP_DIV_PD, "a1sys_div_pd", "a1sys_div", 0),
++	GATE_TOP1(CLK_TOP_A2SYS_HP_DIV_PD, "a2sys_div_pd", "a2sys_div", 16),
++};
++
++static const struct mtk_clk_divider top_adj_divs[] = {
++	DIV_ADJ(CLK_TOP_APLL1_DIV, "apll1_ck_div", "apll1_ck_sel",
++		0x120, 24, 3),
++	DIV_ADJ(CLK_TOP_APLL2_DIV, "apll2_ck_div", "apll2_ck_sel",
++		0x120, 28, 3),
++	DIV_ADJ(CLK_TOP_I2S0_MCK_DIV, "i2s0_mck_div", "i2s0_mck_sel",
++		0x124, 0, 7),
++	DIV_ADJ(CLK_TOP_I2S1_MCK_DIV, "i2s1_mck_div", "i2s1_mck_sel",
++		0x124, 8, 7),
++	DIV_ADJ(CLK_TOP_I2S2_MCK_DIV, "i2s2_mck_div", "aud_i2s2_mck",
++		0x124, 16, 7),
++	DIV_ADJ(CLK_TOP_I2S3_MCK_DIV, "i2s3_mck_div", "i2s3_mck_sel",
++		0x124, 24, 7),
++	DIV_ADJ(CLK_TOP_A1SYS_HP_DIV, "a1sys_div", "a1sys_hp_sel",
++		0x128, 8, 7),
++	DIV_ADJ(CLK_TOP_A2SYS_HP_DIV, "a2sys_div", "a2sys_hp_sel",
++		0x128, 24, 7),
++};
++
++static const struct mtk_gate peri_clks[] = {
++	/* PERI0 */
++	GATE_PERI0(CLK_PERI_THERM_PD, "peri_therm_pd", "axi_sel", 1),
++	GATE_PERI0(CLK_PERI_PWM1_PD, "peri_pwm1_pd", "clkxtal", 2),
++	GATE_PERI0(CLK_PERI_PWM2_PD, "peri_pwm2_pd", "clkxtal", 3),
++	GATE_PERI0(CLK_PERI_PWM3_PD, "peri_pwm3_pd", "clkxtal", 4),
++	GATE_PERI0(CLK_PERI_PWM4_PD, "peri_pwm4_pd", "clkxtal", 5),
++	GATE_PERI0(CLK_PERI_PWM5_PD, "peri_pwm5_pd", "clkxtal", 6),
++	GATE_PERI0(CLK_PERI_PWM6_PD, "peri_pwm6_pd", "clkxtal", 7),
++	GATE_PERI0(CLK_PERI_PWM7_PD, "peri_pwm7_pd", "clkxtal", 8),
++	GATE_PERI0(CLK_PERI_PWM_PD, "peri_pwm_pd", "clkxtal", 9),
++	GATE_PERI0(CLK_PERI_AP_DMA_PD, "peri_ap_dma_pd", "axi_sel", 12),
++	GATE_PERI0(CLK_PERI_MSDC30_0_PD, "peri_msdc30_0", "msdc30_0_sel", 13),
++	GATE_PERI0(CLK_PERI_MSDC30_1_PD, "peri_msdc30_1", "msdc30_1_sel", 14),
++	GATE_PERI0(CLK_PERI_UART0_PD, "peri_uart0_pd", "axi_sel", 17),
++	GATE_PERI0(CLK_PERI_UART1_PD, "peri_uart1_pd", "axi_sel", 18),
++	GATE_PERI0(CLK_PERI_UART2_PD, "peri_uart2_pd", "axi_sel", 19),
++	GATE_PERI0(CLK_PERI_UART3_PD, "peri_uart3_pd", "axi_sel", 20),
++	GATE_PERI0(CLK_PERI_UART4_PD, "peri_uart4_pd", "axi_sel", 21),
++	GATE_PERI0(CLK_PERI_BTIF_PD, "peri_btif_pd", "axi_sel", 22),
++	GATE_PERI0(CLK_PERI_I2C0_PD, "peri_i2c0_pd", "axi_sel", 23),
++	GATE_PERI0(CLK_PERI_I2C1_PD, "peri_i2c1_pd", "axi_sel", 24),
++	GATE_PERI0(CLK_PERI_I2C2_PD, "peri_i2c2_pd", "axi_sel", 25),
++	GATE_PERI0(CLK_PERI_SPI1_PD, "peri_spi1_pd", "spi1_sel", 26),
++	GATE_PERI0(CLK_PERI_AUXADC_PD, "peri_auxadc_pd", "clkxtal", 27),
++	GATE_PERI0(CLK_PERI_SPI0_PD, "peri_spi0_pd", "spi0_sel", 28),
++	GATE_PERI0(CLK_PERI_SNFI_PD, "peri_snfi_pd", "nfi_infra_sel", 29),
++	GATE_PERI0(CLK_PERI_NFI_PD, "peri_nfi_pd", "axi_sel", 30),
++	GATE_PERI0(CLK_PERI_NFIECC_PD, "peri_nfiecc_pd", "axi_sel", 31),
++
++	/* PERI1 */
++	GATE_PERI1(CLK_PERI_FLASH_PD, "peri_flash_pd", "flash_sel", 1),
++	GATE_PERI1(CLK_PERI_IRTX_PD, "peri_irtx_pd", "irtx_sel", 2),
++};
++
++static struct mtk_composite infra_muxes[] __initdata = {
++	MUX(CLK_INFRA_MUX1_SEL, "infra_mux1_sel", infra_mux1_parents,
++	    0x000, 2, 2),
++};
++
++static struct mtk_composite top_muxes[] = {
++	/* CLK_CFG_0 */
++	MUX_GATE(CLK_TOP_AXI_SEL, "axi_sel", axi_parents,
++		 0x040, 0, 3, 7),
++	MUX_GATE(CLK_TOP_MEM_SEL, "mem_sel", mem_parents,
++		 0x040, 8, 1, 15),
++	MUX_GATE(CLK_TOP_DDRPHYCFG_SEL, "ddrphycfg_sel", ddrphycfg_parents,
++		 0x040, 16, 1, 23),
++	MUX_GATE(CLK_TOP_ETH_SEL, "eth_sel", eth_parents,
++		 0x040, 24, 3, 31),
++
++	/* CLK_CFG_1 */
++	MUX_GATE(CLK_TOP_PWM_SEL, "pwm_sel", pwm_parents,
++		 0x050, 0, 2, 7),
++	MUX_GATE(CLK_TOP_F10M_REF_SEL, "f10m_ref_sel", f10m_ref_parents,
++		 0x050, 8, 1, 15),
++	MUX_GATE(CLK_TOP_NFI_INFRA_SEL, "nfi_infra_sel", nfi_infra_parents,
++		 0x050, 16, 4, 23),
++	MUX_GATE(CLK_TOP_FLASH_SEL, "flash_sel", flash_parents,
++		 0x050, 24, 3, 31),
++
++	/* CLK_CFG_2 */
++	MUX_GATE(CLK_TOP_UART_SEL, "uart_sel", uart_parents,
++		 0x060, 0, 1, 7),
++	MUX_GATE(CLK_TOP_SPI0_SEL, "spi0_sel", spi0_parents,
++		 0x060, 8, 3, 15),
++	MUX_GATE(CLK_TOP_SPI1_SEL, "spi1_sel", spi1_parents,
++		 0x060, 16, 3, 23),
++	MUX_GATE(CLK_TOP_MSDC50_0_SEL, "msdc50_0_sel", uart_parents,
++		 0x060, 24, 3, 31),
++
++	/* CLK_CFG_3 */
++	MUX_GATE(CLK_TOP_MSDC30_0_SEL, "msdc30_0_sel", msdc30_0_parents,
++		 0x070, 0, 3, 7),
++	MUX_GATE(CLK_TOP_MSDC30_1_SEL, "msdc30_1_sel", msdc30_0_parents,
++		 0x070, 8, 3, 15),
++	MUX_GATE(CLK_TOP_A1SYS_HP_SEL, "a1sys_hp_sel", a1sys_hp_parents,
++		 0x070, 16, 2, 23),
++	MUX_GATE(CLK_TOP_A2SYS_HP_SEL, "a2sys_hp_sel", a1sys_hp_parents,
++		 0x070, 24, 2, 31),
++
++	/* CLK_CFG_4 */
++	MUX_GATE(CLK_TOP_INTDIR_SEL, "intdir_sel", intdir_parents,
++		 0x080, 0, 2, 7),
++	MUX_GATE(CLK_TOP_AUD_INTBUS_SEL, "aud_intbus_sel", aud_intbus_parents,
++		 0x080, 8, 2, 15),
++	MUX_GATE(CLK_TOP_PMICSPI_SEL, "pmicspi_sel", pmicspi_parents,
++		 0x080, 16, 3, 23),
++	MUX_GATE(CLK_TOP_SCP_SEL, "scp_sel", ddrphycfg_parents,
++		 0x080, 24, 2, 31),
++
++	/* CLK_CFG_5 */
++	MUX_GATE(CLK_TOP_ATB_SEL, "atb_sel", atb_parents,
++		 0x090, 0, 2, 7),
++	MUX_GATE(CLK_TOP_HIF_SEL, "hif_sel", eth_parents,
++		 0x090, 8, 3, 15),
++	MUX_GATE(CLK_TOP_AUDIO_SEL, "audio_sel", audio_parents,
++		 0x090, 16, 2, 23),
++	MUX_GATE(CLK_TOP_U2_SEL, "usb20_sel", usb20_parents,
++		 0x090, 24, 2, 31),
++
++	/* CLK_CFG_6 */
++	MUX_GATE(CLK_TOP_AUD1_SEL, "aud1_sel", aud1_parents,
++		 0x0A0, 0, 1, 7),
++	MUX_GATE(CLK_TOP_AUD2_SEL, "aud2_sel", aud2_parents,
++		 0x0A0, 8, 1, 15),
++	MUX_GATE(CLK_TOP_IRRX_SEL, "irrx_sel", f10m_ref_parents,
++		 0x0A0, 16, 1, 23),
++	MUX_GATE(CLK_TOP_IRTX_SEL, "irtx_sel", f10m_ref_parents,
++		 0x0A0, 24, 1, 31),
++
++	/* CLK_CFG_7 */
++	MUX_GATE(CLK_TOP_ASM_L_SEL, "asm_l_sel", asm_l_parents,
++		 0x0B0, 0, 2, 7),
++	MUX_GATE(CLK_TOP_ASM_M_SEL, "asm_m_sel", asm_l_parents,
++		 0x0B0, 8, 2, 15),
++	MUX_GATE(CLK_TOP_ASM_H_SEL, "asm_h_sel", asm_l_parents,
++		 0x0B0, 16, 2, 23),
++
++	/* CLK_AUDDIV_0 */
++	MUX(CLK_TOP_APLL1_SEL, "apll1_ck_sel", apll1_ck_parents,
++	    0x120, 6, 1),
++	MUX(CLK_TOP_APLL2_SEL, "apll2_ck_sel", apll1_ck_parents,
++	    0x120, 7, 1),
++	MUX(CLK_TOP_I2S0_MCK_SEL, "i2s0_mck_sel", apll1_ck_parents,
++	    0x120, 8, 1),
++	MUX(CLK_TOP_I2S1_MCK_SEL, "i2s1_mck_sel", apll1_ck_parents,
++	    0x120, 9, 1),
++	MUX(CLK_TOP_I2S2_MCK_SEL, "i2s2_mck_sel", apll1_ck_parents,
++	    0x120, 10, 1),
++	MUX(CLK_TOP_I2S3_MCK_SEL, "i2s3_mck_sel", apll1_ck_parents,
++	    0x120, 11, 1),
++};
++
++static struct mtk_composite peri_muxes[] = {
++	/* PERI_GLOBALCON_CKSEL */
++	MUX(CLK_PERIBUS_SEL, "peribus_ck_sel", peribus_ck_parents, 0x05C, 0, 1),
++};
++
++static int mtk_topckgen_init(struct platform_device *pdev)
++{
++	struct clk_onecell_data *clk_data;
++	void __iomem *base;
++	struct device_node *node = pdev->dev.of_node;
++	struct resource *res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
++
++	base = devm_ioremap_resource(&pdev->dev, res);
++	if (IS_ERR(base))
++		return PTR_ERR(base);
++
++	clk_data = mtk_alloc_clk_data(CLK_TOP_NR_CLK);
++
++	mtk_clk_register_fixed_clks(top_fixed_clks, ARRAY_SIZE(top_fixed_clks),
++				    clk_data);
++
++	mtk_clk_register_factors(top_divs, ARRAY_SIZE(top_divs),
++				 clk_data);
++
++	mtk_clk_register_composites(top_muxes, ARRAY_SIZE(top_muxes),
++				    base, &mt7622_clk_lock, clk_data);
++
++	mtk_clk_register_dividers(top_adj_divs, ARRAY_SIZE(top_adj_divs),
++				  base, &mt7622_clk_lock, clk_data);
++
++	mtk_clk_register_gates(node, top_clks, ARRAY_SIZE(top_clks),
++			       clk_data);
++
++	clk_prepare_enable(clk_data->clks[CLK_TOP_AXI_SEL]);
++	clk_prepare_enable(clk_data->clks[CLK_TOP_MEM_SEL]);
++	clk_prepare_enable(clk_data->clks[CLK_TOP_DDRPHYCFG_SEL]);
++
++	return of_clk_add_provider(node, of_clk_src_onecell_get, clk_data);
++}
++
++static int __init mtk_infrasys_init(struct platform_device *pdev)
++{
++	struct device_node *node = pdev->dev.of_node;
++	struct clk_onecell_data *clk_data;
++	int r;
++
++	clk_data = mtk_alloc_clk_data(CLK_INFRA_NR_CLK);
++
++	mtk_clk_register_gates(node, infra_clks, ARRAY_SIZE(infra_clks),
++			       clk_data);
++
++	mtk_clk_register_cpumuxes(node, infra_muxes, ARRAY_SIZE(infra_muxes),
++				  clk_data);
++
++	r = of_clk_add_provider(node, of_clk_src_onecell_get,
++				clk_data);
++	if (r)
++		return r;
++
++	mtk_register_reset_controller(node, 1, 0x30);
++
++	return 0;
++}
++
++static int mtk_apmixedsys_init(struct platform_device *pdev)
++{
++	struct clk_onecell_data *clk_data;
++	struct device_node *node = pdev->dev.of_node;
++
++	clk_data = mtk_alloc_clk_data(CLK_APMIXED_NR_CLK);
++	if (!clk_data)
++		return -ENOMEM;
++
++	mtk_clk_register_plls(node, plls, ARRAY_SIZE(plls),
++			      clk_data);
++
++	mtk_clk_register_gates(node, apmixed_clks,
++			       ARRAY_SIZE(apmixed_clks), clk_data);
++
++	clk_prepare_enable(clk_data->clks[CLK_APMIXED_ARMPLL]);
++	clk_prepare_enable(clk_data->clks[CLK_APMIXED_MAIN_CORE_EN]);
++
++	return of_clk_add_provider(node, of_clk_src_onecell_get, clk_data);
++}
++
++static int mtk_pericfg_init(struct platform_device *pdev)
++{
++	struct clk_onecell_data *clk_data;
++	void __iomem *base;
++	int r;
++	struct device_node *node = pdev->dev.of_node;
++	struct resource *res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
++
++	base = devm_ioremap_resource(&pdev->dev, res);
++	if (IS_ERR(base))
++		return PTR_ERR(base);
++
++	clk_data = mtk_alloc_clk_data(CLK_PERI_NR_CLK);
++
++	mtk_clk_register_gates(node, peri_clks, ARRAY_SIZE(peri_clks),
++			       clk_data);
++
++	mtk_clk_register_composites(peri_muxes, ARRAY_SIZE(peri_muxes), base,
++				    &mt7622_clk_lock, clk_data);
++
++	r = of_clk_add_provider(node, of_clk_src_onecell_get, clk_data);
++	if (r)
++		return r;
++
++	clk_prepare_enable(clk_data->clks[CLK_PERI_UART0_PD]);
++
++	mtk_register_reset_controller(node, 2, 0x0);
++
++	return 0;
++}
++
++static const struct of_device_id of_match_clk_mt7622[] = {
++	{
++		.compatible = "mediatek,mt7622-apmixedsys",
++		.data = mtk_apmixedsys_init,
++	}, {
++		.compatible = "mediatek,mt7622-infracfg",
++		.data = mtk_infrasys_init,
++	}, {
++		.compatible = "mediatek,mt7622-topckgen",
++		.data = mtk_topckgen_init,
++	}, {
++		.compatible = "mediatek,mt7622-pericfg",
++		.data = mtk_pericfg_init,
++	}, {
++		/* sentinel */
++	}
++};
++
++static int clk_mt7622_probe(struct platform_device *pdev)
++{
++	int (*clk_init)(struct platform_device *);
++	int r;
++
++	clk_init = of_device_get_match_data(&pdev->dev);
++	if (!clk_init)
++		return -EINVAL;
++
++	r = clk_init(pdev);
++	if (r)
++		dev_err(&pdev->dev,
++			"could not register clock provider: %s: %d\n",
++			pdev->name, r);
++
++	return r;
++}
++
++static struct platform_driver clk_mt7622_drv = {
++	.probe = clk_mt7622_probe,
++	.driver = {
++		.name = "clk-mt7622",
++		.of_match_table = of_match_clk_mt7622,
++	},
++};
++
++static int clk_mt7622_init(void)
++{
++	return platform_driver_register(&clk_mt7622_drv);
++}
++
++arch_initcall(clk_mt7622_init);
+-- 
+2.11.0
+
diff --git a/target/linux/mediatek/patches-4.14/0151-arm64-dts-mt8173-remove-mediatek-mt8135-mmc-from-mmc.patch b/target/linux/mediatek/patches-4.14/0151-arm64-dts-mt8173-remove-mediatek-mt8135-mmc-from-mmc.patch
new file mode 100644
index 0000000000..6c8c3c081f
--- /dev/null
+++ b/target/linux/mediatek/patches-4.14/0151-arm64-dts-mt8173-remove-mediatek-mt8135-mmc-from-mmc.patch
@@ -0,0 +1,66 @@
+From fa69904d3b7357a5be43771f764e10fd99ebbb11 Mon Sep 17 00:00:00 2001
+From: Chaotian Jing <chaotian.jing@mediatek.com>
+Date: Mon, 16 Oct 2017 09:46:30 +0800
+Subject: [PATCH 151/224] arm64: dts: mt8173: remove "mediatek, mt8135-mmc"
+ from mmc nodes
+
+devicetree bindings has been updated to support multi-platforms,
+so that each platform has its owns compatible name.
+And, this compatible name may used in driver to distinguish with
+other platform.
+
+Signed-off-by: Chaotian Jing <chaotian.jing@mediatek.com>
+Tested-by: Sean Wang <sean.wang@mediatek.com>
+Signed-off-by: Ulf Hansson <ulf.hansson@linaro.org>
+Acked-by: Matthias Brugger <matthias.bgg@gmail.com>
+---
+ arch/arm64/boot/dts/mediatek/mt8173.dtsi | 12 ++++--------
+ 1 file changed, 4 insertions(+), 8 deletions(-)
+
+diff --git a/arch/arm64/boot/dts/mediatek/mt8173.dtsi b/arch/arm64/boot/dts/mediatek/mt8173.dtsi
+index b99a27372965..26396ef53bde 100644
+--- a/arch/arm64/boot/dts/mediatek/mt8173.dtsi
++++ b/arch/arm64/boot/dts/mediatek/mt8173.dtsi
+@@ -682,8 +682,7 @@
+ 		};
+ 
+ 		mmc0: mmc@11230000 {
+-			compatible = "mediatek,mt8173-mmc",
+-				     "mediatek,mt8135-mmc";
++			compatible = "mediatek,mt8173-mmc";
+ 			reg = <0 0x11230000 0 0x1000>;
+ 			interrupts = <GIC_SPI 71 IRQ_TYPE_LEVEL_LOW>;
+ 			clocks = <&pericfg CLK_PERI_MSDC30_0>,
+@@ -693,8 +692,7 @@
+ 		};
+ 
+ 		mmc1: mmc@11240000 {
+-			compatible = "mediatek,mt8173-mmc",
+-				     "mediatek,mt8135-mmc";
++			compatible = "mediatek,mt8173-mmc";
+ 			reg = <0 0x11240000 0 0x1000>;
+ 			interrupts = <GIC_SPI 72 IRQ_TYPE_LEVEL_LOW>;
+ 			clocks = <&pericfg CLK_PERI_MSDC30_1>,
+@@ -704,8 +702,7 @@
+ 		};
+ 
+ 		mmc2: mmc@11250000 {
+-			compatible = "mediatek,mt8173-mmc",
+-				     "mediatek,mt8135-mmc";
++			compatible = "mediatek,mt8173-mmc";
+ 			reg = <0 0x11250000 0 0x1000>;
+ 			interrupts = <GIC_SPI 73 IRQ_TYPE_LEVEL_LOW>;
+ 			clocks = <&pericfg CLK_PERI_MSDC30_2>,
+@@ -715,8 +712,7 @@
+ 		};
+ 
+ 		mmc3: mmc@11260000 {
+-			compatible = "mediatek,mt8173-mmc",
+-				     "mediatek,mt8135-mmc";
++			compatible = "mediatek,mt8173-mmc";
+ 			reg = <0 0x11260000 0 0x1000>;
+ 			interrupts = <GIC_SPI 74 IRQ_TYPE_LEVEL_LOW>;
+ 			clocks = <&pericfg CLK_PERI_MSDC30_3>,
+-- 
+2.11.0
+
diff --git a/target/linux/mediatek/patches-4.14/0152-mmc-mediatek-make-hs400_tune_response-only-for-mt817.patch b/target/linux/mediatek/patches-4.14/0152-mmc-mediatek-make-hs400_tune_response-only-for-mt817.patch
new file mode 100644
index 0000000000..3c665dc317
--- /dev/null
+++ b/target/linux/mediatek/patches-4.14/0152-mmc-mediatek-make-hs400_tune_response-only-for-mt817.patch
@@ -0,0 +1,75 @@
+From bc70c7f1174b937af2784977281a1567f69dd2b6 Mon Sep 17 00:00:00 2001
+From: Chaotian Jing <chaotian.jing@mediatek.com>
+Date: Mon, 16 Oct 2017 09:46:31 +0800
+Subject: [PATCH 152/224] mmc: mediatek: make hs400_tune_response only for
+ mt8173
+
+the origin design of hs400_tune_response is for mt8173 because of
+mt8173 has a special design. for doing that, we add a new member
+"compatible", by now it's only for mt8173.
+
+Signed-off-by: Chaotian Jing <chaotian.jing@mediatek.com>
+Tested-by: Sean Wang <sean.wang@mediatek.com>
+Signed-off-by: Ulf Hansson <ulf.hansson@linaro.org>
+---
+ drivers/mmc/host/mtk-sd.c | 11 +++++++++--
+ 1 file changed, 9 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/mmc/host/mtk-sd.c b/drivers/mmc/host/mtk-sd.c
+index 643c795f1bdd..ab2fbbbdfda3 100644
+--- a/drivers/mmc/host/mtk-sd.c
++++ b/drivers/mmc/host/mtk-sd.c
+@@ -300,6 +300,7 @@ struct msdc_save_para {
+ 
+ struct mtk_mmc_compatible {
+ 	u8 clk_div_bits;
++	bool hs400_tune; /* only used for MT8173 */
+ };
+ 
+ struct msdc_tune_para {
+@@ -360,18 +361,22 @@ struct msdc_host {
+ 
+ static const struct mtk_mmc_compatible mt8135_compat = {
+ 	.clk_div_bits = 8,
++	.hs400_tune = false,
+ };
+ 
+ static const struct mtk_mmc_compatible mt8173_compat = {
+ 	.clk_div_bits = 8,
++	.hs400_tune = true,
+ };
+ 
+ static const struct mtk_mmc_compatible mt2701_compat = {
+ 	.clk_div_bits = 12,
++	.hs400_tune = false,
+ };
+ 
+ static const struct mtk_mmc_compatible mt2712_compat = {
+ 	.clk_div_bits = 12,
++	.hs400_tune = false,
+ };
+ 
+ static const struct of_device_id msdc_of_ids[] = {
+@@ -666,7 +671,8 @@ static void msdc_set_mclk(struct msdc_host *host, unsigned char timing, u32 hz)
+ 		       host->base + PAD_CMD_TUNE);
+ 	}
+ 
+-	if (timing == MMC_TIMING_MMC_HS400)
++	if (timing == MMC_TIMING_MMC_HS400 &&
++	    host->dev_comp->hs400_tune)
+ 		sdr_set_field(host->base + PAD_CMD_TUNE,
+ 			      MSDC_PAD_TUNE_CMDRRDLY,
+ 			      host->hs400_cmd_int_delay);
+@@ -1594,7 +1600,8 @@ static int msdc_execute_tuning(struct mmc_host *mmc, u32 opcode)
+ 	struct msdc_host *host = mmc_priv(mmc);
+ 	int ret;
+ 
+-	if (host->hs400_mode)
++	if (host->hs400_mode &&
++	    host->dev_comp->hs400_tune)
+ 		ret = hs400_tune_response(mmc, opcode);
+ 	else
+ 		ret = msdc_tune_response(mmc, opcode);
+-- 
+2.11.0
+
diff --git a/target/linux/mediatek/patches-4.14/0153-mmc-mediatek-add-pad_tune0-support.patch b/target/linux/mediatek/patches-4.14/0153-mmc-mediatek-add-pad_tune0-support.patch
new file mode 100644
index 0000000000..d0f81be5a8
--- /dev/null
+++ b/target/linux/mediatek/patches-4.14/0153-mmc-mediatek-add-pad_tune0-support.patch
@@ -0,0 +1,261 @@
+From a10349f1710a11239c58da3a7e5b353c6b2070c2 Mon Sep 17 00:00:00 2001
+From: Chaotian Jing <chaotian.jing@mediatek.com>
+Date: Mon, 16 Oct 2017 09:46:32 +0800
+Subject: [PATCH 153/224] mmc: mediatek: add pad_tune0 support
+
+from mt2701, the register of PAD_TUNE has been phased out,
+while there is a new register of PAD_TUNE0
+
+Signed-off-by: Chaotian Jing <chaotian.jing@mediatek.com>
+Tested-by: Sean Wang <sean.wang@mediatek.com>
+Signed-off-by: Ulf Hansson <ulf.hansson@linaro.org>
+---
+ drivers/mmc/host/mtk-sd.c | 51 ++++++++++++++++++++++++++++++-----------------
+ 1 file changed, 33 insertions(+), 18 deletions(-)
+
+diff --git a/drivers/mmc/host/mtk-sd.c b/drivers/mmc/host/mtk-sd.c
+index ab2fbbbdfda3..bcd83d6f2b86 100644
+--- a/drivers/mmc/host/mtk-sd.c
++++ b/drivers/mmc/host/mtk-sd.c
+@@ -75,6 +75,7 @@
+ #define MSDC_PATCH_BIT   0xb0
+ #define MSDC_PATCH_BIT1  0xb4
+ #define MSDC_PAD_TUNE    0xec
++#define MSDC_PAD_TUNE0   0xf0
+ #define PAD_DS_TUNE      0x188
+ #define PAD_CMD_TUNE     0x18c
+ #define EMMC50_CFG0      0x208
+@@ -301,6 +302,7 @@ struct msdc_save_para {
+ struct mtk_mmc_compatible {
+ 	u8 clk_div_bits;
+ 	bool hs400_tune; /* only used for MT8173 */
++	u32 pad_tune_reg;
+ };
+ 
+ struct msdc_tune_para {
+@@ -362,21 +364,25 @@ struct msdc_host {
+ static const struct mtk_mmc_compatible mt8135_compat = {
+ 	.clk_div_bits = 8,
+ 	.hs400_tune = false,
++	.pad_tune_reg = MSDC_PAD_TUNE,
+ };
+ 
+ static const struct mtk_mmc_compatible mt8173_compat = {
+ 	.clk_div_bits = 8,
+ 	.hs400_tune = true,
++	.pad_tune_reg = MSDC_PAD_TUNE,
+ };
+ 
+ static const struct mtk_mmc_compatible mt2701_compat = {
+ 	.clk_div_bits = 12,
+ 	.hs400_tune = false,
++	.pad_tune_reg = MSDC_PAD_TUNE0,
+ };
+ 
+ static const struct mtk_mmc_compatible mt2712_compat = {
+ 	.clk_div_bits = 12,
+ 	.hs400_tune = false,
++	.pad_tune_reg = MSDC_PAD_TUNE0,
+ };
+ 
+ static const struct of_device_id msdc_of_ids[] = {
+@@ -581,6 +587,7 @@ static void msdc_set_mclk(struct msdc_host *host, unsigned char timing, u32 hz)
+ 	u32 flags;
+ 	u32 div;
+ 	u32 sclk;
++	u32 tune_reg = host->dev_comp->pad_tune_reg;
+ 
+ 	if (!hz) {
+ 		dev_dbg(host->dev, "set mclk to 0\n");
+@@ -663,10 +670,10 @@ static void msdc_set_mclk(struct msdc_host *host, unsigned char timing, u32 hz)
+ 	 */
+ 	if (host->sclk <= 52000000) {
+ 		writel(host->def_tune_para.iocon, host->base + MSDC_IOCON);
+-		writel(host->def_tune_para.pad_tune, host->base + MSDC_PAD_TUNE);
++		writel(host->def_tune_para.pad_tune, host->base + tune_reg);
+ 	} else {
+ 		writel(host->saved_tune_para.iocon, host->base + MSDC_IOCON);
+-		writel(host->saved_tune_para.pad_tune, host->base + MSDC_PAD_TUNE);
++		writel(host->saved_tune_para.pad_tune, host->base + tune_reg);
+ 		writel(host->saved_tune_para.pad_cmd_tune,
+ 		       host->base + PAD_CMD_TUNE);
+ 	}
+@@ -1224,6 +1231,7 @@ static irqreturn_t msdc_irq(int irq, void *dev_id)
+ static void msdc_init_hw(struct msdc_host *host)
+ {
+ 	u32 val;
++	u32 tune_reg = host->dev_comp->pad_tune_reg;
+ 
+ 	/* Configure to MMC/SD mode, clock free running */
+ 	sdr_set_bits(host->base + MSDC_CFG, MSDC_CFG_MODE | MSDC_CFG_CKPDN);
+@@ -1239,7 +1247,7 @@ static void msdc_init_hw(struct msdc_host *host)
+ 	val = readl(host->base + MSDC_INT);
+ 	writel(val, host->base + MSDC_INT);
+ 
+-	writel(0, host->base + MSDC_PAD_TUNE);
++	writel(0, host->base + tune_reg);
+ 	writel(0, host->base + MSDC_IOCON);
+ 	sdr_set_field(host->base + MSDC_IOCON, MSDC_IOCON_DDLSEL, 0);
+ 	writel(0x403c0046, host->base + MSDC_PATCH_BIT);
+@@ -1259,7 +1267,7 @@ static void msdc_init_hw(struct msdc_host *host)
+ 	sdr_set_field(host->base + SDC_CFG, SDC_CFG_DTOC, 3);
+ 
+ 	host->def_tune_para.iocon = readl(host->base + MSDC_IOCON);
+-	host->def_tune_para.pad_tune = readl(host->base + MSDC_PAD_TUNE);
++	host->def_tune_para.pad_tune = readl(host->base + tune_reg);
+ 	dev_dbg(host->dev, "init hardware done!");
+ }
+ 
+@@ -1402,18 +1410,19 @@ static int msdc_tune_response(struct mmc_host *mmc, u32 opcode)
+ 	struct msdc_delay_phase internal_delay_phase;
+ 	u8 final_delay, final_maxlen;
+ 	u32 internal_delay = 0;
++	u32 tune_reg = host->dev_comp->pad_tune_reg;
+ 	int cmd_err;
+ 	int i, j;
+ 
+ 	if (mmc->ios.timing == MMC_TIMING_MMC_HS200 ||
+ 	    mmc->ios.timing == MMC_TIMING_UHS_SDR104)
+-		sdr_set_field(host->base + MSDC_PAD_TUNE,
++		sdr_set_field(host->base + tune_reg,
+ 			      MSDC_PAD_TUNE_CMDRRDLY,
+ 			      host->hs200_cmd_int_delay);
+ 
+ 	sdr_clr_bits(host->base + MSDC_IOCON, MSDC_IOCON_RSPL);
+ 	for (i = 0 ; i < PAD_DELAY_MAX; i++) {
+-		sdr_set_field(host->base + MSDC_PAD_TUNE,
++		sdr_set_field(host->base + tune_reg,
+ 			      MSDC_PAD_TUNE_CMDRDLY, i);
+ 		/*
+ 		 * Using the same parameters, it may sometimes pass the test,
+@@ -1437,7 +1446,7 @@ static int msdc_tune_response(struct mmc_host *mmc, u32 opcode)
+ 
+ 	sdr_set_bits(host->base + MSDC_IOCON, MSDC_IOCON_RSPL);
+ 	for (i = 0; i < PAD_DELAY_MAX; i++) {
+-		sdr_set_field(host->base + MSDC_PAD_TUNE,
++		sdr_set_field(host->base + tune_reg,
+ 			      MSDC_PAD_TUNE_CMDRDLY, i);
+ 		/*
+ 		 * Using the same parameters, it may sometimes pass the test,
+@@ -1462,12 +1471,12 @@ static int msdc_tune_response(struct mmc_host *mmc, u32 opcode)
+ 		final_maxlen = final_fall_delay.maxlen;
+ 	if (final_maxlen == final_rise_delay.maxlen) {
+ 		sdr_clr_bits(host->base + MSDC_IOCON, MSDC_IOCON_RSPL);
+-		sdr_set_field(host->base + MSDC_PAD_TUNE, MSDC_PAD_TUNE_CMDRDLY,
++		sdr_set_field(host->base + tune_reg, MSDC_PAD_TUNE_CMDRDLY,
+ 			      final_rise_delay.final_phase);
+ 		final_delay = final_rise_delay.final_phase;
+ 	} else {
+ 		sdr_set_bits(host->base + MSDC_IOCON, MSDC_IOCON_RSPL);
+-		sdr_set_field(host->base + MSDC_PAD_TUNE, MSDC_PAD_TUNE_CMDRDLY,
++		sdr_set_field(host->base + tune_reg, MSDC_PAD_TUNE_CMDRDLY,
+ 			      final_fall_delay.final_phase);
+ 		final_delay = final_fall_delay.final_phase;
+ 	}
+@@ -1475,7 +1484,7 @@ static int msdc_tune_response(struct mmc_host *mmc, u32 opcode)
+ 		goto skip_internal;
+ 
+ 	for (i = 0; i < PAD_DELAY_MAX; i++) {
+-		sdr_set_field(host->base + MSDC_PAD_TUNE,
++		sdr_set_field(host->base + tune_reg,
+ 			      MSDC_PAD_TUNE_CMDRRDLY, i);
+ 		mmc_send_tuning(mmc, opcode, &cmd_err);
+ 		if (!cmd_err)
+@@ -1483,7 +1492,7 @@ static int msdc_tune_response(struct mmc_host *mmc, u32 opcode)
+ 	}
+ 	dev_dbg(host->dev, "Final internal delay: 0x%x\n", internal_delay);
+ 	internal_delay_phase = get_best_delay(host, internal_delay);
+-	sdr_set_field(host->base + MSDC_PAD_TUNE, MSDC_PAD_TUNE_CMDRRDLY,
++	sdr_set_field(host->base + tune_reg, MSDC_PAD_TUNE_CMDRRDLY,
+ 		      internal_delay_phase.final_phase);
+ skip_internal:
+ 	dev_dbg(host->dev, "Final cmd pad delay: %x\n", final_delay);
+@@ -1545,12 +1554,13 @@ static int msdc_tune_data(struct mmc_host *mmc, u32 opcode)
+ 	u32 rise_delay = 0, fall_delay = 0;
+ 	struct msdc_delay_phase final_rise_delay, final_fall_delay = { 0,};
+ 	u8 final_delay, final_maxlen;
++	u32 tune_reg = host->dev_comp->pad_tune_reg;
+ 	int i, ret;
+ 
+ 	sdr_clr_bits(host->base + MSDC_IOCON, MSDC_IOCON_DSPL);
+ 	sdr_clr_bits(host->base + MSDC_IOCON, MSDC_IOCON_W_DSPL);
+ 	for (i = 0 ; i < PAD_DELAY_MAX; i++) {
+-		sdr_set_field(host->base + MSDC_PAD_TUNE,
++		sdr_set_field(host->base + tune_reg,
+ 			      MSDC_PAD_TUNE_DATRRDLY, i);
+ 		ret = mmc_send_tuning(mmc, opcode, NULL);
+ 		if (!ret)
+@@ -1565,7 +1575,7 @@ static int msdc_tune_data(struct mmc_host *mmc, u32 opcode)
+ 	sdr_set_bits(host->base + MSDC_IOCON, MSDC_IOCON_DSPL);
+ 	sdr_set_bits(host->base + MSDC_IOCON, MSDC_IOCON_W_DSPL);
+ 	for (i = 0; i < PAD_DELAY_MAX; i++) {
+-		sdr_set_field(host->base + MSDC_PAD_TUNE,
++		sdr_set_field(host->base + tune_reg,
+ 			      MSDC_PAD_TUNE_DATRRDLY, i);
+ 		ret = mmc_send_tuning(mmc, opcode, NULL);
+ 		if (!ret)
+@@ -1578,14 +1588,14 @@ static int msdc_tune_data(struct mmc_host *mmc, u32 opcode)
+ 	if (final_maxlen == final_rise_delay.maxlen) {
+ 		sdr_clr_bits(host->base + MSDC_IOCON, MSDC_IOCON_DSPL);
+ 		sdr_clr_bits(host->base + MSDC_IOCON, MSDC_IOCON_W_DSPL);
+-		sdr_set_field(host->base + MSDC_PAD_TUNE,
++		sdr_set_field(host->base + tune_reg,
+ 			      MSDC_PAD_TUNE_DATRRDLY,
+ 			      final_rise_delay.final_phase);
+ 		final_delay = final_rise_delay.final_phase;
+ 	} else {
+ 		sdr_set_bits(host->base + MSDC_IOCON, MSDC_IOCON_DSPL);
+ 		sdr_set_bits(host->base + MSDC_IOCON, MSDC_IOCON_W_DSPL);
+-		sdr_set_field(host->base + MSDC_PAD_TUNE,
++		sdr_set_field(host->base + tune_reg,
+ 			      MSDC_PAD_TUNE_DATRRDLY,
+ 			      final_fall_delay.final_phase);
+ 		final_delay = final_fall_delay.final_phase;
+@@ -1599,6 +1609,7 @@ static int msdc_execute_tuning(struct mmc_host *mmc, u32 opcode)
+ {
+ 	struct msdc_host *host = mmc_priv(mmc);
+ 	int ret;
++	u32 tune_reg = host->dev_comp->pad_tune_reg;
+ 
+ 	if (host->hs400_mode &&
+ 	    host->dev_comp->hs400_tune)
+@@ -1616,7 +1627,7 @@ static int msdc_execute_tuning(struct mmc_host *mmc, u32 opcode)
+ 	}
+ 
+ 	host->saved_tune_para.iocon = readl(host->base + MSDC_IOCON);
+-	host->saved_tune_para.pad_tune = readl(host->base + MSDC_PAD_TUNE);
++	host->saved_tune_para.pad_tune = readl(host->base + tune_reg);
+ 	host->saved_tune_para.pad_cmd_tune = readl(host->base + PAD_CMD_TUNE);
+ 	return ret;
+ }
+@@ -1857,10 +1868,12 @@ static int msdc_drv_remove(struct platform_device *pdev)
+ #ifdef CONFIG_PM
+ static void msdc_save_reg(struct msdc_host *host)
+ {
++	u32 tune_reg = host->dev_comp->pad_tune_reg;
++
+ 	host->save_para.msdc_cfg = readl(host->base + MSDC_CFG);
+ 	host->save_para.iocon = readl(host->base + MSDC_IOCON);
+ 	host->save_para.sdc_cfg = readl(host->base + SDC_CFG);
+-	host->save_para.pad_tune = readl(host->base + MSDC_PAD_TUNE);
++	host->save_para.pad_tune = readl(host->base + tune_reg);
+ 	host->save_para.patch_bit0 = readl(host->base + MSDC_PATCH_BIT);
+ 	host->save_para.patch_bit1 = readl(host->base + MSDC_PATCH_BIT1);
+ 	host->save_para.pad_ds_tune = readl(host->base + PAD_DS_TUNE);
+@@ -1870,10 +1883,12 @@ static void msdc_save_reg(struct msdc_host *host)
+ 
+ static void msdc_restore_reg(struct msdc_host *host)
+ {
++	u32 tune_reg = host->dev_comp->pad_tune_reg;
++
+ 	writel(host->save_para.msdc_cfg, host->base + MSDC_CFG);
+ 	writel(host->save_para.iocon, host->base + MSDC_IOCON);
+ 	writel(host->save_para.sdc_cfg, host->base + SDC_CFG);
+-	writel(host->save_para.pad_tune, host->base + MSDC_PAD_TUNE);
++	writel(host->save_para.pad_tune, host->base + tune_reg);
+ 	writel(host->save_para.patch_bit0, host->base + MSDC_PATCH_BIT);
+ 	writel(host->save_para.patch_bit1, host->base + MSDC_PATCH_BIT1);
+ 	writel(host->save_para.pad_ds_tune, host->base + PAD_DS_TUNE);
+-- 
+2.11.0
+
diff --git a/target/linux/mediatek/patches-4.14/0154-mmc-mediatek-add-async-fifo-and-data-tune-support.patch b/target/linux/mediatek/patches-4.14/0154-mmc-mediatek-add-async-fifo-and-data-tune-support.patch
new file mode 100644
index 0000000000..0bd5ca13bc
--- /dev/null
+++ b/target/linux/mediatek/patches-4.14/0154-mmc-mediatek-add-async-fifo-and-data-tune-support.patch
@@ -0,0 +1,175 @@
+From 830574225e621809600902b69bbdd563e67ef4eb Mon Sep 17 00:00:00 2001
+From: Chaotian Jing <chaotian.jing@mediatek.com>
+Date: Mon, 16 Oct 2017 09:46:33 +0800
+Subject: [PATCH 154/224] mmc: mediatek: add async fifo and data tune support
+
+mt2701/mt2712 supports async fifo & data tune, which can improve
+host stability.
+
+Signed-off-by: Chaotian Jing <chaotian.jing@mediatek.com>
+Tested-by: Sean Wang <sean.wang@mediatek.com>
+Signed-off-by: Ulf Hansson <ulf.hansson@linaro.org>
+---
+ drivers/mmc/host/mtk-sd.c | 52 +++++++++++++++++++++++++++++++++++++++++++++--
+ 1 file changed, 50 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/mmc/host/mtk-sd.c b/drivers/mmc/host/mtk-sd.c
+index bcd83d6f2b86..8113bacc1540 100644
+--- a/drivers/mmc/host/mtk-sd.c
++++ b/drivers/mmc/host/mtk-sd.c
+@@ -74,6 +74,7 @@
+ #define MSDC_DMA_CFG     0x9c
+ #define MSDC_PATCH_BIT   0xb0
+ #define MSDC_PATCH_BIT1  0xb4
++#define MSDC_PATCH_BIT2  0xb8
+ #define MSDC_PAD_TUNE    0xec
+ #define MSDC_PAD_TUNE0   0xf0
+ #define PAD_DS_TUNE      0x188
+@@ -216,11 +217,20 @@
+ #define MSDC_PATCH_BIT_SPCPUSH    (0x1 << 29)	/* RW */
+ #define MSDC_PATCH_BIT_DECRCTMO   (0x1 << 30)	/* RW */
+ 
++#define MSDC_PATCH_BIT2_CFGRESP   (0x1 << 15)   /* RW */
++#define MSDC_PATCH_BIT2_CFGCRCSTS (0x1 << 28)   /* RW */
++#define MSDC_PB2_RESPWAIT         (0x3 << 2)    /* RW */
++#define MSDC_PB2_RESPSTSENSEL     (0x7 << 16)   /* RW */
++#define MSDC_PB2_CRCSTSENSEL      (0x7 << 29)   /* RW */
++
+ #define MSDC_PAD_TUNE_DATWRDLY	  (0x1f <<  0)	/* RW */
+ #define MSDC_PAD_TUNE_DATRRDLY	  (0x1f <<  8)	/* RW */
+ #define MSDC_PAD_TUNE_CMDRDLY	  (0x1f << 16)  /* RW */
+ #define MSDC_PAD_TUNE_CMDRRDLY	  (0x1f << 22)	/* RW */
+ #define MSDC_PAD_TUNE_CLKTDLY	  (0x1f << 27)  /* RW */
++#define MSDC_PAD_TUNE_RXDLYSEL	  (0x1 << 15)   /* RW */
++#define MSDC_PAD_TUNE_RD_SEL	  (0x1 << 13)   /* RW */
++#define MSDC_PAD_TUNE_CMD_SEL	  (0x1 << 21)   /* RW */
+ 
+ #define PAD_DS_TUNE_DLY1	  (0x1f << 2)   /* RW */
+ #define PAD_DS_TUNE_DLY2	  (0x1f << 7)   /* RW */
+@@ -294,6 +304,7 @@ struct msdc_save_para {
+ 	u32 pad_tune;
+ 	u32 patch_bit0;
+ 	u32 patch_bit1;
++	u32 patch_bit2;
+ 	u32 pad_ds_tune;
+ 	u32 pad_cmd_tune;
+ 	u32 emmc50_cfg0;
+@@ -303,6 +314,8 @@ struct mtk_mmc_compatible {
+ 	u8 clk_div_bits;
+ 	bool hs400_tune; /* only used for MT8173 */
+ 	u32 pad_tune_reg;
++	bool async_fifo;
++	bool data_tune;
+ };
+ 
+ struct msdc_tune_para {
+@@ -365,24 +378,32 @@ static const struct mtk_mmc_compatible mt8135_compat = {
+ 	.clk_div_bits = 8,
+ 	.hs400_tune = false,
+ 	.pad_tune_reg = MSDC_PAD_TUNE,
++	.async_fifo = false,
++	.data_tune = false,
+ };
+ 
+ static const struct mtk_mmc_compatible mt8173_compat = {
+ 	.clk_div_bits = 8,
+ 	.hs400_tune = true,
+ 	.pad_tune_reg = MSDC_PAD_TUNE,
++	.async_fifo = false,
++	.data_tune = false,
+ };
+ 
+ static const struct mtk_mmc_compatible mt2701_compat = {
+ 	.clk_div_bits = 12,
+ 	.hs400_tune = false,
+ 	.pad_tune_reg = MSDC_PAD_TUNE0,
++	.async_fifo = true,
++	.data_tune = true,
+ };
+ 
+ static const struct mtk_mmc_compatible mt2712_compat = {
+ 	.clk_div_bits = 12,
+ 	.hs400_tune = false,
+ 	.pad_tune_reg = MSDC_PAD_TUNE0,
++	.async_fifo = true,
++	.data_tune = true,
+ };
+ 
+ static const struct of_device_id msdc_of_ids[] = {
+@@ -1252,8 +1273,29 @@ static void msdc_init_hw(struct msdc_host *host)
+ 	sdr_set_field(host->base + MSDC_IOCON, MSDC_IOCON_DDLSEL, 0);
+ 	writel(0x403c0046, host->base + MSDC_PATCH_BIT);
+ 	sdr_set_field(host->base + MSDC_PATCH_BIT, MSDC_CKGEN_MSDC_DLY_SEL, 1);
+-	writel(0xffff0089, host->base + MSDC_PATCH_BIT1);
++	writel(0xffff4089, host->base + MSDC_PATCH_BIT1);
+ 	sdr_set_bits(host->base + EMMC50_CFG0, EMMC50_CFG_CFCSTS_SEL);
++	if (host->dev_comp->async_fifo) {
++		sdr_set_field(host->base + MSDC_PATCH_BIT2,
++			      MSDC_PB2_RESPWAIT, 3);
++		sdr_set_field(host->base + MSDC_PATCH_BIT2,
++			      MSDC_PB2_RESPSTSENSEL, 2);
++		sdr_set_field(host->base + MSDC_PATCH_BIT2,
++			      MSDC_PB2_CRCSTSENSEL, 2);
++		/* use async fifo, then no need tune internal delay */
++		sdr_clr_bits(host->base + MSDC_PATCH_BIT2,
++			     MSDC_PATCH_BIT2_CFGRESP);
++		sdr_set_bits(host->base + MSDC_PATCH_BIT2,
++			     MSDC_PATCH_BIT2_CFGCRCSTS);
++	}
++
++	if (host->dev_comp->data_tune) {
++		sdr_set_bits(host->base + tune_reg,
++			     MSDC_PAD_TUNE_RD_SEL | MSDC_PAD_TUNE_CMD_SEL);
++	} else {
++		/* choose clock tune */
++		sdr_set_bits(host->base + tune_reg, MSDC_PAD_TUNE_RXDLYSEL);
++	}
+ 
+ 	/* Configure to enable SDIO mode.
+ 	 * it's must otherwise sdio cmd5 failed
+@@ -1268,6 +1310,8 @@ static void msdc_init_hw(struct msdc_host *host)
+ 
+ 	host->def_tune_para.iocon = readl(host->base + MSDC_IOCON);
+ 	host->def_tune_para.pad_tune = readl(host->base + tune_reg);
++	host->saved_tune_para.iocon = readl(host->base + MSDC_IOCON);
++	host->saved_tune_para.pad_tune = readl(host->base + tune_reg);
+ 	dev_dbg(host->dev, "init hardware done!");
+ }
+ 
+@@ -1480,7 +1524,7 @@ static int msdc_tune_response(struct mmc_host *mmc, u32 opcode)
+ 			      final_fall_delay.final_phase);
+ 		final_delay = final_fall_delay.final_phase;
+ 	}
+-	if (host->hs200_cmd_int_delay)
++	if (host->dev_comp->async_fifo || host->hs200_cmd_int_delay)
+ 		goto skip_internal;
+ 
+ 	for (i = 0; i < PAD_DELAY_MAX; i++) {
+@@ -1638,6 +1682,8 @@ static int msdc_prepare_hs400_tuning(struct mmc_host *mmc, struct mmc_ios *ios)
+ 	host->hs400_mode = true;
+ 
+ 	writel(host->hs400_ds_delay, host->base + PAD_DS_TUNE);
++	/* hs400 mode must set it to 0 */
++	sdr_clr_bits(host->base + MSDC_PATCH_BIT2, MSDC_PATCH_BIT2_CFGCRCSTS);
+ 	return 0;
+ }
+ 
+@@ -1876,6 +1922,7 @@ static void msdc_save_reg(struct msdc_host *host)
+ 	host->save_para.pad_tune = readl(host->base + tune_reg);
+ 	host->save_para.patch_bit0 = readl(host->base + MSDC_PATCH_BIT);
+ 	host->save_para.patch_bit1 = readl(host->base + MSDC_PATCH_BIT1);
++	host->save_para.patch_bit2 = readl(host->base + MSDC_PATCH_BIT2);
+ 	host->save_para.pad_ds_tune = readl(host->base + PAD_DS_TUNE);
+ 	host->save_para.pad_cmd_tune = readl(host->base + PAD_CMD_TUNE);
+ 	host->save_para.emmc50_cfg0 = readl(host->base + EMMC50_CFG0);
+@@ -1891,6 +1938,7 @@ static void msdc_restore_reg(struct msdc_host *host)
+ 	writel(host->save_para.pad_tune, host->base + tune_reg);
+ 	writel(host->save_para.patch_bit0, host->base + MSDC_PATCH_BIT);
+ 	writel(host->save_para.patch_bit1, host->base + MSDC_PATCH_BIT1);
++	writel(host->save_para.patch_bit2, host->base + MSDC_PATCH_BIT2);
+ 	writel(host->save_para.pad_ds_tune, host->base + PAD_DS_TUNE);
+ 	writel(host->save_para.pad_cmd_tune, host->base + PAD_CMD_TUNE);
+ 	writel(host->save_para.emmc50_cfg0, host->base + EMMC50_CFG0);
+-- 
+2.11.0
+
diff --git a/target/linux/mediatek/patches-4.14/0155-mmc-mediatek-add-busy_check-support.patch b/target/linux/mediatek/patches-4.14/0155-mmc-mediatek-add-busy_check-support.patch
new file mode 100644
index 0000000000..1e7aa7e7d7
--- /dev/null
+++ b/target/linux/mediatek/patches-4.14/0155-mmc-mediatek-add-busy_check-support.patch
@@ -0,0 +1,72 @@
+From 788d269aee4c612d5cd97b896ea5d22f19137097 Mon Sep 17 00:00:00 2001
+From: Chaotian Jing <chaotian.jing@mediatek.com>
+Date: Mon, 16 Oct 2017 09:46:34 +0800
+Subject: [PATCH 155/224] mmc: mediatek: add busy_check support
+
+bit7 of PATCH_BIT1 has different meaning in new design, to
+compatible with previous platform, clear this bit in new
+platform.
+
+Signed-off-by: Chaotian Jing <chaotian.jing@mediatek.com>
+Tested-by: Sean Wang <sean.wang@mediatek.com>
+Signed-off-by: Ulf Hansson <ulf.hansson@linaro.org>
+---
+ drivers/mmc/host/mtk-sd.c | 7 +++++++
+ 1 file changed, 7 insertions(+)
+
+diff --git a/drivers/mmc/host/mtk-sd.c b/drivers/mmc/host/mtk-sd.c
+index 8113bacc1540..eceaee86ba4d 100644
+--- a/drivers/mmc/host/mtk-sd.c
++++ b/drivers/mmc/host/mtk-sd.c
+@@ -316,6 +316,7 @@ struct mtk_mmc_compatible {
+ 	u32 pad_tune_reg;
+ 	bool async_fifo;
+ 	bool data_tune;
++	bool busy_check;
+ };
+ 
+ struct msdc_tune_para {
+@@ -380,6 +381,7 @@ static const struct mtk_mmc_compatible mt8135_compat = {
+ 	.pad_tune_reg = MSDC_PAD_TUNE,
+ 	.async_fifo = false,
+ 	.data_tune = false,
++	.busy_check = false,
+ };
+ 
+ static const struct mtk_mmc_compatible mt8173_compat = {
+@@ -388,6 +390,7 @@ static const struct mtk_mmc_compatible mt8173_compat = {
+ 	.pad_tune_reg = MSDC_PAD_TUNE,
+ 	.async_fifo = false,
+ 	.data_tune = false,
++	.busy_check = false,
+ };
+ 
+ static const struct mtk_mmc_compatible mt2701_compat = {
+@@ -396,6 +399,7 @@ static const struct mtk_mmc_compatible mt2701_compat = {
+ 	.pad_tune_reg = MSDC_PAD_TUNE0,
+ 	.async_fifo = true,
+ 	.data_tune = true,
++	.busy_check = false,
+ };
+ 
+ static const struct mtk_mmc_compatible mt2712_compat = {
+@@ -404,6 +408,7 @@ static const struct mtk_mmc_compatible mt2712_compat = {
+ 	.pad_tune_reg = MSDC_PAD_TUNE0,
+ 	.async_fifo = true,
+ 	.data_tune = true,
++	.busy_check = true,
+ };
+ 
+ static const struct of_device_id msdc_of_ids[] = {
+@@ -1275,6 +1280,8 @@ static void msdc_init_hw(struct msdc_host *host)
+ 	sdr_set_field(host->base + MSDC_PATCH_BIT, MSDC_CKGEN_MSDC_DLY_SEL, 1);
+ 	writel(0xffff4089, host->base + MSDC_PATCH_BIT1);
+ 	sdr_set_bits(host->base + EMMC50_CFG0, EMMC50_CFG_CFCSTS_SEL);
++	if (host->dev_comp->busy_check)
++		sdr_clr_bits(host->base + MSDC_PATCH_BIT1, (1 << 7));
+ 	if (host->dev_comp->async_fifo) {
+ 		sdr_set_field(host->base + MSDC_PATCH_BIT2,
+ 			      MSDC_PB2_RESPWAIT, 3);
+-- 
+2.11.0
+
diff --git a/target/linux/mediatek/patches-4.14/0156-mmc-mediatek-add-stop_clk-fix-and-enhance_rx-support.patch b/target/linux/mediatek/patches-4.14/0156-mmc-mediatek-add-stop_clk-fix-and-enhance_rx-support.patch
new file mode 100644
index 0000000000..04c4ca5216
--- /dev/null
+++ b/target/linux/mediatek/patches-4.14/0156-mmc-mediatek-add-stop_clk-fix-and-enhance_rx-support.patch
@@ -0,0 +1,173 @@
+From 9257240bcaf8f9ee6878357e00e7ab511ad6d325 Mon Sep 17 00:00:00 2001
+From: Chaotian Jing <chaotian.jing@mediatek.com>
+Date: Mon, 16 Oct 2017 09:46:35 +0800
+Subject: [PATCH 156/224] mmc: mediatek: add stop_clk fix and enhance_rx
+ support
+
+mt2712 supports stop_clk fix and enhance_rx, which can improve
+host stability.
+
+Signed-off-by: Chaotian Jing <chaotian.jing@mediatek.com>
+Tested-by: Sean Wang <sean.wang@mediatek.com>
+Signed-off-by: Ulf Hansson <ulf.hansson@linaro.org>
+---
+ drivers/mmc/host/mtk-sd.c | 47 +++++++++++++++++++++++++++++++++++++++++++----
+ 1 file changed, 43 insertions(+), 4 deletions(-)
+
+diff --git a/drivers/mmc/host/mtk-sd.c b/drivers/mmc/host/mtk-sd.c
+index eceaee86ba4d..94d16a3a8d94 100644
+--- a/drivers/mmc/host/mtk-sd.c
++++ b/drivers/mmc/host/mtk-sd.c
+@@ -67,6 +67,7 @@
+ #define SDC_RESP2        0x48
+ #define SDC_RESP3        0x4c
+ #define SDC_BLK_NUM      0x50
++#define SDC_ADV_CFG0     0x64
+ #define EMMC_IOCON       0x7c
+ #define SDC_ACMD_RESP    0x80
+ #define MSDC_DMA_SA      0x90
+@@ -80,6 +81,7 @@
+ #define PAD_DS_TUNE      0x188
+ #define PAD_CMD_TUNE     0x18c
+ #define EMMC50_CFG0      0x208
++#define SDC_FIFO_CFG     0x228
+ 
+ /*--------------------------------------------------------------------------*/
+ /* Register Mask                                                            */
+@@ -188,6 +190,9 @@
+ #define SDC_STS_CMDBUSY         (0x1 << 1)	/* RW */
+ #define SDC_STS_SWR_COMPL       (0x1 << 31)	/* RW */
+ 
++/* SDC_ADV_CFG0 mask */
++#define SDC_RX_ENHANCE_EN	(0x1 << 20)	/* RW */
++
+ /* MSDC_DMA_CTRL mask */
+ #define MSDC_DMA_CTRL_START     (0x1 << 0)	/* W */
+ #define MSDC_DMA_CTRL_STOP      (0x1 << 1)	/* W */
+@@ -217,6 +222,8 @@
+ #define MSDC_PATCH_BIT_SPCPUSH    (0x1 << 29)	/* RW */
+ #define MSDC_PATCH_BIT_DECRCTMO   (0x1 << 30)	/* RW */
+ 
++#define MSDC_PATCH_BIT1_STOP_DLY  (0xf << 8)    /* RW */
++
+ #define MSDC_PATCH_BIT2_CFGRESP   (0x1 << 15)   /* RW */
+ #define MSDC_PATCH_BIT2_CFGCRCSTS (0x1 << 28)   /* RW */
+ #define MSDC_PB2_RESPWAIT         (0x3 << 2)    /* RW */
+@@ -242,6 +249,9 @@
+ #define EMMC50_CFG_CRCSTS_EDGE    (0x1 << 3)   /* RW */
+ #define EMMC50_CFG_CFCSTS_SEL     (0x1 << 4)   /* RW */
+ 
++#define SDC_FIFO_CFG_WRVALIDSEL   (0x1 << 24)  /* RW */
++#define SDC_FIFO_CFG_RDVALIDSEL   (0x1 << 25)  /* RW */
++
+ #define REQ_CMD_EIO  (0x1 << 0)
+ #define REQ_CMD_TMO  (0x1 << 1)
+ #define REQ_DAT_ERR  (0x1 << 2)
+@@ -308,6 +318,7 @@ struct msdc_save_para {
+ 	u32 pad_ds_tune;
+ 	u32 pad_cmd_tune;
+ 	u32 emmc50_cfg0;
++	u32 sdc_fifo_cfg;
+ };
+ 
+ struct mtk_mmc_compatible {
+@@ -317,6 +328,8 @@ struct mtk_mmc_compatible {
+ 	bool async_fifo;
+ 	bool data_tune;
+ 	bool busy_check;
++	bool stop_clk_fix;
++	bool enhance_rx;
+ };
+ 
+ struct msdc_tune_para {
+@@ -382,6 +395,8 @@ static const struct mtk_mmc_compatible mt8135_compat = {
+ 	.async_fifo = false,
+ 	.data_tune = false,
+ 	.busy_check = false,
++	.stop_clk_fix = false,
++	.enhance_rx = false,
+ };
+ 
+ static const struct mtk_mmc_compatible mt8173_compat = {
+@@ -391,6 +406,8 @@ static const struct mtk_mmc_compatible mt8173_compat = {
+ 	.async_fifo = false,
+ 	.data_tune = false,
+ 	.busy_check = false,
++	.stop_clk_fix = false,
++	.enhance_rx = false,
+ };
+ 
+ static const struct mtk_mmc_compatible mt2701_compat = {
+@@ -400,6 +417,8 @@ static const struct mtk_mmc_compatible mt2701_compat = {
+ 	.async_fifo = true,
+ 	.data_tune = true,
+ 	.busy_check = false,
++	.stop_clk_fix = false,
++	.enhance_rx = false,
+ };
+ 
+ static const struct mtk_mmc_compatible mt2712_compat = {
+@@ -409,6 +428,8 @@ static const struct mtk_mmc_compatible mt2712_compat = {
+ 	.async_fifo = true,
+ 	.data_tune = true,
+ 	.busy_check = true,
++	.stop_clk_fix = true,
++	.enhance_rx = true,
+ };
+ 
+ static const struct of_device_id msdc_of_ids[] = {
+@@ -1280,15 +1301,31 @@ static void msdc_init_hw(struct msdc_host *host)
+ 	sdr_set_field(host->base + MSDC_PATCH_BIT, MSDC_CKGEN_MSDC_DLY_SEL, 1);
+ 	writel(0xffff4089, host->base + MSDC_PATCH_BIT1);
+ 	sdr_set_bits(host->base + EMMC50_CFG0, EMMC50_CFG_CFCSTS_SEL);
++
++	if (host->dev_comp->stop_clk_fix) {
++		sdr_set_field(host->base + MSDC_PATCH_BIT1,
++			      MSDC_PATCH_BIT1_STOP_DLY, 3);
++		sdr_clr_bits(host->base + SDC_FIFO_CFG,
++			     SDC_FIFO_CFG_WRVALIDSEL);
++		sdr_clr_bits(host->base + SDC_FIFO_CFG,
++			     SDC_FIFO_CFG_RDVALIDSEL);
++	}
++
+ 	if (host->dev_comp->busy_check)
+ 		sdr_clr_bits(host->base + MSDC_PATCH_BIT1, (1 << 7));
++
+ 	if (host->dev_comp->async_fifo) {
+ 		sdr_set_field(host->base + MSDC_PATCH_BIT2,
+ 			      MSDC_PB2_RESPWAIT, 3);
+-		sdr_set_field(host->base + MSDC_PATCH_BIT2,
+-			      MSDC_PB2_RESPSTSENSEL, 2);
+-		sdr_set_field(host->base + MSDC_PATCH_BIT2,
+-			      MSDC_PB2_CRCSTSENSEL, 2);
++		if (host->dev_comp->enhance_rx) {
++			sdr_set_bits(host->base + SDC_ADV_CFG0,
++				     SDC_RX_ENHANCE_EN);
++		} else {
++			sdr_set_field(host->base + MSDC_PATCH_BIT2,
++				      MSDC_PB2_RESPSTSENSEL, 2);
++			sdr_set_field(host->base + MSDC_PATCH_BIT2,
++				      MSDC_PB2_CRCSTSENSEL, 2);
++		}
+ 		/* use async fifo, then no need tune internal delay */
+ 		sdr_clr_bits(host->base + MSDC_PATCH_BIT2,
+ 			     MSDC_PATCH_BIT2_CFGRESP);
+@@ -1933,6 +1970,7 @@ static void msdc_save_reg(struct msdc_host *host)
+ 	host->save_para.pad_ds_tune = readl(host->base + PAD_DS_TUNE);
+ 	host->save_para.pad_cmd_tune = readl(host->base + PAD_CMD_TUNE);
+ 	host->save_para.emmc50_cfg0 = readl(host->base + EMMC50_CFG0);
++	host->save_para.sdc_fifo_cfg = readl(host->base + SDC_FIFO_CFG);
+ }
+ 
+ static void msdc_restore_reg(struct msdc_host *host)
+@@ -1949,6 +1987,7 @@ static void msdc_restore_reg(struct msdc_host *host)
+ 	writel(host->save_para.pad_ds_tune, host->base + PAD_DS_TUNE);
+ 	writel(host->save_para.pad_cmd_tune, host->base + PAD_CMD_TUNE);
+ 	writel(host->save_para.emmc50_cfg0, host->base + EMMC50_CFG0);
++	writel(host->save_para.sdc_fifo_cfg, host->base + SDC_FIFO_CFG);
+ }
+ 
+ static int msdc_runtime_suspend(struct device *dev)
+-- 
+2.11.0
+
diff --git a/target/linux/mediatek/patches-4.14/0157-mmc-mediatek-add-support-of-source_cg-clock.patch b/target/linux/mediatek/patches-4.14/0157-mmc-mediatek-add-support-of-source_cg-clock.patch
new file mode 100644
index 0000000000..89cb7c8617
--- /dev/null
+++ b/target/linux/mediatek/patches-4.14/0157-mmc-mediatek-add-support-of-source_cg-clock.patch
@@ -0,0 +1,90 @@
+From 3c6b94d7091f0793445f2faf777e584af643e9da Mon Sep 17 00:00:00 2001
+From: Chaotian Jing <chaotian.jing@mediatek.com>
+Date: Mon, 16 Oct 2017 09:46:36 +0800
+Subject: [PATCH 157/224] mmc: mediatek: add support of source_cg clock
+
+source clock need an independent cg to control, when doing clk mode
+switch, need gate source clock to avoid hw issue(multi-bit sync hw hang)
+
+Signed-off-by: Chaotian Jing <chaotian.jing@mediatek.com>
+Tested-by: Sean Wang <sean.wang@mediatek.com>
+Signed-off-by: Ulf Hansson <ulf.hansson@linaro.org>
+---
+ drivers/mmc/host/mtk-sd.c | 23 ++++++++++++++++++++++-
+ 1 file changed, 22 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/mmc/host/mtk-sd.c b/drivers/mmc/host/mtk-sd.c
+index 94d16a3a8d94..a2f26c9b17b4 100644
+--- a/drivers/mmc/host/mtk-sd.c
++++ b/drivers/mmc/host/mtk-sd.c
+@@ -372,6 +372,7 @@ struct msdc_host {
+ 
+ 	struct clk *src_clk;	/* msdc source clock */
+ 	struct clk *h_clk;      /* msdc h_clk */
++	struct clk *src_clk_cg; /* msdc source clock control gate */
+ 	u32 mclk;		/* mmc subsystem clock frequency */
+ 	u32 src_clk_freq;	/* source clock frequency */
+ 	u32 sclk;		/* SD/MS bus clock frequency */
+@@ -616,6 +617,7 @@ static void msdc_set_timeout(struct msdc_host *host, u32 ns, u32 clks)
+ 
+ static void msdc_gate_clock(struct msdc_host *host)
+ {
++	clk_disable_unprepare(host->src_clk_cg);
+ 	clk_disable_unprepare(host->src_clk);
+ 	clk_disable_unprepare(host->h_clk);
+ }
+@@ -624,6 +626,7 @@ static void msdc_ungate_clock(struct msdc_host *host)
+ {
+ 	clk_prepare_enable(host->h_clk);
+ 	clk_prepare_enable(host->src_clk);
++	clk_prepare_enable(host->src_clk_cg);
+ 	while (!(readl(host->base + MSDC_CFG) & MSDC_CFG_CKSTB))
+ 		cpu_relax();
+ }
+@@ -692,6 +695,15 @@ static void msdc_set_mclk(struct msdc_host *host, unsigned char timing, u32 hz)
+ 			sclk = (host->src_clk_freq >> 2) / div;
+ 		}
+ 	}
++	sdr_clr_bits(host->base + MSDC_CFG, MSDC_CFG_CKPDN);
++	/*
++	 * As src_clk/HCLK use the same bit to gate/ungate,
++	 * So if want to only gate src_clk, need gate its parent(mux).
++	 */
++	if (host->src_clk_cg)
++		clk_disable_unprepare(host->src_clk_cg);
++	else
++		clk_disable_unprepare(clk_get_parent(host->src_clk));
+ 	if (host->dev_comp->clk_div_bits == 8)
+ 		sdr_set_field(host->base + MSDC_CFG,
+ 			      MSDC_CFG_CKMOD | MSDC_CFG_CKDIV,
+@@ -700,10 +712,14 @@ static void msdc_set_mclk(struct msdc_host *host, unsigned char timing, u32 hz)
+ 		sdr_set_field(host->base + MSDC_CFG,
+ 			      MSDC_CFG_CKMOD_EXTRA | MSDC_CFG_CKDIV_EXTRA,
+ 			      (mode << 12) | div);
++	if (host->src_clk_cg)
++		clk_prepare_enable(host->src_clk_cg);
++	else
++		clk_prepare_enable(clk_get_parent(host->src_clk));
+ 
+-	sdr_set_bits(host->base + MSDC_CFG, MSDC_CFG_CKPDN);
+ 	while (!(readl(host->base + MSDC_CFG) & MSDC_CFG_CKSTB))
+ 		cpu_relax();
++	sdr_set_bits(host->base + MSDC_CFG, MSDC_CFG_CKPDN);
+ 	host->sclk = sclk;
+ 	host->mclk = hz;
+ 	host->timing = timing;
+@@ -1822,6 +1838,11 @@ static int msdc_drv_probe(struct platform_device *pdev)
+ 		goto host_free;
+ 	}
+ 
++	/*source clock control gate is optional clock*/
++	host->src_clk_cg = devm_clk_get(&pdev->dev, "source_cg");
++	if (IS_ERR(host->src_clk_cg))
++		host->src_clk_cg = NULL;
++
+ 	host->irq = platform_get_irq(pdev, 0);
+ 	if (host->irq < 0) {
+ 		ret = -EINVAL;
+-- 
+2.11.0
+
diff --git a/target/linux/mediatek/patches-4.14/0158-mmc-mediatek-add-latch-ck-support.patch b/target/linux/mediatek/patches-4.14/0158-mmc-mediatek-add-latch-ck-support.patch
new file mode 100644
index 0000000000..c2c00e8712
--- /dev/null
+++ b/target/linux/mediatek/patches-4.14/0158-mmc-mediatek-add-latch-ck-support.patch
@@ -0,0 +1,50 @@
+From de14d1d0dc7ecf5c3e7e2a591b4f14e688fa52e6 Mon Sep 17 00:00:00 2001
+From: Chaotian Jing <chaotian.jing@mediatek.com>
+Date: Mon, 16 Oct 2017 09:46:37 +0800
+Subject: [PATCH 158/224] mmc: mediatek: add latch-ck support
+
+some platform(eg.mt2701) does not support "stop clk fix", in
+this case, need set correct latch-ck to avoid crc error caused
+by stop clock block-internally.
+
+Signed-off-by: Chaotian Jing <chaotian.jing@mediatek.com>
+Tested-by: Sean Wang <sean.wang@mediatek.com>
+Signed-off-by: Ulf Hansson <ulf.hansson@linaro.org>
+---
+ drivers/mmc/host/mtk-sd.c | 6 ++++++
+ 1 file changed, 6 insertions(+)
+
+diff --git a/drivers/mmc/host/mtk-sd.c b/drivers/mmc/host/mtk-sd.c
+index a2f26c9b17b4..d75a93d6803f 100644
+--- a/drivers/mmc/host/mtk-sd.c
++++ b/drivers/mmc/host/mtk-sd.c
+@@ -378,6 +378,7 @@ struct msdc_host {
+ 	u32 sclk;		/* SD/MS bus clock frequency */
+ 	unsigned char timing;
+ 	bool vqmmc_enabled;
++	u32 latch_ck;
+ 	u32 hs400_ds_delay;
+ 	u32 hs200_cmd_int_delay; /* cmd internal delay for HS200/SDR104 */
+ 	u32 hs400_cmd_int_delay; /* cmd internal delay for HS400 */
+@@ -1661,6 +1662,8 @@ static int msdc_tune_data(struct mmc_host *mmc, u32 opcode)
+ 	u32 tune_reg = host->dev_comp->pad_tune_reg;
+ 	int i, ret;
+ 
++	sdr_set_field(host->base + MSDC_PATCH_BIT, MSDC_INT_DAT_LATCH_CK_SEL,
++		      host->latch_ck);
+ 	sdr_clr_bits(host->base + MSDC_IOCON, MSDC_IOCON_DSPL);
+ 	sdr_clr_bits(host->base + MSDC_IOCON, MSDC_IOCON_W_DSPL);
+ 	for (i = 0 ; i < PAD_DELAY_MAX; i++) {
+@@ -1773,6 +1776,9 @@ static const struct mmc_host_ops mt_msdc_ops = {
+ static void msdc_of_property_parse(struct platform_device *pdev,
+ 				   struct msdc_host *host)
+ {
++	of_property_read_u32(pdev->dev.of_node, "mediatek,latch-ck",
++			     &host->latch_ck);
++
+ 	of_property_read_u32(pdev->dev.of_node, "hs400-ds-delay",
+ 			     &host->hs400_ds_delay);
+ 
+-- 
+2.11.0
+
diff --git a/target/linux/mediatek/patches-4.14/0159-mmc-mediatek-improve-eMMC-hs400-mode-read-performanc.patch b/target/linux/mediatek/patches-4.14/0159-mmc-mediatek-improve-eMMC-hs400-mode-read-performanc.patch
new file mode 100644
index 0000000000..9fd4f553ec
--- /dev/null
+++ b/target/linux/mediatek/patches-4.14/0159-mmc-mediatek-improve-eMMC-hs400-mode-read-performanc.patch
@@ -0,0 +1,73 @@
+From 29e154716049310bb8c559f742bf2b460d5b6bbc Mon Sep 17 00:00:00 2001
+From: Chaotian Jing <chaotian.jing@mediatek.com>
+Date: Mon, 16 Oct 2017 09:46:38 +0800
+Subject: [PATCH 159/224] mmc: mediatek: improve eMMC hs400 mode read
+ performance
+
+enlarge outstanding value to improve read performance
+
+Signed-off-by: Chaotian Jing <chaotian.jing@mediatek.com>
+Tested-by: Sean Wang <sean.wang@mediatek.com>
+Signed-off-by: Ulf Hansson <ulf.hansson@linaro.org>
+---
+ drivers/mmc/host/mtk-sd.c | 9 +++++++++
+ 1 file changed, 9 insertions(+)
+
+diff --git a/drivers/mmc/host/mtk-sd.c b/drivers/mmc/host/mtk-sd.c
+index d75a93d6803f..95759bba0dd0 100644
+--- a/drivers/mmc/host/mtk-sd.c
++++ b/drivers/mmc/host/mtk-sd.c
+@@ -81,6 +81,7 @@
+ #define PAD_DS_TUNE      0x188
+ #define PAD_CMD_TUNE     0x18c
+ #define EMMC50_CFG0      0x208
++#define EMMC50_CFG3      0x220
+ #define SDC_FIFO_CFG     0x228
+ 
+ /*--------------------------------------------------------------------------*/
+@@ -249,6 +250,8 @@
+ #define EMMC50_CFG_CRCSTS_EDGE    (0x1 << 3)   /* RW */
+ #define EMMC50_CFG_CFCSTS_SEL     (0x1 << 4)   /* RW */
+ 
++#define EMMC50_CFG3_OUTS_WR       (0x1f << 0)  /* RW */
++
+ #define SDC_FIFO_CFG_WRVALIDSEL   (0x1 << 24)  /* RW */
+ #define SDC_FIFO_CFG_RDVALIDSEL   (0x1 << 25)  /* RW */
+ 
+@@ -318,6 +321,7 @@ struct msdc_save_para {
+ 	u32 pad_ds_tune;
+ 	u32 pad_cmd_tune;
+ 	u32 emmc50_cfg0;
++	u32 emmc50_cfg3;
+ 	u32 sdc_fifo_cfg;
+ };
+ 
+@@ -1747,6 +1751,9 @@ static int msdc_prepare_hs400_tuning(struct mmc_host *mmc, struct mmc_ios *ios)
+ 	writel(host->hs400_ds_delay, host->base + PAD_DS_TUNE);
+ 	/* hs400 mode must set it to 0 */
+ 	sdr_clr_bits(host->base + MSDC_PATCH_BIT2, MSDC_PATCH_BIT2_CFGCRCSTS);
++	/* to improve read performance, set outstanding to 2 */
++	sdr_set_field(host->base + EMMC50_CFG3, EMMC50_CFG3_OUTS_WR, 2);
++
+ 	return 0;
+ }
+ 
+@@ -1997,6 +2004,7 @@ static void msdc_save_reg(struct msdc_host *host)
+ 	host->save_para.pad_ds_tune = readl(host->base + PAD_DS_TUNE);
+ 	host->save_para.pad_cmd_tune = readl(host->base + PAD_CMD_TUNE);
+ 	host->save_para.emmc50_cfg0 = readl(host->base + EMMC50_CFG0);
++	host->save_para.emmc50_cfg3 = readl(host->base + EMMC50_CFG3);
+ 	host->save_para.sdc_fifo_cfg = readl(host->base + SDC_FIFO_CFG);
+ }
+ 
+@@ -2014,6 +2022,7 @@ static void msdc_restore_reg(struct msdc_host *host)
+ 	writel(host->save_para.pad_ds_tune, host->base + PAD_DS_TUNE);
+ 	writel(host->save_para.pad_cmd_tune, host->base + PAD_CMD_TUNE);
+ 	writel(host->save_para.emmc50_cfg0, host->base + EMMC50_CFG0);
++	writel(host->save_para.emmc50_cfg3, host->base + EMMC50_CFG3);
+ 	writel(host->save_para.sdc_fifo_cfg, host->base + SDC_FIFO_CFG);
+ }
+ 
+-- 
+2.11.0
+
diff --git a/target/linux/mediatek/patches-4.14/0160-mmc-mediatek-perfer-to-use-rise-edge-latching-for-cm.patch b/target/linux/mediatek/patches-4.14/0160-mmc-mediatek-perfer-to-use-rise-edge-latching-for-cm.patch
new file mode 100644
index 0000000000..c34bf12445
--- /dev/null
+++ b/target/linux/mediatek/patches-4.14/0160-mmc-mediatek-perfer-to-use-rise-edge-latching-for-cm.patch
@@ -0,0 +1,33 @@
+From 81fdc4983e33ef01935a9bf01187951aad34e2ac Mon Sep 17 00:00:00 2001
+From: Chaotian Jing <chaotian.jing@mediatek.com>
+Date: Mon, 16 Oct 2017 09:46:39 +0800
+Subject: [PATCH 160/224] mmc: mediatek: perfer to use rise edge latching for
+ cmd line
+
+data lines have applied to perfer to use rise edge, also need
+apply it to cmd line.
+
+Signed-off-by: Chaotian Jing <chaotian.jing@mediatek.com>
+Tested-by: Sean Wang <sean.wang@mediatek.com>
+Signed-off-by: Ulf Hansson <ulf.hansson@linaro.org>
+---
+ drivers/mmc/host/mtk-sd.c | 3 ++-
+ 1 file changed, 2 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/mmc/host/mtk-sd.c b/drivers/mmc/host/mtk-sd.c
+index 95759bba0dd0..27a62254f12f 100644
+--- a/drivers/mmc/host/mtk-sd.c
++++ b/drivers/mmc/host/mtk-sd.c
+@@ -1550,7 +1550,8 @@ static int msdc_tune_response(struct mmc_host *mmc, u32 opcode)
+ 	}
+ 	final_rise_delay = get_best_delay(host, rise_delay);
+ 	/* if rising edge has enough margin, then do not scan falling edge */
+-	if (final_rise_delay.maxlen >= 12 && final_rise_delay.start < 4)
++	if (final_rise_delay.maxlen >= 12 ||
++	    (final_rise_delay.start == 0 && final_rise_delay.maxlen >= 4))
+ 		goto skip_fall;
+ 
+ 	sdr_set_bits(host->base + MSDC_IOCON, MSDC_IOCON_RSPL);
+-- 
+2.11.0
+
diff --git a/target/linux/mediatek/patches-4.14/0161-pwm-mediatek-Add-MT2712-MT7622-support.patch b/target/linux/mediatek/patches-4.14/0161-pwm-mediatek-Add-MT2712-MT7622-support.patch
new file mode 100644
index 0000000000..2d91ab98a9
--- /dev/null
+++ b/target/linux/mediatek/patches-4.14/0161-pwm-mediatek-Add-MT2712-MT7622-support.patch
@@ -0,0 +1,150 @@
+From 7cc8226e45b2c6b9f06ce82ba6995b8f911afe25 Mon Sep 17 00:00:00 2001
+From: Zhi Mao <zhi.mao@mediatek.com>
+Date: Wed, 25 Oct 2017 18:11:01 +0800
+Subject: [PATCH 161/224] pwm: mediatek: Add MT2712/MT7622 support
+
+Add support for MT2712 and MT7622. Due to register offset address of
+pwm7 for MT2712 is not fixed 0x40, add mtk_pwm_reg_offset array for PWM
+register offset.
+
+Reviewed-by: Claudiu Beznea <claudiu.beznea@microchip.com>
+Reviewed-by: Matthias Brugger <matthias.bgg@gmail.com>
+Signed-off-by: Zhi Mao <zhi.mao@mediatek.com>
+Signed-off-by: Thierry Reding <thierry.reding@gmail.com>
+---
+ drivers/pwm/pwm-mediatek.c | 53 ++++++++++++++++++++++++++++++++++++++--------
+ 1 file changed, 44 insertions(+), 9 deletions(-)
+
+diff --git a/drivers/pwm/pwm-mediatek.c b/drivers/pwm/pwm-mediatek.c
+index b52f3afb2ba1..f5d97e0ad52b 100644
+--- a/drivers/pwm/pwm-mediatek.c
++++ b/drivers/pwm/pwm-mediatek.c
+@@ -16,6 +16,7 @@
+ #include <linux/module.h>
+ #include <linux/clk.h>
+ #include <linux/of.h>
++#include <linux/of_device.h>
+ #include <linux/platform_device.h>
+ #include <linux/pwm.h>
+ #include <linux/slab.h>
+@@ -40,11 +41,19 @@ enum {
+ 	MTK_CLK_PWM3,
+ 	MTK_CLK_PWM4,
+ 	MTK_CLK_PWM5,
++	MTK_CLK_PWM6,
++	MTK_CLK_PWM7,
++	MTK_CLK_PWM8,
+ 	MTK_CLK_MAX,
+ };
+ 
+-static const char * const mtk_pwm_clk_name[] = {
+-	"main", "top", "pwm1", "pwm2", "pwm3", "pwm4", "pwm5"
++static const char * const mtk_pwm_clk_name[MTK_CLK_MAX] = {
++	"main", "top", "pwm1", "pwm2", "pwm3", "pwm4", "pwm5", "pwm6", "pwm7",
++	"pwm8"
++};
++
++struct mtk_pwm_platform_data {
++	unsigned int num_pwms;
+ };
+ 
+ /**
+@@ -59,6 +68,10 @@ struct mtk_pwm_chip {
+ 	struct clk *clks[MTK_CLK_MAX];
+ };
+ 
++static const unsigned int mtk_pwm_reg_offset[] = {
++	0x0010, 0x0050, 0x0090, 0x00d0, 0x0110, 0x0150, 0x0190, 0x0220
++};
++
+ static inline struct mtk_pwm_chip *to_mtk_pwm_chip(struct pwm_chip *chip)
+ {
+ 	return container_of(chip, struct mtk_pwm_chip, chip);
+@@ -103,14 +116,14 @@ static void mtk_pwm_clk_disable(struct pwm_chip *chip, struct pwm_device *pwm)
+ static inline u32 mtk_pwm_readl(struct mtk_pwm_chip *chip, unsigned int num,
+ 				unsigned int offset)
+ {
+-	return readl(chip->regs + 0x10 + (num * 0x40) + offset);
++	return readl(chip->regs + mtk_pwm_reg_offset[num] + offset);
+ }
+ 
+ static inline void mtk_pwm_writel(struct mtk_pwm_chip *chip,
+ 				  unsigned int num, unsigned int offset,
+ 				  u32 value)
+ {
+-	writel(value, chip->regs + 0x10 + (num * 0x40) + offset);
++	writel(value, chip->regs + mtk_pwm_reg_offset[num] + offset);
+ }
+ 
+ static int mtk_pwm_config(struct pwm_chip *chip, struct pwm_device *pwm,
+@@ -185,6 +198,7 @@ static const struct pwm_ops mtk_pwm_ops = {
+ 
+ static int mtk_pwm_probe(struct platform_device *pdev)
+ {
++	const struct mtk_pwm_platform_data *data;
+ 	struct mtk_pwm_chip *pc;
+ 	struct resource *res;
+ 	unsigned int i;
+@@ -194,15 +208,22 @@ static int mtk_pwm_probe(struct platform_device *pdev)
+ 	if (!pc)
+ 		return -ENOMEM;
+ 
++	data = of_device_get_match_data(&pdev->dev);
++	if (data == NULL)
++		return -EINVAL;
++
+ 	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+ 	pc->regs = devm_ioremap_resource(&pdev->dev, res);
+ 	if (IS_ERR(pc->regs))
+ 		return PTR_ERR(pc->regs);
+ 
+-	for (i = 0; i < MTK_CLK_MAX; i++) {
++	for (i = 0; i < data->num_pwms + 2; i++) {
+ 		pc->clks[i] = devm_clk_get(&pdev->dev, mtk_pwm_clk_name[i]);
+-		if (IS_ERR(pc->clks[i]))
++		if (IS_ERR(pc->clks[i])) {
++			dev_err(&pdev->dev, "clock: %s fail: %ld\n",
++				mtk_pwm_clk_name[i], PTR_ERR(pc->clks[i]));
+ 			return PTR_ERR(pc->clks[i]);
++		}
+ 	}
+ 
+ 	platform_set_drvdata(pdev, pc);
+@@ -210,7 +231,7 @@ static int mtk_pwm_probe(struct platform_device *pdev)
+ 	pc->chip.dev = &pdev->dev;
+ 	pc->chip.ops = &mtk_pwm_ops;
+ 	pc->chip.base = -1;
+-	pc->chip.npwm = 5;
++	pc->chip.npwm = data->num_pwms;
+ 
+ 	ret = pwmchip_add(&pc->chip);
+ 	if (ret < 0) {
+@@ -228,9 +249,23 @@ static int mtk_pwm_remove(struct platform_device *pdev)
+ 	return pwmchip_remove(&pc->chip);
+ }
+ 
++static const struct mtk_pwm_platform_data mt2712_pwm_data = {
++	.num_pwms = 8,
++};
++
++static const struct mtk_pwm_platform_data mt7622_pwm_data = {
++	.num_pwms = 6,
++};
++
++static const struct mtk_pwm_platform_data mt7623_pwm_data = {
++	.num_pwms = 5,
++};
++
+ static const struct of_device_id mtk_pwm_of_match[] = {
+-	{ .compatible = "mediatek,mt7623-pwm" },
+-	{ }
++	{ .compatible = "mediatek,mt2712-pwm", .data = &mt2712_pwm_data },
++	{ .compatible = "mediatek,mt7622-pwm", .data = &mt7622_pwm_data },
++	{ .compatible = "mediatek,mt7623-pwm", .data = &mt7623_pwm_data },
++	{ },
+ };
+ MODULE_DEVICE_TABLE(of, mtk_pwm_of_match);
+ 
+-- 
+2.11.0
+
diff --git a/target/linux/mediatek/patches-4.14/0162-mtd-nand-mtk-use-nand_reset-to-reset-NAND-devices-in.patch b/target/linux/mediatek/patches-4.14/0162-mtd-nand-mtk-use-nand_reset-to-reset-NAND-devices-in.patch
new file mode 100644
index 0000000000..df2bd3056f
--- /dev/null
+++ b/target/linux/mediatek/patches-4.14/0162-mtd-nand-mtk-use-nand_reset-to-reset-NAND-devices-in.patch
@@ -0,0 +1,46 @@
+From fb607c7c1eaeb47ec2ffed99cab571892cb6af7d Mon Sep 17 00:00:00 2001
+From: Xiaolei Li <xiaolei.li@mediatek.com>
+Date: Thu, 2 Nov 2017 10:05:07 +0800
+Subject: [PATCH 162/224] mtd: nand: mtk: use nand_reset() to reset NAND
+ devices in resume function
+
+Previously, we only select chips and then send reset command to a NAND
+device during resuming nand driver. There is a lack of deselecting chips.
+It is advised to reset and initialize a NAND device using nand_reset().
+
+Signed-off-by: Xiaolei Li <xiaolei.li@mediatek.com>
+Reviewed-by: Matthias Brugger <matthias.bgg@gmail.com>
+Signed-off-by: Boris Brezillon <boris.brezillon@free-electrons.com>
+---
+ drivers/mtd/nand/mtk_nand.c | 8 ++------
+ 1 file changed, 2 insertions(+), 6 deletions(-)
+
+diff --git a/drivers/mtd/nand/mtk_nand.c b/drivers/mtd/nand/mtk_nand.c
+index d86a7d131cc0..6d0101e13ef6 100644
+--- a/drivers/mtd/nand/mtk_nand.c
++++ b/drivers/mtd/nand/mtk_nand.c
+@@ -1540,7 +1540,6 @@ static int mtk_nfc_resume(struct device *dev)
+ 	struct mtk_nfc *nfc = dev_get_drvdata(dev);
+ 	struct mtk_nfc_nand_chip *chip;
+ 	struct nand_chip *nand;
+-	struct mtd_info *mtd;
+ 	int ret;
+ 	u32 i;
+ 
+@@ -1553,11 +1552,8 @@ static int mtk_nfc_resume(struct device *dev)
+ 	/* reset NAND chip if VCC was powered off */
+ 	list_for_each_entry(chip, &nfc->chips, node) {
+ 		nand = &chip->nand;
+-		mtd = nand_to_mtd(nand);
+-		for (i = 0; i < chip->nsels; i++) {
+-			nand->select_chip(mtd, i);
+-			nand->cmdfunc(mtd, NAND_CMD_RESET, -1, -1);
+-		}
++		for (i = 0; i < chip->nsels; i++)
++			nand_reset(nand, i);
+ 	}
+ 
+ 	return 0;
+-- 
+2.11.0
+
diff --git a/target/linux/mediatek/patches-4.14/0164-cpufreq-mediatek-add-mt2712-into-compatible-list.patch b/target/linux/mediatek/patches-4.14/0164-cpufreq-mediatek-add-mt2712-into-compatible-list.patch
new file mode 100644
index 0000000000..f44eabfe7c
--- /dev/null
+++ b/target/linux/mediatek/patches-4.14/0164-cpufreq-mediatek-add-mt2712-into-compatible-list.patch
@@ -0,0 +1,29 @@
+From f027d8b7248cef5b3d3eb8ac68e1040fba340995 Mon Sep 17 00:00:00 2001
+From: Andrew-sh Cheng <andrew-sh.cheng@mediatek.com>
+Date: Fri, 8 Dec 2017 14:07:55 +0800
+Subject: [PATCH 164/224] cpufreq: mediatek: add mt2712 into compatible list
+
+Support mt2712 in mediatek-cpufreq.c
+
+Signed-off-by: Andrew-sh Cheng <andrew-sh.cheng@mediatek.com>
+Acked-by: Viresh Kumar <viresh.kumar@linaro.org>
+Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
+---
+ drivers/cpufreq/mediatek-cpufreq.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/drivers/cpufreq/mediatek-cpufreq.c b/drivers/cpufreq/mediatek-cpufreq.c
+index 18c4bd9a5c65..62aec5cdbb26 100644
+--- a/drivers/cpufreq/mediatek-cpufreq.c
++++ b/drivers/cpufreq/mediatek-cpufreq.c
+@@ -574,6 +574,7 @@ static struct platform_driver mtk_cpufreq_platdrv = {
+ /* List of machines supported by this driver */
+ static const struct of_device_id mtk_cpufreq_machines[] __initconst = {
+ 	{ .compatible = "mediatek,mt2701", },
++	{ .compatible = "mediatek,mt2712", },
+ 	{ .compatible = "mediatek,mt7622", },
+ 	{ .compatible = "mediatek,mt7623", },
+ 	{ .compatible = "mediatek,mt817x", },
+-- 
+2.11.0
+
diff --git a/target/linux/mediatek/patches-4.14/0165-mtd-nand-mtk-update-DT-bindings.patch b/target/linux/mediatek/patches-4.14/0165-mtd-nand-mtk-update-DT-bindings.patch
new file mode 100644
index 0000000000..d60383eadd
--- /dev/null
+++ b/target/linux/mediatek/patches-4.14/0165-mtd-nand-mtk-update-DT-bindings.patch
@@ -0,0 +1,46 @@
+From 42611c6d9f12d16ce4247d76b16218e54ef5b949 Mon Sep 17 00:00:00 2001
+From: RogerCC Lin <rogercc.lin@mediatek.com>
+Date: Thu, 30 Nov 2017 22:10:43 +0800
+Subject: [PATCH 165/224] mtd: nand: mtk: update DT bindings
+
+Add MT7622 NAND Flash Controller dt bindings documentation.
+
+Signed-off-by: RogerCC Lin <rogercc.lin@mediatek.com>
+Reviewed-by: Matthias Brugger <matthias.bgg@gmail.com>
+Signed-off-by: Boris Brezillon <boris.brezillon@free-electrons.com>
+---
+ Documentation/devicetree/bindings/mtd/mtk-nand.txt | 11 ++++++++---
+ 1 file changed, 8 insertions(+), 3 deletions(-)
+
+diff --git a/Documentation/devicetree/bindings/mtd/mtk-nand.txt b/Documentation/devicetree/bindings/mtd/mtk-nand.txt
+index dbf9e054c11c..0025bc4c94a0 100644
+--- a/Documentation/devicetree/bindings/mtd/mtk-nand.txt
++++ b/Documentation/devicetree/bindings/mtd/mtk-nand.txt
+@@ -12,8 +12,10 @@ tree nodes.
+ 
+ The first part of NFC is NAND Controller Interface (NFI) HW.
+ Required NFI properties:
+-- compatible:			Should be one of "mediatek,mt2701-nfc",
+-				"mediatek,mt2712-nfc".
++- compatible:			Should be one of
++				"mediatek,mt2701-nfc",
++				"mediatek,mt2712-nfc",
++				"mediatek,mt7622-nfc".
+ - reg:				Base physical address and size of NFI.
+ - interrupts:			Interrupts of NFI.
+ - clocks:			NFI required clocks.
+@@ -142,7 +144,10 @@ Example:
+ ==============
+ 
+ Required BCH properties:
+-- compatible:	Should be one of "mediatek,mt2701-ecc", "mediatek,mt2712-ecc".
++- compatible:	Should be one of
++		"mediatek,mt2701-ecc",
++		"mediatek,mt2712-ecc",
++		"mediatek,mt7622-ecc".
+ - reg:		Base physical address and size of ECC.
+ - interrupts:	Interrupts of ECC.
+ - clocks:	ECC required clocks.
+-- 
+2.11.0
+
diff --git a/target/linux/mediatek/patches-4.14/0166-mtd-nand-mtk-Support-different-MTK-NAND-flash-contro.patch b/target/linux/mediatek/patches-4.14/0166-mtd-nand-mtk-Support-different-MTK-NAND-flash-contro.patch
new file mode 100644
index 0000000000..b890a8d766
--- /dev/null
+++ b/target/linux/mediatek/patches-4.14/0166-mtd-nand-mtk-Support-different-MTK-NAND-flash-contro.patch
@@ -0,0 +1,389 @@
+From fd1a1eabf2473e769b5cafc704e0336d11f61961 Mon Sep 17 00:00:00 2001
+From: RogerCC Lin <rogercc.lin@mediatek.com>
+Date: Thu, 30 Nov 2017 22:10:44 +0800
+Subject: [PATCH 166/224] mtd: nand: mtk: Support different MTK NAND flash
+ controller IP
+
+MT7622 uses an MTK's earlier NAND flash controller IP which support
+different sector size, max spare size per sector and paraity bits...,
+some register's offset and definition also been changed in the NAND
+flash controller, this patch is the preparation to support MT7622
+NAND flash controller.
+
+MT7622 NFC and ECC engine are similar to MT2701's, except below
+differences:
+(1)MT7622 NFC's max sector size(ECC data size) is 512 bytes, and
+   MT2701's is 1024, and MT7622's max sector number is 8.
+(2)The parity bit of MT7622 is 13, MT2701 is 14.
+(3)MT7622 ECC supports less ECC strength, max to 16 bit ecc strength.
+(4)MT7622 supports less spare size per sector, max spare size per
+   sector is 28 bytes.
+(5)Some register's offset are different, include ECC_ENCIRQ_EN,
+   ECC_ENCIRQ_STA, ECC_DECDONE, ECC_DECIRQ_EN and ECC_DECIRQ_STA.
+(6)ENC_MODE of ECC_ENCCNFG register is moved from bit 5-6 to bit 4-5.
+
+Signed-off-by: RogerCC Lin <rogercc.lin@mediatek.com>
+Signed-off-by: Boris Brezillon <boris.brezillon@free-electrons.com>
+---
+ drivers/mtd/nand/mtk_ecc.c  | 100 ++++++++++++++++++++++++++++++--------------
+ drivers/mtd/nand/mtk_ecc.h  |   3 +-
+ drivers/mtd/nand/mtk_nand.c |  27 ++++++++----
+ 3 files changed, 89 insertions(+), 41 deletions(-)
+
+diff --git a/drivers/mtd/nand/mtk_ecc.c b/drivers/mtd/nand/mtk_ecc.c
+index c51d214d169e..6610eefaa92b 100644
+--- a/drivers/mtd/nand/mtk_ecc.c
++++ b/drivers/mtd/nand/mtk_ecc.c
+@@ -34,34 +34,28 @@
+ 
+ #define ECC_ENCCON		(0x00)
+ #define ECC_ENCCNFG		(0x04)
+-#define		ECC_MODE_SHIFT		(5)
+ #define		ECC_MS_SHIFT		(16)
+ #define ECC_ENCDIADDR		(0x08)
+ #define ECC_ENCIDLE		(0x0C)
+-#define ECC_ENCIRQ_EN		(0x80)
+-#define ECC_ENCIRQ_STA		(0x84)
+ #define ECC_DECCON		(0x100)
+ #define ECC_DECCNFG		(0x104)
+ #define		DEC_EMPTY_EN		BIT(31)
+ #define		DEC_CNFG_CORRECT	(0x3 << 12)
+ #define ECC_DECIDLE		(0x10C)
+ #define ECC_DECENUM0		(0x114)
+-#define ECC_DECDONE		(0x124)
+-#define ECC_DECIRQ_EN		(0x200)
+-#define ECC_DECIRQ_STA		(0x204)
+ 
+ #define ECC_TIMEOUT		(500000)
+ 
+ #define ECC_IDLE_REG(op)	((op) == ECC_ENCODE ? ECC_ENCIDLE : ECC_DECIDLE)
+ #define ECC_CTL_REG(op)		((op) == ECC_ENCODE ? ECC_ENCCON : ECC_DECCON)
+-#define ECC_IRQ_REG(op)		((op) == ECC_ENCODE ? \
+-					ECC_ENCIRQ_EN : ECC_DECIRQ_EN)
+ 
+ struct mtk_ecc_caps {
+ 	u32 err_mask;
+ 	const u8 *ecc_strength;
++	const u32 *ecc_regs;
+ 	u8 num_ecc_strength;
+-	u32 encode_parity_reg0;
++	u8 ecc_mode_shift;
++	u32 parity_bits;
+ 	int pg_irq_sel;
+ };
+ 
+@@ -89,6 +83,33 @@ static const u8 ecc_strength_mt2712[] = {
+ 	40, 44, 48, 52, 56, 60, 68, 72, 80
+ };
+ 
++enum mtk_ecc_regs {
++	ECC_ENCPAR00,
++	ECC_ENCIRQ_EN,
++	ECC_ENCIRQ_STA,
++	ECC_DECDONE,
++	ECC_DECIRQ_EN,
++	ECC_DECIRQ_STA,
++};
++
++static int mt2701_ecc_regs[] = {
++	[ECC_ENCPAR00] =        0x10,
++	[ECC_ENCIRQ_EN] =       0x80,
++	[ECC_ENCIRQ_STA] =      0x84,
++	[ECC_DECDONE] =         0x124,
++	[ECC_DECIRQ_EN] =       0x200,
++	[ECC_DECIRQ_STA] =      0x204,
++};
++
++static int mt2712_ecc_regs[] = {
++	[ECC_ENCPAR00] =        0x300,
++	[ECC_ENCIRQ_EN] =       0x80,
++	[ECC_ENCIRQ_STA] =      0x84,
++	[ECC_DECDONE] =         0x124,
++	[ECC_DECIRQ_EN] =       0x200,
++	[ECC_DECIRQ_STA] =      0x204,
++};
++
+ static inline void mtk_ecc_wait_idle(struct mtk_ecc *ecc,
+ 				     enum mtk_ecc_operation op)
+ {
+@@ -107,32 +128,30 @@ static inline void mtk_ecc_wait_idle(struct mtk_ecc *ecc,
+ static irqreturn_t mtk_ecc_irq(int irq, void *id)
+ {
+ 	struct mtk_ecc *ecc = id;
+-	enum mtk_ecc_operation op;
+ 	u32 dec, enc;
+ 
+-	dec = readw(ecc->regs + ECC_DECIRQ_STA) & ECC_IRQ_EN;
++	dec = readw(ecc->regs + ecc->caps->ecc_regs[ECC_DECIRQ_STA])
++		    & ECC_IRQ_EN;
+ 	if (dec) {
+-		op = ECC_DECODE;
+-		dec = readw(ecc->regs + ECC_DECDONE);
++		dec = readw(ecc->regs + ecc->caps->ecc_regs[ECC_DECDONE]);
+ 		if (dec & ecc->sectors) {
+ 			/*
+ 			 * Clear decode IRQ status once again to ensure that
+ 			 * there will be no extra IRQ.
+ 			 */
+-			readw(ecc->regs + ECC_DECIRQ_STA);
++			readw(ecc->regs + ecc->caps->ecc_regs[ECC_DECIRQ_STA]);
+ 			ecc->sectors = 0;
+ 			complete(&ecc->done);
+ 		} else {
+ 			return IRQ_HANDLED;
+ 		}
+ 	} else {
+-		enc = readl(ecc->regs + ECC_ENCIRQ_STA) & ECC_IRQ_EN;
+-		if (enc) {
+-			op = ECC_ENCODE;
++		enc = readl(ecc->regs + ecc->caps->ecc_regs[ECC_ENCIRQ_STA])
++		      & ECC_IRQ_EN;
++		if (enc)
+ 			complete(&ecc->done);
+-		} else {
++		else
+ 			return IRQ_NONE;
+-		}
+ 	}
+ 
+ 	return IRQ_HANDLED;
+@@ -160,7 +179,7 @@ static int mtk_ecc_config(struct mtk_ecc *ecc, struct mtk_ecc_config *config)
+ 		/* configure ECC encoder (in bits) */
+ 		enc_sz = config->len << 3;
+ 
+-		reg = ecc_bit | (config->mode << ECC_MODE_SHIFT);
++		reg = ecc_bit | (config->mode << ecc->caps->ecc_mode_shift);
+ 		reg |= (enc_sz << ECC_MS_SHIFT);
+ 		writel(reg, ecc->regs + ECC_ENCCNFG);
+ 
+@@ -171,9 +190,9 @@ static int mtk_ecc_config(struct mtk_ecc *ecc, struct mtk_ecc_config *config)
+ 	} else {
+ 		/* configure ECC decoder (in bits) */
+ 		dec_sz = (config->len << 3) +
+-					config->strength * ECC_PARITY_BITS;
++			 config->strength * ecc->caps->parity_bits;
+ 
+-		reg = ecc_bit | (config->mode << ECC_MODE_SHIFT);
++		reg = ecc_bit | (config->mode << ecc->caps->ecc_mode_shift);
+ 		reg |= (dec_sz << ECC_MS_SHIFT) | DEC_CNFG_CORRECT;
+ 		reg |= DEC_EMPTY_EN;
+ 		writel(reg, ecc->regs + ECC_DECCNFG);
+@@ -291,7 +310,12 @@ int mtk_ecc_enable(struct mtk_ecc *ecc, struct mtk_ecc_config *config)
+ 		 */
+ 		if (ecc->caps->pg_irq_sel && config->mode == ECC_NFI_MODE)
+ 			reg_val |= ECC_PG_IRQ_SEL;
+-		writew(reg_val, ecc->regs + ECC_IRQ_REG(op));
++		if (op == ECC_ENCODE)
++			writew(reg_val, ecc->regs +
++			       ecc->caps->ecc_regs[ECC_ENCIRQ_EN]);
++		else
++			writew(reg_val, ecc->regs +
++			       ecc->caps->ecc_regs[ECC_DECIRQ_EN]);
+ 	}
+ 
+ 	writew(ECC_OP_ENABLE, ecc->regs + ECC_CTL_REG(op));
+@@ -310,13 +334,17 @@ void mtk_ecc_disable(struct mtk_ecc *ecc)
+ 
+ 	/* disable it */
+ 	mtk_ecc_wait_idle(ecc, op);
+-	if (op == ECC_DECODE)
++	if (op == ECC_DECODE) {
+ 		/*
+ 		 * Clear decode IRQ status in case there is a timeout to wait
+ 		 * decode IRQ.
+ 		 */
+-		readw(ecc->regs + ECC_DECIRQ_STA);
+-	writew(0, ecc->regs + ECC_IRQ_REG(op));
++		readw(ecc->regs + ecc->caps->ecc_regs[ECC_DECDONE]);
++		writew(0, ecc->regs + ecc->caps->ecc_regs[ECC_DECIRQ_EN]);
++	} else {
++		writew(0, ecc->regs + ecc->caps->ecc_regs[ECC_ENCIRQ_EN]);
++	}
++
+ 	writew(ECC_OP_DISABLE, ecc->regs + ECC_CTL_REG(op));
+ 
+ 	mutex_unlock(&ecc->lock);
+@@ -367,11 +395,11 @@ int mtk_ecc_encode(struct mtk_ecc *ecc, struct mtk_ecc_config *config,
+ 	mtk_ecc_wait_idle(ecc, ECC_ENCODE);
+ 
+ 	/* Program ECC bytes to OOB: per sector oob = FDM + ECC + SPARE */
+-	len = (config->strength * ECC_PARITY_BITS + 7) >> 3;
++	len = (config->strength * ecc->caps->parity_bits + 7) >> 3;
+ 
+ 	/* write the parity bytes generated by the ECC back to temp buffer */
+ 	__ioread32_copy(ecc->eccdata,
+-			ecc->regs + ecc->caps->encode_parity_reg0,
++			ecc->regs + ecc->caps->ecc_regs[ECC_ENCPAR00],
+ 			round_up(len, 4));
+ 
+ 	/* copy into possibly unaligned OOB region with actual length */
+@@ -404,19 +432,29 @@ void mtk_ecc_adjust_strength(struct mtk_ecc *ecc, u32 *p)
+ }
+ EXPORT_SYMBOL(mtk_ecc_adjust_strength);
+ 
++unsigned int mtk_ecc_get_parity_bits(struct mtk_ecc *ecc)
++{
++	return ecc->caps->parity_bits;
++}
++EXPORT_SYMBOL(mtk_ecc_get_parity_bits);
++
+ static const struct mtk_ecc_caps mtk_ecc_caps_mt2701 = {
+ 	.err_mask = 0x3f,
+ 	.ecc_strength = ecc_strength_mt2701,
++	.ecc_regs = mt2701_ecc_regs,
+ 	.num_ecc_strength = 20,
+-	.encode_parity_reg0 = 0x10,
++	.ecc_mode_shift = 5,
++	.parity_bits = 14,
+ 	.pg_irq_sel = 0,
+ };
+ 
+ static const struct mtk_ecc_caps mtk_ecc_caps_mt2712 = {
+ 	.err_mask = 0x7f,
+ 	.ecc_strength = ecc_strength_mt2712,
++	.ecc_regs = mt2712_ecc_regs,
+ 	.num_ecc_strength = 23,
+-	.encode_parity_reg0 = 0x300,
++	.ecc_mode_shift = 5,
++	.parity_bits = 14,
+ 	.pg_irq_sel = 1,
+ };
+ 
+@@ -452,7 +490,7 @@ static int mtk_ecc_probe(struct platform_device *pdev)
+ 
+ 	max_eccdata_size = ecc->caps->num_ecc_strength - 1;
+ 	max_eccdata_size = ecc->caps->ecc_strength[max_eccdata_size];
+-	max_eccdata_size = (max_eccdata_size * ECC_PARITY_BITS + 7) >> 3;
++	max_eccdata_size = (max_eccdata_size * ecc->caps->parity_bits + 7) >> 3;
+ 	max_eccdata_size = round_up(max_eccdata_size, 4);
+ 	ecc->eccdata = devm_kzalloc(dev, max_eccdata_size, GFP_KERNEL);
+ 	if (!ecc->eccdata)
+diff --git a/drivers/mtd/nand/mtk_ecc.h b/drivers/mtd/nand/mtk_ecc.h
+index d245c14f1b80..a455df080952 100644
+--- a/drivers/mtd/nand/mtk_ecc.h
++++ b/drivers/mtd/nand/mtk_ecc.h
+@@ -14,8 +14,6 @@
+ 
+ #include <linux/types.h>
+ 
+-#define ECC_PARITY_BITS		(14)
+-
+ enum mtk_ecc_mode {ECC_DMA_MODE = 0, ECC_NFI_MODE = 1};
+ enum mtk_ecc_operation {ECC_ENCODE, ECC_DECODE};
+ 
+@@ -43,6 +41,7 @@ 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 *);
+diff --git a/drivers/mtd/nand/mtk_nand.c b/drivers/mtd/nand/mtk_nand.c
+index 6d0101e13ef6..7349aa846f9a 100644
+--- a/drivers/mtd/nand/mtk_nand.c
++++ b/drivers/mtd/nand/mtk_nand.c
+@@ -97,7 +97,6 @@
+ 
+ #define MTK_TIMEOUT		(500000)
+ #define MTK_RESET_TIMEOUT	(1000000)
+-#define MTK_MAX_SECTOR		(16)
+ #define MTK_NAND_MAX_NSELS	(2)
+ #define MTK_NFC_MIN_SPARE	(16)
+ #define ACCTIMING(tpoecs, tprecs, tc2r, tw2r, twh, twst, trlt) \
+@@ -109,6 +108,8 @@ struct mtk_nfc_caps {
+ 	u8 num_spare_size;
+ 	u8 pageformat_spare_shift;
+ 	u8 nfi_clk_div;
++	u8 max_sector;
++	u32 max_sector_size;
+ };
+ 
+ struct mtk_nfc_bad_mark_ctl {
+@@ -450,7 +451,7 @@ static inline u8 mtk_nfc_read_byte(struct mtd_info *mtd)
+ 		 * set to max sector to allow the HW to continue reading over
+ 		 * unaligned accesses
+ 		 */
+-		reg = (MTK_MAX_SECTOR << CON_SEC_SHIFT) | CON_BRD;
++		reg = (nfc->caps->max_sector << CON_SEC_SHIFT) | CON_BRD;
+ 		nfi_writel(nfc, reg, NFI_CON);
+ 
+ 		/* trigger to fetch data */
+@@ -481,7 +482,7 @@ static void mtk_nfc_write_byte(struct mtd_info *mtd, u8 byte)
+ 		reg = nfi_readw(nfc, NFI_CNFG) | CNFG_BYTE_RW;
+ 		nfi_writew(nfc, reg, NFI_CNFG);
+ 
+-		reg = MTK_MAX_SECTOR << CON_SEC_SHIFT | CON_BWR;
++		reg = nfc->caps->max_sector << CON_SEC_SHIFT | CON_BWR;
+ 		nfi_writel(nfc, reg, NFI_CON);
+ 
+ 		nfi_writew(nfc, STAR_EN, NFI_STRDATA);
+@@ -1126,9 +1127,11 @@ static void mtk_nfc_set_fdm(struct mtk_nfc_fdm *fdm, struct mtd_info *mtd)
+ {
+ 	struct nand_chip *nand = mtd_to_nand(mtd);
+ 	struct mtk_nfc_nand_chip *chip = to_mtk_nand(nand);
++	struct mtk_nfc *nfc = nand_get_controller_data(nand);
+ 	u32 ecc_bytes;
+ 
+-	ecc_bytes = DIV_ROUND_UP(nand->ecc.strength * ECC_PARITY_BITS, 8);
++	ecc_bytes = DIV_ROUND_UP(nand->ecc.strength *
++				 mtk_ecc_get_parity_bits(nfc->ecc), 8);
+ 
+ 	fdm->reg_size = chip->spare_per_sector - ecc_bytes;
+ 	if (fdm->reg_size > NFI_FDM_MAX_SIZE)
+@@ -1208,7 +1211,8 @@ static int mtk_nfc_ecc_init(struct device *dev, struct mtd_info *mtd)
+ 		 * this controller only supports 512 and 1024 sizes
+ 		 */
+ 		if (nand->ecc.size < 1024) {
+-			if (mtd->writesize > 512) {
++			if (mtd->writesize > 512 &&
++			    nfc->caps->max_sector_size > 512) {
+ 				nand->ecc.size = 1024;
+ 				nand->ecc.strength <<= 1;
+ 			} else {
+@@ -1223,7 +1227,8 @@ static int mtk_nfc_ecc_init(struct device *dev, struct mtd_info *mtd)
+ 			return ret;
+ 
+ 		/* calculate oob bytes except ecc parity data */
+-		free = ((nand->ecc.strength * ECC_PARITY_BITS) + 7) >> 3;
++		free = (nand->ecc.strength * mtk_ecc_get_parity_bits(nfc->ecc)
++			+ 7) >> 3;
+ 		free = spare - free;
+ 
+ 		/*
+@@ -1233,10 +1238,12 @@ static int mtk_nfc_ecc_init(struct device *dev, struct mtd_info *mtd)
+ 		 */
+ 		if (free > NFI_FDM_MAX_SIZE) {
+ 			spare -= NFI_FDM_MAX_SIZE;
+-			nand->ecc.strength = (spare << 3) / ECC_PARITY_BITS;
++			nand->ecc.strength = (spare << 3) /
++					     mtk_ecc_get_parity_bits(nfc->ecc);
+ 		} else if (free < 0) {
+ 			spare -= NFI_FDM_MIN_SIZE;
+-			nand->ecc.strength = (spare << 3) / ECC_PARITY_BITS;
++			nand->ecc.strength = (spare << 3) /
++					     mtk_ecc_get_parity_bits(nfc->ecc);
+ 		}
+ 	}
+ 
+@@ -1389,6 +1396,8 @@ static const struct mtk_nfc_caps mtk_nfc_caps_mt2701 = {
+ 	.num_spare_size = 16,
+ 	.pageformat_spare_shift = 4,
+ 	.nfi_clk_div = 1,
++	.max_sector = 16,
++	.max_sector_size = 1024,
+ };
+ 
+ static const struct mtk_nfc_caps mtk_nfc_caps_mt2712 = {
+@@ -1396,6 +1405,8 @@ static const struct mtk_nfc_caps mtk_nfc_caps_mt2712 = {
+ 	.num_spare_size = 19,
+ 	.pageformat_spare_shift = 16,
+ 	.nfi_clk_div = 2,
++	.max_sector = 16,
++	.max_sector_size = 1024,
+ };
+ 
+ static const struct of_device_id mtk_nfc_id_table[] = {
+-- 
+2.11.0
+
diff --git a/target/linux/mediatek/patches-4.14/0167-mtd-nand-mtk-Support-MT7622-NAND-flash-controller.patch b/target/linux/mediatek/patches-4.14/0167-mtd-nand-mtk-Support-MT7622-NAND-flash-controller.patch
new file mode 100644
index 0000000000..d7550ee7e8
--- /dev/null
+++ b/target/linux/mediatek/patches-4.14/0167-mtd-nand-mtk-Support-MT7622-NAND-flash-controller.patch
@@ -0,0 +1,116 @@
+From f395a149fbbc190afbadbdcf9ce95f85f78da22f Mon Sep 17 00:00:00 2001
+From: RogerCC Lin <rogercc.lin@mediatek.com>
+Date: Thu, 30 Nov 2017 22:10:45 +0800
+Subject: [PATCH 167/224] mtd: nand: mtk: Support MT7622 NAND flash controller.
+
+Add tables to support MT7622 NAND flash controller.
+
+Signed-off-by: RogerCC Lin <rogercc.lin@mediatek.com>
+Signed-off-by: Boris Brezillon <boris.brezillon@free-electrons.com>
+---
+ drivers/mtd/nand/mtk_ecc.c  | 26 ++++++++++++++++++++++++++
+ drivers/mtd/nand/mtk_nand.c | 16 ++++++++++++++++
+ 2 files changed, 42 insertions(+)
+
+diff --git a/drivers/mtd/nand/mtk_ecc.c b/drivers/mtd/nand/mtk_ecc.c
+index 6610eefaa92b..40d86a861a70 100644
+--- a/drivers/mtd/nand/mtk_ecc.c
++++ b/drivers/mtd/nand/mtk_ecc.c
+@@ -83,6 +83,10 @@ static const u8 ecc_strength_mt2712[] = {
+ 	40, 44, 48, 52, 56, 60, 68, 72, 80
+ };
+ 
++static const u8 ecc_strength_mt7622[] = {
++	4, 6, 8, 10, 12, 14, 16
++};
++
+ enum mtk_ecc_regs {
+ 	ECC_ENCPAR00,
+ 	ECC_ENCIRQ_EN,
+@@ -110,6 +114,15 @@ static int mt2712_ecc_regs[] = {
+ 	[ECC_DECIRQ_STA] =      0x204,
+ };
+ 
++static int mt7622_ecc_regs[] = {
++	[ECC_ENCPAR00] =        0x10,
++	[ECC_ENCIRQ_EN] =       0x30,
++	[ECC_ENCIRQ_STA] =      0x34,
++	[ECC_DECDONE] =         0x11c,
++	[ECC_DECIRQ_EN] =       0x140,
++	[ECC_DECIRQ_STA] =      0x144,
++};
++
+ static inline void mtk_ecc_wait_idle(struct mtk_ecc *ecc,
+ 				     enum mtk_ecc_operation op)
+ {
+@@ -458,6 +471,16 @@ static const struct mtk_ecc_caps mtk_ecc_caps_mt2712 = {
+ 	.pg_irq_sel = 1,
+ };
+ 
++static const struct mtk_ecc_caps mtk_ecc_caps_mt7622 = {
++	.err_mask = 0x3f,
++	.ecc_strength = ecc_strength_mt7622,
++	.ecc_regs = mt7622_ecc_regs,
++	.num_ecc_strength = 7,
++	.ecc_mode_shift = 4,
++	.parity_bits = 13,
++	.pg_irq_sel = 0,
++};
++
+ static const struct of_device_id mtk_ecc_dt_match[] = {
+ 	{
+ 		.compatible = "mediatek,mt2701-ecc",
+@@ -465,6 +488,9 @@ static const struct of_device_id mtk_ecc_dt_match[] = {
+ 	}, {
+ 		.compatible = "mediatek,mt2712-ecc",
+ 		.data = &mtk_ecc_caps_mt2712,
++	}, {
++		.compatible = "mediatek,mt7622-ecc",
++		.data = &mtk_ecc_caps_mt7622,
+ 	},
+ 	{},
+ };
+diff --git a/drivers/mtd/nand/mtk_nand.c b/drivers/mtd/nand/mtk_nand.c
+index 7349aa846f9a..8f71b405d639 100644
+--- a/drivers/mtd/nand/mtk_nand.c
++++ b/drivers/mtd/nand/mtk_nand.c
+@@ -174,6 +174,10 @@ static const u8 spare_size_mt2712[] = {
+ 	74
+ };
+ 
++static const u8 spare_size_mt7622[] = {
++	16, 26, 27, 28
++};
++
+ static inline struct mtk_nfc_nand_chip *to_mtk_nand(struct nand_chip *nand)
+ {
+ 	return container_of(nand, struct mtk_nfc_nand_chip, nand);
+@@ -1409,6 +1413,15 @@ static const struct mtk_nfc_caps mtk_nfc_caps_mt2712 = {
+ 	.max_sector_size = 1024,
+ };
+ 
++static const struct mtk_nfc_caps mtk_nfc_caps_mt7622 = {
++	.spare_size = spare_size_mt7622,
++	.num_spare_size = 4,
++	.pageformat_spare_shift = 4,
++	.nfi_clk_div = 1,
++	.max_sector = 8,
++	.max_sector_size = 512,
++};
++
+ static const struct of_device_id mtk_nfc_id_table[] = {
+ 	{
+ 		.compatible = "mediatek,mt2701-nfc",
+@@ -1416,6 +1429,9 @@ static const struct of_device_id mtk_nfc_id_table[] = {
+ 	}, {
+ 		.compatible = "mediatek,mt2712-nfc",
+ 		.data = &mtk_nfc_caps_mt2712,
++	}, {
++		.compatible = "mediatek,mt7622-nfc",
++		.data = &mtk_nfc_caps_mt7622,
+ 	},
+ 	{}
+ };
+-- 
+2.11.0
+
diff --git a/target/linux/mediatek/patches-4.14/0168-mmc-dt-bindings-add-mmc-support-to-MT7623-SoC.patch b/target/linux/mediatek/patches-4.14/0168-mmc-dt-bindings-add-mmc-support-to-MT7623-SoC.patch
new file mode 100644
index 0000000000..c68b21fdbd
--- /dev/null
+++ b/target/linux/mediatek/patches-4.14/0168-mmc-dt-bindings-add-mmc-support-to-MT7623-SoC.patch
@@ -0,0 +1,31 @@
+From bb37b1aa5d1aadfcecd9189a653856099fbed507 Mon Sep 17 00:00:00 2001
+From: Sean Wang <sean.wang@mediatek.com>
+Date: Thu, 7 Dec 2017 14:43:22 +0800
+Subject: [PATCH 168/224] mmc: dt-bindings: add mmc support to MT7623 SoC
+
+Add the devicetree binding for MT7623 SoC using MT2701 as the fallback.
+
+Cc: devicetree@vger.kernel.org
+Signed-off-by: Sean Wang <sean.wang@mediatek.com>
+Acked-by: Rob Herring <robh@kernel.org>
+Signed-off-by: Ulf Hansson <ulf.hansson@linaro.org>
+---
+ Documentation/devicetree/bindings/mmc/mtk-sd.txt | 2 ++
+ 1 file changed, 2 insertions(+)
+
+diff --git a/Documentation/devicetree/bindings/mmc/mtk-sd.txt b/Documentation/devicetree/bindings/mmc/mtk-sd.txt
+index 72d2a734ab85..9b8017670870 100644
+--- a/Documentation/devicetree/bindings/mmc/mtk-sd.txt
++++ b/Documentation/devicetree/bindings/mmc/mtk-sd.txt
+@@ -12,6 +12,8 @@ Required properties:
+ 	"mediatek,mt8173-mmc": for mmc host ip compatible with mt8173
+ 	"mediatek,mt2701-mmc": for mmc host ip compatible with mt2701
+ 	"mediatek,mt2712-mmc": for mmc host ip compatible with mt2712
++	"mediatek,mt7623-mmc", "mediatek,mt2701-mmc": for MT7623 SoC
++
+ - reg: physical base address of the controller and length
+ - interrupts: Should contain MSDC interrupt number
+ - clocks: Should contain phandle for the clock feeding the MMC controller
+-- 
+2.11.0
+
diff --git a/target/linux/mediatek/patches-4.14/0169-dt-bindings-pinctrl-add-bindings-for-MediaTek-MT7622.patch b/target/linux/mediatek/patches-4.14/0169-dt-bindings-pinctrl-add-bindings-for-MediaTek-MT7622.patch
new file mode 100644
index 0000000000..b8679be22d
--- /dev/null
+++ b/target/linux/mediatek/patches-4.14/0169-dt-bindings-pinctrl-add-bindings-for-MediaTek-MT7622.patch
@@ -0,0 +1,377 @@
+From 4e4c2d695a5daf6dc55b8713af720ef15b52c0e7 Mon Sep 17 00:00:00 2001
+From: Sean Wang <sean.wang@mediatek.com>
+Date: Tue, 12 Dec 2017 14:24:18 +0800
+Subject: [PATCH 169/224] dt-bindings: pinctrl: add bindings for MediaTek
+ MT7622 SoC
+
+Add devicetree bindings for MediaTek MT7622 pinctrl driver.
+
+Signed-off-by: Sean Wang <sean.wang@mediatek.com>
+Reviewed-by: Biao Huang <biao.huang@mediatek.com>
+Acked-by: Rob Herring <robh@kernel.org>
+Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
+---
+ .../devicetree/bindings/pinctrl/pinctrl-mt7622.txt | 351 +++++++++++++++++++++
+ 1 file changed, 351 insertions(+)
+ create mode 100644 Documentation/devicetree/bindings/pinctrl/pinctrl-mt7622.txt
+
+diff --git a/Documentation/devicetree/bindings/pinctrl/pinctrl-mt7622.txt b/Documentation/devicetree/bindings/pinctrl/pinctrl-mt7622.txt
+new file mode 100644
+index 000000000000..f18ed99f6e14
+--- /dev/null
++++ b/Documentation/devicetree/bindings/pinctrl/pinctrl-mt7622.txt
+@@ -0,0 +1,351 @@
++== MediaTek MT7622 pinctrl controller ==
++
++Required properties for the root node:
++ - compatible: Should be one of the following
++	       "mediatek,mt7622-pinctrl" for MT7622 SoC
++ - reg: offset and length of the pinctrl space
++
++ - gpio-controller: Marks the device node as a GPIO controller.
++ - #gpio-cells: Should be two. The first cell is the pin number and the
++   second is the GPIO flags.
++
++Please refer to pinctrl-bindings.txt in this directory for details of the
++common pinctrl bindings used by client devices, including the meaning of the
++phrase "pin configuration node".
++
++MT7622 pin configuration nodes act as a container for an arbitrary number of
++subnodes. Each of these subnodes represents some desired configuration for a
++pin, a group, or a list of pins or groups. This configuration can include the
++mux function to select on those pin(s)/group(s), and various pin configuration
++parameters, such as pull-up, slew rate, etc.
++
++We support 2 types of configuration nodes. Those nodes can be either pinmux
++nodes or pinconf nodes. Each configuration node can consist of multiple nodes
++describing the pinmux and pinconf options.
++
++The name of each subnode doesn't matter as long as it is unique; all subnodes
++should be enumerated and processed purely based on their content.
++
++== pinmux nodes content ==
++
++The following generic properties as defined in pinctrl-bindings.txt are valid
++to specify in a pinmux subnode:
++
++Required properties are:
++ - groups: An array of strings. Each string contains the name of a group.
++  Valid values for these names are listed below.
++ - function: A string containing the name of the function to mux to the
++  group. Valid values for function names are listed below.
++
++== pinconf nodes content ==
++
++The following generic properties as defined in pinctrl-bindings.txt are valid
++to specify in a pinconf subnode:
++
++Required properties are:
++ - pins: An array of strings. Each string contains the name of a pin.
++  Valid values for these names are listed below.
++ - groups: An array of strings. Each string contains the name of a group.
++  Valid values for these names are listed below.
++
++Optional properies are:
++ bias-disable, bias-pull, bias-pull-down, input-enable,
++ input-schmitt-enable, input-schmitt-disable, output-enable
++ output-low, output-high, drive-strength, slew-rate
++
++ Valid arguments for 'slew-rate' are '0' for no slew rate controlled and '1' for
++ slower slew rate respectively.
++ Valid arguments for 'drive-strength', 4, 8, 12, or 16 in mA.
++
++The following specific properties as defined are valid to specify in a pinconf
++subnode:
++
++Optional properties are:
++ - mediatek,tdsel: An integer describing the steps for output level shifter duty
++   cycle when asserted (high pulse width adjustment). Valid arguments are from 0
++   to 15.
++ - mediatek,rdsel: An integer describing the steps for input level shifter duty
++   cycle when asserted (high pulse width adjustment). Valid arguments are from 0
++   to 63.
++
++== Valid values for pins, function and groups on MT7622 ==
++
++Valid values for pins are:
++pins can be referenced via the pin names as the below table shown and the
++related physical number is also put ahead of those names which helps cross
++references to pins between groups to know whether pins assignment conflict
++happens among devices try to acquire those available pins.
++
++	Pin #:  Valid values for pins
++	-----------------------------
++	PIN 0: "GPIO_A"
++	PIN 1: "I2S1_IN"
++	PIN 2: "I2S1_OUT"
++	PIN 3: "I2S_BCLK"
++	PIN 4: "I2S_WS"
++	PIN 5: "I2S_MCLK"
++	PIN 6: "TXD0"
++	PIN 7: "RXD0"
++	PIN 8: "SPI_WP"
++	PIN 9: "SPI_HOLD"
++	PIN 10: "SPI_CLK"
++	PIN 11: "SPI_MOSI"
++	PIN 12: "SPI_MISO"
++	PIN 13: "SPI_CS"
++	PIN 14: "I2C_SDA"
++	PIN 15: "I2C_SCL"
++	PIN 16: "I2S2_IN"
++	PIN 17: "I2S3_IN"
++	PIN 18: "I2S4_IN"
++	PIN 19: "I2S2_OUT"
++	PIN 20: "I2S3_OUT"
++	PIN 21: "I2S4_OUT"
++	PIN 22: "GPIO_B"
++	PIN 23: "MDC"
++	PIN 24: "MDIO"
++	PIN 25: "G2_TXD0"
++	PIN 26: "G2_TXD1"
++	PIN 27: "G2_TXD2"
++	PIN 28: "G2_TXD3"
++	PIN 29: "G2_TXEN"
++	PIN 30: "G2_TXC"
++	PIN 31: "G2_RXD0"
++	PIN 32: "G2_RXD1"
++	PIN 33: "G2_RXD2"
++	PIN 34: "G2_RXD3"
++	PIN 35: "G2_RXDV"
++	PIN 36: "G2_RXC"
++	PIN 37: "NCEB"
++	PIN 38: "NWEB"
++	PIN 39: "NREB"
++	PIN 40: "NDL4"
++	PIN 41: "NDL5"
++	PIN 42: "NDL6"
++	PIN 43: "NDL7"
++	PIN 44: "NRB"
++	PIN 45: "NCLE"
++	PIN 46: "NALE"
++	PIN 47: "NDL0"
++	PIN 48: "NDL1"
++	PIN 49: "NDL2"
++	PIN 50: "NDL3"
++	PIN 51: "MDI_TP_P0"
++	PIN 52: "MDI_TN_P0"
++	PIN 53: "MDI_RP_P0"
++	PIN 54: "MDI_RN_P0"
++	PIN 55: "MDI_TP_P1"
++	PIN 56: "MDI_TN_P1"
++	PIN 57: "MDI_RP_P1"
++	PIN 58: "MDI_RN_P1"
++	PIN 59: "MDI_RP_P2"
++	PIN 60: "MDI_RN_P2"
++	PIN 61: "MDI_TP_P2"
++	PIN 62: "MDI_TN_P2"
++	PIN 63: "MDI_TP_P3"
++	PIN 64: "MDI_TN_P3"
++	PIN 65: "MDI_RP_P3"
++	PIN 66: "MDI_RN_P3"
++	PIN 67: "MDI_RP_P4"
++	PIN 68: "MDI_RN_P4"
++	PIN 69: "MDI_TP_P4"
++	PIN 70: "MDI_TN_P4"
++	PIN 71: "PMIC_SCL"
++	PIN 72: "PMIC_SDA"
++	PIN 73: "SPIC1_CLK"
++	PIN 74: "SPIC1_MOSI"
++	PIN 75: "SPIC1_MISO"
++	PIN 76: "SPIC1_CS"
++	PIN 77: "GPIO_D"
++	PIN 78: "WATCHDOG"
++	PIN 79: "RTS3_N"
++	PIN 80: "CTS3_N"
++	PIN 81: "TXD3"
++	PIN 82: "RXD3"
++	PIN 83: "PERST0_N"
++	PIN 84: "PERST1_N"
++	PIN 85: "WLED_N"
++	PIN 86: "EPHY_LED0_N"
++	PIN 87: "AUXIN0"
++	PIN 88: "AUXIN1"
++	PIN 89: "AUXIN2"
++	PIN 90: "AUXIN3"
++	PIN 91: "TXD4"
++	PIN 92: "RXD4"
++	PIN 93: "RTS4_N"
++	PIN 94: "CST4_N"
++	PIN 95: "PWM1"
++	PIN 96: "PWM2"
++	PIN 97: "PWM3"
++	PIN 98: "PWM4"
++	PIN 99: "PWM5"
++	PIN 100: "PWM6"
++	PIN 101: "PWM7"
++	PIN 102: "GPIO_E"
++
++Valid values for function are:
++	"emmc", "eth", "i2c", "i2s", "ir", "led", "flash", "pcie",
++	"pmic", "pwm", "sd", "spi", "tdm", "uart", "watchdog"
++
++Valid values for groups are:
++additional data is put followingly with valid value allowing us to know which
++applicable function and which relevant pins (in pin#) are able applied for that
++group.
++
++	Valid value			function	pins (in pin#)
++	-------------------------------------------------------------------------
++	"emmc"				"emmc"		40, 41, 42, 43, 44, 45,
++							47, 48, 49, 50
++	"emmc_rst"			"emmc"		37
++	"esw"				"eth"		51, 52, 53, 54, 55, 56,
++							57, 58, 59, 60, 61, 62,
++							63, 64, 65, 66, 67, 68,
++							69, 70
++	"esw_p0_p1"			"eth"		51, 52, 53, 54, 55, 56,
++							57, 58
++	"esw_p2_p3_p4"			"eth"		59, 60, 61, 62, 63, 64,
++							65, 66, 67, 68, 69, 70
++	"rgmii_via_esw"			"eth"		59, 60, 61, 62, 63, 64,
++							65, 66, 67, 68, 69, 70
++	"rgmii_via_gmac1"		"eth"		59, 60, 61, 62, 63, 64,
++							65, 66, 67, 68, 69, 70
++	"rgmii_via_gmac2"		"eth"		25, 26, 27, 28, 29, 30,
++							31, 32, 33, 34, 35, 36
++	"mdc_mdio"			"eth"		23, 24
++	"i2c0"				"i2c"		14, 15
++	"i2c1_0"			"i2c"		55, 56
++	"i2c1_1"			"i2c"		73, 74
++	"i2c1_2"			"i2c"		87, 88
++	"i2c2_0"			"i2c"		57, 58
++	"i2c2_1"			"i2c"		75, 76
++	"i2c2_2"			"i2c"		89, 90
++	"i2s_in_mclk_bclk_ws"		"i2s"		3, 4, 5
++	"i2s1_in_data"			"i2s"		1
++	"i2s2_in_data"			"i2s"		16
++	"i2s3_in_data"			"i2s"		17
++	"i2s4_in_data"			"i2s"		18
++	"i2s_out_mclk_bclk_ws"		"i2s"		3, 4, 5
++	"i2s1_out_data"			"i2s"		2
++	"i2s2_out_data"			"i2s"		19
++	"i2s3_out_data"			"i2s"		20
++	"i2s4_out_data"			"i2s"		21
++	"ir_0_tx"			"ir"		16
++	"ir_1_tx"			"ir"		59
++	"ir_2_tx"			"ir"		99
++	"ir_0_rx"			"ir"		17
++	"ir_1_rx"			"ir"		60
++	"ir_2_rx"			"ir"		100
++	"ephy_leds"			"led"		86, 91, 92, 93, 94
++	"ephy0_led"			"led"		86
++	"ephy1_led"			"led"		91
++	"ephy2_led"			"led"		92
++	"ephy3_led"			"led"		93
++	"ephy4_led"			"led"		94
++	"wled"				"led"		85
++	"par_nand"			"flash"		37, 38, 39, 40, 41, 42,
++							43, 44, 45, 46, 47, 48,
++							49, 50
++	"snfi"				"flash"		8, 9, 10, 11, 12, 13
++	"spi_nor"			"flash"		8, 9, 10, 11, 12, 13
++	"pcie0_0_waken"			"pcie"		14
++	"pcie0_1_waken"			"pcie"		79
++	"pcie1_0_waken"			"pcie"		14
++	"pcie0_0_clkreq"		"pcie"		15
++	"pcie0_1_clkreq"		"pcie"		80
++	"pcie1_0_clkreq"		"pcie"		15
++	"pcie0_pad_perst"		"pcie"		83
++	"pcie1_pad_perst"		"pcie"		84
++	"pmic_bus"			"pmic"		71, 72
++	"pwm_ch1_0"			"pwm"		51
++	"pwm_ch1_1"			"pwm"		73
++	"pwm_ch1_2"			"pwm"		95
++	"pwm_ch2_0"			"pwm"		52
++	"pwm_ch2_1"			"pwm"		74
++	"pwm_ch2_2"			"pwm"		96
++	"pwm_ch3_0"			"pwm"		53
++	"pwm_ch3_1"			"pwm"		75
++	"pwm_ch3_2"			"pwm"		97
++	"pwm_ch4_0"			"pwm"		54
++	"pwm_ch4_1"			"pwm"		67
++	"pwm_ch4_2"			"pwm"		76
++	"pwm_ch4_3"			"pwm"		98
++	"pwm_ch5_0"			"pwm"		68
++	"pwm_ch5_1"			"pwm"		77
++	"pwm_ch5_2"			"pwm"		99
++	"pwm_ch6_0"			"pwm"		69
++	"pwm_ch6_1"			"pwm"		78
++	"pwm_ch6_2"			"pwm"		81
++	"pwm_ch6_3"			"pwm"		100
++	"pwm_ch7_0"			"pwm"		70
++	"pwm_ch7_1"			"pwm"		82
++	"pwm_ch7_2"			"pwm"		101
++	"sd_0"				"sd"		16, 17, 18, 19, 20, 21
++	"sd_1"				"sd"		25, 26, 27, 28, 29, 30
++	"spic0_0"			"spi"		63, 64, 65, 66
++	"spic0_1"			"spi"		79, 80, 81, 82
++	"spic1_0"			"spi"		67, 68, 69, 70
++	"spic1_1"			"spi"		73, 74, 75, 76
++	"spic2_0_wp_hold"		"spi"		8, 9
++	"spic2_0"			"spi"		10, 11, 12, 13
++	"tdm_0_out_mclk_bclk_ws"	"tdm"		8, 9, 10
++	"tdm_0_in_mclk_bclk_ws"		"tdm"		11, 12, 13
++	"tdm_0_out_data"		"tdm"		20
++	"tdm_0_in_data"			"tdm"		21
++	"tdm_1_out_mclk_bclk_ws"	"tdm"		57, 58, 59
++	"tdm_1_in_mclk_bclk_ws"		"tdm"		60, 61, 62
++	"tdm_1_out_data"		"tdm"		55
++	"tdm_1_in_data"			"tdm"		56
++	"uart0_0_tx_rx"			"uart"		6, 7
++	"uart1_0_tx_rx"			"uart"		55, 56
++	"uart1_0_rts_cts"		"uart"		57, 58
++	"uart1_1_tx_rx"			"uart"		73, 74
++	"uart1_1_rts_cts"		"uart"		75, 76
++	"uart2_0_tx_rx"			"uart"		3, 4
++	"uart2_0_rts_cts"		"uart"		1, 2
++	"uart2_1_tx_rx"			"uart"		51, 52
++	"uart2_1_rts_cts"		"uart"		53, 54
++	"uart2_2_tx_rx"			"uart"		59, 60
++	"uart2_2_rts_cts"		"uart"		61, 62
++	"uart2_3_tx_rx"			"uart"		95, 96
++	"uart3_0_tx_rx"			"uart"		57, 58
++	"uart3_1_tx_rx"			"uart"		81, 82
++	"uart3_1_rts_cts"		"uart"		79, 80
++	"uart4_0_tx_rx"			"uart"		61, 62
++	"uart4_1_tx_rx"			"uart"		91, 92
++	"uart4_1_rts_cts"		"uart"		93, 94
++	"uart4_2_tx_rx"			"uart"		97, 98
++	"uart4_2_rts_cts"		"uart"		95, 96
++	"watchdog"			"watchdog"	78
++
++Example:
++
++	pio: pinctrl@10211000 {
++		compatible = "mediatek,mt7622-pinctrl";
++		reg = <0 0x10211000 0 0x1000>;
++		gpio-controller;
++		#gpio-cells = <2>;
++
++		pinctrl_eth_default: eth-default {
++			mux-mdio {
++				groups = "mdc_mdio";
++				function = "eth";
++				drive-strength = <12>;
++			};
++
++			mux-gmac2 {
++				groups = "gmac2";
++				function = "eth";
++				drive-strength = <12>;
++			};
++
++			mux-esw {
++				groups = "esw";
++				function = "eth";
++				drive-strength = <8>;
++			};
++
++			conf-mdio {
++				pins = "MDC";
++				bias-pull-up;
++			};
++		};
++	};
+-- 
+2.11.0
+
diff --git a/target/linux/mediatek/patches-4.14/0170-pinctrl-mediatek-cleanup-for-placing-all-drivers-und.patch b/target/linux/mediatek/patches-4.14/0170-pinctrl-mediatek-cleanup-for-placing-all-drivers-und.patch
new file mode 100644
index 0000000000..264cfda099
--- /dev/null
+++ b/target/linux/mediatek/patches-4.14/0170-pinctrl-mediatek-cleanup-for-placing-all-drivers-und.patch
@@ -0,0 +1,37 @@
+From 547700768b2e7a105ed27a3b955fd9b7142987d7 Mon Sep 17 00:00:00 2001
+From: Sean Wang <sean.wang@mediatek.com>
+Date: Tue, 12 Dec 2017 14:24:19 +0800
+Subject: [PATCH 170/224] pinctrl: mediatek: cleanup for placing all drivers
+ under the menu
+
+Since lots of MediaTek drivers had been added, it seems slightly better
+for that adding cleanup for placing MediaTek pinctrl drivers under the
+independent menu as other kinds of drivers usually was done.
+
+Signed-off-by: Sean Wang <sean.wang@mediatek.com>
+Reviewed-by: Biao Huang <biao.huang@mediatek.com>
+Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
+---
+ drivers/pinctrl/mediatek/Kconfig | 5 +++--
+ 1 file changed, 3 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/pinctrl/mediatek/Kconfig b/drivers/pinctrl/mediatek/Kconfig
+index fac9866311f3..03b3023d5fe5 100644
+--- a/drivers/pinctrl/mediatek/Kconfig
++++ b/drivers/pinctrl/mediatek/Kconfig
+@@ -1,4 +1,5 @@
+-if ARCH_MEDIATEK || COMPILE_TEST
++menu "MediaTek pinctrl drivers"
++	depends on ARCH_MEDIATEK || COMPILE_TEST
+ 
+ config PINCTRL_MTK
+ 	bool
+@@ -46,4 +47,4 @@ config PINCTRL_MT6397
+ 	default MFD_MT6397
+ 	select PINCTRL_MTK
+ 
+-endif
++endmenu
+-- 
+2.11.0
+
diff --git a/target/linux/mediatek/patches-4.14/0171-pinctrl-mediatek-add-pinctrl-driver-for-MT7622-SoC.patch b/target/linux/mediatek/patches-4.14/0171-pinctrl-mediatek-add-pinctrl-driver-for-MT7622-SoC.patch
new file mode 100644
index 0000000000..312900ca37
--- /dev/null
+++ b/target/linux/mediatek/patches-4.14/0171-pinctrl-mediatek-add-pinctrl-driver-for-MT7622-SoC.patch
@@ -0,0 +1,1686 @@
+From 4318e143fe3ac617de20cf72aa32fd9d3ad92ee6 Mon Sep 17 00:00:00 2001
+From: Sean Wang <sean.wang@mediatek.com>
+Date: Tue, 12 Dec 2017 14:24:20 +0800
+Subject: [PATCH 171/224] pinctrl: mediatek: add pinctrl driver for MT7622 SoC
+
+Add support for pinctrl on MT7622 SoC. The IO core found on the SoC has
+the registers for pinctrl, pinconf and gpio mixed up in the same register
+range. However, the IO core for the MT7622 SoC is completely distinct from
+anyone of previous MediaTek SoCs which already had support, such as
+the hardware internal, register address map and register detailed
+definition for each pin.
+
+Therefore, instead, the driver is being newly implemented by reusing
+generic methods provided from the core layer with GENERIC_PINCONF,
+GENERIC_PINCTRL_GROUPS, and GENERIC_PINMUX_FUNCTIONS for the sake of code
+simplicity and rid of superfluous code. Where the function of pins
+determined by groups is utilized in this driver which can help developers
+less confused with what combinations of pins effective on the SoC and even
+reducing the mistakes during the integration of those relevant boards.
+
+As the gpio_chip handling is also only a few lines, the driver also
+implements the gpio functionality directly through GPIOLIB.
+
+Signed-off-by: Sean Wang <sean.wang@mediatek.com>
+Reviewed-by: Biao Huang <biao.huang@mediatek.com>
+Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
+---
+ drivers/pinctrl/Makefile                  |    2 +-
+ drivers/pinctrl/mediatek/Kconfig          |   10 +
+ drivers/pinctrl/mediatek/Makefile         |    3 +-
+ drivers/pinctrl/mediatek/pinctrl-mt7622.c | 1595 +++++++++++++++++++++++++++++
+ 4 files changed, 1608 insertions(+), 2 deletions(-)
+ create mode 100644 drivers/pinctrl/mediatek/pinctrl-mt7622.c
+
+diff --git a/drivers/pinctrl/Makefile b/drivers/pinctrl/Makefile
+index c16e27900dbb..3a798d5b0900 100644
+--- a/drivers/pinctrl/Makefile
++++ b/drivers/pinctrl/Makefile
+@@ -63,5 +63,5 @@ obj-$(CONFIG_PINCTRL_SUNXI)	+= sunxi/
+ obj-y				+= ti/
+ obj-$(CONFIG_PINCTRL_UNIPHIER)	+= uniphier/
+ obj-$(CONFIG_ARCH_VT8500)	+= vt8500/
+-obj-$(CONFIG_PINCTRL_MTK)	+= mediatek/
++obj-y				+= mediatek/
+ obj-$(CONFIG_PINCTRL_ZX)	+= zte/
+diff --git a/drivers/pinctrl/mediatek/Kconfig b/drivers/pinctrl/mediatek/Kconfig
+index 03b3023d5fe5..3e598740b379 100644
+--- a/drivers/pinctrl/mediatek/Kconfig
++++ b/drivers/pinctrl/mediatek/Kconfig
+@@ -32,6 +32,16 @@ config PINCTRL_MT8127
+ 	select PINCTRL_MTK
+ 
+ # For ARMv8 SoCs
++config PINCTRL_MT7622
++	bool "MediaTek MT7622 pin control"
++	depends on OF
++	depends on ARM64 || COMPILE_TEST
++	select GENERIC_PINCONF
++	select GENERIC_PINCTRL_GROUPS
++	select GENERIC_PINMUX_FUNCTIONS
++	select GPIOLIB
++	select OF_GPIO
++
+ config PINCTRL_MT8173
+ 	bool "Mediatek MT8173 pin control"
+ 	depends on OF
+diff --git a/drivers/pinctrl/mediatek/Makefile b/drivers/pinctrl/mediatek/Makefile
+index e59c613d4ddd..6e3ca6bbda7a 100644
+--- a/drivers/pinctrl/mediatek/Makefile
++++ b/drivers/pinctrl/mediatek/Makefile
+@@ -1,9 +1,10 @@
+ # Core
+-obj-y				+= pinctrl-mtk-common.o
++obj-$(CONFIG_PINCTRL_MTK)	+= pinctrl-mtk-common.o
+ 
+ # SoC Drivers
+ obj-$(CONFIG_PINCTRL_MT2701)	+= pinctrl-mt2701.o
+ obj-$(CONFIG_PINCTRL_MT8135)	+= pinctrl-mt8135.o
+ obj-$(CONFIG_PINCTRL_MT8127)	+= pinctrl-mt8127.o
++obj-$(CONFIG_PINCTRL_MT7622)	+= pinctrl-mt7622.o
+ obj-$(CONFIG_PINCTRL_MT8173)	+= pinctrl-mt8173.o
+ obj-$(CONFIG_PINCTRL_MT6397)	+= pinctrl-mt6397.o
+diff --git a/drivers/pinctrl/mediatek/pinctrl-mt7622.c b/drivers/pinctrl/mediatek/pinctrl-mt7622.c
+new file mode 100644
+index 000000000000..3824d82888ac
+--- /dev/null
++++ b/drivers/pinctrl/mediatek/pinctrl-mt7622.c
+@@ -0,0 +1,1595 @@
++/*
++ * MediaTek MT7622 Pinctrl Driver
++ *
++ * Copyright (C) 2017 Sean Wang <sean.wang@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.
++ */
++
++#include <linux/gpio.h>
++#include <linux/gpio/driver.h>
++#include <linux/io.h>
++#include <linux/init.h>
++#include <linux/mfd/syscon.h>
++#include <linux/of.h>
++#include <linux/of_platform.h>
++#include <linux/platform_device.h>
++#include <linux/pinctrl/pinctrl.h>
++#include <linux/pinctrl/pinmux.h>
++#include <linux/pinctrl/pinconf.h>
++#include <linux/pinctrl/pinconf-generic.h>
++#include <linux/regmap.h>
++
++#include "../core.h"
++#include "../pinconf.h"
++#include "../pinmux.h"
++
++#define PINCTRL_PINCTRL_DEV		KBUILD_MODNAME
++#define MTK_RANGE(_a)		{ .range = (_a), .nranges = ARRAY_SIZE(_a), }
++#define PINCTRL_PIN_GROUP(name, id)			\
++	{						\
++		name,					\
++		id##_pins,				\
++		ARRAY_SIZE(id##_pins),			\
++		id##_funcs,				\
++	}
++
++#define MTK_GPIO_MODE	1
++#define MTK_INPUT	0
++#define MTK_OUTPUT	1
++#define MTK_DISABLE	0
++#define MTK_ENABLE	1
++
++/* Custom pinconf parameters */
++#define MTK_PIN_CONFIG_TDSEL	(PIN_CONFIG_END + 1)
++#define MTK_PIN_CONFIG_RDSEL	(PIN_CONFIG_END + 2)
++
++/* List these attributes which could be modified for the pin */
++enum {
++	PINCTRL_PIN_REG_MODE,
++	PINCTRL_PIN_REG_DIR,
++	PINCTRL_PIN_REG_DI,
++	PINCTRL_PIN_REG_DO,
++	PINCTRL_PIN_REG_SR,
++	PINCTRL_PIN_REG_SMT,
++	PINCTRL_PIN_REG_PD,
++	PINCTRL_PIN_REG_PU,
++	PINCTRL_PIN_REG_E4,
++	PINCTRL_PIN_REG_E8,
++	PINCTRL_PIN_REG_TDSEL,
++	PINCTRL_PIN_REG_RDSEL,
++	PINCTRL_PIN_REG_MAX,
++};
++
++/* struct mtk_pin_field - the structure that holds the information of the field
++ *			  used to describe the attribute for the pin
++ * @offset:		the register offset relative to the base address
++ * @mask:		the mask used to filter out the field from the register
++ * @bitpos:		the start bit relative to the register
++ * @next:		the indication that the field would be extended to the
++			next register
++ */
++struct mtk_pin_field {
++	u32 offset;
++	u32 mask;
++	u8  bitpos;
++	u8  next;
++};
++
++/* struct mtk_pin_field_calc - the structure that holds the range providing
++ *			       the guide used to look up the relevant field
++ * @s_pin:		the start pin within the range
++ * @e_pin:		the end pin within the range
++ * @s_addr:		the start address for the range
++ * @x_addrs:		the address distance between two consecutive registers
++ *			within the range
++ * @s_bit:		the start bit for the first register within the range
++ * @x_bits:		the bit distance between two consecutive pins within
++ *			the range
++ */
++struct mtk_pin_field_calc {
++	u16 s_pin;
++	u16 e_pin;
++	u32 s_addr;
++	u8  x_addrs;
++	u8  s_bit;
++	u8  x_bits;
++};
++
++/* struct mtk_pin_reg_calc - the structure that holds all ranges used to
++ *			     determine which register the pin would make use of
++ *			     for certain pin attribute.
++ * @range:		     the start address for the range
++ * @nranges:		     the number of items in the range
++ */
++struct mtk_pin_reg_calc {
++	const struct mtk_pin_field_calc *range;
++	unsigned int nranges;
++};
++
++/* struct mtk_pin_soc - the structure that holds SoC-specific data */
++struct mtk_pin_soc {
++	const struct mtk_pin_reg_calc	*reg_cal;
++	const struct pinctrl_pin_desc	*pins;
++	unsigned int			npins;
++	const struct group_desc		*grps;
++	unsigned int			ngrps;
++	const struct function_desc	*funcs;
++	unsigned int			nfuncs;
++};
++
++struct mtk_pinctrl {
++	struct pinctrl_dev		*pctrl;
++	void __iomem			*base;
++	struct device			*dev;
++	struct gpio_chip		chip;
++	const struct mtk_pin_soc	*soc;
++};
++
++static const struct mtk_pin_field_calc mt7622_pin_mode_range[] = {
++	{0, 0, 0x320, 0x10, 16, 4},
++	{1, 4, 0x3a0, 0x10,  16, 4},
++	{5, 5, 0x320, 0x10,  0, 4},
++	{6, 6, 0x300, 0x10,  4, 4},
++	{7, 7, 0x300, 0x10,  4, 4},
++	{8, 9, 0x350, 0x10,  20, 4},
++	{10, 10, 0x300, 0x10, 8, 4},
++	{11, 11, 0x300, 0x10, 8, 4},
++	{12, 12, 0x300, 0x10, 8, 4},
++	{13, 13, 0x300, 0x10, 8, 4},
++	{14, 15, 0x320, 0x10, 4, 4},
++	{16, 17, 0x320, 0x10, 20, 4},
++	{18, 21, 0x310, 0x10, 16, 4},
++	{22, 22, 0x380, 0x10, 16, 4},
++	{23, 23, 0x300,	0x10, 24, 4},
++	{24, 24, 0x300, 0x10, 24, 4},
++	{25, 25, 0x300, 0x10, 12, 4},
++	{25, 25, 0x300, 0x10, 12, 4},
++	{26, 26, 0x300, 0x10, 12, 4},
++	{27, 27, 0x300, 0x10, 12, 4},
++	{28, 28, 0x300, 0x10, 12, 4},
++	{29, 29, 0x300, 0x10, 12, 4},
++	{30, 30, 0x300, 0x10, 12, 4},
++	{31, 31, 0x300, 0x10, 12, 4},
++	{32, 32, 0x300, 0x10, 12, 4},
++	{33, 33, 0x300,	0x10, 12, 4},
++	{34, 34, 0x300,	0x10, 12, 4},
++	{35, 35, 0x300,	0x10, 12, 4},
++	{36, 36, 0x300, 0x10, 12, 4},
++	{37, 37, 0x300, 0x10, 20, 4},
++	{38, 38, 0x300, 0x10, 20, 4},
++	{39, 39, 0x300, 0x10, 20, 4},
++	{40, 40, 0x300, 0x10, 20, 4},
++	{41, 41, 0x300,	0x10, 20, 4},
++	{42, 42, 0x300, 0x10, 20, 4},
++	{43, 43, 0x300,	0x10, 20, 4},
++	{44, 44, 0x300, 0x10, 20, 4},
++	{45, 46, 0x300, 0x10, 20, 4},
++	{47, 47, 0x300,	0x10, 20, 4},
++	{48, 48, 0x300, 0x10, 20, 4},
++	{49, 49, 0x300, 0x10, 20, 4},
++	{50, 50, 0x300, 0x10, 20, 4},
++	{51, 70, 0x330, 0x10, 4, 4},
++	{71, 71, 0x300, 0x10, 16, 4},
++	{72, 72, 0x300, 0x10, 16, 4},
++	{73, 76, 0x310, 0x10, 0, 4},
++	{77, 77, 0x320, 0x10, 28, 4},
++	{78, 78, 0x320, 0x10, 12, 4},
++	{79, 82, 0x3a0, 0x10, 0, 4},
++	{83, 83, 0x350,	0x10, 28, 4},
++	{84, 84, 0x330, 0x10, 0, 4},
++	{85, 90, 0x360, 0x10, 4, 4},
++	{91, 94, 0x390, 0x10, 16, 4},
++	{95, 97, 0x380, 0x10, 20, 4},
++	{98, 101, 0x390, 0x10, 0, 4},
++	{102, 102, 0x360, 0x10, 0, 4},
++};
++
++static const struct mtk_pin_field_calc mt7622_pin_dir_range[] = {
++	{0, 102, 0x0, 0x10, 0, 1},
++};
++
++static const struct mtk_pin_field_calc mt7622_pin_di_range[] = {
++	{0, 102, 0x200, 0x10, 0, 1},
++};
++
++static const struct mtk_pin_field_calc mt7622_pin_do_range[] = {
++	{0, 102, 0x100, 0x10, 0, 1},
++};
++
++static const struct mtk_pin_field_calc mt7622_pin_sr_range[] = {
++	{0, 31, 0x910, 0x10, 0, 1},
++	{32, 50, 0xa10, 0x10, 0, 1},
++	{51, 70, 0x810, 0x10, 0, 1},
++	{71, 72, 0xb10, 0x10, 0, 1},
++	{73, 86, 0xb10, 0x10, 4, 1},
++	{87, 90, 0xc10, 0x10, 0, 1},
++	{91, 102, 0xb10, 0x10, 18, 1},
++};
++
++static const struct mtk_pin_field_calc mt7622_pin_smt_range[] = {
++	{0, 31, 0x920, 0x10, 0, 1},
++	{32, 50, 0xa20, 0x10, 0, 1},
++	{51, 70, 0x820, 0x10, 0, 1},
++	{71, 72, 0xb20, 0x10, 0, 1},
++	{73, 86, 0xb20, 0x10, 4, 1},
++	{87, 90, 0xc20, 0x10, 0, 1},
++	{91, 102, 0xb20, 0x10, 18, 1},
++};
++
++static const struct mtk_pin_field_calc mt7622_pin_pu_range[] = {
++	{0, 31, 0x930, 0x10, 0, 1},
++	{32, 50, 0xa30, 0x10, 0, 1},
++	{51, 70, 0x830, 0x10, 0, 1},
++	{71, 72, 0xb30, 0x10, 0, 1},
++	{73, 86, 0xb30, 0x10, 4, 1},
++	{87, 90, 0xc30, 0x10, 0, 1},
++	{91, 102, 0xb30, 0x10, 18, 1},
++};
++
++static const struct mtk_pin_field_calc mt7622_pin_pd_range[] = {
++	{0, 31, 0x940, 0x10, 0, 1},
++	{32, 50, 0xa40, 0x10, 0, 1},
++	{51, 70, 0x840, 0x10, 0, 1},
++	{71, 72, 0xb40, 0x10, 0, 1},
++	{73, 86, 0xb40, 0x10, 4, 1},
++	{87, 90, 0xc40, 0x10, 0, 1},
++	{91, 102, 0xb40, 0x10, 18, 1},
++};
++
++static const struct mtk_pin_field_calc mt7622_pin_e4_range[] = {
++	{0, 31, 0x960, 0x10, 0, 1},
++	{32, 50, 0xa60, 0x10, 0, 1},
++	{51, 70, 0x860, 0x10, 0, 1},
++	{71, 72, 0xb60, 0x10, 0, 1},
++	{73, 86, 0xb60, 0x10, 4, 1},
++	{87, 90, 0xc60, 0x10, 0, 1},
++	{91, 102, 0xb60, 0x10, 18, 1},
++};
++
++static const struct mtk_pin_field_calc mt7622_pin_e8_range[] = {
++	{0, 31, 0x970, 0x10, 0, 1},
++	{32, 50, 0xa70, 0x10, 0, 1},
++	{51, 70, 0x870, 0x10, 0, 1},
++	{71, 72, 0xb70, 0x10, 0, 1},
++	{73, 86, 0xb70, 0x10, 4, 1},
++	{87, 90, 0xc70, 0x10, 0, 1},
++	{91, 102, 0xb70, 0x10, 18, 1},
++};
++
++static const struct mtk_pin_field_calc mt7622_pin_tdsel_range[] = {
++	{0, 31, 0x980, 0x4, 0, 4},
++	{32, 50, 0xa80, 0x4, 0, 4},
++	{51, 70, 0x880, 0x4, 0, 4},
++	{71, 72, 0xb80, 0x4, 0, 4},
++	{73, 86, 0xb80, 0x4, 16, 4},
++	{87, 90, 0xc80, 0x4, 0, 4},
++	{91, 102, 0xb88, 0x4, 8, 4},
++};
++
++static const struct mtk_pin_field_calc mt7622_pin_rdsel_range[] = {
++	{0, 31, 0x990, 0x4, 0, 6},
++	{32, 50, 0xa90, 0x4, 0, 6},
++	{51, 58, 0x890, 0x4, 0, 6},
++	{59, 60, 0x894, 0x4, 28, 6},
++	{61, 62, 0x894, 0x4, 16, 6},
++	{63, 66, 0x898, 0x4, 8, 6},
++	{67, 68, 0x89c, 0x4, 12, 6},
++	{69, 70, 0x89c, 0x4, 0, 6},
++	{71, 72, 0xb90, 0x4, 0, 6},
++	{73, 86, 0xb90, 0x4, 24, 6},
++	{87, 90, 0xc90, 0x4, 0, 6},
++	{91, 102, 0xb9c, 0x4, 12, 6},
++};
++
++static const struct mtk_pin_reg_calc mt7622_reg_cals[PINCTRL_PIN_REG_MAX] = {
++	[PINCTRL_PIN_REG_MODE] = MTK_RANGE(mt7622_pin_mode_range),
++	[PINCTRL_PIN_REG_DIR] = MTK_RANGE(mt7622_pin_dir_range),
++	[PINCTRL_PIN_REG_DI] = MTK_RANGE(mt7622_pin_di_range),
++	[PINCTRL_PIN_REG_DO] = MTK_RANGE(mt7622_pin_do_range),
++	[PINCTRL_PIN_REG_SR] = MTK_RANGE(mt7622_pin_sr_range),
++	[PINCTRL_PIN_REG_SMT] = MTK_RANGE(mt7622_pin_smt_range),
++	[PINCTRL_PIN_REG_PU] = MTK_RANGE(mt7622_pin_pu_range),
++	[PINCTRL_PIN_REG_PD] = MTK_RANGE(mt7622_pin_pd_range),
++	[PINCTRL_PIN_REG_E4] = MTK_RANGE(mt7622_pin_e4_range),
++	[PINCTRL_PIN_REG_E8] = MTK_RANGE(mt7622_pin_e8_range),
++	[PINCTRL_PIN_REG_TDSEL] = MTK_RANGE(mt7622_pin_tdsel_range),
++	[PINCTRL_PIN_REG_RDSEL] = MTK_RANGE(mt7622_pin_rdsel_range),
++};
++
++static const struct pinctrl_pin_desc mt7622_pins[] = {
++	PINCTRL_PIN(0, "GPIO_A"),
++	PINCTRL_PIN(1, "I2S1_IN"),
++	PINCTRL_PIN(2, "I2S1_OUT"),
++	PINCTRL_PIN(3, "I2S_BCLK"),
++	PINCTRL_PIN(4, "I2S_WS"),
++	PINCTRL_PIN(5, "I2S_MCLK"),
++	PINCTRL_PIN(6, "TXD0"),
++	PINCTRL_PIN(7, "RXD0"),
++	PINCTRL_PIN(8, "SPI_WP"),
++	PINCTRL_PIN(9, "SPI_HOLD"),
++	PINCTRL_PIN(10, "SPI_CLK"),
++	PINCTRL_PIN(11, "SPI_MOSI"),
++	PINCTRL_PIN(12, "SPI_MISO"),
++	PINCTRL_PIN(13, "SPI_CS"),
++	PINCTRL_PIN(14, "I2C_SDA"),
++	PINCTRL_PIN(15, "I2C_SCL"),
++	PINCTRL_PIN(16, "I2S2_IN"),
++	PINCTRL_PIN(17, "I2S3_IN"),
++	PINCTRL_PIN(18, "I2S4_IN"),
++	PINCTRL_PIN(19, "I2S2_OUT"),
++	PINCTRL_PIN(20, "I2S3_OUT"),
++	PINCTRL_PIN(21, "I2S4_OUT"),
++	PINCTRL_PIN(22, "GPIO_B"),
++	PINCTRL_PIN(23, "MDC"),
++	PINCTRL_PIN(24, "MDIO"),
++	PINCTRL_PIN(25, "G2_TXD0"),
++	PINCTRL_PIN(26, "G2_TXD1"),
++	PINCTRL_PIN(27, "G2_TXD2"),
++	PINCTRL_PIN(28, "G2_TXD3"),
++	PINCTRL_PIN(29, "G2_TXEN"),
++	PINCTRL_PIN(30, "G2_TXC"),
++	PINCTRL_PIN(31, "G2_RXD0"),
++	PINCTRL_PIN(32, "G2_RXD1"),
++	PINCTRL_PIN(33, "G2_RXD2"),
++	PINCTRL_PIN(34, "G2_RXD3"),
++	PINCTRL_PIN(35, "G2_RXDV"),
++	PINCTRL_PIN(36, "G2_RXC"),
++	PINCTRL_PIN(37, "NCEB"),
++	PINCTRL_PIN(38, "NWEB"),
++	PINCTRL_PIN(39, "NREB"),
++	PINCTRL_PIN(40, "NDL4"),
++	PINCTRL_PIN(41, "NDL5"),
++	PINCTRL_PIN(42, "NDL6"),
++	PINCTRL_PIN(43, "NDL7"),
++	PINCTRL_PIN(44, "NRB"),
++	PINCTRL_PIN(45, "NCLE"),
++	PINCTRL_PIN(46, "NALE"),
++	PINCTRL_PIN(47, "NDL0"),
++	PINCTRL_PIN(48, "NDL1"),
++	PINCTRL_PIN(49, "NDL2"),
++	PINCTRL_PIN(50, "NDL3"),
++	PINCTRL_PIN(51, "MDI_TP_P0"),
++	PINCTRL_PIN(52, "MDI_TN_P0"),
++	PINCTRL_PIN(53, "MDI_RP_P0"),
++	PINCTRL_PIN(54, "MDI_RN_P0"),
++	PINCTRL_PIN(55, "MDI_TP_P1"),
++	PINCTRL_PIN(56, "MDI_TN_P1"),
++	PINCTRL_PIN(57, "MDI_RP_P1"),
++	PINCTRL_PIN(58, "MDI_RN_P1"),
++	PINCTRL_PIN(59, "MDI_RP_P2"),
++	PINCTRL_PIN(60, "MDI_RN_P2"),
++	PINCTRL_PIN(61, "MDI_TP_P2"),
++	PINCTRL_PIN(62, "MDI_TN_P2"),
++	PINCTRL_PIN(63, "MDI_TP_P3"),
++	PINCTRL_PIN(64, "MDI_TN_P3"),
++	PINCTRL_PIN(65, "MDI_RP_P3"),
++	PINCTRL_PIN(66, "MDI_RN_P3"),
++	PINCTRL_PIN(67, "MDI_RP_P4"),
++	PINCTRL_PIN(68, "MDI_RN_P4"),
++	PINCTRL_PIN(69, "MDI_TP_P4"),
++	PINCTRL_PIN(70, "MDI_TN_P4"),
++	PINCTRL_PIN(71, "PMIC_SCL"),
++	PINCTRL_PIN(72, "PMIC_SDA"),
++	PINCTRL_PIN(73, "SPIC1_CLK"),
++	PINCTRL_PIN(74, "SPIC1_MOSI"),
++	PINCTRL_PIN(75, "SPIC1_MISO"),
++	PINCTRL_PIN(76, "SPIC1_CS"),
++	PINCTRL_PIN(77, "GPIO_D"),
++	PINCTRL_PIN(78, "WATCHDOG"),
++	PINCTRL_PIN(79, "RTS3_N"),
++	PINCTRL_PIN(80, "CTS3_N"),
++	PINCTRL_PIN(81, "TXD3"),
++	PINCTRL_PIN(82, "RXD3"),
++	PINCTRL_PIN(83, "PERST0_N"),
++	PINCTRL_PIN(84, "PERST1_N"),
++	PINCTRL_PIN(85, "WLED_N"),
++	PINCTRL_PIN(86, "EPHY_LED0_N"),
++	PINCTRL_PIN(87, "AUXIN0"),
++	PINCTRL_PIN(88, "AUXIN1"),
++	PINCTRL_PIN(89, "AUXIN2"),
++	PINCTRL_PIN(90, "AUXIN3"),
++	PINCTRL_PIN(91, "TXD4"),
++	PINCTRL_PIN(92, "RXD4"),
++	PINCTRL_PIN(93, "RTS4_N"),
++	PINCTRL_PIN(94, "CTS4_N"),
++	PINCTRL_PIN(95, "PWM1"),
++	PINCTRL_PIN(96, "PWM2"),
++	PINCTRL_PIN(97, "PWM3"),
++	PINCTRL_PIN(98, "PWM4"),
++	PINCTRL_PIN(99, "PWM5"),
++	PINCTRL_PIN(100, "PWM6"),
++	PINCTRL_PIN(101, "PWM7"),
++	PINCTRL_PIN(102, "GPIO_E"),
++};
++
++/* List all groups consisting of these pins dedicated to the enablement of
++ * certain hardware block and the corresponding mode for all of the pins. The
++ * hardware probably has multiple combinations of these pinouts.
++ */
++
++/* EMMC */
++static int mt7622_emmc_pins[] = { 40, 41, 42, 43, 44, 45, 47, 48, 49, 50, };
++static int mt7622_emmc_funcs[] = { 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, };
++
++static int mt7622_emmc_rst_pins[] = { 37, };
++static int mt7622_emmc_rst_funcs[] = { 1, };
++
++/* LED for EPHY */
++static int mt7622_ephy_leds_pins[] = { 86, 91, 92, 93, 94, };
++static int mt7622_ephy_leds_funcs[] = { 0, 0, 0, 0, 0, };
++static int mt7622_ephy0_led_pins[] = { 86, };
++static int mt7622_ephy0_led_funcs[] = { 0, };
++static int mt7622_ephy1_led_pins[] = { 91, };
++static int mt7622_ephy1_led_funcs[] = { 2, };
++static int mt7622_ephy2_led_pins[] = { 92, };
++static int mt7622_ephy2_led_funcs[] = { 2, };
++static int mt7622_ephy3_led_pins[] = { 93, };
++static int mt7622_ephy3_led_funcs[] = { 2, };
++static int mt7622_ephy4_led_pins[] = { 94, };
++static int mt7622_ephy4_led_funcs[] = { 2, };
++
++/* Embedded Switch */
++static int mt7622_esw_pins[] = { 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61,
++				 62, 63, 64, 65, 66, 67, 68, 69, 70, };
++static int mt7622_esw_funcs[] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
++				  0, 0, 0, 0, 0, 0, 0, 0, 0, };
++static int mt7622_esw_p0_p1_pins[] = { 51, 52, 53, 54, 55, 56, 57, 58, };
++static int mt7622_esw_p0_p1_funcs[] = { 0, 0, 0, 0, 0, 0, 0, 0, };
++static int mt7622_esw_p2_p3_p4_pins[] = { 59, 60, 61, 62, 63, 64, 65, 66, 67,
++					  68, 69, 70, };
++static int mt7622_esw_p2_p3_p4_funcs[] = { 0, 0, 0, 0, 0, 0, 0, 0, 0,
++					   0, 0, 0, };
++/* RGMII via ESW */
++static int mt7622_rgmii_via_esw_pins[] = { 59, 60, 61, 62, 63, 64, 65, 66,
++					   67, 68, 69, 70, };
++static int mt7622_rgmii_via_esw_funcs[] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
++					    0, };
++
++/* RGMII via GMAC1 */
++static int mt7622_rgmii_via_gmac1_pins[] = { 59, 60, 61, 62, 63, 64, 65, 66,
++					     67, 68, 69, 70, };
++static int mt7622_rgmii_via_gmac1_funcs[] = { 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
++					      2, };
++
++/* RGMII via GMAC2 */
++static int mt7622_rgmii_via_gmac2_pins[] = { 25, 26, 27, 28, 29, 30, 31, 32,
++					     33, 34, 35, 36, };
++static int mt7622_rgmii_via_gmac2_funcs[] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
++					      0, };
++
++/* I2C */
++static int mt7622_i2c0_pins[] = { 14, 15, };
++static int mt7622_i2c0_funcs[] = { 0, 0, };
++static int mt7622_i2c1_0_pins[] = { 55, 56, };
++static int mt7622_i2c1_0_funcs[] = { 0, 0, };
++static int mt7622_i2c1_1_pins[] = { 73, 74, };
++static int mt7622_i2c1_1_funcs[] = { 3, 3, };
++static int mt7622_i2c1_2_pins[] = { 87, 88, };
++static int mt7622_i2c1_2_funcs[] = { 0, 0, };
++static int mt7622_i2c2_0_pins[] = { 57, 58, };
++static int mt7622_i2c2_0_funcs[] = { 0, 0, };
++static int mt7622_i2c2_1_pins[] = { 75, 76, };
++static int mt7622_i2c2_1_funcs[] = { 3, 3, };
++static int mt7622_i2c2_2_pins[] = { 89, 90, };
++static int mt7622_i2c2_2_funcs[] = { 0, 0, };
++
++/* I2S */
++static int mt7622_i2s_in_mclk_bclk_ws_pins[] = { 3, 4, 5, };
++static int mt7622_i2s_in_mclk_bclk_ws_funcs[] = { 3, 3, 0, };
++static int mt7622_i2s1_in_data_pins[] = { 1, };
++static int mt7622_i2s1_in_data_funcs[] = { 0, };
++static int mt7622_i2s2_in_data_pins[] = { 16, };
++static int mt7622_i2s2_in_data_funcs[] = { 0, };
++static int mt7622_i2s3_in_data_pins[] = { 17, };
++static int mt7622_i2s3_in_data_funcs[] = { 0, };
++static int mt7622_i2s4_in_data_pins[] = { 18, };
++static int mt7622_i2s4_in_data_funcs[] = { 0, };
++static int mt7622_i2s_out_mclk_bclk_ws_pins[] = { 3, 4, 5, };
++static int mt7622_i2s_out_mclk_bclk_ws_funcs[] = { 0, 0, 0, };
++static int mt7622_i2s1_out_data_pins[] = { 2, };
++static int mt7622_i2s1_out_data_funcs[] = { 0, };
++static int mt7622_i2s2_out_data_pins[] = { 19, };
++static int mt7622_i2s2_out_data_funcs[] = { 0, };
++static int mt7622_i2s3_out_data_pins[] = { 20, };
++static int mt7622_i2s3_out_data_funcs[] = { 0, };
++static int mt7622_i2s4_out_data_pins[] = { 21, };
++static int mt7622_i2s4_out_data_funcs[] = { 0, };
++
++/* IR */
++static int mt7622_ir_0_tx_pins[] = { 16, };
++static int mt7622_ir_0_tx_funcs[] = { 4, };
++static int mt7622_ir_1_tx_pins[] = { 59, };
++static int mt7622_ir_1_tx_funcs[] = { 5, };
++static int mt7622_ir_2_tx_pins[] = { 99, };
++static int mt7622_ir_2_tx_funcs[] = { 3, };
++static int mt7622_ir_0_rx_pins[] = { 17, };
++static int mt7622_ir_0_rx_funcs[] = { 4, };
++static int mt7622_ir_1_rx_pins[] = { 60, };
++static int mt7622_ir_1_rx_funcs[] = { 5, };
++static int mt7622_ir_2_rx_pins[] = { 100, };
++static int mt7622_ir_2_rx_funcs[] = { 3, };
++
++/* MDIO */
++static int mt7622_mdc_mdio_pins[] = { 23, 24, };
++static int mt7622_mdc_mdio_funcs[] = { 0, 0, };
++
++/* PCIE */
++static int mt7622_pcie0_0_waken_pins[] = { 14, };
++static int mt7622_pcie0_0_waken_funcs[] = { 2, };
++static int mt7622_pcie0_0_clkreq_pins[] = { 15, };
++static int mt7622_pcie0_0_clkreq_funcs[] = { 2, };
++static int mt7622_pcie0_1_waken_pins[] = { 79, };
++static int mt7622_pcie0_1_waken_funcs[] = { 4, };
++static int mt7622_pcie0_1_clkreq_pins[] = { 80, };
++static int mt7622_pcie0_1_clkreq_funcs[] = { 4, };
++static int mt7622_pcie1_0_waken_pins[] = { 14, };
++static int mt7622_pcie1_0_waken_funcs[] = { 3, };
++static int mt7622_pcie1_0_clkreq_pins[] = { 15, };
++static int mt7622_pcie1_0_clkreq_funcs[] = { 3, };
++
++static int mt7622_pcie0_pad_perst_pins[] = { 83, };
++static int mt7622_pcie0_pad_perst_funcs[] = { 0, };
++static int mt7622_pcie1_pad_perst_pins[] = { 84, };
++static int mt7622_pcie1_pad_perst_funcs[] = { 0, };
++
++/* PMIC bus */
++static int mt7622_pmic_bus_pins[] = { 71, 72, };
++static int mt7622_pmic_bus_funcs[] = { 0, 0, };
++
++/* Parallel NAND */
++static int mt7622_pnand_pins[] = { 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47,
++				   48, 49, 50, };
++static int mt7622_pnand_funcs[] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
++				    0, };
++
++/* PWM */
++static int mt7622_pwm_ch1_0_pins[] = { 51, };
++static int mt7622_pwm_ch1_0_funcs[] = { 3, };
++static int mt7622_pwm_ch1_1_pins[] = { 73, };
++static int mt7622_pwm_ch1_1_funcs[] = { 4, };
++static int mt7622_pwm_ch1_2_pins[] = { 95, };
++static int mt7622_pwm_ch1_2_funcs[] = { 0, };
++static int mt7622_pwm_ch2_0_pins[] = { 52, };
++static int mt7622_pwm_ch2_0_funcs[] = { 3, };
++static int mt7622_pwm_ch2_1_pins[] = { 74, };
++static int mt7622_pwm_ch2_1_funcs[] = { 4, };
++static int mt7622_pwm_ch2_2_pins[] = { 96, };
++static int mt7622_pwm_ch2_2_funcs[] = { 0, };
++static int mt7622_pwm_ch3_0_pins[] = { 53, };
++static int mt7622_pwm_ch3_0_funcs[] = { 3, };
++static int mt7622_pwm_ch3_1_pins[] = { 75, };
++static int mt7622_pwm_ch3_1_funcs[] = { 4, };
++static int mt7622_pwm_ch3_2_pins[] = { 97, };
++static int mt7622_pwm_ch3_2_funcs[] = { 0, };
++static int mt7622_pwm_ch4_0_pins[] = { 54, };
++static int mt7622_pwm_ch4_0_funcs[] = { 3, };
++static int mt7622_pwm_ch4_1_pins[] = { 67, };
++static int mt7622_pwm_ch4_1_funcs[] = { 3, };
++static int mt7622_pwm_ch4_2_pins[] = { 76, };
++static int mt7622_pwm_ch4_2_funcs[] = { 4, };
++static int mt7622_pwm_ch4_3_pins[] = { 98, };
++static int mt7622_pwm_ch4_3_funcs[] = { 0, };
++static int mt7622_pwm_ch5_0_pins[] = { 68, };
++static int mt7622_pwm_ch5_0_funcs[] = { 3, };
++static int mt7622_pwm_ch5_1_pins[] = { 77, };
++static int mt7622_pwm_ch5_1_funcs[] = { 4, };
++static int mt7622_pwm_ch5_2_pins[] = { 99, };
++static int mt7622_pwm_ch5_2_funcs[] = { 0, };
++static int mt7622_pwm_ch6_0_pins[] = { 69, };
++static int mt7622_pwm_ch6_0_funcs[] = { 3, };
++static int mt7622_pwm_ch6_1_pins[] = { 78, };
++static int mt7622_pwm_ch6_1_funcs[] = { 4, };
++static int mt7622_pwm_ch6_2_pins[] = { 81, };
++static int mt7622_pwm_ch6_2_funcs[] = { 4, };
++static int mt7622_pwm_ch6_3_pins[] = { 100, };
++static int mt7622_pwm_ch6_3_funcs[] = { 0, };
++static int mt7622_pwm_ch7_0_pins[] = { 70, };
++static int mt7622_pwm_ch7_0_funcs[] = { 3, };
++static int mt7622_pwm_ch7_1_pins[] = { 82, };
++static int mt7622_pwm_ch7_1_funcs[] = { 4, };
++static int mt7622_pwm_ch7_2_pins[] = { 101, };
++static int mt7622_pwm_ch7_2_funcs[] = { 0, };
++
++/* SD */
++static int mt7622_sd_0_pins[] = { 16, 17, 18, 19, 20, 21, };
++static int mt7622_sd_0_funcs[] = { 2, 2, 2, 2, 2, 2, };
++static int mt7622_sd_1_pins[] = { 25, 26, 27, 28, 29, 30, };
++static int mt7622_sd_1_funcs[] = { 2, 2, 2, 2, 2, 2, };
++
++/* Serial NAND */
++static int mt7622_snfi_pins[] = { 8, 9, 10, 11, 12, 13, };
++static int mt7622_snfi_funcs[] = { 2, 2, 2, 2, 2, 2, };
++
++/* SPI NOR */
++static int mt7622_spi_pins[] = { 8, 9, 10, 11, 12, 13 };
++static int mt7622_spi_funcs[] = { 0, 0, 0, 0, 0, 0, };
++
++/* SPIC */
++static int mt7622_spic0_0_pins[] = { 63, 64, 65, 66, };
++static int mt7622_spic0_0_funcs[] = { 4, 4, 4, 4, };
++static int mt7622_spic0_1_pins[] = { 79, 80, 81, 82, };
++static int mt7622_spic0_1_funcs[] = { 3, 3, 3, 3, };
++static int mt7622_spic1_0_pins[] = { 67, 68, 69, 70, };
++static int mt7622_spic1_0_funcs[] = { 4, 4, 4, 4, };
++static int mt7622_spic1_1_pins[] = { 73, 74, 75, 76, };
++static int mt7622_spic1_1_funcs[] = { 0, 0, 0, 0, };
++static int mt7622_spic2_0_pins[] = { 10, 11, 12, 13, };
++static int mt7622_spic2_0_funcs[] = { 0, 0, 0, 0, };
++static int mt7622_spic2_0_wp_hold_pins[] = { 8, 9, };
++static int mt7622_spic2_0_wp_hold_funcs[] = { 0, 0, };
++
++/* TDM */
++static int mt7622_tdm_0_out_mclk_bclk_ws_pins[] = { 8, 9, 10, };
++static int mt7622_tdm_0_out_mclk_bclk_ws_funcs[] = { 3, 3, 3, };
++static int mt7622_tdm_0_in_mclk_bclk_ws_pins[] = { 11, 12, 13, };
++static int mt7622_tdm_0_in_mclk_bclk_ws_funcs[] = { 3, 3, 3, };
++static int mt7622_tdm_0_out_data_pins[] = { 20, };
++static int mt7622_tdm_0_out_data_funcs[] = { 3, };
++static int mt7622_tdm_0_in_data_pins[] = { 21, };
++static int mt7622_tdm_0_in_data_funcs[] = { 3, };
++static int mt7622_tdm_1_out_mclk_bclk_ws_pins[] = { 57, 58, 59, };
++static int mt7622_tdm_1_out_mclk_bclk_ws_funcs[] = { 3, 3, 3, };
++static int mt7622_tdm_1_in_mclk_bclk_ws_pins[] = { 60, 61, 62, };
++static int mt7622_tdm_1_in_mclk_bclk_ws_funcs[] = { 3, 3, 3, };
++static int mt7622_tdm_1_out_data_pins[] = { 55, };
++static int mt7622_tdm_1_out_data_funcs[] = { 3, };
++static int mt7622_tdm_1_in_data_pins[] = { 56, };
++static int mt7622_tdm_1_in_data_funcs[] = { 3, };
++
++/* UART */
++static int mt7622_uart0_0_tx_rx_pins[] = { 6, 7, };
++static int mt7622_uart0_0_tx_rx_funcs[] = { 0, 0, };
++static int mt7622_uart1_0_tx_rx_pins[] = { 55, 56, };
++static int mt7622_uart1_0_tx_rx_funcs[] = { 2, 2, };
++static int mt7622_uart1_0_rts_cts_pins[] = { 57, 58, };
++static int mt7622_uart1_0_rts_cts_funcs[] = { 2, 2, };
++static int mt7622_uart1_1_tx_rx_pins[] = { 73, 74, };
++static int mt7622_uart1_1_tx_rx_funcs[] = { 2, 2, };
++static int mt7622_uart1_1_rts_cts_pins[] = { 75, 76, };
++static int mt7622_uart1_1_rts_cts_funcs[] = { 2, 2, };
++static int mt7622_uart2_0_tx_rx_pins[] = { 3, 4, };
++static int mt7622_uart2_0_tx_rx_funcs[] = { 2, 2, };
++static int mt7622_uart2_0_rts_cts_pins[] = { 1, 2, };
++static int mt7622_uart2_0_rts_cts_funcs[] = { 2, 2, };
++static int mt7622_uart2_1_tx_rx_pins[] = { 51, 52, };
++static int mt7622_uart2_1_tx_rx_funcs[] = { 0, 0, };
++static int mt7622_uart2_1_rts_cts_pins[] = { 53, 54, };
++static int mt7622_uart2_1_rts_cts_funcs[] = { 0, 0, };
++static int mt7622_uart2_2_tx_rx_pins[] = { 59, 60, };
++static int mt7622_uart2_2_tx_rx_funcs[] = { 4, 4, };
++static int mt7622_uart2_2_rts_cts_pins[] = { 61, 62, };
++static int mt7622_uart2_2_rts_cts_funcs[] = { 4, 4, };
++static int mt7622_uart2_3_tx_rx_pins[] = { 95, 96, };
++static int mt7622_uart2_3_tx_rx_funcs[] = { 3, 3, };
++static int mt7622_uart3_0_tx_rx_pins[] = { 57, 58, };
++static int mt7622_uart3_0_tx_rx_funcs[] = { 5, 5, };
++static int mt7622_uart3_1_tx_rx_pins[] = { 81, 82, };
++static int mt7622_uart3_1_tx_rx_funcs[] = { 0, 0, };
++static int mt7622_uart3_1_rts_cts_pins[] = { 79, 80, };
++static int mt7622_uart3_1_rts_cts_funcs[] = { 0, 0, };
++static int mt7622_uart4_0_tx_rx_pins[] = { 61, 62, };
++static int mt7622_uart4_0_tx_rx_funcs[] = { 5, 5, };
++static int mt7622_uart4_1_tx_rx_pins[] = { 91, 92, };
++static int mt7622_uart4_1_tx_rx_funcs[] = { 0, 0, };
++static int mt7622_uart4_1_rts_cts_pins[] = { 93, 94 };
++static int mt7622_uart4_1_rts_cts_funcs[] = { 0, 0, };
++static int mt7622_uart4_2_tx_rx_pins[] = { 97, 98, };
++static int mt7622_uart4_2_tx_rx_funcs[] = { 2, 2, };
++static int mt7622_uart4_2_rts_cts_pins[] = { 95, 96 };
++static int mt7622_uart4_2_rts_cts_funcs[] = { 2, 2, };
++
++/* Watchdog */
++static int mt7622_watchdog_pins[] = { 78, };
++static int mt7622_watchdog_funcs[] = { 0, };
++
++/* WLAN LED */
++static int mt7622_wled_pins[] = { 85, };
++static int mt7622_wled_funcs[] = { 0, };
++
++static const struct group_desc mt7622_groups[] = {
++	PINCTRL_PIN_GROUP("emmc", mt7622_emmc),
++	PINCTRL_PIN_GROUP("emmc_rst", mt7622_emmc_rst),
++	PINCTRL_PIN_GROUP("ephy_leds", mt7622_ephy_leds),
++	PINCTRL_PIN_GROUP("ephy0_led", mt7622_ephy0_led),
++	PINCTRL_PIN_GROUP("ephy1_led", mt7622_ephy1_led),
++	PINCTRL_PIN_GROUP("ephy2_led", mt7622_ephy2_led),
++	PINCTRL_PIN_GROUP("ephy3_led", mt7622_ephy3_led),
++	PINCTRL_PIN_GROUP("ephy4_led", mt7622_ephy4_led),
++	PINCTRL_PIN_GROUP("esw", mt7622_esw),
++	PINCTRL_PIN_GROUP("esw_p0_p1", mt7622_esw_p0_p1),
++	PINCTRL_PIN_GROUP("esw_p2_p3_p4", mt7622_esw_p2_p3_p4),
++	PINCTRL_PIN_GROUP("rgmii_via_esw", mt7622_rgmii_via_esw),
++	PINCTRL_PIN_GROUP("rgmii_via_gmac1", mt7622_rgmii_via_gmac1),
++	PINCTRL_PIN_GROUP("rgmii_via_gmac2", mt7622_rgmii_via_gmac2),
++	PINCTRL_PIN_GROUP("i2c0", mt7622_i2c0),
++	PINCTRL_PIN_GROUP("i2c1_0", mt7622_i2c1_0),
++	PINCTRL_PIN_GROUP("i2c1_1", mt7622_i2c1_1),
++	PINCTRL_PIN_GROUP("i2c1_2", mt7622_i2c1_2),
++	PINCTRL_PIN_GROUP("i2c2_0", mt7622_i2c2_0),
++	PINCTRL_PIN_GROUP("i2c2_1", mt7622_i2c2_1),
++	PINCTRL_PIN_GROUP("i2c2_2", mt7622_i2c2_2),
++	PINCTRL_PIN_GROUP("i2s_out_mclk_bclk_ws", mt7622_i2s_out_mclk_bclk_ws),
++	PINCTRL_PIN_GROUP("i2s_in_mclk_bclk_ws", mt7622_i2s_in_mclk_bclk_ws),
++	PINCTRL_PIN_GROUP("i2s1_in_data", mt7622_i2s1_in_data),
++	PINCTRL_PIN_GROUP("i2s2_in_data", mt7622_i2s2_in_data),
++	PINCTRL_PIN_GROUP("i2s3_in_data", mt7622_i2s3_in_data),
++	PINCTRL_PIN_GROUP("i2s4_in_data", mt7622_i2s4_in_data),
++	PINCTRL_PIN_GROUP("i2s1_out_data", mt7622_i2s1_out_data),
++	PINCTRL_PIN_GROUP("i2s2_out_data", mt7622_i2s2_out_data),
++	PINCTRL_PIN_GROUP("i2s3_out_data", mt7622_i2s3_out_data),
++	PINCTRL_PIN_GROUP("i2s4_out_data", mt7622_i2s4_out_data),
++	PINCTRL_PIN_GROUP("ir_0_tx", mt7622_ir_0_tx),
++	PINCTRL_PIN_GROUP("ir_1_tx", mt7622_ir_1_tx),
++	PINCTRL_PIN_GROUP("ir_2_tx", mt7622_ir_2_tx),
++	PINCTRL_PIN_GROUP("ir_0_rx", mt7622_ir_0_rx),
++	PINCTRL_PIN_GROUP("ir_1_rx", mt7622_ir_1_rx),
++	PINCTRL_PIN_GROUP("ir_2_rx", mt7622_ir_2_rx),
++	PINCTRL_PIN_GROUP("mdc_mdio", mt7622_mdc_mdio),
++	PINCTRL_PIN_GROUP("pcie0_0_waken", mt7622_pcie0_0_waken),
++	PINCTRL_PIN_GROUP("pcie0_0_clkreq", mt7622_pcie0_0_clkreq),
++	PINCTRL_PIN_GROUP("pcie0_1_waken", mt7622_pcie0_1_waken),
++	PINCTRL_PIN_GROUP("pcie0_1_clkreq", mt7622_pcie0_1_clkreq),
++	PINCTRL_PIN_GROUP("pcie1_0_waken", mt7622_pcie1_0_waken),
++	PINCTRL_PIN_GROUP("pcie1_0_clkreq", mt7622_pcie1_0_clkreq),
++	PINCTRL_PIN_GROUP("pcie0_pad_perst", mt7622_pcie0_pad_perst),
++	PINCTRL_PIN_GROUP("pcie1_pad_perst", mt7622_pcie1_pad_perst),
++	PINCTRL_PIN_GROUP("par_nand", mt7622_pnand),
++	PINCTRL_PIN_GROUP("pmic_bus", mt7622_pmic_bus),
++	PINCTRL_PIN_GROUP("pwm_ch1_0", mt7622_pwm_ch1_0),
++	PINCTRL_PIN_GROUP("pwm_ch1_1", mt7622_pwm_ch1_1),
++	PINCTRL_PIN_GROUP("pwm_ch1_2", mt7622_pwm_ch1_2),
++	PINCTRL_PIN_GROUP("pwm_ch2_0", mt7622_pwm_ch2_0),
++	PINCTRL_PIN_GROUP("pwm_ch2_1", mt7622_pwm_ch2_1),
++	PINCTRL_PIN_GROUP("pwm_ch2_2", mt7622_pwm_ch2_2),
++	PINCTRL_PIN_GROUP("pwm_ch3_0", mt7622_pwm_ch3_0),
++	PINCTRL_PIN_GROUP("pwm_ch3_1", mt7622_pwm_ch3_1),
++	PINCTRL_PIN_GROUP("pwm_ch3_2", mt7622_pwm_ch3_2),
++	PINCTRL_PIN_GROUP("pwm_ch4_0", mt7622_pwm_ch4_0),
++	PINCTRL_PIN_GROUP("pwm_ch4_1", mt7622_pwm_ch4_1),
++	PINCTRL_PIN_GROUP("pwm_ch4_2", mt7622_pwm_ch4_2),
++	PINCTRL_PIN_GROUP("pwm_ch4_3", mt7622_pwm_ch4_3),
++	PINCTRL_PIN_GROUP("pwm_ch5_0", mt7622_pwm_ch5_0),
++	PINCTRL_PIN_GROUP("pwm_ch5_1", mt7622_pwm_ch5_1),
++	PINCTRL_PIN_GROUP("pwm_ch5_2", mt7622_pwm_ch5_2),
++	PINCTRL_PIN_GROUP("pwm_ch6_0", mt7622_pwm_ch6_0),
++	PINCTRL_PIN_GROUP("pwm_ch6_1", mt7622_pwm_ch6_1),
++	PINCTRL_PIN_GROUP("pwm_ch6_2", mt7622_pwm_ch6_2),
++	PINCTRL_PIN_GROUP("pwm_ch6_3", mt7622_pwm_ch6_3),
++	PINCTRL_PIN_GROUP("pwm_ch7_0", mt7622_pwm_ch7_0),
++	PINCTRL_PIN_GROUP("pwm_ch7_1", mt7622_pwm_ch7_1),
++	PINCTRL_PIN_GROUP("pwm_ch7_2", mt7622_pwm_ch7_2),
++	PINCTRL_PIN_GROUP("sd_0", mt7622_sd_0),
++	PINCTRL_PIN_GROUP("sd_1", mt7622_sd_1),
++	PINCTRL_PIN_GROUP("snfi", mt7622_snfi),
++	PINCTRL_PIN_GROUP("spi_nor", mt7622_spi),
++	PINCTRL_PIN_GROUP("spic0_0", mt7622_spic0_0),
++	PINCTRL_PIN_GROUP("spic0_1", mt7622_spic0_1),
++	PINCTRL_PIN_GROUP("spic1_0", mt7622_spic1_0),
++	PINCTRL_PIN_GROUP("spic1_1", mt7622_spic1_1),
++	PINCTRL_PIN_GROUP("spic2_0", mt7622_spic2_0),
++	PINCTRL_PIN_GROUP("spic2_0_wp_hold", mt7622_spic2_0_wp_hold),
++	PINCTRL_PIN_GROUP("tdm_0_out_mclk_bclk_ws",
++			  mt7622_tdm_0_out_mclk_bclk_ws),
++	PINCTRL_PIN_GROUP("tdm_0_in_mclk_bclk_ws",
++			  mt7622_tdm_0_in_mclk_bclk_ws),
++	PINCTRL_PIN_GROUP("tdm_0_out_data",  mt7622_tdm_0_out_data),
++	PINCTRL_PIN_GROUP("tdm_0_in_data", mt7622_tdm_0_in_data),
++	PINCTRL_PIN_GROUP("tdm_1_out_mclk_bclk_ws",
++			  mt7622_tdm_1_out_mclk_bclk_ws),
++	PINCTRL_PIN_GROUP("tdm_1_in_mclk_bclk_ws",
++			  mt7622_tdm_1_in_mclk_bclk_ws),
++	PINCTRL_PIN_GROUP("tdm_1_out_data",  mt7622_tdm_1_out_data),
++	PINCTRL_PIN_GROUP("tdm_1_in_data", mt7622_tdm_1_in_data),
++	PINCTRL_PIN_GROUP("uart0_0_tx_rx", mt7622_uart0_0_tx_rx),
++	PINCTRL_PIN_GROUP("uart1_0_tx_rx", mt7622_uart1_0_tx_rx),
++	PINCTRL_PIN_GROUP("uart1_0_rts_cts", mt7622_uart1_0_rts_cts),
++	PINCTRL_PIN_GROUP("uart1_1_tx_rx", mt7622_uart1_1_tx_rx),
++	PINCTRL_PIN_GROUP("uart1_1_rts_cts", mt7622_uart1_1_rts_cts),
++	PINCTRL_PIN_GROUP("uart2_0_tx_rx", mt7622_uart2_0_tx_rx),
++	PINCTRL_PIN_GROUP("uart2_0_rts_cts", mt7622_uart2_0_rts_cts),
++	PINCTRL_PIN_GROUP("uart2_1_tx_rx", mt7622_uart2_1_tx_rx),
++	PINCTRL_PIN_GROUP("uart2_1_rts_cts", mt7622_uart2_1_rts_cts),
++	PINCTRL_PIN_GROUP("uart2_2_tx_rx", mt7622_uart2_2_tx_rx),
++	PINCTRL_PIN_GROUP("uart2_2_rts_cts", mt7622_uart2_2_rts_cts),
++	PINCTRL_PIN_GROUP("uart2_3_tx_rx", mt7622_uart2_3_tx_rx),
++	PINCTRL_PIN_GROUP("uart3_0_tx_rx", mt7622_uart3_0_tx_rx),
++	PINCTRL_PIN_GROUP("uart3_1_tx_rx", mt7622_uart3_1_tx_rx),
++	PINCTRL_PIN_GROUP("uart3_1_rts_cts", mt7622_uart3_1_rts_cts),
++	PINCTRL_PIN_GROUP("uart4_0_tx_rx", mt7622_uart4_0_tx_rx),
++	PINCTRL_PIN_GROUP("uart4_1_tx_rx", mt7622_uart4_1_tx_rx),
++	PINCTRL_PIN_GROUP("uart4_1_rts_cts", mt7622_uart4_1_rts_cts),
++	PINCTRL_PIN_GROUP("uart4_2_tx_rx", mt7622_uart4_2_tx_rx),
++	PINCTRL_PIN_GROUP("uart4_2_rts_cts", mt7622_uart4_2_rts_cts),
++	PINCTRL_PIN_GROUP("watchdog", mt7622_watchdog),
++	PINCTRL_PIN_GROUP("wled", mt7622_wled),
++};
++
++/* Joint those groups owning the same capability in user point of view which
++ * allows that people tend to use through the device tree.
++ */
++static const char *mt7622_emmc_groups[] = { "emmc", "emmc_rst", };
++static const char *mt7622_ethernet_groups[] = { "esw", "esw_p0_p1",
++						"esw_p2_p3_p4", "mdc_mdio",
++						"rgmii_via_gmac1",
++						"rgmii_via_gmac2",
++						"rgmii_via_esw", };
++static const char *mt7622_i2c_groups[] = { "i2c0", "i2c1_0", "i2c1_1",
++					   "i2c1_2", "i2c2_0", "i2c2_1",
++					   "i2c2_2", };
++static const char *mt7622_i2s_groups[] = { "i2s_out_mclk_bclk_ws",
++					   "i2s_in_mclk_bclk_ws",
++					   "i2s1_in_data", "i2s2_in_data",
++					   "i2s3_in_data", "i2s4_in_data",
++					   "i2s1_out_data", "i2s2_out_data",
++					   "i2s3_out_data", "i2s4_out_data", };
++static const char *mt7622_ir_groups[] = { "ir_0_tx", "ir_1_tx", "ir_2_tx",
++					  "ir_0_rx", "ir_1_rx", "ir_2_rx"};
++static const char *mt7622_led_groups[] = { "ephy_leds", "ephy0_led",
++					   "ephy1_led", "ephy2_led",
++					   "ephy3_led", "ephy4_led",
++					   "wled", };
++static const char *mt7622_flash_groups[] = { "par_nand", "snfi", "spi_nor"};
++static const char *mt7622_pcie_groups[] = { "pcie0_0_waken", "pcie0_0_clkreq",
++					    "pcie0_1_waken", "pcie0_1_clkreq",
++					    "pcie1_0_waken", "pcie1_0_clkreq",
++					    "pcie0_pad_perst",
++					    "pcie1_pad_perst", };
++static const char *mt7622_pmic_bus_groups[] = { "pmic_bus", };
++static const char *mt7622_pwm_groups[] = { "pwm_ch1_0", "pwm_ch1_1",
++					   "pwm_ch1_2", "pwm_ch2_0",
++					   "pwm_ch2_1", "pwm_ch2_2",
++					   "pwm_ch3_0", "pwm_ch3_1",
++					   "pwm_ch3_2", "pwm_ch4_0",
++					   "pwm_ch4_1", "pwm_ch4_2",
++					   "pwm_ch4_3", "pwm_ch5_0",
++					   "pwm_ch5_1", "pwm_ch5_2",
++					   "pwm_ch6_0", "pwm_ch6_1",
++					   "pwm_ch6_2", "pwm_ch6_3",
++					   "pwm_ch7_0", "pwm_ch7_1",
++					   "pwm_ch7_2", };
++static const char *mt7622_sd_groups[] = { "sd_0", "sd_1", };
++static const char *mt7622_spic_groups[] = { "spic0_0", "spic0_1", "spic1_0",
++					    "spic1_1", "spic2_0",
++					    "spic2_0_wp_hold", };
++static const char *mt7622_tdm_groups[] = { "tdm_0_out_mclk_bclk_ws",
++					   "tdm_0_in_mclk_bclk_ws",
++					   "tdm_0_out_data",
++					   "tdm_0_in_data",
++					   "tdm_1_out_mclk_bclk_ws",
++					   "tdm_1_in_mclk_bclk_ws",
++					   "tdm_1_out_data",
++					   "tdm_1_in_data", };
++
++static const char *mt7622_uart_groups[] = { "uart0_0_tx_rx",
++					    "uart1_0_tx_rx", "uart1_0_rts_cts",
++					    "uart1_1_tx_rx", "uart1_1_rts_cts",
++					    "uart2_0_tx_rx", "uart2_0_rts_cts",
++					    "uart2_1_tx_rx", "uart2_1_rts_cts",
++					    "uart2_2_tx_rx", "uart2_2_rts_cts",
++					    "uart2_3_tx_rx",
++					    "uart3_0_tx_rx",
++					    "uart3_1_tx_rx", "uart3_1_rts_cts",
++					    "uart4_0_tx_rx",
++					    "uart4_1_tx_rx", "uart4_1_rts_cts",
++					    "uart4_2_tx_rx",
++					    "uart4_2_rts_cts",};
++static const char *mt7622_wdt_groups[] = { "watchdog", };
++
++static const struct function_desc mt7622_functions[] = {
++	{"emmc", mt7622_emmc_groups, ARRAY_SIZE(mt7622_emmc_groups)},
++	{"eth",	mt7622_ethernet_groups, ARRAY_SIZE(mt7622_ethernet_groups)},
++	{"i2c", mt7622_i2c_groups, ARRAY_SIZE(mt7622_i2c_groups)},
++	{"i2s",	mt7622_i2s_groups, ARRAY_SIZE(mt7622_i2s_groups)},
++	{"ir", mt7622_ir_groups, ARRAY_SIZE(mt7622_ir_groups)},
++	{"led",	mt7622_led_groups, ARRAY_SIZE(mt7622_led_groups)},
++	{"flash", mt7622_flash_groups, ARRAY_SIZE(mt7622_flash_groups)},
++	{"pcie", mt7622_pcie_groups, ARRAY_SIZE(mt7622_pcie_groups)},
++	{"pmic", mt7622_pmic_bus_groups, ARRAY_SIZE(mt7622_pmic_bus_groups)},
++	{"pwm",	mt7622_pwm_groups, ARRAY_SIZE(mt7622_pwm_groups)},
++	{"sd", mt7622_sd_groups, ARRAY_SIZE(mt7622_sd_groups)},
++	{"spi",	mt7622_spic_groups, ARRAY_SIZE(mt7622_spic_groups)},
++	{"tdm",	mt7622_tdm_groups, ARRAY_SIZE(mt7622_tdm_groups)},
++	{"uart", mt7622_uart_groups, ARRAY_SIZE(mt7622_uart_groups)},
++	{"watchdog", mt7622_wdt_groups, ARRAY_SIZE(mt7622_wdt_groups)},
++};
++
++static const struct pinconf_generic_params mtk_custom_bindings[] = {
++	{"mediatek,tdsel",	MTK_PIN_CONFIG_TDSEL,		0},
++	{"mediatek,rdsel",	MTK_PIN_CONFIG_RDSEL,		0},
++};
++
++#ifdef CONFIG_DEBUG_FS
++static const struct pin_config_item mtk_conf_items[] = {
++	PCONFDUMP(MTK_PIN_CONFIG_TDSEL, "tdsel", NULL, true),
++	PCONFDUMP(MTK_PIN_CONFIG_RDSEL, "rdsel", NULL, true),
++};
++#endif
++
++static const struct mtk_pin_soc mt7622_data = {
++	.reg_cal = mt7622_reg_cals,
++	.pins = mt7622_pins,
++	.npins = ARRAY_SIZE(mt7622_pins),
++	.grps = mt7622_groups,
++	.ngrps = ARRAY_SIZE(mt7622_groups),
++	.funcs = mt7622_functions,
++	.nfuncs = ARRAY_SIZE(mt7622_functions),
++};
++
++static void mtk_w32(struct mtk_pinctrl *pctl, u32 reg, u32 val)
++{
++	writel_relaxed(val, pctl->base + reg);
++}
++
++static u32 mtk_r32(struct mtk_pinctrl *pctl, u32 reg)
++{
++	return readl_relaxed(pctl->base + reg);
++}
++
++static void mtk_rmw(struct mtk_pinctrl *pctl, u32 reg, u32 mask, u32 set)
++{
++	u32 val;
++
++	val = mtk_r32(pctl, reg);
++	val &= ~mask;
++	val |= set;
++	mtk_w32(pctl, reg, val);
++}
++
++static int mtk_hw_pin_field_lookup(struct mtk_pinctrl *hw, int pin,
++				   const struct mtk_pin_reg_calc *rc,
++				   struct mtk_pin_field *pfd)
++{
++	const struct mtk_pin_field_calc *c, *e;
++	u32 bits;
++
++	c = rc->range;
++	e = c + rc->nranges;
++
++	while (c < e) {
++		if (pin >= c->s_pin && pin <= c->e_pin)
++			break;
++		c++;
++	}
++
++	if (c >= e) {
++		dev_err(hw->dev, "Out of range for pin = %d\n", pin);
++		return -EINVAL;
++	}
++
++	/* Caculated bits as the overall offset the pin is located at */
++	bits = c->s_bit + (pin - c->s_pin) * (c->x_bits);
++
++	/* Fill pfd from bits and 32-bit register applied is assumed */
++	pfd->offset = c->s_addr + c->x_addrs * (bits / 32);
++	pfd->bitpos = bits % 32;
++	pfd->mask = (1 << c->x_bits) - 1;
++
++	/* pfd->next is used for indicating that bit wrapping-around happens
++	 * which requires the manipulation for bit 0 starting in the next
++	 * register to form the complete field read/write.
++	 */
++	pfd->next = pfd->bitpos + c->x_bits - 1 > 31 ? c->x_addrs : 0;
++
++	return 0;
++}
++
++static int mtk_hw_pin_field_get(struct mtk_pinctrl *hw, int pin,
++				int field, struct mtk_pin_field *pfd)
++{
++	const struct mtk_pin_reg_calc *rc;
++
++	if (field < 0 || field >= PINCTRL_PIN_REG_MAX) {
++		dev_err(hw->dev, "Invalid Field %d\n", field);
++		return -EINVAL;
++	}
++
++	if (hw->soc->reg_cal && hw->soc->reg_cal[field].range) {
++		rc = &hw->soc->reg_cal[field];
++	} else {
++		dev_err(hw->dev, "Undefined range for field %d\n", field);
++		return -EINVAL;
++	}
++
++	return mtk_hw_pin_field_lookup(hw, pin, rc, pfd);
++}
++
++static void mtk_hw_bits_part(struct mtk_pin_field *pf, int *h, int *l)
++{
++	*l = 32 - pf->bitpos;
++	*h = get_count_order(pf->mask) - *l;
++}
++
++static void mtk_hw_write_cross_field(struct mtk_pinctrl *hw,
++				     struct mtk_pin_field *pf, int value)
++{
++	int nbits_l, nbits_h;
++
++	mtk_hw_bits_part(pf, &nbits_h, &nbits_l);
++
++	mtk_rmw(hw, pf->offset, pf->mask << pf->bitpos,
++		(value & pf->mask) << pf->bitpos);
++
++	mtk_rmw(hw, pf->offset + pf->next, BIT(nbits_h) - 1,
++		(value & pf->mask) >> nbits_l);
++}
++
++static void mtk_hw_read_cross_field(struct mtk_pinctrl *hw,
++				    struct mtk_pin_field *pf, int *value)
++{
++	int nbits_l, nbits_h, h, l;
++
++	mtk_hw_bits_part(pf, &nbits_h, &nbits_l);
++
++	l  = (mtk_r32(hw, pf->offset) >> pf->bitpos) & (BIT(nbits_l) - 1);
++	h  = (mtk_r32(hw, pf->offset + pf->next)) & (BIT(nbits_h) - 1);
++
++	*value = (h << nbits_l) | l;
++}
++
++static int mtk_hw_set_value(struct mtk_pinctrl *hw, int pin, int field,
++			    int value)
++{
++	struct mtk_pin_field pf;
++	int err;
++
++	err = mtk_hw_pin_field_get(hw, pin, field, &pf);
++	if (err)
++		return err;
++
++	if (!pf.next)
++		mtk_rmw(hw, pf.offset, pf.mask << pf.bitpos,
++			(value & pf.mask) << pf.bitpos);
++	else
++		mtk_hw_write_cross_field(hw, &pf, value);
++
++	return 0;
++}
++
++static int mtk_hw_get_value(struct mtk_pinctrl *hw, int pin, int field,
++			    int *value)
++{
++	struct mtk_pin_field pf;
++	int err;
++
++	err = mtk_hw_pin_field_get(hw, pin, field, &pf);
++	if (err)
++		return err;
++
++	if (!pf.next)
++		*value = (mtk_r32(hw, pf.offset) >> pf.bitpos) & pf.mask;
++	else
++		mtk_hw_read_cross_field(hw, &pf, value);
++
++	return 0;
++}
++
++static int mtk_pinmux_set_mux(struct pinctrl_dev *pctldev,
++			      unsigned int selector, unsigned int group)
++{
++	struct mtk_pinctrl *hw = pinctrl_dev_get_drvdata(pctldev);
++	struct function_desc *func;
++	struct group_desc *grp;
++	int i;
++
++	func = pinmux_generic_get_function(pctldev, selector);
++	if (!func)
++		return -EINVAL;
++
++	grp = pinctrl_generic_get_group(pctldev, group);
++	if (!grp)
++		return -EINVAL;
++
++	dev_dbg(pctldev->dev, "enable function %s group %s\n",
++		func->name, grp->name);
++
++	for (i = 0; i < grp->num_pins; i++) {
++		int *pin_modes = grp->data;
++
++		mtk_hw_set_value(hw, grp->pins[i], PINCTRL_PIN_REG_MODE,
++				 pin_modes[i]);
++	}
++
++	return 0;
++}
++
++static int mtk_pinmux_gpio_request_enable(struct pinctrl_dev *pctldev,
++					  struct pinctrl_gpio_range *range,
++					  unsigned int pin)
++{
++	struct mtk_pinctrl *hw = pinctrl_dev_get_drvdata(pctldev);
++
++	return mtk_hw_set_value(hw, pin, PINCTRL_PIN_REG_MODE, MTK_GPIO_MODE);
++}
++
++static int mtk_pinmux_gpio_set_direction(struct pinctrl_dev *pctldev,
++					 struct pinctrl_gpio_range *range,
++					 unsigned int pin, bool input)
++{
++	struct mtk_pinctrl *hw = pinctrl_dev_get_drvdata(pctldev);
++
++	/* hardware would take 0 as input direction */
++	return mtk_hw_set_value(hw, pin, PINCTRL_PIN_REG_DIR, !input);
++}
++
++static int mtk_pinconf_get(struct pinctrl_dev *pctldev,
++			   unsigned int pin, unsigned long *config)
++{
++	struct mtk_pinctrl *hw = pinctrl_dev_get_drvdata(pctldev);
++	u32 param = pinconf_to_config_param(*config);
++	int val, val2, err, reg, ret = 1;
++
++	switch (param) {
++	case PIN_CONFIG_BIAS_DISABLE:
++		err = mtk_hw_get_value(hw, pin, PINCTRL_PIN_REG_PU, &val);
++		if (err)
++			return err;
++
++		err = mtk_hw_get_value(hw, pin, PINCTRL_PIN_REG_PD, &val2);
++		if (err)
++			return err;
++
++		if (val || val2)
++			return -EINVAL;
++
++		break;
++	case PIN_CONFIG_BIAS_PULL_UP:
++	case PIN_CONFIG_BIAS_PULL_DOWN:
++	case PIN_CONFIG_SLEW_RATE:
++		reg = (param == PIN_CONFIG_BIAS_PULL_UP) ?
++		      PINCTRL_PIN_REG_PU :
++		      (param == PIN_CONFIG_BIAS_PULL_DOWN) ?
++		      PINCTRL_PIN_REG_PD : PINCTRL_PIN_REG_SR;
++
++		err = mtk_hw_get_value(hw, pin, reg, &val);
++		if (err)
++			return err;
++
++		if (!val)
++			return -EINVAL;
++
++		break;
++	case PIN_CONFIG_INPUT_ENABLE:
++	case PIN_CONFIG_OUTPUT_ENABLE:
++		err = mtk_hw_get_value(hw, pin, PINCTRL_PIN_REG_DIR, &val);
++		if (err)
++			return -EINVAL;
++
++		/* HW takes input mode as zero; output mode as non-zero */
++		if ((val && param == PIN_CONFIG_INPUT_ENABLE) ||
++		    (!val && param == PIN_CONFIG_OUTPUT_ENABLE))
++			return -EINVAL;
++
++		break;
++	case PIN_CONFIG_INPUT_SCHMITT_ENABLE:
++		err = mtk_hw_get_value(hw, pin, PINCTRL_PIN_REG_DIR, &val);
++		if (err)
++			return err;
++
++		err = mtk_hw_get_value(hw, pin, PINCTRL_PIN_REG_SMT, &val2);
++		if (err)
++			return err;
++
++		if (val || !val2)
++			return -EINVAL;
++
++		break;
++	case PIN_CONFIG_DRIVE_STRENGTH:
++		err = mtk_hw_get_value(hw, pin, PINCTRL_PIN_REG_E4, &val);
++		if (err)
++			return -EINVAL;
++
++		err = mtk_hw_get_value(hw, pin, PINCTRL_PIN_REG_E8, &val2);
++		if (err)
++			return -EINVAL;
++
++		/* 4mA when (e8, e4) = (0, 0); 8mA when (e8, e4) = (0, 1)
++		 * 12mA when (e8, e4) = (1, 0); 16mA when (e8, e4) = (1, 1)
++		 */
++		ret = ((val2 << 1) + val + 1) * 4;
++
++		break;
++	case MTK_PIN_CONFIG_TDSEL:
++	case MTK_PIN_CONFIG_RDSEL:
++		reg = (param == MTK_PIN_CONFIG_TDSEL) ?
++		       PINCTRL_PIN_REG_TDSEL : PINCTRL_PIN_REG_RDSEL;
++
++		err = mtk_hw_get_value(hw, pin, reg, &val);
++		if (err)
++			return -EINVAL;
++
++		ret = val;
++
++		break;
++	default:
++		return -ENOTSUPP;
++	}
++
++	*config = pinconf_to_config_packed(param, ret);
++
++	return 0;
++}
++
++static int mtk_pinconf_set(struct pinctrl_dev *pctldev, unsigned int pin,
++			   unsigned long *configs, unsigned int num_configs)
++{
++	struct mtk_pinctrl *hw = pinctrl_dev_get_drvdata(pctldev);
++	u32 reg, param, arg;
++	int cfg, err = 0;
++
++	for (cfg = 0; cfg < num_configs; cfg++) {
++		param = pinconf_to_config_param(configs[cfg]);
++		arg = pinconf_to_config_argument(configs[cfg]);
++
++		switch (param) {
++		case PIN_CONFIG_BIAS_DISABLE:
++		case PIN_CONFIG_BIAS_PULL_UP:
++		case PIN_CONFIG_BIAS_PULL_DOWN:
++			arg = (param == PIN_CONFIG_BIAS_DISABLE) ? 0 :
++			       (param == PIN_CONFIG_BIAS_PULL_UP) ? 1 : 2;
++
++			err = mtk_hw_set_value(hw, pin, PINCTRL_PIN_REG_PU,
++					       arg & 1);
++			if (err)
++				goto err;
++
++			err = mtk_hw_set_value(hw, pin, PINCTRL_PIN_REG_PD,
++					       !!(arg & 2));
++			if (err)
++				goto err;
++			break;
++		case PIN_CONFIG_OUTPUT_ENABLE:
++			err = mtk_hw_set_value(hw, pin, PINCTRL_PIN_REG_SMT,
++					       MTK_DISABLE);
++			if (err)
++				goto err;
++		case PIN_CONFIG_INPUT_ENABLE:
++		case PIN_CONFIG_SLEW_RATE:
++			reg = (param == PIN_CONFIG_SLEW_RATE) ?
++			       PINCTRL_PIN_REG_SR : PINCTRL_PIN_REG_DIR;
++
++			arg = (param == PIN_CONFIG_INPUT_ENABLE) ? 0 :
++			      (param == PIN_CONFIG_OUTPUT_ENABLE) ? 1 : arg;
++			err = mtk_hw_set_value(hw, pin, reg, arg);
++			if (err)
++				goto err;
++
++			break;
++		case PIN_CONFIG_OUTPUT:
++			err = mtk_hw_set_value(hw, pin, PINCTRL_PIN_REG_DIR,
++					       MTK_OUTPUT);
++			if (err)
++				goto err;
++
++			err = mtk_hw_set_value(hw, pin, PINCTRL_PIN_REG_DO,
++					       arg);
++			if (err)
++				goto err;
++			break;
++		case PIN_CONFIG_INPUT_SCHMITT_ENABLE:
++			/* arg = 1: Input mode & SMT enable ;
++			 * arg = 0: Output mode & SMT disable
++			 */
++			arg = arg ? 2 : 1;
++			err = mtk_hw_set_value(hw, pin, PINCTRL_PIN_REG_DIR,
++					       arg & 1);
++			if (err)
++				goto err;
++
++			err = mtk_hw_set_value(hw, pin, PINCTRL_PIN_REG_SMT,
++					       !!(arg & 2));
++			if (err)
++				goto err;
++			break;
++		case PIN_CONFIG_DRIVE_STRENGTH:
++			/* 4mA when (e8, e4) = (0, 0);
++			 * 8mA when (e8, e4) = (0, 1);
++			 * 12mA when (e8, e4) = (1, 0);
++			 * 16mA when (e8, e4) = (1, 1)
++			 */
++			if (!(arg % 4) && (arg >= 4 && arg <= 16)) {
++				arg = arg / 4 - 1;
++				err = mtk_hw_set_value(hw, pin,
++						       PINCTRL_PIN_REG_E4,
++						       arg & 0x1);
++				if (err)
++					goto err;
++
++				err = mtk_hw_set_value(hw, pin,
++						       PINCTRL_PIN_REG_E8,
++						       (arg & 0x2) >> 1);
++				if (err)
++					goto err;
++			} else {
++				err = -ENOTSUPP;
++			}
++			break;
++		case MTK_PIN_CONFIG_TDSEL:
++		case MTK_PIN_CONFIG_RDSEL:
++			reg = (param == MTK_PIN_CONFIG_TDSEL) ?
++			       PINCTRL_PIN_REG_TDSEL : PINCTRL_PIN_REG_RDSEL;
++
++			err = mtk_hw_set_value(hw, pin, reg, arg);
++			if (err)
++				goto err;
++			break;
++		default:
++			err = -ENOTSUPP;
++		}
++	}
++err:
++	return err;
++}
++
++static int mtk_pinconf_group_get(struct pinctrl_dev *pctldev,
++				 unsigned int group, unsigned long *config)
++{
++	const unsigned int *pins;
++	unsigned int i, npins, old = 0;
++	int ret;
++
++	ret = pinctrl_generic_get_group_pins(pctldev, group, &pins, &npins);
++	if (ret)
++		return ret;
++
++	for (i = 0; i < npins; i++) {
++		if (mtk_pinconf_get(pctldev, pins[i], config))
++			return -ENOTSUPP;
++
++		/* configs do not match between two pins */
++		if (i && old != *config)
++			return -ENOTSUPP;
++
++		old = *config;
++	}
++
++	return 0;
++}
++
++static int mtk_pinconf_group_set(struct pinctrl_dev *pctldev,
++				 unsigned int group, unsigned long *configs,
++				 unsigned int num_configs)
++{
++	const unsigned int *pins;
++	unsigned int i, npins;
++	int ret;
++
++	ret = pinctrl_generic_get_group_pins(pctldev, group, &pins, &npins);
++	if (ret)
++		return ret;
++
++	for (i = 0; i < npins; i++) {
++		ret = mtk_pinconf_set(pctldev, pins[i], configs, num_configs);
++		if (ret)
++			return ret;
++	}
++
++	return 0;
++}
++
++static const struct pinctrl_ops mtk_pctlops = {
++	.get_groups_count = pinctrl_generic_get_group_count,
++	.get_group_name = pinctrl_generic_get_group_name,
++	.get_group_pins = pinctrl_generic_get_group_pins,
++	.dt_node_to_map = pinconf_generic_dt_node_to_map_all,
++	.dt_free_map = pinconf_generic_dt_free_map,
++};
++
++static const struct pinmux_ops mtk_pmxops = {
++	.get_functions_count = pinmux_generic_get_function_count,
++	.get_function_name = pinmux_generic_get_function_name,
++	.get_function_groups = pinmux_generic_get_function_groups,
++	.set_mux = mtk_pinmux_set_mux,
++	.gpio_request_enable = mtk_pinmux_gpio_request_enable,
++	.gpio_set_direction = mtk_pinmux_gpio_set_direction,
++	.strict = true,
++};
++
++static const struct pinconf_ops mtk_confops = {
++	.is_generic = true,
++	.pin_config_get = mtk_pinconf_get,
++	.pin_config_set = mtk_pinconf_set,
++	.pin_config_group_get = mtk_pinconf_group_get,
++	.pin_config_group_set = mtk_pinconf_group_set,
++	.pin_config_config_dbg_show = pinconf_generic_dump_config,
++};
++
++static struct pinctrl_desc mtk_desc = {
++	.name = PINCTRL_PINCTRL_DEV,
++	.pctlops = &mtk_pctlops,
++	.pmxops = &mtk_pmxops,
++	.confops = &mtk_confops,
++	.owner = THIS_MODULE,
++};
++
++static int mtk_gpio_get(struct gpio_chip *chip, unsigned int gpio)
++{
++	struct mtk_pinctrl *hw = dev_get_drvdata(chip->parent);
++	int value;
++
++	mtk_hw_get_value(hw, gpio, PINCTRL_PIN_REG_DI, &value);
++
++	return !!value;
++}
++
++static void mtk_gpio_set(struct gpio_chip *chip, unsigned int gpio, int value)
++{
++	struct mtk_pinctrl *hw = dev_get_drvdata(chip->parent);
++
++	mtk_hw_set_value(hw, gpio, PINCTRL_PIN_REG_DO, !!value);
++}
++
++static int mtk_gpio_direction_input(struct gpio_chip *chip, unsigned int gpio)
++{
++	return pinctrl_gpio_direction_input(chip->base + gpio);
++}
++
++static int mtk_gpio_direction_output(struct gpio_chip *chip, unsigned int gpio,
++				     int value)
++{
++	mtk_gpio_set(chip, gpio, value);
++
++	return pinctrl_gpio_direction_output(chip->base + gpio);
++}
++
++static int mtk_build_gpiochip(struct mtk_pinctrl *hw, struct device_node *np)
++{
++	struct gpio_chip *chip = &hw->chip;
++	int ret;
++
++	chip->label		= PINCTRL_PINCTRL_DEV;
++	chip->parent		= hw->dev;
++	chip->request		= gpiochip_generic_request;
++	chip->free		= gpiochip_generic_free;
++	chip->direction_input	= mtk_gpio_direction_input;
++	chip->direction_output	= mtk_gpio_direction_output;
++	chip->get		= mtk_gpio_get;
++	chip->set		= mtk_gpio_set;
++	chip->base		= -1;
++	chip->ngpio		= hw->soc->npins;
++	chip->of_node		= np;
++	chip->of_gpio_n_cells	= 2;
++
++	ret = gpiochip_add_data(chip, hw);
++	if (ret < 0)
++		return ret;
++
++	ret = gpiochip_add_pin_range(chip, dev_name(hw->dev), 0, 0,
++				     chip->ngpio);
++	if (ret < 0) {
++		gpiochip_remove(chip);
++		return ret;
++	}
++
++	return 0;
++}
++
++static int mtk_build_groups(struct mtk_pinctrl *hw)
++{
++	int err, i;
++
++	for (i = 0; i < hw->soc->ngrps; i++) {
++		const struct group_desc *group = hw->soc->grps + i;
++
++		err = pinctrl_generic_add_group(hw->pctrl, group->name,
++						group->pins, group->num_pins,
++						group->data);
++		if (err) {
++			dev_err(hw->dev, "Failed to register group %s\n",
++				group->name);
++			return err;
++		}
++	}
++
++	return 0;
++}
++
++static int mtk_build_functions(struct mtk_pinctrl *hw)
++{
++	int i, err;
++
++	for (i = 0; i < hw->soc->nfuncs ; i++) {
++		const struct function_desc *func = hw->soc->funcs + i;
++
++		err = pinmux_generic_add_function(hw->pctrl, func->name,
++						  func->group_names,
++						  func->num_group_names,
++						  func->data);
++		if (err) {
++			dev_err(hw->dev, "Failed to register function %s\n",
++				func->name);
++			return err;
++		}
++	}
++
++	return 0;
++}
++
++static const struct of_device_id mtk_pinctrl_of_match[] = {
++	{ .compatible = "mediatek,mt7622-pinctrl", .data = &mt7622_data},
++	{ }
++};
++
++static int mtk_pinctrl_probe(struct platform_device *pdev)
++{
++	struct resource *res;
++	struct mtk_pinctrl *hw;
++	const struct of_device_id *of_id =
++		of_match_device(mtk_pinctrl_of_match, &pdev->dev);
++	int err;
++
++	hw = devm_kzalloc(&pdev->dev, sizeof(*hw), GFP_KERNEL);
++	if (!hw)
++		return -ENOMEM;
++
++	hw->soc = of_id->data;
++
++	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
++	if (!res) {
++		dev_err(&pdev->dev, "missing IO resource\n");
++		return -ENXIO;
++	}
++
++	hw->dev = &pdev->dev;
++	hw->base = devm_ioremap_resource(&pdev->dev, res);
++	if (IS_ERR(hw->base))
++		return PTR_ERR(hw->base);
++
++	/* Setup pins descriptions per SoC types */
++	mtk_desc.pins = hw->soc->pins;
++	mtk_desc.npins = hw->soc->npins;
++	mtk_desc.num_custom_params = ARRAY_SIZE(mtk_custom_bindings);
++	mtk_desc.custom_params = mtk_custom_bindings;
++#ifdef CONFIG_DEBUG_FS
++	mtk_desc.custom_conf_items = mtk_conf_items;
++#endif
++
++	hw->pctrl = devm_pinctrl_register(&pdev->dev, &mtk_desc, hw);
++	if (IS_ERR(hw->pctrl))
++		return PTR_ERR(hw->pctrl);
++
++	/* Setup groups descriptions per SoC types */
++	err = mtk_build_groups(hw);
++	if (err) {
++		dev_err(&pdev->dev, "Failed to build groups\n");
++		return 0;
++	}
++
++	/* Setup functions descriptions per SoC types */
++	err = mtk_build_functions(hw);
++	if (err) {
++		dev_err(&pdev->dev, "Failed to build functions\n");
++		return err;
++	}
++
++	err = mtk_build_gpiochip(hw, pdev->dev.of_node);
++	if (err) {
++		dev_err(&pdev->dev, "Failed to add gpio_chip\n");
++		return err;
++	}
++
++	platform_set_drvdata(pdev, hw);
++
++	return 0;
++}
++
++static struct platform_driver mtk_pinctrl_driver = {
++	.driver = {
++		.name = "mtk-pinctrl",
++		.of_match_table = mtk_pinctrl_of_match,
++	},
++	.probe = mtk_pinctrl_probe,
++};
++
++static int __init mtk_pinctrl_init(void)
++{
++	return platform_driver_register(&mtk_pinctrl_driver);
++}
++arch_initcall(mtk_pinctrl_init);
+-- 
+2.11.0
+
diff --git a/target/linux/mediatek/patches-4.14/0172-clk-mediatek-group-drivers-under-indpendent-menu.patch b/target/linux/mediatek/patches-4.14/0172-clk-mediatek-group-drivers-under-indpendent-menu.patch
new file mode 100644
index 0000000000..ce16723af7
--- /dev/null
+++ b/target/linux/mediatek/patches-4.14/0172-clk-mediatek-group-drivers-under-indpendent-menu.patch
@@ -0,0 +1,228 @@
+From 13ee94af58240b75550f413fece707987d563193 Mon Sep 17 00:00:00 2001
+From: Sean Wang <sean.wang@mediatek.com>
+Date: Wed, 20 Dec 2017 14:42:58 +0800
+Subject: [PATCH 172/224] clk: mediatek: group drivers under indpendent menu
+
+Getting much MediaTek clock driver have been added to CCF, so it's
+better adding the cleanup for grouping drivers under the independent
+menu to simplify configuration selection. In addition, really trivial
+fixups for typos are added in the same patch.
+
+Signed-off-by: Sean Wang <sean.wang@mediatek.com>
+Signed-off-by: Stephen Boyd <sboyd@codeaurora.org>
+---
+ drivers/clk/mediatek/Kconfig | 96 +++++++++++++++++++++++---------------------
+ 1 file changed, 50 insertions(+), 46 deletions(-)
+
+diff --git a/drivers/clk/mediatek/Kconfig b/drivers/clk/mediatek/Kconfig
+index 59dc0aad553c..7338f816c603 100644
+--- a/drivers/clk/mediatek/Kconfig
++++ b/drivers/clk/mediatek/Kconfig
+@@ -1,136 +1,139 @@
+ #
+-# MediaTek SoC drivers
++# MediaTek Clock Drivers
+ #
++menu "Clock driver for MediaTek SoC"
++	depends on ARCH_MEDIATEK || COMPILE_TEST
++
+ config COMMON_CLK_MEDIATEK
+ 	bool
+ 	---help---
+-	  Mediatek SoCs' clock support.
++	  MediaTek SoCs' clock support.
+ 
+ config COMMON_CLK_MT2701
+-	bool "Clock driver for Mediatek MT2701"
++	bool "Clock driver for MediaTek MT2701"
+ 	depends on (ARCH_MEDIATEK && ARM) || COMPILE_TEST
+ 	select COMMON_CLK_MEDIATEK
+ 	default ARCH_MEDIATEK && ARM
+ 	---help---
+-	  This driver supports Mediatek MT2701 basic clocks.
++	  This driver supports MediaTek MT2701 basic clocks.
+ 
+ config COMMON_CLK_MT2701_MMSYS
+-	bool "Clock driver for Mediatek MT2701 mmsys"
++	bool "Clock driver for MediaTek MT2701 mmsys"
+ 	depends on COMMON_CLK_MT2701
+ 	---help---
+-	  This driver supports Mediatek MT2701 mmsys clocks.
++	  This driver supports MediaTek MT2701 mmsys clocks.
+ 
+ config COMMON_CLK_MT2701_IMGSYS
+-	bool "Clock driver for Mediatek MT2701 imgsys"
++	bool "Clock driver for MediaTek MT2701 imgsys"
+ 	depends on COMMON_CLK_MT2701
+ 	---help---
+-	  This driver supports Mediatek MT2701 imgsys clocks.
++	  This driver supports MediaTek MT2701 imgsys clocks.
+ 
+ config COMMON_CLK_MT2701_VDECSYS
+-	bool "Clock driver for Mediatek MT2701 vdecsys"
++	bool "Clock driver for MediaTek MT2701 vdecsys"
+ 	depends on COMMON_CLK_MT2701
+ 	---help---
+-	  This driver supports Mediatek MT2701 vdecsys clocks.
++	  This driver supports MediaTek MT2701 vdecsys clocks.
+ 
+ config COMMON_CLK_MT2701_HIFSYS
+-	bool "Clock driver for Mediatek MT2701 hifsys"
++	bool "Clock driver for MediaTek MT2701 hifsys"
+ 	depends on COMMON_CLK_MT2701
+ 	---help---
+-	  This driver supports Mediatek MT2701 hifsys clocks.
++	  This driver supports MediaTek MT2701 hifsys clocks.
+ 
+ config COMMON_CLK_MT2701_ETHSYS
+-	bool "Clock driver for Mediatek MT2701 ethsys"
++	bool "Clock driver for MediaTek MT2701 ethsys"
+ 	depends on COMMON_CLK_MT2701
+ 	---help---
+-	  This driver supports Mediatek MT2701 ethsys clocks.
++	  This driver supports MediaTek MT2701 ethsys clocks.
+ 
+ config COMMON_CLK_MT2701_BDPSYS
+-	bool "Clock driver for Mediatek MT2701 bdpsys"
++	bool "Clock driver for MediaTek MT2701 bdpsys"
+ 	depends on COMMON_CLK_MT2701
+ 	---help---
+-	  This driver supports Mediatek MT2701 bdpsys clocks.
++	  This driver supports MediaTek MT2701 bdpsys clocks.
+ 
+ config COMMON_CLK_MT2712
+-	bool "Clock driver for Mediatek MT2712"
++	bool "Clock driver for MediaTek MT2712"
+ 	depends on (ARCH_MEDIATEK && ARM64) || COMPILE_TEST
+ 	select COMMON_CLK_MEDIATEK
+ 	default ARCH_MEDIATEK && ARM64
+ 	---help---
+-	  This driver supports Mediatek MT2712 basic clocks.
++	  This driver supports MediaTek MT2712 basic clocks.
+ 
+ config COMMON_CLK_MT2712_BDPSYS
+-	bool "Clock driver for Mediatek MT2712 bdpsys"
++	bool "Clock driver for MediaTek MT2712 bdpsys"
+ 	depends on COMMON_CLK_MT2712
+ 	---help---
+-	  This driver supports Mediatek MT2712 bdpsys clocks.
++	  This driver supports MediaTek MT2712 bdpsys clocks.
+ 
+ config COMMON_CLK_MT2712_IMGSYS
+-	bool "Clock driver for Mediatek MT2712 imgsys"
++	bool "Clock driver for MediaTek MT2712 imgsys"
+ 	depends on COMMON_CLK_MT2712
+ 	---help---
+-	  This driver supports Mediatek MT2712 imgsys clocks.
++	  This driver supports MediaTek MT2712 imgsys clocks.
+ 
+ config COMMON_CLK_MT2712_JPGDECSYS
+-	bool "Clock driver for Mediatek MT2712 jpgdecsys"
++	bool "Clock driver for MediaTek MT2712 jpgdecsys"
+ 	depends on COMMON_CLK_MT2712
+ 	---help---
+-	  This driver supports Mediatek MT2712 jpgdecsys clocks.
++	  This driver supports MediaTek MT2712 jpgdecsys clocks.
+ 
+ config COMMON_CLK_MT2712_MFGCFG
+-	bool "Clock driver for Mediatek MT2712 mfgcfg"
++	bool "Clock driver for MediaTek MT2712 mfgcfg"
+ 	depends on COMMON_CLK_MT2712
+ 	---help---
+-	  This driver supports Mediatek MT2712 mfgcfg clocks.
++	  This driver supports MediaTek MT2712 mfgcfg clocks.
+ 
+ config COMMON_CLK_MT2712_MMSYS
+-	bool "Clock driver for Mediatek MT2712 mmsys"
++	bool "Clock driver for MediaTek MT2712 mmsys"
+ 	depends on COMMON_CLK_MT2712
+ 	---help---
+-	  This driver supports Mediatek MT2712 mmsys clocks.
++	  This driver supports MediaTek MT2712 mmsys clocks.
+ 
+ config COMMON_CLK_MT2712_VDECSYS
+-	bool "Clock driver for Mediatek MT2712 vdecsys"
++	bool "Clock driver for MediaTek MT2712 vdecsys"
+ 	depends on COMMON_CLK_MT2712
+ 	---help---
+-	  This driver supports Mediatek MT2712 vdecsys clocks.
++	  This driver supports MediaTek MT2712 vdecsys clocks.
+ 
+ config COMMON_CLK_MT2712_VENCSYS
+-	bool "Clock driver for Mediatek MT2712 vencsys"
++	bool "Clock driver for MediaTek MT2712 vencsys"
+ 	depends on COMMON_CLK_MT2712
+ 	---help---
+-	  This driver supports Mediatek MT2712 vencsys clocks.
++	  This driver supports MediaTek MT2712 vencsys clocks.
+ 
+ config COMMON_CLK_MT6797
+-       bool "Clock driver for Mediatek MT6797"
++       bool "Clock driver for MediaTek MT6797"
+        depends on (ARCH_MEDIATEK && ARM64) || COMPILE_TEST
+        select COMMON_CLK_MEDIATEK
+        default ARCH_MEDIATEK && ARM64
+        ---help---
+-         This driver supports Mediatek MT6797 basic clocks.
++         This driver supports MediaTek MT6797 basic clocks.
+ 
+ config COMMON_CLK_MT6797_MMSYS
+-       bool "Clock driver for Mediatek MT6797 mmsys"
++       bool "Clock driver for MediaTek MT6797 mmsys"
+        depends on COMMON_CLK_MT6797
+        ---help---
+-         This driver supports Mediatek MT6797 mmsys clocks.
++         This driver supports MediaTek MT6797 mmsys clocks.
+ 
+ config COMMON_CLK_MT6797_IMGSYS
+-       bool "Clock driver for Mediatek MT6797 imgsys"
++       bool "Clock driver for MediaTek MT6797 imgsys"
+        depends on COMMON_CLK_MT6797
+        ---help---
+-         This driver supports Mediatek MT6797 imgsys clocks.
++         This driver supports MediaTek MT6797 imgsys clocks.
+ 
+ config COMMON_CLK_MT6797_VDECSYS
+-       bool "Clock driver for Mediatek MT6797 vdecsys"
++       bool "Clock driver for MediaTek MT6797 vdecsys"
+        depends on COMMON_CLK_MT6797
+        ---help---
+-         This driver supports Mediatek MT6797 vdecsys clocks.
++         This driver supports MediaTek MT6797 vdecsys clocks.
+ 
+ config COMMON_CLK_MT6797_VENCSYS
+-       bool "Clock driver for Mediatek MT6797 vencsys"
++       bool "Clock driver for MediaTek MT6797 vencsys"
+        depends on COMMON_CLK_MT6797
+        ---help---
+-         This driver supports Mediatek MT6797 vencsys clocks.
++         This driver supports MediaTek MT6797 vencsys clocks.
+ 
+ config COMMON_CLK_MT7622
+ 	bool "Clock driver for MediaTek MT7622"
+@@ -163,17 +166,18 @@ config COMMON_CLK_MT7622_AUDSYS
+ 	  to audio consumers such as I2S and TDM.
+ 
+ config COMMON_CLK_MT8135
+-	bool "Clock driver for Mediatek MT8135"
++	bool "Clock driver for MediaTek MT8135"
+ 	depends on (ARCH_MEDIATEK && ARM) || COMPILE_TEST
+ 	select COMMON_CLK_MEDIATEK
+ 	default ARCH_MEDIATEK && ARM
+ 	---help---
+-	  This driver supports Mediatek MT8135 clocks.
++	  This driver supports MediaTek MT8135 clocks.
+ 
+ config COMMON_CLK_MT8173
+-	bool "Clock driver for Mediatek MT8173"
++	bool "Clock driver for MediaTek MT8173"
+ 	depends on ARCH_MEDIATEK || COMPILE_TEST
+ 	select COMMON_CLK_MEDIATEK
+ 	default ARCH_MEDIATEK
+ 	---help---
+-	  This driver supports Mediatek MT8173 clocks.
++	  This driver supports MediaTek MT8173 clocks.
++endmenu
+-- 
+2.11.0
+
diff --git a/target/linux/mediatek/patches-4.14/0173-clk-mediatek-fixup-test-building-of-MediaTek-clock-d.patch b/target/linux/mediatek/patches-4.14/0173-clk-mediatek-fixup-test-building-of-MediaTek-clock-d.patch
new file mode 100644
index 0000000000..386a15a568
--- /dev/null
+++ b/target/linux/mediatek/patches-4.14/0173-clk-mediatek-fixup-test-building-of-MediaTek-clock-d.patch
@@ -0,0 +1,32 @@
+From 3f963310151f6e630f94acf73ff44493619038ff Mon Sep 17 00:00:00 2001
+From: Sean Wang <sean.wang@mediatek.com>
+Date: Wed, 20 Dec 2017 14:42:59 +0800
+Subject: [PATCH 173/224] clk: mediatek: fixup test-building of MediaTek clock
+ drivers
+
+Let the build system looking into the directiory where the clock drivers
+resides for the COMPILE_TEST alternative dependency allows test-building
+the drivers.
+
+Signed-off-by: Sean Wang <sean.wang@mediatek.com>
+Signed-off-by: Stephen Boyd <sboyd@codeaurora.org>
+---
+ drivers/clk/Makefile | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/clk/Makefile b/drivers/clk/Makefile
+index c99f363826f0..838000f92b69 100644
+--- a/drivers/clk/Makefile
++++ b/drivers/clk/Makefile
+@@ -66,7 +66,7 @@ obj-$(CONFIG_ARCH_MXC)			+= imx/
+ obj-$(CONFIG_MACH_INGENIC)		+= ingenic/
+ obj-$(CONFIG_ARCH_KEYSTONE)		+= keystone/
+ obj-$(CONFIG_MACH_LOONGSON32)		+= loongson1/
+-obj-$(CONFIG_ARCH_MEDIATEK)		+= mediatek/
++obj-y					+= mediatek/
+ obj-$(CONFIG_COMMON_CLK_AMLOGIC)	+= meson/
+ obj-$(CONFIG_MACH_PIC32)		+= microchip/
+ ifeq ($(CONFIG_COMMON_CLK), y)
+-- 
+2.11.0
+
diff --git a/target/linux/mediatek/patches-4.14/0174-dt-bindings-net-mediatek-add-condition-to-property-m.patch b/target/linux/mediatek/patches-4.14/0174-dt-bindings-net-mediatek-add-condition-to-property-m.patch
new file mode 100644
index 0000000000..aed5ec59f3
--- /dev/null
+++ b/target/linux/mediatek/patches-4.14/0174-dt-bindings-net-mediatek-add-condition-to-property-m.patch
@@ -0,0 +1,32 @@
+From ee687ebf4708fb9e2a64830cdecd8cf992ef9b2b Mon Sep 17 00:00:00 2001
+From: Sean Wang <sean.wang@mediatek.com>
+Date: Wed, 20 Dec 2017 17:47:05 +0800
+Subject: [PATCH 174/224] dt-bindings: net: mediatek: add condition to property
+ mediatek, pctl
+
+The property "mediatek,pctl" is only required for SoCs such as MT2701 and
+MT7623, so adding a few words for stating the condition.
+
+Signed-off-by: Sean Wang <sean.wang@mediatek.com>
+Reviewed-by: Rob Herring <robh@kernel.org>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+---
+ Documentation/devicetree/bindings/net/mediatek-net.txt | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/Documentation/devicetree/bindings/net/mediatek-net.txt b/Documentation/devicetree/bindings/net/mediatek-net.txt
+index 214eaa9a6683..53c13ee384a4 100644
+--- a/Documentation/devicetree/bindings/net/mediatek-net.txt
++++ b/Documentation/devicetree/bindings/net/mediatek-net.txt
+@@ -28,7 +28,7 @@ Required properties:
+ - mediatek,sgmiisys: phandle to the syscon node that handles the SGMII setup
+ 	which is required for those SoCs equipped with SGMII such as MT7622 SoC.
+ - mediatek,pctl: phandle to the syscon node that handles the ports slew rate
+-	and driver current
++	and driver current: only for MT2701 and MT7623 SoC
+ 
+ Optional properties:
+ - interrupt-parent: Should be the phandle for the interrupt controller
+-- 
+2.11.0
+
diff --git a/target/linux/mediatek/patches-4.14/0175-net-mediatek-remove-superfluous-pin-setup-for-MT7622.patch b/target/linux/mediatek/patches-4.14/0175-net-mediatek-remove-superfluous-pin-setup-for-MT7622.patch
new file mode 100644
index 0000000000..3116f03f06
--- /dev/null
+++ b/target/linux/mediatek/patches-4.14/0175-net-mediatek-remove-superfluous-pin-setup-for-MT7622.patch
@@ -0,0 +1,106 @@
+From d96cf7e724105dc73f623c2019ab5bc78cef036e Mon Sep 17 00:00:00 2001
+From: Sean Wang <sean.wang@mediatek.com>
+Date: Wed, 20 Dec 2017 17:47:06 +0800
+Subject: [PATCH 175/224] net: mediatek: remove superfluous pin setup for
+ MT7622 SoC
+
+Remove superfluous pin setup to get out of accessing invalid I/O pin
+registers because the way for pin configuring tends to be different from
+various SoCs and thus it should be better being managed and controlled by
+the pinctrl driver which MT7622 already can support.
+
+Signed-off-by: Sean Wang <sean.wang@mediatek.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+---
+ drivers/net/ethernet/mediatek/mtk_eth_soc.c | 35 +++++++++++++++++------------
+ drivers/net/ethernet/mediatek/mtk_eth_soc.h |  3 +++
+ 2 files changed, 24 insertions(+), 14 deletions(-)
+
+Index: linux-4.14.37/drivers/net/ethernet/mediatek/mtk_eth_soc.c
+===================================================================
+--- linux-4.14.37.orig/drivers/net/ethernet/mediatek/mtk_eth_soc.c
++++ linux-4.14.37/drivers/net/ethernet/mediatek/mtk_eth_soc.c
+@@ -1976,14 +1976,16 @@ static int mtk_hw_init(struct mtk_eth *e
+ 	}
+ 	regmap_write(eth->ethsys, ETHSYS_SYSCFG0, val);
+ 
+-	/* Set GE2 driving and slew rate */
+-	regmap_write(eth->pctl, GPIO_DRV_SEL10, 0xa00);
++	if (eth->pctl) {
++		/* Set GE2 driving and slew rate */
++		regmap_write(eth->pctl, GPIO_DRV_SEL10, 0xa00);
+ 
+-	/* set GE2 TDSEL */
+-	regmap_write(eth->pctl, GPIO_OD33_CTRL8, 0x5);
++		/* set GE2 TDSEL */
++		regmap_write(eth->pctl, GPIO_OD33_CTRL8, 0x5);
+ 
+-	/* set GE2 TUNE */
+-	regmap_write(eth->pctl, GPIO_BIAS_CTRL, 0x0);
++		/* set GE2 TUNE */
++		regmap_write(eth->pctl, GPIO_BIAS_CTRL, 0x0);
++	}
+ 
+ 	/* Set linkdown as the default for each GMAC. Its own MCR would be set
+ 	 * up with the more appropriate value when mtk_phy_link_adjust call is
+@@ -2568,11 +2570,13 @@ static int mtk_probe(struct platform_dev
+ 		}
+ 	}
+ 
+-	eth->pctl = syscon_regmap_lookup_by_phandle(pdev->dev.of_node,
+-						    "mediatek,pctl");
+-	if (IS_ERR(eth->pctl)) {
+-		dev_err(&pdev->dev, "no pctl regmap found\n");
+-		return PTR_ERR(eth->pctl);
++	if (eth->soc->required_pctl) {
++		eth->pctl = syscon_regmap_lookup_by_phandle(pdev->dev.of_node,
++							    "mediatek,pctl");
++		if (IS_ERR(eth->pctl)) {
++			dev_err(&pdev->dev, "no pctl regmap found\n");
++			return PTR_ERR(eth->pctl);
++		}
+ 	}
+ 
+ 	for (i = 0; i < 3; i++) {
+@@ -2698,17 +2702,20 @@ static int mtk_remove(struct platform_de
+ 
+ static const struct mtk_soc_data mt2701_data = {
+ 	.caps = MTK_GMAC1_TRGMII,
+-	.required_clks = MT7623_CLKS_BITMAP
++	.required_clks = MT7623_CLKS_BITMAP,
++	.required_pctl = true,
+ };
+ 
+ static const struct mtk_soc_data mt7622_data = {
+ 	.caps = MTK_DUAL_GMAC_SHARED_SGMII | MTK_GMAC1_ESW,
+-	.required_clks = MT7622_CLKS_BITMAP
++	.required_clks = MT7622_CLKS_BITMAP,
++	.required_pctl = false,
+ };
+ 
+ static const struct mtk_soc_data mt7623_data = {
+ 	.caps = MTK_GMAC1_TRGMII,
+-	.required_clks = MT7623_CLKS_BITMAP
++	.required_clks = MT7623_CLKS_BITMAP,
++	.required_pctl = true,
+ };
+ 
+ const struct of_device_id of_mtk_match[] = {
+Index: linux-4.14.37/drivers/net/ethernet/mediatek/mtk_eth_soc.h
+===================================================================
+--- linux-4.14.37.orig/drivers/net/ethernet/mediatek/mtk_eth_soc.h
++++ linux-4.14.37/drivers/net/ethernet/mediatek/mtk_eth_soc.h
+@@ -574,10 +574,13 @@ struct mtk_rx_ring {
+  * @caps			Flags shown the extra capability for the SoC
+  * @required_clks		Flags shown the bitmap for required clocks on
+  *				the target SoC
++ * @required_pctl		A bool value to show whether the SoC requires
++ *				the extra setup for those pins used by GMAC.
+  */
+ struct mtk_soc_data {
+ 	u32		caps;
+ 	u32		required_clks;
++	bool		required_pctl;
+ };
+ 
+ /* currently no SoC has more than 2 macs */
diff --git a/target/linux/mediatek/patches-4.14/0176-clk-mediatek-Fix-all-warnings-for-missing-struct-clk.patch b/target/linux/mediatek/patches-4.14/0176-clk-mediatek-Fix-all-warnings-for-missing-struct-clk.patch
new file mode 100644
index 0000000000..911082bf4d
--- /dev/null
+++ b/target/linux/mediatek/patches-4.14/0176-clk-mediatek-Fix-all-warnings-for-missing-struct-clk.patch
@@ -0,0 +1,73 @@
+From f42f141077a12e28fe33c0033f698afb1402ec20 Mon Sep 17 00:00:00 2001
+From: Sean Wang <sean.wang@mediatek.com>
+Date: Mon, 25 Dec 2017 16:03:57 +0800
+Subject: [PATCH 176/224] clk: mediatek: Fix all warnings for missing struct
+ clk_onecell_data
+
+Even though the header file linux/clk-provider.h is already being properly
+included in clk-mtk.h, the definition of struct clk_onecell_data still
+must depend on CONFIG_COMMON_CLK defined and thus it's possible that
+below build warnings occur when CONFIG_COMMON_CLK is not being selected.
+
+Therefore, these functions which need struct clk_onecell_data without
+declaring that structure first requires simply declaring that this struct
+exists prior to referencing it in clk-mtk.h
+
+Changes from v1->v2:
+enhance v1 based on two useful solutions Jean Delvare kindly suggested.
+
+All warnings (new ones prefixed by >>):
+
+In file included from drivers/clk/mediatek/reset.c:22:0:
+>>drivers/clk/mediatek/clk-mtk.h:44:19: warning: 'struct clk_onecell_data'
+declared inside parameter list will not be visible outside of
+this definition or declaration
+  int num, struct clk_onecell_data *clk_data);
+		  ^~~~~~~~~~~~~~~~
+drivers/clk/mediatek/clk-mtk.h:63:19: warning: 'struct clk_onecell_data'
+declared inside parameter list will not be visible outside of
+this definition or declaration
+  int num, struct clk_onecell_data *clk_data);
+		  ^~~~~~~~~~~~~~~~
+drivers/clk/mediatek/clk-mtk.h:145:10: warning: 'struct clk_onecell_data'
+declared inside parameter list will not be visible outside of
+this definition or declaration
+  struct clk_onecell_data *clk_data);
+	 ^~~~~~~~~~~~~~~~
+drivers/clk/mediatek/clk-mtk.h:164:11: warning: 'struct clk_onecell_data'
+declared inside parameter list will not be visible outside of
+this definition or declaration
+   struct clk_onecell_data *clk_data);
+	  ^~~~~~~~~~~~~~~~
+drivers/clk/mediatek/clk-mtk.h:190:12: warning: 'struct clk_onecell_data'
+declared inside parameter list will not be visible outside of this
+definition or declaration
+    struct clk_onecell_data *clk_data);
+	   ^~~~~~~~~~~~~~~~
+
+Reported-by: kbuild test robot <fengguang.wu@intel.com>
+Signed-off-by: Sean Wang <sean.wang@mediatek.com>
+Cc: kbuild-all@01.org
+Cc: Stephen Boyd <sboyd@codeaurora.org>
+Cc: Jean Delvare <jdelvare@suse.de>
+Cc: linux-clk@vger.kernel.org
+Signed-off-by: Stephen Boyd <sboyd@codeaurora.org>
+---
+ drivers/clk/mediatek/clk-mtk.h | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/drivers/clk/mediatek/clk-mtk.h b/drivers/clk/mediatek/clk-mtk.h
+index f10250dcece4..bf8006d41861 100644
+--- a/drivers/clk/mediatek/clk-mtk.h
++++ b/drivers/clk/mediatek/clk-mtk.h
+@@ -20,6 +20,7 @@
+ #include <linux/clk-provider.h>
+ 
+ struct clk;
++struct clk_onecell_data;
+ 
+ #define MAX_MUX_GATE_BIT	31
+ #define INVALID_MUX_GATE_BIT	(MAX_MUX_GATE_BIT + 1)
+-- 
+2.11.0
+
diff --git a/target/linux/mediatek/patches-4.14/0177-phy-phy-mtk-tphy-use-auto-instead-of-force-to-bypass.patch b/target/linux/mediatek/patches-4.14/0177-phy-phy-mtk-tphy-use-auto-instead-of-force-to-bypass.patch
new file mode 100644
index 0000000000..4b230cd622
--- /dev/null
+++ b/target/linux/mediatek/patches-4.14/0177-phy-phy-mtk-tphy-use-auto-instead-of-force-to-bypass.patch
@@ -0,0 +1,80 @@
+From dacdae142ffd909ed6718adb05af74ff800da668 Mon Sep 17 00:00:00 2001
+From: Chunfeng Yun <chunfeng.yun@mediatek.com>
+Date: Thu, 7 Dec 2017 19:53:34 +0800
+Subject: [PATCH 177/224] phy: phy-mtk-tphy: use auto instead of force to
+ bypass utmi signals
+
+When system is running, if usb2 phy is forced to bypass utmi signals,
+all PLL will be turned off, and it can't detect device connection
+anymore, so replace force mode with auto mode which can bypass utmi
+signals automatically if no device attached for normal flow.
+But keep the force mode to fix RX sensitivity degradation issue.
+
+Signed-off-by: Chunfeng Yun <chunfeng.yun@mediatek.com>
+Signed-off-by: Kishon Vijay Abraham I <kishon@ti.com>
+---
+ drivers/phy/mediatek/phy-mtk-tphy.c | 19 +++++++------------
+ 1 file changed, 7 insertions(+), 12 deletions(-)
+
+diff --git a/drivers/phy/mediatek/phy-mtk-tphy.c b/drivers/phy/mediatek/phy-mtk-tphy.c
+index 402385f2562a..54cc44b2d289 100644
+--- a/drivers/phy/mediatek/phy-mtk-tphy.c
++++ b/drivers/phy/mediatek/phy-mtk-tphy.c
+@@ -440,9 +440,9 @@ static void u2_phy_instance_init(struct mtk_tphy *tphy,
+ 	u32 index = instance->index;
+ 	u32 tmp;
+ 
+-	/* switch to USB function. (system register, force ip into usb mode) */
++	/* switch to USB function, and enable usb pll */
+ 	tmp = readl(com + U3P_U2PHYDTM0);
+-	tmp &= ~P2C_FORCE_UART_EN;
++	tmp &= ~(P2C_FORCE_UART_EN | P2C_FORCE_SUSPENDM);
+ 	tmp |= P2C_RG_XCVRSEL_VAL(1) | P2C_RG_DATAIN_VAL(0);
+ 	writel(tmp, com + U3P_U2PHYDTM0);
+ 
+@@ -502,10 +502,8 @@ static void u2_phy_instance_power_on(struct mtk_tphy *tphy,
+ 	u32 index = instance->index;
+ 	u32 tmp;
+ 
+-	/* (force_suspendm=0) (let suspendm=1, enable usb 480MHz pll) */
+ 	tmp = readl(com + U3P_U2PHYDTM0);
+-	tmp &= ~(P2C_FORCE_SUSPENDM | P2C_RG_XCVRSEL);
+-	tmp &= ~(P2C_RG_DATAIN | P2C_DTM0_PART_MASK);
++	tmp &= ~(P2C_RG_XCVRSEL | P2C_RG_DATAIN | P2C_DTM0_PART_MASK);
+ 	writel(tmp, com + U3P_U2PHYDTM0);
+ 
+ 	/* OTG Enable */
+@@ -540,7 +538,6 @@ static void u2_phy_instance_power_off(struct mtk_tphy *tphy,
+ 
+ 	tmp = readl(com + U3P_U2PHYDTM0);
+ 	tmp &= ~(P2C_RG_XCVRSEL | P2C_RG_DATAIN);
+-	tmp |= P2C_FORCE_SUSPENDM;
+ 	writel(tmp, com + U3P_U2PHYDTM0);
+ 
+ 	/* OTG Disable */
+@@ -548,18 +545,16 @@ static void u2_phy_instance_power_off(struct mtk_tphy *tphy,
+ 	tmp &= ~PA6_RG_U2_OTG_VBUSCMP_EN;
+ 	writel(tmp, com + U3P_USBPHYACR6);
+ 
+-	/* let suspendm=0, set utmi into analog power down */
+-	tmp = readl(com + U3P_U2PHYDTM0);
+-	tmp &= ~P2C_RG_SUSPENDM;
+-	writel(tmp, com + U3P_U2PHYDTM0);
+-	udelay(1);
+-
+ 	tmp = readl(com + U3P_U2PHYDTM1);
+ 	tmp &= ~(P2C_RG_VBUSVALID | P2C_RG_AVALID);
+ 	tmp |= P2C_RG_SESSEND;
+ 	writel(tmp, com + U3P_U2PHYDTM1);
+ 
+ 	if (tphy->pdata->avoid_rx_sen_degradation && index) {
++		tmp = readl(com + U3P_U2PHYDTM0);
++		tmp &= ~(P2C_RG_SUSPENDM | P2C_FORCE_SUSPENDM);
++		writel(tmp, com + U3P_U2PHYDTM0);
++
+ 		tmp = readl(com + U3D_U2PHYDCR0);
+ 		tmp &= ~P2C_RG_SIF_U2PLL_FORCE_ON;
+ 		writel(tmp, com + U3D_U2PHYDCR0);
+-- 
+2.11.0
+
diff --git a/target/linux/mediatek/patches-4.14/0178-phy-phy-mtk-tphy-make-shared-banks-optional-for-V1-T.patch b/target/linux/mediatek/patches-4.14/0178-phy-phy-mtk-tphy-make-shared-banks-optional-for-V1-T.patch
new file mode 100644
index 0000000000..78e913ea6f
--- /dev/null
+++ b/target/linux/mediatek/patches-4.14/0178-phy-phy-mtk-tphy-make-shared-banks-optional-for-V1-T.patch
@@ -0,0 +1,35 @@
+From d7a38584713b00cf9ae97aed89d5e8fb7e3c1bea Mon Sep 17 00:00:00 2001
+From: Chunfeng Yun <chunfeng.yun@mediatek.com>
+Date: Thu, 7 Dec 2017 19:53:35 +0800
+Subject: [PATCH 178/224] phy: phy-mtk-tphy: make shared banks optional for V1
+ TPHY
+
+V1 TPHY for SATA doesn't have shared banks if it isn't shared
+with PCIe or USB, so make it optional.
+
+Signed-off-by: Chunfeng Yun <chunfeng.yun@mediatek.com>
+Signed-off-by: Kishon Vijay Abraham I <kishon@ti.com>
+---
+ drivers/phy/mediatek/phy-mtk-tphy.c | 5 +++--
+ 1 file changed, 3 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/phy/mediatek/phy-mtk-tphy.c b/drivers/phy/mediatek/phy-mtk-tphy.c
+index 54cc44b2d289..11cab1d84a02 100644
+--- a/drivers/phy/mediatek/phy-mtk-tphy.c
++++ b/drivers/phy/mediatek/phy-mtk-tphy.c
+@@ -1023,9 +1023,10 @@ static int mtk_tphy_probe(struct platform_device *pdev)
+ 	tphy->dev = dev;
+ 	platform_set_drvdata(pdev, tphy);
+ 
+-	if (tphy->pdata->version == MTK_PHY_V1) {
++	sif_res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
++	/* SATA phy of V1 needn't it if not shared with PCIe or USB */
++	if (sif_res && tphy->pdata->version == MTK_PHY_V1) {
+ 		/* get banks shared by multiple phys */
+-		sif_res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+ 		tphy->sif_base = devm_ioremap_resource(dev, sif_res);
+ 		if (IS_ERR(tphy->sif_base)) {
+ 			dev_err(dev, "failed to remap sif regs\n");
+-- 
+2.11.0
+
diff --git a/target/linux/mediatek/patches-4.14/0179-phy-phy-mtk-tphy-use-of_device_get_match_data.patch b/target/linux/mediatek/patches-4.14/0179-phy-phy-mtk-tphy-use-of_device_get_match_data.patch
new file mode 100644
index 0000000000..e28ab55c3a
--- /dev/null
+++ b/target/linux/mediatek/patches-4.14/0179-phy-phy-mtk-tphy-use-of_device_get_match_data.patch
@@ -0,0 +1,56 @@
+From 3e53007a55e70d5036a527900befecf9a6316d05 Mon Sep 17 00:00:00 2001
+From: Chunfeng Yun <chunfeng.yun@mediatek.com>
+Date: Thu, 28 Dec 2017 16:40:36 +0530
+Subject: [PATCH 179/224] phy: phy-mtk-tphy: use of_device_get_match_data()
+
+reduce the boilerplate code to get the specific data
+
+Signed-off-by: Chunfeng Yun <chunfeng.yun@mediatek.com>
+Signed-off-by: Kishon Vijay Abraham I <kishon@ti.com>
+---
+ drivers/phy/mediatek/phy-mtk-tphy.c | 11 +++++------
+ 1 file changed, 5 insertions(+), 6 deletions(-)
+
+diff --git a/drivers/phy/mediatek/phy-mtk-tphy.c b/drivers/phy/mediatek/phy-mtk-tphy.c
+index 11cab1d84a02..1e96d0740ef5 100644
+--- a/drivers/phy/mediatek/phy-mtk-tphy.c
++++ b/drivers/phy/mediatek/phy-mtk-tphy.c
+@@ -20,6 +20,7 @@
+ #include <linux/iopoll.h>
+ #include <linux/module.h>
+ #include <linux/of_address.h>
++#include <linux/of_device.h>
+ #include <linux/phy/phy.h>
+ #include <linux/platform_device.h>
+ 
+@@ -995,7 +996,6 @@ MODULE_DEVICE_TABLE(of, mtk_tphy_id_table);
+ 
+ static int mtk_tphy_probe(struct platform_device *pdev)
+ {
+-	const struct of_device_id *match;
+ 	struct device *dev = &pdev->dev;
+ 	struct device_node *np = dev->of_node;
+ 	struct device_node *child_np;
+@@ -1005,15 +1005,14 @@ static int mtk_tphy_probe(struct platform_device *pdev)
+ 	struct resource res;
+ 	int port, retval;
+ 
+-	match = of_match_node(mtk_tphy_id_table, pdev->dev.of_node);
+-	if (!match)
+-		return -EINVAL;
+-
+ 	tphy = devm_kzalloc(dev, sizeof(*tphy), GFP_KERNEL);
+ 	if (!tphy)
+ 		return -ENOMEM;
+ 
+-	tphy->pdata = match->data;
++	tphy->pdata = of_device_get_match_data(dev);
++	if (!tphy->pdata)
++		return -EINVAL;
++
+ 	tphy->nphys = of_get_child_count(np);
+ 	tphy->phys = devm_kcalloc(dev, tphy->nphys,
+ 				       sizeof(*tphy->phys), GFP_KERNEL);
+-- 
+2.11.0
+
diff --git a/target/linux/mediatek/patches-4.14/0180-ASoC-mediatek-fix-error-handling-in-mt2701_afe_pcm_d.patch b/target/linux/mediatek/patches-4.14/0180-ASoC-mediatek-fix-error-handling-in-mt2701_afe_pcm_d.patch
new file mode 100644
index 0000000000..074baa04b2
--- /dev/null
+++ b/target/linux/mediatek/patches-4.14/0180-ASoC-mediatek-fix-error-handling-in-mt2701_afe_pcm_d.patch
@@ -0,0 +1,86 @@
+From 17508c32dd65649d2617c1c52b32b02bdb54b793 Mon Sep 17 00:00:00 2001
+From: Ryder Lee <ryder.lee@mediatek.com>
+Date: Tue, 2 Jan 2018 19:47:18 +0800
+Subject: [PATCH 180/224] ASoC: mediatek: fix error handling in
+ mt2701_afe_pcm_dev_probe()
+
+Fix unbalanced error handling path which will get incorrect counts
+if probe failed. The .remove() should be adjusted accordingly.
+
+Signed-off-by: Ryder Lee <ryder.lee@mediatek.com>
+Tested-by: Garlic Tseng <garlic.tseng@mediatek.com>
+Signed-off-by: Mark Brown <broonie@kernel.org>
+---
+ sound/soc/mediatek/mt2701/mt2701-afe-pcm.c | 31 ++++++++++++++----------------
+ 1 file changed, 14 insertions(+), 17 deletions(-)
+
+diff --git a/sound/soc/mediatek/mt2701/mt2701-afe-pcm.c b/sound/soc/mediatek/mt2701/mt2701-afe-pcm.c
+index 8fda182f849b..a7362d1cda1b 100644
+--- a/sound/soc/mediatek/mt2701/mt2701-afe-pcm.c
++++ b/sound/soc/mediatek/mt2701/mt2701-afe-pcm.c
+@@ -1590,12 +1590,16 @@ static int mt2701_afe_pcm_dev_probe(struct platform_device *pdev)
+ 	}
+ 
+ 	platform_set_drvdata(pdev, afe);
+-	pm_runtime_enable(&pdev->dev);
+-	if (!pm_runtime_enabled(&pdev->dev))
+-		goto err_pm_disable;
+-	pm_runtime_get_sync(&pdev->dev);
+ 
+-	ret = snd_soc_register_platform(&pdev->dev, &mtk_afe_pcm_platform);
++	pm_runtime_enable(dev);
++	if (!pm_runtime_enabled(dev)) {
++		ret = mt2701_afe_runtime_resume(dev);
++		if (ret)
++			goto err_pm_disable;
++	}
++	pm_runtime_get_sync(dev);
++
++	ret = snd_soc_register_platform(dev, &mtk_afe_pcm_platform);
+ 	if (ret) {
+ 		dev_warn(dev, "err_platform\n");
+ 		goto err_platform;
+@@ -1610,35 +1614,28 @@ static int mt2701_afe_pcm_dev_probe(struct platform_device *pdev)
+ 		goto err_dai_component;
+ 	}
+ 
+-	mt2701_afe_runtime_resume(&pdev->dev);
+-
+ 	return 0;
+ 
+ err_dai_component:
+-	snd_soc_unregister_component(&pdev->dev);
+-
++	snd_soc_unregister_platform(dev);
+ err_platform:
+-	snd_soc_unregister_platform(&pdev->dev);
+-
++	pm_runtime_put_sync(dev);
+ err_pm_disable:
+-	pm_runtime_disable(&pdev->dev);
++	pm_runtime_disable(dev);
+ 
+ 	return ret;
+ }
+ 
+ static int mt2701_afe_pcm_dev_remove(struct platform_device *pdev)
+ {
+-	struct mtk_base_afe *afe = platform_get_drvdata(pdev);
+-
++	pm_runtime_put_sync(&pdev->dev);
+ 	pm_runtime_disable(&pdev->dev);
+ 	if (!pm_runtime_status_suspended(&pdev->dev))
+ 		mt2701_afe_runtime_suspend(&pdev->dev);
+-	pm_runtime_put_sync(&pdev->dev);
+ 
+ 	snd_soc_unregister_component(&pdev->dev);
+ 	snd_soc_unregister_platform(&pdev->dev);
+-	/* disable afe clock */
+-	mt2701_afe_disable_clock(afe);
++
+ 	return 0;
+ }
+ 
+-- 
+2.11.0
+
diff --git a/target/linux/mediatek/patches-4.14/0181-ASoC-mediatek-rework-clock-functions-for-MT2701.patch b/target/linux/mediatek/patches-4.14/0181-ASoC-mediatek-rework-clock-functions-for-MT2701.patch
new file mode 100644
index 0000000000..579749038c
--- /dev/null
+++ b/target/linux/mediatek/patches-4.14/0181-ASoC-mediatek-rework-clock-functions-for-MT2701.patch
@@ -0,0 +1,932 @@
+From d038da516563d910dd39930777f431d4c65a56cd Mon Sep 17 00:00:00 2001
+From: Ryder Lee <ryder.lee@mediatek.com>
+Date: Tue, 2 Jan 2018 19:47:19 +0800
+Subject: [PATCH 181/224] ASoC: mediatek: rework clock functions for MT2701
+
+Reworks clock part to make it more reasonable. The current changes are:
+
+- Replace regmap operations by CCF APIs. Doing so, we just need to handle
+  the element clocks and can also get accurate information via CCF.
+
+- Rename clocks to make them more generic so that the future revisions
+  of the IP can adapt gracefully.
+
+- Regroup 'aud_clks[]' by usage - the basic needs and I2S parts:
+
+  The new code just keep the common clocks in array and let SoC self decide
+  I2S numbers - If future chips have different sets of channels we will
+  add a little more abstract here.
+
+  Moreover, this patch moves I2S clocks to the struct mt2701_i2s_data
+  so that we can easily manage them when calls .prepare() and .shutdown().
+
+Signed-off-by: Ryder Lee <ryder.lee@mediatek.com>
+Tested-by: Garlic Tseng <garlic.tseng@mediatek.com>
+Signed-off-by: Mark Brown <broonie@kernel.org>
+---
+ sound/soc/mediatek/mt2701/mt2701-afe-clock-ctrl.c | 518 +++++++---------------
+ sound/soc/mediatek/mt2701/mt2701-afe-clock-ctrl.h |  15 +-
+ sound/soc/mediatek/mt2701/mt2701-afe-common.h     |  64 +--
+ sound/soc/mediatek/mt2701/mt2701-afe-pcm.c        |  45 +-
+ 4 files changed, 200 insertions(+), 442 deletions(-)
+
+diff --git a/sound/soc/mediatek/mt2701/mt2701-afe-clock-ctrl.c b/sound/soc/mediatek/mt2701/mt2701-afe-clock-ctrl.c
+index affa7fb25dd9..75ccdca5811d 100644
+--- a/sound/soc/mediatek/mt2701/mt2701-afe-clock-ctrl.c
++++ b/sound/soc/mediatek/mt2701/mt2701-afe-clock-ctrl.c
+@@ -21,442 +21,256 @@
+ #include "mt2701-afe-common.h"
+ #include "mt2701-afe-clock-ctrl.h"
+ 
+-static const char *aud_clks[MT2701_CLOCK_NUM] = {
+-	[MT2701_AUD_INFRA_SYS_AUDIO] = "infra_sys_audio_clk",
+-	[MT2701_AUD_AUD_MUX1_SEL] = "top_audio_mux1_sel",
+-	[MT2701_AUD_AUD_MUX2_SEL] = "top_audio_mux2_sel",
+-	[MT2701_AUD_AUD_MUX1_DIV] = "top_audio_mux1_div",
+-	[MT2701_AUD_AUD_MUX2_DIV] = "top_audio_mux2_div",
+-	[MT2701_AUD_AUD_48K_TIMING] = "top_audio_48k_timing",
+-	[MT2701_AUD_AUD_44K_TIMING] = "top_audio_44k_timing",
+-	[MT2701_AUD_AUDPLL_MUX_SEL] = "top_audpll_mux_sel",
+-	[MT2701_AUD_APLL_SEL] = "top_apll_sel",
+-	[MT2701_AUD_AUD1PLL_98M] = "top_aud1_pll_98M",
+-	[MT2701_AUD_AUD2PLL_90M] = "top_aud2_pll_90M",
+-	[MT2701_AUD_HADDS2PLL_98M] = "top_hadds2_pll_98M",
+-	[MT2701_AUD_HADDS2PLL_294M] = "top_hadds2_pll_294M",
+-	[MT2701_AUD_AUDPLL] = "top_audpll",
+-	[MT2701_AUD_AUDPLL_D4] = "top_audpll_d4",
+-	[MT2701_AUD_AUDPLL_D8] = "top_audpll_d8",
+-	[MT2701_AUD_AUDPLL_D16] = "top_audpll_d16",
+-	[MT2701_AUD_AUDPLL_D24] = "top_audpll_d24",
+-	[MT2701_AUD_AUDINTBUS] = "top_audintbus_sel",
+-	[MT2701_AUD_CLK_26M] = "clk_26m",
+-	[MT2701_AUD_SYSPLL1_D4] = "top_syspll1_d4",
+-	[MT2701_AUD_AUD_K1_SRC_SEL] = "top_aud_k1_src_sel",
+-	[MT2701_AUD_AUD_K2_SRC_SEL] = "top_aud_k2_src_sel",
+-	[MT2701_AUD_AUD_K3_SRC_SEL] = "top_aud_k3_src_sel",
+-	[MT2701_AUD_AUD_K4_SRC_SEL] = "top_aud_k4_src_sel",
+-	[MT2701_AUD_AUD_K5_SRC_SEL] = "top_aud_k5_src_sel",
+-	[MT2701_AUD_AUD_K6_SRC_SEL] = "top_aud_k6_src_sel",
+-	[MT2701_AUD_AUD_K1_SRC_DIV] = "top_aud_k1_src_div",
+-	[MT2701_AUD_AUD_K2_SRC_DIV] = "top_aud_k2_src_div",
+-	[MT2701_AUD_AUD_K3_SRC_DIV] = "top_aud_k3_src_div",
+-	[MT2701_AUD_AUD_K4_SRC_DIV] = "top_aud_k4_src_div",
+-	[MT2701_AUD_AUD_K5_SRC_DIV] = "top_aud_k5_src_div",
+-	[MT2701_AUD_AUD_K6_SRC_DIV] = "top_aud_k6_src_div",
+-	[MT2701_AUD_AUD_I2S1_MCLK] = "top_aud_i2s1_mclk",
+-	[MT2701_AUD_AUD_I2S2_MCLK] = "top_aud_i2s2_mclk",
+-	[MT2701_AUD_AUD_I2S3_MCLK] = "top_aud_i2s3_mclk",
+-	[MT2701_AUD_AUD_I2S4_MCLK] = "top_aud_i2s4_mclk",
+-	[MT2701_AUD_AUD_I2S5_MCLK] = "top_aud_i2s5_mclk",
+-	[MT2701_AUD_AUD_I2S6_MCLK] = "top_aud_i2s6_mclk",
+-	[MT2701_AUD_ASM_M_SEL] = "top_asm_m_sel",
+-	[MT2701_AUD_ASM_H_SEL] = "top_asm_h_sel",
+-	[MT2701_AUD_UNIVPLL2_D4] = "top_univpll2_d4",
+-	[MT2701_AUD_UNIVPLL2_D2] = "top_univpll2_d2",
+-	[MT2701_AUD_SYSPLL_D5] = "top_syspll_d5",
++static const char *const base_clks[] = {
++	[MT2701_TOP_AUD_MCLK_SRC0] = "top_audio_mux1_sel",
++	[MT2701_TOP_AUD_MCLK_SRC1] = "top_audio_mux2_sel",
++	[MT2701_AUDSYS_AFE] = "audio_afe_pd",
++	[MT2701_AUDSYS_AFE_CONN] = "audio_afe_conn_pd",
++	[MT2701_AUDSYS_A1SYS] = "audio_a1sys_pd",
++	[MT2701_AUDSYS_A2SYS] = "audio_a2sys_pd",
+ };
+ 
+ int mt2701_init_clock(struct mtk_base_afe *afe)
+ {
+ 	struct mt2701_afe_private *afe_priv = afe->platform_priv;
+-	int i = 0;
+-
+-	for (i = 0; i < MT2701_CLOCK_NUM; i++) {
+-		afe_priv->clocks[i] = devm_clk_get(afe->dev, aud_clks[i]);
+-		if (IS_ERR(afe_priv->clocks[i])) {
+-			dev_warn(afe->dev, "%s devm_clk_get %s fail\n",
+-				 __func__, aud_clks[i]);
+-			return PTR_ERR(aud_clks[i]);
++	int i;
++
++	for (i = 0; i < MT2701_BASE_CLK_NUM; i++) {
++		afe_priv->base_ck[i] = devm_clk_get(afe->dev, base_clks[i]);
++		if (IS_ERR(afe_priv->base_ck[i])) {
++			dev_err(afe->dev, "failed to get %s\n", base_clks[i]);
++			return PTR_ERR(afe_priv->base_ck[i]);
+ 		}
+ 	}
+ 
+-	return 0;
+-}
++	/* Get I2S related clocks */
++	for (i = 0; i < MT2701_I2S_NUM; i++) {
++		struct mt2701_i2s_path *i2s_path = &afe_priv->i2s_path[i];
++		char name[13];
+ 
+-int mt2701_afe_enable_clock(struct mtk_base_afe *afe)
+-{
+-	int ret = 0;
++		snprintf(name, sizeof(name), "i2s%d_src_sel", i);
++		i2s_path->sel_ck = devm_clk_get(afe->dev, name);
++		if (IS_ERR(i2s_path->sel_ck)) {
++			dev_err(afe->dev, "failed to get %s\n", name);
++			return PTR_ERR(i2s_path->sel_ck);
++		}
+ 
+-	ret = mt2701_turn_on_a1sys_clock(afe);
+-	if (ret) {
+-		dev_err(afe->dev, "%s turn_on_a1sys_clock fail %d\n",
+-			__func__, ret);
+-		return ret;
+-	}
++		snprintf(name, sizeof(name), "i2s%d_src_div", i);
++		i2s_path->div_ck = devm_clk_get(afe->dev, name);
++		if (IS_ERR(i2s_path->div_ck)) {
++			dev_err(afe->dev, "failed to get %s\n", name);
++			return PTR_ERR(i2s_path->div_ck);
++		}
+ 
+-	ret = mt2701_turn_on_a2sys_clock(afe);
+-	if (ret) {
+-		dev_err(afe->dev, "%s turn_on_a2sys_clock fail %d\n",
+-			__func__, ret);
+-		mt2701_turn_off_a1sys_clock(afe);
+-		return ret;
+-	}
++		snprintf(name, sizeof(name), "i2s%d_mclk_en", i);
++		i2s_path->mclk_ck = devm_clk_get(afe->dev, name);
++		if (IS_ERR(i2s_path->mclk_ck)) {
++			dev_err(afe->dev, "failed to get %s\n", name);
++			return PTR_ERR(i2s_path->mclk_ck);
++		}
+ 
+-	ret = mt2701_turn_on_afe_clock(afe);
+-	if (ret) {
+-		dev_err(afe->dev, "%s turn_on_afe_clock fail %d\n",
+-			__func__, ret);
+-		mt2701_turn_off_a1sys_clock(afe);
+-		mt2701_turn_off_a2sys_clock(afe);
+-		return ret;
++		snprintf(name, sizeof(name), "i2so%d_hop_ck", i);
++		i2s_path->hop_ck[I2S_OUT] = devm_clk_get(afe->dev, name);
++		if (IS_ERR(i2s_path->hop_ck[I2S_OUT])) {
++			dev_err(afe->dev, "failed to get %s\n", name);
++			return PTR_ERR(i2s_path->hop_ck[I2S_OUT]);
++		}
++
++		snprintf(name, sizeof(name), "i2si%d_hop_ck", i);
++		i2s_path->hop_ck[I2S_IN] = devm_clk_get(afe->dev, name);
++		if (IS_ERR(i2s_path->hop_ck[I2S_IN])) {
++			dev_err(afe->dev, "failed to get %s\n", name);
++			return PTR_ERR(i2s_path->hop_ck[I2S_IN]);
++		}
++
++		snprintf(name, sizeof(name), "asrc%d_out_ck", i);
++		i2s_path->asrco_ck = devm_clk_get(afe->dev, name);
++		if (IS_ERR(i2s_path->asrco_ck)) {
++			dev_err(afe->dev, "failed to get %s\n", name);
++			return PTR_ERR(i2s_path->asrco_ck);
++		}
+ 	}
+ 
+-	regmap_update_bits(afe->regmap, ASYS_TOP_CON,
+-			   AUDIO_TOP_CON0_A1SYS_A2SYS_ON,
+-			   AUDIO_TOP_CON0_A1SYS_A2SYS_ON);
+-	regmap_update_bits(afe->regmap, AFE_DAC_CON0,
+-			   AFE_DAC_CON0_AFE_ON,
+-			   AFE_DAC_CON0_AFE_ON);
+-	regmap_write(afe->regmap, PWR2_TOP_CON,
+-		     PWR2_TOP_CON_INIT_VAL);
+-	regmap_write(afe->regmap, PWR1_ASM_CON1,
+-		     PWR1_ASM_CON1_INIT_VAL);
+-	regmap_write(afe->regmap, PWR2_ASM_CON1,
+-		     PWR2_ASM_CON1_INIT_VAL);
++	/* Some platforms may support BT path */
++	afe_priv->mrgif_ck = devm_clk_get(afe->dev, "audio_mrgif_pd");
++	if (IS_ERR(afe_priv->mrgif_ck)) {
++		if (PTR_ERR(afe_priv->mrgif_ck) == -EPROBE_DEFER)
++			return -EPROBE_DEFER;
+ 
+-	return 0;
+-}
++		afe_priv->mrgif_ck = NULL;
++	}
+ 
+-void mt2701_afe_disable_clock(struct mtk_base_afe *afe)
+-{
+-	mt2701_turn_off_afe_clock(afe);
+-	mt2701_turn_off_a1sys_clock(afe);
+-	mt2701_turn_off_a2sys_clock(afe);
+-	regmap_update_bits(afe->regmap, ASYS_TOP_CON,
+-			   AUDIO_TOP_CON0_A1SYS_A2SYS_ON, 0);
+-	regmap_update_bits(afe->regmap, AFE_DAC_CON0,
+-			   AFE_DAC_CON0_AFE_ON, 0);
++	return 0;
+ }
+ 
+-int mt2701_turn_on_a1sys_clock(struct mtk_base_afe *afe)
++int mt2701_afe_enable_i2s(struct mtk_base_afe *afe, int id, int dir)
+ {
+ 	struct mt2701_afe_private *afe_priv = afe->platform_priv;
+-	int ret = 0;
++	struct mt2701_i2s_path *i2s_path = &afe_priv->i2s_path[id];
++	int ret;
+ 
+-	/* Set Mux */
+-	ret = clk_prepare_enable(afe_priv->clocks[MT2701_AUD_AUD_MUX1_SEL]);
++	ret = clk_prepare_enable(i2s_path->asrco_ck);
+ 	if (ret) {
+-		dev_err(afe->dev, "%s clk_prepare_enable %s fail %d\n",
+-			__func__, aud_clks[MT2701_AUD_AUD_MUX1_SEL], ret);
+-		goto A1SYS_CLK_AUD_MUX1_SEL_ERR;
++		dev_err(afe->dev, "failed to enable ASRC clock %d\n", ret);
++		return ret;
+ 	}
+ 
+-	ret = clk_set_parent(afe_priv->clocks[MT2701_AUD_AUD_MUX1_SEL],
+-			     afe_priv->clocks[MT2701_AUD_AUD1PLL_98M]);
++	ret = clk_prepare_enable(i2s_path->hop_ck[dir]);
+ 	if (ret) {
+-		dev_err(afe->dev, "%s clk_set_parent %s-%s fail %d\n", __func__,
+-			aud_clks[MT2701_AUD_AUD_MUX1_SEL],
+-			aud_clks[MT2701_AUD_AUD1PLL_98M], ret);
+-		goto A1SYS_CLK_AUD_MUX1_SEL_ERR;
++		dev_err(afe->dev, "failed to enable I2S clock %d\n", ret);
++		goto err_hop_ck;
+ 	}
+ 
+-	/* Set Divider */
+-	ret = clk_prepare_enable(afe_priv->clocks[MT2701_AUD_AUD_MUX1_DIV]);
+-	if (ret) {
+-		dev_err(afe->dev, "%s clk_prepare_enable %s fail %d\n",
+-			__func__,
+-			aud_clks[MT2701_AUD_AUD_MUX1_DIV],
+-			ret);
+-		goto A1SYS_CLK_AUD_MUX1_DIV_ERR;
+-	}
++	return 0;
+ 
+-	ret = clk_set_rate(afe_priv->clocks[MT2701_AUD_AUD_MUX1_DIV],
+-			   MT2701_AUD_AUD_MUX1_DIV_RATE);
+-	if (ret) {
+-		dev_err(afe->dev, "%s clk_set_parent %s-%d fail %d\n", __func__,
+-			aud_clks[MT2701_AUD_AUD_MUX1_DIV],
+-			MT2701_AUD_AUD_MUX1_DIV_RATE, ret);
+-		goto A1SYS_CLK_AUD_MUX1_DIV_ERR;
+-	}
++err_hop_ck:
++	clk_disable_unprepare(i2s_path->asrco_ck);
+ 
+-	/* Enable clock gate */
+-	ret = clk_prepare_enable(afe_priv->clocks[MT2701_AUD_AUD_48K_TIMING]);
+-	if (ret) {
+-		dev_err(afe->dev, "%s clk_prepare_enable %s fail %d\n",
+-			__func__, aud_clks[MT2701_AUD_AUD_48K_TIMING], ret);
+-		goto A1SYS_CLK_AUD_48K_ERR;
+-	}
++	return ret;
++}
+ 
+-	/* Enable infra audio */
+-	ret = clk_prepare_enable(afe_priv->clocks[MT2701_AUD_INFRA_SYS_AUDIO]);
+-	if (ret) {
+-		dev_err(afe->dev, "%s clk_prepare_enable %s fail %d\n",
+-			__func__, aud_clks[MT2701_AUD_INFRA_SYS_AUDIO], ret);
+-		goto A1SYS_CLK_INFRA_ERR;
+-	}
++void mt2701_afe_disable_i2s(struct mtk_base_afe *afe, int id, int dir)
++{
++	struct mt2701_afe_private *afe_priv = afe->platform_priv;
++	struct mt2701_i2s_path *i2s_path = &afe_priv->i2s_path[id];
+ 
+-	return 0;
++	clk_disable_unprepare(i2s_path->hop_ck[dir]);
++	clk_disable_unprepare(i2s_path->asrco_ck);
++}
+ 
+-A1SYS_CLK_INFRA_ERR:
+-	clk_disable_unprepare(afe_priv->clocks[MT2701_AUD_INFRA_SYS_AUDIO]);
+-A1SYS_CLK_AUD_48K_ERR:
+-	clk_disable_unprepare(afe_priv->clocks[MT2701_AUD_AUD_48K_TIMING]);
+-A1SYS_CLK_AUD_MUX1_DIV_ERR:
+-	clk_disable_unprepare(afe_priv->clocks[MT2701_AUD_AUD_MUX1_DIV]);
+-A1SYS_CLK_AUD_MUX1_SEL_ERR:
+-	clk_disable_unprepare(afe_priv->clocks[MT2701_AUD_AUD_MUX1_SEL]);
++int mt2701_afe_enable_mclk(struct mtk_base_afe *afe, int id)
++{
++	struct mt2701_afe_private *afe_priv = afe->platform_priv;
++	struct mt2701_i2s_path *i2s_path = &afe_priv->i2s_path[id];
+ 
+-	return ret;
++	return clk_prepare_enable(i2s_path->mclk_ck);
+ }
+ 
+-void mt2701_turn_off_a1sys_clock(struct mtk_base_afe *afe)
++void mt2701_afe_disable_mclk(struct mtk_base_afe *afe, int id)
+ {
+ 	struct mt2701_afe_private *afe_priv = afe->platform_priv;
++	struct mt2701_i2s_path *i2s_path = &afe_priv->i2s_path[id];
+ 
+-	clk_disable_unprepare(afe_priv->clocks[MT2701_AUD_INFRA_SYS_AUDIO]);
+-	clk_disable_unprepare(afe_priv->clocks[MT2701_AUD_AUD_48K_TIMING]);
+-	clk_disable_unprepare(afe_priv->clocks[MT2701_AUD_AUD_MUX1_DIV]);
+-	clk_disable_unprepare(afe_priv->clocks[MT2701_AUD_AUD_MUX1_SEL]);
++	clk_disable_unprepare(i2s_path->mclk_ck);
+ }
+ 
+-int mt2701_turn_on_a2sys_clock(struct mtk_base_afe *afe)
++int mt2701_enable_btmrg_clk(struct mtk_base_afe *afe)
+ {
+ 	struct mt2701_afe_private *afe_priv = afe->platform_priv;
+-	int ret = 0;
+ 
+-	/* Set Mux */
+-	ret = clk_prepare_enable(afe_priv->clocks[MT2701_AUD_AUD_MUX2_SEL]);
+-	if (ret) {
+-		dev_err(afe->dev, "%s clk_prepare_enable %s fail %d\n",
+-			__func__, aud_clks[MT2701_AUD_AUD_MUX2_SEL], ret);
+-		goto A2SYS_CLK_AUD_MUX2_SEL_ERR;
+-	}
++	return clk_prepare_enable(afe_priv->mrgif_ck);
++}
+ 
+-	ret = clk_set_parent(afe_priv->clocks[MT2701_AUD_AUD_MUX2_SEL],
+-			     afe_priv->clocks[MT2701_AUD_AUD2PLL_90M]);
+-	if (ret) {
+-		dev_err(afe->dev, "%s clk_set_parent %s-%s fail %d\n", __func__,
+-			aud_clks[MT2701_AUD_AUD_MUX2_SEL],
+-			aud_clks[MT2701_AUD_AUD2PLL_90M], ret);
+-		goto A2SYS_CLK_AUD_MUX2_SEL_ERR;
+-	}
++void mt2701_disable_btmrg_clk(struct mtk_base_afe *afe)
++{
++	struct mt2701_afe_private *afe_priv = afe->platform_priv;
+ 
+-	/* Set Divider */
+-	ret = clk_prepare_enable(afe_priv->clocks[MT2701_AUD_AUD_MUX2_DIV]);
+-	if (ret) {
+-		dev_err(afe->dev, "%s clk_prepare_enable %s fail %d\n",
+-			__func__, aud_clks[MT2701_AUD_AUD_MUX2_DIV], ret);
+-		goto A2SYS_CLK_AUD_MUX2_DIV_ERR;
+-	}
++	clk_disable_unprepare(afe_priv->mrgif_ck);
++}
+ 
+-	ret = clk_set_rate(afe_priv->clocks[MT2701_AUD_AUD_MUX2_DIV],
+-			   MT2701_AUD_AUD_MUX2_DIV_RATE);
+-	if (ret) {
+-		dev_err(afe->dev, "%s clk_set_parent %s-%d fail %d\n", __func__,
+-			aud_clks[MT2701_AUD_AUD_MUX2_DIV],
+-			MT2701_AUD_AUD_MUX2_DIV_RATE, ret);
+-		goto A2SYS_CLK_AUD_MUX2_DIV_ERR;
+-	}
++static int mt2701_afe_enable_audsys(struct mtk_base_afe *afe)
++{
++	struct mt2701_afe_private *afe_priv = afe->platform_priv;
++	int ret;
+ 
+-	/* Enable clock gate */
+-	ret = clk_prepare_enable(afe_priv->clocks[MT2701_AUD_AUD_44K_TIMING]);
+-	if (ret) {
+-		dev_err(afe->dev, "%s clk_prepare_enable %s fail %d\n",
+-			__func__, aud_clks[MT2701_AUD_AUD_44K_TIMING], ret);
+-		goto A2SYS_CLK_AUD_44K_ERR;
+-	}
++	ret = clk_prepare_enable(afe_priv->base_ck[MT2701_AUDSYS_AFE]);
++	if (ret)
++		return ret;
+ 
+-	/* Enable infra audio */
+-	ret = clk_prepare_enable(afe_priv->clocks[MT2701_AUD_INFRA_SYS_AUDIO]);
+-	if (ret) {
+-		dev_err(afe->dev, "%s clk_prepare_enable %s fail %d\n",
+-			__func__, aud_clks[MT2701_AUD_INFRA_SYS_AUDIO], ret);
+-		goto A2SYS_CLK_INFRA_ERR;
+-	}
++	ret = clk_prepare_enable(afe_priv->base_ck[MT2701_AUDSYS_A1SYS]);
++	if (ret)
++		goto err_audio_a1sys;
++
++	ret = clk_prepare_enable(afe_priv->base_ck[MT2701_AUDSYS_A2SYS]);
++	if (ret)
++		goto err_audio_a2sys;
++
++	ret = clk_prepare_enable(afe_priv->base_ck[MT2701_AUDSYS_AFE_CONN]);
++	if (ret)
++		goto err_afe_conn;
+ 
+ 	return 0;
+ 
+-A2SYS_CLK_INFRA_ERR:
+-	clk_disable_unprepare(afe_priv->clocks[MT2701_AUD_INFRA_SYS_AUDIO]);
+-A2SYS_CLK_AUD_44K_ERR:
+-	clk_disable_unprepare(afe_priv->clocks[MT2701_AUD_AUD_44K_TIMING]);
+-A2SYS_CLK_AUD_MUX2_DIV_ERR:
+-	clk_disable_unprepare(afe_priv->clocks[MT2701_AUD_AUD_MUX2_DIV]);
+-A2SYS_CLK_AUD_MUX2_SEL_ERR:
+-	clk_disable_unprepare(afe_priv->clocks[MT2701_AUD_AUD_MUX2_SEL]);
++err_afe_conn:
++	clk_disable_unprepare(afe_priv->base_ck[MT2701_AUDSYS_A2SYS]);
++err_audio_a2sys:
++	clk_disable_unprepare(afe_priv->base_ck[MT2701_AUDSYS_A1SYS]);
++err_audio_a1sys:
++	clk_disable_unprepare(afe_priv->base_ck[MT2701_AUDSYS_AFE]);
+ 
+ 	return ret;
+ }
+ 
+-void mt2701_turn_off_a2sys_clock(struct mtk_base_afe *afe)
++static void mt2701_afe_disable_audsys(struct mtk_base_afe *afe)
+ {
+ 	struct mt2701_afe_private *afe_priv = afe->platform_priv;
+ 
+-	clk_disable_unprepare(afe_priv->clocks[MT2701_AUD_INFRA_SYS_AUDIO]);
+-	clk_disable_unprepare(afe_priv->clocks[MT2701_AUD_AUD_44K_TIMING]);
+-	clk_disable_unprepare(afe_priv->clocks[MT2701_AUD_AUD_MUX2_DIV]);
+-	clk_disable_unprepare(afe_priv->clocks[MT2701_AUD_AUD_MUX2_SEL]);
++	clk_disable_unprepare(afe_priv->base_ck[MT2701_AUDSYS_AFE_CONN]);
++	clk_disable_unprepare(afe_priv->base_ck[MT2701_AUDSYS_A2SYS]);
++	clk_disable_unprepare(afe_priv->base_ck[MT2701_AUDSYS_A1SYS]);
++	clk_disable_unprepare(afe_priv->base_ck[MT2701_AUDSYS_AFE]);
+ }
+ 
+-int mt2701_turn_on_afe_clock(struct mtk_base_afe *afe)
++int mt2701_afe_enable_clock(struct mtk_base_afe *afe)
+ {
+-	struct mt2701_afe_private *afe_priv = afe->platform_priv;
+ 	int ret;
+ 
+-	/* enable INFRA_SYS */
+-	ret = clk_prepare_enable(afe_priv->clocks[MT2701_AUD_INFRA_SYS_AUDIO]);
+-	if (ret) {
+-		dev_err(afe->dev, "%s clk_prepare_enable %s fail %d\n",
+-			__func__, aud_clks[MT2701_AUD_INFRA_SYS_AUDIO], ret);
+-		goto AFE_AUD_INFRA_ERR;
+-	}
+-
+-	/* Set MT2701_AUD_AUDINTBUS to MT2701_AUD_SYSPLL1_D4 */
+-	ret = clk_prepare_enable(afe_priv->clocks[MT2701_AUD_AUDINTBUS]);
+-	if (ret) {
+-		dev_err(afe->dev, "%s clk_prepare_enable %s fail %d\n",
+-			__func__, aud_clks[MT2701_AUD_AUDINTBUS], ret);
+-		goto AFE_AUD_AUDINTBUS_ERR;
+-	}
+-
+-	ret = clk_set_parent(afe_priv->clocks[MT2701_AUD_AUDINTBUS],
+-			     afe_priv->clocks[MT2701_AUD_SYSPLL1_D4]);
+-	if (ret) {
+-		dev_err(afe->dev, "%s clk_set_parent %s-%s fail %d\n", __func__,
+-			aud_clks[MT2701_AUD_AUDINTBUS],
+-			aud_clks[MT2701_AUD_SYSPLL1_D4], ret);
+-		goto AFE_AUD_AUDINTBUS_ERR;
+-	}
+-
+-	/* Set MT2701_AUD_ASM_H_SEL to MT2701_AUD_UNIVPLL2_D2 */
+-	ret = clk_prepare_enable(afe_priv->clocks[MT2701_AUD_ASM_H_SEL]);
+-	if (ret) {
+-		dev_err(afe->dev, "%s clk_prepare_enable %s fail %d\n",
+-			__func__, aud_clks[MT2701_AUD_ASM_H_SEL], ret);
+-		goto AFE_AUD_ASM_H_ERR;
+-	}
+-
+-	ret = clk_set_parent(afe_priv->clocks[MT2701_AUD_ASM_H_SEL],
+-			     afe_priv->clocks[MT2701_AUD_UNIVPLL2_D2]);
+-	if (ret) {
+-		dev_err(afe->dev, "%s clk_set_parent %s-%s fail %d\n", __func__,
+-			aud_clks[MT2701_AUD_ASM_H_SEL],
+-			aud_clks[MT2701_AUD_UNIVPLL2_D2], ret);
+-		goto AFE_AUD_ASM_H_ERR;
+-	}
+-
+-	/* Set MT2701_AUD_ASM_M_SEL to MT2701_AUD_UNIVPLL2_D4 */
+-	ret = clk_prepare_enable(afe_priv->clocks[MT2701_AUD_ASM_M_SEL]);
++	/* Enable audio system */
++	ret = mt2701_afe_enable_audsys(afe);
+ 	if (ret) {
+-		dev_err(afe->dev, "%s clk_prepare_enable %s fail %d\n",
+-			__func__, aud_clks[MT2701_AUD_ASM_M_SEL], ret);
+-		goto AFE_AUD_ASM_M_ERR;
++		dev_err(afe->dev, "failed to enable audio system %d\n", ret);
++		return ret;
+ 	}
+ 
+-	ret = clk_set_parent(afe_priv->clocks[MT2701_AUD_ASM_M_SEL],
+-			     afe_priv->clocks[MT2701_AUD_UNIVPLL2_D4]);
+-	if (ret) {
+-		dev_err(afe->dev, "%s clk_set_parent %s-%s fail %d\n", __func__,
+-			aud_clks[MT2701_AUD_ASM_M_SEL],
+-			aud_clks[MT2701_AUD_UNIVPLL2_D4], ret);
+-		goto AFE_AUD_ASM_M_ERR;
+-	}
++	regmap_update_bits(afe->regmap, ASYS_TOP_CON,
++			   AUDIO_TOP_CON0_A1SYS_A2SYS_ON,
++			   AUDIO_TOP_CON0_A1SYS_A2SYS_ON);
++	regmap_update_bits(afe->regmap, AFE_DAC_CON0,
++			   AFE_DAC_CON0_AFE_ON,
++			   AFE_DAC_CON0_AFE_ON);
+ 
+-	regmap_update_bits(afe->regmap, AUDIO_TOP_CON0,
+-			   AUDIO_TOP_CON0_PDN_AFE, 0);
+-	regmap_update_bits(afe->regmap, AUDIO_TOP_CON0,
+-			   AUDIO_TOP_CON0_PDN_APLL_CK, 0);
+-	regmap_update_bits(afe->regmap, AUDIO_TOP_CON4,
+-			   AUDIO_TOP_CON4_PDN_A1SYS, 0);
+-	regmap_update_bits(afe->regmap, AUDIO_TOP_CON4,
+-			   AUDIO_TOP_CON4_PDN_A2SYS, 0);
+-	regmap_update_bits(afe->regmap, AUDIO_TOP_CON4,
+-			   AUDIO_TOP_CON4_PDN_AFE_CONN, 0);
++	/* Configure ASRC */
++	regmap_write(afe->regmap, PWR1_ASM_CON1, PWR1_ASM_CON1_INIT_VAL);
++	regmap_write(afe->regmap, PWR2_ASM_CON1, PWR2_ASM_CON1_INIT_VAL);
+ 
+ 	return 0;
+-
+-AFE_AUD_ASM_M_ERR:
+-	clk_disable_unprepare(afe_priv->clocks[MT2701_AUD_ASM_M_SEL]);
+-AFE_AUD_ASM_H_ERR:
+-	clk_disable_unprepare(afe_priv->clocks[MT2701_AUD_ASM_H_SEL]);
+-AFE_AUD_AUDINTBUS_ERR:
+-	clk_disable_unprepare(afe_priv->clocks[MT2701_AUD_AUDINTBUS]);
+-AFE_AUD_INFRA_ERR:
+-	clk_disable_unprepare(afe_priv->clocks[MT2701_AUD_INFRA_SYS_AUDIO]);
+-
+-	return ret;
+ }
+ 
+-void mt2701_turn_off_afe_clock(struct mtk_base_afe *afe)
++int mt2701_afe_disable_clock(struct mtk_base_afe *afe)
+ {
+-	struct mt2701_afe_private *afe_priv = afe->platform_priv;
++	regmap_update_bits(afe->regmap, ASYS_TOP_CON,
++			   AUDIO_TOP_CON0_A1SYS_A2SYS_ON, 0);
++	regmap_update_bits(afe->regmap, AFE_DAC_CON0,
++			   AFE_DAC_CON0_AFE_ON, 0);
+ 
+-	clk_disable_unprepare(afe_priv->clocks[MT2701_AUD_INFRA_SYS_AUDIO]);
+-
+-	clk_disable_unprepare(afe_priv->clocks[MT2701_AUD_AUDINTBUS]);
+-	clk_disable_unprepare(afe_priv->clocks[MT2701_AUD_ASM_H_SEL]);
+-	clk_disable_unprepare(afe_priv->clocks[MT2701_AUD_ASM_M_SEL]);
+-
+-	regmap_update_bits(afe->regmap, AUDIO_TOP_CON0,
+-			   AUDIO_TOP_CON0_PDN_AFE, AUDIO_TOP_CON0_PDN_AFE);
+-	regmap_update_bits(afe->regmap, AUDIO_TOP_CON0,
+-			   AUDIO_TOP_CON0_PDN_APLL_CK,
+-			   AUDIO_TOP_CON0_PDN_APLL_CK);
+-	regmap_update_bits(afe->regmap, AUDIO_TOP_CON4,
+-			   AUDIO_TOP_CON4_PDN_A1SYS,
+-			   AUDIO_TOP_CON4_PDN_A1SYS);
+-	regmap_update_bits(afe->regmap, AUDIO_TOP_CON4,
+-			   AUDIO_TOP_CON4_PDN_A2SYS,
+-			   AUDIO_TOP_CON4_PDN_A2SYS);
+-	regmap_update_bits(afe->regmap, AUDIO_TOP_CON4,
+-			   AUDIO_TOP_CON4_PDN_AFE_CONN,
+-			   AUDIO_TOP_CON4_PDN_AFE_CONN);
++	mt2701_afe_disable_audsys(afe);
++
++	return 0;
+ }
+ 
+ void mt2701_mclk_configuration(struct mtk_base_afe *afe, int id, int domain,
+ 			       int mclk)
+ {
+-	struct mt2701_afe_private *afe_priv = afe->platform_priv;
++	struct mt2701_afe_private *priv = afe->platform_priv;
++	struct mt2701_i2s_path *i2s_path = &priv->i2s_path[id];
+ 	int ret;
+-	int aud_src_div_id = MT2701_AUD_AUD_K1_SRC_DIV + id;
+-	int aud_src_clk_id = MT2701_AUD_AUD_K1_SRC_SEL + id;
+ 
+-	/* Set MCLK Kx_SRC_SEL(domain) */
+-	ret = clk_prepare_enable(afe_priv->clocks[aud_src_clk_id]);
+-	if (ret)
+-		dev_err(afe->dev, "%s clk_prepare_enable %s fail %d\n",
+-			__func__, aud_clks[aud_src_clk_id], ret);
+-
+-	if (domain == 0) {
+-		ret = clk_set_parent(afe_priv->clocks[aud_src_clk_id],
+-				     afe_priv->clocks[MT2701_AUD_AUD_MUX1_SEL]);
+-		if (ret)
+-			dev_err(afe->dev, "%s clk_set_parent %s-%s fail %d\n",
+-				__func__, aud_clks[aud_src_clk_id],
+-				aud_clks[MT2701_AUD_AUD_MUX1_SEL], ret);
+-	} else {
+-		ret = clk_set_parent(afe_priv->clocks[aud_src_clk_id],
+-				     afe_priv->clocks[MT2701_AUD_AUD_MUX2_SEL]);
+-		if (ret)
+-			dev_err(afe->dev, "%s clk_set_parent %s-%s fail %d\n",
+-				__func__, aud_clks[aud_src_clk_id],
+-				aud_clks[MT2701_AUD_AUD_MUX2_SEL], ret);
+-	}
+-	clk_disable_unprepare(afe_priv->clocks[aud_src_clk_id]);
++	/* Set mclk source */
++	if (domain == 0)
++		ret = clk_set_parent(i2s_path->sel_ck,
++				     priv->base_ck[MT2701_TOP_AUD_MCLK_SRC0]);
++	else
++		ret = clk_set_parent(i2s_path->sel_ck,
++				     priv->base_ck[MT2701_TOP_AUD_MCLK_SRC1]);
+ 
+-	/* Set MCLK Kx_SRC_DIV(divider) */
+-	ret = clk_prepare_enable(afe_priv->clocks[aud_src_div_id]);
+ 	if (ret)
+-		dev_err(afe->dev, "%s clk_prepare_enable %s fail %d\n",
+-			__func__, aud_clks[aud_src_div_id], ret);
++		dev_err(afe->dev, "failed to set domain%d mclk source %d\n",
++			domain, ret);
+ 
+-	ret = clk_set_rate(afe_priv->clocks[aud_src_div_id], mclk);
++	/* Set mclk divider */
++	ret = clk_set_rate(i2s_path->div_ck, mclk);
+ 	if (ret)
+-		dev_err(afe->dev, "%s clk_set_rate %s-%d fail %d\n", __func__,
+-			aud_clks[aud_src_div_id], mclk, ret);
+-	clk_disable_unprepare(afe_priv->clocks[aud_src_div_id]);
++		dev_err(afe->dev, "failed to set mclk divider %d\n", ret);
+ }
+ 
+ MODULE_DESCRIPTION("MT2701 afe clock control");
+diff --git a/sound/soc/mediatek/mt2701/mt2701-afe-clock-ctrl.h b/sound/soc/mediatek/mt2701/mt2701-afe-clock-ctrl.h
+index 6497d570cf09..15417d9d6597 100644
+--- a/sound/soc/mediatek/mt2701/mt2701-afe-clock-ctrl.h
++++ b/sound/soc/mediatek/mt2701/mt2701-afe-clock-ctrl.h
+@@ -21,16 +21,15 @@ struct mtk_base_afe;
+ 
+ int mt2701_init_clock(struct mtk_base_afe *afe);
+ int mt2701_afe_enable_clock(struct mtk_base_afe *afe);
+-void mt2701_afe_disable_clock(struct mtk_base_afe *afe);
++int mt2701_afe_disable_clock(struct mtk_base_afe *afe);
+ 
+-int mt2701_turn_on_a1sys_clock(struct mtk_base_afe *afe);
+-void mt2701_turn_off_a1sys_clock(struct mtk_base_afe *afe);
++int mt2701_afe_enable_i2s(struct mtk_base_afe *afe, int id, int dir);
++void mt2701_afe_disable_i2s(struct mtk_base_afe *afe, int id, int dir);
++int mt2701_afe_enable_mclk(struct mtk_base_afe *afe, int id);
++void mt2701_afe_disable_mclk(struct mtk_base_afe *afe, int id);
+ 
+-int mt2701_turn_on_a2sys_clock(struct mtk_base_afe *afe);
+-void mt2701_turn_off_a2sys_clock(struct mtk_base_afe *afe);
+-
+-int mt2701_turn_on_afe_clock(struct mtk_base_afe *afe);
+-void mt2701_turn_off_afe_clock(struct mtk_base_afe *afe);
++int mt2701_enable_btmrg_clk(struct mtk_base_afe *afe);
++void mt2701_disable_btmrg_clk(struct mtk_base_afe *afe);
+ 
+ void mt2701_mclk_configuration(struct mtk_base_afe *afe, int id, int domain,
+ 			       int mclk);
+diff --git a/sound/soc/mediatek/mt2701/mt2701-afe-common.h b/sound/soc/mediatek/mt2701/mt2701-afe-common.h
+index c19430e98adf..ce5bd4dc864d 100644
+--- a/sound/soc/mediatek/mt2701/mt2701-afe-common.h
++++ b/sound/soc/mediatek/mt2701/mt2701-afe-common.h
+@@ -69,53 +69,14 @@ enum {
+ 	MT2701_IRQ_ASYS_END,
+ };
+ 
+-/* 2701 clock def */
+-enum audio_system_clock_type {
+-	MT2701_AUD_INFRA_SYS_AUDIO,
+-	MT2701_AUD_AUD_MUX1_SEL,
+-	MT2701_AUD_AUD_MUX2_SEL,
+-	MT2701_AUD_AUD_MUX1_DIV,
+-	MT2701_AUD_AUD_MUX2_DIV,
+-	MT2701_AUD_AUD_48K_TIMING,
+-	MT2701_AUD_AUD_44K_TIMING,
+-	MT2701_AUD_AUDPLL_MUX_SEL,
+-	MT2701_AUD_APLL_SEL,
+-	MT2701_AUD_AUD1PLL_98M,
+-	MT2701_AUD_AUD2PLL_90M,
+-	MT2701_AUD_HADDS2PLL_98M,
+-	MT2701_AUD_HADDS2PLL_294M,
+-	MT2701_AUD_AUDPLL,
+-	MT2701_AUD_AUDPLL_D4,
+-	MT2701_AUD_AUDPLL_D8,
+-	MT2701_AUD_AUDPLL_D16,
+-	MT2701_AUD_AUDPLL_D24,
+-	MT2701_AUD_AUDINTBUS,
+-	MT2701_AUD_CLK_26M,
+-	MT2701_AUD_SYSPLL1_D4,
+-	MT2701_AUD_AUD_K1_SRC_SEL,
+-	MT2701_AUD_AUD_K2_SRC_SEL,
+-	MT2701_AUD_AUD_K3_SRC_SEL,
+-	MT2701_AUD_AUD_K4_SRC_SEL,
+-	MT2701_AUD_AUD_K5_SRC_SEL,
+-	MT2701_AUD_AUD_K6_SRC_SEL,
+-	MT2701_AUD_AUD_K1_SRC_DIV,
+-	MT2701_AUD_AUD_K2_SRC_DIV,
+-	MT2701_AUD_AUD_K3_SRC_DIV,
+-	MT2701_AUD_AUD_K4_SRC_DIV,
+-	MT2701_AUD_AUD_K5_SRC_DIV,
+-	MT2701_AUD_AUD_K6_SRC_DIV,
+-	MT2701_AUD_AUD_I2S1_MCLK,
+-	MT2701_AUD_AUD_I2S2_MCLK,
+-	MT2701_AUD_AUD_I2S3_MCLK,
+-	MT2701_AUD_AUD_I2S4_MCLK,
+-	MT2701_AUD_AUD_I2S5_MCLK,
+-	MT2701_AUD_AUD_I2S6_MCLK,
+-	MT2701_AUD_ASM_M_SEL,
+-	MT2701_AUD_ASM_H_SEL,
+-	MT2701_AUD_UNIVPLL2_D4,
+-	MT2701_AUD_UNIVPLL2_D2,
+-	MT2701_AUD_SYSPLL_D5,
+-	MT2701_CLOCK_NUM
++enum audio_base_clock {
++	MT2701_TOP_AUD_MCLK_SRC0,
++	MT2701_TOP_AUD_MCLK_SRC1,
++	MT2701_AUDSYS_AFE,
++	MT2701_AUDSYS_AFE_CONN,
++	MT2701_AUDSYS_A1SYS,
++	MT2701_AUDSYS_A2SYS,
++	MT2701_BASE_CLK_NUM,
+ };
+ 
+ static const unsigned int mt2701_afe_backup_list[] = {
+@@ -144,7 +105,6 @@ struct mtk_base_irq_data;
+ 
+ struct mt2701_i2s_data {
+ 	int i2s_ctrl_reg;
+-	int i2s_pwn_shift;
+ 	int i2s_asrc_fs_shift;
+ 	int i2s_asrc_fs_mask;
+ };
+@@ -161,11 +121,17 @@ struct mt2701_i2s_path {
+ 	int on[I2S_DIR_NUM];
+ 	int occupied[I2S_DIR_NUM];
+ 	const struct mt2701_i2s_data *i2s_data[2];
++	struct clk *hop_ck[I2S_DIR_NUM];
++	struct clk *sel_ck;
++	struct clk *div_ck;
++	struct clk *mclk_ck;
++	struct clk *asrco_ck;
+ };
+ 
+ struct mt2701_afe_private {
+-	struct clk *clocks[MT2701_CLOCK_NUM];
+ 	struct mt2701_i2s_path i2s_path[MT2701_I2S_NUM];
++	struct clk *base_ck[MT2701_BASE_CLK_NUM];
++	struct clk *mrgif_ck;
+ 	bool mrg_enable[MT2701_STREAM_DIR_NUM];
+ };
+ 
+diff --git a/sound/soc/mediatek/mt2701/mt2701-afe-pcm.c b/sound/soc/mediatek/mt2701/mt2701-afe-pcm.c
+index a7362d1cda1b..33f809228f25 100644
+--- a/sound/soc/mediatek/mt2701/mt2701-afe-pcm.c
++++ b/sound/soc/mediatek/mt2701/mt2701-afe-pcm.c
+@@ -97,21 +97,12 @@ static int mt2701_afe_i2s_startup(struct snd_pcm_substream *substream,
+ {
+ 	struct snd_soc_pcm_runtime *rtd = substream->private_data;
+ 	struct mtk_base_afe *afe = snd_soc_platform_get_drvdata(rtd->platform);
+-	struct mt2701_afe_private *afe_priv = afe->platform_priv;
+ 	int i2s_num = mt2701_dai_num_to_i2s(afe, dai->id);
+-	int clk_num = MT2701_AUD_AUD_I2S1_MCLK + i2s_num;
+-	int ret = 0;
+ 
+ 	if (i2s_num < 0)
+ 		return i2s_num;
+ 
+-	/* enable mclk */
+-	ret = clk_prepare_enable(afe_priv->clocks[clk_num]);
+-	if (ret)
+-		dev_err(afe->dev, "Failed to enable mclk for I2S: %d\n",
+-			i2s_num);
+-
+-	return ret;
++	return mt2701_afe_enable_mclk(afe, i2s_num);
+ }
+ 
+ static int mt2701_afe_i2s_path_shutdown(struct snd_pcm_substream *substream,
+@@ -151,9 +142,9 @@ static int mt2701_afe_i2s_path_shutdown(struct snd_pcm_substream *substream,
+ 	/* disable i2s */
+ 	regmap_update_bits(afe->regmap, i2s_data->i2s_ctrl_reg,
+ 			   ASYS_I2S_CON_I2S_EN, 0);
+-	regmap_update_bits(afe->regmap, AUDIO_TOP_CON4,
+-			   1 << i2s_data->i2s_pwn_shift,
+-			   1 << i2s_data->i2s_pwn_shift);
++
++	mt2701_afe_disable_i2s(afe, i2s_num, stream_dir);
++
+ 	return 0;
+ }
+ 
+@@ -165,7 +156,6 @@ static void mt2701_afe_i2s_shutdown(struct snd_pcm_substream *substream,
+ 	struct mt2701_afe_private *afe_priv = afe->platform_priv;
+ 	int i2s_num = mt2701_dai_num_to_i2s(afe, dai->id);
+ 	struct mt2701_i2s_path *i2s_path;
+-	int clk_num = MT2701_AUD_AUD_I2S1_MCLK + i2s_num;
+ 
+ 	if (i2s_num < 0)
+ 		return;
+@@ -185,7 +175,7 @@ static void mt2701_afe_i2s_shutdown(struct snd_pcm_substream *substream,
+ 
+ I2S_UNSTART:
+ 	/* disable mclk */
+-	clk_disable_unprepare(afe_priv->clocks[clk_num]);
++	mt2701_afe_disable_mclk(afe, i2s_num);
+ }
+ 
+ static int mt2701_i2s_path_prepare_enable(struct snd_pcm_substream *substream,
+@@ -251,9 +241,7 @@ static int mt2701_i2s_path_prepare_enable(struct snd_pcm_substream *substream,
+ 			   fs << i2s_data->i2s_asrc_fs_shift);
+ 
+ 	/* enable i2s */
+-	regmap_update_bits(afe->regmap, AUDIO_TOP_CON4,
+-			   1 << i2s_data->i2s_pwn_shift,
+-			   0 << i2s_data->i2s_pwn_shift);
++	mt2701_afe_enable_i2s(afe, i2s_num, stream_dir);
+ 
+ 	/* reset i2s hw status before enable */
+ 	regmap_update_bits(afe->regmap, i2s_data->i2s_ctrl_reg,
+@@ -339,9 +327,11 @@ static int mt2701_btmrg_startup(struct snd_pcm_substream *substream,
+ 	struct snd_soc_pcm_runtime *rtd = substream->private_data;
+ 	struct mtk_base_afe *afe = snd_soc_platform_get_drvdata(rtd->platform);
+ 	struct mt2701_afe_private *afe_priv = afe->platform_priv;
++	int ret;
+ 
+-	regmap_update_bits(afe->regmap, AUDIO_TOP_CON4,
+-			   AUDIO_TOP_CON4_PDN_MRGIF, 0);
++	ret = mt2701_enable_btmrg_clk(afe);
++	if (ret)
++		return ret;
+ 
+ 	afe_priv->mrg_enable[substream->stream] = 1;
+ 	return 0;
+@@ -406,9 +396,7 @@ static void mt2701_btmrg_shutdown(struct snd_pcm_substream *substream,
+ 				   AFE_MRGIF_CON_MRG_EN, 0);
+ 		regmap_update_bits(afe->regmap, AFE_MRGIF_CON,
+ 				   AFE_MRGIF_CON_MRG_I2S_EN, 0);
+-		regmap_update_bits(afe->regmap, AUDIO_TOP_CON4,
+-				   AUDIO_TOP_CON4_PDN_MRGIF,
+-				   AUDIO_TOP_CON4_PDN_MRGIF);
++		mt2701_disable_btmrg_clk(afe);
+ 	}
+ 	afe_priv->mrg_enable[substream->stream] = 0;
+ }
+@@ -1386,14 +1374,12 @@ static const struct mt2701_i2s_data mt2701_i2s_data[MT2701_I2S_NUM][2] = {
+ 	{
+ 		{
+ 			.i2s_ctrl_reg = ASYS_I2SO1_CON,
+-			.i2s_pwn_shift = 6,
+ 			.i2s_asrc_fs_shift = 0,
+ 			.i2s_asrc_fs_mask = 0x1f,
+ 
+ 		},
+ 		{
+ 			.i2s_ctrl_reg = ASYS_I2SIN1_CON,
+-			.i2s_pwn_shift = 0,
+ 			.i2s_asrc_fs_shift = 0,
+ 			.i2s_asrc_fs_mask = 0x1f,
+ 
+@@ -1402,14 +1388,12 @@ static const struct mt2701_i2s_data mt2701_i2s_data[MT2701_I2S_NUM][2] = {
+ 	{
+ 		{
+ 			.i2s_ctrl_reg = ASYS_I2SO2_CON,
+-			.i2s_pwn_shift = 7,
+ 			.i2s_asrc_fs_shift = 5,
+ 			.i2s_asrc_fs_mask = 0x1f,
+ 
+ 		},
+ 		{
+ 			.i2s_ctrl_reg = ASYS_I2SIN2_CON,
+-			.i2s_pwn_shift = 1,
+ 			.i2s_asrc_fs_shift = 5,
+ 			.i2s_asrc_fs_mask = 0x1f,
+ 
+@@ -1418,14 +1402,12 @@ static const struct mt2701_i2s_data mt2701_i2s_data[MT2701_I2S_NUM][2] = {
+ 	{
+ 		{
+ 			.i2s_ctrl_reg = ASYS_I2SO3_CON,
+-			.i2s_pwn_shift = 8,
+ 			.i2s_asrc_fs_shift = 10,
+ 			.i2s_asrc_fs_mask = 0x1f,
+ 
+ 		},
+ 		{
+ 			.i2s_ctrl_reg = ASYS_I2SIN3_CON,
+-			.i2s_pwn_shift = 2,
+ 			.i2s_asrc_fs_shift = 10,
+ 			.i2s_asrc_fs_mask = 0x1f,
+ 
+@@ -1434,14 +1416,12 @@ static const struct mt2701_i2s_data mt2701_i2s_data[MT2701_I2S_NUM][2] = {
+ 	{
+ 		{
+ 			.i2s_ctrl_reg = ASYS_I2SO4_CON,
+-			.i2s_pwn_shift = 9,
+ 			.i2s_asrc_fs_shift = 15,
+ 			.i2s_asrc_fs_mask = 0x1f,
+ 
+ 		},
+ 		{
+ 			.i2s_ctrl_reg = ASYS_I2SIN4_CON,
+-			.i2s_pwn_shift = 3,
+ 			.i2s_asrc_fs_shift = 15,
+ 			.i2s_asrc_fs_mask = 0x1f,
+ 
+@@ -1483,8 +1463,7 @@ static int mt2701_afe_runtime_suspend(struct device *dev)
+ {
+ 	struct mtk_base_afe *afe = dev_get_drvdata(dev);
+ 
+-	mt2701_afe_disable_clock(afe);
+-	return 0;
++	return mt2701_afe_disable_clock(afe);
+ }
+ 
+ static int mt2701_afe_runtime_resume(struct device *dev)
+-- 
+2.11.0
+
diff --git a/target/linux/mediatek/patches-4.14/0182-ASoC-mediatek-cleanup-audio-driver-for-MT2701.patch b/target/linux/mediatek/patches-4.14/0182-ASoC-mediatek-cleanup-audio-driver-for-MT2701.patch
new file mode 100644
index 0000000000..ee439ff531
--- /dev/null
+++ b/target/linux/mediatek/patches-4.14/0182-ASoC-mediatek-cleanup-audio-driver-for-MT2701.patch
@@ -0,0 +1,439 @@
+From 4087c924ec899881951b2170a7bb8888747ec532 Mon Sep 17 00:00:00 2001
+From: Ryder Lee <ryder.lee@mediatek.com>
+Date: Tue, 2 Jan 2018 19:47:20 +0800
+Subject: [PATCH 182/224] ASoC: mediatek: cleanup audio driver for MT2701
+
+Cleanup unused code such as 'i2s_num' guard, headers, indentation
+and some defines.
+
+Signed-off-by: Ryder Lee <ryder.lee@mediatek.com>
+Signed-off-by: Mark Brown <broonie@kernel.org>
+---
+ sound/soc/mediatek/mt2701/mt2701-afe-clock-ctrl.c | 14 +---
+ sound/soc/mediatek/mt2701/mt2701-afe-common.h     | 20 +----
+ sound/soc/mediatek/mt2701/mt2701-afe-pcm.c        | 94 ++++-------------------
+ sound/soc/mediatek/mt2701/mt2701-reg.h            | 41 +---------
+ 4 files changed, 24 insertions(+), 145 deletions(-)
+
+diff --git a/sound/soc/mediatek/mt2701/mt2701-afe-clock-ctrl.c b/sound/soc/mediatek/mt2701/mt2701-afe-clock-ctrl.c
+index 75ccdca5811d..56a057c78c9a 100644
+--- a/sound/soc/mediatek/mt2701/mt2701-afe-clock-ctrl.c
++++ b/sound/soc/mediatek/mt2701/mt2701-afe-clock-ctrl.c
+@@ -14,10 +14,6 @@
+  * GNU General Public License for more details.
+  */
+ 
+-#include <sound/soc.h>
+-#include <linux/regmap.h>
+-#include <linux/pm_runtime.h>
+-
+ #include "mt2701-afe-common.h"
+ #include "mt2701-afe-clock-ctrl.h"
+ 
+@@ -223,8 +219,8 @@ int mt2701_afe_enable_clock(struct mtk_base_afe *afe)
+ 	}
+ 
+ 	regmap_update_bits(afe->regmap, ASYS_TOP_CON,
+-			   AUDIO_TOP_CON0_A1SYS_A2SYS_ON,
+-			   AUDIO_TOP_CON0_A1SYS_A2SYS_ON);
++			   ASYS_TOP_CON_ASYS_TIMING_ON,
++			   ASYS_TOP_CON_ASYS_TIMING_ON);
+ 	regmap_update_bits(afe->regmap, AFE_DAC_CON0,
+ 			   AFE_DAC_CON0_AFE_ON,
+ 			   AFE_DAC_CON0_AFE_ON);
+@@ -239,7 +235,7 @@ int mt2701_afe_enable_clock(struct mtk_base_afe *afe)
+ int mt2701_afe_disable_clock(struct mtk_base_afe *afe)
+ {
+ 	regmap_update_bits(afe->regmap, ASYS_TOP_CON,
+-			   AUDIO_TOP_CON0_A1SYS_A2SYS_ON, 0);
++			   ASYS_TOP_CON_ASYS_TIMING_ON, 0);
+ 	regmap_update_bits(afe->regmap, AFE_DAC_CON0,
+ 			   AFE_DAC_CON0_AFE_ON, 0);
+ 
+@@ -272,7 +268,3 @@ void mt2701_mclk_configuration(struct mtk_base_afe *afe, int id, int domain,
+ 	if (ret)
+ 		dev_err(afe->dev, "failed to set mclk divider %d\n", ret);
+ }
+-
+-MODULE_DESCRIPTION("MT2701 afe clock control");
+-MODULE_AUTHOR("Garlic Tseng <garlic.tseng@mediatek.com>");
+-MODULE_LICENSE("GPL v2");
+diff --git a/sound/soc/mediatek/mt2701/mt2701-afe-common.h b/sound/soc/mediatek/mt2701/mt2701-afe-common.h
+index ce5bd4dc864d..9a2b301a4c21 100644
+--- a/sound/soc/mediatek/mt2701/mt2701-afe-common.h
++++ b/sound/soc/mediatek/mt2701/mt2701-afe-common.h
+@@ -16,6 +16,7 @@
+ 
+ #ifndef _MT_2701_AFE_COMMON_H_
+ #define _MT_2701_AFE_COMMON_H_
++
+ #include <sound/soc.h>
+ #include <linux/clk.h>
+ #include <linux/regmap.h>
+@@ -25,16 +26,7 @@
+ #define MT2701_STREAM_DIR_NUM (SNDRV_PCM_STREAM_LAST + 1)
+ #define MT2701_PLL_DOMAIN_0_RATE	98304000
+ #define MT2701_PLL_DOMAIN_1_RATE	90316800
+-#define MT2701_AUD_AUD_MUX1_DIV_RATE (MT2701_PLL_DOMAIN_0_RATE / 2)
+-#define MT2701_AUD_AUD_MUX2_DIV_RATE (MT2701_PLL_DOMAIN_1_RATE / 2)
+-
+-enum {
+-	MT2701_I2S_1,
+-	MT2701_I2S_2,
+-	MT2701_I2S_3,
+-	MT2701_I2S_4,
+-	MT2701_I2S_NUM,
+-};
++#define MT2701_I2S_NUM	4
+ 
+ enum {
+ 	MT2701_MEMIF_DL1,
+@@ -62,8 +54,7 @@ enum {
+ };
+ 
+ enum {
+-	MT2701_IRQ_ASYS_START,
+-	MT2701_IRQ_ASYS_IRQ1 = MT2701_IRQ_ASYS_START,
++	MT2701_IRQ_ASYS_IRQ1,
+ 	MT2701_IRQ_ASYS_IRQ2,
+ 	MT2701_IRQ_ASYS_IRQ3,
+ 	MT2701_IRQ_ASYS_END,
+@@ -100,9 +91,6 @@ static const unsigned int mt2701_afe_backup_list[] = {
+ 	AFE_MEMIF_PBUF_SIZE,
+ };
+ 
+-struct snd_pcm_substream;
+-struct mtk_base_irq_data;
+-
+ struct mt2701_i2s_data {
+ 	int i2s_ctrl_reg;
+ 	int i2s_asrc_fs_shift;
+@@ -120,7 +108,7 @@ struct mt2701_i2s_path {
+ 	int mclk_rate;
+ 	int on[I2S_DIR_NUM];
+ 	int occupied[I2S_DIR_NUM];
+-	const struct mt2701_i2s_data *i2s_data[2];
++	const struct mt2701_i2s_data *i2s_data[I2S_DIR_NUM];
+ 	struct clk *hop_ck[I2S_DIR_NUM];
+ 	struct clk *sel_ck;
+ 	struct clk *div_ck;
+diff --git a/sound/soc/mediatek/mt2701/mt2701-afe-pcm.c b/sound/soc/mediatek/mt2701/mt2701-afe-pcm.c
+index 33f809228f25..0edadca12a5e 100644
+--- a/sound/soc/mediatek/mt2701/mt2701-afe-pcm.c
++++ b/sound/soc/mediatek/mt2701/mt2701-afe-pcm.c
+@@ -20,16 +20,12 @@
+ #include <linux/of.h>
+ #include <linux/of_address.h>
+ #include <linux/pm_runtime.h>
+-#include <sound/soc.h>
+ 
+ #include "mt2701-afe-common.h"
+-
+ #include "mt2701-afe-clock-ctrl.h"
+ #include "../common/mtk-afe-platform-driver.h"
+ #include "../common/mtk-afe-fe-dai.h"
+ 
+-#define AFE_IRQ_STATUS_BITS	0xff
+-
+ static const struct snd_pcm_hardware mt2701_afe_hardware = {
+ 	.info = SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED
+ 		| SNDRV_PCM_INFO_RESUME | SNDRV_PCM_INFO_MMAP_VALID,
+@@ -107,21 +103,16 @@ static int mt2701_afe_i2s_startup(struct snd_pcm_substream *substream,
+ 
+ static int mt2701_afe_i2s_path_shutdown(struct snd_pcm_substream *substream,
+ 					struct snd_soc_dai *dai,
++					int i2s_num,
+ 					int dir_invert)
+ {
+ 	struct snd_soc_pcm_runtime *rtd = substream->private_data;
+ 	struct mtk_base_afe *afe = snd_soc_platform_get_drvdata(rtd->platform);
+ 	struct mt2701_afe_private *afe_priv = afe->platform_priv;
+-	int i2s_num = mt2701_dai_num_to_i2s(afe, dai->id);
+-	struct mt2701_i2s_path *i2s_path;
++	struct mt2701_i2s_path *i2s_path = &afe_priv->i2s_path[i2s_num];
+ 	const struct mt2701_i2s_data *i2s_data;
+ 	int stream_dir = substream->stream;
+ 
+-	if (i2s_num < 0)
+-		return i2s_num;
+-
+-	i2s_path = &afe_priv->i2s_path[i2s_num];
+-
+ 	if (dir_invert)	{
+ 		if (stream_dir == SNDRV_PCM_STREAM_PLAYBACK)
+ 			stream_dir = SNDRV_PCM_STREAM_CAPTURE;
+@@ -167,11 +158,11 @@ static void mt2701_afe_i2s_shutdown(struct snd_pcm_substream *substream,
+ 	else
+ 		goto I2S_UNSTART;
+ 
+-	mt2701_afe_i2s_path_shutdown(substream, dai, 0);
++	mt2701_afe_i2s_path_shutdown(substream, dai, i2s_num, 0);
+ 
+ 	/* need to disable i2s-out path when disable i2s-in */
+ 	if (substream->stream == SNDRV_PCM_STREAM_CAPTURE)
+-		mt2701_afe_i2s_path_shutdown(substream, dai, 1);
++		mt2701_afe_i2s_path_shutdown(substream, dai, i2s_num, 1);
+ 
+ I2S_UNSTART:
+ 	/* disable mclk */
+@@ -180,24 +171,19 @@ static void mt2701_afe_i2s_shutdown(struct snd_pcm_substream *substream,
+ 
+ static int mt2701_i2s_path_prepare_enable(struct snd_pcm_substream *substream,
+ 					  struct snd_soc_dai *dai,
++					  int i2s_num,
+ 					  int dir_invert)
+ {
+ 	struct snd_soc_pcm_runtime *rtd = substream->private_data;
+ 	struct mtk_base_afe *afe = snd_soc_platform_get_drvdata(rtd->platform);
+ 	struct mt2701_afe_private *afe_priv = afe->platform_priv;
+-	int i2s_num = mt2701_dai_num_to_i2s(afe, dai->id);
+-	struct mt2701_i2s_path *i2s_path;
++	struct mt2701_i2s_path *i2s_path = &afe_priv->i2s_path[i2s_num];
+ 	const struct mt2701_i2s_data *i2s_data;
+ 	struct snd_pcm_runtime * const runtime = substream->runtime;
+ 	int reg, fs, w_len = 1; /* now we support bck 64bits only */
+ 	int stream_dir = substream->stream;
+ 	unsigned int mask = 0, val = 0;
+ 
+-	if (i2s_num < 0)
+-		return i2s_num;
+-
+-	i2s_path = &afe_priv->i2s_path[i2s_num];
+-
+ 	if (dir_invert) {
+ 		if (stream_dir == SNDRV_PCM_STREAM_PLAYBACK)
+ 			stream_dir = SNDRV_PCM_STREAM_CAPTURE;
+@@ -288,13 +274,13 @@ static int mt2701_afe_i2s_prepare(struct snd_pcm_substream *substream,
+ 	mt2701_mclk_configuration(afe, i2s_num, clk_domain, mclk_rate);
+ 
+ 	if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
+-		mt2701_i2s_path_prepare_enable(substream, dai, 0);
++		mt2701_i2s_path_prepare_enable(substream, dai, i2s_num, 0);
+ 	} else {
+ 		/* need to enable i2s-out path when enable i2s-in */
+ 		/* prepare for another direction "out" */
+-		mt2701_i2s_path_prepare_enable(substream, dai, 1);
++		mt2701_i2s_path_prepare_enable(substream, dai, i2s_num, 1);
+ 		/* prepare for "in" */
+-		mt2701_i2s_path_prepare_enable(substream, dai, 0);
++		mt2701_i2s_path_prepare_enable(substream, dai, i2s_num, 0);
+ 	}
+ 
+ 	return 0;
+@@ -562,7 +548,6 @@ static const struct snd_soc_dai_ops mt2701_single_memif_dai_ops = {
+ 	.hw_free	= mtk_afe_fe_hw_free,
+ 	.prepare	= mtk_afe_fe_prepare,
+ 	.trigger	= mtk_afe_fe_trigger,
+-
+ };
+ 
+ static const struct snd_soc_dai_ops mt2701_dlm_memif_dai_ops = {
+@@ -903,31 +888,6 @@ static const struct snd_kcontrol_new mt2701_afe_multi_ch_out_i2s4[] = {
+ 				    PWR2_TOP_CON, 19, 1, 0),
+ };
+ 
+-static const struct snd_kcontrol_new mt2701_afe_multi_ch_out_asrc0[] = {
+-	SOC_DAPM_SINGLE_AUTODISABLE("Asrc0 out Switch", AUDIO_TOP_CON4, 14, 1,
+-				    1),
+-};
+-
+-static const struct snd_kcontrol_new mt2701_afe_multi_ch_out_asrc1[] = {
+-	SOC_DAPM_SINGLE_AUTODISABLE("Asrc1 out Switch", AUDIO_TOP_CON4, 15, 1,
+-				    1),
+-};
+-
+-static const struct snd_kcontrol_new mt2701_afe_multi_ch_out_asrc2[] = {
+-	SOC_DAPM_SINGLE_AUTODISABLE("Asrc2 out Switch", PWR2_TOP_CON, 6, 1,
+-				    1),
+-};
+-
+-static const struct snd_kcontrol_new mt2701_afe_multi_ch_out_asrc3[] = {
+-	SOC_DAPM_SINGLE_AUTODISABLE("Asrc3 out Switch", PWR2_TOP_CON, 7, 1,
+-				    1),
+-};
+-
+-static const struct snd_kcontrol_new mt2701_afe_multi_ch_out_asrc4[] = {
+-	SOC_DAPM_SINGLE_AUTODISABLE("Asrc4 out Switch", PWR2_TOP_CON, 8, 1,
+-				    1),
+-};
+-
+ static const struct snd_soc_dapm_widget mt2701_afe_pcm_widgets[] = {
+ 	/* inter-connections */
+ 	SND_SOC_DAPM_MIXER("I00", SND_SOC_NOPM, 0, 0, NULL, 0),
+@@ -987,19 +947,6 @@ static const struct snd_soc_dapm_widget mt2701_afe_pcm_widgets[] = {
+ 	SND_SOC_DAPM_MIXER("I18I19", SND_SOC_NOPM, 0, 0,
+ 			   mt2701_afe_multi_ch_out_i2s3,
+ 			   ARRAY_SIZE(mt2701_afe_multi_ch_out_i2s3)),
+-
+-	SND_SOC_DAPM_MIXER("ASRC_O0", SND_SOC_NOPM, 0, 0,
+-			   mt2701_afe_multi_ch_out_asrc0,
+-			   ARRAY_SIZE(mt2701_afe_multi_ch_out_asrc0)),
+-	SND_SOC_DAPM_MIXER("ASRC_O1", SND_SOC_NOPM, 0, 0,
+-			   mt2701_afe_multi_ch_out_asrc1,
+-			   ARRAY_SIZE(mt2701_afe_multi_ch_out_asrc1)),
+-	SND_SOC_DAPM_MIXER("ASRC_O2", SND_SOC_NOPM, 0, 0,
+-			   mt2701_afe_multi_ch_out_asrc2,
+-			   ARRAY_SIZE(mt2701_afe_multi_ch_out_asrc2)),
+-	SND_SOC_DAPM_MIXER("ASRC_O3", SND_SOC_NOPM, 0, 0,
+-			   mt2701_afe_multi_ch_out_asrc3,
+-			   ARRAY_SIZE(mt2701_afe_multi_ch_out_asrc3)),
+ };
+ 
+ static const struct snd_soc_dapm_route mt2701_afe_pcm_routes[] = {
+@@ -1009,7 +956,6 @@ static const struct snd_soc_dapm_route mt2701_afe_pcm_routes[] = {
+ 
+ 	{"I2S0 Playback", NULL, "O15"},
+ 	{"I2S0 Playback", NULL, "O16"},
+-
+ 	{"I2S1 Playback", NULL, "O17"},
+ 	{"I2S1 Playback", NULL, "O18"},
+ 	{"I2S2 Playback", NULL, "O19"},
+@@ -1026,7 +972,6 @@ static const struct snd_soc_dapm_route mt2701_afe_pcm_routes[] = {
+ 
+ 	{"I00", NULL, "I2S0 Capture"},
+ 	{"I01", NULL, "I2S0 Capture"},
+-
+ 	{"I02", NULL, "I2S1 Capture"},
+ 	{"I03", NULL, "I2S1 Capture"},
+ 	/* I02,03 link to UL2, also need to open I2S0 */
+@@ -1034,15 +979,10 @@ static const struct snd_soc_dapm_route mt2701_afe_pcm_routes[] = {
+ 
+ 	{"I26", NULL, "BT Capture"},
+ 
+-	{"ASRC_O0", "Asrc0 out Switch", "DLM"},
+-	{"ASRC_O1", "Asrc1 out Switch", "DLM"},
+-	{"ASRC_O2", "Asrc2 out Switch", "DLM"},
+-	{"ASRC_O3", "Asrc3 out Switch", "DLM"},
+-
+-	{"I12I13", "Multich I2S0 Out Switch", "ASRC_O0"},
+-	{"I14I15", "Multich I2S1 Out Switch", "ASRC_O1"},
+-	{"I16I17", "Multich I2S2 Out Switch", "ASRC_O2"},
+-	{"I18I19", "Multich I2S3 Out Switch", "ASRC_O3"},
++	{"I12I13", "Multich I2S0 Out Switch", "DLM"},
++	{"I14I15", "Multich I2S1 Out Switch", "DLM"},
++	{"I16I17", "Multich I2S2 Out Switch", "DLM"},
++	{"I18I19", "Multich I2S3 Out Switch", "DLM"},
+ 
+ 	{ "I12", NULL, "I12I13" },
+ 	{ "I13", NULL, "I12I13" },
+@@ -1067,7 +1007,6 @@ static const struct snd_soc_dapm_route mt2701_afe_pcm_routes[] = {
+ 	{ "O21", "I18 Switch", "I18" },
+ 	{ "O22", "I19 Switch", "I19" },
+ 	{ "O31", "I35 Switch", "I35" },
+-
+ };
+ 
+ static const struct snd_soc_component_driver mt2701_afe_pcm_dai_component = {
+@@ -1484,12 +1423,13 @@ static int mt2701_afe_pcm_dev_probe(struct platform_device *pdev)
+ 	afe = devm_kzalloc(&pdev->dev, sizeof(*afe), GFP_KERNEL);
+ 	if (!afe)
+ 		return -ENOMEM;
++
+ 	afe->platform_priv = devm_kzalloc(&pdev->dev, sizeof(*afe_priv),
+ 					  GFP_KERNEL);
+ 	if (!afe->platform_priv)
+ 		return -ENOMEM;
+-	afe_priv = afe->platform_priv;
+ 
++	afe_priv = afe->platform_priv;
+ 	afe->dev = &pdev->dev;
+ 	dev = afe->dev;
+ 
+@@ -1524,7 +1464,6 @@ static int mt2701_afe_pcm_dev_probe(struct platform_device *pdev)
+ 	afe->memif_size = MT2701_MEMIF_NUM;
+ 	afe->memif = devm_kcalloc(dev, afe->memif_size, sizeof(*afe->memif),
+ 				  GFP_KERNEL);
+-
+ 	if (!afe->memif)
+ 		return -ENOMEM;
+ 
+@@ -1537,7 +1476,6 @@ static int mt2701_afe_pcm_dev_probe(struct platform_device *pdev)
+ 	afe->irqs_size = MT2701_IRQ_ASYS_END;
+ 	afe->irqs = devm_kcalloc(dev, afe->irqs_size, sizeof(*afe->irqs),
+ 				 GFP_KERNEL);
+-
+ 	if (!afe->irqs)
+ 		return -ENOMEM;
+ 
+@@ -1555,7 +1493,6 @@ static int mt2701_afe_pcm_dev_probe(struct platform_device *pdev)
+ 	afe->mtk_afe_hardware = &mt2701_afe_hardware;
+ 	afe->memif_fs = mt2701_memif_fs;
+ 	afe->irq_fs = mt2701_irq_fs;
+-
+ 	afe->reg_back_up_list = mt2701_afe_backup_list;
+ 	afe->reg_back_up_list_num = ARRAY_SIZE(mt2701_afe_backup_list);
+ 	afe->runtime_resume = mt2701_afe_runtime_resume;
+@@ -1646,4 +1583,3 @@ module_platform_driver(mt2701_afe_pcm_driver);
+ MODULE_DESCRIPTION("Mediatek ALSA SoC AFE platform driver for 2701");
+ MODULE_AUTHOR("Garlic Tseng <garlic.tseng@mediatek.com>");
+ MODULE_LICENSE("GPL v2");
+-
+diff --git a/sound/soc/mediatek/mt2701/mt2701-reg.h b/sound/soc/mediatek/mt2701/mt2701-reg.h
+index bb62b1c55957..f17c76f37b5f 100644
+--- a/sound/soc/mediatek/mt2701/mt2701-reg.h
++++ b/sound/soc/mediatek/mt2701/mt2701-reg.h
+@@ -17,17 +17,6 @@
+ #ifndef _MT2701_REG_H_
+ #define _MT2701_REG_H_
+ 
+-#include <linux/delay.h>
+-#include <linux/module.h>
+-#include <linux/of.h>
+-#include <linux/of_address.h>
+-#include <linux/pm_runtime.h>
+-#include <sound/soc.h>
+-#include "mt2701-afe-common.h"
+-
+-/*****************************************************************************
+- *                  R E G I S T E R       D E F I N I T I O N
+- *****************************************************************************/
+ #define AUDIO_TOP_CON0 0x0000
+ #define AUDIO_TOP_CON4 0x0010
+ #define AUDIO_TOP_CON5 0x0014
+@@ -109,18 +98,6 @@
+ #define AFE_DAI_BASE 0x1370
+ #define AFE_DAI_CUR 0x137c
+ 
+-/* AUDIO_TOP_CON0 (0x0000) */
+-#define AUDIO_TOP_CON0_A1SYS_A2SYS_ON	(0x3 << 0)
+-#define AUDIO_TOP_CON0_PDN_AFE		(0x1 << 2)
+-#define AUDIO_TOP_CON0_PDN_APLL_CK	(0x1 << 23)
+-
+-/* AUDIO_TOP_CON4 (0x0010) */
+-#define AUDIO_TOP_CON4_I2SO1_PWN	(0x1 << 6)
+-#define AUDIO_TOP_CON4_PDN_A1SYS	(0x1 << 21)
+-#define AUDIO_TOP_CON4_PDN_A2SYS	(0x1 << 22)
+-#define AUDIO_TOP_CON4_PDN_AFE_CONN	(0x1 << 23)
+-#define AUDIO_TOP_CON4_PDN_MRGIF	(0x1 << 25)
+-
+ /* AFE_DAIBT_CON0 (0x001c) */
+ #define AFE_DAIBT_CON0_DAIBT_EN		(0x1 << 0)
+ #define AFE_DAIBT_CON0_BT_FUNC_EN	(0x1 << 1)
+@@ -137,22 +114,8 @@
+ #define AFE_MRGIF_CON_I2S_MODE_MASK	(0xf << 20)
+ #define AFE_MRGIF_CON_I2S_MODE_32K	(0x4 << 20)
+ 
+-/* ASYS_I2SO1_CON (0x061c) */
+-#define ASYS_I2SO1_CON_FS		(0x1f << 8)
+-#define ASYS_I2SO1_CON_FS_SET(x)	((x) << 8)
+-#define ASYS_I2SO1_CON_MULTI_CH		(0x1 << 16)
+-#define ASYS_I2SO1_CON_SIDEGEN		(0x1 << 30)
+-#define ASYS_I2SO1_CON_I2S_EN		(0x1 << 0)
+-/* 0:EIAJ 1:I2S */
+-#define ASYS_I2SO1_CON_I2S_MODE		(0x1 << 3)
+-#define ASYS_I2SO1_CON_WIDE_MODE	(0x1 << 1)
+-#define ASYS_I2SO1_CON_WIDE_MODE_SET(x)	((x) << 1)
+-
+-/* PWR2_TOP_CON (0x0634) */
+-#define PWR2_TOP_CON_INIT_VAL		(0xffe1ffff)
+-
+-/* ASYS_IRQ_CLR (0x07c0) */
+-#define ASYS_IRQ_CLR_ALL		(0xffffffff)
++/* ASYS_TOP_CON (0x0600) */
++#define ASYS_TOP_CON_ASYS_TIMING_ON		(0x3 << 0)
+ 
+ /* PWR2_ASM_CON1 (0x1070) */
+ #define PWR2_ASM_CON1_INIT_VAL		(0x492492)
+-- 
+2.11.0
+
diff --git a/target/linux/mediatek/patches-4.14/0183-ASoC-mediatek-update-clock-related-properties-of-MT2.patch b/target/linux/mediatek/patches-4.14/0183-ASoC-mediatek-update-clock-related-properties-of-MT2.patch
new file mode 100644
index 0000000000..7aa20b76e7
--- /dev/null
+++ b/target/linux/mediatek/patches-4.14/0183-ASoC-mediatek-update-clock-related-properties-of-MT2.patch
@@ -0,0 +1,263 @@
+From d5b391bb7208c8a7b6b874c1357d3cd110537167 Mon Sep 17 00:00:00 2001
+From: Ryder Lee <ryder.lee@mediatek.com>
+Date: Tue, 2 Jan 2018 19:47:21 +0800
+Subject: [PATCH 183/224] ASoC: mediatek: update clock related properties of
+ MT2701 AFE
+
+Add 'assigned-clocks*' properties which are used to initialize default
+domain sources of audio system. we could configure different sets of
+input clocks through DTS now. Hence driver no longer cares about that.
+
+Also we change some 'clock-names' to make them more generic so that
+other chips can reuse gracefully.
+
+Signed-off-by: Ryder Lee <ryder.lee@mediatek.com>
+Signed-off-by: Mark Brown <broonie@kernel.org>
+---
+ .../devicetree/bindings/sound/mt2701-afe-pcm.txt   | 207 +++++++++------------
+ 1 file changed, 91 insertions(+), 116 deletions(-)
+
+diff --git a/Documentation/devicetree/bindings/sound/mt2701-afe-pcm.txt b/Documentation/devicetree/bindings/sound/mt2701-afe-pcm.txt
+index 77a57f84bed4..0450baad2813 100644
+--- a/Documentation/devicetree/bindings/sound/mt2701-afe-pcm.txt
++++ b/Documentation/devicetree/bindings/sound/mt2701-afe-pcm.txt
+@@ -6,51 +6,44 @@ Required properties:
+ - interrupts: should contain AFE and ASYS interrupts
+ - interrupt-names: should be "afe" and "asys"
+ - power-domains: should define the power domain
++- clocks: Must contain an entry for each entry in clock-names
++  See ../clocks/clock-bindings.txt for details
+ - clock-names: should have these clock names:
+-		"infra_sys_audio_clk",
+ 		"top_audio_mux1_sel",
+ 		"top_audio_mux2_sel",
+-		"top_audio_mux1_div",
+-		"top_audio_mux2_div",
+-		"top_audio_48k_timing",
+-		"top_audio_44k_timing",
+-		"top_audpll_mux_sel",
+-		"top_apll_sel",
+-		"top_aud1_pll_98M",
+-		"top_aud2_pll_90M",
+-		"top_hadds2_pll_98M",
+-		"top_hadds2_pll_294M",
+-		"top_audpll",
+-		"top_audpll_d4",
+-		"top_audpll_d8",
+-		"top_audpll_d16",
+-		"top_audpll_d24",
+-		"top_audintbus_sel",
+-		"clk_26m",
+-		"top_syspll1_d4",
+-		"top_aud_k1_src_sel",
+-		"top_aud_k2_src_sel",
+-		"top_aud_k3_src_sel",
+-		"top_aud_k4_src_sel",
+-		"top_aud_k5_src_sel",
+-		"top_aud_k6_src_sel",
+-		"top_aud_k1_src_div",
+-		"top_aud_k2_src_div",
+-		"top_aud_k3_src_div",
+-		"top_aud_k4_src_div",
+-		"top_aud_k5_src_div",
+-		"top_aud_k6_src_div",
+-		"top_aud_i2s1_mclk",
+-		"top_aud_i2s2_mclk",
+-		"top_aud_i2s3_mclk",
+-		"top_aud_i2s4_mclk",
+-		"top_aud_i2s5_mclk",
+-		"top_aud_i2s6_mclk",
+-		"top_asm_m_sel",
+-		"top_asm_h_sel",
+-		"top_univpll2_d4",
+-		"top_univpll2_d2",
+-		"top_syspll_d5";
++		"i2s0_src_sel",
++		"i2s1_src_sel",
++		"i2s2_src_sel",
++		"i2s3_src_sel",
++		"i2s0_src_div",
++		"i2s1_src_div",
++		"i2s2_src_div",
++		"i2s3_src_div",
++		"i2s0_mclk_en",
++		"i2s1_mclk_en",
++		"i2s2_mclk_en",
++		"i2s3_mclk_en",
++		"i2so0_hop_ck",
++		"i2so1_hop_ck",
++		"i2so2_hop_ck",
++		"i2so3_hop_ck",
++		"i2si0_hop_ck",
++		"i2si1_hop_ck",
++		"i2si2_hop_ck",
++		"i2si3_hop_ck",
++		"asrc0_out_ck",
++		"asrc1_out_ck",
++		"asrc2_out_ck",
++		"asrc3_out_ck",
++		"audio_afe_pd",
++		"audio_afe_conn_pd",
++		"audio_a1sys_pd",
++		"audio_a2sys_pd",
++		"audio_mrgif_pd";
++- assigned-clocks: list of input clocks and dividers for the audio system.
++		   See ../clocks/clock-bindings.txt for details.
++- assigned-clocks-parents: parent of input clocks of assigned clocks.
++- assigned-clock-rates: list of clock frequencies of assigned clocks.
+ 
+ Example:
+ 
+@@ -62,93 +55,75 @@ Example:
+ 			     <GIC_SPI 132 IRQ_TYPE_LEVEL_LOW>;
+ 		interrupt-names	= "afe", "asys";
+ 		power-domains = <&scpsys MT2701_POWER_DOMAIN_IFR_MSC>;
+-		clocks = <&infracfg CLK_INFRA_AUDIO>,
+-			 <&topckgen CLK_TOP_AUD_MUX1_SEL>,
++		clocks = <&topckgen CLK_TOP_AUD_MUX1_SEL>,
+ 			 <&topckgen CLK_TOP_AUD_MUX2_SEL>,
+-			 <&topckgen CLK_TOP_AUD_MUX1_DIV>,
+-			 <&topckgen CLK_TOP_AUD_MUX2_DIV>,
+-			 <&topckgen CLK_TOP_AUD_48K_TIMING>,
+-			 <&topckgen CLK_TOP_AUD_44K_TIMING>,
+-			 <&topckgen CLK_TOP_AUDPLL_MUX_SEL>,
+-			 <&topckgen CLK_TOP_APLL_SEL>,
+-			 <&topckgen CLK_TOP_AUD1PLL_98M>,
+-			 <&topckgen CLK_TOP_AUD2PLL_90M>,
+-			 <&topckgen CLK_TOP_HADDS2PLL_98M>,
+-			 <&topckgen CLK_TOP_HADDS2PLL_294M>,
+-			 <&topckgen CLK_TOP_AUDPLL>,
+-			 <&topckgen CLK_TOP_AUDPLL_D4>,
+-			 <&topckgen CLK_TOP_AUDPLL_D8>,
+-			 <&topckgen CLK_TOP_AUDPLL_D16>,
+-			 <&topckgen CLK_TOP_AUDPLL_D24>,
+-			 <&topckgen CLK_TOP_AUDINTBUS_SEL>,
+-			 <&clk26m>,
+-			 <&topckgen CLK_TOP_SYSPLL1_D4>,
+ 			 <&topckgen CLK_TOP_AUD_K1_SRC_SEL>,
+ 			 <&topckgen CLK_TOP_AUD_K2_SRC_SEL>,
+ 			 <&topckgen CLK_TOP_AUD_K3_SRC_SEL>,
+ 			 <&topckgen CLK_TOP_AUD_K4_SRC_SEL>,
+-			 <&topckgen CLK_TOP_AUD_K5_SRC_SEL>,
+-			 <&topckgen CLK_TOP_AUD_K6_SRC_SEL>,
+ 			 <&topckgen CLK_TOP_AUD_K1_SRC_DIV>,
+ 			 <&topckgen CLK_TOP_AUD_K2_SRC_DIV>,
+ 			 <&topckgen CLK_TOP_AUD_K3_SRC_DIV>,
+ 			 <&topckgen CLK_TOP_AUD_K4_SRC_DIV>,
+-			 <&topckgen CLK_TOP_AUD_K5_SRC_DIV>,
+-			 <&topckgen CLK_TOP_AUD_K6_SRC_DIV>,
+ 			 <&topckgen CLK_TOP_AUD_I2S1_MCLK>,
+ 			 <&topckgen CLK_TOP_AUD_I2S2_MCLK>,
+ 			 <&topckgen CLK_TOP_AUD_I2S3_MCLK>,
+ 			 <&topckgen CLK_TOP_AUD_I2S4_MCLK>,
+-			 <&topckgen CLK_TOP_AUD_I2S5_MCLK>,
+-			 <&topckgen CLK_TOP_AUD_I2S6_MCLK>,
+-			 <&topckgen CLK_TOP_ASM_M_SEL>,
+-			 <&topckgen CLK_TOP_ASM_H_SEL>,
+-			 <&topckgen CLK_TOP_UNIVPLL2_D4>,
+-			 <&topckgen CLK_TOP_UNIVPLL2_D2>,
+-			 <&topckgen CLK_TOP_SYSPLL_D5>;
++			 <&audiosys CLK_AUD_I2SO1>,
++			 <&audiosys CLK_AUD_I2SO2>,
++			 <&audiosys CLK_AUD_I2SO3>,
++			 <&audiosys CLK_AUD_I2SO4>,
++			 <&audiosys CLK_AUD_I2SIN1>,
++			 <&audiosys CLK_AUD_I2SIN2>,
++			 <&audiosys CLK_AUD_I2SIN3>,
++			 <&audiosys CLK_AUD_I2SIN4>,
++			 <&audiosys CLK_AUD_ASRCO1>,
++			 <&audiosys CLK_AUD_ASRCO2>,
++			 <&audiosys CLK_AUD_ASRCO3>,
++			 <&audiosys CLK_AUD_ASRCO4>,
++			 <&audiosys CLK_AUD_AFE>,
++			 <&audiosys CLK_AUD_AFE_CONN>,
++			 <&audiosys CLK_AUD_A1SYS>,
++			 <&audiosys CLK_AUD_A2SYS>,
++			 <&audiosys CLK_AUD_AFE_MRGIF>;
+ 
+-		clock-names = "infra_sys_audio_clk",
+-			      "top_audio_mux1_sel",
++		clock-names = "top_audio_mux1_sel",
+ 			      "top_audio_mux2_sel",
+-			      "top_audio_mux1_div",
+-			      "top_audio_mux2_div",
+-			      "top_audio_48k_timing",
+-			      "top_audio_44k_timing",
+-			      "top_audpll_mux_sel",
+-			      "top_apll_sel",
+-			      "top_aud1_pll_98M",
+-			      "top_aud2_pll_90M",
+-			      "top_hadds2_pll_98M",
+-			      "top_hadds2_pll_294M",
+-			      "top_audpll",
+-			      "top_audpll_d4",
+-			      "top_audpll_d8",
+-			      "top_audpll_d16",
+-			      "top_audpll_d24",
+-			      "top_audintbus_sel",
+-			      "clk_26m",
+-			      "top_syspll1_d4",
+-			      "top_aud_k1_src_sel",
+-			      "top_aud_k2_src_sel",
+-			      "top_aud_k3_src_sel",
+-			      "top_aud_k4_src_sel",
+-			      "top_aud_k5_src_sel",
+-			      "top_aud_k6_src_sel",
+-			      "top_aud_k1_src_div",
+-			      "top_aud_k2_src_div",
+-			      "top_aud_k3_src_div",
+-			      "top_aud_k4_src_div",
+-			      "top_aud_k5_src_div",
+-			      "top_aud_k6_src_div",
+-			      "top_aud_i2s1_mclk",
+-			      "top_aud_i2s2_mclk",
+-			      "top_aud_i2s3_mclk",
+-			      "top_aud_i2s4_mclk",
+-			      "top_aud_i2s5_mclk",
+-			      "top_aud_i2s6_mclk",
+-			      "top_asm_m_sel",
+-			      "top_asm_h_sel",
+-			      "top_univpll2_d4",
+-			      "top_univpll2_d2",
+-			      "top_syspll_d5";
++			      "i2s0_src_sel",
++			      "i2s1_src_sel",
++			      "i2s2_src_sel",
++			      "i2s3_src_sel",
++			      "i2s0_src_div",
++			      "i2s1_src_div",
++			      "i2s2_src_div",
++			      "i2s3_src_div",
++			      "i2s0_mclk_en",
++			      "i2s1_mclk_en",
++			      "i2s2_mclk_en",
++			      "i2s3_mclk_en",
++			      "i2so0_hop_ck",
++			      "i2so1_hop_ck",
++			      "i2so2_hop_ck",
++			      "i2so3_hop_ck",
++			      "i2si0_hop_ck",
++			      "i2si1_hop_ck",
++			      "i2si2_hop_ck",
++			      "i2si3_hop_ck",
++			      "asrc0_out_ck",
++			      "asrc1_out_ck",
++			      "asrc2_out_ck",
++			      "asrc3_out_ck",
++			      "audio_afe_pd",
++			      "audio_afe_conn_pd",
++			      "audio_a1sys_pd",
++			      "audio_a2sys_pd",
++			      "audio_mrgif_pd";
++
++		assigned-clocks = <&topckgen CLK_TOP_AUD_MUX1_SEL>,
++				  <&topckgen CLK_TOP_AUD_MUX2_SEL>,
++				  <&topckgen CLK_TOP_AUD_MUX1_DIV>,
++				  <&topckgen CLK_TOP_AUD_MUX2_DIV>;
++		assigned-clock-parents = <&topckgen CLK_TOP_AUD1PLL_98M>,
++					 <&topckgen CLK_TOP_AUD2PLL_90M>;
++		assigned-clock-rates = <0>, <0>, <49152000>, <45158400>;
+ 	};
+-- 
+2.11.0
+
diff --git a/target/linux/mediatek/patches-4.14/0184-ASoC-mediatek-add-some-core-clocks-for-MT2701-AFE.patch b/target/linux/mediatek/patches-4.14/0184-ASoC-mediatek-add-some-core-clocks-for-MT2701-AFE.patch
new file mode 100644
index 0000000000..d64d5a7072
--- /dev/null
+++ b/target/linux/mediatek/patches-4.14/0184-ASoC-mediatek-add-some-core-clocks-for-MT2701-AFE.patch
@@ -0,0 +1,100 @@
+From e0e3768b73daae674c69db1f71718894274b7bfc Mon Sep 17 00:00:00 2001
+From: Ryder Lee <ryder.lee@mediatek.com>
+Date: Thu, 4 Jan 2018 15:44:07 +0800
+Subject: [PATCH 184/224] ASoC: mediatek: add some core clocks for MT2701 AFE
+
+Add three core clocks for MT2701 AFE.
+
+Signed-off-by: Ryder Lee <ryder.lee@mediatek.com>
+Signed-off-by: Mark Brown <broonie@kernel.org>
+---
+ sound/soc/mediatek/mt2701/mt2701-afe-clock-ctrl.c | 30 ++++++++++++++++++++++-
+ sound/soc/mediatek/mt2701/mt2701-afe-common.h     |  3 +++
+ 2 files changed, 32 insertions(+), 1 deletion(-)
+
+diff --git a/sound/soc/mediatek/mt2701/mt2701-afe-clock-ctrl.c b/sound/soc/mediatek/mt2701/mt2701-afe-clock-ctrl.c
+index 56a057c78c9a..949fc3a1d025 100644
+--- a/sound/soc/mediatek/mt2701/mt2701-afe-clock-ctrl.c
++++ b/sound/soc/mediatek/mt2701/mt2701-afe-clock-ctrl.c
+@@ -18,8 +18,11 @@
+ #include "mt2701-afe-clock-ctrl.h"
+ 
+ static const char *const base_clks[] = {
++	[MT2701_INFRA_SYS_AUDIO] = "infra_sys_audio_clk",
+ 	[MT2701_TOP_AUD_MCLK_SRC0] = "top_audio_mux1_sel",
+ 	[MT2701_TOP_AUD_MCLK_SRC1] = "top_audio_mux2_sel",
++	[MT2701_TOP_AUD_A1SYS] = "top_audio_a1sys_hp",
++	[MT2701_TOP_AUD_A2SYS] = "top_audio_a2sys_hp",
+ 	[MT2701_AUDSYS_AFE] = "audio_afe_pd",
+ 	[MT2701_AUDSYS_AFE_CONN] = "audio_afe_conn_pd",
+ 	[MT2701_AUDSYS_A1SYS] = "audio_a1sys_pd",
+@@ -169,10 +172,26 @@ static int mt2701_afe_enable_audsys(struct mtk_base_afe *afe)
+ 	struct mt2701_afe_private *afe_priv = afe->platform_priv;
+ 	int ret;
+ 
+-	ret = clk_prepare_enable(afe_priv->base_ck[MT2701_AUDSYS_AFE]);
++	/* Enable infra clock gate */
++	ret = clk_prepare_enable(afe_priv->base_ck[MT2701_INFRA_SYS_AUDIO]);
+ 	if (ret)
+ 		return ret;
+ 
++	/* Enable top a1sys clock gate */
++	ret = clk_prepare_enable(afe_priv->base_ck[MT2701_TOP_AUD_A1SYS]);
++	if (ret)
++		goto err_a1sys;
++
++	/* Enable top a2sys clock gate */
++	ret = clk_prepare_enable(afe_priv->base_ck[MT2701_TOP_AUD_A2SYS]);
++	if (ret)
++		goto err_a2sys;
++
++	/* Internal clock gates */
++	ret = clk_prepare_enable(afe_priv->base_ck[MT2701_AUDSYS_AFE]);
++	if (ret)
++		goto err_afe;
++
+ 	ret = clk_prepare_enable(afe_priv->base_ck[MT2701_AUDSYS_A1SYS]);
+ 	if (ret)
+ 		goto err_audio_a1sys;
+@@ -193,6 +212,12 @@ static int mt2701_afe_enable_audsys(struct mtk_base_afe *afe)
+ 	clk_disable_unprepare(afe_priv->base_ck[MT2701_AUDSYS_A1SYS]);
+ err_audio_a1sys:
+ 	clk_disable_unprepare(afe_priv->base_ck[MT2701_AUDSYS_AFE]);
++err_afe:
++	clk_disable_unprepare(afe_priv->base_ck[MT2701_TOP_AUD_A2SYS]);
++err_a2sys:
++	clk_disable_unprepare(afe_priv->base_ck[MT2701_TOP_AUD_A1SYS]);
++err_a1sys:
++	clk_disable_unprepare(afe_priv->base_ck[MT2701_INFRA_SYS_AUDIO]);
+ 
+ 	return ret;
+ }
+@@ -205,6 +230,9 @@ static void mt2701_afe_disable_audsys(struct mtk_base_afe *afe)
+ 	clk_disable_unprepare(afe_priv->base_ck[MT2701_AUDSYS_A2SYS]);
+ 	clk_disable_unprepare(afe_priv->base_ck[MT2701_AUDSYS_A1SYS]);
+ 	clk_disable_unprepare(afe_priv->base_ck[MT2701_AUDSYS_AFE]);
++	clk_disable_unprepare(afe_priv->base_ck[MT2701_TOP_AUD_A1SYS]);
++	clk_disable_unprepare(afe_priv->base_ck[MT2701_TOP_AUD_A2SYS]);
++	clk_disable_unprepare(afe_priv->base_ck[MT2701_INFRA_SYS_AUDIO]);
+ }
+ 
+ int mt2701_afe_enable_clock(struct mtk_base_afe *afe)
+diff --git a/sound/soc/mediatek/mt2701/mt2701-afe-common.h b/sound/soc/mediatek/mt2701/mt2701-afe-common.h
+index 9a2b301a4c21..ae8ddeacfbfe 100644
+--- a/sound/soc/mediatek/mt2701/mt2701-afe-common.h
++++ b/sound/soc/mediatek/mt2701/mt2701-afe-common.h
+@@ -61,8 +61,11 @@ enum {
+ };
+ 
+ enum audio_base_clock {
++	MT2701_INFRA_SYS_AUDIO,
+ 	MT2701_TOP_AUD_MCLK_SRC0,
+ 	MT2701_TOP_AUD_MCLK_SRC1,
++	MT2701_TOP_AUD_A1SYS,
++	MT2701_TOP_AUD_A2SYS,
+ 	MT2701_AUDSYS_AFE,
+ 	MT2701_AUDSYS_AFE_CONN,
+ 	MT2701_AUDSYS_A1SYS,
+-- 
+2.11.0
+
diff --git a/target/linux/mediatek/patches-4.14/0185-ASoC-mediatek-modify-MT2701-AFE-driver-to-adapt-mfd-.patch b/target/linux/mediatek/patches-4.14/0185-ASoC-mediatek-modify-MT2701-AFE-driver-to-adapt-mfd-.patch
new file mode 100644
index 0000000000..fe5f9d398e
--- /dev/null
+++ b/target/linux/mediatek/patches-4.14/0185-ASoC-mediatek-modify-MT2701-AFE-driver-to-adapt-mfd-.patch
@@ -0,0 +1,135 @@
+From 310ca2954c7cce10d716001ff869bc255494e3df Mon Sep 17 00:00:00 2001
+From: Ryder Lee <ryder.lee@mediatek.com>
+Date: Thu, 4 Jan 2018 15:44:08 +0800
+Subject: [PATCH 185/224] ASoC: mediatek: modify MT2701 AFE driver to adapt mfd
+ device
+
+As the new MFD parent is in place, modify MT2701 AFE driver to adapt it.
+
+Signed-off-by: Ryder Lee <ryder.lee@mediatek.com>
+Signed-off-by: Mark Brown <broonie@kernel.org>
+---
+ sound/soc/mediatek/mt2701/mt2701-afe-pcm.c | 45 +++++++++++++-----------------
+ sound/soc/mediatek/mt2701/mt2701-reg.h     |  1 -
+ 2 files changed, 20 insertions(+), 26 deletions(-)
+
+diff --git a/sound/soc/mediatek/mt2701/mt2701-afe-pcm.c b/sound/soc/mediatek/mt2701/mt2701-afe-pcm.c
+index 0edadca12a5e..f0cd08fa5c5d 100644
+--- a/sound/soc/mediatek/mt2701/mt2701-afe-pcm.c
++++ b/sound/soc/mediatek/mt2701/mt2701-afe-pcm.c
+@@ -17,6 +17,7 @@
+ 
+ #include <linux/delay.h>
+ #include <linux/module.h>
++#include <linux/mfd/syscon.h>
+ #include <linux/of.h>
+ #include <linux/of_address.h>
+ #include <linux/pm_runtime.h>
+@@ -1368,14 +1369,6 @@ static const struct mt2701_i2s_data mt2701_i2s_data[MT2701_I2S_NUM][2] = {
+ 	},
+ };
+ 
+-static const struct regmap_config mt2701_afe_regmap_config = {
+-	.reg_bits = 32,
+-	.reg_stride = 4,
+-	.val_bits = 32,
+-	.max_register = AFE_END_ADDR,
+-	.cache_type = REGCACHE_NONE,
+-};
+-
+ static irqreturn_t mt2701_asys_isr(int irq_id, void *dev)
+ {
+ 	int id;
+@@ -1414,9 +1407,9 @@ static int mt2701_afe_runtime_resume(struct device *dev)
+ 
+ static int mt2701_afe_pcm_dev_probe(struct platform_device *pdev)
+ {
++	struct snd_soc_component *component;
+ 	struct mtk_base_afe *afe;
+ 	struct mt2701_afe_private *afe_priv;
+-	struct resource *res;
+ 	struct device *dev;
+ 	int i, irq_id, ret;
+ 
+@@ -1446,17 +1439,11 @@ static int mt2701_afe_pcm_dev_probe(struct platform_device *pdev)
+ 		return ret;
+ 	}
+ 
+-	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+-
+-	afe->base_addr = devm_ioremap_resource(&pdev->dev, res);
+-
+-	if (IS_ERR(afe->base_addr))
+-		return PTR_ERR(afe->base_addr);
+-
+-	afe->regmap = devm_regmap_init_mmio(&pdev->dev, afe->base_addr,
+-		&mt2701_afe_regmap_config);
+-	if (IS_ERR(afe->regmap))
+-		return PTR_ERR(afe->regmap);
++	afe->regmap = syscon_node_to_regmap(dev->parent->of_node);
++	if (!afe->regmap) {
++		dev_err(dev, "could not get regmap from parent\n");
++		return -ENODEV;
++	}
+ 
+ 	mutex_init(&afe->irq_alloc_lock);
+ 
+@@ -1490,6 +1477,12 @@ static int mt2701_afe_pcm_dev_probe(struct platform_device *pdev)
+ 			= &mt2701_i2s_data[i][I2S_IN];
+ 	}
+ 
++	component = kzalloc(sizeof(*component), GFP_KERNEL);
++	if (!component)
++		return -ENOMEM;
++
++	component->regmap = afe->regmap;
++
+ 	afe->mtk_afe_hardware = &mt2701_afe_hardware;
+ 	afe->memif_fs = mt2701_memif_fs;
+ 	afe->irq_fs = mt2701_irq_fs;
+@@ -1502,7 +1495,7 @@ static int mt2701_afe_pcm_dev_probe(struct platform_device *pdev)
+ 	ret = mt2701_init_clock(afe);
+ 	if (ret) {
+ 		dev_err(dev, "init clock error\n");
+-		return ret;
++		goto err_init_clock;
+ 	}
+ 
+ 	platform_set_drvdata(pdev, afe);
+@@ -1521,10 +1514,10 @@ static int mt2701_afe_pcm_dev_probe(struct platform_device *pdev)
+ 		goto err_platform;
+ 	}
+ 
+-	ret = snd_soc_register_component(&pdev->dev,
+-					 &mt2701_afe_pcm_dai_component,
+-					 mt2701_afe_pcm_dais,
+-					 ARRAY_SIZE(mt2701_afe_pcm_dais));
++	ret = snd_soc_add_component(dev, component,
++				    &mt2701_afe_pcm_dai_component,
++				    mt2701_afe_pcm_dais,
++				    ARRAY_SIZE(mt2701_afe_pcm_dais));
+ 	if (ret) {
+ 		dev_warn(dev, "err_dai_component\n");
+ 		goto err_dai_component;
+@@ -1538,6 +1531,8 @@ static int mt2701_afe_pcm_dev_probe(struct platform_device *pdev)
+ 	pm_runtime_put_sync(dev);
+ err_pm_disable:
+ 	pm_runtime_disable(dev);
++err_init_clock:
++	kfree(component);
+ 
+ 	return ret;
+ }
+diff --git a/sound/soc/mediatek/mt2701/mt2701-reg.h b/sound/soc/mediatek/mt2701/mt2701-reg.h
+index f17c76f37b5f..18e676974f22 100644
+--- a/sound/soc/mediatek/mt2701/mt2701-reg.h
++++ b/sound/soc/mediatek/mt2701/mt2701-reg.h
+@@ -145,5 +145,4 @@
+ #define ASYS_I2S_CON_WIDE_MODE_SET(x)	((x) << 1)
+ #define ASYS_I2S_IN_PHASE_FIX		(0x1 << 31)
+ 
+-#define AFE_END_ADDR 0x15e0
+ #endif
+-- 
+2.11.0
+
diff --git a/target/linux/mediatek/patches-4.14/0186-ASoC-mediatek-update-MT2701-AFE-documentation-to-ada.patch b/target/linux/mediatek/patches-4.14/0186-ASoC-mediatek-update-MT2701-AFE-documentation-to-ada.patch
new file mode 100644
index 0000000000..3d515402b5
--- /dev/null
+++ b/target/linux/mediatek/patches-4.14/0186-ASoC-mediatek-update-MT2701-AFE-documentation-to-ada.patch
@@ -0,0 +1,217 @@
+From 018219d340c0f7a10098683b8a4733618ea76ba3 Mon Sep 17 00:00:00 2001
+From: Ryder Lee <ryder.lee@mediatek.com>
+Date: Thu, 4 Jan 2018 15:44:09 +0800
+Subject: [PATCH 186/224] ASoC: mediatek: update MT2701 AFE documentation to
+ adapt mfd device
+
+As the new MFD parent is in place, modify MT2701 AFE documentation to
+adapt it. Also add three core clocks in example.
+
+Signed-off-by: Ryder Lee <ryder.lee@mediatek.com>
+Signed-off-by: Mark Brown <broonie@kernel.org>
+---
+ .../devicetree/bindings/sound/mt2701-afe-pcm.txt   | 171 +++++++++++----------
+ 1 file changed, 93 insertions(+), 78 deletions(-)
+
+diff --git a/Documentation/devicetree/bindings/sound/mt2701-afe-pcm.txt b/Documentation/devicetree/bindings/sound/mt2701-afe-pcm.txt
+index 0450baad2813..6df87b97f7cb 100644
+--- a/Documentation/devicetree/bindings/sound/mt2701-afe-pcm.txt
++++ b/Documentation/devicetree/bindings/sound/mt2701-afe-pcm.txt
+@@ -2,15 +2,17 @@ Mediatek AFE PCM controller for mt2701
+ 
+ Required properties:
+ - compatible = "mediatek,mt2701-audio";
+-- reg: register location and size
+ - interrupts: should contain AFE and ASYS interrupts
+ - interrupt-names: should be "afe" and "asys"
+ - power-domains: should define the power domain
+ - clocks: Must contain an entry for each entry in clock-names
+   See ../clocks/clock-bindings.txt for details
+ - clock-names: should have these clock names:
++		"infra_sys_audio_clk",
+ 		"top_audio_mux1_sel",
+ 		"top_audio_mux2_sel",
++		"top_audio_a1sys_hp",
++		"top_audio_a2sys_hp",
+ 		"i2s0_src_sel",
+ 		"i2s1_src_sel",
+ 		"i2s2_src_sel",
+@@ -45,85 +47,98 @@ Required properties:
+ - assigned-clocks-parents: parent of input clocks of assigned clocks.
+ - assigned-clock-rates: list of clock frequencies of assigned clocks.
+ 
++Must be a subnode of MediaTek audsys device tree node.
++See ../arm/mediatek/mediatek,audsys.txt for details about the parent node.
++
+ Example:
+ 
+-	afe: mt2701-afe-pcm@11220000 {
+-		compatible = "mediatek,mt2701-audio";
+-		reg = <0 0x11220000 0 0x2000>,
+-		      <0 0x112A0000 0 0x20000>;
+-		interrupts = <GIC_SPI 104 IRQ_TYPE_LEVEL_LOW>,
+-			     <GIC_SPI 132 IRQ_TYPE_LEVEL_LOW>;
+-		interrupt-names	= "afe", "asys";
+-		power-domains = <&scpsys MT2701_POWER_DOMAIN_IFR_MSC>;
+-		clocks = <&topckgen CLK_TOP_AUD_MUX1_SEL>,
+-			 <&topckgen CLK_TOP_AUD_MUX2_SEL>,
+-			 <&topckgen CLK_TOP_AUD_K1_SRC_SEL>,
+-			 <&topckgen CLK_TOP_AUD_K2_SRC_SEL>,
+-			 <&topckgen CLK_TOP_AUD_K3_SRC_SEL>,
+-			 <&topckgen CLK_TOP_AUD_K4_SRC_SEL>,
+-			 <&topckgen CLK_TOP_AUD_K1_SRC_DIV>,
+-			 <&topckgen CLK_TOP_AUD_K2_SRC_DIV>,
+-			 <&topckgen CLK_TOP_AUD_K3_SRC_DIV>,
+-			 <&topckgen CLK_TOP_AUD_K4_SRC_DIV>,
+-			 <&topckgen CLK_TOP_AUD_I2S1_MCLK>,
+-			 <&topckgen CLK_TOP_AUD_I2S2_MCLK>,
+-			 <&topckgen CLK_TOP_AUD_I2S3_MCLK>,
+-			 <&topckgen CLK_TOP_AUD_I2S4_MCLK>,
+-			 <&audiosys CLK_AUD_I2SO1>,
+-			 <&audiosys CLK_AUD_I2SO2>,
+-			 <&audiosys CLK_AUD_I2SO3>,
+-			 <&audiosys CLK_AUD_I2SO4>,
+-			 <&audiosys CLK_AUD_I2SIN1>,
+-			 <&audiosys CLK_AUD_I2SIN2>,
+-			 <&audiosys CLK_AUD_I2SIN3>,
+-			 <&audiosys CLK_AUD_I2SIN4>,
+-			 <&audiosys CLK_AUD_ASRCO1>,
+-			 <&audiosys CLK_AUD_ASRCO2>,
+-			 <&audiosys CLK_AUD_ASRCO3>,
+-			 <&audiosys CLK_AUD_ASRCO4>,
+-			 <&audiosys CLK_AUD_AFE>,
+-			 <&audiosys CLK_AUD_AFE_CONN>,
+-			 <&audiosys CLK_AUD_A1SYS>,
+-			 <&audiosys CLK_AUD_A2SYS>,
+-			 <&audiosys CLK_AUD_AFE_MRGIF>;
++	audsys: audio-subsystem@11220000 {
++		compatible = "mediatek,mt2701-audsys", "syscon", "simple-mfd";
++		...
++
++		afe: audio-controller {
++			compatible = "mediatek,mt2701-audio";
++			interrupts =  <GIC_SPI 104 IRQ_TYPE_LEVEL_LOW>,
++				      <GIC_SPI 132 IRQ_TYPE_LEVEL_LOW>;
++			interrupt-names	= "afe", "asys";
++			power-domains = <&scpsys MT2701_POWER_DOMAIN_IFR_MSC>;
++
++			clocks = <&infracfg CLK_INFRA_AUDIO>,
++				 <&topckgen CLK_TOP_AUD_MUX1_SEL>,
++				 <&topckgen CLK_TOP_AUD_MUX2_SEL>,
++				 <&topckgen CLK_TOP_AUD_48K_TIMING>,
++				 <&topckgen CLK_TOP_AUD_44K_TIMING>,
++				 <&topckgen CLK_TOP_AUD_K1_SRC_SEL>,
++				 <&topckgen CLK_TOP_AUD_K2_SRC_SEL>,
++				 <&topckgen CLK_TOP_AUD_K3_SRC_SEL>,
++				 <&topckgen CLK_TOP_AUD_K4_SRC_SEL>,
++				 <&topckgen CLK_TOP_AUD_K1_SRC_DIV>,
++				 <&topckgen CLK_TOP_AUD_K2_SRC_DIV>,
++				 <&topckgen CLK_TOP_AUD_K3_SRC_DIV>,
++				 <&topckgen CLK_TOP_AUD_K4_SRC_DIV>,
++				 <&topckgen CLK_TOP_AUD_I2S1_MCLK>,
++				 <&topckgen CLK_TOP_AUD_I2S2_MCLK>,
++				 <&topckgen CLK_TOP_AUD_I2S3_MCLK>,
++				 <&topckgen CLK_TOP_AUD_I2S4_MCLK>,
++				 <&audsys CLK_AUD_I2SO1>,
++				 <&audsys CLK_AUD_I2SO2>,
++				 <&audsys CLK_AUD_I2SO3>,
++				 <&audsys CLK_AUD_I2SO4>,
++				 <&audsys CLK_AUD_I2SIN1>,
++				 <&audsys CLK_AUD_I2SIN2>,
++				 <&audsys CLK_AUD_I2SIN3>,
++				 <&audsys CLK_AUD_I2SIN4>,
++				 <&audsys CLK_AUD_ASRCO1>,
++				 <&audsys CLK_AUD_ASRCO2>,
++				 <&audsys CLK_AUD_ASRCO3>,
++				 <&audsys CLK_AUD_ASRCO4>,
++				 <&audsys CLK_AUD_AFE>,
++				 <&audsys CLK_AUD_AFE_CONN>,
++				 <&audsys CLK_AUD_A1SYS>,
++				 <&audsys CLK_AUD_A2SYS>,
++				 <&audsys CLK_AUD_AFE_MRGIF>;
+ 
+-		clock-names = "top_audio_mux1_sel",
+-			      "top_audio_mux2_sel",
+-			      "i2s0_src_sel",
+-			      "i2s1_src_sel",
+-			      "i2s2_src_sel",
+-			      "i2s3_src_sel",
+-			      "i2s0_src_div",
+-			      "i2s1_src_div",
+-			      "i2s2_src_div",
+-			      "i2s3_src_div",
+-			      "i2s0_mclk_en",
+-			      "i2s1_mclk_en",
+-			      "i2s2_mclk_en",
+-			      "i2s3_mclk_en",
+-			      "i2so0_hop_ck",
+-			      "i2so1_hop_ck",
+-			      "i2so2_hop_ck",
+-			      "i2so3_hop_ck",
+-			      "i2si0_hop_ck",
+-			      "i2si1_hop_ck",
+-			      "i2si2_hop_ck",
+-			      "i2si3_hop_ck",
+-			      "asrc0_out_ck",
+-			      "asrc1_out_ck",
+-			      "asrc2_out_ck",
+-			      "asrc3_out_ck",
+-			      "audio_afe_pd",
+-			      "audio_afe_conn_pd",
+-			      "audio_a1sys_pd",
+-			      "audio_a2sys_pd",
+-			      "audio_mrgif_pd";
++			clock-names = "infra_sys_audio_clk",
++				      "top_audio_mux1_sel",
++				      "top_audio_mux2_sel",
++				      "top_audio_a1sys_hp",
++				      "top_audio_a2sys_hp",
++				      "i2s0_src_sel",
++				      "i2s1_src_sel",
++				      "i2s2_src_sel",
++				      "i2s3_src_sel",
++				      "i2s0_src_div",
++				      "i2s1_src_div",
++				      "i2s2_src_div",
++				      "i2s3_src_div",
++				      "i2s0_mclk_en",
++				      "i2s1_mclk_en",
++				      "i2s2_mclk_en",
++				      "i2s3_mclk_en",
++				      "i2so0_hop_ck",
++				      "i2so1_hop_ck",
++				      "i2so2_hop_ck",
++				      "i2so3_hop_ck",
++				      "i2si0_hop_ck",
++				      "i2si1_hop_ck",
++				      "i2si2_hop_ck",
++				      "i2si3_hop_ck",
++				      "asrc0_out_ck",
++				      "asrc1_out_ck",
++				      "asrc2_out_ck",
++				      "asrc3_out_ck",
++				      "audio_afe_pd",
++				      "audio_afe_conn_pd",
++				      "audio_a1sys_pd",
++				      "audio_a2sys_pd",
++				      "audio_mrgif_pd";
+ 
+-		assigned-clocks = <&topckgen CLK_TOP_AUD_MUX1_SEL>,
+-				  <&topckgen CLK_TOP_AUD_MUX2_SEL>,
+-				  <&topckgen CLK_TOP_AUD_MUX1_DIV>,
+-				  <&topckgen CLK_TOP_AUD_MUX2_DIV>;
+-		assigned-clock-parents = <&topckgen CLK_TOP_AUD1PLL_98M>,
+-					 <&topckgen CLK_TOP_AUD2PLL_90M>;
+-		assigned-clock-rates = <0>, <0>, <49152000>, <45158400>;
++			assigned-clocks = <&topckgen CLK_TOP_AUD_MUX1_SEL>,
++					  <&topckgen CLK_TOP_AUD_MUX2_SEL>,
++					  <&topckgen CLK_TOP_AUD_MUX1_DIV>,
++					  <&topckgen CLK_TOP_AUD_MUX2_DIV>;
++			assigned-clock-parents = <&topckgen CLK_TOP_AUD1PLL_98M>,
++						 <&topckgen CLK_TOP_AUD2PLL_90M>;
++			assigned-clock-rates = <0>, <0>, <49152000>, <45158400>;
++		};
+ 	};
+-- 
+2.11.0
+
diff --git a/target/linux/mediatek/patches-4.14/0187-usb-mtu3-fix-error-code-for-getting-extcon-device.patch b/target/linux/mediatek/patches-4.14/0187-usb-mtu3-fix-error-code-for-getting-extcon-device.patch
new file mode 100644
index 0000000000..4d79623e5d
--- /dev/null
+++ b/target/linux/mediatek/patches-4.14/0187-usb-mtu3-fix-error-code-for-getting-extcon-device.patch
@@ -0,0 +1,31 @@
+From 3d5564bbc0a39ba07d1bbdaec1f69a3d39c4495e Mon Sep 17 00:00:00 2001
+From: Chunfeng Yun <chunfeng.yun@mediatek.com>
+Date: Wed, 3 Jan 2018 16:53:17 +0800
+Subject: [PATCH 187/224] usb: mtu3: fix error code for getting extcon device
+
+When failing to get extcon device, extcon_get_edev_by_phandle()
+may return different error codes, but not only -EPROBE_DEFER,
+so can't always return -EPROBE_DEFER, and fix it.
+
+Signed-off-by: Chunfeng Yun <chunfeng.yun@mediatek.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/usb/mtu3/mtu3_plat.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/usb/mtu3/mtu3_plat.c b/drivers/usb/mtu3/mtu3_plat.c
+index 9ff33579b42e..a2523ead46cf 100644
+--- a/drivers/usb/mtu3/mtu3_plat.c
++++ b/drivers/usb/mtu3/mtu3_plat.c
+@@ -317,7 +317,7 @@ static int get_ssusb_rscs(struct platform_device *pdev, struct ssusb_mtk *ssusb)
+ 		otg_sx->edev = extcon_get_edev_by_phandle(ssusb->dev, 0);
+ 		if (IS_ERR(otg_sx->edev)) {
+ 			dev_err(ssusb->dev, "couldn't get extcon device\n");
+-			return -EPROBE_DEFER;
++			return PTR_ERR(otg_sx->edev);
+ 		}
+ 	}
+ 
+-- 
+2.11.0
+
diff --git a/target/linux/mediatek/patches-4.14/0188-usb-mtu3-supports-remote-wakeup-for-mt2712-with-two-.patch b/target/linux/mediatek/patches-4.14/0188-usb-mtu3-supports-remote-wakeup-for-mt2712-with-two-.patch
new file mode 100644
index 0000000000..105d6f156b
--- /dev/null
+++ b/target/linux/mediatek/patches-4.14/0188-usb-mtu3-supports-remote-wakeup-for-mt2712-with-two-.patch
@@ -0,0 +1,245 @@
+From 354655aaf0f71ce2b567cbc02afb0664c99e434e Mon Sep 17 00:00:00 2001
+From: Chunfeng Yun <chunfeng.yun@mediatek.com>
+Date: Wed, 3 Jan 2018 16:53:18 +0800
+Subject: [PATCH 188/224] usb: mtu3: supports remote wakeup for mt2712 with two
+ SSUSB IPs
+
+The old way of usb wakeup only supports platform with single SSUSB IP,
+such as mt8173, but mt2712 has two SSUSB IPs, so rebuild its flow and
+also supports the new glue layer of usb wakeup on mt2712 which is
+different from mt8173.
+
+Signed-off-by: Chunfeng Yun <chunfeng.yun@mediatek.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/usb/mtu3/mtu3.h      |  11 +++--
+ drivers/usb/mtu3/mtu3_dr.h   |   3 +-
+ drivers/usb/mtu3/mtu3_host.c | 115 +++++++++++++++++++++----------------------
+ drivers/usb/mtu3/mtu3_plat.c |   8 +--
+ 4 files changed, 70 insertions(+), 67 deletions(-)
+
+diff --git a/drivers/usb/mtu3/mtu3.h b/drivers/usb/mtu3/mtu3.h
+index d80e4e813248..ed3aec46eda1 100644
+--- a/drivers/usb/mtu3/mtu3.h
++++ b/drivers/usb/mtu3/mtu3.h
+@@ -238,7 +238,10 @@ struct otg_switch_mtk {
+  * @u3p_dis_msk: mask of disabling usb3 ports, for example, bit0==1 to
+  *		disable u3port0, bit1==1 to disable u3port1,... etc
+  * @dbgfs_root: only used when supports manual dual-role switch via debugfs
+- * @wakeup_en: it's true when supports remote wakeup in host mode
++ * @uwk_en: it's true when supports remote wakeup in host mode
++ * @uwk: syscon including usb wakeup glue layer between SSUSB IP and SPM
++ * @uwk_reg_base: the base address of the wakeup glue layer in @uwk
++ * @uwk_vers: the version of the wakeup glue layer
+  */
+ struct ssusb_mtk {
+ 	struct device *dev;
+@@ -262,8 +265,10 @@ struct ssusb_mtk {
+ 	int u3p_dis_msk;
+ 	struct dentry *dbgfs_root;
+ 	/* usb wakeup for host mode */
+-	bool wakeup_en;
+-	struct regmap *pericfg;
++	bool uwk_en;
++	struct regmap *uwk;
++	u32 uwk_reg_base;
++	u32 uwk_vers;
+ };
+ 
+ /**
+diff --git a/drivers/usb/mtu3/mtu3_dr.h b/drivers/usb/mtu3/mtu3_dr.h
+index 0f0cbac00192..1fa62ce136b6 100644
+--- a/drivers/usb/mtu3/mtu3_dr.h
++++ b/drivers/usb/mtu3/mtu3_dr.h
+@@ -27,8 +27,7 @@ int ssusb_wakeup_of_property_parse(struct ssusb_mtk *ssusb,
+ 				struct device_node *dn);
+ int ssusb_host_enable(struct ssusb_mtk *ssusb);
+ int ssusb_host_disable(struct ssusb_mtk *ssusb, bool suspend);
+-int ssusb_wakeup_enable(struct ssusb_mtk *ssusb);
+-void ssusb_wakeup_disable(struct ssusb_mtk *ssusb);
++void ssusb_wakeup_set(struct ssusb_mtk *ssusb, bool enable);
+ 
+ #else
+ 
+diff --git a/drivers/usb/mtu3/mtu3_host.c b/drivers/usb/mtu3/mtu3_host.c
+index ec76b86dd887..1a1b6cf432a1 100644
+--- a/drivers/usb/mtu3/mtu3_host.c
++++ b/drivers/usb/mtu3/mtu3_host.c
+@@ -27,66 +27,77 @@
+ #include "mtu3.h"
+ #include "mtu3_dr.h"
+ 
+-#define PERI_WK_CTRL1		0x404
+-#define UWK_CTL1_IS_C(x)	(((x) & 0xf) << 26)
+-#define UWK_CTL1_IS_E		BIT(25)
+-#define UWK_CTL1_IDDIG_C(x)	(((x) & 0xf) << 11)  /* cycle debounce */
+-#define UWK_CTL1_IDDIG_E	BIT(10) /* enable debounce */
+-#define UWK_CTL1_IDDIG_P	BIT(9)  /* polarity */
+-#define UWK_CTL1_IS_P		BIT(6)  /* polarity for ip sleep */
++/* mt8173 etc */
++#define PERI_WK_CTRL1	0x4
++#define WC1_IS_C(x)	(((x) & 0xf) << 26)  /* cycle debounce */
++#define WC1_IS_EN	BIT(25)
++#define WC1_IS_P	BIT(6)  /* polarity for ip sleep */
++
++/* mt2712 etc */
++#define PERI_SSUSB_SPM_CTRL	0x0
++#define SSC_IP_SLEEP_EN	BIT(4)
++#define SSC_SPM_INT_EN		BIT(1)
++
++enum ssusb_uwk_vers {
++	SSUSB_UWK_V1 = 1,
++	SSUSB_UWK_V2,
++};
+ 
+ /*
+  * ip-sleep wakeup mode:
+  * all clocks can be turn off, but power domain should be kept on
+  */
+-static void ssusb_wakeup_ip_sleep_en(struct ssusb_mtk *ssusb)
++static void ssusb_wakeup_ip_sleep_set(struct ssusb_mtk *ssusb, bool enable)
+ {
+-	u32 tmp;
+-	struct regmap *pericfg = ssusb->pericfg;
+-
+-	regmap_read(pericfg, PERI_WK_CTRL1, &tmp);
+-	tmp &= ~UWK_CTL1_IS_P;
+-	tmp &= ~(UWK_CTL1_IS_C(0xf));
+-	tmp |= UWK_CTL1_IS_C(0x8);
+-	regmap_write(pericfg, PERI_WK_CTRL1, tmp);
+-	regmap_write(pericfg, PERI_WK_CTRL1, tmp | UWK_CTL1_IS_E);
+-
+-	regmap_read(pericfg, PERI_WK_CTRL1, &tmp);
+-	dev_dbg(ssusb->dev, "%s(): WK_CTRL1[P6,E25,C26:29]=%#x\n",
+-		__func__, tmp);
+-}
+-
+-static void ssusb_wakeup_ip_sleep_dis(struct ssusb_mtk *ssusb)
+-{
+-	u32 tmp;
+-
+-	regmap_read(ssusb->pericfg, PERI_WK_CTRL1, &tmp);
+-	tmp &= ~UWK_CTL1_IS_E;
+-	regmap_write(ssusb->pericfg, PERI_WK_CTRL1, tmp);
++	u32 reg, msk, val;
++
++	switch (ssusb->uwk_vers) {
++	case SSUSB_UWK_V1:
++		reg = ssusb->uwk_reg_base + PERI_WK_CTRL1;
++		msk = WC1_IS_EN | WC1_IS_C(0xf) | WC1_IS_P;
++		val = enable ? (WC1_IS_EN | WC1_IS_C(0x8)) : 0;
++		break;
++	case SSUSB_UWK_V2:
++		reg = ssusb->uwk_reg_base + PERI_SSUSB_SPM_CTRL;
++		msk = SSC_IP_SLEEP_EN | SSC_SPM_INT_EN;
++		val = enable ? msk : 0;
++		break;
++	default:
++		return;
++	};
++	regmap_update_bits(ssusb->uwk, reg, msk, val);
+ }
+ 
+ int ssusb_wakeup_of_property_parse(struct ssusb_mtk *ssusb,
+ 				struct device_node *dn)
+ {
+-	struct device *dev = ssusb->dev;
++	struct of_phandle_args args;
++	int ret;
+ 
+-	/*
+-	 * Wakeup function is optional, so it is not an error if this property
+-	 * does not exist, and in such case, no need to get relative
+-	 * properties anymore.
+-	 */
+-	ssusb->wakeup_en = of_property_read_bool(dn, "mediatek,enable-wakeup");
+-	if (!ssusb->wakeup_en)
++	/* wakeup function is optional */
++	ssusb->uwk_en = of_property_read_bool(dn, "wakeup-source");
++	if (!ssusb->uwk_en)
+ 		return 0;
+ 
+-	ssusb->pericfg = syscon_regmap_lookup_by_phandle(dn,
+-						"mediatek,syscon-wakeup");
+-	if (IS_ERR(ssusb->pericfg)) {
+-		dev_err(dev, "fail to get pericfg regs\n");
+-		return PTR_ERR(ssusb->pericfg);
+-	}
++	ret = of_parse_phandle_with_fixed_args(dn,
++				"mediatek,syscon-wakeup", 2, 0, &args);
++	if (ret)
++		return ret;
+ 
+-	return 0;
++	ssusb->uwk_reg_base = args.args[0];
++	ssusb->uwk_vers = args.args[1];
++	ssusb->uwk = syscon_node_to_regmap(args.np);
++	of_node_put(args.np);
++	dev_info(ssusb->dev, "uwk - reg:0x%x, version:%d\n",
++			ssusb->uwk_reg_base, ssusb->uwk_vers);
++
++	return PTR_ERR_OR_ZERO(ssusb->uwk);
++}
++
++void ssusb_wakeup_set(struct ssusb_mtk *ssusb, bool enable)
++{
++	if (ssusb->uwk_en)
++		ssusb_wakeup_ip_sleep_set(ssusb, enable);
+ }
+ 
+ static void host_ports_num_get(struct ssusb_mtk *ssusb)
+@@ -244,17 +255,3 @@ void ssusb_host_exit(struct ssusb_mtk *ssusb)
+ 	of_platform_depopulate(ssusb->dev);
+ 	ssusb_host_cleanup(ssusb);
+ }
+-
+-int ssusb_wakeup_enable(struct ssusb_mtk *ssusb)
+-{
+-	if (ssusb->wakeup_en)
+-		ssusb_wakeup_ip_sleep_en(ssusb);
+-
+-	return 0;
+-}
+-
+-void ssusb_wakeup_disable(struct ssusb_mtk *ssusb)
+-{
+-	if (ssusb->wakeup_en)
+-		ssusb_wakeup_ip_sleep_dis(ssusb);
+-}
+diff --git a/drivers/usb/mtu3/mtu3_plat.c b/drivers/usb/mtu3/mtu3_plat.c
+index a2523ead46cf..4cafd4ca8457 100644
+--- a/drivers/usb/mtu3/mtu3_plat.c
++++ b/drivers/usb/mtu3/mtu3_plat.c
+@@ -291,8 +291,10 @@ static int get_ssusb_rscs(struct platform_device *pdev, struct ssusb_mtk *ssusb)
+ 
+ 	/* if host role is supported */
+ 	ret = ssusb_wakeup_of_property_parse(ssusb, node);
+-	if (ret)
++	if (ret) {
++		dev_err(dev, "failed to parse uwk property\n");
+ 		return ret;
++	}
+ 
+ 	/* optional property, ignore the error if it does not exist */
+ 	of_property_read_u32(node, "mediatek,u3p-dis-msk",
+@@ -466,7 +468,7 @@ static int __maybe_unused mtu3_suspend(struct device *dev)
+ 	ssusb_host_disable(ssusb, true);
+ 	ssusb_phy_power_off(ssusb);
+ 	ssusb_clks_disable(ssusb);
+-	ssusb_wakeup_enable(ssusb);
++	ssusb_wakeup_set(ssusb, true);
+ 
+ 	return 0;
+ }
+@@ -482,7 +484,7 @@ static int __maybe_unused mtu3_resume(struct device *dev)
+ 	if (!ssusb->is_host)
+ 		return 0;
+ 
+-	ssusb_wakeup_disable(ssusb);
++	ssusb_wakeup_set(ssusb, false);
+ 	ret = ssusb_clks_enable(ssusb);
+ 	if (ret)
+ 		goto clks_err;
+-- 
+2.11.0
+
diff --git a/target/linux/mediatek/patches-4.14/0189-dt-bindings-usb-mtu3-update-USB-wakeup-properties.patch b/target/linux/mediatek/patches-4.14/0189-dt-bindings-usb-mtu3-update-USB-wakeup-properties.patch
new file mode 100644
index 0000000000..30de3dd162
--- /dev/null
+++ b/target/linux/mediatek/patches-4.14/0189-dt-bindings-usb-mtu3-update-USB-wakeup-properties.patch
@@ -0,0 +1,52 @@
+From 067ad5fd18e2e7e38b77ca94eebaaf8d9a35d842 Mon Sep 17 00:00:00 2001
+From: Chunfeng Yun <chunfeng.yun@mediatek.com>
+Date: Wed, 3 Jan 2018 16:53:19 +0800
+Subject: [PATCH 189/224] dt-bindings: usb: mtu3: update USB wakeup properties
+
+Add two arguments in "mediatek,syscon-wakeup" to support multi
+wakeup glue layer between SSUSB and SPM, and use standard property
+"wakeup-source" to replace the private "mediatek,enable-wakeup"
+
+Signed-off-by: Chunfeng Yun <chunfeng.yun@mediatek.com>
+Reviewed-by: Rob Herring <robh@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ Documentation/devicetree/bindings/usb/mediatek,mtu3.txt | 15 ++++++++++-----
+ 1 file changed, 10 insertions(+), 5 deletions(-)
+
+diff --git a/Documentation/devicetree/bindings/usb/mediatek,mtu3.txt b/Documentation/devicetree/bindings/usb/mediatek,mtu3.txt
+index b2271d8e6b50..d589a1ef96a1 100644
+--- a/Documentation/devicetree/bindings/usb/mediatek,mtu3.txt
++++ b/Documentation/devicetree/bindings/usb/mediatek,mtu3.txt
+@@ -42,9 +42,14 @@ Optional properties:
+  - enable-manual-drd : supports manual dual-role switch via debugfs; usually
+ 	used when receptacle is TYPE-A and also wants to support dual-role
+ 	mode.
+- - mediatek,enable-wakeup : supports ip sleep wakeup used by host mode
+- - mediatek,syscon-wakeup : phandle to syscon used to access USB wakeup
+-	control register, it depends on "mediatek,enable-wakeup".
++ - wakeup-source: enable USB remote wakeup of host mode.
++ - mediatek,syscon-wakeup : phandle to syscon used to access the register
++	of the USB wakeup glue layer between SSUSB and SPM; it depends on
++	"wakeup-source", and has two arguments:
++	- the first one : register base address of the glue layer in syscon;
++	- the second one : hardware version of the glue layer
++		- 1 : used by mt8173 etc
++		- 2 : used by mt2712 etc
+  - mediatek,u3p-dis-msk : mask to disable u3ports, bit0 for u3port0,
+ 	bit1 for u3port1, ... etc;
+ 
+@@ -71,8 +76,8 @@ ssusb: usb@11271000 {
+ 	vbus-supply = <&usb_p0_vbus>;
+ 	extcon = <&extcon_usb>;
+ 	dr_mode = "otg";
+-	mediatek,enable-wakeup;
+-	mediatek,syscon-wakeup = <&pericfg>;
++	wakeup-source;
++	mediatek,syscon-wakeup = <&pericfg 0x400 1>;
+ 	#address-cells = <2>;
+ 	#size-cells = <2>;
+ 	ranges;
+-- 
+2.11.0
+
diff --git a/target/linux/mediatek/patches-4.14/0190-usb-xhci-mtk-supports-remote-wakeup-for-mt2712-with-.patch b/target/linux/mediatek/patches-4.14/0190-usb-xhci-mtk-supports-remote-wakeup-for-mt2712-with-.patch
new file mode 100644
index 0000000000..ba7b834f84
--- /dev/null
+++ b/target/linux/mediatek/patches-4.14/0190-usb-xhci-mtk-supports-remote-wakeup-for-mt2712-with-.patch
@@ -0,0 +1,273 @@
+From e6fe50ef22071fe87ce48f79ab4fe21cbec2081b Mon Sep 17 00:00:00 2001
+From: Chunfeng Yun <chunfeng.yun@mediatek.com>
+Date: Wed, 3 Jan 2018 16:53:20 +0800
+Subject: [PATCH 190/224] usb: xhci-mtk: supports remote wakeup for mt2712 with
+ two xHCI IPs
+
+The old way of usb wakeup only supports platform with single xHCI IP,
+such as mt8173, but mt2712 has two xHCI IPs, so rebuild its flow and
+supports the new glue layer of usb wakeup on mt2712 which is different
+from mt8173.
+Due to there is a hardware bug with the LINE STATE wakeup mode on
+mt8173 which causes wakeup failure by low speed devices, and also
+because IP SLEEP mode can cover all functions of LINE STATE mode,
+it is unused in fact, and will not support it later, so remove it at
+the same time.
+
+Signed-off-by: Chunfeng Yun <chunfeng.yun@mediatek.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/usb/host/xhci-mtk.c | 177 +++++++++++++++-----------------------------
+ drivers/usb/host/xhci-mtk.h |   6 +-
+ 2 files changed, 65 insertions(+), 118 deletions(-)
+
+diff --git a/drivers/usb/host/xhci-mtk.c b/drivers/usb/host/xhci-mtk.c
+index e5caabe7eebe..8e51b3fec386 100644
+--- a/drivers/usb/host/xhci-mtk.c
++++ b/drivers/usb/host/xhci-mtk.c
+@@ -66,26 +66,21 @@
+ /* u2_phy_pll register */
+ #define CTRL_U2_FORCE_PLL_STB	BIT(28)
+ 
+-#define PERI_WK_CTRL0		0x400
+-#define UWK_CTR0_0P_LS_PE	BIT(8)  /* posedge */
+-#define UWK_CTR0_0P_LS_NE	BIT(7)  /* negedge for 0p linestate*/
+-#define UWK_CTL1_1P_LS_C(x)	(((x) & 0xf) << 1)
+-#define UWK_CTL1_1P_LS_E	BIT(0)
+-
+-#define PERI_WK_CTRL1		0x404
+-#define UWK_CTL1_IS_C(x)	(((x) & 0xf) << 26)
+-#define UWK_CTL1_IS_E		BIT(25)
+-#define UWK_CTL1_0P_LS_C(x)	(((x) & 0xf) << 21)
+-#define UWK_CTL1_0P_LS_E	BIT(20)
+-#define UWK_CTL1_IDDIG_C(x)	(((x) & 0xf) << 11)  /* cycle debounce */
+-#define UWK_CTL1_IDDIG_E	BIT(10) /* enable debounce */
+-#define UWK_CTL1_IDDIG_P	BIT(9)  /* polarity */
+-#define UWK_CTL1_0P_LS_P	BIT(7)
+-#define UWK_CTL1_IS_P		BIT(6)  /* polarity for ip sleep */
+-
+-enum ssusb_wakeup_src {
+-	SSUSB_WK_IP_SLEEP = 1,
+-	SSUSB_WK_LINE_STATE = 2,
++/* usb remote wakeup registers in syscon */
++/* mt8173 etc */
++#define PERI_WK_CTRL1	0x4
++#define WC1_IS_C(x)	(((x) & 0xf) << 26)  /* cycle debounce */
++#define WC1_IS_EN	BIT(25)
++#define WC1_IS_P	BIT(6)  /* polarity for ip sleep */
++
++/* mt2712 etc */
++#define PERI_SSUSB_SPM_CTRL	0x0
++#define SSC_IP_SLEEP_EN	BIT(4)
++#define SSC_SPM_INT_EN		BIT(1)
++
++enum ssusb_uwk_vers {
++	SSUSB_UWK_V1 = 1,
++	SSUSB_UWK_V2,
+ };
+ 
+ static int xhci_mtk_host_enable(struct xhci_hcd_mtk *mtk)
+@@ -308,112 +303,58 @@ static void xhci_mtk_clks_disable(struct xhci_hcd_mtk *mtk)
+ }
+ 
+ /* only clocks can be turn off for ip-sleep wakeup mode */
+-static void usb_wakeup_ip_sleep_en(struct xhci_hcd_mtk *mtk)
++static void usb_wakeup_ip_sleep_set(struct xhci_hcd_mtk *mtk, bool enable)
+ {
+-	u32 tmp;
+-	struct regmap *pericfg = mtk->pericfg;
+-
+-	regmap_read(pericfg, PERI_WK_CTRL1, &tmp);
+-	tmp &= ~UWK_CTL1_IS_P;
+-	tmp &= ~(UWK_CTL1_IS_C(0xf));
+-	tmp |= UWK_CTL1_IS_C(0x8);
+-	regmap_write(pericfg, PERI_WK_CTRL1, tmp);
+-	regmap_write(pericfg, PERI_WK_CTRL1, tmp | UWK_CTL1_IS_E);
+-
+-	regmap_read(pericfg, PERI_WK_CTRL1, &tmp);
+-	dev_dbg(mtk->dev, "%s(): WK_CTRL1[P6,E25,C26:29]=%#x\n",
+-		__func__, tmp);
++	u32 reg, msk, val;
++
++	switch (mtk->uwk_vers) {
++	case SSUSB_UWK_V1:
++		reg = mtk->uwk_reg_base + PERI_WK_CTRL1;
++		msk = WC1_IS_EN | WC1_IS_C(0xf) | WC1_IS_P;
++		val = enable ? (WC1_IS_EN | WC1_IS_C(0x8)) : 0;
++		break;
++	case SSUSB_UWK_V2:
++		reg = mtk->uwk_reg_base + PERI_SSUSB_SPM_CTRL;
++		msk = SSC_IP_SLEEP_EN | SSC_SPM_INT_EN;
++		val = enable ? msk : 0;
++		break;
++	default:
++		return;
++	};
++	regmap_update_bits(mtk->uwk, reg, msk, val);
+ }
+ 
+-static void usb_wakeup_ip_sleep_dis(struct xhci_hcd_mtk *mtk)
++static int usb_wakeup_of_property_parse(struct xhci_hcd_mtk *mtk,
++				struct device_node *dn)
+ {
+-	u32 tmp;
++	struct of_phandle_args args;
++	int ret;
+ 
+-	regmap_read(mtk->pericfg, PERI_WK_CTRL1, &tmp);
+-	tmp &= ~UWK_CTL1_IS_E;
+-	regmap_write(mtk->pericfg, PERI_WK_CTRL1, tmp);
+-}
++	/* Wakeup function is optional */
++	mtk->uwk_en = of_property_read_bool(dn, "wakeup-source");
++	if (!mtk->uwk_en)
++		return 0;
+ 
+-/*
+-* for line-state wakeup mode, phy's power should not power-down
+-* and only support cable plug in/out
+-*/
+-static void usb_wakeup_line_state_en(struct xhci_hcd_mtk *mtk)
+-{
+-	u32 tmp;
+-	struct regmap *pericfg = mtk->pericfg;
+-
+-	/* line-state of u2-port0 */
+-	regmap_read(pericfg, PERI_WK_CTRL1, &tmp);
+-	tmp &= ~UWK_CTL1_0P_LS_P;
+-	tmp &= ~(UWK_CTL1_0P_LS_C(0xf));
+-	tmp |= UWK_CTL1_0P_LS_C(0x8);
+-	regmap_write(pericfg, PERI_WK_CTRL1, tmp);
+-	regmap_read(pericfg, PERI_WK_CTRL1, &tmp);
+-	regmap_write(pericfg, PERI_WK_CTRL1, tmp | UWK_CTL1_0P_LS_E);
+-
+-	/* line-state of u2-port1 */
+-	regmap_read(pericfg, PERI_WK_CTRL0, &tmp);
+-	tmp &= ~(UWK_CTL1_1P_LS_C(0xf));
+-	tmp |= UWK_CTL1_1P_LS_C(0x8);
+-	regmap_write(pericfg, PERI_WK_CTRL0, tmp);
+-	regmap_write(pericfg, PERI_WK_CTRL0, tmp | UWK_CTL1_1P_LS_E);
+-}
++	ret = of_parse_phandle_with_fixed_args(dn,
++				"mediatek,syscon-wakeup", 2, 0, &args);
++	if (ret)
++		return ret;
+ 
+-static void usb_wakeup_line_state_dis(struct xhci_hcd_mtk *mtk)
+-{
+-	u32 tmp;
+-	struct regmap *pericfg = mtk->pericfg;
+-
+-	/* line-state of u2-port0 */
+-	regmap_read(pericfg, PERI_WK_CTRL1, &tmp);
+-	tmp &= ~UWK_CTL1_0P_LS_E;
+-	regmap_write(pericfg, PERI_WK_CTRL1, tmp);
+-
+-	/* line-state of u2-port1 */
+-	regmap_read(pericfg, PERI_WK_CTRL0, &tmp);
+-	tmp &= ~UWK_CTL1_1P_LS_E;
+-	regmap_write(pericfg, PERI_WK_CTRL0, tmp);
+-}
++	mtk->uwk_reg_base = args.args[0];
++	mtk->uwk_vers = args.args[1];
++	mtk->uwk = syscon_node_to_regmap(args.np);
++	of_node_put(args.np);
++	dev_info(mtk->dev, "uwk - reg:0x%x, version:%d\n",
++			mtk->uwk_reg_base, mtk->uwk_vers);
+ 
+-static void usb_wakeup_enable(struct xhci_hcd_mtk *mtk)
+-{
+-	if (mtk->wakeup_src == SSUSB_WK_IP_SLEEP)
+-		usb_wakeup_ip_sleep_en(mtk);
+-	else if (mtk->wakeup_src == SSUSB_WK_LINE_STATE)
+-		usb_wakeup_line_state_en(mtk);
+-}
++	return PTR_ERR_OR_ZERO(mtk->uwk);
+ 
+-static void usb_wakeup_disable(struct xhci_hcd_mtk *mtk)
+-{
+-	if (mtk->wakeup_src == SSUSB_WK_IP_SLEEP)
+-		usb_wakeup_ip_sleep_dis(mtk);
+-	else if (mtk->wakeup_src == SSUSB_WK_LINE_STATE)
+-		usb_wakeup_line_state_dis(mtk);
+ }
+ 
+-static int usb_wakeup_of_property_parse(struct xhci_hcd_mtk *mtk,
+-				struct device_node *dn)
++static void usb_wakeup_set(struct xhci_hcd_mtk *mtk, bool enable)
+ {
+-	struct device *dev = mtk->dev;
+-
+-	/*
+-	* wakeup function is optional, so it is not an error if this property
+-	* does not exist, and in such case, no need to get relative
+-	* properties anymore.
+-	*/
+-	of_property_read_u32(dn, "mediatek,wakeup-src", &mtk->wakeup_src);
+-	if (!mtk->wakeup_src)
+-		return 0;
+-
+-	mtk->pericfg = syscon_regmap_lookup_by_phandle(dn,
+-						"mediatek,syscon-wakeup");
+-	if (IS_ERR(mtk->pericfg)) {
+-		dev_err(dev, "fail to get pericfg regs\n");
+-		return PTR_ERR(mtk->pericfg);
+-	}
+-
+-	return 0;
++	if (mtk->uwk_en)
++		usb_wakeup_ip_sleep_set(mtk, enable);
+ }
+ 
+ static int xhci_mtk_setup(struct usb_hcd *hcd);
+@@ -595,8 +536,10 @@ static int xhci_mtk_probe(struct platform_device *pdev)
+ 			     &mtk->u3p_dis_msk);
+ 
+ 	ret = usb_wakeup_of_property_parse(mtk, node);
+-	if (ret)
++	if (ret) {
++		dev_err(dev, "failed to parse uwk property\n");
+ 		return ret;
++	}
+ 
+ 	mtk->num_phys = of_count_phandle_with_args(node,
+ 			"phys", "#phy-cells");
+@@ -780,7 +723,7 @@ static int __maybe_unused xhci_mtk_suspend(struct device *dev)
+ 	xhci_mtk_host_disable(mtk);
+ 	xhci_mtk_phy_power_off(mtk);
+ 	xhci_mtk_clks_disable(mtk);
+-	usb_wakeup_enable(mtk);
++	usb_wakeup_set(mtk, true);
+ 	return 0;
+ }
+ 
+@@ -790,7 +733,7 @@ static int __maybe_unused xhci_mtk_resume(struct device *dev)
+ 	struct usb_hcd *hcd = mtk->hcd;
+ 	struct xhci_hcd *xhci = hcd_to_xhci(hcd);
+ 
+-	usb_wakeup_disable(mtk);
++	usb_wakeup_set(mtk, false);
+ 	xhci_mtk_clks_enable(mtk);
+ 	xhci_mtk_phy_power_on(mtk);
+ 	xhci_mtk_host_enable(mtk);
+diff --git a/drivers/usb/host/xhci-mtk.h b/drivers/usb/host/xhci-mtk.h
+index 45ff5c67efb5..85c007ee1f52 100644
+--- a/drivers/usb/host/xhci-mtk.h
++++ b/drivers/usb/host/xhci-mtk.h
+@@ -131,8 +131,12 @@ struct xhci_hcd_mtk {
+ 	struct regmap *pericfg;
+ 	struct phy **phys;
+ 	int num_phys;
+-	int wakeup_src;
+ 	bool lpm_support;
++	/* usb remote wakeup */
++	bool uwk_en;
++	struct regmap *uwk;
++	u32 uwk_reg_base;
++	u32 uwk_vers;
+ };
+ 
+ static inline struct xhci_hcd_mtk *hcd_to_mtk(struct usb_hcd *hcd)
+-- 
+2.11.0
+
diff --git a/target/linux/mediatek/patches-4.14/0191-usb-xhci-allow-imod-interval-to-be-configurable.patch b/target/linux/mediatek/patches-4.14/0191-usb-xhci-allow-imod-interval-to-be-configurable.patch
new file mode 100644
index 0000000000..8bb6d5c51e
--- /dev/null
+++ b/target/linux/mediatek/patches-4.14/0191-usb-xhci-allow-imod-interval-to-be-configurable.patch
@@ -0,0 +1,155 @@
+From c5c72d252dc8e417388386d5767ea790ee8f5b44 Mon Sep 17 00:00:00 2001
+From: Adam Wallis <awallis@codeaurora.org>
+Date: Fri, 8 Dec 2017 17:59:13 +0200
+Subject: [PATCH 191/224] usb: xhci: allow imod-interval to be configurable
+
+The xHCI driver currently has the IMOD set to 160, which
+translates to an IMOD interval of 40,000ns (160 * 250)ns
+
+Commit 0cbd4b34cda9 ("xhci: mediatek: support MTK xHCI host controller")
+introduced a QUIRK for the MTK platform to adjust this interval to 20,
+which translates to an IMOD interval of 5,000ns (20 * 250)ns. This is
+due to the fact that the MTK controller IMOD interval is 8 times
+as much as defined in xHCI spec.
+
+Instead of adding more quirk bits for additional platforms, this patch
+introduces the ability for vendors to set the IMOD_INTERVAL as is
+optimal for their platform. By using device_property_read_u32() on
+"imod-interval-ns", the IMOD INTERVAL can be specified in nano seconds.
+If no interval is specified, the default of 40,000ns (IMOD=160) will be
+used.
+
+No bounds checking has been implemented due to the fact that a vendor
+may have violated the spec and would need to specify a value outside of
+the max 8,000 IRQs/second limit specified in the xHCI spec.
+
+Tested-by: Chunfeng Yun <chunfeng.yun@mediatek.com>
+Reviewed-by: Rob Herring <robh@kernel.org>
+Signed-off-by: Adam Wallis <awallis@codeaurora.org>
+Signed-off-by: Mathias Nyman <mathias.nyman@linux.intel.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ Documentation/devicetree/bindings/usb/mediatek,mtk-xhci.txt | 2 ++
+ Documentation/devicetree/bindings/usb/usb-xhci.txt          | 1 +
+ drivers/usb/host/xhci-mtk.c                                 | 9 +++++++++
+ drivers/usb/host/xhci-pci.c                                 | 3 +++
+ drivers/usb/host/xhci-plat.c                                | 5 +++++
+ drivers/usb/host/xhci.c                                     | 6 +-----
+ drivers/usb/host/xhci.h                                     | 2 ++
+ 7 files changed, 23 insertions(+), 5 deletions(-)
+
+diff --git a/Documentation/devicetree/bindings/usb/mediatek,mtk-xhci.txt b/Documentation/devicetree/bindings/usb/mediatek,mtk-xhci.txt
+index 30595964876a..9ff560298498 100644
+--- a/Documentation/devicetree/bindings/usb/mediatek,mtk-xhci.txt
++++ b/Documentation/devicetree/bindings/usb/mediatek,mtk-xhci.txt
+@@ -46,6 +46,7 @@ Optional properties:
+  - pinctrl-names : a pinctrl state named "default" must be defined
+  - pinctrl-0 : pin control group
+ 	See: Documentation/devicetree/bindings/pinctrl/pinctrl-bindings.txt
++ - imod-interval-ns: default interrupt moderation interval is 5000ns
+ 
+ Example:
+ usb30: usb@11270000 {
+@@ -66,6 +67,7 @@ usb30: usb@11270000 {
+ 	usb3-lpm-capable;
+ 	mediatek,syscon-wakeup = <&pericfg>;
+ 	mediatek,wakeup-src = <1>;
++	imod-interval-ns = <10000>;
+ };
+ 
+ 2nd: dual-role mode with xHCI driver
+diff --git a/Documentation/devicetree/bindings/usb/usb-xhci.txt b/Documentation/devicetree/bindings/usb/usb-xhci.txt
+index 2d80b60eeabe..2390ae58636b 100644
+--- a/Documentation/devicetree/bindings/usb/usb-xhci.txt
++++ b/Documentation/devicetree/bindings/usb/usb-xhci.txt
+@@ -28,6 +28,7 @@ Optional properties:
+   - clocks: reference to a clock
+   - usb3-lpm-capable: determines if platform is USB3 LPM capable
+   - quirk-broken-port-ped: set if the controller has broken port disable mechanism
++  - imod-interval-ns: default interrupt moderation interval is 5000ns
+ 
+ Example:
+ 	usb@f0931000 {
+diff --git a/drivers/usb/host/xhci-mtk.c b/drivers/usb/host/xhci-mtk.c
+index 8e51b3fec386..8e4495be6592 100644
+--- a/drivers/usb/host/xhci-mtk.c
++++ b/drivers/usb/host/xhci-mtk.c
+@@ -629,6 +629,15 @@ static int xhci_mtk_probe(struct platform_device *pdev)
+ 
+ 	xhci = hcd_to_xhci(hcd);
+ 	xhci->main_hcd = hcd;
++
++	/*
++	 * imod_interval is the interrupt moderation value in nanoseconds.
++	 * The increment interval is 8 times as much as that defined in
++	 * the xHCI spec on MTK's controller.
++	 */
++	xhci->imod_interval = 5000;
++	device_property_read_u32(dev, "imod-interval-ns", &xhci->imod_interval);
++
+ 	xhci->shared_hcd = usb_create_shared_hcd(driver, dev,
+ 			dev_name(dev), hcd);
+ 	if (!xhci->shared_hcd) {
+diff --git a/drivers/usb/host/xhci-pci.c b/drivers/usb/host/xhci-pci.c
+index 8071c8fdd15e..cdd7d7bdfc0f 100644
+--- a/drivers/usb/host/xhci-pci.c
++++ b/drivers/usb/host/xhci-pci.c
+@@ -258,6 +258,9 @@ static int xhci_pci_setup(struct usb_hcd *hcd)
+ 	if (!xhci->sbrn)
+ 		pci_read_config_byte(pdev, XHCI_SBRN_OFFSET, &xhci->sbrn);
+ 
++	/* imod_interval is the interrupt moderation value in nanoseconds. */
++	xhci->imod_interval = 40000;
++
+ 	retval = xhci_gen_setup(hcd, xhci_pci_quirks);
+ 	if (retval)
+ 		return retval;
+diff --git a/drivers/usb/host/xhci-plat.c b/drivers/usb/host/xhci-plat.c
+index 163bafde709f..47230453a876 100644
+--- a/drivers/usb/host/xhci-plat.c
++++ b/drivers/usb/host/xhci-plat.c
+@@ -265,6 +265,11 @@ static int xhci_plat_probe(struct platform_device *pdev)
+ 	if (device_property_read_bool(&pdev->dev, "quirk-broken-port-ped"))
+ 		xhci->quirks |= XHCI_BROKEN_PORT_PED;
+ 
++	/* imod_interval is the interrupt moderation value in nanoseconds. */
++	xhci->imod_interval = 40000;
++	device_property_read_u32(sysdev, "imod-interval-ns",
++				 &xhci->imod_interval);
++
+ 	hcd->usb_phy = devm_usb_get_phy_by_phandle(sysdev, "usb-phy", 0);
+ 	if (IS_ERR(hcd->usb_phy)) {
+ 		ret = PTR_ERR(hcd->usb_phy);
+diff --git a/drivers/usb/host/xhci.c b/drivers/usb/host/xhci.c
+index b2ff1ff1a02f..ac1b26a81e77 100644
+--- a/drivers/usb/host/xhci.c
++++ b/drivers/usb/host/xhci.c
+@@ -597,11 +597,7 @@ int xhci_run(struct usb_hcd *hcd)
+ 			"// Set the interrupt modulation register");
+ 	temp = readl(&xhci->ir_set->irq_control);
+ 	temp &= ~ER_IRQ_INTERVAL_MASK;
+-	/*
+-	 * the increment interval is 8 times as much as that defined
+-	 * in xHCI spec on MTK's controller
+-	 */
+-	temp |= (u32) ((xhci->quirks & XHCI_MTK_HOST) ? 20 : 160);
++	temp |= (xhci->imod_interval / 250) & ER_IRQ_INTERVAL_MASK;
+ 	writel(temp, &xhci->ir_set->irq_control);
+ 
+ 	/* Set the HCD state before we enable the irqs */
+diff --git a/drivers/usb/host/xhci.h b/drivers/usb/host/xhci.h
+index 2abaa4d6d39d..614380af0f96 100644
+--- a/drivers/usb/host/xhci.h
++++ b/drivers/usb/host/xhci.h
+@@ -1723,6 +1723,8 @@ struct xhci_hcd {
+ 	u8		max_interrupters;
+ 	u8		max_ports;
+ 	u8		isoc_threshold;
++	/* imod_interval in ns (I * 250ns) */
++	u32		imod_interval;
+ 	int		event_ring_max;
+ 	/* 4KB min, 128MB max */
+ 	int		page_size;
+-- 
+2.11.0
+
diff --git a/target/linux/mediatek/patches-4.14/0192-dt-bindings-usb-mtk-xhci-update-USB-wakeup-propertie.patch b/target/linux/mediatek/patches-4.14/0192-dt-bindings-usb-mtk-xhci-update-USB-wakeup-propertie.patch
new file mode 100644
index 0000000000..250d647a98
--- /dev/null
+++ b/target/linux/mediatek/patches-4.14/0192-dt-bindings-usb-mtk-xhci-update-USB-wakeup-propertie.patch
@@ -0,0 +1,54 @@
+From bbbbdd36c7311a786d7392f2394b355b1f78cf8b Mon Sep 17 00:00:00 2001
+From: Chunfeng Yun <chunfeng.yun@mediatek.com>
+Date: Wed, 3 Jan 2018 16:53:21 +0800
+Subject: [PATCH 192/224] dt-bindings: usb: mtk-xhci: update USB wakeup
+ properties
+
+Add two arguments in "mediatek,syscon-wakeup" to support multi
+wakeup glue layer between SSUSB and SPM, and use standard property
+"wakeup-source" to replace the private "mediatek,wakeup-src"
+
+Signed-off-by: Chunfeng Yun <chunfeng.yun@mediatek.com>
+Reviewed-by: Rob Herring <robh@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ .../devicetree/bindings/usb/mediatek,mtk-xhci.txt        | 16 ++++++++++------
+ 1 file changed, 10 insertions(+), 6 deletions(-)
+
+diff --git a/Documentation/devicetree/bindings/usb/mediatek,mtk-xhci.txt b/Documentation/devicetree/bindings/usb/mediatek,mtk-xhci.txt
+index 9ff560298498..88d9f4a4b280 100644
+--- a/Documentation/devicetree/bindings/usb/mediatek,mtk-xhci.txt
++++ b/Documentation/devicetree/bindings/usb/mediatek,mtk-xhci.txt
+@@ -35,10 +35,14 @@ Required properties:
+  - phys : a list of phandle + phy specifier pairs
+ 
+ Optional properties:
+- - mediatek,wakeup-src : 1: ip sleep wakeup mode; 2: line state wakeup
+-	mode;
+- - mediatek,syscon-wakeup : phandle to syscon used to access USB wakeup
+-	control register, it depends on "mediatek,wakeup-src".
++ - wakeup-source : enable USB remote wakeup;
++ - mediatek,syscon-wakeup : phandle to syscon used to access the register
++	of the USB wakeup glue layer between xHCI and SPM; it depends on
++	"wakeup-source", and has two arguments:
++	- the first one : register base address of the glue layer in syscon;
++	- the second one : hardware version of the glue layer
++		- 1 : used by mt8173 etc
++		- 2 : used by mt2712 etc
+  - mediatek,u3p-dis-msk : mask to disable u3ports, bit0 for u3port0,
+ 	bit1 for u3port1, ... etc;
+  - vbus-supply : reference to the VBUS regulator;
+@@ -65,8 +69,8 @@ usb30: usb@11270000 {
+ 	vusb33-supply = <&mt6397_vusb_reg>;
+ 	vbus-supply = <&usb_p1_vbus>;
+ 	usb3-lpm-capable;
+-	mediatek,syscon-wakeup = <&pericfg>;
+-	mediatek,wakeup-src = <1>;
++	mediatek,syscon-wakeup = <&pericfg 0x400 1>;
++	wakeup-source;
+ 	imod-interval-ns = <10000>;
+ };
+ 
+-- 
+2.11.0
+
diff --git a/target/linux/mediatek/patches-4.14/0193-clk-mediatek-adjust-dependency-of-reset.c-to-avoid-u.patch b/target/linux/mediatek/patches-4.14/0193-clk-mediatek-adjust-dependency-of-reset.c-to-avoid-u.patch
new file mode 100644
index 0000000000..19527f1a06
--- /dev/null
+++ b/target/linux/mediatek/patches-4.14/0193-clk-mediatek-adjust-dependency-of-reset.c-to-avoid-u.patch
@@ -0,0 +1,77 @@
+From 0f9391b4ee12cad5c93e109b9eb6c0c6298da0d3 Mon Sep 17 00:00:00 2001
+From: Sean Wang <sean.wang@mediatek.com>
+Date: Fri, 5 Jan 2018 16:14:06 +0800
+Subject: [PATCH 193/224] clk: mediatek: adjust dependency of reset.c to avoid
+ unexpectedly being built
+
+Changes from v1->v2:
+Add 'select RESET_CONTROLLER' under COMMON_CLK_MEDIATEK and enable
+reset.c to be built when COMMON_CLK_MEDIATEK is selected. That should
+be quite reasonable because the reset controller is tightly embedded
+inside and exported from these clock subsystems. At least it can be found
+on infracfg and pericfg subsystem that both are really fundamental block
+lots of devices must depend on.
+
+commit 74cb0d6dde8 ("clk: mediatek: fixup test-building of MediaTek clock
+drivers") can let the build system looking into the directory where the
+clock drivers resides and then allow test-building the drivers.
+
+But the change also gives rise to certain incorrect behavior which is
+reset.c being built even not depending on either COMPILE_TEST or
+ARCH_MEDIATEK alternative dependency. To get rid of reset.c being built
+unexpectedly on the other platforms, it would be a good change that the
+file should be built depending on its own specific configuration rather
+than just on generic RESET_CONTROLLER one.
+
+Signed-off-by: Sean Wang <sean.wang@mediatek.com>
+Cc: Jean Delvare <jdelvare@suse.de>
+Signed-off-by: Stephen Boyd <sboyd@codeaurora.org>
+---
+ drivers/clk/mediatek/Kconfig   | 1 +
+ drivers/clk/mediatek/Makefile  | 4 ++--
+ drivers/clk/mediatek/clk-mtk.h | 7 -------
+ 3 files changed, 3 insertions(+), 9 deletions(-)
+
+Index: linux-4.14.25/drivers/clk/mediatek/Kconfig
+===================================================================
+--- linux-4.14.25.orig/drivers/clk/mediatek/Kconfig
++++ linux-4.14.25/drivers/clk/mediatek/Kconfig
+@@ -6,6 +6,7 @@ menu "Clock driver for MediaTek SoC"
+ 
+ config COMMON_CLK_MEDIATEK
+ 	bool
++	select RESET_CONTROLLER
+ 	---help---
+ 	  MediaTek SoCs' clock support.
+ 
+Index: linux-4.14.25/drivers/clk/mediatek/Makefile
+===================================================================
+--- linux-4.14.25.orig/drivers/clk/mediatek/Makefile
++++ linux-4.14.25/drivers/clk/mediatek/Makefile
+@@ -1,6 +1,5 @@
+ # SPDX-License-Identifier: GPL-2.0
+-obj-$(CONFIG_COMMON_CLK_MEDIATEK) += clk-mtk.o clk-pll.o clk-gate.o clk-apmixed.o clk-cpumux.o
+-obj-$(CONFIG_RESET_CONTROLLER) += reset.o
++obj-$(CONFIG_COMMON_CLK_MEDIATEK) += clk-mtk.o clk-pll.o clk-gate.o clk-apmixed.o clk-cpumux.o reset.o
+ obj-$(CONFIG_COMMON_CLK_MT6797) += clk-mt6797.o
+ obj-$(CONFIG_COMMON_CLK_MT6797_IMGSYS) += clk-mt6797-img.o
+ obj-$(CONFIG_COMMON_CLK_MT6797_MMSYS) += clk-mt6797-mm.o
+Index: linux-4.14.25/drivers/clk/mediatek/clk-mtk.h
+===================================================================
+--- linux-4.14.25.orig/drivers/clk/mediatek/clk-mtk.h
++++ linux-4.14.25/drivers/clk/mediatek/clk-mtk.h
+@@ -229,14 +229,7 @@ void mtk_clk_register_plls(struct device
+ struct clk *mtk_clk_register_ref2usb_tx(const char *name,
+ 			const char *parent_name, void __iomem *reg);
+ 
+-#ifdef CONFIG_RESET_CONTROLLER
+ void mtk_register_reset_controller(struct device_node *np,
+ 			unsigned int num_regs, int regofs);
+-#else
+-static inline void mtk_register_reset_controller(struct device_node *np,
+-			unsigned int num_regs, int regofs)
+-{
+-}
+-#endif
+ 
+ #endif /* __DRV_CLK_MTK_H */
diff --git a/target/linux/mediatek/patches-4.14/0194-pinctrl-mediatek-mt7622-fix-potential-uninitialized-.patch b/target/linux/mediatek/patches-4.14/0194-pinctrl-mediatek-mt7622-fix-potential-uninitialized-.patch
new file mode 100644
index 0000000000..a71af5005c
--- /dev/null
+++ b/target/linux/mediatek/patches-4.14/0194-pinctrl-mediatek-mt7622-fix-potential-uninitialized-.patch
@@ -0,0 +1,54 @@
+From cfcb2cc358f3ff466d4c419d8f6fe0263bdc47b1 Mon Sep 17 00:00:00 2001
+From: Sean Wang <sean.wang@mediatek.com>
+Date: Wed, 10 Jan 2018 00:28:24 +0800
+Subject: [PATCH 194/224] pinctrl: mediatek: mt7622: fix potential
+ uninitialized value being returned
+
+commit d6ed93551320 ("pinctrl: mediatek: add pinctrl driver for MT7622
+SoC") leads to the following static checker warning:
+
+drivers/pinctrl/mediatek/pinctrl-mt7622.c:1419 mtk_gpio_get()
+error: uninitialized symbol 'value'.
+1412  static int mtk_gpio_get(struct gpio_chip *chip, unsigned int gpio)
+1413  {
+1414          struct mtk_pinctrl *hw = dev_get_drvdata(chip->parent);
+1415          int value;
+1416
+1417          mtk_hw_get_value(hw, gpio, PINCTRL_PIN_REG_DI, &value);
+^^^^^^^^^^^^^^^^
+1418
+1419          return !!value;
+1420  }
+
+The appropriate error handling must be added to avoid the potential error
+caused by uninitialized value being returned.
+
+Reported-by: Dan Carpenter <dan.carpenter@oracle.com>
+Signed-off-by: Sean Wang <sean.wang@mediatek.com>
+Reviewed-by: Matthias Brugger <matthias.bgg@gmail.com>
+Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
+---
+ drivers/pinctrl/mediatek/pinctrl-mt7622.c | 6 ++++--
+ 1 file changed, 4 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/pinctrl/mediatek/pinctrl-mt7622.c b/drivers/pinctrl/mediatek/pinctrl-mt7622.c
+index 3824d82888ac..dc32e3c3bd73 100644
+--- a/drivers/pinctrl/mediatek/pinctrl-mt7622.c
++++ b/drivers/pinctrl/mediatek/pinctrl-mt7622.c
+@@ -1412,9 +1412,11 @@ static struct pinctrl_desc mtk_desc = {
+ static int mtk_gpio_get(struct gpio_chip *chip, unsigned int gpio)
+ {
+ 	struct mtk_pinctrl *hw = dev_get_drvdata(chip->parent);
+-	int value;
++	int value, err;
+ 
+-	mtk_hw_get_value(hw, gpio, PINCTRL_PIN_REG_DI, &value);
++	err = mtk_hw_get_value(hw, gpio, PINCTRL_PIN_REG_DI, &value);
++	if (err)
++		return err;
+ 
+ 	return !!value;
+ }
+-- 
+2.11.0
+
diff --git a/target/linux/mediatek/patches-4.14/0195-pinctrl-mediatek-mt7622-align-error-handling-of-mtk_.patch b/target/linux/mediatek/patches-4.14/0195-pinctrl-mediatek-mt7622-align-error-handling-of-mtk_.patch
new file mode 100644
index 0000000000..31f25df2f3
--- /dev/null
+++ b/target/linux/mediatek/patches-4.14/0195-pinctrl-mediatek-mt7622-align-error-handling-of-mtk_.patch
@@ -0,0 +1,55 @@
+From 8d3e3f3159284dba7a86788464edd4d5cdba4f06 Mon Sep 17 00:00:00 2001
+From: Sean Wang <sean.wang@mediatek.com>
+Date: Wed, 10 Jan 2018 00:28:25 +0800
+Subject: [PATCH 195/224] pinctrl: mediatek: mt7622: align error handling of
+ mtk_hw_get_value call
+
+Make consistent error handling of all mtk_hw_get_value occurrences using
+propagating error code from the internal instead of creating a new one.
+
+Signed-off-by: Sean Wang <sean.wang@mediatek.com>
+Reviewed-by: Matthias Brugger <matthias.bgg@gmail.com>
+Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
+---
+ drivers/pinctrl/mediatek/pinctrl-mt7622.c | 8 ++++----
+ 1 file changed, 4 insertions(+), 4 deletions(-)
+
+diff --git a/drivers/pinctrl/mediatek/pinctrl-mt7622.c b/drivers/pinctrl/mediatek/pinctrl-mt7622.c
+index dc32e3c3bd73..06e8406c4440 100644
+--- a/drivers/pinctrl/mediatek/pinctrl-mt7622.c
++++ b/drivers/pinctrl/mediatek/pinctrl-mt7622.c
+@@ -1160,7 +1160,7 @@ static int mtk_pinconf_get(struct pinctrl_dev *pctldev,
+ 	case PIN_CONFIG_OUTPUT_ENABLE:
+ 		err = mtk_hw_get_value(hw, pin, PINCTRL_PIN_REG_DIR, &val);
+ 		if (err)
+-			return -EINVAL;
++			return err;
+ 
+ 		/* HW takes input mode as zero; output mode as non-zero */
+ 		if ((val && param == PIN_CONFIG_INPUT_ENABLE) ||
+@@ -1184,11 +1184,11 @@ static int mtk_pinconf_get(struct pinctrl_dev *pctldev,
+ 	case PIN_CONFIG_DRIVE_STRENGTH:
+ 		err = mtk_hw_get_value(hw, pin, PINCTRL_PIN_REG_E4, &val);
+ 		if (err)
+-			return -EINVAL;
++			return err;
+ 
+ 		err = mtk_hw_get_value(hw, pin, PINCTRL_PIN_REG_E8, &val2);
+ 		if (err)
+-			return -EINVAL;
++			return err;
+ 
+ 		/* 4mA when (e8, e4) = (0, 0); 8mA when (e8, e4) = (0, 1)
+ 		 * 12mA when (e8, e4) = (1, 0); 16mA when (e8, e4) = (1, 1)
+@@ -1203,7 +1203,7 @@ static int mtk_pinconf_get(struct pinctrl_dev *pctldev,
+ 
+ 		err = mtk_hw_get_value(hw, pin, reg, &val);
+ 		if (err)
+-			return -EINVAL;
++			return err;
+ 
+ 		ret = val;
+ 
+-- 
+2.11.0
+
diff --git a/target/linux/mediatek/patches-4.14/0196-mtd-mtk-nor-modify-functions-name-more-generally.patch b/target/linux/mediatek/patches-4.14/0196-mtd-mtk-nor-modify-functions-name-more-generally.patch
new file mode 100644
index 0000000000..0840f7678e
--- /dev/null
+++ b/target/linux/mediatek/patches-4.14/0196-mtd-mtk-nor-modify-functions-name-more-generally.patch
@@ -0,0 +1,559 @@
+From 4dab73d46eb58c142b5d2e7039f12e4e5df357ad Mon Sep 17 00:00:00 2001
+From: Guochun Mao <guochun.mao@mediatek.com>
+Date: Mon, 18 Dec 2017 09:47:35 +0800
+Subject: [PATCH 196/224] mtd: mtk-nor: modify functions' name more generally
+
+Since more and more Mediatek's SoC can use this driver to
+control spi-nor flash, functions' name with "mt8173_" is
+no longer properly. Replacing "mt8173_" with "mtk_" will
+be more accurate to describe these functions' usable scope.
+
+Signed-off-by: Guochun Mao <guochun.mao@mediatek.com>
+Signed-off-by: Cyrille Pitchen <cyrille.pitchen@wedev4u.fr>
+---
+ drivers/mtd/spi-nor/mtk-quadspi.c | 240 +++++++++++++++++++-------------------
+ 1 file changed, 120 insertions(+), 120 deletions(-)
+
+diff --git a/drivers/mtd/spi-nor/mtk-quadspi.c b/drivers/mtd/spi-nor/mtk-quadspi.c
+index abe455ccd68b..5442993b71ff 100644
+--- a/drivers/mtd/spi-nor/mtk-quadspi.c
++++ b/drivers/mtd/spi-nor/mtk-quadspi.c
+@@ -110,7 +110,7 @@
+ #define MTK_NOR_PRG_REG(n)		(MTK_NOR_PRGDATA0_REG + 4 * (n))
+ #define MTK_NOR_SHREG(n)		(MTK_NOR_SHREG0_REG + 4 * (n))
+ 
+-struct mt8173_nor {
++struct mtk_nor {
+ 	struct spi_nor nor;
+ 	struct device *dev;
+ 	void __iomem *base;	/* nor flash base address */
+@@ -118,48 +118,48 @@ struct mt8173_nor {
+ 	struct clk *nor_clk;
+ };
+ 
+-static void mt8173_nor_set_read_mode(struct mt8173_nor *mt8173_nor)
++static void mtk_nor_set_read_mode(struct mtk_nor *mtk_nor)
+ {
+-	struct spi_nor *nor = &mt8173_nor->nor;
++	struct spi_nor *nor = &mtk_nor->nor;
+ 
+ 	switch (nor->read_proto) {
+ 	case SNOR_PROTO_1_1_1:
+-		writeb(nor->read_opcode, mt8173_nor->base +
++		writeb(nor->read_opcode, mtk_nor->base +
+ 		       MTK_NOR_PRGDATA3_REG);
+-		writeb(MTK_NOR_FAST_READ, mt8173_nor->base +
++		writeb(MTK_NOR_FAST_READ, mtk_nor->base +
+ 		       MTK_NOR_CFG1_REG);
+ 		break;
+ 	case SNOR_PROTO_1_1_2:
+-		writeb(nor->read_opcode, mt8173_nor->base +
++		writeb(nor->read_opcode, mtk_nor->base +
+ 		       MTK_NOR_PRGDATA3_REG);
+-		writeb(MTK_NOR_DUAL_READ_EN, mt8173_nor->base +
++		writeb(MTK_NOR_DUAL_READ_EN, mtk_nor->base +
+ 		       MTK_NOR_DUAL_REG);
+ 		break;
+ 	case SNOR_PROTO_1_1_4:
+-		writeb(nor->read_opcode, mt8173_nor->base +
++		writeb(nor->read_opcode, mtk_nor->base +
+ 		       MTK_NOR_PRGDATA4_REG);
+-		writeb(MTK_NOR_QUAD_READ_EN, mt8173_nor->base +
++		writeb(MTK_NOR_QUAD_READ_EN, mtk_nor->base +
+ 		       MTK_NOR_DUAL_REG);
+ 		break;
+ 	default:
+-		writeb(MTK_NOR_DUAL_DISABLE, mt8173_nor->base +
++		writeb(MTK_NOR_DUAL_DISABLE, mtk_nor->base +
+ 		       MTK_NOR_DUAL_REG);
+ 		break;
+ 	}
+ }
+ 
+-static int mt8173_nor_execute_cmd(struct mt8173_nor *mt8173_nor, u8 cmdval)
++static int mtk_nor_execute_cmd(struct mtk_nor *mtk_nor, u8 cmdval)
+ {
+ 	int reg;
+ 	u8 val = cmdval & 0x1f;
+ 
+-	writeb(cmdval, mt8173_nor->base + MTK_NOR_CMD_REG);
+-	return readl_poll_timeout(mt8173_nor->base + MTK_NOR_CMD_REG, reg,
++	writeb(cmdval, mtk_nor->base + MTK_NOR_CMD_REG);
++	return readl_poll_timeout(mtk_nor->base + MTK_NOR_CMD_REG, reg,
+ 				  !(reg & val), 100, 10000);
+ }
+ 
+-static int mt8173_nor_do_tx_rx(struct mt8173_nor *mt8173_nor, u8 op,
+-			       u8 *tx, int txlen, u8 *rx, int rxlen)
++static int mtk_nor_do_tx_rx(struct mtk_nor *mtk_nor, u8 op,
++			    u8 *tx, int txlen, u8 *rx, int rxlen)
+ {
+ 	int len = 1 + txlen + rxlen;
+ 	int i, ret, idx;
+@@ -167,26 +167,26 @@ static int mt8173_nor_do_tx_rx(struct mt8173_nor *mt8173_nor, u8 op,
+ 	if (len > MTK_NOR_MAX_SHIFT)
+ 		return -EINVAL;
+ 
+-	writeb(len * 8, mt8173_nor->base + MTK_NOR_CNT_REG);
++	writeb(len * 8, mtk_nor->base + MTK_NOR_CNT_REG);
+ 
+ 	/* start at PRGDATA5, go down to PRGDATA0 */
+ 	idx = MTK_NOR_MAX_RX_TX_SHIFT - 1;
+ 
+ 	/* opcode */
+-	writeb(op, mt8173_nor->base + MTK_NOR_PRG_REG(idx));
++	writeb(op, mtk_nor->base + MTK_NOR_PRG_REG(idx));
+ 	idx--;
+ 
+ 	/* program TX data */
+ 	for (i = 0; i < txlen; i++, idx--)
+-		writeb(tx[i], mt8173_nor->base + MTK_NOR_PRG_REG(idx));
++		writeb(tx[i], mtk_nor->base + MTK_NOR_PRG_REG(idx));
+ 
+ 	/* clear out rest of TX registers */
+ 	while (idx >= 0) {
+-		writeb(0, mt8173_nor->base + MTK_NOR_PRG_REG(idx));
++		writeb(0, mtk_nor->base + MTK_NOR_PRG_REG(idx));
+ 		idx--;
+ 	}
+ 
+-	ret = mt8173_nor_execute_cmd(mt8173_nor, MTK_NOR_PRG_CMD);
++	ret = mtk_nor_execute_cmd(mtk_nor, MTK_NOR_PRG_CMD);
+ 	if (ret)
+ 		return ret;
+ 
+@@ -195,20 +195,20 @@ static int mt8173_nor_do_tx_rx(struct mt8173_nor *mt8173_nor, u8 op,
+ 
+ 	/* read out RX data */
+ 	for (i = 0; i < rxlen; i++, idx--)
+-		rx[i] = readb(mt8173_nor->base + MTK_NOR_SHREG(idx));
++		rx[i] = readb(mtk_nor->base + MTK_NOR_SHREG(idx));
+ 
+ 	return 0;
+ }
+ 
+ /* Do a WRSR (Write Status Register) command */
+-static int mt8173_nor_wr_sr(struct mt8173_nor *mt8173_nor, u8 sr)
++static int mtk_nor_wr_sr(struct mtk_nor *mtk_nor, u8 sr)
+ {
+-	writeb(sr, mt8173_nor->base + MTK_NOR_PRGDATA5_REG);
+-	writeb(8, mt8173_nor->base + MTK_NOR_CNT_REG);
+-	return mt8173_nor_execute_cmd(mt8173_nor, MTK_NOR_WRSR_CMD);
++	writeb(sr, mtk_nor->base + MTK_NOR_PRGDATA5_REG);
++	writeb(8, mtk_nor->base + MTK_NOR_CNT_REG);
++	return mtk_nor_execute_cmd(mtk_nor, MTK_NOR_WRSR_CMD);
+ }
+ 
+-static int mt8173_nor_write_buffer_enable(struct mt8173_nor *mt8173_nor)
++static int mtk_nor_write_buffer_enable(struct mtk_nor *mtk_nor)
+ {
+ 	u8 reg;
+ 
+@@ -216,27 +216,27 @@ static int mt8173_nor_write_buffer_enable(struct mt8173_nor *mt8173_nor)
+ 	 * 0: pre-fetch buffer use for read
+ 	 * 1: pre-fetch buffer use for page program
+ 	 */
+-	writel(MTK_NOR_WR_BUF_ENABLE, mt8173_nor->base + MTK_NOR_CFG2_REG);
+-	return readb_poll_timeout(mt8173_nor->base + MTK_NOR_CFG2_REG, reg,
++	writel(MTK_NOR_WR_BUF_ENABLE, mtk_nor->base + MTK_NOR_CFG2_REG);
++	return readb_poll_timeout(mtk_nor->base + MTK_NOR_CFG2_REG, reg,
+ 				  0x01 == (reg & 0x01), 100, 10000);
+ }
+ 
+-static int mt8173_nor_write_buffer_disable(struct mt8173_nor *mt8173_nor)
++static int mtk_nor_write_buffer_disable(struct mtk_nor *mtk_nor)
+ {
+ 	u8 reg;
+ 
+-	writel(MTK_NOR_WR_BUF_DISABLE, mt8173_nor->base + MTK_NOR_CFG2_REG);
+-	return readb_poll_timeout(mt8173_nor->base + MTK_NOR_CFG2_REG, reg,
++	writel(MTK_NOR_WR_BUF_DISABLE, mtk_nor->base + MTK_NOR_CFG2_REG);
++	return readb_poll_timeout(mtk_nor->base + MTK_NOR_CFG2_REG, reg,
+ 				  MTK_NOR_WR_BUF_DISABLE == (reg & 0x1), 100,
+ 				  10000);
+ }
+ 
+-static void mt8173_nor_set_addr_width(struct mt8173_nor *mt8173_nor)
++static void mtk_nor_set_addr_width(struct mtk_nor *mtk_nor)
+ {
+ 	u8 val;
+-	struct spi_nor *nor = &mt8173_nor->nor;
++	struct spi_nor *nor = &mtk_nor->nor;
+ 
+-	val = readb(mt8173_nor->base + MTK_NOR_DUAL_REG);
++	val = readb(mtk_nor->base + MTK_NOR_DUAL_REG);
+ 
+ 	switch (nor->addr_width) {
+ 	case 3:
+@@ -246,115 +246,115 @@ static void mt8173_nor_set_addr_width(struct mt8173_nor *mt8173_nor)
+ 		val |= MTK_NOR_4B_ADDR_EN;
+ 		break;
+ 	default:
+-		dev_warn(mt8173_nor->dev, "Unexpected address width %u.\n",
++		dev_warn(mtk_nor->dev, "Unexpected address width %u.\n",
+ 			 nor->addr_width);
+ 		break;
+ 	}
+ 
+-	writeb(val, mt8173_nor->base + MTK_NOR_DUAL_REG);
++	writeb(val, mtk_nor->base + MTK_NOR_DUAL_REG);
+ }
+ 
+-static void mt8173_nor_set_addr(struct mt8173_nor *mt8173_nor, u32 addr)
++static void mtk_nor_set_addr(struct mtk_nor *mtk_nor, u32 addr)
+ {
+ 	int i;
+ 
+-	mt8173_nor_set_addr_width(mt8173_nor);
++	mtk_nor_set_addr_width(mtk_nor);
+ 
+ 	for (i = 0; i < 3; i++) {
+-		writeb(addr & 0xff, mt8173_nor->base + MTK_NOR_RADR0_REG + i * 4);
++		writeb(addr & 0xff, mtk_nor->base + MTK_NOR_RADR0_REG + i * 4);
+ 		addr >>= 8;
+ 	}
+ 	/* Last register is non-contiguous */
+-	writeb(addr & 0xff, mt8173_nor->base + MTK_NOR_RADR3_REG);
++	writeb(addr & 0xff, mtk_nor->base + MTK_NOR_RADR3_REG);
+ }
+ 
+-static ssize_t mt8173_nor_read(struct spi_nor *nor, loff_t from, size_t length,
+-			       u_char *buffer)
++static ssize_t mtk_nor_read(struct spi_nor *nor, loff_t from, size_t length,
++			    u_char *buffer)
+ {
+ 	int i, ret;
+ 	int addr = (int)from;
+ 	u8 *buf = (u8 *)buffer;
+-	struct mt8173_nor *mt8173_nor = nor->priv;
++	struct mtk_nor *mtk_nor = nor->priv;
+ 
+ 	/* set mode for fast read mode ,dual mode or quad mode */
+-	mt8173_nor_set_read_mode(mt8173_nor);
+-	mt8173_nor_set_addr(mt8173_nor, addr);
++	mtk_nor_set_read_mode(mtk_nor);
++	mtk_nor_set_addr(mtk_nor, addr);
+ 
+ 	for (i = 0; i < length; i++) {
+-		ret = mt8173_nor_execute_cmd(mt8173_nor, MTK_NOR_PIO_READ_CMD);
++		ret = mtk_nor_execute_cmd(mtk_nor, MTK_NOR_PIO_READ_CMD);
+ 		if (ret < 0)
+ 			return ret;
+-		buf[i] = readb(mt8173_nor->base + MTK_NOR_RDATA_REG);
++		buf[i] = readb(mtk_nor->base + MTK_NOR_RDATA_REG);
+ 	}
+ 	return length;
+ }
+ 
+-static int mt8173_nor_write_single_byte(struct mt8173_nor *mt8173_nor,
+-					int addr, int length, u8 *data)
++static int mtk_nor_write_single_byte(struct mtk_nor *mtk_nor,
++				     int addr, int length, u8 *data)
+ {
+ 	int i, ret;
+ 
+-	mt8173_nor_set_addr(mt8173_nor, addr);
++	mtk_nor_set_addr(mtk_nor, addr);
+ 
+ 	for (i = 0; i < length; i++) {
+-		writeb(*data++, mt8173_nor->base + MTK_NOR_WDATA_REG);
+-		ret = mt8173_nor_execute_cmd(mt8173_nor, MTK_NOR_PIO_WR_CMD);
++		writeb(*data++, mtk_nor->base + MTK_NOR_WDATA_REG);
++		ret = mtk_nor_execute_cmd(mtk_nor, MTK_NOR_PIO_WR_CMD);
+ 		if (ret < 0)
+ 			return ret;
+ 	}
+ 	return 0;
+ }
+ 
+-static int mt8173_nor_write_buffer(struct mt8173_nor *mt8173_nor, int addr,
+-				   const u8 *buf)
++static int mtk_nor_write_buffer(struct mtk_nor *mtk_nor, int addr,
++				const u8 *buf)
+ {
+ 	int i, bufidx, data;
+ 
+-	mt8173_nor_set_addr(mt8173_nor, addr);
++	mtk_nor_set_addr(mtk_nor, addr);
+ 
+ 	bufidx = 0;
+ 	for (i = 0; i < SFLASH_WRBUF_SIZE; i += 4) {
+ 		data = buf[bufidx + 3]<<24 | buf[bufidx + 2]<<16 |
+ 		       buf[bufidx + 1]<<8 | buf[bufidx];
+ 		bufidx += 4;
+-		writel(data, mt8173_nor->base + MTK_NOR_PP_DATA_REG);
++		writel(data, mtk_nor->base + MTK_NOR_PP_DATA_REG);
+ 	}
+-	return mt8173_nor_execute_cmd(mt8173_nor, MTK_NOR_WR_CMD);
++	return mtk_nor_execute_cmd(mtk_nor, MTK_NOR_WR_CMD);
+ }
+ 
+-static ssize_t mt8173_nor_write(struct spi_nor *nor, loff_t to, size_t len,
+-				const u_char *buf)
++static ssize_t mtk_nor_write(struct spi_nor *nor, loff_t to, size_t len,
++			     const u_char *buf)
+ {
+ 	int ret;
+-	struct mt8173_nor *mt8173_nor = nor->priv;
++	struct mtk_nor *mtk_nor = nor->priv;
+ 	size_t i;
+ 
+-	ret = mt8173_nor_write_buffer_enable(mt8173_nor);
++	ret = mtk_nor_write_buffer_enable(mtk_nor);
+ 	if (ret < 0) {
+-		dev_warn(mt8173_nor->dev, "write buffer enable failed!\n");
++		dev_warn(mtk_nor->dev, "write buffer enable failed!\n");
+ 		return ret;
+ 	}
+ 
+ 	for (i = 0; i + SFLASH_WRBUF_SIZE <= len; i += SFLASH_WRBUF_SIZE) {
+-		ret = mt8173_nor_write_buffer(mt8173_nor, to, buf);
++		ret = mtk_nor_write_buffer(mtk_nor, to, buf);
+ 		if (ret < 0) {
+-			dev_err(mt8173_nor->dev, "write buffer failed!\n");
++			dev_err(mtk_nor->dev, "write buffer failed!\n");
+ 			return ret;
+ 		}
+ 		to += SFLASH_WRBUF_SIZE;
+ 		buf += SFLASH_WRBUF_SIZE;
+ 	}
+-	ret = mt8173_nor_write_buffer_disable(mt8173_nor);
++	ret = mtk_nor_write_buffer_disable(mtk_nor);
+ 	if (ret < 0) {
+-		dev_warn(mt8173_nor->dev, "write buffer disable failed!\n");
++		dev_warn(mtk_nor->dev, "write buffer disable failed!\n");
+ 		return ret;
+ 	}
+ 
+ 	if (i < len) {
+-		ret = mt8173_nor_write_single_byte(mt8173_nor, to,
+-						   (int)(len - i), (u8 *)buf);
++		ret = mtk_nor_write_single_byte(mtk_nor, to,
++						(int)(len - i), (u8 *)buf);
+ 		if (ret < 0) {
+-			dev_err(mt8173_nor->dev, "write single byte failed!\n");
++			dev_err(mtk_nor->dev, "write single byte failed!\n");
+ 			return ret;
+ 		}
+ 	}
+@@ -362,72 +362,72 @@ static ssize_t mt8173_nor_write(struct spi_nor *nor, loff_t to, size_t len,
+ 	return len;
+ }
+ 
+-static int mt8173_nor_read_reg(struct spi_nor *nor, u8 opcode, u8 *buf, int len)
++static int mtk_nor_read_reg(struct spi_nor *nor, u8 opcode, u8 *buf, int len)
+ {
+ 	int ret;
+-	struct mt8173_nor *mt8173_nor = nor->priv;
++	struct mtk_nor *mtk_nor = nor->priv;
+ 
+ 	switch (opcode) {
+ 	case SPINOR_OP_RDSR:
+-		ret = mt8173_nor_execute_cmd(mt8173_nor, MTK_NOR_RDSR_CMD);
++		ret = mtk_nor_execute_cmd(mtk_nor, MTK_NOR_RDSR_CMD);
+ 		if (ret < 0)
+ 			return ret;
+ 		if (len == 1)
+-			*buf = readb(mt8173_nor->base + MTK_NOR_RDSR_REG);
++			*buf = readb(mtk_nor->base + MTK_NOR_RDSR_REG);
+ 		else
+-			dev_err(mt8173_nor->dev, "len should be 1 for read status!\n");
++			dev_err(mtk_nor->dev, "len should be 1 for read status!\n");
+ 		break;
+ 	default:
+-		ret = mt8173_nor_do_tx_rx(mt8173_nor, opcode, NULL, 0, buf, len);
++		ret = mtk_nor_do_tx_rx(mtk_nor, opcode, NULL, 0, buf, len);
+ 		break;
+ 	}
+ 	return ret;
+ }
+ 
+-static int mt8173_nor_write_reg(struct spi_nor *nor, u8 opcode, u8 *buf,
+-				int len)
++static int mtk_nor_write_reg(struct spi_nor *nor, u8 opcode, u8 *buf,
++			     int len)
+ {
+ 	int ret;
+-	struct mt8173_nor *mt8173_nor = nor->priv;
++	struct mtk_nor *mtk_nor = nor->priv;
+ 
+ 	switch (opcode) {
+ 	case SPINOR_OP_WRSR:
+ 		/* We only handle 1 byte */
+-		ret = mt8173_nor_wr_sr(mt8173_nor, *buf);
++		ret = mtk_nor_wr_sr(mtk_nor, *buf);
+ 		break;
+ 	default:
+-		ret = mt8173_nor_do_tx_rx(mt8173_nor, opcode, buf, len, NULL, 0);
++		ret = mtk_nor_do_tx_rx(mtk_nor, opcode, buf, len, NULL, 0);
+ 		if (ret)
+-			dev_warn(mt8173_nor->dev, "write reg failure!\n");
++			dev_warn(mtk_nor->dev, "write reg failure!\n");
+ 		break;
+ 	}
+ 	return ret;
+ }
+ 
+-static void mt8173_nor_disable_clk(struct mt8173_nor *mt8173_nor)
++static void mtk_nor_disable_clk(struct mtk_nor *mtk_nor)
+ {
+-	clk_disable_unprepare(mt8173_nor->spi_clk);
+-	clk_disable_unprepare(mt8173_nor->nor_clk);
++	clk_disable_unprepare(mtk_nor->spi_clk);
++	clk_disable_unprepare(mtk_nor->nor_clk);
+ }
+ 
+-static int mt8173_nor_enable_clk(struct mt8173_nor *mt8173_nor)
++static int mtk_nor_enable_clk(struct mtk_nor *mtk_nor)
+ {
+ 	int ret;
+ 
+-	ret = clk_prepare_enable(mt8173_nor->spi_clk);
++	ret = clk_prepare_enable(mtk_nor->spi_clk);
+ 	if (ret)
+ 		return ret;
+ 
+-	ret = clk_prepare_enable(mt8173_nor->nor_clk);
++	ret = clk_prepare_enable(mtk_nor->nor_clk);
+ 	if (ret) {
+-		clk_disable_unprepare(mt8173_nor->spi_clk);
++		clk_disable_unprepare(mtk_nor->spi_clk);
+ 		return ret;
+ 	}
+ 
+ 	return 0;
+ }
+ 
+-static int mtk_nor_init(struct mt8173_nor *mt8173_nor,
++static int mtk_nor_init(struct mtk_nor *mtk_nor,
+ 			struct device_node *flash_node)
+ {
+ 	const struct spi_nor_hwcaps hwcaps = {
+@@ -439,18 +439,18 @@ static int mtk_nor_init(struct mt8173_nor *mt8173_nor,
+ 	struct spi_nor *nor;
+ 
+ 	/* initialize controller to accept commands */
+-	writel(MTK_NOR_ENABLE_SF_CMD, mt8173_nor->base + MTK_NOR_WRPROT_REG);
++	writel(MTK_NOR_ENABLE_SF_CMD, mtk_nor->base + MTK_NOR_WRPROT_REG);
+ 
+-	nor = &mt8173_nor->nor;
+-	nor->dev = mt8173_nor->dev;
+-	nor->priv = mt8173_nor;
++	nor = &mtk_nor->nor;
++	nor->dev = mtk_nor->dev;
++	nor->priv = mtk_nor;
+ 	spi_nor_set_flash_node(nor, flash_node);
+ 
+ 	/* fill the hooks to spi nor */
+-	nor->read = mt8173_nor_read;
+-	nor->read_reg = mt8173_nor_read_reg;
+-	nor->write = mt8173_nor_write;
+-	nor->write_reg = mt8173_nor_write_reg;
++	nor->read = mtk_nor_read;
++	nor->read_reg = mtk_nor_read_reg;
++	nor->write = mtk_nor_write;
++	nor->write_reg = mtk_nor_write_reg;
+ 	nor->mtd.name = "mtk_nor";
+ 	/* initialized with NULL */
+ 	ret = spi_nor_scan(nor, NULL, &hwcaps);
+@@ -465,34 +465,34 @@ static int mtk_nor_drv_probe(struct platform_device *pdev)
+ 	struct device_node *flash_np;
+ 	struct resource *res;
+ 	int ret;
+-	struct mt8173_nor *mt8173_nor;
++	struct mtk_nor *mtk_nor;
+ 
+ 	if (!pdev->dev.of_node) {
+ 		dev_err(&pdev->dev, "No DT found\n");
+ 		return -EINVAL;
+ 	}
+ 
+-	mt8173_nor = devm_kzalloc(&pdev->dev, sizeof(*mt8173_nor), GFP_KERNEL);
+-	if (!mt8173_nor)
++	mtk_nor = devm_kzalloc(&pdev->dev, sizeof(*mtk_nor), GFP_KERNEL);
++	if (!mtk_nor)
+ 		return -ENOMEM;
+-	platform_set_drvdata(pdev, mt8173_nor);
++	platform_set_drvdata(pdev, mtk_nor);
+ 
+ 	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+-	mt8173_nor->base = devm_ioremap_resource(&pdev->dev, res);
+-	if (IS_ERR(mt8173_nor->base))
+-		return PTR_ERR(mt8173_nor->base);
++	mtk_nor->base = devm_ioremap_resource(&pdev->dev, res);
++	if (IS_ERR(mtk_nor->base))
++		return PTR_ERR(mtk_nor->base);
+ 
+-	mt8173_nor->spi_clk = devm_clk_get(&pdev->dev, "spi");
+-	if (IS_ERR(mt8173_nor->spi_clk))
+-		return PTR_ERR(mt8173_nor->spi_clk);
++	mtk_nor->spi_clk = devm_clk_get(&pdev->dev, "spi");
++	if (IS_ERR(mtk_nor->spi_clk))
++		return PTR_ERR(mtk_nor->spi_clk);
+ 
+-	mt8173_nor->nor_clk = devm_clk_get(&pdev->dev, "sf");
+-	if (IS_ERR(mt8173_nor->nor_clk))
+-		return PTR_ERR(mt8173_nor->nor_clk);
++	mtk_nor->nor_clk = devm_clk_get(&pdev->dev, "sf");
++	if (IS_ERR(mtk_nor->nor_clk))
++		return PTR_ERR(mtk_nor->nor_clk);
+ 
+-	mt8173_nor->dev = &pdev->dev;
++	mtk_nor->dev = &pdev->dev;
+ 
+-	ret = mt8173_nor_enable_clk(mt8173_nor);
++	ret = mtk_nor_enable_clk(mtk_nor);
+ 	if (ret)
+ 		return ret;
+ 
+@@ -503,20 +503,20 @@ static int mtk_nor_drv_probe(struct platform_device *pdev)
+ 		ret = -ENODEV;
+ 		goto nor_free;
+ 	}
+-	ret = mtk_nor_init(mt8173_nor, flash_np);
++	ret = mtk_nor_init(mtk_nor, flash_np);
+ 
+ nor_free:
+ 	if (ret)
+-		mt8173_nor_disable_clk(mt8173_nor);
++		mtk_nor_disable_clk(mtk_nor);
+ 
+ 	return ret;
+ }
+ 
+ static int mtk_nor_drv_remove(struct platform_device *pdev)
+ {
+-	struct mt8173_nor *mt8173_nor = platform_get_drvdata(pdev);
++	struct mtk_nor *mtk_nor = platform_get_drvdata(pdev);
+ 
+-	mt8173_nor_disable_clk(mt8173_nor);
++	mtk_nor_disable_clk(mtk_nor);
+ 
+ 	return 0;
+ }
+@@ -524,18 +524,18 @@ static int mtk_nor_drv_remove(struct platform_device *pdev)
+ #ifdef CONFIG_PM_SLEEP
+ static int mtk_nor_suspend(struct device *dev)
+ {
+-	struct mt8173_nor *mt8173_nor = dev_get_drvdata(dev);
++	struct mtk_nor *mtk_nor = dev_get_drvdata(dev);
+ 
+-	mt8173_nor_disable_clk(mt8173_nor);
++	mtk_nor_disable_clk(mtk_nor);
+ 
+ 	return 0;
+ }
+ 
+ static int mtk_nor_resume(struct device *dev)
+ {
+-	struct mt8173_nor *mt8173_nor = dev_get_drvdata(dev);
++	struct mtk_nor *mtk_nor = dev_get_drvdata(dev);
+ 
+-	return mt8173_nor_enable_clk(mt8173_nor);
++	return mtk_nor_enable_clk(mtk_nor);
+ }
+ 
+ static const struct dev_pm_ops mtk_nor_dev_pm_ops = {
+-- 
+2.11.0
+
diff --git a/target/linux/mediatek/patches-4.14/0197-hwrng-mediatek-Setup-default-RNG-quality.patch b/target/linux/mediatek/patches-4.14/0197-hwrng-mediatek-Setup-default-RNG-quality.patch
new file mode 100644
index 0000000000..a766169cc2
--- /dev/null
+++ b/target/linux/mediatek/patches-4.14/0197-hwrng-mediatek-Setup-default-RNG-quality.patch
@@ -0,0 +1,30 @@
+From cd4a7d700a148f89d599ebe53fd97dc64193683a Mon Sep 17 00:00:00 2001
+From: Sean Wang <sean.wang@mediatek.com>
+Date: Wed, 10 Jan 2018 12:02:46 +0800
+Subject: [PATCH 197/224] hwrng: mediatek - Setup default RNG quality
+
+When hw_random device's quality is non-zero, it will automatically fill
+the kernel's entropy pool at boot.  For the purpose, one conservative
+quality value is being picked up as the default value.
+
+Signed-off-by: Sean Wang <sean.wang@mediatek.com>
+Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
+---
+ drivers/char/hw_random/mtk-rng.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/drivers/char/hw_random/mtk-rng.c b/drivers/char/hw_random/mtk-rng.c
+index 8da7bcf54105..7f99cd52b40e 100644
+--- a/drivers/char/hw_random/mtk-rng.c
++++ b/drivers/char/hw_random/mtk-rng.c
+@@ -135,6 +135,7 @@ static int mtk_rng_probe(struct platform_device *pdev)
+ #endif
+ 	priv->rng.read = mtk_rng_read;
+ 	priv->rng.priv = (unsigned long)&pdev->dev;
++	priv->rng.quality = 900;
+ 
+ 	priv->clk = devm_clk_get(&pdev->dev, "rng");
+ 	if (IS_ERR(priv->clk)) {
+-- 
+2.11.0
+
diff --git a/target/linux/mediatek/patches-4.14/0198-dt-bindings-thermal-add-binding-for-MT7622-SoC.patch b/target/linux/mediatek/patches-4.14/0198-dt-bindings-thermal-add-binding-for-MT7622-SoC.patch
new file mode 100644
index 0000000000..068dafda70
--- /dev/null
+++ b/target/linux/mediatek/patches-4.14/0198-dt-bindings-thermal-add-binding-for-MT7622-SoC.patch
@@ -0,0 +1,31 @@
+From bdaa6312375055d3e104869ca04cc463ac0a33d1 Mon Sep 17 00:00:00 2001
+From: Sean Wang <sean.wang@mediatek.com>
+Date: Wed, 17 Jan 2018 00:00:39 +0800
+Subject: [PATCH 198/224] dt-bindings: thermal: add binding for MT7622 SoC
+
+Add devicetree bindings for MediaTek MT7622 thermal controller
+
+Changes v1 -> v2: add tag from Rob
+
+Signed-off-by: Sean Wang <sean.wang@mediatek.com>
+Signed-off-by: Shunli Wang <shunli.wang@mediatek.com>
+Reviewed-by: Rob Herring <robh@kernel.org>
+---
+ Documentation/devicetree/bindings/thermal/mediatek-thermal.txt | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/Documentation/devicetree/bindings/thermal/mediatek-thermal.txt b/Documentation/devicetree/bindings/thermal/mediatek-thermal.txt
+index 0d73ea5e9c0c..41d6a443ad66 100644
+--- a/Documentation/devicetree/bindings/thermal/mediatek-thermal.txt
++++ b/Documentation/devicetree/bindings/thermal/mediatek-thermal.txt
+@@ -12,6 +12,7 @@ Required properties:
+   - "mediatek,mt8173-thermal" : For MT8173 family of SoCs
+   - "mediatek,mt2701-thermal" : For MT2701 family of SoCs
+   - "mediatek,mt2712-thermal" : For MT2712 family of SoCs
++  - "mediatek,mt7622-thermal" : For MT7622 SoC
+ - reg: Address range of the thermal controller
+ - interrupts: IRQ for the thermal controller
+ - clocks, clock-names: Clocks needed for the thermal controller. required
+-- 
+2.11.0
+
diff --git a/target/linux/mediatek/patches-4.14/0199-thermal-mtk-Cleanup-unused-defines.patch b/target/linux/mediatek/patches-4.14/0199-thermal-mtk-Cleanup-unused-defines.patch
new file mode 100644
index 0000000000..d028e4586c
--- /dev/null
+++ b/target/linux/mediatek/patches-4.14/0199-thermal-mtk-Cleanup-unused-defines.patch
@@ -0,0 +1,56 @@
+From 8bf9b7eeef3f5f4866d66878db75b6b944a8eab4 Mon Sep 17 00:00:00 2001
+From: Matthias Brugger <matthias.bgg@gmail.com>
+Date: Fri, 1 Dec 2017 11:43:21 +0100
+Subject: [PATCH 199/224] thermal: mtk: Cleanup unused defines
+
+The mtk_thermal has some defiens which are never used within the driver.
+This patch delets them.
+
+Signed-off-by: Matthias Brugger <mbrugger@suse.com>
+Acked-by: Daniel Lezcano <daniel.lezcano@linaro.org>
+Signed-off-by: Eduardo Valentin <edubezval@gmail.com>
+---
+ drivers/thermal/mtk_thermal.c | 9 +--------
+ 1 file changed, 1 insertion(+), 8 deletions(-)
+
+diff --git a/drivers/thermal/mtk_thermal.c b/drivers/thermal/mtk_thermal.c
+index 1e61c09153c9..c75661a3801a 100644
+--- a/drivers/thermal/mtk_thermal.c
++++ b/drivers/thermal/mtk_thermal.c
+@@ -32,15 +32,10 @@
+ #include <linux/types.h>
+ 
+ /* AUXADC Registers */
+-#define AUXADC_CON0_V		0x000
+-#define AUXADC_CON1_V		0x004
+ #define AUXADC_CON1_SET_V	0x008
+ #define AUXADC_CON1_CLR_V	0x00c
+ #define AUXADC_CON2_V		0x010
+ #define AUXADC_DATA(channel)	(0x14 + (channel) * 4)
+-#define AUXADC_MISC_V		0x094
+-
+-#define AUXADC_CON1_CHANNEL(x)	BIT(x)
+ 
+ #define APMIXED_SYS_TS_CON1	0x604
+ 
+@@ -158,8 +153,6 @@
+ /* The number of sensing points per bank */
+ #define MT2712_NUM_SENSORS_PER_ZONE	4
+ 
+-#define THERMAL_NAME    "mtk-thermal"
+-
+ struct mtk_thermal;
+ 
+ struct thermal_bank_cfg {
+@@ -765,7 +758,7 @@ static struct platform_driver mtk_thermal_driver = {
+ 	.probe = mtk_thermal_probe,
+ 	.remove = mtk_thermal_remove,
+ 	.driver = {
+-		.name = THERMAL_NAME,
++		.name = "mtk-thermal",
+ 		.of_match_table = mtk_thermal_of_match,
+ 	},
+ };
+-- 
+2.11.0
+
diff --git a/target/linux/mediatek/patches-4.14/0200-thermal-mediatek-add-support-for-MT7622-SoC.patch b/target/linux/mediatek/patches-4.14/0200-thermal-mediatek-add-support-for-MT7622-SoC.patch
new file mode 100644
index 0000000000..4f31eb8d65
--- /dev/null
+++ b/target/linux/mediatek/patches-4.14/0200-thermal-mediatek-add-support-for-MT7622-SoC.patch
@@ -0,0 +1,86 @@
+From b93889b200a963acde20e559dbf51886ad6b6229 Mon Sep 17 00:00:00 2001
+From: Sean Wang <sean.wang@mediatek.com>
+Date: Tue, 16 Jan 2018 23:50:48 +0800
+Subject: [PATCH 200/224] thermal: mediatek: add support for MT7622 SoC
+
+MT7622 SoC has built-in thermal controller with one sensing point, the
+patch just is to extend the functionality of the existing logic.
+
+Changes v1 -> v2: rebase to 4.16-rc1
+
+Signed-off-by: Sean Wang <sean.wang@mediatek.com>
+Signed-off-by: Shunli Wang <shunli.wang@mediatek.com>
+---
+ drivers/thermal/mtk_thermal.c | 35 +++++++++++++++++++++++++++++++++++
+ 1 file changed, 35 insertions(+)
+
+diff --git a/drivers/thermal/mtk_thermal.c b/drivers/thermal/mtk_thermal.c
+index c75661a3801a..e709acb2235e 100644
+--- a/drivers/thermal/mtk_thermal.c
++++ b/drivers/thermal/mtk_thermal.c
+@@ -153,6 +153,12 @@
+ /* The number of sensing points per bank */
+ #define MT2712_NUM_SENSORS_PER_ZONE	4
+ 
++#define MT7622_TEMP_AUXADC_CHANNEL	11
++#define MT7622_NUM_SENSORS		1
++#define MT7622_NUM_ZONES		1
++#define MT7622_NUM_SENSORS_PER_ZONE	1
++#define MT7622_TS1	0
++
+ struct mtk_thermal;
+ 
+ struct thermal_bank_cfg {
+@@ -242,6 +248,12 @@ static const int mt2712_adcpnp[MT2712_NUM_SENSORS_PER_ZONE] = {
+ 
+ static const int mt2712_mux_values[MT2712_NUM_SENSORS] = { 0, 1, 2, 3 };
+ 
++/* MT7622 thermal sensor data */
++static const int mt7622_bank_data[MT7622_NUM_SENSORS] = { MT7622_TS1, };
++static const int mt7622_msr[MT7622_NUM_SENSORS_PER_ZONE] = { TEMP_MSR0, };
++static const int mt7622_adcpnp[MT7622_NUM_SENSORS_PER_ZONE] = { TEMP_ADCPNP0, };
++static const int mt7622_mux_values[MT7622_NUM_SENSORS] = { 0, };
++
+ /**
+  * The MT8173 thermal controller has four banks. Each bank can read up to
+  * four temperature sensors simultaneously. The MT8173 has a total of 5
+@@ -329,6 +341,25 @@ static const struct mtk_thermal_data mt2712_thermal_data = {
+ 	.sensor_mux_values = mt2712_mux_values,
+ };
+ 
++/*
++ * MT7622 have only one sensing point which uses AUXADC Channel 11 for raw data
++ * access.
++ */
++static const struct mtk_thermal_data mt7622_thermal_data = {
++	.auxadc_channel = MT7622_TEMP_AUXADC_CHANNEL,
++	.num_banks = MT7622_NUM_ZONES,
++	.num_sensors = MT7622_NUM_SENSORS,
++	.bank_data = {
++		{
++			.num_sensors = 1,
++			.sensors = mt7622_bank_data,
++		},
++	},
++	.msr = mt7622_msr,
++	.adcpnp = mt7622_adcpnp,
++	.sensor_mux_values = mt7622_mux_values,
++};
++
+ /**
+  * raw_to_mcelsius - convert a raw ADC value to mcelsius
+  * @mt:		The thermal controller
+@@ -631,6 +662,10 @@ static const struct of_device_id mtk_thermal_of_match[] = {
+ 	{
+ 		.compatible = "mediatek,mt2712-thermal",
+ 		.data = (void *)&mt2712_thermal_data,
++	},
++	{
++		.compatible = "mediatek,mt7622-thermal",
++		.data = (void *)&mt7622_thermal_data,
+ 	}, {
+ 	},
+ };
+-- 
+2.11.0
+
diff --git a/target/linux/mediatek/patches-4.14/0201-dt-bindings-clock-mediatek-add-missing-required-rese.patch b/target/linux/mediatek/patches-4.14/0201-dt-bindings-clock-mediatek-add-missing-required-rese.patch
new file mode 100644
index 0000000000..601e5b9855
--- /dev/null
+++ b/target/linux/mediatek/patches-4.14/0201-dt-bindings-clock-mediatek-add-missing-required-rese.patch
@@ -0,0 +1,73 @@
+From 4a1990ee249df257848f9583cef71478e3411c3e Mon Sep 17 00:00:00 2001
+From: Sean Wang <sean.wang@mediatek.com>
+Date: Thu, 28 Dec 2017 11:24:45 +0800
+Subject: [PATCH 201/224] dt-bindings: clock: mediatek: add missing required
+ #reset-cells
+
+All ethsys, pciesys and ssusbsys internally include reset controller, so
+explicitly add back these missing cell definitions to related bindings
+and examples.
+
+Signed-off-by: Sean Wang <sean.wang@mediatek.com>
+Cc: Rob Herring <robh@kernel.org>
+Cc: Michael Turquette <mturquette@baylibre.com>
+Cc: Stephen Boyd <sboyd@codeaurora.org>
+Cc: linux-clk@vger.kernel.org
+Reviewed-by: Rob Herring <robh@kernel.org>
+---
+ Documentation/devicetree/bindings/arm/mediatek/mediatek,ethsys.txt   | 1 +
+ Documentation/devicetree/bindings/arm/mediatek/mediatek,pciesys.txt  | 2 ++
+ Documentation/devicetree/bindings/arm/mediatek/mediatek,ssusbsys.txt | 2 ++
+ 3 files changed, 5 insertions(+)
+
+diff --git a/Documentation/devicetree/bindings/arm/mediatek/mediatek,ethsys.txt b/Documentation/devicetree/bindings/arm/mediatek/mediatek,ethsys.txt
+index 7aa3fa167668..52757adf86bb 100644
+--- a/Documentation/devicetree/bindings/arm/mediatek/mediatek,ethsys.txt
++++ b/Documentation/devicetree/bindings/arm/mediatek/mediatek,ethsys.txt
+@@ -9,6 +9,7 @@ Required Properties:
+ 	- "mediatek,mt2701-ethsys", "syscon"
+ 	- "mediatek,mt7622-ethsys", "syscon"
+ - #clock-cells: Must be 1
++- #reset-cells: Must be 1
+ 
+ The ethsys controller uses the common clk binding from
+ Documentation/devicetree/bindings/clock/clock-bindings.txt
+diff --git a/Documentation/devicetree/bindings/arm/mediatek/mediatek,pciesys.txt b/Documentation/devicetree/bindings/arm/mediatek/mediatek,pciesys.txt
+index d5d5f1227665..7fe5dc6097a6 100644
+--- a/Documentation/devicetree/bindings/arm/mediatek/mediatek,pciesys.txt
++++ b/Documentation/devicetree/bindings/arm/mediatek/mediatek,pciesys.txt
+@@ -8,6 +8,7 @@ Required Properties:
+ - compatible: Should be:
+ 	- "mediatek,mt7622-pciesys", "syscon"
+ - #clock-cells: Must be 1
++- #reset-cells: Must be 1
+ 
+ The PCIESYS controller uses the common clk binding from
+ Documentation/devicetree/bindings/clock/clock-bindings.txt
+@@ -19,4 +20,5 @@ pciesys: pciesys@1a100800 {
+ 	compatible = "mediatek,mt7622-pciesys", "syscon";
+ 	reg = <0 0x1a100800 0 0x1000>;
+ 	#clock-cells = <1>;
++	#reset-cells = <1>;
+ };
+diff --git a/Documentation/devicetree/bindings/arm/mediatek/mediatek,ssusbsys.txt b/Documentation/devicetree/bindings/arm/mediatek/mediatek,ssusbsys.txt
+index 00760019da00..b8184da2508c 100644
+--- a/Documentation/devicetree/bindings/arm/mediatek/mediatek,ssusbsys.txt
++++ b/Documentation/devicetree/bindings/arm/mediatek/mediatek,ssusbsys.txt
+@@ -8,6 +8,7 @@ Required Properties:
+ - compatible: Should be:
+ 	- "mediatek,mt7622-ssusbsys", "syscon"
+ - #clock-cells: Must be 1
++- #reset-cells: Must be 1
+ 
+ The SSUSBSYS controller uses the common clk binding from
+ Documentation/devicetree/bindings/clock/clock-bindings.txt
+@@ -19,4 +20,5 @@ ssusbsys: ssusbsys@1a000000 {
+ 	compatible = "mediatek,mt7622-ssusbsys", "syscon";
+ 	reg = <0 0x1a000000 0 0x1000>;
+ 	#clock-cells = <1>;
++	#reset-cells = <1>;
+ };
+-- 
+2.11.0
+
diff --git a/target/linux/mediatek/patches-4.14/0202-mmc-dt-bindings-add-support-for-MT7622-SoC.patch b/target/linux/mediatek/patches-4.14/0202-mmc-dt-bindings-add-support-for-MT7622-SoC.patch
new file mode 100644
index 0000000000..4d19ead2c1
--- /dev/null
+++ b/target/linux/mediatek/patches-4.14/0202-mmc-dt-bindings-add-support-for-MT7622-SoC.patch
@@ -0,0 +1,27 @@
+From 5365d402c8c4f0ff2cf2f26cfb8f46b520719ac0 Mon Sep 17 00:00:00 2001
+From: Sean Wang <sean.wang@mediatek.com>
+Date: Mon, 5 Mar 2018 14:47:26 +0800
+Subject: [PATCH 202/224] mmc: dt-bindings: add support for MT7622 SoC
+
+Add the devicetree binding for MT7622 SoC
+
+Signed-off-by: Sean Wang <sean.wang@mediatek.com>
+---
+ Documentation/devicetree/bindings/mmc/mtk-sd.txt | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/Documentation/devicetree/bindings/mmc/mtk-sd.txt b/Documentation/devicetree/bindings/mmc/mtk-sd.txt
+index 9b8017670870..f33467a54a05 100644
+--- a/Documentation/devicetree/bindings/mmc/mtk-sd.txt
++++ b/Documentation/devicetree/bindings/mmc/mtk-sd.txt
+@@ -12,6 +12,7 @@ Required properties:
+ 	"mediatek,mt8173-mmc": for mmc host ip compatible with mt8173
+ 	"mediatek,mt2701-mmc": for mmc host ip compatible with mt2701
+ 	"mediatek,mt2712-mmc": for mmc host ip compatible with mt2712
++	"mediatek,mt7622-mmc": for MT7622 SoC
+ 	"mediatek,mt7623-mmc", "mediatek,mt2701-mmc": for MT7623 SoC
+ 
+ - reg: physical base address of the controller and length
+-- 
+2.11.0
+
diff --git a/target/linux/mediatek/patches-4.14/0203-mmc-mediatek-add-support-for-MT7622-SoC.patch b/target/linux/mediatek/patches-4.14/0203-mmc-mediatek-add-support-for-MT7622-SoC.patch
new file mode 100644
index 0000000000..242e5045fa
--- /dev/null
+++ b/target/linux/mediatek/patches-4.14/0203-mmc-mediatek-add-support-for-MT7622-SoC.patch
@@ -0,0 +1,47 @@
+From 9af606beb87182120ab40563cd596a9e1cfc842b Mon Sep 17 00:00:00 2001
+From: Sean Wang <sean.wang@mediatek.com>
+Date: Fri, 2 Feb 2018 14:25:11 +0800
+Subject: [PATCH 203/224] mmc: mediatek: add support for MT7622 SoC
+
+Just applying the existing logic and adding its own characteristics into
+the space pointed by an extra entry of struct of_device_id to have support
+of MT7622 SoC.
+
+Signed-off-by: Chaotian Jing <chaotian.jing@mediatek.com>
+Signed-off-by: Sean Wang <sean.wang@mediatek.com>
+Tested-by: Jumin Li <jumin.li@mediatek.com>
+---
+ drivers/mmc/host/mtk-sd.c | 12 ++++++++++++
+ 1 file changed, 12 insertions(+)
+
+diff --git a/drivers/mmc/host/mtk-sd.c b/drivers/mmc/host/mtk-sd.c
+index 27a62254f12f..f5e0662f2590 100644
+--- a/drivers/mmc/host/mtk-sd.c
++++ b/drivers/mmc/host/mtk-sd.c
+@@ -438,11 +438,23 @@ static const struct mtk_mmc_compatible mt2712_compat = {
+ 	.enhance_rx = true,
+ };
+ 
++static const struct mtk_mmc_compatible mt7622_compat = {
++	.clk_div_bits = 12,
++	.hs400_tune = false,
++	.pad_tune_reg = MSDC_PAD_TUNE0,
++	.async_fifo = true,
++	.data_tune = true,
++	.busy_check = true,
++	.stop_clk_fix = true,
++	.enhance_rx = true,
++};
++
+ static const struct of_device_id msdc_of_ids[] = {
+ 	{ .compatible = "mediatek,mt8135-mmc", .data = &mt8135_compat},
+ 	{ .compatible = "mediatek,mt8173-mmc", .data = &mt8173_compat},
+ 	{ .compatible = "mediatek,mt2701-mmc", .data = &mt2701_compat},
+ 	{ .compatible = "mediatek,mt2712-mmc", .data = &mt2712_compat},
++	{ .compatible = "mediatek,mt7622-mmc", .data = &mt7622_compat},
+ 	{}
+ };
+ MODULE_DEVICE_TABLE(of, msdc_of_ids);
+-- 
+2.11.0
+
diff --git a/target/linux/mediatek/patches-4.14/0204-dt-bindings-dmaengine-Add-MediaTek-High-Speed-DMA-co.patch b/target/linux/mediatek/patches-4.14/0204-dt-bindings-dmaengine-Add-MediaTek-High-Speed-DMA-co.patch
new file mode 100644
index 0000000000..edb3852ce5
--- /dev/null
+++ b/target/linux/mediatek/patches-4.14/0204-dt-bindings-dmaengine-Add-MediaTek-High-Speed-DMA-co.patch
@@ -0,0 +1,57 @@
+From 71198859668501ef57450be07da77e9544f59f1e Mon Sep 17 00:00:00 2001
+From: Sean Wang <sean.wang@mediatek.com>
+Date: Sat, 13 May 2017 15:16:58 +0800
+Subject: [PATCH 204/224] dt-bindings: dmaengine: Add MediaTek High-Speed DMA
+ controller bindings
+
+Document the devicetree bindings for MediaTek High-Speed DMA controller
+which could be found on MT7623 SoC or other similar Mediatek SoCs.
+
+Signed-off-by: Sean Wang <sean.wang@mediatek.com>
+---
+ .../devicetree/bindings/dma/mtk-hsdma.txt          | 33 ++++++++++++++++++++++
+ 1 file changed, 33 insertions(+)
+ create mode 100644 Documentation/devicetree/bindings/dma/mtk-hsdma.txt
+
+diff --git a/Documentation/devicetree/bindings/dma/mtk-hsdma.txt b/Documentation/devicetree/bindings/dma/mtk-hsdma.txt
+new file mode 100644
+index 000000000000..4bb317359dc6
+--- /dev/null
++++ b/Documentation/devicetree/bindings/dma/mtk-hsdma.txt
+@@ -0,0 +1,33 @@
++MediaTek High-Speed DMA Controller
++==================================
++
++This device follows the generic DMA bindings defined in dma/dma.txt.
++
++Required properties:
++
++- compatible:	Must be one of
++		  "mediatek,mt7622-hsdma": for MT7622 SoC
++		  "mediatek,mt7623-hsdma": for MT7623 SoC
++- reg:		Should contain the register's base address and length.
++- interrupts:	Should contain a reference to the interrupt used by this
++		device.
++- clocks:	Should be the clock specifiers corresponding to the entry in
++		clock-names property.
++- clock-names:	Should contain "hsdma" entries.
++- power-domains: Phandle to the power domain that the device is part of
++- #dma-cells: 	The length of the DMA specifier, must be <1>. This one cell
++		in dmas property of a client device represents the channel
++		number.
++Example:
++
++        hsdma: dma-controller@1b007000 {
++		compatible = "mediatek,mt7623-hsdma";
++		reg = <0 0x1b007000 0 0x1000>;
++		interrupts = <GIC_SPI 98 IRQ_TYPE_LEVEL_LOW>;
++		clocks = <&ethsys CLK_ETHSYS_HSDMA>;
++		clock-names = "hsdma";
++		power-domains = <&scpsys MT2701_POWER_DOMAIN_ETH>;
++		#dma-cells = <1>;
++	};
++
++DMA clients must use the format described in dma/dma.txt file.
+-- 
+2.11.0
+
diff --git a/target/linux/mediatek/patches-4.14/0205-dmaengine-mediatek-Add-MediaTek-High-Speed-DMA-contr.patch b/target/linux/mediatek/patches-4.14/0205-dmaengine-mediatek-Add-MediaTek-High-Speed-DMA-contr.patch
new file mode 100644
index 0000000000..cd6e1004fb
--- /dev/null
+++ b/target/linux/mediatek/patches-4.14/0205-dmaengine-mediatek-Add-MediaTek-High-Speed-DMA-contr.patch
@@ -0,0 +1,1144 @@
+From 2b97c5d7886a920adc8f7c32c2a60583475654f2 Mon Sep 17 00:00:00 2001
+From: Sean Wang <sean.wang@mediatek.com>
+Date: Fri, 12 May 2017 17:05:12 +0800
+Subject: [PATCH 205/224] dmaengine: mediatek: Add MediaTek High-Speed DMA
+ controller for MT7622 and MT7623 SoC
+
+MediaTek High-Speed DMA controller (HSDMA) on MT7622 and MT7623 SoC has
+a single ring is dedicated to memory-to-memory transfer through ring based
+descriptor management.
+
+Even though there is only one physical ring available inside HSDMA, the
+driver can be easily extended to the support of multiple virtual channels
+processing simultaneously by means of DMA_VIRTUAL_CHANNELS effort.
+
+Signed-off-by: Sean Wang <sean.wang@mediatek.com>
+Cc: Randy Dunlap <rdunlap@infradead.org>
+Cc: Fengguang Wu <fengguang.wu@intel.com>
+Cc: Julia Lawall <julia.lawall@lip6.fr>
+---
+ drivers/dma/Kconfig              |    2 +
+ drivers/dma/Makefile             |    1 +
+ drivers/dma/mediatek/Kconfig     |   13 +
+ drivers/dma/mediatek/Makefile    |    1 +
+ drivers/dma/mediatek/mtk-hsdma.c | 1056 ++++++++++++++++++++++++++++++++++++++
+ 5 files changed, 1073 insertions(+)
+ create mode 100644 drivers/dma/mediatek/Kconfig
+ create mode 100644 drivers/dma/mediatek/Makefile
+ create mode 100644 drivers/dma/mediatek/mtk-hsdma.c
+
+diff --git a/drivers/dma/Kconfig b/drivers/dma/Kconfig
+index fadc4d8783bd..3100b6dfa6e8 100644
+--- a/drivers/dma/Kconfig
++++ b/drivers/dma/Kconfig
+@@ -604,6 +604,8 @@ config ZX_DMA
+ # driver files
+ source "drivers/dma/bestcomm/Kconfig"
+ 
++source "drivers/dma/mediatek/Kconfig"
++
+ source "drivers/dma/qcom/Kconfig"
+ 
+ source "drivers/dma/dw/Kconfig"
+diff --git a/drivers/dma/Makefile b/drivers/dma/Makefile
+index f08f8de1b567..26b0ef43a8f9 100644
+--- a/drivers/dma/Makefile
++++ b/drivers/dma/Makefile
+@@ -71,5 +71,6 @@ obj-$(CONFIG_XGENE_DMA) += xgene-dma.o
+ obj-$(CONFIG_ZX_DMA) += zx_dma.o
+ obj-$(CONFIG_ST_FDMA) += st_fdma.o
+ 
++obj-y += mediatek/
+ obj-y += qcom/
+ obj-y += xilinx/
+diff --git a/drivers/dma/mediatek/Kconfig b/drivers/dma/mediatek/Kconfig
+new file mode 100644
+index 000000000000..27bac0bba09e
+--- /dev/null
++++ b/drivers/dma/mediatek/Kconfig
+@@ -0,0 +1,13 @@
++
++config MTK_HSDMA
++	tristate "MediaTek High-Speed DMA controller support"
++	depends on ARCH_MEDIATEK || COMPILE_TEST
++	select DMA_ENGINE
++	select DMA_VIRTUAL_CHANNELS
++	---help---
++	  Enable support for High-Speed DMA controller on MediaTek
++	  SoCs.
++
++	  This controller provides the channels which is dedicated to
++	  memory-to-memory transfer to offload from CPU through ring-
++	  based descriptor management.
+diff --git a/drivers/dma/mediatek/Makefile b/drivers/dma/mediatek/Makefile
+new file mode 100644
+index 000000000000..6e778f842f01
+--- /dev/null
++++ b/drivers/dma/mediatek/Makefile
+@@ -0,0 +1 @@
++obj-$(CONFIG_MTK_HSDMA) += mtk-hsdma.o
+diff --git a/drivers/dma/mediatek/mtk-hsdma.c b/drivers/dma/mediatek/mtk-hsdma.c
+new file mode 100644
+index 000000000000..b7ec56ae02a6
+--- /dev/null
++++ b/drivers/dma/mediatek/mtk-hsdma.c
+@@ -0,0 +1,1056 @@
++// SPDX-License-Identifier: GPL-2.0
++// Copyright (c) 2017-2018 MediaTek Inc.
++
++/*
++ * Driver for MediaTek High-Speed DMA Controller
++ *
++ * Author: Sean Wang <sean.wang@mediatek.com>
++ *
++ */
++
++#include <linux/bitops.h>
++#include <linux/clk.h>
++#include <linux/dmaengine.h>
++#include <linux/dma-mapping.h>
++#include <linux/err.h>
++#include <linux/iopoll.h>
++#include <linux/list.h>
++#include <linux/module.h>
++#include <linux/of.h>
++#include <linux/of_device.h>
++#include <linux/of_dma.h>
++#include <linux/platform_device.h>
++#include <linux/pm_runtime.h>
++#include <linux/refcount.h>
++#include <linux/slab.h>
++
++#include "../virt-dma.h"
++
++#define MTK_HSDMA_USEC_POLL		20
++#define MTK_HSDMA_TIMEOUT_POLL		200000
++#define MTK_HSDMA_DMA_BUSWIDTHS		BIT(DMA_SLAVE_BUSWIDTH_4_BYTES)
++
++/* The default number of virtual channel */
++#define MTK_HSDMA_NR_VCHANS		3
++
++/* Only one physical channel supported */
++#define MTK_HSDMA_NR_MAX_PCHANS		1
++
++/* Macro for physical descriptor (PD) manipulation */
++/* The number of PD which must be 2 of power */
++#define MTK_DMA_SIZE			64
++#define MTK_HSDMA_NEXT_DESP_IDX(x, y)	(((x) + 1) & ((y) - 1))
++#define MTK_HSDMA_LAST_DESP_IDX(x, y)	(((x) - 1) & ((y) - 1))
++#define MTK_HSDMA_MAX_LEN		0x3f80
++#define MTK_HSDMA_ALIGN_SIZE		4
++#define MTK_HSDMA_PLEN_MASK		0x3fff
++#define MTK_HSDMA_DESC_PLEN(x)		(((x) & MTK_HSDMA_PLEN_MASK) << 16)
++#define MTK_HSDMA_DESC_PLEN_GET(x)	(((x) >> 16) & MTK_HSDMA_PLEN_MASK)
++
++/* Registers for underlying ring manipulation */
++#define MTK_HSDMA_TX_BASE		0x0
++#define MTK_HSDMA_TX_CNT		0x4
++#define MTK_HSDMA_TX_CPU		0x8
++#define MTK_HSDMA_TX_DMA		0xc
++#define MTK_HSDMA_RX_BASE		0x100
++#define MTK_HSDMA_RX_CNT		0x104
++#define MTK_HSDMA_RX_CPU		0x108
++#define MTK_HSDMA_RX_DMA		0x10c
++
++/* Registers for global setup */
++#define MTK_HSDMA_GLO			0x204
++#define MTK_HSDMA_GLO_MULTI_DMA		BIT(10)
++#define MTK_HSDMA_TX_WB_DDONE		BIT(6)
++#define MTK_HSDMA_BURST_64BYTES		(0x2 << 4)
++#define MTK_HSDMA_GLO_RX_BUSY		BIT(3)
++#define MTK_HSDMA_GLO_RX_DMA		BIT(2)
++#define MTK_HSDMA_GLO_TX_BUSY		BIT(1)
++#define MTK_HSDMA_GLO_TX_DMA		BIT(0)
++#define MTK_HSDMA_GLO_DMA		(MTK_HSDMA_GLO_TX_DMA |	\
++					 MTK_HSDMA_GLO_RX_DMA)
++#define MTK_HSDMA_GLO_BUSY		(MTK_HSDMA_GLO_RX_BUSY | \
++					 MTK_HSDMA_GLO_TX_BUSY)
++#define MTK_HSDMA_GLO_DEFAULT		(MTK_HSDMA_GLO_TX_DMA | \
++					 MTK_HSDMA_GLO_RX_DMA | \
++					 MTK_HSDMA_TX_WB_DDONE | \
++					 MTK_HSDMA_BURST_64BYTES | \
++					 MTK_HSDMA_GLO_MULTI_DMA)
++
++/* Registers for reset */
++#define MTK_HSDMA_RESET			0x208
++#define MTK_HSDMA_RST_TX		BIT(0)
++#define MTK_HSDMA_RST_RX		BIT(16)
++
++/* Registers for interrupt control */
++#define MTK_HSDMA_DLYINT		0x20c
++#define MTK_HSDMA_RXDLY_INT_EN		BIT(15)
++
++/* Interrupt fires when the pending number's more than the specified */
++#define MTK_HSDMA_RXMAX_PINT(x)		(((x) & 0x7f) << 8)
++
++/* Interrupt fires when the pending time's more than the specified in 20 us */
++#define MTK_HSDMA_RXMAX_PTIME(x)	((x) & 0x7f)
++#define MTK_HSDMA_DLYINT_DEFAULT	(MTK_HSDMA_RXDLY_INT_EN | \
++					 MTK_HSDMA_RXMAX_PINT(20) | \
++					 MTK_HSDMA_RXMAX_PTIME(20))
++#define MTK_HSDMA_INT_STATUS		0x220
++#define MTK_HSDMA_INT_ENABLE		0x228
++#define MTK_HSDMA_INT_RXDONE		BIT(16)
++
++enum mtk_hsdma_vdesc_flag {
++	MTK_HSDMA_VDESC_FINISHED	= 0x01,
++};
++
++#define IS_MTK_HSDMA_VDESC_FINISHED(x) ((x) == MTK_HSDMA_VDESC_FINISHED)
++
++/**
++ * struct mtk_hsdma_pdesc - This is the struct holding info describing physical
++ *			    descriptor (PD) and its placement must be kept at
++ *			    4-bytes alignment in little endian order.
++ * @desc[1-4]:		    The control pad used to indicate hardware how to
++ *			    deal with the descriptor such as source and
++ *			    destination address and data length. The maximum
++ *			    data length each pdesc can handle is 0x3f80 bytes
++ */
++struct mtk_hsdma_pdesc {
++	__le32 desc1;
++	__le32 desc2;
++	__le32 desc3;
++	__le32 desc4;
++} __packed __aligned(4);
++
++/**
++ * struct mtk_hsdma_vdesc - This is the struct holding info describing virtual
++ *			    descriptor (VD)
++ * @vd:			    An instance for struct virt_dma_desc
++ * @len:		    The total data size device wants to move
++ * @residue:		    The remaining data size device will move
++ * @dest:		    The destination address device wants to move to
++ * @src:		    The source address device wants to move from
++ */
++struct mtk_hsdma_vdesc {
++	struct virt_dma_desc vd;
++	size_t len;
++	size_t residue;
++	dma_addr_t dest;
++	dma_addr_t src;
++};
++
++/**
++ * struct mtk_hsdma_cb - This is the struct holding extra info required for RX
++ *			 ring to know what relevant VD the the PD is being
++ *			 mapped to.
++ * @vd:			 Pointer to the relevant VD.
++ * @flag:		 Flag indicating what action should be taken when VD
++ *			 is completed.
++ */
++struct mtk_hsdma_cb {
++	struct virt_dma_desc *vd;
++	enum mtk_hsdma_vdesc_flag flag;
++};
++
++/**
++ * struct mtk_hsdma_ring - This struct holds info describing underlying ring
++ *			   space
++ * @txd:		   The descriptor TX ring which describes DMA source
++ *			   information
++ * @rxd:		   The descriptor RX ring which describes DMA
++ *			   destination information
++ * @cb:			   The extra information pointed at by RX ring
++ * @tphys:		   The physical addr of TX ring
++ * @rphys:		   The physical addr of RX ring
++ * @cur_tptr:		   Pointer to the next free descriptor used by the host
++ * @cur_rptr:		   Pointer to the last done descriptor by the device
++ */
++struct mtk_hsdma_ring {
++	struct mtk_hsdma_pdesc *txd;
++	struct mtk_hsdma_pdesc *rxd;
++	struct mtk_hsdma_cb *cb;
++	dma_addr_t tphys;
++	dma_addr_t rphys;
++	u16 cur_tptr;
++	u16 cur_rptr;
++};
++
++/**
++ * struct mtk_hsdma_pchan - This is the struct holding info describing physical
++ *			   channel (PC)
++ * @ring:		   An instance for the underlying ring
++ * @sz_ring:		   Total size allocated for the ring
++ * @nr_free:		   Total number of free rooms in the ring. It would
++ *			   be accessed and updated frequently between IRQ
++ *			   context and user context to reflect whether ring
++ *			   can accept requests from VD.
++ */
++struct mtk_hsdma_pchan {
++	struct mtk_hsdma_ring ring;
++	size_t sz_ring;
++	atomic_t nr_free;
++};
++
++/**
++ * struct mtk_hsdma_vchan - This is the struct holding info describing virtual
++ *			   channel (VC)
++ * @vc:			   An instance for struct virt_dma_chan
++ * @issue_completion:	   The wait for all issued descriptors completited
++ * @issue_synchronize:	   Bool indicating channel synchronization starts
++ * @desc_hw_processing:	   List those descriptors the hardware is processing,
++ *			   which is protected by vc.lock
++ */
++struct mtk_hsdma_vchan {
++	struct virt_dma_chan vc;
++	struct completion issue_completion;
++	bool issue_synchronize;
++	struct list_head desc_hw_processing;
++};
++
++/**
++ * struct mtk_hsdma_soc - This is the struct holding differences among SoCs
++ * @ddone:		  Bit mask for DDONE
++ * @ls0:		  Bit mask for LS0
++ */
++struct mtk_hsdma_soc {
++	__le32 ddone;
++	__le32 ls0;
++};
++
++/**
++ * struct mtk_hsdma_device - This is the struct holding info describing HSDMA
++ *			     device
++ * @ddev:		     An instance for struct dma_device
++ * @base:		     The mapped register I/O base
++ * @clk:		     The clock that device internal is using
++ * @irq:		     The IRQ that device are using
++ * @dma_requests:	     The number of VCs the device supports to
++ * @vc:			     The pointer to all available VCs
++ * @pc:			     The pointer to the underlying PC
++ * @pc_refcnt:		     Track how many VCs are using the PC
++ * @lock:		     Lock protect agaisting multiple VCs access PC
++ * @soc:		     The pointer to area holding differences among
++ *			     vaious platform
++ */
++struct mtk_hsdma_device {
++	struct dma_device ddev;
++	void __iomem *base;
++	struct clk *clk;
++	u32 irq;
++
++	u32 dma_requests;
++	struct mtk_hsdma_vchan *vc;
++	struct mtk_hsdma_pchan *pc;
++	refcount_t pc_refcnt;
++
++	/* Lock used to protect against multiple VCs access PC */
++	spinlock_t lock;
++
++	const struct mtk_hsdma_soc *soc;
++};
++
++static struct mtk_hsdma_device *to_hsdma_dev(struct dma_chan *chan)
++{
++	return container_of(chan->device, struct mtk_hsdma_device, ddev);
++}
++
++static inline struct mtk_hsdma_vchan *to_hsdma_vchan(struct dma_chan *chan)
++{
++	return container_of(chan, struct mtk_hsdma_vchan, vc.chan);
++}
++
++static struct mtk_hsdma_vdesc *to_hsdma_vdesc(struct virt_dma_desc *vd)
++{
++	return container_of(vd, struct mtk_hsdma_vdesc, vd);
++}
++
++static struct device *hsdma2dev(struct mtk_hsdma_device *hsdma)
++{
++	return hsdma->ddev.dev;
++}
++
++static u32 mtk_dma_read(struct mtk_hsdma_device *hsdma, u32 reg)
++{
++	return readl(hsdma->base + reg);
++}
++
++static void mtk_dma_write(struct mtk_hsdma_device *hsdma, u32 reg, u32 val)
++{
++	writel(val, hsdma->base + reg);
++}
++
++static void mtk_dma_rmw(struct mtk_hsdma_device *hsdma, u32 reg,
++			u32 mask, u32 set)
++{
++	u32 val;
++
++	val = mtk_dma_read(hsdma, reg);
++	val &= ~mask;
++	val |= set;
++	mtk_dma_write(hsdma, reg, val);
++}
++
++static void mtk_dma_set(struct mtk_hsdma_device *hsdma, u32 reg, u32 val)
++{
++	mtk_dma_rmw(hsdma, reg, 0, val);
++}
++
++static void mtk_dma_clr(struct mtk_hsdma_device *hsdma, u32 reg, u32 val)
++{
++	mtk_dma_rmw(hsdma, reg, val, 0);
++}
++
++static void mtk_hsdma_vdesc_free(struct virt_dma_desc *vd)
++{
++	kfree(container_of(vd, struct mtk_hsdma_vdesc, vd));
++}
++
++static int mtk_hsdma_busy_wait(struct mtk_hsdma_device *hsdma)
++{
++	u32 status = 0;
++
++	return readl_poll_timeout(hsdma->base + MTK_HSDMA_GLO, status,
++				  !(status & MTK_HSDMA_GLO_BUSY),
++				  MTK_HSDMA_USEC_POLL,
++				  MTK_HSDMA_TIMEOUT_POLL);
++}
++
++static int mtk_hsdma_alloc_pchan(struct mtk_hsdma_device *hsdma,
++				 struct mtk_hsdma_pchan *pc)
++{
++	struct mtk_hsdma_ring *ring = &pc->ring;
++	int err;
++
++	memset(pc, 0, sizeof(*pc));
++
++	/*
++	 * Allocate ring space where [0 ... MTK_DMA_SIZE - 1] is for TX ring
++	 * and [MTK_DMA_SIZE ... 2 * MTK_DMA_SIZE - 1] is for RX ring.
++	 */
++	pc->sz_ring = 2 * MTK_DMA_SIZE * sizeof(*ring->txd);
++	ring->txd = dma_zalloc_coherent(hsdma2dev(hsdma), pc->sz_ring,
++					&ring->tphys, GFP_NOWAIT);
++	if (!ring->txd)
++		return -ENOMEM;
++
++	ring->rxd = &ring->txd[MTK_DMA_SIZE];
++	ring->rphys = ring->tphys + MTK_DMA_SIZE * sizeof(*ring->txd);
++	ring->cur_tptr = 0;
++	ring->cur_rptr = MTK_DMA_SIZE - 1;
++
++	ring->cb = kcalloc(MTK_DMA_SIZE, sizeof(*ring->cb), GFP_NOWAIT);
++	if (!ring->cb) {
++		err = -ENOMEM;
++		goto err_free_dma;
++	}
++
++	atomic_set(&pc->nr_free, MTK_DMA_SIZE - 1);
++
++	/* Disable HSDMA and wait for the completion */
++	mtk_dma_clr(hsdma, MTK_HSDMA_GLO, MTK_HSDMA_GLO_DMA);
++	err = mtk_hsdma_busy_wait(hsdma);
++	if (err)
++		goto err_free_cb;
++
++	/* Reset */
++	mtk_dma_set(hsdma, MTK_HSDMA_RESET,
++		    MTK_HSDMA_RST_TX | MTK_HSDMA_RST_RX);
++	mtk_dma_clr(hsdma, MTK_HSDMA_RESET,
++		    MTK_HSDMA_RST_TX | MTK_HSDMA_RST_RX);
++
++	/* Setup HSDMA initial pointer in the ring */
++	mtk_dma_write(hsdma, MTK_HSDMA_TX_BASE, ring->tphys);
++	mtk_dma_write(hsdma, MTK_HSDMA_TX_CNT, MTK_DMA_SIZE);
++	mtk_dma_write(hsdma, MTK_HSDMA_TX_CPU, ring->cur_tptr);
++	mtk_dma_write(hsdma, MTK_HSDMA_TX_DMA, 0);
++	mtk_dma_write(hsdma, MTK_HSDMA_RX_BASE, ring->rphys);
++	mtk_dma_write(hsdma, MTK_HSDMA_RX_CNT, MTK_DMA_SIZE);
++	mtk_dma_write(hsdma, MTK_HSDMA_RX_CPU, ring->cur_rptr);
++	mtk_dma_write(hsdma, MTK_HSDMA_RX_DMA, 0);
++
++	/* Enable HSDMA */
++	mtk_dma_set(hsdma, MTK_HSDMA_GLO, MTK_HSDMA_GLO_DMA);
++
++	/* Setup delayed interrupt */
++	mtk_dma_write(hsdma, MTK_HSDMA_DLYINT, MTK_HSDMA_DLYINT_DEFAULT);
++
++	/* Enable interrupt */
++	mtk_dma_set(hsdma, MTK_HSDMA_INT_ENABLE, MTK_HSDMA_INT_RXDONE);
++
++	return 0;
++
++err_free_cb:
++	kfree(ring->cb);
++
++err_free_dma:
++	dma_free_coherent(hsdma2dev(hsdma),
++			  pc->sz_ring, ring->txd, ring->tphys);
++	return err;
++}
++
++static void mtk_hsdma_free_pchan(struct mtk_hsdma_device *hsdma,
++				 struct mtk_hsdma_pchan *pc)
++{
++	struct mtk_hsdma_ring *ring = &pc->ring;
++
++	/* Disable HSDMA and then wait for the completion */
++	mtk_dma_clr(hsdma, MTK_HSDMA_GLO, MTK_HSDMA_GLO_DMA);
++	mtk_hsdma_busy_wait(hsdma);
++
++	/* Reset pointer in the ring */
++	mtk_dma_clr(hsdma, MTK_HSDMA_INT_ENABLE, MTK_HSDMA_INT_RXDONE);
++	mtk_dma_write(hsdma, MTK_HSDMA_TX_BASE, 0);
++	mtk_dma_write(hsdma, MTK_HSDMA_TX_CNT, 0);
++	mtk_dma_write(hsdma, MTK_HSDMA_TX_CPU, 0);
++	mtk_dma_write(hsdma, MTK_HSDMA_RX_BASE, 0);
++	mtk_dma_write(hsdma, MTK_HSDMA_RX_CNT, 0);
++	mtk_dma_write(hsdma, MTK_HSDMA_RX_CPU, MTK_DMA_SIZE - 1);
++
++	kfree(ring->cb);
++
++	dma_free_coherent(hsdma2dev(hsdma),
++			  pc->sz_ring, ring->txd, ring->tphys);
++}
++
++static int mtk_hsdma_issue_pending_vdesc(struct mtk_hsdma_device *hsdma,
++					 struct mtk_hsdma_pchan *pc,
++					 struct mtk_hsdma_vdesc *hvd)
++{
++	struct mtk_hsdma_ring *ring = &pc->ring;
++	struct mtk_hsdma_pdesc *txd, *rxd;
++	u16 reserved, prev, tlen, num_sgs;
++	unsigned long flags;
++
++	/* Protect against PC is accessed by multiple VCs simultaneously */
++	spin_lock_irqsave(&hsdma->lock, flags);
++
++	/*
++	 * Reserve rooms, where pc->nr_free is used to track how many free
++	 * rooms in the ring being updated in user and IRQ context.
++	 */
++	num_sgs = DIV_ROUND_UP(hvd->len, MTK_HSDMA_MAX_LEN);
++	reserved = min_t(u16, num_sgs, atomic_read(&pc->nr_free));
++
++	if (!reserved) {
++		spin_unlock_irqrestore(&hsdma->lock, flags);
++		return -ENOSPC;
++	}
++
++	atomic_sub(reserved, &pc->nr_free);
++
++	while (reserved--) {
++		/* Limit size by PD capability for valid data moving */
++		tlen = (hvd->len > MTK_HSDMA_MAX_LEN) ?
++		       MTK_HSDMA_MAX_LEN : hvd->len;
++
++		/*
++		 * Setup PDs using the remaining VD info mapped on those
++		 * reserved rooms. And since RXD is shared memory between the
++		 * host and the device allocated by dma_alloc_coherent call,
++		 * the helper macro WRITE_ONCE can ensure the data written to
++		 * RAM would really happens.
++		 */
++		txd = &ring->txd[ring->cur_tptr];
++		WRITE_ONCE(txd->desc1, hvd->src);
++		WRITE_ONCE(txd->desc2,
++			   hsdma->soc->ls0 | MTK_HSDMA_DESC_PLEN(tlen));
++
++		rxd = &ring->rxd[ring->cur_tptr];
++		WRITE_ONCE(rxd->desc1, hvd->dest);
++		WRITE_ONCE(rxd->desc2, MTK_HSDMA_DESC_PLEN(tlen));
++
++		/* Associate VD, the PD belonged to */
++		ring->cb[ring->cur_tptr].vd = &hvd->vd;
++
++		/* Move forward the pointer of TX ring */
++		ring->cur_tptr = MTK_HSDMA_NEXT_DESP_IDX(ring->cur_tptr,
++							 MTK_DMA_SIZE);
++
++		/* Update VD with remaining data */
++		hvd->src  += tlen;
++		hvd->dest += tlen;
++		hvd->len  -= tlen;
++	}
++
++	/*
++	 * Tagging flag for the last PD for VD will be responsible for
++	 * completing VD.
++	 */
++	if (!hvd->len) {
++		prev = MTK_HSDMA_LAST_DESP_IDX(ring->cur_tptr, MTK_DMA_SIZE);
++		ring->cb[prev].flag = MTK_HSDMA_VDESC_FINISHED;
++	}
++
++	/* Ensure all changes indeed done before we're going on */
++	wmb();
++
++	/*
++	 * Updating into hardware the pointer of TX ring lets HSDMA to take
++	 * action for those pending PDs.
++	 */
++	mtk_dma_write(hsdma, MTK_HSDMA_TX_CPU, ring->cur_tptr);
++
++	spin_unlock_irqrestore(&hsdma->lock, flags);
++
++	return 0;
++}
++
++static void mtk_hsdma_issue_vchan_pending(struct mtk_hsdma_device *hsdma,
++					  struct mtk_hsdma_vchan *hvc)
++{
++	struct virt_dma_desc *vd, *vd2;
++	int err;
++
++	lockdep_assert_held(&hvc->vc.lock);
++
++	list_for_each_entry_safe(vd, vd2, &hvc->vc.desc_issued, node) {
++		struct mtk_hsdma_vdesc *hvd;
++
++		hvd = to_hsdma_vdesc(vd);
++
++		/* Map VD into PC and all VCs shares a single PC */
++		err = mtk_hsdma_issue_pending_vdesc(hsdma, hsdma->pc, hvd);
++
++		/*
++		 * Move VD from desc_issued to desc_hw_processing when entire
++		 * VD is fit into available PDs. Otherwise, the uncompleted
++		 * VDs would stay in list desc_issued and then restart the
++		 * processing as soon as possible once underlying ring space
++		 * got freed.
++		 */
++		if (err == -ENOSPC || hvd->len > 0)
++			break;
++
++		/*
++		 * The extra list desc_hw_processing is used because
++		 * hardware can't provide sufficient information allowing us
++		 * to know what VDs are still working on the underlying ring.
++		 * Through the additional list, it can help us to implement
++		 * terminate_all, residue calculation and such thing needed
++		 * to know detail descriptor status on the hardware.
++		 */
++		list_move_tail(&vd->node, &hvc->desc_hw_processing);
++	}
++}
++
++static void mtk_hsdma_free_rooms_in_ring(struct mtk_hsdma_device *hsdma)
++{
++	struct mtk_hsdma_vchan *hvc;
++	struct mtk_hsdma_pdesc *rxd;
++	struct mtk_hsdma_vdesc *hvd;
++	struct mtk_hsdma_pchan *pc;
++	struct mtk_hsdma_cb *cb;
++	int i = MTK_DMA_SIZE;
++	__le32 desc2;
++	u32 status;
++	u16 next;
++
++	/* Read IRQ status */
++	status = mtk_dma_read(hsdma, MTK_HSDMA_INT_STATUS);
++	if (unlikely(!(status & MTK_HSDMA_INT_RXDONE)))
++		goto rx_done;
++
++	pc = hsdma->pc;
++
++	/*
++	 * Using a fail-safe loop with iterations of up to MTK_DMA_SIZE to
++	 * reclaim these finished descriptors: The most number of PDs the ISR
++	 * can handle at one time shouldn't be more than MTK_DMA_SIZE so we
++	 * take it as limited count instead of just using a dangerous infinite
++	 * poll.
++	 */
++	while (i--) {
++		next = MTK_HSDMA_NEXT_DESP_IDX(pc->ring.cur_rptr,
++					       MTK_DMA_SIZE);
++		rxd = &pc->ring.rxd[next];
++
++		/*
++		 * If MTK_HSDMA_DESC_DDONE is no specified, that means data
++		 * moving for the PD is still under going.
++		 */
++		desc2 = READ_ONCE(rxd->desc2);
++		if (!(desc2 & hsdma->soc->ddone))
++			break;
++
++		cb = &pc->ring.cb[next];
++		if (unlikely(!cb->vd)) {
++			dev_err(hsdma2dev(hsdma), "cb->vd cannot be null\n");
++			break;
++		}
++
++		/* Update residue of VD the associated PD belonged to */
++		hvd = to_hsdma_vdesc(cb->vd);
++		hvd->residue -= MTK_HSDMA_DESC_PLEN_GET(rxd->desc2);
++
++		/* Complete VD until the relevant last PD is finished */
++		if (IS_MTK_HSDMA_VDESC_FINISHED(cb->flag)) {
++			hvc = to_hsdma_vchan(cb->vd->tx.chan);
++
++			spin_lock(&hvc->vc.lock);
++
++			/* Remove VD from list desc_hw_processing */
++			list_del(&cb->vd->node);
++
++			/* Add VD into list desc_completed */
++			vchan_cookie_complete(cb->vd);
++
++			if (hvc->issue_synchronize &&
++			    list_empty(&hvc->desc_hw_processing)) {
++				complete(&hvc->issue_completion);
++				hvc->issue_synchronize = false;
++			}
++			spin_unlock(&hvc->vc.lock);
++
++			cb->flag = 0;
++		}
++
++		cb->vd = 0;
++
++		/*
++		 * Recycle the RXD with the helper WRITE_ONCE that can ensure
++		 * data written into RAM would really happens.
++		 */
++		WRITE_ONCE(rxd->desc1, 0);
++		WRITE_ONCE(rxd->desc2, 0);
++		pc->ring.cur_rptr = next;
++
++		/* Release rooms */
++		atomic_inc(&pc->nr_free);
++	}
++
++	/* Ensure all changes indeed done before we're going on */
++	wmb();
++
++	/* Update CPU pointer for those completed PDs */
++	mtk_dma_write(hsdma, MTK_HSDMA_RX_CPU, pc->ring.cur_rptr);
++
++	/*
++	 * Acking the pending IRQ allows hardware no longer to keep the used
++	 * IRQ line in certain trigger state when software has completed all
++	 * the finished physical descriptors.
++	 */
++	if (atomic_read(&pc->nr_free) >= MTK_DMA_SIZE - 1)
++		mtk_dma_write(hsdma, MTK_HSDMA_INT_STATUS, status);
++
++	/* ASAP handles pending VDs in all VCs after freeing some rooms */
++	for (i = 0; i < hsdma->dma_requests; i++) {
++		hvc = &hsdma->vc[i];
++		spin_lock(&hvc->vc.lock);
++		mtk_hsdma_issue_vchan_pending(hsdma, hvc);
++		spin_unlock(&hvc->vc.lock);
++	}
++
++rx_done:
++	/* All completed PDs are cleaned up, so enable interrupt again */
++	mtk_dma_set(hsdma, MTK_HSDMA_INT_ENABLE, MTK_HSDMA_INT_RXDONE);
++}
++
++static irqreturn_t mtk_hsdma_irq(int irq, void *devid)
++{
++	struct mtk_hsdma_device *hsdma = devid;
++
++	/*
++	 * Disable interrupt until all completed PDs are cleaned up in
++	 * mtk_hsdma_free_rooms call.
++	 */
++	mtk_dma_clr(hsdma, MTK_HSDMA_INT_ENABLE, MTK_HSDMA_INT_RXDONE);
++
++	mtk_hsdma_free_rooms_in_ring(hsdma);
++
++	return IRQ_HANDLED;
++}
++
++static struct virt_dma_desc *mtk_hsdma_find_active_desc(struct dma_chan *c,
++							dma_cookie_t cookie)
++{
++	struct mtk_hsdma_vchan *hvc = to_hsdma_vchan(c);
++	struct virt_dma_desc *vd;
++
++	list_for_each_entry(vd, &hvc->desc_hw_processing, node)
++		if (vd->tx.cookie == cookie)
++			return vd;
++
++	list_for_each_entry(vd, &hvc->vc.desc_issued, node)
++		if (vd->tx.cookie == cookie)
++			return vd;
++
++	return NULL;
++}
++
++static enum dma_status mtk_hsdma_tx_status(struct dma_chan *c,
++					   dma_cookie_t cookie,
++					   struct dma_tx_state *txstate)
++{
++	struct mtk_hsdma_vchan *hvc = to_hsdma_vchan(c);
++	struct mtk_hsdma_vdesc *hvd;
++	struct virt_dma_desc *vd;
++	enum dma_status ret;
++	unsigned long flags;
++	size_t bytes = 0;
++
++	ret = dma_cookie_status(c, cookie, txstate);
++	if (ret == DMA_COMPLETE || !txstate)
++		return ret;
++
++	spin_lock_irqsave(&hvc->vc.lock, flags);
++	vd = mtk_hsdma_find_active_desc(c, cookie);
++	spin_unlock_irqrestore(&hvc->vc.lock, flags);
++
++	if (vd) {
++		hvd = to_hsdma_vdesc(vd);
++		bytes = hvd->residue;
++	}
++
++	dma_set_residue(txstate, bytes);
++
++	return ret;
++}
++
++static void mtk_hsdma_issue_pending(struct dma_chan *c)
++{
++	struct mtk_hsdma_device *hsdma = to_hsdma_dev(c);
++	struct mtk_hsdma_vchan *hvc = to_hsdma_vchan(c);
++	unsigned long flags;
++
++	spin_lock_irqsave(&hvc->vc.lock, flags);
++
++	if (vchan_issue_pending(&hvc->vc))
++		mtk_hsdma_issue_vchan_pending(hsdma, hvc);
++
++	spin_unlock_irqrestore(&hvc->vc.lock, flags);
++}
++
++static struct dma_async_tx_descriptor *
++mtk_hsdma_prep_dma_memcpy(struct dma_chan *c, dma_addr_t dest,
++			  dma_addr_t src, size_t len, unsigned long flags)
++{
++	struct mtk_hsdma_vdesc *hvd;
++
++	hvd = kzalloc(sizeof(*hvd), GFP_NOWAIT);
++	if (!hvd)
++		return NULL;
++
++	hvd->len = len;
++	hvd->residue = len;
++	hvd->src = src;
++	hvd->dest = dest;
++
++	return vchan_tx_prep(to_virt_chan(c), &hvd->vd, flags);
++}
++
++static int mtk_hsdma_free_inactive_desc(struct dma_chan *c)
++{
++	struct virt_dma_chan *vc = to_virt_chan(c);
++	unsigned long flags;
++	LIST_HEAD(head);
++
++	spin_lock_irqsave(&vc->lock, flags);
++	list_splice_tail_init(&vc->desc_allocated, &head);
++	list_splice_tail_init(&vc->desc_submitted, &head);
++	list_splice_tail_init(&vc->desc_issued, &head);
++	spin_unlock_irqrestore(&vc->lock, flags);
++
++	/* At the point, we don't expect users put descriptor into VC again */
++	vchan_dma_desc_free_list(vc, &head);
++
++	return 0;
++}
++
++static void mtk_hsdma_free_active_desc(struct dma_chan *c)
++{
++	struct mtk_hsdma_vchan *hvc = to_hsdma_vchan(c);
++	bool sync_needed = false;
++
++	/*
++	 * Once issue_synchronize is being set, which means once the hardware
++	 * consumes all descriptors for the channel in the ring, the
++	 * synchronization must be be notified immediately it is completed.
++	 */
++	spin_lock(&hvc->vc.lock);
++	if (!list_empty(&hvc->desc_hw_processing)) {
++		hvc->issue_synchronize = true;
++		sync_needed = true;
++	}
++	spin_unlock(&hvc->vc.lock);
++
++	if (sync_needed)
++		wait_for_completion(&hvc->issue_completion);
++	/*
++	 * At the point, we expect that all remaining descriptors in the ring
++	 * for the channel should be all processing done.
++	 */
++	WARN_ONCE(!list_empty(&hvc->desc_hw_processing),
++		  "Desc pending still in list desc_hw_processing\n");
++
++	/* Free all descriptors in list desc_completed */
++	vchan_synchronize(&hvc->vc);
++
++	WARN_ONCE(!list_empty(&hvc->vc.desc_completed),
++		  "Desc pending still in list desc_completed\n");
++}
++
++static int mtk_hsdma_terminate_all(struct dma_chan *c)
++{
++	/*
++	 * Free pending descriptors not processed yet by hardware that have
++	 * previously been submitted to the channel.
++	 */
++	mtk_hsdma_free_inactive_desc(c);
++
++	/*
++	 * However, the DMA engine doesn't provide any way to stop these
++	 * descriptors being processed currently by hardware. The only way is
++	 * to just waiting until these descriptors are all processed completely
++	 * through mtk_hsdma_free_active_desc call.
++	 */
++	mtk_hsdma_free_active_desc(c);
++
++	return 0;
++}
++
++static int mtk_hsdma_alloc_chan_resources(struct dma_chan *c)
++{
++	struct mtk_hsdma_device *hsdma = to_hsdma_dev(c);
++	int err;
++
++	/*
++	 * Since HSDMA has only one PC, the resource for PC is being allocated
++	 * when the first VC is being created and the other VCs would run on
++	 * the same PC.
++	 */
++	if (!refcount_read(&hsdma->pc_refcnt)) {
++		err = mtk_hsdma_alloc_pchan(hsdma, hsdma->pc);
++		if (err)
++			return err;
++		/*
++		 * refcount_inc would complain increment on 0; use-after-free.
++		 * Thus, we need to explicitly set it as 1 initially.
++		 */
++		refcount_set(&hsdma->pc_refcnt, 1);
++	} else {
++		refcount_inc(&hsdma->pc_refcnt);
++	}
++
++	return 0;
++}
++
++static void mtk_hsdma_free_chan_resources(struct dma_chan *c)
++{
++	struct mtk_hsdma_device *hsdma = to_hsdma_dev(c);
++
++	/* Free all descriptors in all lists on the VC */
++	mtk_hsdma_terminate_all(c);
++
++	/* The resource for PC is not freed until all the VCs are destroyed */
++	if (!refcount_dec_and_test(&hsdma->pc_refcnt))
++		return;
++
++	mtk_hsdma_free_pchan(hsdma, hsdma->pc);
++}
++
++static int mtk_hsdma_hw_init(struct mtk_hsdma_device *hsdma)
++{
++	int err;
++
++	pm_runtime_enable(hsdma2dev(hsdma));
++	pm_runtime_get_sync(hsdma2dev(hsdma));
++
++	err = clk_prepare_enable(hsdma->clk);
++	if (err)
++		return err;
++
++	mtk_dma_write(hsdma, MTK_HSDMA_INT_ENABLE, 0);
++	mtk_dma_write(hsdma, MTK_HSDMA_GLO, MTK_HSDMA_GLO_DEFAULT);
++
++	return 0;
++}
++
++static int mtk_hsdma_hw_deinit(struct mtk_hsdma_device *hsdma)
++{
++	mtk_dma_write(hsdma, MTK_HSDMA_GLO, 0);
++
++	clk_disable_unprepare(hsdma->clk);
++
++	pm_runtime_put_sync(hsdma2dev(hsdma));
++	pm_runtime_disable(hsdma2dev(hsdma));
++
++	return 0;
++}
++
++static const struct mtk_hsdma_soc mt7623_soc = {
++	.ddone = BIT(31),
++	.ls0 = BIT(30),
++};
++
++static const struct mtk_hsdma_soc mt7622_soc = {
++	.ddone = BIT(15),
++	.ls0 = BIT(14),
++};
++
++static const struct of_device_id mtk_hsdma_match[] = {
++	{ .compatible = "mediatek,mt7623-hsdma", .data = &mt7623_soc},
++	{ .compatible = "mediatek,mt7622-hsdma", .data = &mt7622_soc},
++	{ /* sentinel */ }
++};
++MODULE_DEVICE_TABLE(of, mtk_hsdma_match);
++
++static int mtk_hsdma_probe(struct platform_device *pdev)
++{
++	struct mtk_hsdma_device *hsdma;
++	struct mtk_hsdma_vchan *vc;
++	struct dma_device *dd;
++	struct resource *res;
++	int i, err;
++
++	hsdma = devm_kzalloc(&pdev->dev, sizeof(*hsdma), GFP_KERNEL);
++	if (!hsdma)
++		return -ENOMEM;
++
++	dd = &hsdma->ddev;
++
++	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
++	hsdma->base = devm_ioremap_resource(&pdev->dev, res);
++	if (IS_ERR(hsdma->base))
++		return PTR_ERR(hsdma->base);
++
++	hsdma->soc = of_device_get_match_data(&pdev->dev);
++	if (!hsdma->soc) {
++		dev_err(&pdev->dev, "No device match found\n");
++		return -ENODEV;
++	}
++
++	hsdma->clk = devm_clk_get(&pdev->dev, "hsdma");
++	if (IS_ERR(hsdma->clk)) {
++		dev_err(&pdev->dev, "No clock for %s\n",
++			dev_name(&pdev->dev));
++		return PTR_ERR(hsdma->clk);
++	}
++
++	res = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
++	if (!res) {
++		dev_err(&pdev->dev, "No irq resource for %s\n",
++			dev_name(&pdev->dev));
++		return -EINVAL;
++	}
++	hsdma->irq = res->start;
++
++	refcount_set(&hsdma->pc_refcnt, 0);
++	spin_lock_init(&hsdma->lock);
++
++	dma_cap_set(DMA_MEMCPY, dd->cap_mask);
++
++	dd->copy_align = MTK_HSDMA_ALIGN_SIZE;
++	dd->device_alloc_chan_resources = mtk_hsdma_alloc_chan_resources;
++	dd->device_free_chan_resources = mtk_hsdma_free_chan_resources;
++	dd->device_tx_status = mtk_hsdma_tx_status;
++	dd->device_issue_pending = mtk_hsdma_issue_pending;
++	dd->device_prep_dma_memcpy = mtk_hsdma_prep_dma_memcpy;
++	dd->device_terminate_all = mtk_hsdma_terminate_all;
++	dd->src_addr_widths = MTK_HSDMA_DMA_BUSWIDTHS;
++	dd->dst_addr_widths = MTK_HSDMA_DMA_BUSWIDTHS;
++	dd->directions = BIT(DMA_MEM_TO_MEM);
++	dd->residue_granularity = DMA_RESIDUE_GRANULARITY_SEGMENT;
++	dd->dev = &pdev->dev;
++	INIT_LIST_HEAD(&dd->channels);
++
++	hsdma->dma_requests = MTK_HSDMA_NR_VCHANS;
++	if (pdev->dev.of_node && of_property_read_u32(pdev->dev.of_node,
++						      "dma-requests",
++						      &hsdma->dma_requests)) {
++		dev_info(&pdev->dev,
++			 "Using %u as missing dma-requests property\n",
++			 MTK_HSDMA_NR_VCHANS);
++	}
++
++	hsdma->pc = devm_kcalloc(&pdev->dev, MTK_HSDMA_NR_MAX_PCHANS,
++				 sizeof(*hsdma->pc), GFP_KERNEL);
++	if (!hsdma->pc)
++		return -ENOMEM;
++
++	hsdma->vc = devm_kcalloc(&pdev->dev, hsdma->dma_requests,
++				 sizeof(*hsdma->vc), GFP_KERNEL);
++	if (!hsdma->vc)
++		return -ENOMEM;
++
++	for (i = 0; i < hsdma->dma_requests; i++) {
++		vc = &hsdma->vc[i];
++		vc->vc.desc_free = mtk_hsdma_vdesc_free;
++		vchan_init(&vc->vc, dd);
++		init_completion(&vc->issue_completion);
++		INIT_LIST_HEAD(&vc->desc_hw_processing);
++	}
++
++	err = dma_async_device_register(dd);
++	if (err)
++		return err;
++
++	err = of_dma_controller_register(pdev->dev.of_node,
++					 of_dma_xlate_by_chan_id, hsdma);
++	if (err) {
++		dev_err(&pdev->dev,
++			"MediaTek HSDMA OF registration failed %d\n", err);
++		goto err_unregister;
++	}
++
++	mtk_hsdma_hw_init(hsdma);
++
++	err = devm_request_irq(&pdev->dev, hsdma->irq,
++			       mtk_hsdma_irq, 0,
++			       dev_name(&pdev->dev), hsdma);
++	if (err) {
++		dev_err(&pdev->dev,
++			"request_irq failed with err %d\n", err);
++		goto err_unregister;
++	}
++
++	platform_set_drvdata(pdev, hsdma);
++
++	dev_info(&pdev->dev, "MediaTek HSDMA driver registered\n");
++
++	return 0;
++
++err_unregister:
++	dma_async_device_unregister(dd);
++
++	return err;
++}
++
++static int mtk_hsdma_remove(struct platform_device *pdev)
++{
++	struct mtk_hsdma_device *hsdma = platform_get_drvdata(pdev);
++	struct mtk_hsdma_vchan *vc;
++	int i;
++
++	/* Kill VC task */
++	for (i = 0; i < hsdma->dma_requests; i++) {
++		vc = &hsdma->vc[i];
++
++		list_del(&vc->vc.chan.device_node);
++		tasklet_kill(&vc->vc.task);
++	}
++
++	/* Disable DMA interrupt */
++	mtk_dma_write(hsdma, MTK_HSDMA_INT_ENABLE, 0);
++
++	/* Waits for any pending IRQ handlers to complete */
++	synchronize_irq(hsdma->irq);
++
++	/* Disable hardware */
++	mtk_hsdma_hw_deinit(hsdma);
++
++	dma_async_device_unregister(&hsdma->ddev);
++	of_dma_controller_free(pdev->dev.of_node);
++
++	return 0;
++}
++
++static struct platform_driver mtk_hsdma_driver = {
++	.probe		= mtk_hsdma_probe,
++	.remove		= mtk_hsdma_remove,
++	.driver = {
++		.name		= KBUILD_MODNAME,
++		.of_match_table	= mtk_hsdma_match,
++	},
++};
++module_platform_driver(mtk_hsdma_driver);
++
++MODULE_DESCRIPTION("MediaTek High-Speed DMA Controller Driver");
++MODULE_AUTHOR("Sean Wang <sean.wang@mediatek.com>");
++MODULE_LICENSE("GPL v2");
+-- 
+2.11.0
+
diff --git a/target/linux/mediatek/patches-4.14/0206-dt-bindings-clock-mediatek-update-audsys-documentati.patch b/target/linux/mediatek/patches-4.14/0206-dt-bindings-clock-mediatek-update-audsys-documentati.patch
new file mode 100644
index 0000000000..d92c0c50fb
--- /dev/null
+++ b/target/linux/mediatek/patches-4.14/0206-dt-bindings-clock-mediatek-update-audsys-documentati.patch
@@ -0,0 +1,50 @@
+From e6d9c3121f2a8b92bd6202d6a32e7d428990d7d7 Mon Sep 17 00:00:00 2001
+From: Ryder Lee <ryder.lee@mediatek.com>
+Date: Tue, 6 Mar 2018 17:09:29 +0800
+Subject: [PATCH 206/224] dt-bindings: clock: mediatek: update audsys
+ documentation to adapt MFD device
+
+The MediaTek audio hardware block that exposes functionalities that are
+handled by separate subsystems in the kernel.  These functions are all
+mapped somewhere at 0x112xxxxx, and there are some control bits are mixed
+up with other functions within the same registers.
+
+This patch modifies example to illustrate child nodes.
+
+Signed-off-by: Ryder Lee <ryder.lee@mediatek.com>
+---
+ .../bindings/arm/mediatek/mediatek,audsys.txt         | 19 ++++++++++++++-----
+ 1 file changed, 14 insertions(+), 5 deletions(-)
+
+diff --git a/Documentation/devicetree/bindings/arm/mediatek/mediatek,audsys.txt b/Documentation/devicetree/bindings/arm/mediatek/mediatek,audsys.txt
+index 9b8f578d5e19..97b304eaa47c 100644
+--- a/Documentation/devicetree/bindings/arm/mediatek/mediatek,audsys.txt
++++ b/Documentation/devicetree/bindings/arm/mediatek/mediatek,audsys.txt
+@@ -13,10 +13,19 @@ The AUDSYS controller uses the common clk binding from
+ Documentation/devicetree/bindings/clock/clock-bindings.txt
+ The available clocks are defined in dt-bindings/clock/mt*-clk.h.
+ 
++Required sub-nodes:
++-------
++For common binding part and usage, refer to
++../sonud/mt2701-afe-pcm.txt.
++
+ Example:
+ 
+-audsys: audsys@11220000 {
+-	compatible = "mediatek,mt7622-audsys", "syscon";
+-	reg = <0 0x11220000 0 0x1000>;
+-	#clock-cells = <1>;
+-};
++	audsys: clock-controller@11220000 {
++		compatible = "mediatek,mt7622-audsys", "syscon";
++		reg = <0 0x11220000 0 0x2000>;
++		#clock-cells = <1>;
++
++		afe: audio-controller {
++			...
++		};
++	};
+-- 
+2.11.0
+
diff --git a/target/linux/mediatek/patches-4.14/0207-dt-bindings-clock-mediatek-add-audsys-support-for-MT.patch b/target/linux/mediatek/patches-4.14/0207-dt-bindings-clock-mediatek-add-audsys-support-for-MT.patch
new file mode 100644
index 0000000000..8349b85ae4
--- /dev/null
+++ b/target/linux/mediatek/patches-4.14/0207-dt-bindings-clock-mediatek-add-audsys-support-for-MT.patch
@@ -0,0 +1,28 @@
+From 301de0fca7698f1ed5ed34fa7c082c3ae62d1e61 Mon Sep 17 00:00:00 2001
+From: Ryder Lee <ryder.lee@mediatek.com>
+Date: Tue, 6 Mar 2018 17:09:30 +0800
+Subject: [PATCH 207/224] dt-bindings: clock: mediatek: add audsys support for
+ MT2701
+
+This patch adds a compatible string for MT2701.
+
+Signed-off-by: Ryder Lee <ryder.lee@mediatek.com>
+---
+ Documentation/devicetree/bindings/arm/mediatek/mediatek,audsys.txt | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/Documentation/devicetree/bindings/arm/mediatek/mediatek,audsys.txt b/Documentation/devicetree/bindings/arm/mediatek/mediatek,audsys.txt
+index 97b304eaa47c..34a69ba67f13 100644
+--- a/Documentation/devicetree/bindings/arm/mediatek/mediatek,audsys.txt
++++ b/Documentation/devicetree/bindings/arm/mediatek/mediatek,audsys.txt
+@@ -6,6 +6,7 @@ The MediaTek AUDSYS controller provides various clocks to the system.
+ Required Properties:
+ 
+ - compatible: Should be one of:
++	- "mediatek,mt2701-audsys", "syscon"
+ 	- "mediatek,mt7622-audsys", "syscon"
+ - #clock-cells: Must be 1
+ 
+-- 
+2.11.0
+
diff --git a/target/linux/mediatek/patches-4.14/0208-clk-mediatek-update-missing-clock-data-for-MT7622-au.patch b/target/linux/mediatek/patches-4.14/0208-clk-mediatek-update-missing-clock-data-for-MT7622-au.patch
new file mode 100644
index 0000000000..c1f7682eec
--- /dev/null
+++ b/target/linux/mediatek/patches-4.14/0208-clk-mediatek-update-missing-clock-data-for-MT7622-au.patch
@@ -0,0 +1,45 @@
+From 0725349768e96542ef06efbd87925a8603cba16a Mon Sep 17 00:00:00 2001
+From: Ryder Lee <ryder.lee@mediatek.com>
+Date: Tue, 6 Mar 2018 17:09:26 +0800
+Subject: [PATCH 208/224] clk: mediatek: update missing clock data for MT7622
+ audsys
+
+Add missing clock data 'CLK_AUDIO_AFE_CONN' for MT7622 audsys.
+
+Signed-off-by: Ryder Lee <ryder.lee@mediatek.com>
+Reviewed-by: Rob Herring <robh@kernel.org>
+Reviewed-by: Matthias Brugger <matthias.bgg@gmail.com>
+---
+ drivers/clk/mediatek/clk-mt7622-aud.c  | 1 +
+ include/dt-bindings/clock/mt7622-clk.h | 3 ++-
+ 2 files changed, 3 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/clk/mediatek/clk-mt7622-aud.c b/drivers/clk/mediatek/clk-mt7622-aud.c
+index fad7d9fc53ba..13f752de7adc 100644
+--- a/drivers/clk/mediatek/clk-mt7622-aud.c
++++ b/drivers/clk/mediatek/clk-mt7622-aud.c
+@@ -106,6 +106,7 @@ static const struct mtk_gate audio_clks[] = {
+ 	GATE_AUDIO1(CLK_AUDIO_INTDIR, "audio_intdir", "intdir_sel", 20),
+ 	GATE_AUDIO1(CLK_AUDIO_A1SYS, "audio_a1sys", "a1sys_hp_sel", 21),
+ 	GATE_AUDIO1(CLK_AUDIO_A2SYS, "audio_a2sys", "a2sys_hp_sel", 22),
++	GATE_AUDIO1(CLK_AUDIO_AFE_CONN, "audio_afe_conn", "a1sys_hp_sel", 23),
+ 	/* AUDIO2 */
+ 	GATE_AUDIO2(CLK_AUDIO_UL1, "audio_ul1", "a1sys_hp_sel", 0),
+ 	GATE_AUDIO2(CLK_AUDIO_UL2, "audio_ul2", "a1sys_hp_sel", 1),
+diff --git a/include/dt-bindings/clock/mt7622-clk.h b/include/dt-bindings/clock/mt7622-clk.h
+index 3e514ed51d15..e9d77f0e8bce 100644
+--- a/include/dt-bindings/clock/mt7622-clk.h
++++ b/include/dt-bindings/clock/mt7622-clk.h
+@@ -235,7 +235,8 @@
+ #define CLK_AUDIO_MEM_ASRC3		43
+ #define CLK_AUDIO_MEM_ASRC4		44
+ #define CLK_AUDIO_MEM_ASRC5		45
+-#define CLK_AUDIO_NR_CLK		46
++#define CLK_AUDIO_AFE_CONN		46
++#define CLK_AUDIO_NR_CLK		47
+ 
+ /* SSUSBSYS */
+ 
+-- 
+2.11.0
+
diff --git a/target/linux/mediatek/patches-4.14/0209-clk-mediatek-add-devm_of_platform_populate-for-MT762.patch b/target/linux/mediatek/patches-4.14/0209-clk-mediatek-add-devm_of_platform_populate-for-MT762.patch
new file mode 100644
index 0000000000..610dcab7c0
--- /dev/null
+++ b/target/linux/mediatek/patches-4.14/0209-clk-mediatek-add-devm_of_platform_populate-for-MT762.patch
@@ -0,0 +1,47 @@
+From 9dbdf33f1f246ecb6d957504781a970590b2d9f0 Mon Sep 17 00:00:00 2001
+From: Ryder Lee <ryder.lee@mediatek.com>
+Date: Tue, 6 Mar 2018 17:09:27 +0800
+Subject: [PATCH 209/224] clk: mediatek: add devm_of_platform_populate() for
+ MT7622 audsys
+
+Add devm_of_platform_populate() to populate devices which are children
+of the root node.
+
+Signed-off-by: Ryder Lee <ryder.lee@mediatek.com>
+---
+ drivers/clk/mediatek/clk-mt7622-aud.c | 8 ++++++--
+ 1 file changed, 6 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/clk/mediatek/clk-mt7622-aud.c b/drivers/clk/mediatek/clk-mt7622-aud.c
+index 13f752de7adc..0a1109ff65b9 100644
+--- a/drivers/clk/mediatek/clk-mt7622-aud.c
++++ b/drivers/clk/mediatek/clk-mt7622-aud.c
+@@ -142,6 +142,7 @@ static int clk_mt7622_audiosys_init(struct platform_device *pdev)
+ {
+ 	struct clk_onecell_data *clk_data;
+ 	struct device_node *node = pdev->dev.of_node;
++
+ 	int r;
+ 
+ 	clk_data = mtk_alloc_clk_data(CLK_AUDIO_NR_CLK);
+@@ -150,12 +151,15 @@ static int clk_mt7622_audiosys_init(struct platform_device *pdev)
+ 			       clk_data);
+ 
+ 	r = of_clk_add_provider(node, of_clk_src_onecell_get, clk_data);
+-	if (r)
++	if (r) {
+ 		dev_err(&pdev->dev,
+ 			"could not register clock provider: %s: %d\n",
+ 			pdev->name, r);
+ 
+-	return r;
++		return r;
++	}
++
++	return devm_of_platform_populate(&pdev->dev);
+ }
+ 
+ static const struct of_device_id of_match_clk_mt7622_aud[] = {
+-- 
+2.11.0
+
diff --git a/target/linux/mediatek/patches-4.14/0210-arm64-dts-mt7622-add-clock-controller-device-nodes.patch b/target/linux/mediatek/patches-4.14/0210-arm64-dts-mt7622-add-clock-controller-device-nodes.patch
new file mode 100644
index 0000000000..5d892118ec
--- /dev/null
+++ b/target/linux/mediatek/patches-4.14/0210-arm64-dts-mt7622-add-clock-controller-device-nodes.patch
@@ -0,0 +1,135 @@
+From 9c76dd09d27dff05207241aa67a2c6054d057b32 Mon Sep 17 00:00:00 2001
+From: Sean Wang <sean.wang@mediatek.com>
+Date: Thu, 28 Dec 2017 10:30:32 +0800
+Subject: [PATCH 210/224] arm64: dts: mt7622: add clock controller device nodes
+
+Add clock controller nodes for MT7622 and include header for topckgen,
+infracfg, pericfg, apmixedsys, ethsys, sgmiisys, pciesys and ssusbsys
+for those devices nodes to be added afterwards.
+
+In addition, provides an oscillator node for the source of PLLs and dummy
+clock for PWARP to complement missing support of clock gate for the
+wrapper circuit in the driver.
+
+Signed-off-by: Sean Wang <sean.wang@mediatek.com>
+Cc: Stephen Boyd <sboyd@codeaurora.org>
+---
+ arch/arm64/boot/dts/mediatek/mt7622.dtsi | 76 ++++++++++++++++++++++++++++++++
+ 1 file changed, 76 insertions(+)
+
+diff --git a/arch/arm64/boot/dts/mediatek/mt7622.dtsi b/arch/arm64/boot/dts/mediatek/mt7622.dtsi
+index b111fec2ed9d..73e5d628a8c8 100644
+--- a/arch/arm64/boot/dts/mediatek/mt7622.dtsi
++++ b/arch/arm64/boot/dts/mediatek/mt7622.dtsi
+@@ -8,6 +8,8 @@
+ 
+ #include <dt-bindings/interrupt-controller/irq.h>
+ #include <dt-bindings/interrupt-controller/arm-gic.h>
++#include <dt-bindings/clock/mt7622-clk.h>
++#include <dt-bindings/reset/mt7622-reset.h>
+ 
+ / {
+ 	compatible = "mediatek,mt7622";
+@@ -48,6 +50,19 @@
+ 		clock-frequency = <280000000>;
+ 	};
+ 
++	pwrap_clk: dummy40m {
++		compatible = "fixed-clock";
++		clock-frequency = <40000000>;
++		#clock-cells = <0>;
++	};
++
++	clk25m: oscillator {
++		compatible = "fixed-clock";
++		#clock-cells = <0>;
++		clock-frequency = <25000000>;
++		clock-output-names = "clkxtal";
++	};
++
+ 	psci {
+ 		compatible  = "arm,psci-0.2";
+ 		method      = "smc";
+@@ -78,6 +93,22 @@
+ 			      IRQ_TYPE_LEVEL_HIGH)>;
+ 	};
+ 
++	infracfg: infracfg@10000000 {
++		compatible = "mediatek,mt7622-infracfg",
++			     "syscon";
++		reg = <0 0x10000000 0 0x1000>;
++		#clock-cells = <1>;
++		#reset-cells = <1>;
++	};
++
++	pericfg: pericfg@10002000 {
++		compatible = "mediatek,mt7622-pericfg",
++			     "syscon";
++		reg = <0 0x10002000 0 0x1000>;
++		#clock-cells = <1>;
++		#reset-cells = <1>;
++	};
++
+ 	sysirq: interrupt-controller@10200620 {
+ 		compatible = "mediatek,mt7622-sysirq",
+ 			     "mediatek,mt6577-sysirq";
+@@ -87,6 +118,20 @@
+ 		reg = <0 0x10200620 0 0x20>;
+ 	};
+ 
++	apmixedsys: apmixedsys@10209000 {
++		compatible = "mediatek,mt7622-apmixedsys",
++			     "syscon";
++		reg = <0 0x10209000 0 0x1000>;
++		#clock-cells = <1>;
++	};
++
++	topckgen: topckgen@10210000 {
++		compatible = "mediatek,mt7622-topckgen",
++			     "syscon";
++		reg = <0 0x10210000 0 0x1000>;
++		#clock-cells = <1>;
++	};
++
+ 	gic: interrupt-controller@10300000 {
+ 		compatible = "arm,gic-400";
+ 		interrupt-controller;
+@@ -107,4 +152,35 @@
+ 		clock-names = "baud", "bus";
+ 		status = "disabled";
+ 	};
++
++	ssusbsys: ssusbsys@1a000000 {
++		compatible = "mediatek,mt7622-ssusbsys",
++			     "syscon";
++		reg = <0 0x1a000000 0 0x1000>;
++		#clock-cells = <1>;
++		#reset-cells = <1>;
++	};
++
++	pciesys: pciesys@1a100800 {
++		compatible = "mediatek,mt7622-pciesys",
++			     "syscon";
++		reg = <0 0x1a100800 0 0x1000>;
++		#clock-cells = <1>;
++		#reset-cells = <1>;
++	};
++
++	ethsys: syscon@1b000000 {
++		compatible = "mediatek,mt7622-ethsys",
++			     "syscon";
++		reg = <0 0x1b000000 0 0x1000>;
++		#clock-cells = <1>;
++		#reset-cells = <1>;
++	};
++
++	sgmiisys: sgmiisys@1b128000 {
++		compatible = "mediatek,mt7622-sgmiisys",
++			     "syscon";
++		reg = <0 0x1b128000 0 0x1000>;
++		#clock-cells = <1>;
++	};
+ };
+-- 
+2.11.0
+
diff --git a/target/linux/mediatek/patches-4.14/0211-arm64-dts-mt7622-add-power-domain-controller-device-.patch b/target/linux/mediatek/patches-4.14/0211-arm64-dts-mt7622-add-power-domain-controller-device-.patch
new file mode 100644
index 0000000000..362d40db15
--- /dev/null
+++ b/target/linux/mediatek/patches-4.14/0211-arm64-dts-mt7622-add-power-domain-controller-device-.patch
@@ -0,0 +1,50 @@
+From 79d0293e8f35e87b1f068fc0b7963a86ba56800e Mon Sep 17 00:00:00 2001
+From: Sean Wang <sean.wang@mediatek.com>
+Date: Thu, 28 Dec 2017 15:46:42 +0800
+Subject: [PATCH 211/224] arm64: dts: mt7622: add power domain controller
+ device nodes
+
+add power domain controller nodes
+
+Signed-off-by: Sean Wang <sean.wang@mediatek.com>
+Cc: Matthias Brugger <matthias.bgg@gmail.com>
+---
+ arch/arm64/boot/dts/mediatek/mt7622.dtsi | 15 +++++++++++++++
+ 1 file changed, 15 insertions(+)
+
+diff --git a/arch/arm64/boot/dts/mediatek/mt7622.dtsi b/arch/arm64/boot/dts/mediatek/mt7622.dtsi
+index 73e5d628a8c8..81207e652d59 100644
+--- a/arch/arm64/boot/dts/mediatek/mt7622.dtsi
++++ b/arch/arm64/boot/dts/mediatek/mt7622.dtsi
+@@ -9,6 +9,7 @@
+ #include <dt-bindings/interrupt-controller/irq.h>
+ #include <dt-bindings/interrupt-controller/arm-gic.h>
+ #include <dt-bindings/clock/mt7622-clk.h>
++#include <dt-bindings/power/mt7622-power.h>
+ #include <dt-bindings/reset/mt7622-reset.h>
+ 
+ / {
+@@ -109,6 +110,20 @@
+ 		#reset-cells = <1>;
+ 	};
+ 
++	scpsys: scpsys@10006000 {
++		compatible = "mediatek,mt7622-scpsys",
++			     "syscon";
++		#power-domain-cells = <1>;
++		reg = <0 0x10006000 0 0x1000>;
++		interrupts = <GIC_SPI 165 IRQ_TYPE_LEVEL_LOW>,
++			     <GIC_SPI 166 IRQ_TYPE_LEVEL_LOW>,
++			     <GIC_SPI 167 IRQ_TYPE_LEVEL_LOW>,
++			     <GIC_SPI 168 IRQ_TYPE_LEVEL_LOW>;
++		infracfg = <&infracfg>;
++		clocks = <&topckgen CLK_TOP_HIF_SEL>;
++		clock-names = "hif_sel";
++	};
++
+ 	sysirq: interrupt-controller@10200620 {
+ 		compatible = "mediatek,mt7622-sysirq",
+ 			     "mediatek,mt6577-sysirq";
+-- 
+2.11.0
+
diff --git a/target/linux/mediatek/patches-4.14/0212-arm64-dts-mt7622-add-pinctrl-related-device-nodes.patch b/target/linux/mediatek/patches-4.14/0212-arm64-dts-mt7622-add-pinctrl-related-device-nodes.patch
new file mode 100644
index 0000000000..9858790450
--- /dev/null
+++ b/target/linux/mediatek/patches-4.14/0212-arm64-dts-mt7622-add-pinctrl-related-device-nodes.patch
@@ -0,0 +1,259 @@
+From 927c736a1a169713cd59140db5e82f8ed11dad60 Mon Sep 17 00:00:00 2001
+From: Sean Wang <sean.wang@mediatek.com>
+Date: Fri, 29 Dec 2017 11:06:52 +0800
+Subject: [PATCH 212/224] arm64: dts: mt7622: add pinctrl related device nodes
+
+add pinctrl device nodes and rfb1 board, additionally include all pin
+groups possible being used on rfb1 board and available gpio keys.
+
+Signed-off-by: Sean Wang <sean.wang@mediatek.com>
+Cc: Matthias Brugger <matthias.bgg@gmail.com>
+---
+ arch/arm64/boot/dts/mediatek/mt7622-rfb1.dts | 200 +++++++++++++++++++++++++++
+ arch/arm64/boot/dts/mediatek/mt7622.dtsi     |   7 +
+ 2 files changed, 207 insertions(+)
+
+diff --git a/arch/arm64/boot/dts/mediatek/mt7622-rfb1.dts b/arch/arm64/boot/dts/mediatek/mt7622-rfb1.dts
+index c08309df2cc7..fc8ef78a0a34 100644
+--- a/arch/arm64/boot/dts/mediatek/mt7622-rfb1.dts
++++ b/arch/arm64/boot/dts/mediatek/mt7622-rfb1.dts
+@@ -7,6 +7,8 @@
+  */
+ 
+ /dts-v1/;
++#include <dt-bindings/input/input.h>
++
+ #include "mt7622.dtsi"
+ 
+ / {
+@@ -17,11 +19,209 @@
+ 		bootargs = "console=ttyS0,115200n1";
+ 	};
+ 
++	gpio-keys {
++		compatible = "gpio-keys-polled";
++		poll-interval = <100>;
++
++		factory {
++			label = "factory";
++			linux,code = <BTN_0>;
++			gpios = <&pio 0 0>;
++		};
++
++		wps {
++			label = "wps";
++			linux,code = <KEY_WPS_BUTTON>;
++			gpios = <&pio 102 0>;
++		};
++	};
++
+ 	memory {
+ 		reg = <0 0x40000000 0 0x3F000000>;
+ 	};
+ };
+ 
++&pio {
++	/* eMMC is shared pin with parallel NAND */
++	emmc_pins_default: emmc-pins-default {
++		mux {
++			function = "emmc", "emmc_rst";
++			groups = "emmc";
++		};
++	};
++
++	emmc_pins_uhs: emmc-pins-uhs {
++		mux {
++			function = "emmc";
++			groups = "emmc";
++		};
++	};
++
++	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_bclk_ws_mclk",
++				  "i2s1_in_data",
++				  "i2s1_out_data";
++		};
++	};
++
++	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";
++		};
++	};
++
++	sd0_pins_uhs: sd0-pins-uhs {
++		mux {
++			function = "sd";
++			groups = "sd_0";
++		};
++	};
++
++	/* 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";
++		};
++	};
++};
++
+ &uart0 {
+ 	status = "okay";
+ };
+diff --git a/arch/arm64/boot/dts/mediatek/mt7622.dtsi b/arch/arm64/boot/dts/mediatek/mt7622.dtsi
+index 81207e652d59..8211bf72ccaa 100644
+--- a/arch/arm64/boot/dts/mediatek/mt7622.dtsi
++++ b/arch/arm64/boot/dts/mediatek/mt7622.dtsi
+@@ -147,6 +147,13 @@
+ 		#clock-cells = <1>;
+ 	};
+ 
++	pio: pinctrl@10211000 {
++		compatible = "mediatek,mt7622-pinctrl";
++		reg = <0 0x10211000 0 0x1000>;
++		gpio-controller;
++		#gpio-cells = <2>;
++	};
++
+ 	gic: interrupt-controller@10300000 {
+ 		compatible = "arm,gic-400";
+ 		interrupt-controller;
+-- 
+2.11.0
+
diff --git a/target/linux/mediatek/patches-4.14/0213-arm64-dts-mt7622-add-PMIC-MT6380-related-nodes.patch b/target/linux/mediatek/patches-4.14/0213-arm64-dts-mt7622-add-PMIC-MT6380-related-nodes.patch
new file mode 100644
index 0000000000..f02f4b31c4
--- /dev/null
+++ b/target/linux/mediatek/patches-4.14/0213-arm64-dts-mt7622-add-PMIC-MT6380-related-nodes.patch
@@ -0,0 +1,165 @@
+From 78e92290c8c9511d0d540dfd0450e64169f08c20 Mon Sep 17 00:00:00 2001
+From: Sean Wang <sean.wang@mediatek.com>
+Date: Mon, 5 Feb 2018 22:44:44 +0800
+Subject: [PATCH 213/224] arm64: dts: mt7622: add PMIC MT6380 related nodes
+
+Enable pwrap and MT6380 on mt7622-rfb1 board. Also add all mt6380
+regulator nodes in an alone file to allow similar boards using MT6380
+able to resue the configuration.
+
+Signed-off-by: Sean Wang <sean.wang@mediatek.com>
+Cc: Mark Brown <broonie@kernel.org>
+Cc: Matthias Brugger <matthias.bgg@gmail.com>
+Cc: Philippe Ombredanne <pombredanne@nexb.com>
+Acked-by: Philippe Ombredanne <pombredanne@nexb.com>
+---
+ arch/arm64/boot/dts/mediatek/mt6380.dtsi     | 86 ++++++++++++++++++++++++++++
+ arch/arm64/boot/dts/mediatek/mt7622-rfb1.dts |  8 +++
+ arch/arm64/boot/dts/mediatek/mt7622.dtsi     | 12 ++++
+ 3 files changed, 106 insertions(+)
+ create mode 100644 arch/arm64/boot/dts/mediatek/mt6380.dtsi
+
+diff --git a/arch/arm64/boot/dts/mediatek/mt6380.dtsi b/arch/arm64/boot/dts/mediatek/mt6380.dtsi
+new file mode 100644
+index 000000000000..53b335d2de5f
+--- /dev/null
++++ b/arch/arm64/boot/dts/mediatek/mt6380.dtsi
+@@ -0,0 +1,86 @@
++// SPDX-License-Identifier: GPL-2.0
++/*
++ * dts file for MediaTek MT6380 regulator
++ *
++ * Copyright (c) 2018 MediaTek Inc.
++ * Author: Chenglin Xu <chenglin.xu@mediatek.com>
++ *	   Sean Wang <sean.wang@mediatek.com>
++ */
++
++&pwrap {
++	regulators {
++		compatible = "mediatek,mt6380-regulator";
++
++		mt6380_vcpu_reg: buck-vcore1 {
++			regulator-name = "vcore1";
++			regulator-min-microvolt = < 600000>;
++			regulator-max-microvolt = <1393750>;
++			regulator-ramp-delay = <6250>;
++			regulator-always-on;
++			regulator-boot-on;
++		};
++
++		mt6380_vcore_reg: buck-vcore {
++			regulator-name = "vcore";
++			regulator-min-microvolt = <600000>;
++			regulator-max-microvolt = <1393750>;
++			regulator-ramp-delay = <6250>;
++			regulator-always-on;
++			regulator-boot-on;
++		};
++
++		mt6380_vrf_reg: buck-vrf {
++			regulator-name = "vrf";
++			regulator-min-microvolt = <1200000>;
++			regulator-max-microvolt = <1575000>;
++			regulator-ramp-delay = <0>;
++			regulator-always-on;
++			regulator-boot-on;
++		};
++
++		mt6380_vm_reg: ldo-vm {
++			regulator-name = "vm";
++			regulator-min-microvolt = <1050000>;
++			regulator-max-microvolt = <1400000>;
++			regulator-ramp-delay = <0>;
++			regulator-always-on;
++			regulator-boot-on;
++		};
++
++		mt6380_va_reg: ldo-va {
++			regulator-name = "va";
++			regulator-min-microvolt = <2200000>;
++			regulator-max-microvolt = <3300000>;
++			regulator-ramp-delay = <0>;
++			regulator-always-on;
++			regulator-boot-on;
++		};
++
++		mt6380_vphy_reg: ldo-vphy {
++			regulator-name = "vphy";
++			regulator-min-microvolt = <1800000>;
++			regulator-max-microvolt = <1800000>;
++			regulator-ramp-delay = <0>;
++			regulator-always-on;
++			regulator-boot-on;
++		};
++
++		mt6380_vddr_reg: ldo-vddr {
++			regulator-name = "vddr";
++			regulator-min-microvolt = <1240000>;
++			regulator-max-microvolt = <1840000>;
++			regulator-ramp-delay = <0>;
++			regulator-always-on;
++			regulator-boot-on;
++		};
++
++		mt6380_vt_reg: ldo-vt {
++			regulator-name = "vt";
++			regulator-min-microvolt = <2200000>;
++			regulator-max-microvolt = <3300000>;
++			regulator-ramp-delay = <0>;
++			regulator-always-on;
++			regulator-boot-on;
++		};
++	};
++};
+diff --git a/arch/arm64/boot/dts/mediatek/mt7622-rfb1.dts b/arch/arm64/boot/dts/mediatek/mt7622-rfb1.dts
+index fc8ef78a0a34..42bd3a4c9a93 100644
+--- a/arch/arm64/boot/dts/mediatek/mt7622-rfb1.dts
++++ b/arch/arm64/boot/dts/mediatek/mt7622-rfb1.dts
+@@ -10,6 +10,7 @@
+ #include <dt-bindings/input/input.h>
+ 
+ #include "mt7622.dtsi"
++#include "mt6380.dtsi"
+ 
+ / {
+ 	model = "MediaTek MT7622 RFB1 board";
+@@ -222,6 +223,13 @@
+ 	};
+ };
+ 
++&pwrap {
++	pinctrl-names = "default";
++	pinctrl-0 = <&pmic_bus_pins>;
++
++	status = "okay";
++};
++
+ &uart0 {
+ 	status = "okay";
+ };
+diff --git a/arch/arm64/boot/dts/mediatek/mt7622.dtsi b/arch/arm64/boot/dts/mediatek/mt7622.dtsi
+index 8211bf72ccaa..c387c4cb7d3e 100644
+--- a/arch/arm64/boot/dts/mediatek/mt7622.dtsi
++++ b/arch/arm64/boot/dts/mediatek/mt7622.dtsi
+@@ -102,6 +102,18 @@
+ 		#reset-cells = <1>;
+ 	};
+ 
++	pwrap: pwrap@10001000 {
++		compatible = "mediatek,mt7622-pwrap";
++		reg = <0 0x10001000 0 0x250>;
++		reg-names = "pwrap";
++		clocks = <&infracfg CLK_INFRA_PMIC_PD>,<&pwrap_clk>;
++		clock-names = "spi","wrap";
++		resets = <&infracfg MT7622_INFRA_PMIC_WRAP_RST>;
++		reset-names = "pwrap";
++		interrupts = <GIC_SPI 163 IRQ_TYPE_LEVEL_HIGH>;
++		status = "disabled";
++	};
++
+ 	pericfg: pericfg@10002000 {
+ 		compatible = "mediatek,mt7622-pericfg",
+ 			     "syscon";
+-- 
+2.11.0
+
diff --git a/target/linux/mediatek/patches-4.14/0214-arm64-dts-mt7622-add-cpufreq-related-device-nodes.patch b/target/linux/mediatek/patches-4.14/0214-arm64-dts-mt7622-add-cpufreq-related-device-nodes.patch
new file mode 100644
index 0000000000..43692d4344
--- /dev/null
+++ b/target/linux/mediatek/patches-4.14/0214-arm64-dts-mt7622-add-cpufreq-related-device-nodes.patch
@@ -0,0 +1,119 @@
+From 19fc79333af0d3733d4987bc1e554ae7e8a8cb0d Mon Sep 17 00:00:00 2001
+From: Sean Wang <sean.wang@mediatek.com>
+Date: Thu, 28 Dec 2017 16:26:10 +0800
+Subject: [PATCH 214/224] arm64: dts: mt7622: add cpufreq related device nodes
+
+Add clocks, regulators and opp information into cpu nodes.
+In addition, the power supply for cpu nodes is deployed on
+mt7622-rfb1 board.
+
+Signed-off-by: Sean Wang <sean.wang@mediatek.com>
+Cc: Viresh Kumar <viresh.kumar@linaro.org>
+---
+ arch/arm64/boot/dts/mediatek/mt7622-rfb1.dts | 12 +++++++
+ arch/arm64/boot/dts/mediatek/mt7622.dtsi     | 52 ++++++++++++++++++++++++++++
+ 2 files changed, 64 insertions(+)
+
+diff --git a/arch/arm64/boot/dts/mediatek/mt7622-rfb1.dts b/arch/arm64/boot/dts/mediatek/mt7622-rfb1.dts
+index 42bd3a4c9a93..b3878656475c 100644
+--- a/arch/arm64/boot/dts/mediatek/mt7622-rfb1.dts
++++ b/arch/arm64/boot/dts/mediatek/mt7622-rfb1.dts
+@@ -20,6 +20,18 @@
+ 		bootargs = "console=ttyS0,115200n1";
+ 	};
+ 
++	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-polled";
+ 		poll-interval = <100>;
+diff --git a/arch/arm64/boot/dts/mediatek/mt7622.dtsi b/arch/arm64/boot/dts/mediatek/mt7622.dtsi
+index c387c4cb7d3e..7256879de4c9 100644
+--- a/arch/arm64/boot/dts/mediatek/mt7622.dtsi
++++ b/arch/arm64/boot/dts/mediatek/mt7622.dtsi
+@@ -18,6 +18,50 @@
+ 	#address-cells = <2>;
+ 	#size-cells = <2>;
+ 
++	cpu_opp_table: opp-table {
++		compatible = "operating-points-v2";
++		opp-shared;
++		opp-300000000 {
++			opp-hz = /bits/ 64 <30000000>;
++			opp-microvolt = <950000>;
++		};
++
++		opp-437500000 {
++			opp-hz = /bits/ 64 <437500000>;
++			opp-microvolt = <1000000>;
++		};
++
++		opp-600000000 {
++			opp-hz = /bits/ 64 <600000000>;
++			opp-microvolt = <1050000>;
++		};
++
++		opp-812500000 {
++			opp-hz = /bits/ 64 <812500000>;
++			opp-microvolt = <1100000>;
++		};
++
++		opp-1025000000 {
++			opp-hz = /bits/ 64 <1025000000>;
++			opp-microvolt = <1150000>;
++		};
++
++		opp-1137500000 {
++			opp-hz = /bits/ 64 <1137500000>;
++			opp-microvolt = <1200000>;
++		};
++
++		opp-1262500000 {
++			opp-hz = /bits/ 64 <1262500000>;
++			opp-microvolt = <1250000>;
++		};
++
++		opp-1350000000 {
++			opp-hz = /bits/ 64 <1350000000>;
++			opp-microvolt = <1310000>;
++		};
++	};
++
+ 	cpus {
+ 		#address-cells = <2>;
+ 		#size-cells = <0>;
+@@ -26,6 +70,10 @@
+ 			device_type = "cpu";
+ 			compatible = "arm,cortex-a53", "arm,armv8";
+ 			reg = <0x0 0x0>;
++			clocks = <&infracfg CLK_INFRA_MUX1_SEL>,
++				 <&apmixedsys CLK_APMIXED_MAIN_CORE_EN>;
++			clock-names = "cpu", "intermediate";
++			operating-points-v2 = <&cpu_opp_table>;
+ 			enable-method = "psci";
+ 			clock-frequency = <1300000000>;
+ 		};
+@@ -34,6 +82,10 @@
+ 			device_type = "cpu";
+ 			compatible = "arm,cortex-a53", "arm,armv8";
+ 			reg = <0x0 0x1>;
++			clocks = <&infracfg CLK_INFRA_MUX1_SEL>,
++				 <&apmixedsys CLK_APMIXED_MAIN_CORE_EN>;
++			clock-names = "cpu", "intermediate";
++			operating-points-v2 = <&cpu_opp_table>;
+ 			enable-method = "psci";
+ 			clock-frequency = <1300000000>;
+ 		};
+-- 
+2.11.0
+
diff --git a/target/linux/mediatek/patches-4.14/0215-arm64-dts-mt7622-turn-uart0-clock-to-real-ones.patch b/target/linux/mediatek/patches-4.14/0215-arm64-dts-mt7622-turn-uart0-clock-to-real-ones.patch
new file mode 100644
index 0000000000..541c46bf47
--- /dev/null
+++ b/target/linux/mediatek/patches-4.14/0215-arm64-dts-mt7622-turn-uart0-clock-to-real-ones.patch
@@ -0,0 +1,50 @@
+From 84b3092b3773777de1ba1ad142e53247fb881ddd Mon Sep 17 00:00:00 2001
+From: Sean Wang <sean.wang@mediatek.com>
+Date: Thu, 28 Dec 2017 18:00:11 +0800
+Subject: [PATCH 215/224] arm64: dts: mt7622: turn uart0 clock to real ones
+
+This patch also cleans up two oscillators that provide clocks for MT7623.
+Switch the uart clocks to the real ones while at it.
+
+Signed-off-by: Sean Wang <sean.wang@mediatek.com>
+Cc: Matthias Brugger <matthias.bgg@gmail.com>
+---
+ arch/arm64/boot/dts/mediatek/mt7622.dtsi | 15 ++-------------
+ 1 file changed, 2 insertions(+), 13 deletions(-)
+
+diff --git a/arch/arm64/boot/dts/mediatek/mt7622.dtsi b/arch/arm64/boot/dts/mediatek/mt7622.dtsi
+index 7256879de4c9..d8a17d10e2ff 100644
+--- a/arch/arm64/boot/dts/mediatek/mt7622.dtsi
++++ b/arch/arm64/boot/dts/mediatek/mt7622.dtsi
+@@ -91,18 +91,6 @@
+ 		};
+ 	};
+ 
+-	uart_clk: dummy25m {
+-		compatible = "fixed-clock";
+-		#clock-cells = <0>;
+-		clock-frequency = <25000000>;
+-	};
+-
+-	bus_clk: dummy280m {
+-		compatible = "fixed-clock";
+-		#clock-cells = <0>;
+-		clock-frequency = <280000000>;
+-	};
+-
+ 	pwrap_clk: dummy40m {
+ 		compatible = "fixed-clock";
+ 		clock-frequency = <40000000>;
+@@ -234,7 +222,8 @@
+ 			     "mediatek,mt6577-uart";
+ 		reg = <0 0x11002000 0 0x400>;
+ 		interrupts = <GIC_SPI 91 IRQ_TYPE_LEVEL_LOW>;
+-		clocks = <&uart_clk>, <&bus_clk>;
++		clocks = <&topckgen CLK_TOP_UART_SEL>,
++			 <&pericfg CLK_PERI_UART1_PD>;
+ 		clock-names = "baud", "bus";
+ 		status = "disabled";
+ 	};
+-- 
+2.11.0
+
diff --git a/target/linux/mediatek/patches-4.14/0216-arm64-dts-mt7622-add-SoC-and-peripheral-related-devi.patch b/target/linux/mediatek/patches-4.14/0216-arm64-dts-mt7622-add-SoC-and-peripheral-related-devi.patch
new file mode 100644
index 0000000000..5db0584122
--- /dev/null
+++ b/target/linux/mediatek/patches-4.14/0216-arm64-dts-mt7622-add-SoC-and-peripheral-related-devi.patch
@@ -0,0 +1,427 @@
+From a69ac853def2f93194e244974f611477a1521a4a Mon Sep 17 00:00:00 2001
+From: Sean Wang <sean.wang@mediatek.com>
+Date: Thu, 28 Dec 2017 18:18:26 +0800
+Subject: [PATCH 216/224] arm64: dts: mt7622: add SoC and peripheral related
+ device nodes
+
+Add watchdog, rtc, auxadc, cir, efuse, rng, uart[1-4], pwm, i2c[0-2],
+spi[0-1], btif and thermal related nodes.
+
+Signed-off-by: Sean Wang <sean.wang@mediatek.com>
+Cc: Andrew-CT Chen <andrew-ct.chen@mediatek.com>
+Cc: Zhiyong Tao <zhiyong.tao@mediatek.com>
+Cc: Zhi Mao <zhi.mao@mediatek.com>
+Cc: Jun Gao <jun.gao@mediatek.com>
+Cc: Leilk Liu <leilk.liu@mediatek.com>
+Cc: Matthias Brugger <matthias.bgg@gmail.com>
+---
+ arch/arm64/boot/dts/mediatek/mt7622-rfb1.dts |  54 ++++++
+ arch/arm64/boot/dts/mediatek/mt7622.dtsi     | 264 +++++++++++++++++++++++++++
+ 2 files changed, 318 insertions(+)
+
+diff --git a/arch/arm64/boot/dts/mediatek/mt7622-rfb1.dts b/arch/arm64/boot/dts/mediatek/mt7622-rfb1.dts
+index b3878656475c..ba6a79caca21 100644
+--- a/arch/arm64/boot/dts/mediatek/mt7622-rfb1.dts
++++ b/arch/arm64/boot/dts/mediatek/mt7622-rfb1.dts
+@@ -235,6 +235,34 @@
+ 	};
+ };
+ 
++&btif {
++	status = "okay";
++};
++
++&cir {
++	pinctrl-names = "default";
++	pinctrl-0 = <&irrx_pins>;
++	status = "okay";
++};
++
++&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>;
+@@ -242,6 +270,32 @@
+ 	status = "okay";
+ };
+ 
++&spi0 {
++	pinctrl-names = "default";
++	pinctrl-0 = <&spic0_pins>;
++	status = "okay";
++};
++
++&spi1 {
++	pinctrl-names = "default";
++	pinctrl-0 = <&spic1_pins>;
++	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";
+ };
+diff --git a/arch/arm64/boot/dts/mediatek/mt7622.dtsi b/arch/arm64/boot/dts/mediatek/mt7622.dtsi
+index d8a17d10e2ff..448cd366995b 100644
+--- a/arch/arm64/boot/dts/mediatek/mt7622.dtsi
++++ b/arch/arm64/boot/dts/mediatek/mt7622.dtsi
+@@ -11,6 +11,7 @@
+ #include <dt-bindings/clock/mt7622-clk.h>
+ #include <dt-bindings/power/mt7622-power.h>
+ #include <dt-bindings/reset/mt7622-reset.h>
++#include <dt-bindings/thermal/thermal.h>
+ 
+ / {
+ 	compatible = "mediatek,mt7622";
+@@ -74,6 +75,7 @@
+ 				 <&apmixedsys CLK_APMIXED_MAIN_CORE_EN>;
+ 			clock-names = "cpu", "intermediate";
+ 			operating-points-v2 = <&cpu_opp_table>;
++			#cooling-cells = <2>;
+ 			enable-method = "psci";
+ 			clock-frequency = <1300000000>;
+ 		};
+@@ -121,6 +123,58 @@
+ 		};
+ 	};
+ 
++	thermal-zones {
++		cpu_thermal: cpu-thermal {
++			polling-delay-passive = <1000>;
++			polling-delay = <1000>;
++
++			thermal-sensors = <&thermal 0>;
++
++			trips {
++				cpu_passive: cpu-passive {
++					temperature = <47000>;
++					hysteresis = <2000>;
++					type = "passive";
++				};
++
++				cpu_active: cpu-active {
++					temperature = <67000>;
++					hysteresis = <2000>;
++					type = "active";
++				};
++
++				cpu_hot: cpu-hot {
++					temperature = <87000>;
++					hysteresis = <2000>;
++					type = "hot";
++				};
++
++				cpu-crit {
++					temperature = <107000>;
++					hysteresis = <2000>;
++					type = "critical";
++				};
++			};
++
++			cooling-maps {
++				map0 {
++					trip = <&cpu_passive>;
++					cooling-device = <&cpu0 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>;
++				};
++
++				map1 {
++					trip = <&cpu_active>;
++					cooling-device = <&cpu0 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>;
++				};
++
++				map2 {
++					trip = <&cpu_hot>;
++					cooling-device = <&cpu0 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>;
++				};
++			};
++		};
++	};
++
+ 	timer {
+ 		compatible = "arm,armv8-timer";
+ 		interrupt-parent = <&gic>;
+@@ -176,6 +230,16 @@
+ 		clock-names = "hif_sel";
+ 	};
+ 
++	cir: cir@10009000 {
++		compatible = "mediatek,mt7622-cir";
++		reg = <0 0x10009000 0 0x1000>;
++		interrupts = <GIC_SPI 175 IRQ_TYPE_LEVEL_LOW>;
++		clocks = <&infracfg CLK_INFRA_IRRX_PD>,
++			 <&topckgen CLK_TOP_AXI_SEL>;
++		clock-names = "clk", "bus";
++		status = "disabled";
++	};
++
+ 	sysirq: interrupt-controller@10200620 {
+ 		compatible = "mediatek,mt7622-sysirq",
+ 			     "mediatek,mt6577-sysirq";
+@@ -185,6 +249,18 @@
+ 		reg = <0 0x10200620 0 0x20>;
+ 	};
+ 
++	efuse: efuse@10206000 {
++		compatible = "mediatek,mt7622-efuse",
++			     "mediatek,efuse";
++		reg = <0 0x10206000 0 0x1000>;
++		#address-cells = <1>;
++		#size-cells = <1>;
++
++		thermal_calibration: calib@198 {
++			reg = <0x198 0xc>;
++		};
++	};
++
+ 	apmixedsys: apmixedsys@10209000 {
+ 		compatible = "mediatek,mt7622-apmixedsys",
+ 			     "syscon";
+@@ -199,6 +275,14 @@
+ 		#clock-cells = <1>;
+ 	};
+ 
++	rng: rng@1020f000 {
++		compatible = "mediatek,mt7622-rng",
++			     "mediatek,mt7623-rng";
++		reg = <0 0x1020f000 0 0x1000>;
++		clocks = <&infracfg CLK_INFRA_TRNG>;
++		clock-names = "rng";
++	};
++
+ 	pio: pinctrl@10211000 {
+ 		compatible = "mediatek,mt7622-pinctrl";
+ 		reg = <0 0x10211000 0 0x1000>;
+@@ -206,6 +290,21 @@
+ 		#gpio-cells = <2>;
+ 	};
+ 
++	watchdog: watchdog@10212000 {
++		compatible = "mediatek,mt7622-wdt",
++			     "mediatek,mt6589-wdt";
++		reg = <0 0x10212000 0 0x800>;
++	};
++
++	rtc: rtc@10212800 {
++		compatible = "mediatek,mt7622-rtc",
++			     "mediatek,soc-rtc";
++		reg = <0 0x10212800 0 0x200>;
++		interrupts = <GIC_SPI 129 IRQ_TYPE_LEVEL_LOW>;
++		clocks = <&topckgen CLK_TOP_RTC>;
++		clock-names = "rtc";
++	};
++
+ 	gic: interrupt-controller@10300000 {
+ 		compatible = "arm,gic-400";
+ 		interrupt-controller;
+@@ -217,6 +316,14 @@
+ 		      <0 0x10360000 0 0x2000>;
+ 	};
+ 
++	auxadc: adc@11001000 {
++		compatible = "mediatek,mt7622-auxadc";
++		reg = <0 0x11001000 0 0x1000>;
++		clocks = <&pericfg CLK_PERI_AUXADC_PD>;
++		clock-names = "main";
++		#io-channel-cells = <1>;
++	};
++
+ 	uart0: serial@11002000 {
+ 		compatible = "mediatek,mt7622-uart",
+ 			     "mediatek,mt6577-uart";
+@@ -228,6 +335,163 @@
+ 		status = "disabled";
+ 	};
+ 
++	uart1: serial@11003000 {
++		compatible = "mediatek,mt7622-uart",
++			     "mediatek,mt6577-uart";
++		reg = <0 0x11003000 0 0x400>;
++		interrupts = <GIC_SPI 92 IRQ_TYPE_LEVEL_LOW>;
++		clocks = <&topckgen CLK_TOP_UART_SEL>,
++			 <&pericfg CLK_PERI_UART1_PD>;
++		clock-names = "baud", "bus";
++		status = "disabled";
++	};
++
++	uart2: serial@11004000 {
++		compatible = "mediatek,mt7622-uart",
++			     "mediatek,mt6577-uart";
++		reg = <0 0x11004000 0 0x400>;
++		interrupts = <GIC_SPI 93 IRQ_TYPE_LEVEL_LOW>;
++		clocks = <&topckgen CLK_TOP_UART_SEL>,
++			 <&pericfg CLK_PERI_UART2_PD>;
++		clock-names = "baud", "bus";
++		status = "disabled";
++	};
++
++	uart3: serial@11005000 {
++		compatible = "mediatek,mt7622-uart",
++			     "mediatek,mt6577-uart";
++		reg = <0 0x11005000 0 0x400>;
++		interrupts = <GIC_SPI 94 IRQ_TYPE_LEVEL_LOW>;
++		clocks = <&topckgen CLK_TOP_UART_SEL>,
++			 <&pericfg CLK_PERI_UART3_PD>;
++		clock-names = "baud", "bus";
++		status = "disabled";
++	};
++
++	pwm: pwm@11006000 {
++		compatible = "mediatek,mt7622-pwm";
++		reg = <0 0x11006000 0 0x1000>;
++		interrupts = <GIC_SPI 77 IRQ_TYPE_LEVEL_LOW>;
++		clocks = <&topckgen CLK_TOP_PWM_SEL>,
++			 <&pericfg CLK_PERI_PWM_PD>,
++			 <&pericfg CLK_PERI_PWM1_PD>,
++			 <&pericfg CLK_PERI_PWM2_PD>,
++			 <&pericfg CLK_PERI_PWM3_PD>,
++			 <&pericfg CLK_PERI_PWM4_PD>,
++			 <&pericfg CLK_PERI_PWM5_PD>,
++			 <&pericfg CLK_PERI_PWM6_PD>;
++		clock-names = "top", "main", "pwm1", "pwm2", "pwm3", "pwm4",
++			      "pwm5", "pwm6";
++		status = "disabled";
++	};
++
++	i2c0: i2c@11007000 {
++		compatible = "mediatek,mt7622-i2c";
++		reg = <0 0x11007000 0 0x90>,
++		      <0 0x11000100 0 0x80>;
++		interrupts = <GIC_SPI 84 IRQ_TYPE_LEVEL_LOW>;
++		clock-div = <16>;
++		clocks = <&pericfg CLK_PERI_I2C0_PD>,
++			 <&pericfg CLK_PERI_AP_DMA_PD>;
++		clock-names = "main", "dma";
++		#address-cells = <1>;
++		#size-cells = <0>;
++		status = "disabled";
++	};
++
++	i2c1: i2c@11008000 {
++		compatible = "mediatek,mt7622-i2c";
++		reg = <0 0x11008000 0 0x90>,
++		      <0 0x11000180 0 0x80>;
++		interrupts = <GIC_SPI 85 IRQ_TYPE_LEVEL_LOW>;
++		clock-div = <16>;
++		clocks = <&pericfg CLK_PERI_I2C1_PD>,
++			 <&pericfg CLK_PERI_AP_DMA_PD>;
++		clock-names = "main", "dma";
++		#address-cells = <1>;
++		#size-cells = <0>;
++		status = "disabled";
++	};
++
++	i2c2: i2c@11009000 {
++		compatible = "mediatek,mt7622-i2c";
++		reg = <0 0x11009000 0 0x90>,
++		      <0 0x11000200 0 0x80>;
++		interrupts = <GIC_SPI 86 IRQ_TYPE_LEVEL_LOW>;
++		clock-div = <16>;
++		clocks = <&pericfg CLK_PERI_I2C2_PD>,
++			 <&pericfg CLK_PERI_AP_DMA_PD>;
++		clock-names = "main", "dma";
++		#address-cells = <1>;
++		#size-cells = <0>;
++		status = "disabled";
++	};
++
++	spi0: spi@1100a000 {
++		compatible = "mediatek,mt7622-spi";
++		reg = <0 0x1100a000 0 0x100>;
++		interrupts = <GIC_SPI 118 IRQ_TYPE_LEVEL_LOW>;
++		clocks = <&topckgen CLK_TOP_SYSPLL3_D2>,
++			 <&topckgen CLK_TOP_SPI0_SEL>,
++			 <&pericfg CLK_PERI_SPI0_PD>;
++		clock-names = "parent-clk", "sel-clk", "spi-clk";
++		#address-cells = <1>;
++		#size-cells = <0>;
++		status = "disabled";
++	};
++
++	thermal: thermal@1100b000 {
++		#thermal-sensor-cells = <1>;
++		compatible = "mediatek,mt7622-thermal";
++		reg = <0 0x1100b000 0 0x1000>;
++		interrupts = <0 78 IRQ_TYPE_LEVEL_LOW>;
++		clocks = <&pericfg CLK_PERI_THERM_PD>,
++			 <&pericfg CLK_PERI_AUXADC_PD>;
++		clock-names = "therm", "auxadc";
++		resets = <&pericfg MT7622_PERI_THERM_SW_RST>;
++		reset-names = "therm";
++		mediatek,auxadc = <&auxadc>;
++		mediatek,apmixedsys = <&apmixedsys>;
++		nvmem-cells = <&thermal_calibration>;
++		nvmem-cell-names = "calibration-data";
++	};
++
++	btif: serial@1100c000 {
++		compatible = "mediatek,mt7622-btif",
++			     "mediatek,mtk-btif";
++		reg = <0 0x1100c000 0 0x1000>;
++		interrupts = <GIC_SPI 90 IRQ_TYPE_LEVEL_LOW>;
++		clocks = <&pericfg CLK_PERI_BTIF_PD>;
++		clock-names = "main";
++		reg-shift = <2>;
++		reg-io-width = <4>;
++		status = "disabled";
++	};
++
++	spi1: spi@11016000 {
++		compatible = "mediatek,mt7622-spi";
++		reg = <0 0x11016000 0 0x100>;
++		interrupts = <GIC_SPI 122 IRQ_TYPE_LEVEL_LOW>;
++		clocks = <&topckgen CLK_TOP_SYSPLL3_D2>,
++			 <&topckgen CLK_TOP_SPI1_SEL>,
++			 <&pericfg CLK_PERI_SPI1_PD>;
++		clock-names = "parent-clk", "sel-clk", "spi-clk";
++		#address-cells = <1>;
++		#size-cells = <0>;
++		status = "disabled";
++	};
++
++	uart4: serial@11019000 {
++		compatible = "mediatek,mt7622-uart",
++			     "mediatek,mt6577-uart";
++		reg = <0 0x11019000 0 0x400>;
++		interrupts = <GIC_SPI 89 IRQ_TYPE_LEVEL_LOW>;
++		clocks = <&topckgen CLK_TOP_UART_SEL>,
++			 <&pericfg CLK_PERI_UART4_PD>;
++		clock-names = "baud", "bus";
++		status = "disabled";
++	};
++
+ 	ssusbsys: ssusbsys@1a000000 {
+ 		compatible = "mediatek,mt7622-ssusbsys",
+ 			     "syscon";
+-- 
+2.11.0
+
diff --git a/target/linux/mediatek/patches-4.14/0217-arm64-dts-mt7622-add-flash-related-device-nodes.patch b/target/linux/mediatek/patches-4.14/0217-arm64-dts-mt7622-add-flash-related-device-nodes.patch
new file mode 100644
index 0000000000..fd11853c4a
--- /dev/null
+++ b/target/linux/mediatek/patches-4.14/0217-arm64-dts-mt7622-add-flash-related-device-nodes.patch
@@ -0,0 +1,103 @@
+From 0a84c72d1c606129b8af670cbcc73be4168ab753 Mon Sep 17 00:00:00 2001
+From: Sean Wang <sean.wang@mediatek.com>
+Date: Fri, 29 Dec 2017 10:36:37 +0800
+Subject: [PATCH 217/224] arm64: dts: mt7622: add flash related device nodes
+
+add nodes for NOR flash, parallel Nand flash with error correction code
+support.
+
+Signed-off-by: Sean Wang <sean.wang@mediatek.com>
+Cc: RogerCC Lin <rogercc.lin@mediatek.com>
+Cc: Guochun Mao <guochun.mao@mediatek.com>
+---
+ arch/arm64/boot/dts/mediatek/mt7622-rfb1.dts | 21 +++++++++++++++++
+ arch/arm64/boot/dts/mediatek/mt7622.dtsi     | 34 ++++++++++++++++++++++++++++
+ 2 files changed, 55 insertions(+)
+
+diff --git a/arch/arm64/boot/dts/mediatek/mt7622-rfb1.dts b/arch/arm64/boot/dts/mediatek/mt7622-rfb1.dts
+index ba6a79caca21..48c5ba472721 100644
+--- a/arch/arm64/boot/dts/mediatek/mt7622-rfb1.dts
++++ b/arch/arm64/boot/dts/mediatek/mt7622-rfb1.dts
+@@ -235,6 +235,10 @@
+ 	};
+ };
+ 
++&bch {
++	status = "disabled";
++};
++
+ &btif {
+ 	status = "okay";
+ };
+@@ -257,6 +261,23 @@
+ 	status = "okay";
+ };
+ 
++&nandc {
++	pinctrl-names = "default";
++	pinctrl-0 = <&parallel_nand_pins>;
++	status = "disabled";
++};
++
++&nor_flash {
++	pinctrl-names = "default";
++	pinctrl-0 = <&spi_nor_pins>;
++	status = "disabled";
++
++	flash@0 {
++		compatible = "jedec,spi-nor";
++		reg = <0>;
++	};
++};
++
+ &pwm {
+ 	pinctrl-names = "default";
+ 	pinctrl-0 = <&pwm7_pins>;
+diff --git a/arch/arm64/boot/dts/mediatek/mt7622.dtsi b/arch/arm64/boot/dts/mediatek/mt7622.dtsi
+index 448cd366995b..d287d75e1a54 100644
+--- a/arch/arm64/boot/dts/mediatek/mt7622.dtsi
++++ b/arch/arm64/boot/dts/mediatek/mt7622.dtsi
+@@ -468,6 +468,40 @@
+ 		status = "disabled";
+ 	};
+ 
++	nandc: nfi@1100d000 {
++		compatible = "mediatek,mt7622-nfc";
++		reg = <0 0x1100D000 0 0x1000>;
++		interrupts = <GIC_SPI 96 IRQ_TYPE_LEVEL_LOW>;
++		clocks = <&pericfg CLK_PERI_NFI_PD>,
++			 <&pericfg CLK_PERI_SNFI_PD>;
++		clock-names = "nfi_clk", "pad_clk";
++		ecc-engine = <&bch>;
++		#address-cells = <1>;
++		#size-cells = <0>;
++		status = "disabled";
++	};
++
++	bch: ecc@1100e000 {
++		compatible = "mediatek,mt7622-ecc";
++		reg = <0 0x1100e000 0 0x1000>;
++		interrupts = <GIC_SPI 95 IRQ_TYPE_LEVEL_LOW>;
++		clocks = <&pericfg CLK_PERI_NFIECC_PD>;
++		clock-names = "nfiecc_clk";
++		status = "disabled";
++	};
++
++	nor_flash: spi@11014000 {
++		compatible = "mediatek,mt7622-nor",
++			     "mediatek,mt8173-nor";
++		reg = <0 0x11014000 0 0xe0>;
++		clocks = <&pericfg CLK_PERI_FLASH_PD>,
++			 <&topckgen CLK_TOP_FLASH_SEL>;
++		clock-names = "spi", "sf";
++		#address-cells = <1>;
++		#size-cells = <0>;
++		status = "disabled";
++	};
++
+ 	spi1: spi@11016000 {
+ 		compatible = "mediatek,mt7622-spi";
+ 		reg = <0 0x11016000 0 0x100>;
+-- 
+2.11.0
+
diff --git a/target/linux/mediatek/patches-4.14/0218-arm64-dts-mt7622-add-ethernet-device-nodes.patch b/target/linux/mediatek/patches-4.14/0218-arm64-dts-mt7622-add-ethernet-device-nodes.patch
new file mode 100644
index 0000000000..82b523c9d1
--- /dev/null
+++ b/target/linux/mediatek/patches-4.14/0218-arm64-dts-mt7622-add-ethernet-device-nodes.patch
@@ -0,0 +1,91 @@
+From 4fbacf244953285ac58cb833060076fafd990588 Mon Sep 17 00:00:00 2001
+From: Sean Wang <sean.wang@mediatek.com>
+Date: Fri, 29 Dec 2017 10:45:07 +0800
+Subject: [PATCH 218/224] arm64: dts: mt7622: add ethernet device nodes
+
+add ethernet device nodes which enable GMAC1 with SGMII interface
+
+Signed-off-by: Sean Wang <sean.wang@mediatek.com>
+---
+ arch/arm64/boot/dts/mediatek/mt7622-rfb1.dts | 22 ++++++++++++++++++++
+ arch/arm64/boot/dts/mediatek/mt7622.dtsi     | 31 ++++++++++++++++++++++++++++
+ 2 files changed, 53 insertions(+)
+
+diff --git a/arch/arm64/boot/dts/mediatek/mt7622-rfb1.dts b/arch/arm64/boot/dts/mediatek/mt7622-rfb1.dts
+index 48c5ba472721..e2bd93e1b49b 100644
+--- a/arch/arm64/boot/dts/mediatek/mt7622-rfb1.dts
++++ b/arch/arm64/boot/dts/mediatek/mt7622-rfb1.dts
+@@ -249,6 +249,28 @@
+ 	status = "okay";
+ };
+ 
++&eth {
++	pinctrl-names = "default";
++	pinctrl-0 = <&eth_pins>;
++	status = "okay";
++
++	gmac1: mac@1 {
++		compatible = "mediatek,eth-mac";
++		reg = <1>;
++		phy-handle = <&phy5>;
++	};
++
++	mdio-bus {
++		#address-cells = <1>;
++		#size-cells = <0>;
++
++		phy5: ethernet-phy@5 {
++			reg = <5>;
++			phy-mode = "sgmii";
++		};
++	};
++};
++
+ &i2c1 {
+ 	pinctrl-names = "default";
+ 	pinctrl-0 = <&i2c1_pins>;
+diff --git a/arch/arm64/boot/dts/mediatek/mt7622.dtsi b/arch/arm64/boot/dts/mediatek/mt7622.dtsi
+index d287d75e1a54..95f947eb824c 100644
+--- a/arch/arm64/boot/dts/mediatek/mt7622.dtsi
++++ b/arch/arm64/boot/dts/mediatek/mt7622.dtsi
+@@ -550,6 +550,37 @@
+ 		#reset-cells = <1>;
+ 	};
+ 
++	eth: ethernet@1b100000 {
++		compatible = "mediatek,mt7622-eth",
++			     "mediatek,mt2701-eth",
++			     "syscon";
++		reg = <0 0x1b100000 0 0x20000>;
++		interrupts = <GIC_SPI 223 IRQ_TYPE_LEVEL_LOW>,
++			     <GIC_SPI 224 IRQ_TYPE_LEVEL_LOW>,
++			     <GIC_SPI 225 IRQ_TYPE_LEVEL_LOW>;
++		clocks = <&topckgen CLK_TOP_ETH_SEL>,
++			 <&ethsys CLK_ETH_ESW_EN>,
++			 <&ethsys CLK_ETH_GP0_EN>,
++			 <&ethsys CLK_ETH_GP1_EN>,
++			 <&ethsys CLK_ETH_GP2_EN>,
++			 <&sgmiisys CLK_SGMII_TX250M_EN>,
++			 <&sgmiisys CLK_SGMII_RX250M_EN>,
++			 <&sgmiisys CLK_SGMII_CDR_REF>,
++			 <&sgmiisys CLK_SGMII_CDR_FB>,
++			 <&topckgen CLK_TOP_SGMIIPLL>,
++			 <&apmixedsys CLK_APMIXED_ETH2PLL>;
++		clock-names = "ethif", "esw", "gp0", "gp1", "gp2",
++			      "sgmii_tx250m", "sgmii_rx250m",
++			      "sgmii_cdr_ref", "sgmii_cdr_fb", "sgmii_ck",
++			      "eth2pll";
++		power-domains = <&scpsys MT7622_POWER_DOMAIN_ETHSYS>;
++		mediatek,ethsys = <&ethsys>;
++		mediatek,sgmiisys = <&sgmiisys>;
++		#address-cells = <1>;
++		#size-cells = <0>;
++		status = "disabled";
++	};
++
+ 	sgmiisys: sgmiisys@1b128000 {
+ 		compatible = "mediatek,mt7622-sgmiisys",
+ 			     "syscon";
+-- 
+2.11.0
+
diff --git a/target/linux/mediatek/patches-4.14/0219-arm64-dts-mt7622-add-PCIe-device-nodes.patch b/target/linux/mediatek/patches-4.14/0219-arm64-dts-mt7622-add-PCIe-device-nodes.patch
new file mode 100644
index 0000000000..83ba63ab96
--- /dev/null
+++ b/target/linux/mediatek/patches-4.14/0219-arm64-dts-mt7622-add-PCIe-device-nodes.patch
@@ -0,0 +1,123 @@
+From e84732bd6022dd12839dd34d508eb27428367c24 Mon Sep 17 00:00:00 2001
+From: Ryder Lee <ryder.lee@mediatek.com>
+Date: Wed, 20 Dec 2017 15:57:30 +0800
+Subject: [PATCH 219/224] arm64: dts: mt7622: add PCIe device nodes
+
+This patch adds PCIe support fot MT7622.
+
+Signed-off-by: Ryder Lee <ryder.lee@mediatek.com>
+Signed-off-by: Sean Wang <sean.wang@mediatek.com>
+---
+ arch/arm64/boot/dts/mediatek/mt7622-rfb1.dts | 10 ++++
+ arch/arm64/boot/dts/mediatek/mt7622.dtsi     | 74 ++++++++++++++++++++++++++++
+ 2 files changed, 84 insertions(+)
+
+diff --git a/arch/arm64/boot/dts/mediatek/mt7622-rfb1.dts b/arch/arm64/boot/dts/mediatek/mt7622-rfb1.dts
+index e2bd93e1b49b..72ef4434bcef 100644
+--- a/arch/arm64/boot/dts/mediatek/mt7622-rfb1.dts
++++ b/arch/arm64/boot/dts/mediatek/mt7622-rfb1.dts
+@@ -54,6 +54,16 @@
+ 	};
+ };
+ 
++&pcie {
++	pinctrl-names = "default";
++	pinctrl-0 = <&pcie0_pins>;
++	status = "okay";
++
++	pcie@0,0 {
++		status = "okay";
++	};
++};
++
+ &pio {
+ 	/* eMMC is shared pin with parallel NAND */
+ 	emmc_pins_default: emmc-pins-default {
+diff --git a/arch/arm64/boot/dts/mediatek/mt7622.dtsi b/arch/arm64/boot/dts/mediatek/mt7622.dtsi
+index 95f947eb824c..cc026ebda2f4 100644
+--- a/arch/arm64/boot/dts/mediatek/mt7622.dtsi
++++ b/arch/arm64/boot/dts/mediatek/mt7622.dtsi
+@@ -542,6 +542,80 @@
+ 		#reset-cells = <1>;
+ 	};
+ 
++	pcie: pcie@1a140000 {
++		compatible = "mediatek,mt7622-pcie";
++		device_type = "pci";
++		reg = <0 0x1a140000 0 0x1000>,
++		      <0 0x1a143000 0 0x1000>,
++		      <0 0x1a145000 0 0x1000>;
++		reg-names = "subsys", "port0", "port1";
++		#address-cells = <3>;
++		#size-cells = <2>;
++		interrupts = <GIC_SPI 228 IRQ_TYPE_LEVEL_LOW>,
++			     <GIC_SPI 229 IRQ_TYPE_LEVEL_LOW>;
++		clocks = <&pciesys CLK_PCIE_P0_MAC_EN>,
++			 <&pciesys CLK_PCIE_P1_MAC_EN>,
++			 <&pciesys CLK_PCIE_P0_AHB_EN>,
++			 <&pciesys CLK_PCIE_P0_AHB_EN>,
++			 <&pciesys CLK_PCIE_P0_AUX_EN>,
++			 <&pciesys CLK_PCIE_P1_AUX_EN>,
++			 <&pciesys CLK_PCIE_P0_AXI_EN>,
++			 <&pciesys CLK_PCIE_P1_AXI_EN>,
++			 <&pciesys CLK_PCIE_P0_OBFF_EN>,
++			 <&pciesys CLK_PCIE_P1_OBFF_EN>,
++			 <&pciesys CLK_PCIE_P0_PIPE_EN>,
++			 <&pciesys CLK_PCIE_P1_PIPE_EN>;
++		clock-names = "sys_ck0", "sys_ck1", "ahb_ck0", "ahb_ck1",
++			      "aux_ck0", "aux_ck1", "axi_ck0", "axi_ck1",
++			      "obff_ck0", "obff_ck1", "pipe_ck0", "pipe_ck1";
++		power-domains = <&scpsys MT7622_POWER_DOMAIN_HIF0>;
++		bus-range = <0x00 0xff>;
++		ranges = <0x82000000 0 0x20000000 0x0 0x20000000 0 0x10000000>;
++		status = "disabled";
++
++		pcie0: pcie@0,0 {
++			reg = <0x0000 0 0 0 0>;
++			#address-cells = <3>;
++			#size-cells = <2>;
++			#interrupt-cells = <1>;
++			ranges;
++			status = "disabled";
++
++			num-lanes = <1>;
++			interrupt-map-mask = <0 0 0 7>;
++			interrupt-map = <0 0 0 1 &pcie_intc0 0>,
++					<0 0 0 2 &pcie_intc0 1>,
++					<0 0 0 3 &pcie_intc0 2>,
++					<0 0 0 4 &pcie_intc0 3>;
++			pcie_intc0: interrupt-controller {
++				interrupt-controller;
++				#address-cells = <0>;
++				#interrupt-cells = <1>;
++			};
++		};
++
++		pcie1: pcie@1,0 {
++			reg = <0x0800 0 0 0 0>;
++			#address-cells = <3>;
++			#size-cells = <2>;
++			#interrupt-cells = <1>;
++			ranges;
++			status = "disabled";
++
++			num-lanes = <1>;
++			interrupt-map-mask = <0 0 0 7>;
++			interrupt-map = <0 0 0 1 &pcie_intc1 0>,
++					<0 0 0 2 &pcie_intc1 1>,
++					<0 0 0 3 &pcie_intc1 2>,
++					<0 0 0 4 &pcie_intc1 3>;
++			pcie_intc1: interrupt-controller {
++				interrupt-controller;
++				#address-cells = <0>;
++				#interrupt-cells = <1>;
++			};
++		};
++	};
++
+ 	ethsys: syscon@1b000000 {
+ 		compatible = "mediatek,mt7622-ethsys",
+ 			     "syscon";
+-- 
+2.11.0
+
diff --git a/target/linux/mediatek/patches-4.14/0220-arm64-dts-mt7622-add-SATA-device-nodes.patch b/target/linux/mediatek/patches-4.14/0220-arm64-dts-mt7622-add-SATA-device-nodes.patch
new file mode 100644
index 0000000000..83abf609c9
--- /dev/null
+++ b/target/linux/mediatek/patches-4.14/0220-arm64-dts-mt7622-add-SATA-device-nodes.patch
@@ -0,0 +1,94 @@
+From 0c8d249a70818f4f8e0d5543dc7157dfd8a5265e Mon Sep 17 00:00:00 2001
+From: Ryder Lee <ryder.lee@mediatek.com>
+Date: Wed, 20 Dec 2017 16:04:24 +0800
+Subject: [PATCH 220/224] arm64: dts: mt7622: add SATA device nodes
+
+This patch adds SATA support fot MT7622.
+
+Signed-off-by: Ryder Lee <ryder.lee@mediatek.com>
+Signed-off-by: Sean Wang <sean.wang@mediatek.com>
+---
+ arch/arm64/boot/dts/mediatek/mt7622-rfb1.dts |  8 ++++++
+ arch/arm64/boot/dts/mediatek/mt7622.dtsi     | 40 ++++++++++++++++++++++++++++
+ 2 files changed, 48 insertions(+)
+
+diff --git a/arch/arm64/boot/dts/mediatek/mt7622-rfb1.dts b/arch/arm64/boot/dts/mediatek/mt7622-rfb1.dts
+index 72ef4434bcef..6715ffa5c15e 100644
+--- a/arch/arm64/boot/dts/mediatek/mt7622-rfb1.dts
++++ b/arch/arm64/boot/dts/mediatek/mt7622-rfb1.dts
+@@ -323,6 +323,14 @@
+ 	status = "okay";
+ };
+ 
++&sata {
++	status = "okay";
++};
++
++&sata_phy {
++	status = "okay";
++};
++
+ &spi0 {
+ 	pinctrl-names = "default";
+ 	pinctrl-0 = <&spic0_pins>;
+diff --git a/arch/arm64/boot/dts/mediatek/mt7622.dtsi b/arch/arm64/boot/dts/mediatek/mt7622.dtsi
+index cc026ebda2f4..881bc17f8f0d 100644
+--- a/arch/arm64/boot/dts/mediatek/mt7622.dtsi
++++ b/arch/arm64/boot/dts/mediatek/mt7622.dtsi
+@@ -9,6 +9,7 @@
+ #include <dt-bindings/interrupt-controller/irq.h>
+ #include <dt-bindings/interrupt-controller/arm-gic.h>
+ #include <dt-bindings/clock/mt7622-clk.h>
++#include <dt-bindings/phy/phy.h>
+ #include <dt-bindings/power/mt7622-power.h>
+ #include <dt-bindings/reset/mt7622-reset.h>
+ #include <dt-bindings/thermal/thermal.h>
+@@ -616,6 +617,45 @@
+ 		};
+ 	};
+ 
++	sata: sata@1a200000 {
++		compatible = "mediatek,mt7622-ahci",
++			     "mediatek,mtk-ahci";
++		reg = <0 0x1a200000 0 0x1100>;
++		interrupts = <GIC_SPI 233 IRQ_TYPE_LEVEL_HIGH>;
++		interrupt-names = "hostc";
++		clocks = <&pciesys CLK_SATA_AHB_EN>,
++			 <&pciesys CLK_SATA_AXI_EN>,
++			 <&pciesys CLK_SATA_ASIC_EN>,
++			 <&pciesys CLK_SATA_RBC_EN>,
++			 <&pciesys CLK_SATA_PM_EN>;
++		clock-names = "ahb", "axi", "asic", "rbc", "pm";
++		phys = <&sata_port PHY_TYPE_SATA>;
++		phy-names = "sata-phy";
++		ports-implemented = <0x1>;
++		power-domains = <&scpsys MT7622_POWER_DOMAIN_HIF0>;
++		resets = <&pciesys MT7622_SATA_AXI_BUS_RST>,
++			 <&pciesys MT7622_SATA_PHY_SW_RST>,
++			 <&pciesys MT7622_SATA_PHY_REG_RST>;
++		reset-names = "axi", "sw", "reg";
++		mediatek,phy-mode = <&pciesys>;
++		status = "disabled";
++	};
++
++	sata_phy: sata-phy@1a243000 {
++		compatible = "mediatek,generic-tphy-v1";
++		#address-cells = <2>;
++		#size-cells = <2>;
++		ranges;
++		status = "disabled";
++
++		sata_port: sata-phy@1a243000 {
++			reg = <0 0x1a243000 0 0x0100>;
++			clocks = <&topckgen CLK_TOP_ETH_500M>;
++			clock-names = "ref";
++			#phy-cells = <1>;
++		};
++	};
++
+ 	ethsys: syscon@1b000000 {
+ 		compatible = "mediatek,mt7622-ethsys",
+ 			     "syscon";
+-- 
+2.11.0
+
diff --git a/target/linux/mediatek/patches-4.14/0221-arm64-dts-mt7622-add-usb-device-nodes.patch b/target/linux/mediatek/patches-4.14/0221-arm64-dts-mt7622-add-usb-device-nodes.patch
new file mode 100644
index 0000000000..9258093cb2
--- /dev/null
+++ b/target/linux/mediatek/patches-4.14/0221-arm64-dts-mt7622-add-usb-device-nodes.patch
@@ -0,0 +1,126 @@
+From 3e23988f5c9c5d54732eda1e8017409ef223048b Mon Sep 17 00:00:00 2001
+From: Chunfeng Yun <chunfeng.yun@mediatek.com>
+Date: Fri, 12 Jan 2018 12:28:31 +0800
+Subject: [PATCH 221/224] arm64: dts: mt7622: add usb device nodes
+
+add xhci node and usb3 phy nodes
+
+Signed-off-by: Chunfeng Yun <chunfeng.yun@mediatek.com>
+Signed-off-by: Sean Wang <sean.wang@mediatek.com>
+Tested-by: Jumin Li <jumin.li@mediatek.com>
+---
+ arch/arm64/boot/dts/mediatek/mt7622-rfb1.dts | 28 +++++++++++++++
+ arch/arm64/boot/dts/mediatek/mt7622.dtsi     | 51 ++++++++++++++++++++++++++++
+ 2 files changed, 79 insertions(+)
+
+diff --git a/arch/arm64/boot/dts/mediatek/mt7622-rfb1.dts b/arch/arm64/boot/dts/mediatek/mt7622-rfb1.dts
+index 6715ffa5c15e..cc89e2e3c597 100644
+--- a/arch/arm64/boot/dts/mediatek/mt7622-rfb1.dts
++++ b/arch/arm64/boot/dts/mediatek/mt7622-rfb1.dts
+@@ -52,6 +52,24 @@
+ 	memory {
+ 		reg = <0 0x40000000 0 0x3F000000>;
+ 	};
++
++	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;
++	};
++
++	reg_5v: regulator-5v {
++		compatible = "regulator-fixed";
++		regulator-name = "fixed-5V";
++		regulator-min-microvolt = <5000000>;
++		regulator-max-microvolt = <5000000>;
++		regulator-boot-on;
++		regulator-always-on;
++	};
+ };
+ 
+ &pcie {
+@@ -343,6 +361,16 @@
+ 	status = "okay";
+ };
+ 
++&ssusb {
++	vusb33-supply = <&reg_3p3v>;
++	vbus-supply = <&reg_5v>;
++	status = "okay";
++};
++
++&u3phy {
++	status = "okay";
++};
++
+ &uart0 {
+ 	pinctrl-names = "default";
+ 	pinctrl-0 = <&uart0_pins>;
+diff --git a/arch/arm64/boot/dts/mediatek/mt7622.dtsi b/arch/arm64/boot/dts/mediatek/mt7622.dtsi
+index 881bc17f8f0d..bad1e997359a 100644
+--- a/arch/arm64/boot/dts/mediatek/mt7622.dtsi
++++ b/arch/arm64/boot/dts/mediatek/mt7622.dtsi
+@@ -535,6 +535,57 @@
+ 		#reset-cells = <1>;
+ 	};
+ 
++	ssusb: usb@1a0c0000 {
++		compatible = "mediatek,mt7622-xhci",
++			     "mediatek,mtk-xhci";
++		reg = <0 0x1a0c0000 0 0x01000>,
++		      <0 0x1a0c4700 0 0x0100>;
++		reg-names = "mac", "ippc";
++		interrupts = <GIC_SPI 232 IRQ_TYPE_LEVEL_LOW>;
++		power-domains = <&scpsys MT7622_POWER_DOMAIN_HIF1>;
++		clocks = <&ssusbsys CLK_SSUSB_SYS_EN>,
++			 <&ssusbsys CLK_SSUSB_REF_EN>,
++			 <&ssusbsys CLK_SSUSB_MCU_EN>,
++			 <&ssusbsys CLK_SSUSB_DMA_EN>;
++		clock-names = "sys_ck", "ref_ck", "mcu_ck", "dma_ck";
++		phys = <&u2port0 PHY_TYPE_USB2>,
++		       <&u3port0 PHY_TYPE_USB3>,
++		       <&u2port1 PHY_TYPE_USB2>;
++
++		status = "disabled";
++	};
++
++	u3phy: usb-phy@1a0c4000 {
++		compatible = "mediatek,mt7622-u3phy",
++			     "mediatek,generic-tphy-v1";
++		reg = <0 0x1a0c4000 0 0x700>;
++		#address-cells = <2>;
++		#size-cells = <2>;
++		ranges;
++		status = "disabled";
++
++		u2port0: usb-phy@1a0c4800 {
++			reg = <0 0x1a0c4800 0 0x0100>;
++			#phy-cells = <1>;
++			clocks = <&ssusbsys CLK_SSUSB_U2_PHY_EN>;
++			clock-names = "ref";
++		};
++
++		u3port0: usb-phy@1a0c4900 {
++			reg = <0 0x1a0c4900 0 0x0700>;
++			#phy-cells = <1>;
++			clocks = <&clk25m>;
++			clock-names = "ref";
++		};
++
++		u2port1: usb-phy@1a0c5000 {
++			reg = <0 0x1a0c5000 0 0x0100>;
++			#phy-cells = <1>;
++			clocks = <&ssusbsys CLK_SSUSB_U2_PHY_1P_EN>;
++			clock-names = "ref";
++		};
++	};
++
+ 	pciesys: pciesys@1a100800 {
+ 		compatible = "mediatek,mt7622-pciesys",
+ 			     "syscon";
+-- 
+2.11.0
+
diff --git a/target/linux/mediatek/patches-4.14/0222-arm64-dts-mt7622-add-High-Speed-DMA-device-nodes.patch b/target/linux/mediatek/patches-4.14/0222-arm64-dts-mt7622-add-High-Speed-DMA-device-nodes.patch
new file mode 100644
index 0000000000..8d22510c8c
--- /dev/null
+++ b/target/linux/mediatek/patches-4.14/0222-arm64-dts-mt7622-add-High-Speed-DMA-device-nodes.patch
@@ -0,0 +1,36 @@
+From c61ef9c4707e38edeafad1bd4d01080d0e0a10da Mon Sep 17 00:00:00 2001
+From: Sean Wang <sean.wang@mediatek.com>
+Date: Wed, 17 Jan 2018 00:52:27 +0800
+Subject: [PATCH 222/224] arm64: dts: mt7622: add High-Speed DMA device nodes
+
+add High-Speed DMA (HSDMA) nodes
+
+Signed-off-by: Sean Wang <sean.wang@mediatek.com>
+---
+ arch/arm64/boot/dts/mediatek/mt7622.dtsi | 10 ++++++++++
+ 1 file changed, 10 insertions(+)
+
+diff --git a/arch/arm64/boot/dts/mediatek/mt7622.dtsi b/arch/arm64/boot/dts/mediatek/mt7622.dtsi
+index bad1e997359a..ffb934b0a097 100644
+--- a/arch/arm64/boot/dts/mediatek/mt7622.dtsi
++++ b/arch/arm64/boot/dts/mediatek/mt7622.dtsi
+@@ -715,6 +715,16 @@
+ 		#reset-cells = <1>;
+ 	};
+ 
++	hsdma: dma-controller@1b007000 {
++		compatible = "mediatek,mt7622-hsdma";
++		reg = <0 0x1b007000 0 0x1000>;
++		interrupts = <GIC_SPI 219 IRQ_TYPE_LEVEL_LOW>;
++		clocks = <&ethsys CLK_ETH_HSDMA_EN>;
++		clock-names = "hsdma";
++		power-domains = <&scpsys MT7622_POWER_DOMAIN_ETHSYS>;
++		#dma-cells = <1>;
++	};
++
+ 	eth: ethernet@1b100000 {
+ 		compatible = "mediatek,mt7622-eth",
+ 			     "mediatek,mt2701-eth",
+-- 
+2.11.0
+
diff --git a/target/linux/mediatek/patches-4.14/0223-arm64-dts-mt7622-add-mmc-related-device-nodes.patch b/target/linux/mediatek/patches-4.14/0223-arm64-dts-mt7622-add-mmc-related-device-nodes.patch
new file mode 100644
index 0000000000..c7c437ac28
--- /dev/null
+++ b/target/linux/mediatek/patches-4.14/0223-arm64-dts-mt7622-add-mmc-related-device-nodes.patch
@@ -0,0 +1,207 @@
+From d41d41bfcbd8ad4bcbb1b433f7d5c3b613c58419 Mon Sep 17 00:00:00 2001
+From: Sean Wang <sean.wang@mediatek.com>
+Date: Mon, 22 Jan 2018 16:58:36 +0800
+Subject: [PATCH 223/224] arm64: dts: mt7622: add mmc related device nodes
+
+add mmc device nodes and proper setup for used pins
+
+Signed-off-by: Sean Wang <sean.wang@mediatek.com>
+Signed-off-by: Jimin Wang <jimin.wang@mediatek.com>
+---
+ arch/arm64/boot/dts/mediatek/mt7622-rfb1.dts | 106 +++++++++++++++++++++++++++
+ arch/arm64/boot/dts/mediatek/mt7622.dtsi     |  20 +++++
+ 2 files changed, 126 insertions(+)
+
+diff --git a/arch/arm64/boot/dts/mediatek/mt7622-rfb1.dts b/arch/arm64/boot/dts/mediatek/mt7622-rfb1.dts
+index cc89e2e3c597..45d8655ee423 100644
+--- a/arch/arm64/boot/dts/mediatek/mt7622-rfb1.dts
++++ b/arch/arm64/boot/dts/mediatek/mt7622-rfb1.dts
+@@ -8,6 +8,7 @@
+ 
+ /dts-v1/;
+ #include <dt-bindings/input/input.h>
++#include <dt-bindings/gpio/gpio.h>
+ 
+ #include "mt7622.dtsi"
+ #include "mt6380.dtsi"
+@@ -53,6 +54,14 @@
+ 		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";
+@@ -89,6 +98,23 @@
+ 			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 {
+@@ -96,6 +122,21 @@
+ 			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 {
+@@ -194,6 +235,27 @@
+ 			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 {
+@@ -201,6 +263,18 @@
+ 			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 */
+@@ -311,6 +385,38 @@
+ 	status = "okay";
+ };
+ 
++&mmc0 {
++	pinctrl-names = "default", "state_uhs";
++	pinctrl-0 = <&emmc_pins_default>;
++	pinctrl-1 = <&emmc_pins_uhs>;
++	status = "okay";
++	bus-width = <8>;
++	max-frequency = <50000000>;
++	cap-mmc-highspeed;
++	mmc-hs200-1_8v;
++	vmmc-supply = <&reg_3p3v>;
++	vqmmc-supply = <&reg_1p8v>;
++	assigned-clocks = <&topckgen CLK_TOP_MSDC30_0_SEL>;
++	assigned-clock-parents = <&topckgen CLK_TOP_UNIV48M>;
++	non-removable;
++};
++
++&mmc1 {
++	pinctrl-names = "default", "state_uhs";
++	pinctrl-0 = <&sd0_pins_default>;
++	pinctrl-1 = <&sd0_pins_uhs>;
++	status = "okay";
++	bus-width = <4>;
++	max-frequency = <50000000>;
++	cap-sd-highspeed;
++	r_smpl = <1>;
++	cd-gpios = <&pio 81 GPIO_ACTIVE_LOW>;
++	vmmc-supply = <&reg_3p3v>;
++	vqmmc-supply = <&reg_3p3v>;
++	assigned-clocks = <&topckgen CLK_TOP_MSDC30_1_SEL>;
++	assigned-clock-parents = <&topckgen CLK_TOP_UNIV48M>;
++};
++
+ &nandc {
+ 	pinctrl-names = "default";
+ 	pinctrl-0 = <&parallel_nand_pins>;
+diff --git a/arch/arm64/boot/dts/mediatek/mt7622.dtsi b/arch/arm64/boot/dts/mediatek/mt7622.dtsi
+index ffb934b0a097..0f1ebddd6619 100644
+--- a/arch/arm64/boot/dts/mediatek/mt7622.dtsi
++++ b/arch/arm64/boot/dts/mediatek/mt7622.dtsi
+@@ -527,6 +527,26 @@
+ 		status = "disabled";
+ 	};
+ 
++	mmc0: mmc@11230000 {
++		compatible = "mediatek,mt7622-mmc";
++		reg = <0 0x11230000 0 0x1000>;
++		interrupts = <GIC_SPI 79 IRQ_TYPE_LEVEL_LOW>;
++		clocks = <&pericfg CLK_PERI_MSDC30_0_PD>,
++			 <&topckgen CLK_TOP_MSDC50_0_SEL>;
++		clock-names = "source", "hclk";
++		status = "disabled";
++	};
++
++	mmc1: mmc@11240000 {
++		compatible = "mediatek,mt7622-mmc";
++		reg = <0 0x11240000 0 0x1000>;
++		interrupts = <GIC_SPI 80 IRQ_TYPE_LEVEL_LOW>;
++		clocks = <&pericfg CLK_PERI_MSDC30_1_PD>,
++			 <&topckgen CLK_TOP_AXI_SEL>;
++		clock-names = "source", "hclk";
++		status = "disabled";
++	};
++
+ 	ssusbsys: ssusbsys@1a000000 {
+ 		compatible = "mediatek,mt7622-ssusbsys",
+ 			     "syscon";
+-- 
+2.11.0
+
diff --git a/target/linux/mediatek/patches-4.14/0224-add-mt7622-defconfig-for-testing-these-new-drivers.patch b/target/linux/mediatek/patches-4.14/0224-add-mt7622-defconfig-for-testing-these-new-drivers.patch
new file mode 100644
index 0000000000..ba128fcc01
--- /dev/null
+++ b/target/linux/mediatek/patches-4.14/0224-add-mt7622-defconfig-for-testing-these-new-drivers.patch
@@ -0,0 +1,294 @@
+From 4d4581541ee9bc4b7aee5e75db561a8128f3a8bd Mon Sep 17 00:00:00 2001
+From: Sean Wang <sean.wang@mediatek.com>
+Date: Fri, 1 Dec 2017 10:57:57 +0800
+Subject: [PATCH 224/224] add mt7622 defconfig for testing these new drivers
+
+---
+ arch/arm64/configs/mt7622_rfb1_defconfig | 275 +++++++++++++++++++++++++++++++
+ 1 file changed, 275 insertions(+)
+ create mode 100644 arch/arm64/configs/mt7622_rfb1_defconfig
+
+diff --git a/arch/arm64/configs/mt7622_rfb1_defconfig b/arch/arm64/configs/mt7622_rfb1_defconfig
+new file mode 100644
+index 000000000000..1870c601cc0f
+--- /dev/null
++++ b/arch/arm64/configs/mt7622_rfb1_defconfig
+@@ -0,0 +1,275 @@
++# CONFIG_LOCALVERSION_AUTO is not set
++CONFIG_DEFAULT_HOSTNAME="(mt7622)"
++# CONFIG_SWAP is not set
++CONFIG_SYSVIPC=y
++# CONFIG_CROSS_MEMORY_ATTACH is not set
++CONFIG_NO_HZ_IDLE=y
++CONFIG_HIGH_RES_TIMERS=y
++CONFIG_IRQ_TIME_ACCOUNTING=y
++CONFIG_BSD_PROCESS_ACCT=y
++CONFIG_BSD_PROCESS_ACCT_V3=y
++CONFIG_IKCONFIG=y
++CONFIG_IKCONFIG_PROC=y
++# CONFIG_UTS_NS is not set
++CONFIG_BLK_DEV_INITRD=y
++CONFIG_INITRAMFS_SOURCE="../prebuilt/bootable/7622_loader/rootfs.cpio.gz"
++# CONFIG_RD_BZIP2 is not set
++# CONFIG_RD_XZ is not set
++# CONFIG_RD_LZO is not set
++# CONFIG_RD_LZ4 is not set
++CONFIG_CC_OPTIMIZE_FOR_SIZE=y
++CONFIG_PERF_EVENTS=y
++# CONFIG_COMPAT_BRK is not set
++CONFIG_JUMP_LABEL=y
++# CONFIG_BLK_DEV_BSG is not set
++# CONFIG_IOSCHED_DEADLINE is not set
++CONFIG_ARCH_MEDIATEK=y
++CONFIG_PCI=y
++CONFIG_PCI_DEBUG=y
++CONFIG_PCIE_MEDIATEK=y
++CONFIG_SCHED_MC=y
++CONFIG_NR_CPUS=2
++CONFIG_PREEMPT=y
++# CONFIG_COMPACTION is not set
++# CONFIG_BOUNCE is not set
++# CONFIG_EFI is not set
++# CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS is not set
++CONFIG_COMPAT=y
++CONFIG_CPU_FREQ=y
++CONFIG_CPU_FREQ_STAT=y
++CONFIG_CPU_FREQ_DEFAULT_GOV_USERSPACE=y
++CONFIG_CPU_FREQ_GOV_PERFORMANCE=y
++CONFIG_CPU_FREQ_GOV_POWERSAVE=y
++CONFIG_CPU_FREQ_GOV_ONDEMAND=y
++CONFIG_CPU_FREQ_GOV_CONSERVATIVE=y
++CONFIG_CPU_FREQ_GOV_SCHEDUTIL=y
++CONFIG_ARM_MEDIATEK_CPUFREQ=y
++CONFIG_NET=y
++CONFIG_PACKET=y
++CONFIG_INET=y
++# CONFIG_INET_XFRM_MODE_TRANSPORT is not set
++# CONFIG_INET_XFRM_MODE_TUNNEL is not set
++# CONFIG_INET_XFRM_MODE_BEET is not set
++# CONFIG_INET_DIAG is not set
++# CONFIG_IPV6 is not set
++CONFIG_BT=y
++CONFIG_BT_RFCOMM=y
++CONFIG_BT_RFCOMM_TTY=y
++CONFIG_BT_BNEP=y
++CONFIG_BT_BNEP_MC_FILTER=y
++CONFIG_BT_BNEP_PROTO_FILTER=y
++CONFIG_BT_HIDP=y
++# CONFIG_BT_HS is not set
++# CONFIG_BT_LE is not set
++CONFIG_BT_HCIUART=y
++CONFIG_BT_HCIVHCI=y
++CONFIG_DEVTMPFS=y
++CONFIG_DEVTMPFS_MOUNT=y
++CONFIG_MTD=y
++# CONFIG_MTD_OF_PARTS is not set
++CONFIG_MTD_NAND=y
++CONFIG_MTD_NAND_MTK=y
++CONFIG_MTD_SPI_NOR=y
++CONFIG_MTD_MT81xx_NOR=y
++# CONFIG_MTD_SPI_NOR_USE_4K_SECTORS is not set
++# CONFIG_BLK_DEV is not set
++CONFIG_BLK_DEV_SD=y
++CONFIG_ATA=y
++CONFIG_AHCI_MTK=y
++CONFIG_NETDEVICES=y
++# CONFIG_NET_VENDOR_3COM is not set
++# CONFIG_NET_VENDOR_ADAPTEC is not set
++# CONFIG_NET_VENDOR_AGERE is not set
++# CONFIG_NET_VENDOR_ALACRITECH is not set
++# CONFIG_NET_VENDOR_ALTEON is not set
++# CONFIG_NET_VENDOR_AMAZON is not set
++# CONFIG_NET_VENDOR_AMD is not set
++# CONFIG_NET_VENDOR_AQUANTIA is not set
++# CONFIG_NET_VENDOR_ARC is not set
++# CONFIG_NET_VENDOR_ATHEROS is not set
++# CONFIG_NET_CADENCE is not set
++# CONFIG_NET_VENDOR_BROADCOM is not set
++# CONFIG_NET_VENDOR_BROCADE is not set
++# CONFIG_NET_VENDOR_CAVIUM is not set
++# CONFIG_NET_VENDOR_CHELSIO is not set
++# CONFIG_NET_VENDOR_CISCO is not set
++# CONFIG_NET_VENDOR_DEC is not set
++# CONFIG_NET_VENDOR_DLINK is not set
++# CONFIG_NET_VENDOR_EMULEX is not set
++# CONFIG_NET_VENDOR_EZCHIP is not set
++# CONFIG_NET_VENDOR_EXAR is not set
++# CONFIG_NET_VENDOR_HISILICON is not set
++# CONFIG_NET_VENDOR_HP is not set
++# CONFIG_NET_VENDOR_HUAWEI is not set
++# CONFIG_NET_VENDOR_INTEL is not set
++# CONFIG_NET_VENDOR_MARVELL is not set
++CONFIG_NET_VENDOR_MEDIATEK=y
++CONFIG_NET_MEDIATEK_SOC=y
++# CONFIG_NET_VENDOR_MELLANOX is not set
++# CONFIG_NET_VENDOR_MICREL is not set
++# CONFIG_NET_VENDOR_MICROCHIP is not set
++# CONFIG_NET_VENDOR_MYRI is not set
++# CONFIG_NET_VENDOR_NATSEMI is not set
++# CONFIG_NET_VENDOR_NETRONOME is not set
++# CONFIG_NET_VENDOR_NVIDIA is not set
++# CONFIG_NET_VENDOR_OKI is not set
++# CONFIG_NET_PACKET_ENGINE is not set
++# CONFIG_NET_VENDOR_QLOGIC is not set
++# CONFIG_NET_VENDOR_QUALCOMM is not set
++# CONFIG_NET_VENDOR_REALTEK is not set
++# CONFIG_NET_VENDOR_RENESAS is not set
++# CONFIG_NET_VENDOR_RDC is not set
++# CONFIG_NET_VENDOR_ROCKER is not set
++# CONFIG_NET_VENDOR_SAMSUNG is not set
++# CONFIG_NET_VENDOR_SEEQ is not set
++# CONFIG_NET_VENDOR_SILAN is not set
++# CONFIG_NET_VENDOR_SIS is not set
++# CONFIG_NET_VENDOR_SOLARFLARE is not set
++# CONFIG_NET_VENDOR_SMSC is not set
++# CONFIG_NET_VENDOR_STMICRO is not set
++# CONFIG_NET_VENDOR_SUN is not set
++# CONFIG_NET_VENDOR_TEHUTI is not set
++# CONFIG_NET_VENDOR_TI is not set
++# CONFIG_NET_VENDOR_VIA is not set
++# CONFIG_NET_VENDOR_WIZNET is not set
++# CONFIG_NET_VENDOR_SYNOPSYS is not set
++CONFIG_ICPLUS_PHY=y
++CONFIG_REALTEK_PHY=y
++CONFIG_USB_CATC=y
++CONFIG_USB_KAWETH=y
++CONFIG_USB_PEGASUS=y
++CONFIG_USB_RTL8150=y
++CONFIG_USB_RTL8152=y
++CONFIG_USB_LAN78XX=y
++CONFIG_USB_USBNET=y
++CONFIG_USB_NET_CDC_EEM=y
++CONFIG_USB_NET_HUAWEI_CDC_NCM=y
++CONFIG_USB_NET_CDC_MBIM=y
++CONFIG_USB_NET_DM9601=y
++CONFIG_USB_NET_SR9700=y
++CONFIG_USB_NET_SR9800=y
++CONFIG_USB_NET_SMSC75XX=y
++CONFIG_USB_NET_SMSC95XX=y
++CONFIG_USB_NET_GL620A=y
++CONFIG_USB_NET_PLUSB=y
++CONFIG_USB_NET_MCS7830=y
++CONFIG_USB_NET_RNDIS_HOST=y
++CONFIG_USB_ALI_M5632=y
++CONFIG_USB_AN2720=y
++CONFIG_USB_EPSON2888=y
++CONFIG_USB_KC2190=y
++CONFIG_USB_NET_CX82310_ETH=y
++CONFIG_USB_NET_KALMIA=y
++CONFIG_USB_NET_QMI_WWAN=y
++CONFIG_USB_NET_INT51X1=y
++CONFIG_USB_IPHETH=y
++CONFIG_USB_SIERRA_NET=y
++CONFIG_USB_VL600=y
++CONFIG_USB_NET_CH9200=y
++CONFIG_INPUT_EVDEV=y
++CONFIG_INPUT_EVBUG=y
++# CONFIG_KEYBOARD_ATKBD is not set
++CONFIG_KEYBOARD_GPIO_POLLED=y
++# CONFIG_INPUT_MOUSE is not set
++CONFIG_SERIO_LIBPS2=y
++CONFIG_VT_HW_CONSOLE_BINDING=y
++CONFIG_LEGACY_PTY_COUNT=16
++CONFIG_SERIAL_8250=y
++CONFIG_SERIAL_8250_CONSOLE=y
++CONFIG_SERIAL_8250_NR_UARTS=3
++CONFIG_SERIAL_8250_RUNTIME_UARTS=3
++CONFIG_SERIAL_8250_MT6577=y
++CONFIG_SERIAL_OF_PLATFORM=y
++CONFIG_SERIAL_DEV_BUS=y
++CONFIG_I2C=y
++CONFIG_I2C_CHARDEV=y
++CONFIG_I2C_MT65XX=y
++CONFIG_I2C_SLAVE=y
++CONFIG_I2C_DEBUG_CORE=y
++CONFIG_I2C_DEBUG_ALGO=y
++CONFIG_I2C_DEBUG_BUS=y
++CONFIG_SPI=y
++CONFIG_SPI_MT65XX=y
++CONFIG_DEBUG_PINCTRL=y
++CONFIG_PINCTRL_MT7622=y
++# CONFIG_PINCTRL_MT8173 is not set
++# CONFIG_PINCTRL_MT6397 is not set
++CONFIG_POWER_RESET_SYSCON=y
++# CONFIG_HWMON is not set
++CONFIG_THERMAL=y
++CONFIG_THERMAL_WRITABLE_TRIPS=y
++CONFIG_THERMAL_GOV_FAIR_SHARE=y
++CONFIG_THERMAL_GOV_BANG_BANG=y
++CONFIG_THERMAL_GOV_USER_SPACE=y
++CONFIG_THERMAL_GOV_POWER_ALLOCATOR=y
++CONFIG_CPU_THERMAL=y
++CONFIG_CLOCK_THERMAL=y
++CONFIG_THERMAL_EMULATION=y
++CONFIG_WATCHDOG=y
++CONFIG_WATCHDOG_SYSFS=y
++CONFIG_MEDIATEK_WATCHDOG=y
++CONFIG_WATCHDOG_PRETIMEOUT_GOV=y
++CONFIG_MFD_MT6397=y
++CONFIG_REGULATOR=y
++CONFIG_REGULATOR_DEBUG=y
++CONFIG_REGULATOR_FIXED_VOLTAGE=y
++CONFIG_REGULATOR_MT6323=y
++CONFIG_REGULATOR_MT6380=y
++CONFIG_RC_CORE=y
++CONFIG_RC_DEVICES=y
++CONFIG_IR_MTK=y
++CONFIG_MEDIA_SUPPORT=y
++CONFIG_USB=y
++# CONFIG_USB_PCI is not set
++# CONFIG_USB_DEFAULT_PERSIST is not set
++CONFIG_USB_XHCI_HCD=y
++CONFIG_USB_XHCI_MTK=y
++CONFIG_USB_STORAGE=y
++CONFIG_USB_STORAGE_DEBUG=y
++CONFIG_MMC=y
++CONFIG_MMC_MTK=y
++CONFIG_NEW_LEDS=y
++CONFIG_LEDS_CLASS=y
++CONFIG_LEDS_USER=y
++CONFIG_LEDS_TRIGGERS=y
++CONFIG_LEDS_TRIGGER_TIMER=y
++CONFIG_LEDS_TRIGGER_ONESHOT=y
++CONFIG_LEDS_TRIGGER_HEARTBEAT=y
++CONFIG_LEDS_TRIGGER_BACKLIGHT=y
++CONFIG_LEDS_TRIGGER_CPU=y
++CONFIG_LEDS_TRIGGER_ACTIVITY=y
++CONFIG_LEDS_TRIGGER_DEFAULT_ON=y
++CONFIG_RTC_CLASS=y
++CONFIG_RTC_DRV_MT7622=y
++CONFIG_DMADEVICES=y
++CONFIG_MTK_HSDMA=y
++CONFIG_DMATEST=y
++# CONFIG_COMMON_CLK_XGENE is not set
++# CONFIG_COMMON_CLK_MT6797 is not set
++CONFIG_COMMON_CLK_MT7622_ETHSYS=y
++CONFIG_COMMON_CLK_MT7622_HIFSYS=y
++CONFIG_COMMON_CLK_MT7622_AUDSYS=y
++# CONFIG_COMMON_CLK_MT8173 is not set
++# CONFIG_IOMMU_SUPPORT is not set
++CONFIG_MTK_PMIC_WRAP=y
++CONFIG_IIO=y
++CONFIG_MEDIATEK_MT6577_AUXADC=y
++CONFIG_PWM=y
++CONFIG_PWM_MEDIATEK=y
++CONFIG_RESET_CONTROLLER=y
++CONFIG_PHY_MTK_TPHY=y
++CONFIG_MTK_EFUSE=y
++CONFIG_TMPFS=y
++# CONFIG_MISC_FILESYSTEMS is not set
++CONFIG_PRINTK_TIME=y
++CONFIG_CONSOLE_LOGLEVEL_DEFAULT=15
++CONFIG_MESSAGE_LOGLEVEL_DEFAULT=7
++CONFIG_DYNAMIC_DEBUG=y
++# CONFIG_ENABLE_WARN_DEPRECATED is not set
++# CONFIG_ENABLE_MUST_CHECK is not set
++CONFIG_DEBUG_FS=y
++CONFIG_DEBUG_SECTION_MISMATCH=y
++# CONFIG_SECTION_MISMATCH_WARN_ONLY is not set
++CONFIG_MAGIC_SYSRQ=y
++CONFIG_DEBUG_KERNEL=y
++# CONFIG_FTRACE is not set
+-- 
+2.11.0
+
-- 
2.30.2