diff mbox

[LEDE-DEV,v2] ipq806x: Add support for ipq40xx AP-DK01.1-C1 and AP-DK04.1-C1

Message ID 1492714537-29604-1-git-send-email-rjangir@codeaurora.org
State Superseded
Headers show

Commit Message

Ram Chandra Jangir April 20, 2017, 6:55 p.m. UTC
This change adds QCA IPQ40xx SoC based AP-DK01.1-C1 and
 AP-DK04.1-C1 boards,

 Supported:
  - AP-DK01.1-C1 and AP-DK04.1-C1 with nor flash boot.
  - ethernet and wifi
  - usb3 works fine

 Test:
  - Tested IPv4 and IPv6 connectivity
  - Router can ping device through WAN interface
  - Device on LAN can ping through router.
  - WiFi connectivity AP as well as STA
  - Validated usb3

Signed-off-by: Ram Chandra Jangir <rjangir@codeaurora.org>
---

Changes since v1:
 * updated review comments.

 target/linux/ipq806x/Makefile                      |    2 +-
 .../ipq806x/base-files/etc/board.d/02_network      |    5 +
 .../etc/hotplug.d/firmware/11-ath10k-caldata       |    8 +
 target/linux/ipq806x/base-files/lib/ipq806x.sh     |    6 +
 target/linux/ipq806x/image/Makefile                |   26 +-
 target/linux/ipq806x/modules.mk                    |   18 +
 ...9-pinctrl-Updated-various-Pin-definitions.patch | 1332 ++++++++++++++++++++
 .../855-clk-qcom-ipq4019-add-ess-reset.patch       |   58 +
 ...-Fix-mdio-driver-to-work-with-IPQ40xx-SoC.patch |  102 ++
 ...arm-dts-Add-ess-switch-device-for-IPQ4019.patch |  355 ++++++
 target/linux/ipq806x/profiles/00-default.mk        |    4 +-
 11 files changed, 1913 insertions(+), 3 deletions(-)
 create mode 100644 target/linux/ipq806x/patches-4.9/852-ipq4019-pinctrl-Updated-various-Pin-definitions.patch
 create mode 100644 target/linux/ipq806x/patches-4.9/855-clk-qcom-ipq4019-add-ess-reset.patch
 create mode 100644 target/linux/ipq806x/patches-4.9/857-ipq40xx-Fix-mdio-driver-to-work-with-IPQ40xx-SoC.patch
 create mode 100644 target/linux/ipq806x/patches-4.9/858-arm-dts-Add-ess-switch-device-for-IPQ4019.patch

Comments

Sven Eckelmann May 22, 2017, 1:52 p.m. UTC | #1
On Freitag, 21. April 2017 00:25:37 CEST Ram Chandra Jangir wrote:
> +@@ -419,18 +424,19 @@
> +                       status = "disabled";
> +
> +                       gmac0: gmac0 {
> +                               local-mac-address = [00 00 00 00 00 00];
> +-                              vlan_tag = <1 0x1f>;
> +-                      };
> +-
> +-                      gmac1: gmac1 {
> +-                              local-mac-address = [00 00 00 00 00 00];
> +                               qcom,phy_mdio_addr = <4>;
> +                               qcom,poll_required = <1>;
> +                               qcom,forced_speed = <1000>;
> +                               qcom,forced_duplex = <1>;
> +                               vlan_tag = <2 0x20>;
> +                       };
> ++
> ++                      gmac1: gmac1 {
> ++                              local-mac-address = [00 00 00 00 00 00];
> ++                              qcom,poll_required_dynamic = <1>;
> ++                              vlan_tag = <1 0x1e>;
> ++                      };

Why did you swap the gmac0 and gmac1 interface? I would guess that you have to 
fix the network setup for the other devices (qcom-ipq4019-rt-ac58u.dts, qcom-
ipq4019-nbg6617.dts, qcom-ipq4019-fritz4040.dts) when you do that.

Kind regards,
	Sven
Ram Chandra Jangir May 23, 2017, 7:11 a.m. UTC | #2
On Freitag, Monday, May 22, 2017 7:22 PM Sven Eckelmann wrote:
>On Freitag, 21. April 2017 00:25:37 CEST Ram Chandra Jangir wrote:
> +@@ -419,18 +424,19 @@
> +                       status = "disabled";
> +
> +                       gmac0: gmac0 {
> +                               local-mac-address = [00 00 00 00 00 00];
> +-                              vlan_tag = <1 0x1f>;
> +-                      };
> +-
> +-                      gmac1: gmac1 {
> +-                              local-mac-address = [00 00 00 00 00 00];
> +                               qcom,phy_mdio_addr = <4>;
> +                               qcom,poll_required = <1>;
> +                               qcom,forced_speed = <1000>;
> +                               qcom,forced_duplex = <1>;
> +                               vlan_tag = <2 0x20>;
> +                       };
> ++
> ++                      gmac1: gmac1 {
> ++                              local-mac-address = [00 00 00 00 00 00];
> ++                              qcom,poll_required_dynamic = <1>;
> ++                              vlan_tag = <1 0x1e>;
> ++                      };

>Why did you swap the gmac0 and gmac1 interface? I would guess that you have
to fix the network setup for the other devices (qcom-ipq4019-rt-ac58u.dts,
qcom- ipq4019-nbg6617.dts, qcom-ipq4019-fritz4040.dts) when you do that.

>Kind regards,
>	Sven


Thanks Sven,

Normally we configure gmac0 for  WAN group and gmac1 for  LAN group,
existing ipq806x boards are also following the same, and we would like to
continue with the  same convention. I do not see any reason to deviate this
in ipq40xx based boards.
I agree that ac58u nbg6617 and fritz4040 needs some changes, and Christian
can help us to make the same.

Thanks,
Ram
Michael Yartys via Lede-dev May 23, 2017, 6:11 p.m. UTC | #3
The sender domain has a DMARC Reject/Quarantine policy which disallows
sending mailing list messages using the original "From" header.

To mitigate this problem, the original message has been wrapped
automatically by the mailing list software.
On Tuesday, May 23, 2017 12:41:41 PM CEST Ram Chandra Jangir wrote:
> On Freitag, Monday, May 22, 2017 7:22 PM Sven Eckelmann wrote:
> >On Freitag, 21. April 2017 00:25:37 CEST Ram Chandra Jangir wrote:
> > +@@ -419,18 +424,19 @@
> > +                       status = "disabled";
> > +
> > +                       gmac0: gmac0 {
> > +                               local-mac-address = [00 00 00 00 00 00];
> > +-                              vlan_tag = <1 0x1f>;
> > +-                      };
> > +-
> > +-                      gmac1: gmac1 {
> > +-                              local-mac-address = [00 00 00 00 00 00];
> > +                               qcom,phy_mdio_addr = <4>;
> > +                               qcom,poll_required = <1>;
> > +                               qcom,forced_speed = <1000>;
> > +                               qcom,forced_duplex = <1>;
> > +                               vlan_tag = <2 0x20>;
> > +                       };
> > ++
> > ++                      gmac1: gmac1 {
> > ++                              local-mac-address = [00 00 00 00 00 00];
> > ++                              qcom,poll_required_dynamic = <1>;
> > ++                              vlan_tag = <1 0x1e>;
> > ++                      };
> 
> >Why did you swap the gmac0 and gmac1 interface? I would guess that you have
> to fix the network setup for the other devices (qcom-ipq4019-rt-ac58u.dts,
> qcom- ipq4019-nbg6617.dts, qcom-ipq4019-fritz4040.dts) when you do that.
> 
> >Kind regards,
> >	Sven
> 
> Thanks Sven,
> 
> Normally we configure gmac0 for  WAN group and gmac1 for  LAN group,
> existing ipq806x boards are also following the same, and we would like to
> continue with the  same convention. I do not see any reason to deviate this
> in ipq40xx based boards.
>
> I agree that ac58u nbg6617 and fritz4040 needs some changes, and Christian
> can help us to make the same.
No. I commented on this issue in v1 of this patch:

<https://www.mail-archive.com/lede-dev@lists.infradead.org/msg07018.html>
| For the record: eth1 IS NOT a separate MAC. From what I can tell, the
| essedma driver just maps different VLANs to multiple ethX instances. 
| So both eth0 and eth1 share the same PSGMII link to the QCA8075. 
| Therefore I suggest to let the kernel handle the VLAN and switch to:
|
|        ucidef_add_switch "switch0" \
|                "0@eth0" "1:lan" "2:lan" "3:lan" "4:lan" "5:wan"
|
|                (the ucidef_set_interfaces_lan_wan gets removed)
|
|This will create eth0.1 and eth0.2 instead of eth0 and eth1.
|I've already tested this and made a patch:
|<https://github.com/chunkeey/LEDE-IPQ40XX/commit/608803737f1c072d3be141f5d8561bc8dd9a4c2d>
| [@John, I think this should fix the weird VLAN issues you had with your box]
|(I'm waiting for AP devices with a AR8036 to see how they behave here)

There's no GMAC1/eth1. it's just a virtual construct in the
essedma driver that is not upstreamable. I think any time
spent on reassigning, renaming or rearranging these custom
properties: vlan_tags, phy-mdio-addr, ... is better spend elsewhere...
Like:
 - adding qca8075 support to the existing qca8k driver.
   From what I know John is looking into this.
 - writing a proper DSA driver for the internal ess-switch (1).
 - remove cruft from essedma and get everything upstream.

(1): Chris Blake picked up an Meraki MR33. The MR33 only has a
single PHY chip: QCA8033. It's PHY ID matches the ar8035 and it
is supported by the at803x driver.

However, he ran into a big issue with the current ar40xx.c code.
The internal ess-switch does not have a working autoneg for connected
single PHYs. Meraki solved this by polling the QCA8033's MII status
register and forcing the ess-switch's port to match its speed and 
duplex setting. This will need to be addressed as well!

Thanks,
Christian
diff mbox

Patch

diff --git a/target/linux/ipq806x/Makefile b/target/linux/ipq806x/Makefile
index e78273c..c60f558 100644
--- a/target/linux/ipq806x/Makefile
+++ b/target/linux/ipq806x/Makefile
@@ -20,7 +20,7 @@  DEFAULT_PACKAGES += \
 	kmod-ata-core kmod-ata-ahci kmod-ata-ahci-platform \
 	kmod-usb-core kmod-usb-ohci kmod-usb2 kmod-usb-ledtrig-usbport \
 	kmod-usb3 kmod-usb-dwc3-of-simple kmod-usb-phy-qcom-dwc3 \
-	kmod-ath10k wpad-mini \
+	kmod-usb-phy-dwc3-ipq40xx kmod-ath10k wpad-mini \
 	uboot-envtools
 
 $(eval $(call BuildTarget))
diff --git a/target/linux/ipq806x/base-files/etc/board.d/02_network b/target/linux/ipq806x/base-files/etc/board.d/02_network
index 36e0fb3..a0b6b30 100755
--- a/target/linux/ipq806x/base-files/etc/board.d/02_network
+++ b/target/linux/ipq806x/base-files/etc/board.d/02_network
@@ -48,6 +48,11 @@  nbg6817)
 	ucidef_set_interface_macaddr "lan" "$hw_mac_addr"
 	ucidef_set_interface_macaddr "wan" "$(macaddr_add $hw_mac_addr 1)"
 	;;
+ap-dk01.1-c1|\
+ap-dk04.1-c1)
+	ucidef_add_switch "switch0" \
+		"1:lan" "2:lan" "3:lan" "4:lan" "0@eth1" "5:wan" "0@eth0"
+	;;
 *)
 	echo "Unsupported hardware. Network interfaces not intialized"
 	;;
diff --git a/target/linux/ipq806x/base-files/etc/hotplug.d/firmware/11-ath10k-caldata b/target/linux/ipq806x/base-files/etc/hotplug.d/firmware/11-ath10k-caldata
index 6526212..46f3f92 100644
--- a/target/linux/ipq806x/base-files/etc/hotplug.d/firmware/11-ath10k-caldata
+++ b/target/linux/ipq806x/base-files/etc/hotplug.d/firmware/11-ath10k-caldata
@@ -51,6 +51,10 @@  case "$FIRMWARE" in
 	fritz4040)
 		/usr/bin/fritz_cal_extract -i 1 -s 0x400 -e 0x207 -l 12064 -o /lib/firmware/$FIRMWARE $(find_mtd_chardev "urlader_config")
 		;;
