Merge "tzt: Enabled exectzt for ipq40xx with dcache off"
diff --git a/arch/arm/dts/ipq807x-hk07.dts b/arch/arm/dts/ipq807x-hk07.dts
index 78b4b33..cdba42b 100644
--- a/arch/arm/dts/ipq807x-hk07.dts
+++ b/arch/arm/dts/ipq807x-hk07.dts
@@ -28,8 +28,34 @@
 		switch_mac_mode = <0x0>;
 		switch_mac_mode1 = <0xFF>;
 		switch_mac_mode2 = <0x6>;
-		8081_port = <5>;
 		napa_gpio = <44>;
+		napa_gpio_cnt = <1>;
+		port_phyinfo {
+			port@0 {
+				phy_address = <0>;
+				phy_type = <1>;
+			};
+			port@1 {
+				phy_address = <1>;
+				phy_type = <1>;
+			};
+			port@2 {
+				phy_address = <2>;
+				phy_type = <1>;
+			};
+			port@3 {
+				phy_address = <3>;
+				phy_type = <1>;
+			};
+			port@4 {
+				phy_address = <4>;
+				phy_type = <1>;
+			};
+			port@5 {
+				phy_address = <28>;
+				phy_type = <2>;
+			};
+		};
 	};
 };
 
diff --git a/arch/arm/dts/ipq807x-hk09.dts b/arch/arm/dts/ipq807x-hk09.dts
index 63f5ef3..d5287f3 100644
--- a/arch/arm/dts/ipq807x-hk09.dts
+++ b/arch/arm/dts/ipq807x-hk09.dts
@@ -27,8 +27,36 @@
 	};
 	ess-switch {
 		switch_mac_mode = <0x0>;
-		switch_mac_mode1 = <0xFF>;
-		switch_mac_mode2 = <0xFF>;
+		switch_mac_mode1 = <0x6>;
+		switch_mac_mode2 = <0x6>;
+		napa_gpio = <25 44>;
+		napa_gpio_cnt = <2>;
+		port_phyinfo {
+			port@0 {
+				phy_address = <0>;
+				phy_type = <1>;
+			};
+			port@1 {
+				phy_address = <1>;
+				phy_type = <1>;
+			};
+			port@2 {
+				phy_address = <2>;
+				phy_type = <1>;
+			};
+			port@3 {
+				phy_address = <3>;
+				phy_type = <1>;
+			};
+			port@4 {
+				phy_address = <24>;
+				phy_type = <2>;
+			};
+			port@5 {
+				phy_address = <28>;
+				phy_type = <2>;
+			};
+		};
 	};
 };
 
diff --git a/board/qca/arm/ipq807x/ipq807x.c b/board/qca/arm/ipq807x/ipq807x.c
index 60f7e3c0..9c9b849 100644
--- a/board/qca/arm/ipq807x/ipq807x.c
+++ b/board/qca/arm/ipq807x/ipq807x.c
@@ -311,17 +311,23 @@
 	return aquantia_gpio;
 }
 
-int get_napa_gpio()
+int get_napa_gpio(int napa_gpio[2])
 {
-	int napa_gpio = -1, node;
+	int napa_gpio_cnt = -1, node;
+	int res = -1;
 
 	node = fdt_path_offset(gd->fdt_blob, "/ess-switch");
-	if (node >= 0)
-		napa_gpio = fdtdec_get_uint(gd->fdt_blob, node, "napa_gpio", -1);
-	else
-		return node;
+	if (node >= 0) {
+		napa_gpio_cnt = fdtdec_get_uint(gd->fdt_blob, node, "napa_gpio_cnt", -1);
+		if (napa_gpio_cnt >= 1) {
+			res = fdtdec_get_int_array(gd->fdt_blob, node, "napa_gpio",
+					napa_gpio, napa_gpio_cnt);
+			if (res >= 0)
+				return napa_gpio_cnt;
+		}
+	}
 
-	return napa_gpio;
+	return res;
 }
 
 void aquantia_phy_reset_init(void)