+	ap-dk01.1-c1 |\
+	ap-dk04.1-c1)
+		ath10kcal_extract "0:ART" 4096 12064
+		;;
 	esac
 	;;
 "ath10k/pre-cal-ahb-a800000.wifi.bin")
@@ -58,6 +62,10 @@  case "$FIRMWARE" in
 	fritz4040)
 		/usr/bin/fritz_cal_extract -i 1 -s 0x400 -e 0x208 -l 12064 -o /lib/firmware/$FIRMWARE $(find_mtd_chardev "urlader_config")
 		;;
+	ap-dk01.1-c1 |\
+	ap-dk04.1-c1)
+		ath10kcal_extract "0:ART" 20480 12064
+		;;
 	esac
 	;;
 
diff --git a/target/linux/ipq806x/base-files/lib/ipq806x.sh b/target/linux/ipq806x/base-files/lib/ipq806x.sh
index 348a3a8..e2bebf5 100644
--- a/target/linux/ipq806x/base-files/lib/ipq806x.sh
+++ b/target/linux/ipq806x/base-files/lib/ipq806x.sh
@@ -47,6 +47,12 @@  ipq806x_board_detect() {
 	*"VR2600v")
 		name="vr2600v"
 		;;
+	*"AP-DK01.1-C1")
+		name="ap-dk01.1-c1"
+		;;
+	*"AP-DK04.1-C1")
+		name="ap-dk04.1-c1"
+		;;
 	esac
 
 	[ -z "$name" ] && name="unknown"
diff --git a/target/linux/ipq806x/image/Makefile b/target/linux/ipq806x/image/Makefile
index de6ddb6..6ebcde5 100644
--- a/target/linux/ipq806x/image/Makefile
+++ b/target/linux/ipq806x/image/Makefile
@@ -250,7 +250,31 @@  define Device/VR2600v
 	IMAGE/sysupgrade.bin := pad-extra 512 | append-kernel | pad-to $$$${KERNEL_SIZE} | append-rootfs | pad-rootfs | append-metadata
 endef
 
+define Device/AP-DK01.1-C1
+	$(call Device/FitImage)
+	DEVICE_DTS := qcom-ipq4019-ap.dk01.1-c1
+	KERNEL_LOADADDR := 0x80208000
+	KERNEL_INSTALL := 1
+	KERNEL_SIZE := 4048k
+	BLOCKSIZE := 128k
+	PAGESIZE := 2048
+	BOARD_NAME := ap-dk01.1-c1
+	DEVICE_TITLE := QCA AP-DK01.1-C1
+endef
+
+define Device/AP-DK04.1-C1
+	$(call Device/FitImage)
+	DEVICE_DTS := qcom-ipq4019-ap.dk04.1-c1
+	KERNEL_LOADADDR := 0x80208000
+	KERNEL_INSTALL := 1
+	KERNEL_SIZE := 4048k
+	BLOCKSIZE := 128k
+	PAGESIZE := 2048
+	BOARD_NAME := ap-dk04.1-c1
+	DEVICE_TITLE := QCA AP-DK04.1-C1
+endef
+
 TARGET_DEVICES += AP148 AP148-legacy C2600 D7800 DB149 EA8500 FRITZ4040 R7500 \
-		  R7500v2 R7800 NBG6817 VR2600v
+		  R7500v2 R7800 NBG6817 VR2600v AP-DK01.1-C1 AP-DK04.1-C1
 
 $(eval $(call BuildImage))
diff --git a/target/linux/ipq806x/modules.mk b/target/linux/ipq806x/modules.mk
index 6f1ca2d..a4a4ed3 100644
--- a/target/linux/ipq806x/modules.mk
+++ b/target/linux/ipq806x/modules.mk
@@ -29,3 +29,21 @@  define KernelPackage/usb-phy-qcom-dwc3/description
 endef
 
 $(eval $(call KernelPackage,usb-phy-qcom-dwc3))