@@ -345,24 +351,29 @@
 
 void napa_phy_reset_init(void)
 {
-	int napa_gpio = -1, node;
+	int napa_gpio[2] = {0}, node, napa_gpio_cnt, i;
 	unsigned int *napa_gpio_base;
 
-	napa_gpio = get_napa_gpio();
-	if (napa_gpio >=0) {
-		napa_gpio_base = (unsigned int *)GPIO_CONFIG_ADDR(napa_gpio);
-		writel(0x203, napa_gpio_base);
-		gpio_direction_output(napa_gpio, 0x0);
+	napa_gpio_cnt = get_napa_gpio(napa_gpio);
+	if (napa_gpio_cnt >= 1) {
+		for (i = 0; i < napa_gpio_cnt; i++) {
+			if (napa_gpio[i] >=0) {
+				napa_gpio_base = (unsigned int *)GPIO_CONFIG_ADDR(napa_gpio[i]);
+				writel(0x203, napa_gpio_base);
+				gpio_direction_output(napa_gpio[i], 0x0);
+			}
+		}
 	}
 }
 
 void napa_phy_reset_init_done(void)
 {
-	int napa_gpio;
+	int napa_gpio[2] = {0}, node, napa_gpio_cnt, i;
 
-	napa_gpio = get_napa_gpio();
-	if (napa_gpio >= 0) {
-		gpio_set_value(napa_gpio, 0x1);
+	napa_gpio_cnt = get_napa_gpio(napa_gpio);
+	if (napa_gpio_cnt >= 1) {
+		for (i = 0; i < napa_gpio_cnt; i++)
+			gpio_set_value(napa_gpio[i], 0x1);
 	}
 }
 
diff --git a/drivers/net/ipq807x/ipq807x_edma.c b/drivers/net/ipq807x/ipq807x_edma.c
index 3148947..3256068 100644
--- a/drivers/net/ipq807x/ipq807x_edma.c
+++ b/drivers/net/ipq807x/ipq807x_edma.c
@@ -45,6 +45,8 @@
 static struct ipq807x_eth_dev *ipq807x_edma_dev[IPQ807X_EDMA_DEV];
 
 uchar ipq807x_def_enetaddr[6] = {0x00, 0x03, 0x7F, 0xBA, 0xDB, 0xAD};
+phy_info_t *phy_info[PHY_MAX] = {0};
+int sgmii_mode[2] = {0};
 
 extern void qca8075_ess_reset(void);
 extern void psgmii_self_test(void);
@@ -856,6 +858,22 @@
 				IPQ807X_EDMA_MASK_INT_DISABLE);
 }
 