+
+define KernelPackage/usb-phy-dwc3-ipq40xx
+  TITLE:=DWC3 USB IPQ40xx PHY driver
+  DEPENDS:=@TARGET_ipq806x
+  KCONFIG:=CONFIG_USB_IPQ4019_PHY
+  FILES:= \
+	$(LINUX_DIR)/drivers/usb/phy/phy-qca-baldur.ko \
+	$(LINUX_DIR)/drivers/usb/phy/phy-qca-uniphy.ko
+  AUTOLOAD:=$(call AutoLoad,45,phy-qca-baldur phy-qca-uniphy,1)
+  $(call AddDepends/usb)
+endef
+
+define KernelPackage/usb-phy-dwc3-ipq40xx/description
+ This driver provides support for the integrated DesignWare
+ USB3 IP Core within the IPQ40xx SoCs.
+endef
+
+$(eval $(call KernelPackage,usb-phy-dwc3-ipq40xx))
diff --git a/target/linux/ipq806x/patches-4.9/852-ipq4019-pinctrl-Updated-various-Pin-definitions.patch b/target/linux/ipq806x/patches-4.9/852-ipq4019-pinctrl-Updated-various-Pin-definitions.patch
new file mode 100644
index 0000000..4267d47
--- /dev/null
+++ b/target/linux/ipq806x/patches-4.9/852-ipq4019-pinctrl-Updated-various-Pin-definitions.patch
@@ -0,0 +1,1332 @@ 
+From fc6cf61517b8b4ab4678659936fc7572f699d6e7 Mon Sep 17 00:00:00 2001
+From: Ram Chandra Jangir <rjangir@codeaurora.org>
+Date: Tue, 28 Mar 2017 14:00:00 +0530
+Subject: [PATCH] ipq4019: pinctrl: Updated various Pin definitions
+
+Populate default values for various GPIO functions
+
+Signed-off-by: Ram Chandra Jangir <rjangir@codeaurora.org>
+---
+ drivers/pinctrl/qcom/pinctrl-ipq4019.c | 1189 +++++++++++++++++++++++++++++---
+ 1 file changed, 1111 insertions(+), 78 deletions(-)
+
+diff --git a/drivers/pinctrl/qcom/pinctrl-ipq4019.c b/drivers/pinctrl/qcom/pinctrl-ipq4019.c
+index 743d1f4..571eb51 100644
+--- a/drivers/pinctrl/qcom/pinctrl-ipq4019.c
++++ b/drivers/pinctrl/qcom/pinctrl-ipq4019.c
+@@ -276,16 +276,531 @@ DECLARE_QCA_GPIO_PINS(99);
+
+
+ enum ipq4019_functions {
++	qca_mux_rmii0_refclk,
++	qca_mux_wifi0_rfsilient0,
++	qca_mux_wifi1_rfsilient0,
++	qca_mux_smart2,
++	qca_mux_led4,
++	qca_mux_wifi0_cal,
++	qca_mux_wifi1_cal,
++	qca_mux_wifi_wci0,
++	qca_mux_rmii0_dv,
++	qca_mux_wifi_wci1,
++	qca_mux_rmii1_refclk,
++	qca_mux_blsp_spi1,
++	qca_mux_led5,
++	qca_mux_rmii10,
++	qca_mux_led6,
++	qca_mux_rmii11,
++	qca_mux_led7,
++	qca_mux_rmii1_dv,
++	qca_mux_led8,
++	qca_mux_rmii1_tx,
++	qca_mux_aud_pin,
++	qca_mux_led9,
++	qca_mux_rmii1_rx,
++	qca_mux_led10,
++	qca_mux_wifi0_rfsilient1,
++	qca_mux_wifi1_rfsilient1,
++	qca_mux_led11,
++	qca_mux_boot7,
++	qca_mux_qpic_pad,
++	qca_mux_pcie_clk,
++	qca_mux_tm_clk0,
++	qca_mux_wifi00,
++	qca_mux_wifi10,
++	qca_mux_mdio1,
++	qca_mux_prng_rosc,
++	qca_mux_dbg_out,
++	qca_mux_tm0,
++	qca_mux_wifi01,
++	qca_mux_wifi11,
++	qca_mux_atest_char3,
++	qca_mux_pmu0,
++	qca_mux_boot8,
++	qca_mux_tm1,
++	qca_mux_atest_char2,
++	qca_mux_pmu1,
++	qca_mux_boot9,
++	qca_mux_tm2,
++	qca_mux_atest_char1,
++	qca_mux_tm_ack,
++	qca_mux_wifi03,
++	qca_mux_wifi13,
++	qca_mux_qpic_pad4,
++	qca_mux_atest_char0,
++	qca_mux_tm3,
++	qca_mux_wifi02,
++	qca_mux_wifi12,
++	qca_mux_qpic_pad5,
++	qca_mux_smart3,
++	qca_mux_wcss0_dbg14,
++	qca_mux_tm4,
++	qca_mux_wifi04,
++	qca_mux_wifi14,
++	qca_mux_qpic_pad6,
++	qca_mux_wcss0_dbg15,
++	qca_mux_qdss_tracectl_a,
++	qca_mux_boot18,
++	qca_mux_tm5,
++	qca_mux_qpic_pad7,
++	qca_mux_atest_char,
++	qca_mux_wcss0_dbg4,
++	qca_mux_qdss_traceclk_a,
++	qca_mux_boot19,
++	qca_mux_tm6,
++	qca_mux_wcss0_dbg5,
++	qca_mux_qdss_cti_trig_out_a0,
++	qca_mux_boot14,
++	qca_mux_tm7,
++	qca_mux_chip_rst,
++	qca_mux_wcss0_dbg6,
++	qca_mux_qdss_cti_trig_out_b0,
++	qca_mux_boot11,
++	qca_mux_tm8,
++	qca_mux_wcss0_dbg7,
++	qca_mux_wcss1_dbg7,
++	qca_mux_boot20,
++	qca_mux_tm9,
++	qca_mux_qpic_pad1,
++	qca_mux_wcss0_dbg8,
++	qca_mux_wcss1_dbg8,
++	qca_mux_qpic_pad2,
++	qca_mux_wcss0_dbg9,
++	qca_mux_wcss1_dbg9,
++	qca_mux_qpic_pad3,
++	qca_mux_wcss0_dbg10,
++	qca_mux_wcss1_dbg10,
++	qca_mux_qpic_pad0,
++	qca_mux_wcss0_dbg11,
++	qca_mux_wcss1_dbg11,
++	qca_mux_qpic_pad8,
++	qca_mux_wcss0_dbg12,
++	qca_mux_wcss1_dbg12,
++	qca_mux_wifi034,
++	qca_mux_wifi134,
++	qca_mux_jtag_tdi,
+	qca_mux_gpio,
++	qca_mux_i2s_rx_bclk,
++	qca_mux_jtag_tck,
++	qca_mux_i2s_rx_fsync,
++	qca_mux_jtag_tms,
++	qca_mux_i2s_rxd,
++	qca_mux_smart0,
++	qca_mux_jtag_tdo,
++	qca_mux_jtag_rst,
++	qca_mux_jtag_trst,
++	qca_mux_mdio0,
++	qca_mux_wcss0_dbg18,
++	qca_mux_wcss1_dbg18,
++	qca_mux_qdss_tracedata_a,
++	qca_mux_mdc,
++	qca_mux_wcss0_dbg19,
++	qca_mux_wcss1_dbg19,
+	qca_mux_blsp_uart1,
++	qca_mux_wifi0_uart,
++	qca_mux_wifi1_uart,
++	qca_mux_smart1,
++	qca_mux_wcss0_dbg20,
++	qca_mux_wcss1_dbg20,
++	qca_mux_wifi0_uart0,
++	qca_mux_wifi1_uart0,
++	qca_mux_wcss0_dbg21,
++	qca_mux_wcss1_dbg21,
+	qca_mux_blsp_i2c0,
++	qca_mux_wcss0_dbg22,
++	qca_mux_wcss1_dbg22,
++	qca_mux_wcss0_dbg23,
++	qca_mux_wcss1_dbg23,
++	qca_mux_blsp_spi0,
+	qca_mux_blsp_i2c1,
++	qca_mux_wcss0_dbg24,
++	qca_mux_wcss1_dbg24,
++	qca_mux_wcss0_dbg25,
++	qca_mux_wcss1_dbg25,
++	qca_mux_wcss0_dbg26,
++	qca_mux_wcss1_dbg26,
++	qca_mux_wcss0_dbg,
++	qca_mux_wcss1_dbg,
+	qca_mux_blsp_uart0,
+-	qca_mux_blsp_spi1,
+-	qca_mux_blsp_spi0,
++	qca_mux_led0,
++	qca_mux_wcss0_dbg28,
++	qca_mux_wcss1_dbg28,
++	qca_mux_led1,
++	qca_mux_wcss0_dbg29,
++	qca_mux_wcss1_dbg29,
++	qca_mux_wifi0_uart1,
++	qca_mux_wifi1_uart1,
++	qca_mux_wcss0_dbg30,
++	qca_mux_wcss1_dbg30,
++	qca_mux_wcss0_dbg31,
++	qca_mux_wcss1_dbg31,
++	qca_mux_i2s_rx_mclk,
++	qca_mux_wcss0_dbg16,
++	qca_mux_wcss1_dbg16,
++	qca_mux_wcss0_dbg17,
++	qca_mux_wcss1_dbg17,
++	qca_mux_rgmii0,
++	qca_mux_sdio0,
++	qca_mux_rgmii1,
++	qca_mux_sdio1,
++	qca_mux_rgmii2,
++	qca_mux_i2s_tx_mclk,
++	qca_mux_sdio2,
++	qca_mux_rgmii3,
++	qca_mux_i2s_tx_bclk,
++	qca_mux_sdio3,
++	qca_mux_rgmii_rx,
++	qca_mux_i2s_tx_fsync,
++	qca_mux_sdio_clk,
++	qca_mux_rgmii_txc,
++	qca_mux_i2s_td1,
++	qca_mux_sdio_cmd,
++	qca_mux_i2s_td2,
++	qca_mux_sdio4,
++	qca_mux_i2s_td3,
++	qca_mux_sdio5,
++	qca_mux_audio_pwm0,
++	qca_mux_sdio6,
++	qca_mux_audio_pwm1,
++	qca_mux_wcss0_dbg27,
++	qca_mux_wcss1_dbg27,
++	qca_mux_sdio7,
++	qca_mux_rgmii_rxc,
++	qca_mux_audio_pwm2,
++	qca_mux_rgmii_tx,
++	qca_mux_audio_pwm3,
++	qca_mux_boot2,
++	qca_mux_i2s_spdif_in,
++	qca_mux_i2s_spdif_out,
++	qca_mux_rmii00,
++	qca_mux_led2,
++	qca_mux_rmii01,
++	qca_mux_wifi0_wci,
++	qca_mux_wifi1_wci,
++	qca_mux_boot4,
++	qca_mux_rmii0_tx,
++	qca_mux_boot5,
++	qca_mux_rmii0_rx,
++	qca_mux_pcie_clk1,
++	qca_mux_led3,
++	qca_mux_sdio_cd,
+	qca_mux_NA,
+ };
+
++static const char * const rmii0_refclk_groups[] = {
++	"gpio40",
++};
++static const char * const wifi0_rfsilient0_groups[] = {
++	"gpio40",
++};
++static const char * const wifi1_rfsilient0_groups[] = {
++	"gpio40",
++};
++static const char * const smart2_groups[] = {
++	"gpio40", "gpio41", "gpio48", "gpio49",
++};
++static const char * const led4_groups[] = {
++	"gpio40",
++};
++static const char * const wifi0_cal_groups[] = {
++	"gpio41", "gpio51",
++};
++static const char * const wifi1_cal_groups[] = {
++	"gpio41", "gpio51",
++};
++static const char * const wifi_wci0_groups[] = {
++	"gpio42",
++};
++static const char * const rmii0_dv_groups[] = {
++	"gpio43",
++};
++static const char * const wifi_wci1_groups[] = {
++	"gpio43",
++};
++static const char * const rmii1_refclk_groups[] = {
++	"gpio44",
++};
++static const char * const blsp_spi1_groups[] = {
++	"gpio44", "gpio45", "gpio46", "gpio47",
++};
++static const char * const led5_groups[] = {
++	"gpio44",
++};
++static const char * const rmii10_groups[] = {
++	"gpio45", "gpio50",
++};
++static const char * const led6_groups[] = {
++	"gpio45",
++};
++static const char * const rmii11_groups[] = {
++	"gpio46", "gpio51",
++};
++static const char * const led7_groups[] = {
++	"gpio46",
++};
++static const char * const rmii1_dv_groups[] = {
++	"gpio47",
++};
++static const char * const led8_groups[] = {
++	"gpio47",
++};
++static const char * const rmii1_tx_groups[] = {
++	"gpio48",
++};
++static const char * const aud_pin_groups[] = {
++	"gpio48", "gpio49", "gpio50", "gpio51",
++};
++static const char * const led9_groups[] = {
++	"gpio48",
++};
++static const char * const rmii1_rx_groups[] = {
++	"gpio49",
++};
++static const char * const led10_groups[] = {
++	"gpio49",
++};
++static const char * const wifi0_rfsilient1_groups[] = {
++	"gpio50",
++};
++static const char * const wifi1_rfsilient1_groups[] = {
++	"gpio50",
++};
++static const char * const led11_groups[] = {
++	"gpio50",
++};
++static const char * const boot7_groups[] = {
++	"gpio51",
++};
++static const char * const qpic_pad_groups[] = {
++	"gpio52", "gpio53", "gpio54", "gpio55", "gpio56", "gpio61", "gpio62",
++	"gpio63", "gpio69",
++};
++static const char * const pcie_clk_groups[] = {
++	"gpio52",
++};
++static const char * const tm_clk0_groups[] = {
++	"gpio52",
++};
++static const char * const wifi00_groups[] = {
++	"gpio52",
++};
++static const char * const wifi10_groups[] = {
++	"gpio52",
++};
++static const char * const mdio1_groups[] = {
++	"gpio53",
++};
++static const char * const prng_rosc_groups[] = {
++	"gpio53",
++};
++static const char * const dbg_out_groups[] = {
++	"gpio53",
++};
++static const char * const tm0_groups[] = {
++	"gpio53",
++};
++static const char * const wifi01_groups[] = {
++	"gpio53",
++};
++static const char * const wifi11_groups[] = {
++	"gpio53",
++};
++static const char * const atest_char3_groups[] = {
++	"gpio54",
++};
++static const char * const pmu0_groups[] = {
++	"gpio54",
++};
++static const char * const boot8_groups[] = {
++	"gpio54",
++};
++static const char * const tm1_groups[] = {
++	"gpio54",
++};
++static const char * const atest_char2_groups[] = {
++	"gpio55",
++};
++static const char * const pmu1_groups[] = {
++	"gpio55",
++};
++static const char * const boot9_groups[] = {
++	"gpio55",
++};
++static const char * const tm2_groups[] = {
++	"gpio55",
++};
++static const char * const atest_char1_groups[] = {
++	"gpio56",
++};
++static const char * const tm_ack_groups[] = {
++	"gpio56",
++};
++static const char * const wifi03_groups[] = {
++	"gpio56",
++};
++static const char * const wifi13_groups[] = {
++	"gpio56",
++};
++static const char * const qpic_pad4_groups[] = {
++	"gpio57",
++};
++static const char * const atest_char0_groups[] = {
++	"gpio57",
++};
++static const char * const tm3_groups[] = {
++	"gpio57",
++};
++static const char * const wifi02_groups[] = {
++	"gpio57",
++};
++static const char * const wifi12_groups[] = {
++	"gpio57",
++};
++static const char * const qpic_pad5_groups[] = {
++	"gpio58",
++};
++static const char * const smart3_groups[] = {
++	"gpio58", "gpio59", "gpio60", "gpio61",
++};
++static const char * const wcss0_dbg14_groups[] = {
++	"gpio58",
++};
++static const char * const tm4_groups[] = {
++	"gpio58",
++};
++static const char * const wifi04_groups[] = {
++	"gpio58",
++};
++static const char * const wifi14_groups[] = {
++	"gpio58",
++};
++static const char * const qpic_pad6_groups[] = {
++	"gpio59",
++};
++static const char * const wcss0_dbg15_groups[] = {
++	"gpio59",
++};
++static const char * const qdss_tracectl_a_groups[] = {
++	"gpio59",
++};
++static const char * const boot18_groups[] = {
++	"gpio59",
++};
++static const char * const tm5_groups[] = {
++	"gpio59",
++};
++static const char * const qpic_pad7_groups[] = {
++	"gpio60",
++};
++static const char * const atest_char_groups[] = {
++	"gpio60",
++};
++static const char * const wcss0_dbg4_groups[] = {
++	"gpio60",
++};
++static const char * const qdss_traceclk_a_groups[] = {
++	"gpio60",
++};
++static const char * const boot19_groups[] = {
++	"gpio60",
++};
++static const char * const tm6_groups[] = {
++	"gpio60",
++};
++static const char * const wcss0_dbg5_groups[] = {
++	"gpio61",
++};
++static const char * const qdss_cti_trig_out_a0_groups[] = {
++	"gpio61",
++};
++static const char * const boot14_groups[] = {
++	"gpio61",
++};
++static const char * const tm7_groups[] = {
++	"gpio61",
++};
++static const char * const chip_rst_groups[] = {
++	"gpio62",
++};
++static const char * const wcss0_dbg6_groups[] = {
++	"gpio62",
++};
++static const char * const qdss_cti_trig_out_b0_groups[] = {
++	"gpio62",
++};
++static const char * const boot11_groups[] = {
++	"gpio62",
++};
++static const char * const tm8_groups[] = {
++	"gpio62",
++};
++static const char * const wcss0_dbg7_groups[] = {
++	"gpio63",
++};
++static const char * const wcss1_dbg7_groups[] = {
++	"gpio63",
++};
++static const char * const boot20_groups[] = {
++	"gpio63",
++};
++static const char * const tm9_groups[] = {
++	"gpio63",
++};
++static const char * const qpic_pad1_groups[] = {
++	"gpio64",
++};
++static const char * const wcss0_dbg8_groups[] = {
++	"gpio64",
++};
++static const char * const wcss1_dbg8_groups[] = {
++	"gpio64",
++};
++static const char * const qpic_pad2_groups[] = {
++	"gpio65",
++};
++static const char * const wcss0_dbg9_groups[] = {
++	"gpio65",
++};
++static const char * const wcss1_dbg9_groups[] = {
++	"gpio65",
++};
++static const char * const qpic_pad3_groups[] = {
++	"gpio66",
++};
++static const char * const wcss0_dbg10_groups[] = {
++	"gpio66",
++};
++static const char * const wcss1_dbg10_groups[] = {
++	"gpio66",
++};
++static const char * const qpic_pad0_groups[] = {
++	"gpio67",
++};
++static const char * const wcss0_dbg11_groups[] = {
++	"gpio67",
++};
++static const char * const wcss1_dbg11_groups[] = {
++	"gpio67",
++};
++static const char * const qpic_pad8_groups[] = {
++	"gpio68",
++};
++static const char * const wcss0_dbg12_groups[] = {
++	"gpio68",
++};
++static const char * const wcss1_dbg12_groups[] = {
++	"gpio68",
++};
++static const char * const wifi034_groups[] = {
++	"gpio98",
++};
++static const char * const wifi134_groups[] = {
++	"gpio98",
++};
++static const char * const jtag_tdi_groups[] = {
++	"gpio0",
++};
+ static const char * const gpio_groups[] = {
+	"gpio0", "gpio1", "gpio2", "gpio3", "gpio4", "gpio5", "gpio6", "gpio7",
+	"gpio8", "gpio9", "gpio10", "gpio11", "gpio12", "gpio13", "gpio14",
+@@ -303,13 +818,103 @@ static const char * const gpio_groups[] = {
+	"gpio92", "gpio93", "gpio94", "gpio95", "gpio96", "gpio97", "gpio98",
+	"gpio99",
+ };
+-
++static const char * const i2s_rx_bclk_groups[] = {
++	"gpio0", "gpio21", "gpio60",
++};
++static const char * const jtag_tck_groups[] = {
++	"gpio1",
++};
++static const char * const i2s_rx_fsync_groups[] = {
++	"gpio1", "gpio22", "gpio61",
++};
++static const char * const jtag_tms_groups[] = {
++	"gpio2",
++};
++static const char * const i2s_rxd_groups[] = {
++	"gpio2", "gpio23", "gpio63",
++};
++static const char * const smart0_groups[] = {
++	"gpio0", "gpio1", "gpio2", "gpio5", "gpio44", "gpio45", "gpio46",
++	"gpio47",
++};
++static const char * const jtag_tdo_groups[] = {
++	"gpio3",
++};
++static const char * const jtag_rst_groups[] = {
++	"gpio4",
++};
++static const char * const jtag_trst_groups[] = {
++	"gpio5",
++};
++static const char * const mdio0_groups[] = {
++	"gpio6",
++};
++static const char * const wcss0_dbg18_groups[] = {
++	"gpio6", "gpio22", "gpio39",
++};
++static const char * const wcss1_dbg18_groups[] = {
++	"gpio6", "gpio22", "gpio39",
++};
++static const char * const qdss_tracedata_a_groups[] = {
++	"gpio6", "gpio7", "gpio8", "gpio9", "gpio10", "gpio11", "gpio16",
++	"gpio17", "gpio37", "gpio38", "gpio39", "gpio40", "gpio41", "gpio42",
++	"gpio43",
++};
++static const char * const mdc_groups[] = {
++	"gpio7", "gpio52",
++};
++static const char * const wcss0_dbg19_groups[] = {
++	"gpio7", "gpio23", "gpio40",
++};
++static const char * const wcss1_dbg19_groups[] = {
++	"gpio7", "gpio23", "gpio40",
++};
+ static const char * const blsp_uart1_groups[] = {
+	"gpio8", "gpio9", "gpio10", "gpio11",
+ };
++static const char * const wifi0_uart_groups[] = {
++	"gpio8", "gpio9", "gpio11", "gpio19", "gpio62",
++};
++static const char * const wifi1_uart_groups[] = {
++	"gpio8", "gpio11", "gpio19", "gpio62", "gpio63",
++};
++static const char * const smart1_groups[] = {
++	"gpio8", "gpio9", "gpio16", "gpio17", "gpio58", "gpio59", "gpio60",
++	"gpio61",
++};
++static const char * const wcss0_dbg20_groups[] = {
++	"gpio8", "gpio24", "gpio41",
++};
++static const char * const wcss1_dbg20_groups[] = {
++	"gpio8", "gpio24", "gpio41",
++};
++static const char * const wifi0_uart0_groups[] = {
++	"gpio9", "gpio10",
++};
++static const char * const wifi1_uart0_groups[] = {
++	"gpio9", "gpio10",
++};
++static const char * const wcss0_dbg21_groups[] = {
++	"gpio9", "gpio25", "gpio42",
++};
++static const char * const wcss1_dbg21_groups[] = {
++	"gpio9", "gpio25", "gpio42",
++};
+ static const char * const blsp_i2c0_groups[] = {
+	"gpio10", "gpio11", "gpio20", "gpio21", "gpio58", "gpio59",
+ };
++static const char * const wcss0_dbg22_groups[] = {
++	"gpio10", "gpio26", "gpio43",
++};
++static const char * const wcss1_dbg22_groups[] = {
++	"gpio10", "gpio26", "gpio43",
++};
++static const char * const wcss0_dbg23_groups[] = {
++	"gpio11", "gpio27", "gpio44",
++};
++static const char * const wcss1_dbg23_groups[] = {
++	"gpio11", "gpio27", "gpio44",
++};
+ static const char * const blsp_spi0_groups[] = {
+	"gpio12", "gpio13", "gpio14", "gpio15", "gpio45",
+	"gpio54", "gpio55", "gpio56", "gpio57",
+@@ -317,94 +922,582 @@ static const char * const blsp_spi0_groups[] = {
+ static const char * const blsp_i2c1_groups[] = {
+	"gpio12", "gpio13", "gpio34", "gpio35",
+ };
++static const char * const wcss0_dbg24_groups[] = {
++	"gpio12", "gpio28", "gpio45",
++};
++static const char * const wcss1_dbg24_groups[] = {
++	"gpio12", "gpio28", "gpio45",
++};
++static const char * const wcss0_dbg25_groups[] = {
++	"gpio13", "gpio29", "gpio46",
++};
++static const char * const wcss1_dbg25_groups[] = {
++	"gpio13", "gpio29", "gpio46",
++};
++static const char * const wcss0_dbg26_groups[] = {
++	"gpio14", "gpio30", "gpio47",
++};
++static const char * const wcss1_dbg26_groups[] = {
++	"gpio14", "gpio30", "gpio47",
++};
++static const char * const wcss0_dbg_groups[] = {
++	"gpio15", "gpio69",
++};
++static const char * const wcss1_dbg_groups[] = {
++	"gpio15",
++};
+ static const char * const blsp_uart0_groups[] = {
+	"gpio16", "gpio17", "gpio60", "gpio61",
+ };
+-static const char * const blsp_spi1_groups[] = {
+-	"gpio44", "gpio45", "gpio46", "gpio47",
++static const char * const led0_groups[] = {
++	"gpio16", "gpio36", "gpio60",
++};
++static const char * const wcss0_dbg28_groups[] = {
++	"gpio16", "gpio32", "gpio49",
++};
++static const char * const wcss1_dbg28_groups[] = {
++	"gpio16", "gpio32", "gpio49",
++};
++static const char * const led1_groups[] = {
++	"gpio17", "gpio37", "gpio61",
++};
++static const char * const wcss0_dbg29_groups[] = {
++	"gpio17", "gpio33", "gpio50",
++};
++static const char * const wcss1_dbg29_groups[] = {
++	"gpio17", "gpio33", "gpio50",
++};
++static const char * const wifi0_uart1_groups[] = {
++	"gpio18", "gpio63",
++};
++static const char * const wifi1_uart1_groups[] = {
++	"gpio18", "gpio63",
++};
++static const char * const wcss0_dbg30_groups[] = {
++	"gpio18", "gpio34", "gpio51",
++};
++static const char * const wcss1_dbg30_groups[] = {
++	"gpio18", "gpio34", "gpio51",
++};
++static const char * const wcss0_dbg31_groups[] = {
++	"gpio19", "gpio35", "gpio52",
++};
++static const char * const wcss1_dbg31_groups[] = {
++	"gpio19", "gpio35",
++};
++static const char * const i2s_rx_mclk_groups[] = {
++	"gpio20", "gpio58",
++};
++static const char * const wcss0_dbg16_groups[] = {
++	"gpio20", "gpio37",
++};
++static const char * const wcss1_dbg16_groups[] = {
++	"gpio20", "gpio37",
++};
++static const char * const wcss0_dbg17_groups[] = {
++	"gpio21", "gpio38",
++};
++static const char * const wcss1_dbg17_groups[] = {
++	"gpio21", "gpio38",
++};
++static const char * const rgmii0_groups[] = {
++	"gpio22", "gpio28",
++};
++static const char * const sdio0_groups[] = {
++	"gpio23",
++};
++static const char * const rgmii1_groups[] = {
++	"gpio23", "gpio29",
++};
++static const char * const sdio1_groups[] = {
++	"gpio24",
++};
++static const char * const rgmii2_groups[] = {
++	"gpio24", "gpio30",
++};
++static const char * const i2s_tx_mclk_groups[] = {
++	"gpio24", "gpio52",
++};
++static const char * const sdio2_groups[] = {
++	"gpio25",
++};
++static const char * const rgmii3_groups[] = {
++	"gpio25", "gpio31",
++};
++static const char * const i2s_tx_bclk_groups[] = {
++	"gpio25", "gpio53", "gpio60",
++};
++static const char * const sdio3_groups[] = {
++	"gpio26",
++};
++static const char * const rgmii_rx_groups[] = {
++	"gpio26",
++};
++static const char * const i2s_tx_fsync_groups[] = {
++	"gpio26", "gpio57", "gpio61",
++};
++static const char * const sdio_clk_groups[] = {
++	"gpio27",
++};
++static const char * const rgmii_txc_groups[] = {
++	"gpio27",
++};
++static const char * const i2s_td1_groups[] = {
++	"gpio27", "gpio54", "gpio63",
++};
++static const char * const sdio_cmd_groups[] = {
++	"gpio28",
++};
++static const char * const i2s_td2_groups[] = {
++	"gpio28", "gpio55",
++};
++static const char * const sdio4_groups[] = {
++	"gpio29",
++};
++static const char * const i2s_td3_groups[] = {
++	"gpio29", "gpio56",
++};
++static const char * const sdio5_groups[] = {
++	"gpio30",
++};
++static const char * const audio_pwm0_groups[] = {
++	"gpio30", "gpio64",
++};
++static const char * const sdio6_groups[] = {
++	"gpio31",
++};
++static const char * const audio_pwm1_groups[] = {
++	"gpio31", "gpio65",
++};
++static const char * const wcss0_dbg27_groups[] = {
++	"gpio31", "gpio48",
++};
++static const char * const wcss1_dbg27_groups[] = {
++	"gpio31", "gpio48",
++};
++static const char * const sdio7_groups[] = {
++	"gpio32",
++};
++static const char * const rgmii_rxc_groups[] = {
++	"gpio32",
++};
++static const char * const audio_pwm2_groups[] = {
++	"gpio32", "gpio66",
++};
++static const char * const rgmii_tx_groups[] = {
++	"gpio33",
++};
++static const char * const audio_pwm3_groups[] = {
++	"gpio33", "gpio67",
++};
++static const char * const boot2_groups[] = {
++	"gpio33",
++};
++static const char * const i2s_spdif_in_groups[] = {
++	"gpio34", "gpio59", "gpio63",
++};
++static const char * const i2s_spdif_out_groups[] = {
++	"gpio35", "gpio62", "gpio63",
++};
++static const char * const rmii00_groups[] = {
++	"gpio36", "gpio41",
++};
++static const char * const led2_groups[] = {
++	"gpio36", "gpio38", "gpio58",
++};
++static const char * const rmii01_groups[] = {
++	"gpio37", "gpio42",
++};
++static const char * const wifi0_wci_groups[] = {
++	"gpio37",
++};
++static const char * const wifi1_wci_groups[] = {
++	"gpio37",
++};
++static const char * const boot4_groups[] = {
++	"gpio37",
++};
++static const char * const rmii0_tx_groups[] = {
++	"gpio38",
++};
++static const char * const boot5_groups[] = {
++	"gpio38",
++};
++static const char * const rmii0_rx_groups[] = {
++	"gpio39",
++};
++static const char * const pcie_clk1_groups[] = {
++	"gpio39",
++};
++static const char * const led3_groups[] = {
++	"gpio39",
++};
++static const char * const sdio_cd_groups[] = {
++	"gpio22",
+ };
+
+ static const struct msm_function ipq4019_functions[] = {
++	FUNCTION(rmii0_refclk),
++	FUNCTION(wifi0_rfsilient0),
++	FUNCTION(wifi1_rfsilient0),
++	FUNCTION(smart2),
++	FUNCTION(led4),
++	FUNCTION(wifi0_cal),
++	FUNCTION(wifi1_cal),
++	FUNCTION(wifi_wci0),
++	FUNCTION(rmii0_dv),
++	FUNCTION(wifi_wci1),
++	FUNCTION(rmii1_refclk),
++	FUNCTION(blsp_spi1),
++	FUNCTION(led5),
++	FUNCTION(rmii10),
++	FUNCTION(led6),
++	FUNCTION(rmii11),
++	FUNCTION(led7),
++	FUNCTION(rmii1_dv),
++	FUNCTION(led8),
++	FUNCTION(rmii1_tx),
++	FUNCTION(aud_pin),
++	FUNCTION(led9),
++	FUNCTION(rmii1_rx),
++	FUNCTION(led10),
++	FUNCTION(wifi0_rfsilient1),
++	FUNCTION(wifi1_rfsilient1),
++	FUNCTION(led11),
++	FUNCTION(boot7),
++	FUNCTION(qpic_pad),
++	FUNCTION(pcie_clk),
++	FUNCTION(tm_clk0),
++	FUNCTION(wifi00),
++	FUNCTION(wifi10),
++	FUNCTION(mdio1),
++	FUNCTION(prng_rosc),
++	FUNCTION(dbg_out),
++	FUNCTION(tm0),
++	FUNCTION(wifi01),
++	FUNCTION(wifi11),
++	FUNCTION(atest_char3),
++	FUNCTION(pmu0),
++	FUNCTION(boot8),
++	FUNCTION(tm1),
++	FUNCTION(atest_char2),
++	FUNCTION(pmu1),
++	FUNCTION(boot9),
++	FUNCTION(tm2),
++	FUNCTION(atest_char1),
++	FUNCTION(tm_ack),
++	FUNCTION(wifi03),
++	FUNCTION(wifi13),
++	FUNCTION(qpic_pad4),
++	FUNCTION(atest_char0),
++	FUNCTION(tm3),
++	FUNCTION(wifi02),
++	FUNCTION(wifi12),
++	FUNCTION(qpic_pad5),
++	FUNCTION(smart3),
++	FUNCTION(wcss0_dbg14),
++	FUNCTION(tm4),
++	FUNCTION(wifi04),
++	FUNCTION(wifi14),
++	FUNCTION(qpic_pad6),
++	FUNCTION(wcss0_dbg15),
++	FUNCTION(qdss_tracectl_a),
++	FUNCTION(boot18),
++	FUNCTION(tm5),
++	FUNCTION(qpic_pad7),
++	FUNCTION(atest_char),
++	FUNCTION(wcss0_dbg4),
++	FUNCTION(qdss_traceclk_a),
++	FUNCTION(boot19),
++	FUNCTION(tm6),
++	FUNCTION(wcss0_dbg5),
++	FUNCTION(qdss_cti_trig_out_a0),
++	FUNCTION(boot14),
++	FUNCTION(tm7),
++	FUNCTION(chip_rst),
++	FUNCTION(wcss0_dbg6),
++	FUNCTION(qdss_cti_trig_out_b0),
++	FUNCTION(boot11),
++	FUNCTION(tm8),
++	FUNCTION(wcss0_dbg7),
++	FUNCTION(wcss1_dbg7),
++	FUNCTION(boot20),
++	FUNCTION(tm9),
++	FUNCTION(qpic_pad1),
++	FUNCTION(wcss0_dbg8),
++	FUNCTION(wcss1_dbg8),
++	FUNCTION(qpic_pad2),
++	FUNCTION(wcss0_dbg9),
++	FUNCTION(wcss1_dbg9),
++	FUNCTION(qpic_pad3),
++	FUNCTION(wcss0_dbg10),
++	FUNCTION(wcss1_dbg10),
++	FUNCTION(qpic_pad0),
++	FUNCTION(wcss0_dbg11),
++	FUNCTION(wcss1_dbg11),
++	FUNCTION(qpic_pad8),
++	FUNCTION(wcss0_dbg12),
++	FUNCTION(wcss1_dbg12),
++	FUNCTION(wifi034),
++	FUNCTION(wifi134),
++	FUNCTION(jtag_tdi),
+	FUNCTION(gpio),
++	FUNCTION(i2s_rx_bclk),
++	FUNCTION(jtag_tck),
++	FUNCTION(i2s_rx_fsync),
++	FUNCTION(jtag_tms),
++	FUNCTION(i2s_rxd),
++	FUNCTION(smart0),
++	FUNCTION(jtag_tdo),
++	FUNCTION(jtag_rst),
++	FUNCTION(jtag_trst),
++	FUNCTION(mdio0),
++	FUNCTION(wcss0_dbg18),
++	FUNCTION(wcss1_dbg18),
++	FUNCTION(qdss_tracedata_a),
++	FUNCTION(mdc),
++	FUNCTION(wcss0_dbg19),
++	FUNCTION(wcss1_dbg19),
+	FUNCTION(blsp_uart1),
++	FUNCTION(wifi0_uart),
++	FUNCTION(wifi1_uart),
++	FUNCTION(smart1),
++	FUNCTION(wcss0_dbg20),
++	FUNCTION(wcss1_dbg20),
++	FUNCTION(wifi0_uart0),
++	FUNCTION(wifi1_uart0),
++	FUNCTION(wcss0_dbg21),
++	FUNCTION(wcss1_dbg21),
+	FUNCTION(blsp_i2c0),
++	FUNCTION(wcss0_dbg22),
++	FUNCTION(wcss1_dbg22),
++	FUNCTION(wcss0_dbg23),
++	FUNCTION(wcss1_dbg23),
++	FUNCTION(blsp_spi0),
+	FUNCTION(blsp_i2c1),
++	FUNCTION(wcss0_dbg24),
++	FUNCTION(wcss1_dbg24),
++	FUNCTION(wcss0_dbg25),
++	FUNCTION(wcss1_dbg25),
++	FUNCTION(wcss0_dbg26),
++	FUNCTION(wcss1_dbg26),
++	FUNCTION(wcss0_dbg),
++	FUNCTION(wcss1_dbg),
+	FUNCTION(blsp_uart0),
+-	FUNCTION(blsp_spi1),
+-	FUNCTION(blsp_spi0),
++	FUNCTION(led0),
++	FUNCTION(wcss0_dbg28),
++	FUNCTION(wcss1_dbg28),
++	FUNCTION(led1),
++	FUNCTION(wcss0_dbg29),
++	FUNCTION(wcss1_dbg29),
++	FUNCTION(wifi0_uart1),
++	FUNCTION(wifi1_uart1),
++	FUNCTION(wcss0_dbg30),
++	FUNCTION(wcss1_dbg30),
++	FUNCTION(wcss0_dbg31),
++	FUNCTION(wcss1_dbg31),
++	FUNCTION(i2s_rx_mclk),
++	FUNCTION(wcss0_dbg16),
++	FUNCTION(wcss1_dbg16),
++	FUNCTION(wcss0_dbg17),
++	FUNCTION(wcss1_dbg17),
++	FUNCTION(rgmii0),
++	FUNCTION(sdio0),
++	FUNCTION(rgmii1),
++	FUNCTION(sdio1),
++	FUNCTION(rgmii2),
++	FUNCTION(i2s_tx_mclk),
++	FUNCTION(sdio2),
++	FUNCTION(rgmii3),
++	FUNCTION(i2s_tx_bclk),
++	FUNCTION(sdio3),
++	FUNCTION(rgmii_rx),
++	FUNCTION(i2s_tx_fsync),
++	FUNCTION(sdio_clk),
++	FUNCTION(rgmii_txc),
++	FUNCTION(i2s_td1),
++	FUNCTION(sdio_cmd),
++	FUNCTION(i2s_td2),
++	FUNCTION(sdio4),
++	FUNCTION(i2s_td3),
++	FUNCTION(sdio5),
++	FUNCTION(audio_pwm0),
++	FUNCTION(sdio6),
++	FUNCTION(audio_pwm1),
++	FUNCTION(wcss0_dbg27),
++	FUNCTION(wcss1_dbg27),
++	FUNCTION(sdio7),
++	FUNCTION(rgmii_rxc),
++	FUNCTION(audio_pwm2),
++	FUNCTION(rgmii_tx),
++	FUNCTION(audio_pwm3),
++	FUNCTION(boot2),
++	FUNCTION(i2s_spdif_in),
++	FUNCTION(i2s_spdif_out),
++	FUNCTION(rmii00),
++	FUNCTION(led2),
++	FUNCTION(rmii01),
++	FUNCTION(wifi0_wci),
++	FUNCTION(wifi1_wci),
++	FUNCTION(boot4),
++	FUNCTION(rmii0_tx),
++	FUNCTION(boot5),
++	FUNCTION(rmii0_rx),
++	FUNCTION(pcie_clk1),
++	FUNCTION(led3),
++	FUNCTION(sdio_cd),
+ };
+
+ static const struct msm_pingroup ipq4019_groups[] = {
+-	PINGROUP(0, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA),
+-	PINGROUP(1, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA),
+-	PINGROUP(2, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA),
+-	PINGROUP(3, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA),
+-	PINGROUP(4, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA),
+-	PINGROUP(5, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA),
+-	PINGROUP(6, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA),
+-	PINGROUP(7, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA),
+-	PINGROUP(8, blsp_uart1, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA),
+-	PINGROUP(9, blsp_uart1, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA),
+-	PINGROUP(10, blsp_uart1, NA, NA, blsp_i2c0, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA),
+-	PINGROUP(11, blsp_uart1, NA, NA, blsp_i2c0, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA),
+-	PINGROUP(12, blsp_spi0, blsp_i2c1, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA),
+-	PINGROUP(13, blsp_spi0, blsp_i2c1, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA),
+-	PINGROUP(14, blsp_spi0, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA),
+-	PINGROUP(15, blsp_spi0, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA),
+-	PINGROUP(16, blsp_uart0, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA),
+-	PINGROUP(17, blsp_uart0, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA),
+-	PINGROUP(18, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA),
+-	PINGROUP(19, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA),
+-	PINGROUP(20, blsp_i2c0, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA),
+-	PINGROUP(21, blsp_i2c0, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA),
+-	PINGROUP(22, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA),
+-	PINGROUP(23, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA),
+-	PINGROUP(24, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA),
+-	PINGROUP(25, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA),
+-	PINGROUP(26, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA),
+-	PINGROUP(27, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA),
+-	PINGROUP(28, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA),
+-	PINGROUP(29, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA),
+-	PINGROUP(30, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA),
+-	PINGROUP(31, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA),
+-	PINGROUP(32, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA),
+-	PINGROUP(33, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA),
+-	PINGROUP(34, blsp_i2c1, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA),
+-	PINGROUP(35, blsp_i2c1, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA),
+-	PINGROUP(36, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA),
+-	PINGROUP(37, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA),
+-	PINGROUP(38, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA),
+-	PINGROUP(39, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA),
+-	PINGROUP(40, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA),
+-	PINGROUP(41, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA),
+-	PINGROUP(42, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA),
+-	PINGROUP(43, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA),
+-	PINGROUP(44, NA, blsp_spi1, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA),
+-	PINGROUP(45, NA, blsp_spi1, blsp_spi0, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA),
+-	PINGROUP(46, NA, blsp_spi1, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA),
+-	PINGROUP(47, NA, blsp_spi1, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA),
+-	PINGROUP(48, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA),
+-	PINGROUP(49, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA),
+-	PINGROUP(50, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA),
+-	PINGROUP(51, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA),
+-	PINGROUP(52, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA),
+-	PINGROUP(53, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA),
+-	PINGROUP(54, NA, blsp_spi0, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA),
+-	PINGROUP(55, NA, blsp_spi0, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA),
+-	PINGROUP(56, NA, blsp_spi0, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA),
+-	PINGROUP(57, NA, blsp_spi0, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA),
+-	PINGROUP(58, NA, NA, blsp_i2c0, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA),
+-	PINGROUP(59, NA, blsp_i2c0, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA),
+-	PINGROUP(60, NA, blsp_uart0, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA),
+-	PINGROUP(61, NA, blsp_uart0, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA),
+-	PINGROUP(62, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA),
+-	PINGROUP(63, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA),
+-	PINGROUP(64, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA),
+-	PINGROUP(65, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA),
+-	PINGROUP(66, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA),
+-	PINGROUP(67, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA),
+-	PINGROUP(68, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA),
+-	PINGROUP(69, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA),
++	PINGROUP(0, jtag_tdi, smart0, i2s_rx_bclk, NA, NA, NA, NA, NA, NA, NA,
++		 NA, NA, NA, NA),
++	PINGROUP(1, jtag_tck, smart0, i2s_rx_fsync, NA, NA, NA, NA, NA, NA, NA,
++		 NA, NA, NA, NA),
++	PINGROUP(2, jtag_tms, smart0, i2s_rxd, NA, NA, NA, NA, NA, NA, NA, NA,
++		 NA, NA, NA),
++	PINGROUP(3, jtag_tdo, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA,
++		 NA),
++	PINGROUP(4, jtag_rst, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA,
++		 NA),
++	PINGROUP(5, jtag_trst, smart0, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA,
++		 NA, NA),
++	PINGROUP(6, mdio0, NA, wcss0_dbg18, wcss1_dbg18, NA, qdss_tracedata_a,
++		 NA, NA, NA, NA, NA, NA, NA, NA),
++	PINGROUP(7, mdc, NA, wcss0_dbg19, wcss1_dbg19, NA, qdss_tracedata_a,
++		 NA, NA, NA, NA, NA, NA, NA, NA),
++	PINGROUP(8, blsp_uart1, wifi0_uart, wifi1_uart, smart1, NA,
++		 wcss0_dbg20, wcss1_dbg20, NA, qdss_tracedata_a, NA, NA, NA,
++		 NA, NA),
++	PINGROUP(9, blsp_uart1, wifi0_uart0, wifi1_uart0, smart1, wifi0_uart,
++		 NA, wcss0_dbg21, wcss1_dbg21, NA, qdss_tracedata_a, NA, NA,
++		 NA, NA),
++	PINGROUP(10, blsp_uart1, wifi0_uart0, wifi1_uart0, blsp_i2c0, NA,
++		 wcss0_dbg22, wcss1_dbg22, NA, qdss_tracedata_a, NA, NA, NA,
++		 NA, NA),
++	PINGROUP(11, blsp_uart1, wifi0_uart, wifi1_uart, blsp_i2c0, NA,
++		 wcss0_dbg23, wcss1_dbg23, NA, qdss_tracedata_a, NA, NA, NA,
++		 NA, NA),
++	PINGROUP(12, blsp_spi0, blsp_i2c1, NA, wcss0_dbg24, wcss1_dbg24, NA,
++		 NA, NA, NA, NA, NA, NA, NA, NA),
++	PINGROUP(13, blsp_spi0, blsp_i2c1, NA, wcss0_dbg25, wcss1_dbg25, NA,
++		 NA, NA, NA, NA, NA, NA, NA, NA),
++	PINGROUP(14, blsp_spi0, NA, wcss0_dbg26, wcss1_dbg26, NA, NA, NA, NA,
++		 NA, NA, NA, NA, NA, NA),
++	PINGROUP(15, blsp_spi0, NA, wcss0_dbg, wcss1_dbg, NA, NA, NA, NA, NA,
++		 NA, NA, NA, NA, NA),
++	PINGROUP(16, blsp_uart0, led0, smart1, NA, wcss0_dbg28, wcss1_dbg28,
++		 NA, qdss_tracedata_a, NA, NA, NA, NA, NA, NA),
++	PINGROUP(17, blsp_uart0, led1, smart1, NA, wcss0_dbg29, wcss1_dbg29,
++		 NA, qdss_tracedata_a, NA, NA, NA, NA, NA, NA),
++	PINGROUP(18, wifi0_uart1, wifi1_uart1, NA, wcss0_dbg30, wcss1_dbg30,
++		 NA, NA, NA, NA, NA, NA, NA, NA, NA),
++	PINGROUP(19, wifi0_uart, wifi1_uart, NA, wcss0_dbg31, wcss1_dbg31, NA,
++		 NA, NA, NA, NA, NA, NA, NA, NA),
++	PINGROUP(20, blsp_i2c0, i2s_rx_mclk, NA, wcss0_dbg16, wcss1_dbg16, NA,
++		 NA, NA, NA, NA, NA, NA, NA, NA),
++	PINGROUP(21, blsp_i2c0, i2s_rx_bclk, NA, wcss0_dbg17, wcss1_dbg17, NA,
++		 NA, NA, NA, NA, NA, NA, NA, NA),
++	PINGROUP(22, rgmii0, i2s_rx_fsync, NA, wcss0_dbg18, wcss1_dbg18, NA,
++		 NA, NA, NA, NA, NA, NA, NA, NA),
++	PINGROUP(23, sdio0, rgmii1, i2s_rxd, NA, wcss0_dbg19, wcss1_dbg19, NA,
++		 NA, NA, NA, NA, NA, NA, NA),
++	PINGROUP(24, sdio1, rgmii2, i2s_tx_mclk, NA, wcss0_dbg20, wcss1_dbg20,
++		 NA, NA, NA, NA, NA, NA, NA, NA),
++	PINGROUP(25, sdio2, rgmii3, i2s_tx_bclk, NA, wcss0_dbg21, wcss1_dbg21,
++		 NA, NA, NA, NA, NA, NA, NA, NA),
++	PINGROUP(26, sdio3, rgmii_rx, i2s_tx_fsync, NA, wcss0_dbg22,
++		 wcss1_dbg22, NA, NA, NA, NA, NA, NA, NA, NA),
++	PINGROUP(27, sdio_clk, rgmii_txc, i2s_td1, NA, wcss0_dbg23,
++		 wcss1_dbg23, NA, NA, NA, NA, NA, NA, NA, NA),
++	PINGROUP(28, sdio_cmd, rgmii0, i2s_td2, NA, wcss0_dbg24, wcss1_dbg24,
++		 NA, NA, NA, NA, NA, NA, NA, NA),
++	PINGROUP(29, sdio4, rgmii1, i2s_td3, NA, wcss0_dbg25, wcss1_dbg25, NA,
++		 NA, NA, NA, NA, NA, NA, NA),
++	PINGROUP(30, sdio5, rgmii2, audio_pwm0, NA, wcss0_dbg26, wcss1_dbg26,
++		 NA, NA, NA, NA, NA, NA, NA, NA),
++	PINGROUP(31, sdio6, rgmii3, audio_pwm1, NA, wcss0_dbg27, wcss1_dbg27,
++		 NA, NA, NA, NA, NA, NA, NA, NA),
++	PINGROUP(32, sdio7, rgmii_rxc, audio_pwm2, NA, wcss0_dbg28,
++		 wcss1_dbg28, NA, NA, NA, NA, NA, NA, NA, NA),
++	PINGROUP(33, rgmii_tx, audio_pwm3, NA, wcss0_dbg29, wcss1_dbg29, NA,
++		 boot2, NA, NA, NA, NA, NA, NA, NA),
++	PINGROUP(34, blsp_i2c1, i2s_spdif_in, NA, wcss0_dbg30, wcss1_dbg30, NA,
++		 NA, NA, NA, NA, NA, NA, NA, NA),
++	PINGROUP(35, blsp_i2c1, i2s_spdif_out, NA, wcss0_dbg31, wcss1_dbg31,
++		 NA, NA, NA, NA, NA, NA, NA, NA, NA),
++	PINGROUP(36, rmii00, led2, led0, NA, NA, NA, NA, NA, NA, NA, NA, NA,
++		 NA, NA),
++	PINGROUP(37, rmii01, wifi0_wci, wifi1_wci, led1, NA, NA, wcss0_dbg16,
++		 wcss1_dbg16, NA, qdss_tracedata_a, boot4, NA, NA, NA),
++	PINGROUP(38, rmii0_tx, led2, NA, NA, wcss0_dbg17, wcss1_dbg17, NA,
++		 qdss_tracedata_a, boot5, NA, NA, NA, NA, NA),
++	PINGROUP(39, rmii0_rx, pcie_clk1, led3, NA, NA, wcss0_dbg18,
++		 wcss1_dbg18, NA, NA, qdss_tracedata_a, NA, NA, NA, NA),
++	PINGROUP(40, rmii0_refclk, wifi0_rfsilient0, wifi1_rfsilient0, smart2,
++		 led4, NA, NA, wcss0_dbg19, wcss1_dbg19, NA, NA,
++		 qdss_tracedata_a, NA, NA),
++	PINGROUP(41, rmii00, wifi0_cal, wifi1_cal, smart2, NA, NA, wcss0_dbg20,
++		 wcss1_dbg20, NA, NA, qdss_tracedata_a, NA, NA, NA),
++	PINGROUP(42, rmii01, wifi_wci0, NA, NA, wcss0_dbg21, wcss1_dbg21, NA,
++		 NA, qdss_tracedata_a, NA, NA, NA, NA, NA),
++	PINGROUP(43, rmii0_dv, wifi_wci1, NA, NA, wcss0_dbg22, wcss1_dbg22, NA,
++		 NA, qdss_tracedata_a, NA, NA, NA, NA, NA),
++	PINGROUP(44, rmii1_refclk, blsp_spi1, smart0, led5, NA, NA,
++		 wcss0_dbg23, wcss1_dbg23, NA, NA, NA, NA, NA, NA),
++	PINGROUP(45, rmii10, blsp_spi1, blsp_spi0, smart0, led6, NA, NA,
++		 wcss0_dbg24, wcss1_dbg24, NA, NA, NA, NA, NA),
++	PINGROUP(46, rmii11, blsp_spi1, smart0, led7, NA, NA, wcss0_dbg25,
++		 wcss1_dbg25, NA, NA, NA, NA, NA, NA),
++	PINGROUP(47, rmii1_dv, blsp_spi1, smart0, led8, NA, NA, wcss0_dbg26,
++		 wcss1_dbg26, NA, NA, NA, NA, NA, NA),
++	PINGROUP(48, rmii1_tx, aud_pin, smart2, led9, NA, NA, wcss0_dbg27,
++		 wcss1_dbg27, NA, NA, NA, NA, NA, NA),
++	PINGROUP(49, rmii1_rx, aud_pin, smart2, led10, NA, NA, wcss0_dbg28,
++		 wcss1_dbg28, NA, NA, NA, NA, NA, NA),
++	PINGROUP(50, rmii10, aud_pin, wifi0_rfsilient1, wifi1_rfsilient1,
++		 led11, NA, NA, wcss0_dbg29, wcss1_dbg29, NA, NA, NA, NA, NA),
++	PINGROUP(51, rmii11, aud_pin, wifi0_cal, wifi1_cal, NA, NA,
++		 wcss0_dbg30, wcss1_dbg30, NA, boot7, NA, NA, NA, NA),
++	PINGROUP(52, qpic_pad, mdc, pcie_clk, i2s_tx_mclk, NA, NA, wcss0_dbg31,
++		 tm_clk0, wifi00, wifi10, NA, NA, NA, NA),
++	PINGROUP(53, qpic_pad, mdio1, i2s_tx_bclk, prng_rosc, dbg_out, tm0,
++		 wifi01, wifi11, NA, NA, NA, NA, NA, NA),
++	PINGROUP(54, qpic_pad, blsp_spi0, i2s_td1, atest_char3, pmu0, NA, NA,
++		 boot8, tm1, NA, NA, NA, NA, NA),
++	PINGROUP(55, qpic_pad, blsp_spi0, i2s_td2, atest_char2, pmu1, NA, NA,
++		 boot9, tm2, NA, NA, NA, NA, NA),
++	PINGROUP(56, qpic_pad, blsp_spi0, i2s_td3, atest_char1, NA, tm_ack,
++		 wifi03, wifi13, NA, NA, NA, NA, NA, NA),
++	PINGROUP(57, qpic_pad4, blsp_spi0, i2s_tx_fsync, atest_char0, NA, tm3,
++		 wifi02, wifi12, NA, NA, NA, NA, NA, NA),
++	PINGROUP(58, qpic_pad5, led2, blsp_i2c0, smart3, smart1, i2s_rx_mclk,
++		 NA, wcss0_dbg14, tm4, wifi04, wifi14, NA, NA, NA),
++	PINGROUP(59, qpic_pad6, blsp_i2c0, smart3, smart1, i2s_spdif_in, NA,
++		 NA, wcss0_dbg15, qdss_tracectl_a, boot18, tm5, NA, NA, NA),
++	PINGROUP(60, qpic_pad7, blsp_uart0, smart1, smart3, led0, i2s_tx_bclk,
++		 i2s_rx_bclk, atest_char, NA, wcss0_dbg4, qdss_traceclk_a,
++		 boot19, tm6, NA),
++	PINGROUP(61, qpic_pad, blsp_uart0, smart1, smart3, led1, i2s_tx_fsync,
++		 i2s_rx_fsync, NA, NA, wcss0_dbg5, qdss_cti_trig_out_a0,
++		 boot14, tm7, NA),
++	PINGROUP(62, qpic_pad, chip_rst, wifi0_uart, wifi1_uart, i2s_spdif_out,
++		 NA, NA, wcss0_dbg6, qdss_cti_trig_out_b0, boot11, tm8, NA, NA,
++		 NA),
++	PINGROUP(63, qpic_pad, wifi0_uart1, wifi1_uart1, wifi1_uart, i2s_td1,
++		 i2s_rxd, i2s_spdif_out, i2s_spdif_in, NA, wcss0_dbg7,
++		 wcss1_dbg7, boot20, tm9, NA),
++	PINGROUP(64, qpic_pad1, audio_pwm0, NA, wcss0_dbg8, wcss1_dbg8, NA, NA,
++		 NA, NA, NA, NA, NA, NA, NA),
++	PINGROUP(65, qpic_pad2, audio_pwm1, NA, wcss0_dbg9, wcss1_dbg9, NA, NA,
++		 NA, NA, NA, NA, NA, NA, NA),
++	PINGROUP(66, qpic_pad3, audio_pwm2, NA, wcss0_dbg10, wcss1_dbg10, NA,
++		 NA, NA, NA, NA, NA, NA, NA, NA),
++	PINGROUP(67, qpic_pad0, audio_pwm3, NA, wcss0_dbg11, wcss1_dbg11, NA,
++		 NA, NA, NA, NA, NA, NA, NA, NA),
++	PINGROUP(68, qpic_pad8, NA, wcss0_dbg12, wcss1_dbg12, NA, NA, NA, NA,
++		 NA, NA, NA, NA, NA, NA),
++	PINGROUP(69, qpic_pad, NA, wcss0_dbg, NA, NA, NA, NA, NA, NA, NA, NA,
++		 NA, NA, NA),
+	PINGROUP(70, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA),
+	PINGROUP(71, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA),
+	PINGROUP(72, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA),
+@@ -433,7 +1526,8 @@ static const struct msm_pingroup ipq4019_groups[] = {
+	PINGROUP(95, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA),
+	PINGROUP(96, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA),
+	PINGROUP(97, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA),
+-	PINGROUP(98, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA),
++	PINGROUP(98, wifi034, wifi134, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA,
++		 NA, NA),
+	PINGROUP(99, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA),
+ };
+
+@@ -460,6 +1554,7 @@ static const struct of_device_id ipq4019_pinctrl_of_match[] = {
+ static struct platform_driver ipq4019_pinctrl_driver = {
+	.driver = {
+		.name = "ipq4019-pinctrl",
++		.owner = THIS_MODULE,
+		.of_match_table = ipq4019_pinctrl_of_match,
+	},
+	.probe = ipq4019_pinctrl_probe,
+--
+2.7.2
diff --git a/target/linux/ipq806x/patches-4.9/855-clk-qcom-ipq4019-add-ess-reset.patch b/target/linux/ipq806x/patches-4.9/855-clk-qcom-ipq4019-add-ess-reset.patch
new file mode 100644
index 0000000..d33b8ab
--- /dev/null
+++ b/target/linux/ipq806x/patches-4.9/855-clk-qcom-ipq4019-add-ess-reset.patch
@@ -0,0 +1,58 @@ 
+From 7efb48a343ca368f83359d3a7087dd5ab25a283a Mon Sep 17 00:00:00 2001
+From: Ram Chandra Jangir <rjangir@codeaurora.org>
+Date: Tue, 28 Mar 2017 22:35:33 +0530
+Subject: [PATCH 5/8] clk: qcom: ipq4019: add ess reset
+
+Added the ESS reset in IPQ4019 GCC.
+
+Signed-off-by: Ram Chandra Jangir <rjangir@codeaurora.org>
+---
+ drivers/clk/qcom/gcc-ipq4019.c               | 11 +++++++++++
+ include/dt-bindings/clock/qcom,gcc-ipq4019.h | 11 +++++++++++
+ 2 files changed, 22 insertions(+)
+
+diff --git a/drivers/clk/qcom/gcc-ipq4019.c b/drivers/clk/qcom/gcc-ipq4019.c
+index d0a5d0e..99a7bdb 100644
+--- a/drivers/clk/qcom/gcc-ipq4019.c
++++ b/drivers/clk/qcom/gcc-ipq4019.c
+@@ -1289,6 +1289,17 @@ static const struct qcom_reset_map gcc_ipq4019_resets[] = {
+	[GCC_TCSR_BCR] = {0x22000, 0},
+	[GCC_MPM_BCR] = {0x24000, 0},
+	[GCC_SPDM_BCR] = {0x25000, 0},
++	[ESS_MAC1_ARES] = {0x1200C, 0},
++	[ESS_MAC2_ARES] = {0x1200C, 1},
++	[ESS_MAC3_ARES] = {0x1200C, 2},
++	[ESS_MAC4_ARES] = {0x1200C, 3},
++	[ESS_MAC5_ARES] = {0x1200C, 4},
++	[ESS_PSGMII_ARES] = {0x1200C, 5},
++	[ESS_MAC1_CLK_DIS] = {0x1200C, 8},
++	[ESS_MAC2_CLK_DIS] = {0x1200C, 9},
++	[ESS_MAC3_CLK_DIS] = {0x1200C, 10},
++	[ESS_MAC4_CLK_DIS] = {0x1200C, 11},
++	[ESS_MAC5_CLK_DIS] = {0x1200C, 12},
+ };
+
+ static const struct regmap_config gcc_ipq4019_regmap_config = {
+diff --git a/include/dt-bindings/clock/qcom,gcc-ipq4019.h b/include/dt-bindings/clock/qcom,gcc-ipq4019.h
+index 6240e5b..9a299e7 100644
+--- a/include/dt-bindings/clock/qcom,gcc-ipq4019.h
++++ b/include/dt-bindings/clock/qcom,gcc-ipq4019.h
+@@ -154,5 +154,16 @@
+ #define GCC_QDSS_BCR					69
+ #define GCC_MPM_BCR					70
+ #define GCC_SPDM_BCR					71
++#define ESS_MAC1_ARES					72
++#define ESS_MAC2_ARES					73
++#define ESS_MAC3_ARES					74
++#define ESS_MAC4_ARES					75
++#define ESS_MAC5_ARES					76
++#define ESS_PSGMII_ARES					77
++#define ESS_MAC1_CLK_DIS				78
++#define ESS_MAC2_CLK_DIS				79
++#define ESS_MAC3_CLK_DIS				80
++#define ESS_MAC4_CLK_DIS				81
++#define ESS_MAC5_CLK_DIS				82
+
+ #endif
+--
+2.7.2
diff --git a/target/linux/ipq806x/patches-4.9/857-ipq40xx-Fix-mdio-driver-to-work-with-IPQ40xx-SoC.patch b/target/linux/ipq806x/patches-4.9/857-ipq40xx-Fix-mdio-driver-to-work-with-IPQ40xx-SoC.patch
new file mode 100644
index 0000000..a9c6c33
--- /dev/null
+++ b/target/linux/ipq806x/patches-4.9/857-ipq40xx-Fix-mdio-driver-to-work-with-IPQ40xx-SoC.patch
@@ -0,0 +1,102 @@ 
+From 1d8433be4af4a5862b8805a5668d404bd6fde945 Mon Sep 17 00:00:00 2001
+From: Ram Chandra Jangir <rjangir@codeaurora.org>
+Date: Tue, 28 Mar 2017 22:32:07 +0530
+Subject: [PATCH] ipq40xx: Fix mdio driver to work with IPQ40xx SoC
+
+- Add phy-reset-gpio support in probe function to fix hang
+  at board booting.
+- Add proper assignment of mii_bus read/write operations
+
+Signed-off-by: Ram Chandra Jangir <rjangir@codeaurora.org>
+---
+ drivers/net/phy/mdio-ipq40xx.c | 56 +++++++++++++++++++++++++++++++++++++++---
+ 1 file changed, 53 insertions(+), 3 deletions(-)
+
+diff --git a/drivers/net/phy/mdio-ipq40xx.c b/drivers/net/phy/mdio-ipq40xx.c
+index 335d531..6f13c96 100644
+--- a/drivers/net/phy/mdio-ipq40xx.c
++++ b/drivers/net/phy/mdio-ipq40xx.c
+@@ -22,6 +22,7 @@
+ #include <linux/of_mdio.h>
+ #include <linux/phy.h>
+ #include <linux/platform_device.h>
++#include <linux/of_gpio.h>
+
+ #define MDIO_CTRL_0_REG		0x40
+ #define MDIO_CTRL_1_REG		0x44
+@@ -122,11 +123,61 @@ static int ipq40xx_mdio_write(struct mii_bus *bus, int mii_id, int regnum,
+	return 0;
+ }
+
++static int ipq40xx_phy_reset(struct platform_device *pdev)
++{
++	struct device_node *mdio_node;
++	int phy_reset_gpio_number;
++	int ret;
++
++	mdio_node = of_find_node_by_name(NULL, "mdio");
++	if (!mdio_node) {
++		dev_err(&pdev->dev, "Could not find mdio node\n");
++		return -ENOENT;
++	}
++
++	ret = of_get_named_gpio(mdio_node, "phy-reset-gpio", 0);
++	if (ret < 0) {
++		dev_warn(&pdev->dev, "Could not find DT gpio phy-reset-gpio missing/malformed:%d\n",ret);
++		ret = 0;
++		return ret;
++	}
++
++	phy_reset_gpio_number = ret;
++
++	ret = gpio_request(phy_reset_gpio_number, "phy-reset-gpio");
++	if (ret) {
++		dev_err(&pdev->dev, "Can't get phy-reset-gpio %d\n", ret);
++		return ret;
++	}
++
++	ret = gpio_direction_output(phy_reset_gpio_number, 0x0);
++	if (ret) {
++		dev_err(&pdev->dev,
++			"Can't set direction for phy-reset-gpio %d\n", ret);
++		goto phy_reset_out;
++	}
++
++	usleep_range(1000, 10005);
++
++	gpio_set_value(phy_reset_gpio_number, 0x01);
++
++phy_reset_out:
++	gpio_free(phy_reset_gpio_number);
++
++	return ret;
++}
++
+ static int ipq40xx_mdio_probe(struct platform_device *pdev)
+ {
+	struct ipq40xx_mdio_data *am;
+	struct resource *res;
+-	int i;
++	int i, ret;
++
++	ret = ipq40xx_phy_reset(pdev);
++	if (ret) {
++		dev_err(&pdev->dev, "Could not find qca8075 reset gpio\n");
++		return ret;
++	}
+
+	am = devm_kzalloc(&pdev->dev, sizeof(*am), GFP_KERNEL);
+	if (!am)
+@@ -151,8 +202,8 @@ static int ipq40xx_mdio_probe(struct platform_device *pdev)
+	writel(CTRL_0_REG_DEFAULT_VALUE, am->membase + MDIO_CTRL_0_REG);
+
+	am->mii_bus->name = "ipq40xx_mdio";
+-	am->mii_bus->read = ipq40xx_mdio_read;
+-	am->mii_bus->write = ipq40xx_mdio_write;
++	am->mii_bus->read = &ipq40xx_mdio_read;
++	am->mii_bus->write = &ipq40xx_mdio_write;
+	memcpy(am->mii_bus->irq, am->phy_irq, sizeof(am->phy_irq));
+	am->mii_bus->priv = am;
+	am->mii_bus->parent = &pdev->dev;
+--
+2.7.2
diff --git a/target/linux/ipq806x/patches-4.9/858-arm-dts-Add-ess-switch-device-for-IPQ4019.patch b/target/linux/ipq806x/patches-4.9/858-arm-dts-Add-ess-switch-device-for-IPQ4019.patch
new file mode 100644
index 0000000..818a7a6
--- /dev/null
+++ b/target/linux/ipq806x/patches-4.9/858-arm-dts-Add-ess-switch-device-for-IPQ4019.patch
@@ -0,0 +1,355 @@ 
+From 4842020af3b39ce8c7c9a92de106d8fffd92b7c0 Mon Sep 17 00:00:00 2001
+From: Ram Chandra Jangir <rjangir@codeaurora.org>
+Date: Tue, 28 Mar 2017 14:00:00 +0530
+Subject: [PATCH] arm: dts: Add ess switch device for IPQ4019
+
+- Update ipq4019 dts nodes for mdio interface, ess-switch
+   and edma driver.
+- Update dt documentation for qca-ess ethernet subsystem
+- This change also enables wifi
+
+Signed-off-by: xiaofeis <xiaofeis@codeaurora.org>
+Signed-off-by: Ram Chandra Jangir <rjangir@codeaurora.org>
+---
+ Documentation/devicetree/bindings/net/qca-ess.txt | 107 ++++++++++++++++++
+ arch/arm/boot/dts/qcom-ipq4019-ap.dk01.1-c1.dts   |  10 +-
+ arch/arm/boot/dts/qcom-ipq4019-ap.dk01.1.dtsi     |  29 +++++
+ arch/arm/boot/dts/qcom-ipq4019-ap.dk04.1.dtsi     |  72 +++++++++++++
+ arch/arm/boot/dts/qcom-ipq4019.dtsi               | 125 ++++++++++++----------
+ 5 files changed, 283 insertions(+), 60 deletions(-)
+ create mode 100644 Documentation/devicetree/bindings/net/qca-ess.txt
+
+diff --git a/Documentation/devicetree/bindings/net/qca-ess.txt b/Documentation/devicetree/bindings/net/qca-ess.txt
+new file mode 100644
+index 0000000..7f16d6b
+--- /dev/null
++++ b/Documentation/devicetree/bindings/net/qca-ess.txt
+@@ -0,0 +1,110 @@
++QCA Ethernet Subsystem
++----------------------
++
++This driver adds support for the Ethernet subsystem
++
++1. QCA Ethernet DMA
++----------------------
++
++Required properties:
++  - compatible = "qcom,ess-edma";
++
++Optional properties:
++
++Example:
++    edma@c080000 {
++	compatible = "qcom,ess-edma";
++	reg = <0xc080000 0x8000>;
++	qcom,page-mode = <0>;
++	qcom,rx_head_buf_size = <1540>;
++	qcom,mdio_supported;
++	qcom,poll_required = <1>;
++	qcom,num_gmac = <2>;
++	interrupts = <0  65 IRQ_TYPE_EDGE_RISING
++		      0  66 IRQ_TYPE_EDGE_RISING
++		      0  67 IRQ_TYPE_EDGE_RISING
++		      0  68 IRQ_TYPE_EDGE_RISING
++		      0  69 IRQ_TYPE_EDGE_RISING
++		      0  70 IRQ_TYPE_EDGE_RISING
++		      0  71 IRQ_TYPE_EDGE_RISING
++		      0  72 IRQ_TYPE_EDGE_RISING
++		      0  73 IRQ_TYPE_EDGE_RISING
++		      0  74 IRQ_TYPE_EDGE_RISING
++		      0  75 IRQ_TYPE_EDGE_RISING
++		      0  76 IRQ_TYPE_EDGE_RISING
++		      0  77 IRQ_TYPE_EDGE_RISING
++		      0  78 IRQ_TYPE_EDGE_RISING
++		      0  79 IRQ_TYPE_EDGE_RISING
++		      0  80 IRQ_TYPE_EDGE_RISING
++		      0 240 IRQ_TYPE_EDGE_RISING
++		      0 241 IRQ_TYPE_EDGE_RISING
++		      0 242 IRQ_TYPE_EDGE_RISING
++		      0 243 IRQ_TYPE_EDGE_RISING
++		      0 244 IRQ_TYPE_EDGE_RISING
++		      0 245 IRQ_TYPE_EDGE_RISING
++		      0 246 IRQ_TYPE_EDGE_RISING
++		      0 247 IRQ_TYPE_EDGE_RISING
++		      0 248 IRQ_TYPE_EDGE_RISING
++		      0 249 IRQ_TYPE_EDGE_RISING
++		      0 250 IRQ_TYPE_EDGE_RISING
++		      0 251 IRQ_TYPE_EDGE_RISING
++		      0 252 IRQ_TYPE_EDGE_RISING
++		      0 253 IRQ_TYPE_EDGE_RISING
++		      0 254 IRQ_TYPE_EDGE_RISING
++		      0 255 IRQ_TYPE_EDGE_RISING>;
++   };
++
++2. QCA Ethernet Switch
++----------------------
++
++Required properties:
++  - compatible = "qcom,ess-switch";
++
++Optional properties:
++
++Example:
++
++	ess-switch@c000000 {
++		compatible = "qcom,ess-switch";
++		reg = <0xc000000 0x80000>; /* 512KB */
++		switch_access_mode = "local bus";
++		resets = <&gcc ESS_RESET>;
++		switch_cpu_bmp = <0x1>;  /* cpu port bitmap */
++		switch_lan_bmp = <0x1e>; /* lan port bitmap */
++		switch_wan_bmp = <0x20>; /* wan port bitmap */
++		switch_initvlas = <0x7c 0x54>;
++	};
++
++3. QCA Ethernet PHY mode
++-------------------------
++
++Required properties:
++  - compatible = "qcom,ess-psgmii";
++
++Optional properties:
++
++Example:
++
++	ess-psgmii@98000 {
++		compatible = "qcom,ess-psgmii";
++		reg = <0x98000 0x800>; /* 2k */
++		psgmii_access_mode = "local bus";
++		resets = <&gcc ESS_PSGMII_ARES>;
++	};
++
++4. MDIO Interface
++----------------------
++
++Required properties:
++  - compatible = "qcom,ipq4019-mdio";
++
++Optional properties:
++
++Example:
++
++	mdio@90000 {
++		#address-cells = <1>;
++		#size-cells = <0>;
++		compatible = "qcom,ipq4019-mdio";
++		reg = <0x90000 0x64>;
++	};
+diff --git a/arch/arm/boot/dts/qcom-ipq4019-ap.dk01.1-c1.dts b/arch/arm/boot/dts/qcom-ipq4019-ap.dk01.1-c1.dts
+index 0d92f1b..2a8cf8d 100644
+--- a/arch/arm/boot/dts/qcom-ipq4019-ap.dk01.1-c1.dts
++++ b/arch/arm/boot/dts/qcom-ipq4019-ap.dk01.1-c1.dts
+@@ -19,4 +19,13 @@
+ / {
+	model = "Qualcomm Technologies, Inc. IPQ40xx/AP-DK01.1-C1";
+
++	soc {
++		mdio@90000 {
++			status = "ok";
++			pinctrl-0 = <&mdio_pins>;
++			pinctrl-names = "default";
++			bias-disable;
++			phy-reset-gpio = <&tlmm 59 0>;
++		};
++        };
+ };
+diff --git a/arch/arm/boot/dts/qcom-ipq4019-ap.dk01.1.dtsi b/arch/arm/boot/dts/qcom-ipq4019-ap.dk01.1.dtsi
+index 2a5cc5e..bf4fde6 100644
+--- a/arch/arm/boot/dts/qcom-ipq4019-ap.dk01.1.dtsi
++++ b/arch/arm/boot/dts/qcom-ipq4019-ap.dk01.1.dtsi
+@@ -41,6 +41,19 @@
+		};
+
+		pinctrl@0x01000000 {
++			mdio_pins: mdio_pinmux {
++				mux_1 {
++					pins = "gpio53";
++					function = "mdio1";
++					bias-bus-hold;
++				};
++				mux_2 {
++					pins = "gpio52";
++					function = "mdc";
++					bias-bus-hold;
++				};
++			};
++
+			serial_pins: serial_pinmux {
+				mux {
+					pins = "gpio60", "gpio61";
+@@ -128,5 +141,29 @@
+		usb2: usb2@60f8800 {
+			status = "ok";
+		};
++
++		ess-switch@c000000 {
++			status = "ok";
++			switch_mac_mode = <0x0>; /* mac mode for RGMII RMII */
++			switch_initvlas = <
++				0x0007c 0x54 /* PORT0_STATUS */
++			>;
++		};
++
++		ess-psgmii@98000 {
++			status = "ok";
++		};
++
++		edma@c080000 {
++			status = "ok";
++		};
++
++		wifi@a000000 {
++			status = "ok";
++		};
++
++		wifi@a800000 {
++			status = "ok";
++		};
+	};
+ };
+diff --git a/arch/arm/boot/dts/qcom-ipq4019-ap.dk04.1.dtsi b/arch/arm/boot/dts/qcom-ipq4019-ap.dk04.1.dtsi
+index b68fc1a..a46afdf 100644
+--- a/arch/arm/boot/dts/qcom-ipq4019-ap.dk04.1.dtsi
++++ b/arch/arm/boot/dts/qcom-ipq4019-ap.dk04.1.dtsi
+@@ -88,6 +88,19 @@
+					bias-disable;
+				};
+			};
++
++			mdio_pins: mdio_pinmux {
++				mux_1 {
++					pins = "gpio6";
++					function = "mdio0";
++					bias-bus-hold;
++				};
++				mux_2 {
++					pins = "gpio7";
++					function = "mdc";
++					bias-bus-hold;
++				};
++			};
+		};
+
+		blsp_dma: dma@7884000 {
+@@ -159,5 +172,37 @@
+		watchdog@b017000 {
+			status = "ok";
+		};
++
++		mdio@90000 {
++			status = "ok";
++			pinctrl-0 = <&mdio_pins>;
++			pinctrl-names = "default";
++			phy-reset-gpio = <&tlmm 47 0>;
++			bias-disable;
++		};
++
++		ess-switch@c000000 {
++			status = "ok";
++			switch_mac_mode = <0x0>; /* mac mode for RGMII RMII */
++			switch_initvlas = <
++				0x0007c 0x54 /* PORT0_STATUS */
++			>;
++		};
++
++		ess-psgmii@98000 {
++			status = "ok";
++		};
++
++		edma@c080000 {
++			status = "ok";
++		};
++
++		wifi@a000000 {
++			status = "ok";
++		};
++
++		wifi@a800000 {
++			status = "ok";
++		};
+	};
+ };
+diff --git a/arch/arm/boot/dts/qcom-ipq4019.dtsi b/arch/arm/boot/dts/qcom-ipq4019.dtsi
+index be5b6f7..c5f5cf6 100644
+--- a/arch/arm/boot/dts/qcom-ipq4019.dtsi
++++ b/arch/arm/boot/dts/qcom-ipq4019.dtsi
+@@ -330,23 +330,23 @@
+			reg = <0x90000 0x64>;
+			status = "disabled";
+
+-			ethernet-phy@0 {
++			phy0: ethernet-phy@0 {
+				reg = <0>;
+			};
+
+-			ethernet-phy@1 {
++			phy1: ethernet-phy@1 {
+				reg = <1>;
+			};
+
+-			ethernet-phy@2 {
++			phy2: ethernet-phy@2 {
+				reg = <2>;
+			};
+
+-			ethernet-phy@3 {
++			phy3: ethernet-phy@3 {
+				reg = <3>;
+			};
+
+-			ethernet-phy@4 {
++			phy4: ethernet-phy@4 {
+				reg = <4>;
+			};
+		};
+@@ -355,8 +355,12 @@
+			compatible = "qcom,ess-switch";
+			reg = <0xc000000 0x80000>;
+			switch_access_mode = "local bus";
+-			resets = <&gcc ESS_RESET>;
+-			reset-names = "ess_rst";
++			resets = <&gcc ESS_RESET>, <&gcc ESS_MAC1_CLK_DIS>, \
++				<&gcc ESS_MAC2_CLK_DIS>, <&gcc ESS_MAC3_CLK_DIS>, \
++				<&gcc ESS_MAC4_CLK_DIS>, <&gcc ESS_MAC5_CLK_DIS>;
++			reset-names = "ess_rst","ess_mac1_clk_dis", \
++				"ess_mac2_clk_dis","ess_mac3_clk_dis", \
++				"ess_mac4_clk_dis", "ess_mac5_clk_dis";
+			clocks = <&gcc GCC_ESS_CLK>;
+			clock-names = "ess_clk";
+			switch_cpu_bmp = <0x1>;
+@@ -371,6 +375,8 @@
+			compatible = "qcom,ess-psgmii";
+			reg = <0x98000 0x800>;
+			psgmii_access_mode = "local bus";
++			resets = <&gcc ESS_PSGMII_ARES>;
++			reset-names = "psgmii_rst";
+			status = "disabled";
+		};
+
+@@ -419,18 +424,19 @@
+			status = "disabled";
+
+			gmac0: gmac0 {
+				local-mac-address = [00 00 00 00 00 00];
+-				vlan_tag = <1 0x1f>;
+-			};
+-
+-			gmac1: gmac1 {
+-				local-mac-address = [00 00 00 00 00 00];
+				qcom,phy_mdio_addr = <4>;
+				qcom,poll_required = <1>;
+				qcom,forced_speed = <1000>;
+				qcom,forced_duplex = <1>;
+				vlan_tag = <2 0x20>;
+			};
++
++			gmac1: gmac1 {
++				local-mac-address = [00 00 00 00 00 00];
++				qcom,poll_required_dynamic = <1>;
++				vlan_tag = <1 0x1e>;
++			};
+		};
+
+		usb3_ss_phy: ssphy@9a000 {
+--
+2.7.2
diff --git a/target/linux/ipq806x/profiles/00-default.mk b/target/linux/ipq806x/profiles/00-default.mk
index 9baa24f..3c17e5b 100644
--- a/target/linux/ipq806x/profiles/00-default.mk
+++ b/target/linux/ipq806x/profiles/00-default.mk
@@ -1,7 +1,9 @@ 
+
 define Profile/Default
   NAME:=Default Profile
   PRIORITY:=1
-  PACKAGES:=ath10k-firmware-qca99x0 ath10k-firmware-qca988x ath10k-firmware-qca9984
+  PACKAGES:=ath10k-firmware-qca99x0 ath10k-firmware-qca988x ath10k-firmware-qca9984 \
+	    ath10k-firmware-qca4019
 endef
 
 define Profile/Default/Description