+int set_sgmii_mode(int port_id, int sg_mode)
+{
+	if (port_id == 4)
+		sgmii_mode[0] = sg_mode;
+	else if (port_id == 5)
+		sgmii_mode[1] = sg_mode;
+}
+
+int get_sgmii_mode(int port_id)
+{
+	if (port_id == 4)
+		return sgmii_mode[0];
+	else if (port_id == 5)
+		return sgmii_mode[1];
+}
+
 static int ipq807x_eth_init(struct eth_device *eth_dev, bd_t *this)
 {
 	struct ipq807x_eth_dev *priv = eth_dev->priv;
@@ -871,8 +889,8 @@
 	char *dp[] = {"Half", "Full"};
 	int linkup=0;
 	int mac_speed = 0, speed_clock1 = 0, speed_clock2 = 0;
-	int phy_addr, port_8033 = -1, node, aquantia_port = -1, port_8081 = -1;
-	int sgmii_mode = 0;
+	int phy_addr, port_8033 = -1, node, aquantia_port = -1;
+	int phy_node = -1;
 
 	node = fdt_path_offset(gd->fdt_blob, "/ess-switch");
 	if (node >= 0)
@@ -881,8 +899,7 @@
 	if (node >= 0)
 		 aquantia_port = fdtdec_get_uint(gd->fdt_blob, node, "aquantia_port", -1);
 
-	if (node >= 0)
-		 port_8081 = fdtdec_get_uint(gd->fdt_blob, node, "8081_port", -1);
+	phy_node = fdt_path_offset(gd->fdt_blob, "/ess-switch/port_phyinfo");
 	/*
 	 * Check PHY link, speed, Duplex on all phys.
 	 * we will proceed even if single link is up
@@ -902,15 +919,17 @@
 			return -1;
 		}
 
-		if (i == port_8033)
-			phy_addr = QCA8033_PHY_ADDR;
-		else if (i == port_8081)
-			phy_addr = QCA8081_PHY_ADDR;
-		else if (i == aquantia_port)
-			phy_addr = AQU_PHY_ADDR;
-		else
-			phy_addr = i;
+		if (phy_node >= 0) {
+			phy_addr = phy_info[i]->phy_address;
+		} else {
 
+			if (i == port_8033)
+				phy_addr = QCA8033_PHY_ADDR;
+			else if (i == aquantia_port)
+				phy_addr = AQU_PHY_ADDR;
+			else
+				phy_addr = i;
+		}
 		status = phy_get_ops->phy_get_link_status(priv->mac_unit, phy_addr);
 		if (status == 0)
 			linkup++;
@@ -932,8 +951,8 @@
 				printf ("eth%d PHY%d %s Speed :%d %s duplex\n",
 						priv->mac_unit, i, lstatus[status], speed,
 						dp[duplex]);
-				if (i == port_8081)
-					sgmii_mode = 1;
+				if (phy_info[i]->phy_type == QCA8081_PHY_TYPE)
+					set_sgmii_mode(i, 1);
 				break;
 			case FAL_SPEED_100:
 				mac_speed = 0x1;
@@ -950,8 +969,8 @@
 				printf ("eth%d PHY%d %s Speed :%d %s duplex\n",
 						priv->mac_unit, i, lstatus[status], speed,
 						dp[duplex]);
-				if (i == port_8081)
-					sgmii_mode = 1;
+				if (phy_info[i]->phy_type == QCA8081_PHY_TYPE)
+					set_sgmii_mode(i, 1);
 				break;
 			case FAL_SPEED_1000:
 				mac_speed = 0x2;
@@ -959,14 +978,16 @@
 					speed_clock1 = 0x104;
 				else if (i == port_8033)
 					speed_clock1 = 0x301;
+				else if (phy_info[i]->phy_type == QCA8081_PHY_TYPE)
+					speed_clock1 = 0x301;
 				else
 					speed_clock1 = 0x101;
 				speed_clock2 = 0x0;
 				printf ("eth%d PHY%d %s Speed :%d %s duplex\n",
 						priv->mac_unit, i, lstatus[status], speed,
 						dp[duplex]);
-				if (i == port_8081)
-					sgmii_mode = 1;
+				if (phy_info[i]->phy_type == QCA8081_PHY_TYPE)
+					set_sgmii_mode(i, 1);
 				break;
 			case FAL_SPEED_10000:
 				mac_speed = 0x3;
@@ -977,23 +998,22 @@
 						dp[duplex]);
 				break;
 			case FAL_SPEED_2500:
-				if (i == port_8081)
+				if (phy_info[i]->phy_type == QCA8081_PHY_TYPE) {
 					mac_speed = 0x2;
-				else
-					mac_speed = 0x4;
-
-				if (port_8081 == 4)
-					speed_clock1 = 0x301;
-				else if (port_8081 == 5)
-					speed_clock1 = 0x101;
-				else
+					if (i == 4)
+						speed_clock1 = 0x301;
+					else if (i == 5)
+						speed_clock1 = 0x101;
+				} else {
 					speed_clock1 = 0x107;
+					mac_speed = 0x4;
+				}
 				speed_clock2 = 0x0;
 				printf ("eth%d PHY%d %s Speed :%d %s duplex\n",
 						priv->mac_unit, i, lstatus[status], speed,
 						dp[duplex]);
-				if (i == port_8081)
-					sgmii_mode = 0;
+				if (phy_info[i]->phy_type == QCA8081_PHY_TYPE)
+					set_sgmii_mode(i, 0);
 				break;
 			case FAL_SPEED_5000:
 				mac_speed = 0x5;
@@ -1008,19 +1028,23 @@
 				break;
 		}
 
-		if (i == port_8081) {
-			if (sgmii_mode != uniphy_phy_mode) {
-				uniphy_phy_mode = sgmii_mode;
-				if (sgmii_mode) {
-					ppe_port_bridge_txmac_set(i, 1);
-					ppe_uniphy_mode_set(0x2, PORT_WRAPPER_SGMII0_RGMII4);
+		if (phy_info[i]->phy_type == QCA8081_PHY_TYPE) {
+				if (get_sgmii_mode(i)) {
+					ppe_port_bridge_txmac_set(i + 1, 1);
+					if (i == 4)
+						ppe_uniphy_mode_set(0x1, PORT_WRAPPER_SGMII0_RGMII4);
+					else if (i == 5)
+						ppe_uniphy_mode_set(0x2, PORT_WRAPPER_SGMII0_RGMII4);
 
 				} else {
-					ppe_port_bridge_txmac_set(i, 1);
-					ppe_uniphy_mode_set(0x2, PORT_WRAPPER_SGMII_PLUS);
+					ppe_port_bridge_txmac_set(i + 1, 1);
+					if (i == 4)
+						ppe_uniphy_mode_set(0x1, PORT_WRAPPER_SGMII_PLUS);
+					else if (i == 5)
+						ppe_uniphy_mode_set(0x2, PORT_WRAPPER_SGMII_PLUS);
 				}
-			}
 		}
+
 		ipq807x_speed_clock_set(i, speed_clock1, speed_clock2);
 		if (i == aquantia_port)
 			ipq807x_uxsgmii_speed_set(i, mac_speed, duplex, status);
@@ -1629,6 +1653,27 @@
 	return 0;
 }
 
+void get_phy_address(int offset)
+{
+	int phy_type;
+	int phy_address;
+	int i;
+
+	for (i = 0; i < PHY_MAX; i++)
+		phy_info[i] = ipq807x_alloc_mem(sizeof(phy_info_t));
+	i = 0;
+	for (offset = fdt_first_subnode(gd->fdt_blob, offset); offset > 0;
+	     offset = fdt_next_subnode(gd->fdt_blob, offset)) {
+
+		phy_address = fdtdec_get_uint(gd->fdt_blob,
+							  offset, "phy_address", 0);
+		phy_type = fdtdec_get_uint(gd->fdt_blob,
+							  offset, "phy_type", 0);
+		phy_info[i]->phy_address = phy_address;
+		phy_info[i++]->phy_type = phy_type;
+	}
+}
+
 int ipq807x_edma_init(void *edma_board_cfg)
 {
 	struct eth_device *dev[IPQ807X_EDMA_DEV];
@@ -1640,8 +1685,10 @@
 	int ret = -1;
 	ipq807x_edma_board_cfg_t ledma_cfg, *edma_cfg;
 	static int sw_init_done = 0;
-	int port_8033 = -1, port_8081 = -1, node, phy_addr, aquantia_port = -1;
-	int mode;
+	int port_8033 = -1, node, phy_addr, aquantia_port = -1;
+	int mode, phy_node = -1;
+	int napa_port_len = 0 , len;
+	unsigned int phy_array[6] = {0};
 
 	node = fdt_path_offset(gd->fdt_blob, "/ess-switch");
 	if (node >= 0)
@@ -1650,8 +1697,9 @@
 	if (node >= 0)
 		aquantia_port = fdtdec_get_uint(gd->fdt_blob, node, "aquantia_port", -1);
 
-	if (node >= 0)
-		port_8081 = fdtdec_get_uint(gd->fdt_blob, node, "8081_port", -1);
+	phy_node = fdt_path_offset(gd->fdt_blob, "/ess-switch/port_phyinfo");
+	if (phy_node >= 0)
+		get_phy_address(phy_node);
 
 	mode = fdtdec_get_uint(gd->fdt_blob, node, "switch_mac_mode", -1);
 	if (mode < 0) {
@@ -1739,14 +1787,16 @@
 			goto init_failed;
 
 		for (phy_id =  0; phy_id < PHY_MAX; phy_id++) {
-			if (phy_id == port_8033)
-				phy_addr = QCA8033_PHY_ADDR;
-			else if (phy_id == aquantia_port)
-				phy_addr = AQU_PHY_ADDR;
-			else if (phy_id == port_8081)
-				phy_addr = QCA8081_PHY_ADDR;
-			else
-				phy_addr = phy_id;
+			if (phy_node >= 0) {
+				phy_addr = phy_info[phy_id]->phy_address;
+			} else {
+				if (phy_id == port_8033)
+					phy_addr = QCA8033_PHY_ADDR;
+				else if (phy_id == aquantia_port)
+					phy_addr = AQU_PHY_ADDR;
+				else
+					phy_addr = phy_id;
+			}
 
 			phy_chip_id1 = ipq_mdio_read(phy_addr, QCA_PHY_ID1, NULL);
 			phy_chip_id2 = ipq_mdio_read(phy_addr, QCA_PHY_ID2, NULL);
diff --git a/drivers/net/ipq807x/ipq807x_ppe.c b/drivers/net/ipq807x/ipq807x_ppe.c
index bc55ca6..a2ee922 100644
--- a/drivers/net/ipq807x/ipq807x_ppe.c
+++ b/drivers/net/ipq807x/ipq807x_ppe.c
@@ -1067,7 +1067,7 @@
 	ipq807x_ppe_reg_write(IPQ807X_PPE_L1_E_SP_CFG_TBL + (id * 0x80), id * 2 + 1);
 }
 
-static void ppe_port_mux_set(int port_id, int port_type)
+static void ppe_port_mux_set(int port_id, int port_type, int mode)
 {
 	union port_mux_ctrl_u port_mux_ctrl;
 
@@ -1075,7 +1075,10 @@
 	port_mux_ctrl.bf.port4_pcs_sel = PORT4_PCS_SEL_GMII_FROM_PCS0;
 	if (port_id == PORT5) {
 		if (port_type == PORT_GMAC_TYPE) {
-			port_mux_ctrl.bf.port5_pcs_sel = PORT5_PCS_SEL_GMII_FROM_PCS0;
+			if (mode == PORT_WRAPPER_SGMII_PLUS)
+				port_mux_ctrl.bf.port5_pcs_sel = PORT5_PCS_SEL_GMII_FROM_PCS1;
+			else
+				port_mux_ctrl.bf.port5_pcs_sel = PORT5_PCS_SEL_GMII_FROM_PCS0;
 			port_mux_ctrl.bf.port5_gmac_sel = PORT5_GMAC_SEL_GMAC;
 		} else if (port_type == PORT_XGMAC_TYPE) {
 			port_mux_ctrl.bf.port5_pcs_sel = PORT5_PCS_SEL_GMII_FROM_PCS1;
@@ -1113,7 +1116,7 @@
 		default:
 			return;
 	}
-	ppe_port_mux_set(port_id, port_type);
+	ppe_port_mux_set(port_id, port_type, mode);
 }
 
 
diff --git a/drivers/net/ipq_common/ipq_phy.h b/drivers/net/ipq_common/ipq_phy.h
index 923a390..05c1df7 100644
--- a/drivers/net/ipq_common/ipq_phy.h
+++ b/drivers/net/ipq_common/ipq_phy.h
@@ -38,7 +38,6 @@
 #define QCA8033_PHY				0x004DD074
 #define QCA8033_PHY_ADDR			0x6
 #define QCA8081_PHY				0x004DD100
-#define QCA8081_PHY_ADDR			0x1C
 #define AQUANTIA_PHY_107			0x03a1b4e2
 #define AQUANTIA_PHY_109			0x03a1b502
 #define AQUANTIA_PHY_111			0x03a1b610
@@ -95,6 +94,15 @@
 	PORT_WRAPPER_SGMII_PLUS,
 };
 
+enum phy_mode {
+	MALIBU_PHY_TYPE = 1,
+	QCA8081_PHY_TYPE = 2,
+};
+
+typedef struct {
+	u32 phy_address;
+	u32 phy_type;
+}phy_info_t;
 
 struct phy_ops {
 	u8 (*phy_get_link_status) (u32 dev_id, u32 phy_id);